1169689Skan/* Subroutines used for MIPS code generation.
2169689Skan   Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4169689Skan   Contributed by A. Lichnewsky, lich@inria.inria.fr.
5169689Skan   Changes by Michael Meissner, meissner@osf.org.
6169689Skan   64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and
7169689Skan   Brendan Eich, brendan@microunity.com.
8169689Skan
9169689SkanThis file is part of GCC.
10169689Skan
11169689SkanGCC is free software; you can redistribute it and/or modify
12169689Skanit under the terms of the GNU General Public License as published by
13169689Skanthe Free Software Foundation; either version 2, or (at your option)
14169689Skanany later version.
15169689Skan
16169689SkanGCC is distributed in the hope that it will be useful,
17169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
18169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19169689SkanGNU General Public License for more details.
20169689Skan
21169689SkanYou should have received a copy of the GNU General Public License
22169689Skanalong with GCC; see the file COPYING.  If not, write to
23169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
24169689SkanBoston, MA 02110-1301, USA.  */
25169689Skan
26169689Skan#include "config.h"
27169689Skan#include "system.h"
28169689Skan#include "coretypes.h"
29169689Skan#include "tm.h"
30169689Skan#include <signal.h>
31169689Skan#include "rtl.h"
32169689Skan#include "regs.h"
33169689Skan#include "hard-reg-set.h"
34169689Skan#include "real.h"
35169689Skan#include "insn-config.h"
36169689Skan#include "conditions.h"
37169689Skan#include "insn-attr.h"
38169689Skan#include "recog.h"
39169689Skan#include "toplev.h"
40169689Skan#include "output.h"
41169689Skan#include "tree.h"
42169689Skan#include "function.h"
43169689Skan#include "expr.h"
44169689Skan#include "optabs.h"
45169689Skan#include "flags.h"
46169689Skan#include "reload.h"
47169689Skan#include "tm_p.h"
48169689Skan#include "ggc.h"
49169689Skan#include "gstab.h"
50169689Skan#include "hashtab.h"
51169689Skan#include "debug.h"
52169689Skan#include "target.h"
53169689Skan#include "target-def.h"
54169689Skan#include "integrate.h"
55169689Skan#include "langhooks.h"
56169689Skan#include "cfglayout.h"
57169689Skan#include "sched-int.h"
58169689Skan#include "tree-gimple.h"
59169689Skan#include "bitmap.h"
60169689Skan
61169689Skan/* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF.  */
62169689Skan#define UNSPEC_ADDRESS_P(X)					\
63169689Skan  (GET_CODE (X) == UNSPEC					\
64169689Skan   && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST			\
65169689Skan   && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)
66169689Skan
67169689Skan/* Extract the symbol or label from UNSPEC wrapper X.  */
68169689Skan#define UNSPEC_ADDRESS(X) \
69169689Skan  XVECEXP (X, 0, 0)
70169689Skan
71169689Skan/* Extract the symbol type from UNSPEC wrapper X.  */
72169689Skan#define UNSPEC_ADDRESS_TYPE(X) \
73169689Skan  ((enum mips_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
74169689Skan
75169689Skan/* The maximum distance between the top of the stack frame and the
76169689Skan   value $sp has when we save & restore registers.
77169689Skan
78169689Skan   Use a maximum gap of 0x100 in the mips16 case.  We can then use
79169689Skan   unextended instructions to save and restore registers, and to
80169689Skan   allocate and deallocate the top part of the frame.
81169689Skan
82169689Skan   The value in the !mips16 case must be a SMALL_OPERAND and must
83169689Skan   preserve the maximum stack alignment.  */
84169689Skan#define MIPS_MAX_FIRST_STACK_STEP (TARGET_MIPS16 ? 0x100 : 0x7ff0)
85169689Skan
86169689Skan/* True if INSN is a mips.md pattern or asm statement.  */
87169689Skan#define USEFUL_INSN_P(INSN)						\
88169689Skan  (INSN_P (INSN)							\
89169689Skan   && GET_CODE (PATTERN (INSN)) != USE					\
90169689Skan   && GET_CODE (PATTERN (INSN)) != CLOBBER				\
91169689Skan   && GET_CODE (PATTERN (INSN)) != ADDR_VEC				\
92169689Skan   && GET_CODE (PATTERN (INSN)) != ADDR_DIFF_VEC)
93169689Skan
94169689Skan/* If INSN is a delayed branch sequence, return the first instruction
95169689Skan   in the sequence, otherwise return INSN itself.  */
96169689Skan#define SEQ_BEGIN(INSN)							\
97169689Skan  (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE		\
98169689Skan   ? XVECEXP (PATTERN (INSN), 0, 0)					\
99169689Skan   : (INSN))
100169689Skan
101169689Skan/* Likewise for the last instruction in a delayed branch sequence.  */
102169689Skan#define SEQ_END(INSN)							\
103169689Skan  (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE		\
104169689Skan   ? XVECEXP (PATTERN (INSN), 0, XVECLEN (PATTERN (INSN), 0) - 1)	\
105169689Skan   : (INSN))
106169689Skan
107169689Skan/* Execute the following loop body with SUBINSN set to each instruction
108169689Skan   between SEQ_BEGIN (INSN) and SEQ_END (INSN) inclusive.  */
109169689Skan#define FOR_EACH_SUBINSN(SUBINSN, INSN)					\
110169689Skan  for ((SUBINSN) = SEQ_BEGIN (INSN);					\
111169689Skan       (SUBINSN) != NEXT_INSN (SEQ_END (INSN));				\
112169689Skan       (SUBINSN) = NEXT_INSN (SUBINSN))
113169689Skan
114169689Skan/* Classifies an address.
115169689Skan
116169689Skan   ADDRESS_REG
117169689Skan       A natural register + offset address.  The register satisfies
118169689Skan       mips_valid_base_register_p and the offset is a const_arith_operand.
119169689Skan
120169689Skan   ADDRESS_LO_SUM
121169689Skan       A LO_SUM rtx.  The first operand is a valid base register and
122169689Skan       the second operand is a symbolic address.
123169689Skan
124169689Skan   ADDRESS_CONST_INT
125169689Skan       A signed 16-bit constant address.
126169689Skan
127169689Skan   ADDRESS_SYMBOLIC:
128169689Skan       A constant symbolic address (equivalent to CONSTANT_SYMBOLIC).  */
129169689Skanenum mips_address_type {
130169689Skan  ADDRESS_REG,
131169689Skan  ADDRESS_LO_SUM,
132169689Skan  ADDRESS_CONST_INT,
133169689Skan  ADDRESS_SYMBOLIC
134169689Skan};
135169689Skan
136169689Skan/* Classifies the prototype of a builtin function.  */
137169689Skanenum mips_function_type
138169689Skan{
139169689Skan  MIPS_V2SF_FTYPE_V2SF,
140169689Skan  MIPS_V2SF_FTYPE_V2SF_V2SF,
141169689Skan  MIPS_V2SF_FTYPE_V2SF_V2SF_INT,
142169689Skan  MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,
143169689Skan  MIPS_V2SF_FTYPE_SF_SF,
144169689Skan  MIPS_INT_FTYPE_V2SF_V2SF,
145169689Skan  MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,
146169689Skan  MIPS_INT_FTYPE_SF_SF,
147169689Skan  MIPS_INT_FTYPE_DF_DF,
148169689Skan  MIPS_SF_FTYPE_V2SF,
149169689Skan  MIPS_SF_FTYPE_SF,
150169689Skan  MIPS_SF_FTYPE_SF_SF,
151169689Skan  MIPS_DF_FTYPE_DF,
152169689Skan  MIPS_DF_FTYPE_DF_DF,
153169689Skan
154169689Skan  /* For MIPS DSP ASE  */
155169689Skan  MIPS_DI_FTYPE_DI_SI,
156169689Skan  MIPS_DI_FTYPE_DI_SI_SI,
157169689Skan  MIPS_DI_FTYPE_DI_V2HI_V2HI,
158169689Skan  MIPS_DI_FTYPE_DI_V4QI_V4QI,
159169689Skan  MIPS_SI_FTYPE_DI_SI,
160169689Skan  MIPS_SI_FTYPE_PTR_SI,
161169689Skan  MIPS_SI_FTYPE_SI,
162169689Skan  MIPS_SI_FTYPE_SI_SI,
163169689Skan  MIPS_SI_FTYPE_V2HI,
164169689Skan  MIPS_SI_FTYPE_V2HI_V2HI,
165169689Skan  MIPS_SI_FTYPE_V4QI,
166169689Skan  MIPS_SI_FTYPE_V4QI_V4QI,
167169689Skan  MIPS_SI_FTYPE_VOID,
168169689Skan  MIPS_V2HI_FTYPE_SI,
169169689Skan  MIPS_V2HI_FTYPE_SI_SI,
170169689Skan  MIPS_V2HI_FTYPE_V2HI,
171169689Skan  MIPS_V2HI_FTYPE_V2HI_SI,
172169689Skan  MIPS_V2HI_FTYPE_V2HI_V2HI,
173169689Skan  MIPS_V2HI_FTYPE_V4QI,
174169689Skan  MIPS_V2HI_FTYPE_V4QI_V2HI,
175169689Skan  MIPS_V4QI_FTYPE_SI,
176169689Skan  MIPS_V4QI_FTYPE_V2HI_V2HI,
177169689Skan  MIPS_V4QI_FTYPE_V4QI_SI,
178169689Skan  MIPS_V4QI_FTYPE_V4QI_V4QI,
179169689Skan  MIPS_VOID_FTYPE_SI_SI,
180169689Skan  MIPS_VOID_FTYPE_V2HI_V2HI,
181169689Skan  MIPS_VOID_FTYPE_V4QI_V4QI,
182169689Skan
183169689Skan  /* The last type.  */
184169689Skan  MIPS_MAX_FTYPE_MAX
185169689Skan};
186169689Skan
187169689Skan/* Specifies how a builtin function should be converted into rtl.  */
188169689Skanenum mips_builtin_type
189169689Skan{
190169689Skan  /* The builtin corresponds directly to an .md pattern.  The return
191169689Skan     value is mapped to operand 0 and the arguments are mapped to
192169689Skan     operands 1 and above.  */
193169689Skan  MIPS_BUILTIN_DIRECT,
194169689Skan
195169689Skan  /* The builtin corresponds directly to an .md pattern.  There is no return
196169689Skan     value and the arguments are mapped to operands 0 and above.  */
197169689Skan  MIPS_BUILTIN_DIRECT_NO_TARGET,
198169689Skan
199169689Skan  /* The builtin corresponds to a comparison instruction followed by
200169689Skan     a mips_cond_move_tf_ps pattern.  The first two arguments are the
201169689Skan     values to compare and the second two arguments are the vector
202169689Skan     operands for the movt.ps or movf.ps instruction (in assembly order).  */
203169689Skan  MIPS_BUILTIN_MOVF,
204169689Skan  MIPS_BUILTIN_MOVT,
205169689Skan
206169689Skan  /* The builtin corresponds to a V2SF comparison instruction.  Operand 0
207169689Skan     of this instruction is the result of the comparison, which has mode
208169689Skan     CCV2 or CCV4.  The function arguments are mapped to operands 1 and
209169689Skan     above.  The function's return value is an SImode boolean that is
210169689Skan     true under the following conditions:
211169689Skan
212169689Skan     MIPS_BUILTIN_CMP_ANY: one of the registers is true
213169689Skan     MIPS_BUILTIN_CMP_ALL: all of the registers are true
214169689Skan     MIPS_BUILTIN_CMP_LOWER: the first register is true
215169689Skan     MIPS_BUILTIN_CMP_UPPER: the second register is true.  */
216169689Skan  MIPS_BUILTIN_CMP_ANY,
217169689Skan  MIPS_BUILTIN_CMP_ALL,
218169689Skan  MIPS_BUILTIN_CMP_UPPER,
219169689Skan  MIPS_BUILTIN_CMP_LOWER,
220169689Skan
221169689Skan  /* As above, but the instruction only sets a single $fcc register.  */
222169689Skan  MIPS_BUILTIN_CMP_SINGLE,
223169689Skan
224169689Skan  /* For generating bposge32 branch instructions in MIPS32 DSP ASE.  */
225169689Skan  MIPS_BUILTIN_BPOSGE32
226169689Skan};
227169689Skan
228169689Skan/* Invokes MACRO (COND) for each c.cond.fmt condition.  */
229169689Skan#define MIPS_FP_CONDITIONS(MACRO) \
230169689Skan  MACRO (f),	\
231169689Skan  MACRO (un),	\
232169689Skan  MACRO (eq),	\
233169689Skan  MACRO (ueq),	\
234169689Skan  MACRO (olt),	\
235169689Skan  MACRO (ult),	\
236169689Skan  MACRO (ole),	\
237169689Skan  MACRO (ule),	\
238169689Skan  MACRO (sf),	\
239169689Skan  MACRO (ngle),	\
240169689Skan  MACRO (seq),	\
241169689Skan  MACRO (ngl),	\
242169689Skan  MACRO (lt),	\
243169689Skan  MACRO (nge),	\
244169689Skan  MACRO (le),	\
245169689Skan  MACRO (ngt)
246169689Skan
247169689Skan/* Enumerates the codes above as MIPS_FP_COND_<X>.  */
248169689Skan#define DECLARE_MIPS_COND(X) MIPS_FP_COND_ ## X
249169689Skanenum mips_fp_condition {
250169689Skan  MIPS_FP_CONDITIONS (DECLARE_MIPS_COND)
251169689Skan};
252169689Skan
253169689Skan/* Index X provides the string representation of MIPS_FP_COND_<X>.  */
254169689Skan#define STRINGIFY(X) #X
255169689Skanstatic const char *const mips_fp_conditions[] = {
256169689Skan  MIPS_FP_CONDITIONS (STRINGIFY)
257169689Skan};
258169689Skan
259169689Skan/* A function to save or store a register.  The first argument is the
260169689Skan   register and the second is the stack slot.  */
261169689Skantypedef void (*mips_save_restore_fn) (rtx, rtx);
262169689Skan
263169689Skanstruct mips16_constant;
264169689Skanstruct mips_arg_info;
265169689Skanstruct mips_address_info;
266169689Skanstruct mips_integer_op;
267169689Skanstruct mips_sim;
268169689Skan
269169689Skanstatic enum mips_symbol_type mips_classify_symbol (rtx);
270169689Skanstatic void mips_split_const (rtx, rtx *, HOST_WIDE_INT *);
271169689Skanstatic bool mips_offset_within_object_p (rtx, HOST_WIDE_INT);
272169689Skanstatic bool mips_valid_base_register_p (rtx, enum machine_mode, int);
273169689Skanstatic bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
274169689Skanstatic bool mips_classify_address (struct mips_address_info *, rtx,
275169689Skan				   enum machine_mode, int);
276169689Skanstatic bool mips_cannot_force_const_mem (rtx);
277169689Skanstatic bool mips_use_blocks_for_constant_p (enum machine_mode, rtx);
278169689Skanstatic int mips_symbol_insns (enum mips_symbol_type);
279169689Skanstatic bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx);
280169689Skanstatic rtx mips_force_temporary (rtx, rtx);
281169689Skanstatic rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type);
282169689Skanstatic rtx mips_add_offset (rtx, rtx, HOST_WIDE_INT);
283169689Skanstatic unsigned int mips_build_shift (struct mips_integer_op *, HOST_WIDE_INT);
284169689Skanstatic unsigned int mips_build_lower (struct mips_integer_op *,
285169689Skan				      unsigned HOST_WIDE_INT);
286169689Skanstatic unsigned int mips_build_integer (struct mips_integer_op *,
287169689Skan					unsigned HOST_WIDE_INT);
288169689Skanstatic void mips_legitimize_const_move (enum machine_mode, rtx, rtx);
289169689Skanstatic int m16_check_op (rtx, int, int, int);
290169689Skanstatic bool mips_rtx_costs (rtx, int, int, int *);
291169689Skanstatic int mips_address_cost (rtx);
292169689Skanstatic void mips_emit_compare (enum rtx_code *, rtx *, rtx *, bool);
293169689Skanstatic void mips_load_call_address (rtx, rtx, int);
294169689Skanstatic bool mips_function_ok_for_sibcall (tree, tree);
295169689Skanstatic void mips_block_move_straight (rtx, rtx, HOST_WIDE_INT);
296169689Skanstatic void mips_adjust_block_mem (rtx, HOST_WIDE_INT, rtx *, rtx *);
297169689Skanstatic void mips_block_move_loop (rtx, rtx, HOST_WIDE_INT);
298169689Skanstatic void mips_arg_info (const CUMULATIVE_ARGS *, enum machine_mode,
299169689Skan			   tree, int, struct mips_arg_info *);
300169689Skanstatic bool mips_get_unaligned_mem (rtx *, unsigned int, int, rtx *, rtx *);
301169689Skanstatic void mips_set_architecture (const struct mips_cpu_info *);
302169689Skanstatic void mips_set_tune (const struct mips_cpu_info *);
303169689Skanstatic bool mips_handle_option (size_t, const char *, int);
304169689Skanstatic struct machine_function *mips_init_machine_status (void);
305169689Skanstatic void print_operand_reloc (FILE *, rtx, const char **);
306169689Skan#if TARGET_IRIX
307169689Skanstatic void irix_output_external_libcall (rtx);
308169689Skan#endif
309169689Skanstatic void mips_file_start (void);
310169689Skanstatic void mips_file_end (void);
311169689Skanstatic bool mips_rewrite_small_data_p (rtx);
312169689Skanstatic int mips_small_data_pattern_1 (rtx *, void *);
313169689Skanstatic int mips_rewrite_small_data_1 (rtx *, void *);
314169689Skanstatic bool mips_function_has_gp_insn (void);
315169689Skanstatic unsigned int mips_global_pointer	(void);
316169689Skanstatic bool mips_save_reg_p (unsigned int);
317169689Skanstatic void mips_save_restore_reg (enum machine_mode, int, HOST_WIDE_INT,
318169689Skan				   mips_save_restore_fn);
319169689Skanstatic void mips_for_each_saved_reg (HOST_WIDE_INT, mips_save_restore_fn);
320169689Skanstatic void mips_output_cplocal (void);
321169689Skanstatic void mips_emit_loadgp (void);
322169689Skanstatic void mips_output_function_prologue (FILE *, HOST_WIDE_INT);
323169689Skanstatic void mips_set_frame_expr (rtx);
324169689Skanstatic rtx mips_frame_set (rtx, rtx);
325169689Skanstatic void mips_save_reg (rtx, rtx);
326169689Skanstatic void mips_output_function_epilogue (FILE *, HOST_WIDE_INT);
327169689Skanstatic void mips_restore_reg (rtx, rtx);
328169689Skanstatic void mips_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
329169689Skan				  HOST_WIDE_INT, tree);
330169689Skanstatic int symbolic_expression_p (rtx);
331169689Skanstatic section *mips_select_rtx_section (enum machine_mode, rtx,
332169689Skan					 unsigned HOST_WIDE_INT);
333169689Skanstatic section *mips_function_rodata_section (tree);
334169689Skanstatic bool mips_in_small_data_p (tree);
335169689Skanstatic bool mips_use_anchors_for_symbol_p (rtx);
336169689Skanstatic int mips_fpr_return_fields (tree, tree *);
337169689Skanstatic bool mips_return_in_msb (tree);
338169689Skanstatic rtx mips_return_fpr_pair (enum machine_mode mode,
339169689Skan				 enum machine_mode mode1, HOST_WIDE_INT,
340169689Skan				 enum machine_mode mode2, HOST_WIDE_INT);
341169689Skanstatic rtx mips16_gp_pseudo_reg (void);
342169689Skanstatic void mips16_fp_args (FILE *, int, int);
343169689Skanstatic void build_mips16_function_stub (FILE *);
344169689Skanstatic rtx dump_constants_1 (enum machine_mode, rtx, rtx);
345169689Skanstatic void dump_constants (struct mips16_constant *, rtx);
346169689Skanstatic int mips16_insn_length (rtx);
347169689Skanstatic int mips16_rewrite_pool_refs (rtx *, void *);
348169689Skanstatic void mips16_lay_out_constants (void);
349169689Skanstatic void mips_sim_reset (struct mips_sim *);
350169689Skanstatic void mips_sim_init (struct mips_sim *, state_t);
351169689Skanstatic void mips_sim_next_cycle (struct mips_sim *);
352169689Skanstatic void mips_sim_wait_reg (struct mips_sim *, rtx, rtx);
353169689Skanstatic int mips_sim_wait_regs_2 (rtx *, void *);
354169689Skanstatic void mips_sim_wait_regs_1 (rtx *, void *);
355169689Skanstatic void mips_sim_wait_regs (struct mips_sim *, rtx);
356169689Skanstatic void mips_sim_wait_units (struct mips_sim *, rtx);
357169689Skanstatic void mips_sim_wait_insn (struct mips_sim *, rtx);
358169689Skanstatic void mips_sim_record_set (rtx, rtx, void *);
359169689Skanstatic void mips_sim_issue_insn (struct mips_sim *, rtx);
360169689Skanstatic void mips_sim_issue_nop (struct mips_sim *);
361169689Skanstatic void mips_sim_finish_insn (struct mips_sim *, rtx);
362169689Skanstatic void vr4130_avoid_branch_rt_conflict (rtx);
363169689Skanstatic void vr4130_align_insns (void);
364169689Skanstatic void mips_avoid_hazard (rtx, rtx, int *, rtx *, rtx);
365169689Skanstatic void mips_avoid_hazards (void);
366169689Skanstatic void mips_reorg (void);
367169689Skanstatic bool mips_strict_matching_cpu_name_p (const char *, const char *);
368169689Skanstatic bool mips_matching_cpu_name_p (const char *, const char *);
369169689Skanstatic const struct mips_cpu_info *mips_parse_cpu (const char *);
370169689Skanstatic const struct mips_cpu_info *mips_cpu_info_from_isa (int);
371169689Skanstatic bool mips_return_in_memory (tree, tree);
372169689Skanstatic bool mips_strict_argument_naming (CUMULATIVE_ARGS *);
373169689Skanstatic void mips_macc_chains_record (rtx);
374169689Skanstatic void mips_macc_chains_reorder (rtx *, int);
375169689Skanstatic void vr4130_true_reg_dependence_p_1 (rtx, rtx, void *);
376169689Skanstatic bool vr4130_true_reg_dependence_p (rtx);
377169689Skanstatic bool vr4130_swap_insns_p (rtx, rtx);
378169689Skanstatic void vr4130_reorder (rtx *, int);
379169689Skanstatic void mips_promote_ready (rtx *, int, int);
380169689Skanstatic int mips_sched_reorder (FILE *, int, rtx *, int *, int);
381169689Skanstatic int mips_variable_issue (FILE *, int, rtx, int);
382169689Skanstatic int mips_adjust_cost (rtx, rtx, rtx, int);
383169689Skanstatic int mips_issue_rate (void);
384169689Skanstatic int mips_multipass_dfa_lookahead (void);
385169689Skanstatic void mips_init_libfuncs (void);
386169689Skanstatic void mips_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
387169689Skan					 tree, int *, int);
388169689Skanstatic tree mips_build_builtin_va_list (void);
389169689Skanstatic tree mips_gimplify_va_arg_expr (tree, tree, tree *, tree *);
390169689Skanstatic bool mips_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode mode,
391169689Skan				    tree, bool);
392169689Skanstatic bool mips_callee_copies (CUMULATIVE_ARGS *, enum machine_mode mode,
393169689Skan				tree, bool);
394169689Skanstatic int mips_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode mode,
395169689Skan				   tree, bool);
396169689Skanstatic bool mips_valid_pointer_mode (enum machine_mode);
397169689Skanstatic bool mips_vector_mode_supported_p (enum machine_mode);
398169689Skanstatic rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);
399169689Skanstatic rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
400169689Skanstatic rtx mips_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
401169689Skanstatic void mips_init_builtins (void);
402169689Skanstatic rtx mips_expand_builtin_direct (enum insn_code, rtx, tree, bool);
403169689Skanstatic rtx mips_expand_builtin_movtf (enum mips_builtin_type,
404169689Skan				      enum insn_code, enum mips_fp_condition,
405169689Skan				      rtx, tree);
406169689Skanstatic rtx mips_expand_builtin_compare (enum mips_builtin_type,
407169689Skan					enum insn_code, enum mips_fp_condition,
408169689Skan					rtx, tree);
409169689Skanstatic rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
410169689Skanstatic void mips_encode_section_info (tree, rtx, int);
411169689Skanstatic void mips_extra_live_on_entry (bitmap);
412169689Skanstatic int mips_mode_rep_extended (enum machine_mode, enum machine_mode);
413169689Skan
414169689Skan/* Structure to be filled in by compute_frame_size with register
415169689Skan   save masks, and offsets for the current function.  */
416169689Skan
417169689Skanstruct mips_frame_info GTY(())
418169689Skan{
419169689Skan  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
420169689Skan  HOST_WIDE_INT var_size;	/* # bytes that variables take up */
421169689Skan  HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */
422169689Skan  HOST_WIDE_INT cprestore_size;	/* # bytes that the .cprestore slot takes up */
423169689Skan  HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */
424169689Skan  HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */
425169689Skan  unsigned int mask;		/* mask of saved gp registers */
426169689Skan  unsigned int fmask;		/* mask of saved fp registers */
427169689Skan  HOST_WIDE_INT gp_save_offset;	/* offset from vfp to store gp registers */
428169689Skan  HOST_WIDE_INT fp_save_offset;	/* offset from vfp to store fp registers */
429169689Skan  HOST_WIDE_INT gp_sp_offset;	/* offset from new sp to store gp registers */
430169689Skan  HOST_WIDE_INT fp_sp_offset;	/* offset from new sp to store fp registers */
431169689Skan  bool initialized;		/* true if frame size already calculated */
432169689Skan  int num_gp;			/* number of gp registers saved */
433169689Skan  int num_fp;			/* number of fp registers saved */
434169689Skan};
435169689Skan
436169689Skanstruct machine_function GTY(()) {
437169689Skan  /* Pseudo-reg holding the value of $28 in a mips16 function which
438169689Skan     refers to GP relative global variables.  */
439169689Skan  rtx mips16_gp_pseudo_rtx;
440169689Skan
441169689Skan  /* The number of extra stack bytes taken up by register varargs.
442169689Skan     This area is allocated by the callee at the very top of the frame.  */
443169689Skan  int varargs_size;
444169689Skan
445169689Skan  /* Current frame information, calculated by compute_frame_size.  */
446169689Skan  struct mips_frame_info frame;
447169689Skan
448169689Skan  /* The register to use as the global pointer within this function.  */
449169689Skan  unsigned int global_pointer;
450169689Skan
451169689Skan  /* True if mips_adjust_insn_length should ignore an instruction's
452169689Skan     hazard attribute.  */
453169689Skan  bool ignore_hazard_length_p;
454169689Skan
455169689Skan  /* True if the whole function is suitable for .set noreorder and
456169689Skan     .set nomacro.  */
457169689Skan  bool all_noreorder_p;
458169689Skan
459169689Skan  /* True if the function is known to have an instruction that needs $gp.  */
460169689Skan  bool has_gp_insn_p;
461169689Skan};
462169689Skan
463169689Skan/* Information about a single argument.  */
464169689Skanstruct mips_arg_info
465169689Skan{
466169689Skan  /* True if the argument is passed in a floating-point register, or
467169689Skan     would have been if we hadn't run out of registers.  */
468169689Skan  bool fpr_p;
469169689Skan
470169689Skan  /* The number of words passed in registers, rounded up.  */
471169689Skan  unsigned int reg_words;
472169689Skan
473169689Skan  /* For EABI, the offset of the first register from GP_ARG_FIRST or
474169689Skan     FP_ARG_FIRST.  For other ABIs, the offset of the first register from
475169689Skan     the start of the ABI's argument structure (see the CUMULATIVE_ARGS
476169689Skan     comment for details).
477169689Skan
478169689Skan     The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely
479169689Skan     on the stack.  */
480169689Skan  unsigned int reg_offset;
481169689Skan
482169689Skan  /* The number of words that must be passed on the stack, rounded up.  */
483169689Skan  unsigned int stack_words;
484169689Skan
485169689Skan  /* The offset from the start of the stack overflow area of the argument's
486169689Skan     first stack word.  Only meaningful when STACK_WORDS is nonzero.  */
487169689Skan  unsigned int stack_offset;
488169689Skan};
489169689Skan
490169689Skan
491169689Skan/* Information about an address described by mips_address_type.
492169689Skan
493169689Skan   ADDRESS_CONST_INT
494169689Skan       No fields are used.
495169689Skan
496169689Skan   ADDRESS_REG
497169689Skan       REG is the base register and OFFSET is the constant offset.
498169689Skan
499169689Skan   ADDRESS_LO_SUM
500169689Skan       REG is the register that contains the high part of the address,
501169689Skan       OFFSET is the symbolic address being referenced and SYMBOL_TYPE
502169689Skan       is the type of OFFSET's symbol.
503169689Skan
504169689Skan   ADDRESS_SYMBOLIC
505169689Skan       SYMBOL_TYPE is the type of symbol being referenced.  */
506169689Skan
507169689Skanstruct mips_address_info
508169689Skan{
509169689Skan  enum mips_address_type type;
510169689Skan  rtx reg;
511169689Skan  rtx offset;
512169689Skan  enum mips_symbol_type symbol_type;
513169689Skan};
514169689Skan
515169689Skan
516169689Skan/* One stage in a constant building sequence.  These sequences have
517169689Skan   the form:
518169689Skan
519169689Skan	A = VALUE[0]
520169689Skan	A = A CODE[1] VALUE[1]
521169689Skan	A = A CODE[2] VALUE[2]
522169689Skan	...
523169689Skan
524169689Skan   where A is an accumulator, each CODE[i] is a binary rtl operation
525169689Skan   and each VALUE[i] is a constant integer.  */
526169689Skanstruct mips_integer_op {
527169689Skan  enum rtx_code code;
528169689Skan  unsigned HOST_WIDE_INT value;
529169689Skan};
530169689Skan
531169689Skan
532169689Skan/* The largest number of operations needed to load an integer constant.
533169689Skan   The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.
534169689Skan   When the lowest bit is clear, we can try, but reject a sequence with
535169689Skan   an extra SLL at the end.  */
536169689Skan#define MIPS_MAX_INTEGER_OPS 7
537169689Skan
538169689Skan
539169689Skan/* Global variables for machine-dependent things.  */
540169689Skan
541169689Skan/* Threshold for data being put into the small data/bss area, instead
542169689Skan   of the normal data area.  */
543169689Skanint mips_section_threshold = -1;
544169689Skan
545169689Skan/* Count the number of .file directives, so that .loc is up to date.  */
546169689Skanint num_source_filenames = 0;
547169689Skan
548169689Skan/* Count the number of sdb related labels are generated (to find block
549169689Skan   start and end boundaries).  */
550169689Skanint sdb_label_count = 0;
551169689Skan
552169689Skan/* Next label # for each statement for Silicon Graphics IRIS systems.  */
553169689Skanint sym_lineno = 0;
554169689Skan
555169689Skan/* Linked list of all externals that are to be emitted when optimizing
556169689Skan   for the global pointer if they haven't been declared by the end of
557169689Skan   the program with an appropriate .comm or initialization.  */
558169689Skan
559169689Skanstruct extern_list GTY (())
560169689Skan{
561169689Skan  struct extern_list *next;	/* next external */
562169689Skan  const char *name;		/* name of the external */
563169689Skan  int size;			/* size in bytes */
564169689Skan};
565169689Skan
566169689Skanstatic GTY (()) struct extern_list *extern_head = 0;
567169689Skan
568169689Skan/* Name of the file containing the current function.  */
569169689Skanconst char *current_function_file = "";
570169689Skan
571169689Skan/* Number of nested .set noreorder, noat, nomacro, and volatile requests.  */
572169689Skanint set_noreorder;
573169689Skanint set_noat;
574169689Skanint set_nomacro;
575169689Skanint set_volatile;
576169689Skan
577169689Skan/* The next branch instruction is a branch likely, not branch normal.  */
578169689Skanint mips_branch_likely;
579169689Skan
580169689Skan/* The operands passed to the last cmpMM expander.  */
581169689Skanrtx cmp_operands[2];
582169689Skan
583169689Skan/* The target cpu for code generation.  */
584169689Skanenum processor_type mips_arch;
585169689Skanconst struct mips_cpu_info *mips_arch_info;
586169689Skan
587169689Skan/* The target cpu for optimization and scheduling.  */
588169689Skanenum processor_type mips_tune;
589169689Skanconst struct mips_cpu_info *mips_tune_info;
590169689Skan
591169689Skan/* Which instruction set architecture to use.  */
592169689Skanint mips_isa;
593169689Skan
594169689Skan/* Which ABI to use.  */
595169689Skanint mips_abi = MIPS_ABI_DEFAULT;
596169689Skan
597169689Skan/* Cost information to use.  */
598169689Skanconst struct mips_rtx_cost_data *mips_cost;
599169689Skan
600169689Skan/* Whether we are generating mips16 hard float code.  In mips16 mode
601169689Skan   we always set TARGET_SOFT_FLOAT; this variable is nonzero if
602169689Skan   -msoft-float was not specified by the user, which means that we
603169689Skan   should arrange to call mips32 hard floating point code.  */
604169689Skanint mips16_hard_float;
605169689Skan
606169689Skan/* The architecture selected by -mipsN.  */
607169689Skanstatic const struct mips_cpu_info *mips_isa_info;
608169689Skan
609169689Skan/* If TRUE, we split addresses into their high and low parts in the RTL.  */
610169689Skanint mips_split_addresses;
611169689Skan
612169689Skan/* Mode used for saving/restoring general purpose registers.  */
613169689Skanstatic enum machine_mode gpr_mode;
614169689Skan
615169689Skan/* Array giving truth value on whether or not a given hard register
616169689Skan   can support a given mode.  */
617169689Skanchar mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
618169689Skan
619169689Skan/* List of all MIPS punctuation characters used by print_operand.  */
620169689Skanchar mips_print_operand_punct[256];
621169689Skan
622169689Skan/* Map GCC register number to debugger register number.  */
623169689Skanint mips_dbx_regno[FIRST_PSEUDO_REGISTER];
624169689Skan
625169689Skan/* A copy of the original flag_delayed_branch: see override_options.  */
626169689Skanstatic int mips_flag_delayed_branch;
627169689Skan
628169689Skanstatic GTY (()) int mips_output_filename_first_time = 1;
629169689Skan
630169689Skan/* mips_split_p[X] is true if symbols of type X can be split by
631169689Skan   mips_split_symbol().  */
632169689Skanbool mips_split_p[NUM_SYMBOL_TYPES];
633169689Skan
634169689Skan/* mips_lo_relocs[X] is the relocation to use when a symbol of type X
635169689Skan   appears in a LO_SUM.  It can be null if such LO_SUMs aren't valid or
636169689Skan   if they are matched by a special .md file pattern.  */
637169689Skanstatic const char *mips_lo_relocs[NUM_SYMBOL_TYPES];
638169689Skan
639169689Skan/* Likewise for HIGHs.  */
640169689Skanstatic const char *mips_hi_relocs[NUM_SYMBOL_TYPES];
641169689Skan
642169689Skan/* Map hard register number to register class */
643169689Skanconst enum reg_class mips_regno_to_class[] =
644169689Skan{
645169689Skan  LEA_REGS,	LEA_REGS,	M16_NA_REGS,	V1_REG,
646169689Skan  M16_REGS,	M16_REGS,	M16_REGS,	M16_REGS,
647169689Skan  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,
648169689Skan  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,
649169689Skan  M16_NA_REGS,	M16_NA_REGS,	LEA_REGS,	LEA_REGS,
650169689Skan  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,
651169689Skan  T_REG,	PIC_FN_ADDR_REG, LEA_REGS,	LEA_REGS,
652169689Skan  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,
653169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
654169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
655169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
656169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
657169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
658169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
659169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
660169689Skan  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
661169689Skan  HI_REG,	LO_REG,		NO_REGS,	ST_REGS,
662169689Skan  ST_REGS,	ST_REGS,	ST_REGS,	ST_REGS,
663169689Skan  ST_REGS,	ST_REGS,	ST_REGS,	NO_REGS,
664169689Skan  NO_REGS,	ALL_REGS,	ALL_REGS,	NO_REGS,
665169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
666169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
667169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
668169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
669169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
670169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
671169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
672169689Skan  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,
673169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
674169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
675169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
676169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
677169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
678169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
679169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
680169689Skan  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,
681169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
682169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
683169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
684169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
685169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
686169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
687169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
688169689Skan  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,
689169689Skan  DSP_ACC_REGS,	DSP_ACC_REGS,	DSP_ACC_REGS,	DSP_ACC_REGS,
690169689Skan  DSP_ACC_REGS,	DSP_ACC_REGS,	ALL_REGS,	ALL_REGS,
691169689Skan  ALL_REGS,	ALL_REGS,	ALL_REGS,	ALL_REGS
692169689Skan};
693169689Skan
694169689Skan/* Table of machine dependent attributes.  */
695169689Skanconst struct attribute_spec mips_attribute_table[] =
696169689Skan{
697169689Skan  { "long_call",   0, 0, false, true,  true,  NULL },
698169689Skan  { NULL,	   0, 0, false, false, false, NULL }
699169689Skan};
700169689Skan
701169689Skan/* A table describing all the processors gcc knows about.  Names are
702169689Skan   matched in the order listed.  The first mention of an ISA level is
703169689Skan   taken as the canonical name for that ISA.
704169689Skan
705169689Skan   To ease comparison, please keep this table in the same order as
706169689Skan   gas's mips_cpu_info_table[].  */
707169689Skanconst struct mips_cpu_info mips_cpu_info_table[] = {
708169689Skan  /* Entries for generic ISAs */
709169689Skan  { "mips1", PROCESSOR_R3000, 1 },
710169689Skan  { "mips2", PROCESSOR_R6000, 2 },
711169689Skan  { "mips3", PROCESSOR_R4000, 3 },
712169689Skan  { "mips4", PROCESSOR_R8000, 4 },
713169689Skan  { "mips32", PROCESSOR_4KC, 32 },
714169689Skan  { "mips32r2", PROCESSOR_M4K, 33 },
715169689Skan  { "mips64", PROCESSOR_5KC, 64 },
716208737Sjmallett  { "mips64r2", PROCESSOR_5KC, 65 },
717169689Skan
718169689Skan  /* MIPS I */
719169689Skan  { "r3000", PROCESSOR_R3000, 1 },
720169689Skan  { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */
721169689Skan  { "r3900", PROCESSOR_R3900, 1 },
722169689Skan
723169689Skan  /* MIPS II */
724169689Skan  { "r6000", PROCESSOR_R6000, 2 },
725169689Skan
726169689Skan  /* MIPS III */
727169689Skan  { "r4000", PROCESSOR_R4000, 3 },
728169689Skan  { "vr4100", PROCESSOR_R4100, 3 },
729169689Skan  { "vr4111", PROCESSOR_R4111, 3 },
730169689Skan  { "vr4120", PROCESSOR_R4120, 3 },
731169689Skan  { "vr4130", PROCESSOR_R4130, 3 },
732169689Skan  { "vr4300", PROCESSOR_R4300, 3 },
733169689Skan  { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */
734169689Skan  { "r4600", PROCESSOR_R4600, 3 },
735169689Skan  { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */
736169689Skan  { "r4650", PROCESSOR_R4650, 3 },
737169689Skan
738169689Skan  /* MIPS IV */
739169689Skan  { "r8000", PROCESSOR_R8000, 4 },
740169689Skan  { "vr5000", PROCESSOR_R5000, 4 },
741169689Skan  { "vr5400", PROCESSOR_R5400, 4 },
742169689Skan  { "vr5500", PROCESSOR_R5500, 4 },
743169689Skan  { "rm7000", PROCESSOR_R7000, 4 },
744169689Skan  { "rm9000", PROCESSOR_R9000, 4 },
745169689Skan
746169689Skan  /* MIPS32 */
747169689Skan  { "4kc", PROCESSOR_4KC, 32 },
748169689Skan  { "4km", PROCESSOR_4KC, 32 }, /* = 4kc */
749169689Skan  { "4kp", PROCESSOR_4KP, 32 },
750169689Skan
751169689Skan  /* MIPS32 Release 2 */
752169689Skan  { "m4k", PROCESSOR_M4K, 33 },
753169689Skan  { "24k", PROCESSOR_24K, 33 },
754169689Skan  { "24kc", PROCESSOR_24K, 33 },  /* 24K  no FPU */
755169689Skan  { "24kf", PROCESSOR_24K, 33 },  /* 24K 1:2 FPU */
756169689Skan  { "24kx", PROCESSOR_24KX, 33 }, /* 24K 1:1 FPU */
757169689Skan
758169689Skan  /* MIPS64 */
759169689Skan  { "5kc", PROCESSOR_5KC, 64 },
760169689Skan  { "5kf", PROCESSOR_5KF, 64 },
761169689Skan  { "20kc", PROCESSOR_20KC, 64 },
762169689Skan  { "sb1", PROCESSOR_SB1, 64 },
763169689Skan  { "sb1a", PROCESSOR_SB1A, 64 },
764169689Skan  { "sr71000", PROCESSOR_SR71000, 64 },
765169689Skan
766208737Sjmallett  /* MIPS64R2 */
767208737Sjmallett  { "octeon", PROCESSOR_OCTEON, 65 },
768208737Sjmallett
769169689Skan  /* End marker */
770169689Skan  { 0, 0, 0 }
771169689Skan};
772169689Skan
773169689Skan/* Default costs. If these are used for a processor we should look
774169689Skan   up the actual costs.  */
775169689Skan#define DEFAULT_COSTS COSTS_N_INSNS (6),  /* fp_add */       \
776169689Skan                      COSTS_N_INSNS (7),  /* fp_mult_sf */   \
777169689Skan                      COSTS_N_INSNS (8),  /* fp_mult_df */   \
778169689Skan                      COSTS_N_INSNS (23), /* fp_div_sf */    \
779169689Skan                      COSTS_N_INSNS (36), /* fp_div_df */    \
780169689Skan                      COSTS_N_INSNS (10), /* int_mult_si */  \
781169689Skan                      COSTS_N_INSNS (10), /* int_mult_di */  \
782169689Skan                      COSTS_N_INSNS (69), /* int_div_si */   \
783169689Skan                      COSTS_N_INSNS (69), /* int_div_di */   \
784169689Skan                                       2, /* branch_cost */  \
785169689Skan                                       4  /* memory_latency */
786169689Skan
787169689Skan/* Need to replace these with the costs of calling the appropriate
788169689Skan   libgcc routine.  */
789169689Skan#define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */       \
790169689Skan                      COSTS_N_INSNS (256), /* fp_mult_sf */   \
791169689Skan                      COSTS_N_INSNS (256), /* fp_mult_df */   \
792169689Skan                      COSTS_N_INSNS (256), /* fp_div_sf */    \
793169689Skan                      COSTS_N_INSNS (256)  /* fp_div_df */
794169689Skan
795169689Skanstatic struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
796169689Skan  {
797169689Skan    { /* R3000 */
798169689Skan      COSTS_N_INSNS (2),            /* fp_add */
799169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
800169689Skan      COSTS_N_INSNS (5),            /* fp_mult_df */
801169689Skan      COSTS_N_INSNS (12),           /* fp_div_sf */
802169689Skan      COSTS_N_INSNS (19),           /* fp_div_df */
803169689Skan      COSTS_N_INSNS (12),           /* int_mult_si */
804169689Skan      COSTS_N_INSNS (12),           /* int_mult_di */
805169689Skan      COSTS_N_INSNS (35),           /* int_div_si */
806169689Skan      COSTS_N_INSNS (35),           /* int_div_di */
807169689Skan                       1,           /* branch_cost */
808169689Skan                       4            /* memory_latency */
809169689Skan
810169689Skan    },
811169689Skan    { /* 4KC */
812169689Skan      SOFT_FP_COSTS,
813169689Skan      COSTS_N_INSNS (6),            /* int_mult_si */
814169689Skan      COSTS_N_INSNS (6),            /* int_mult_di */
815169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
816169689Skan      COSTS_N_INSNS (36),           /* int_div_di */
817169689Skan                       1,           /* branch_cost */
818169689Skan                       4            /* memory_latency */
819169689Skan    },
820169689Skan    { /* 4KP */
821169689Skan      SOFT_FP_COSTS,
822169689Skan      COSTS_N_INSNS (36),           /* int_mult_si */
823169689Skan      COSTS_N_INSNS (36),           /* int_mult_di */
824169689Skan      COSTS_N_INSNS (37),           /* int_div_si */
825169689Skan      COSTS_N_INSNS (37),           /* int_div_di */
826169689Skan                       1,           /* branch_cost */
827169689Skan                       4            /* memory_latency */
828169689Skan    },
829169689Skan    { /* 5KC */
830169689Skan      SOFT_FP_COSTS,
831169689Skan      COSTS_N_INSNS (4),            /* int_mult_si */
832169689Skan      COSTS_N_INSNS (11),           /* int_mult_di */
833169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
834169689Skan      COSTS_N_INSNS (68),           /* int_div_di */
835169689Skan                       1,           /* branch_cost */
836169689Skan                       4            /* memory_latency */
837169689Skan    },
838169689Skan    { /* 5KF */
839169689Skan      COSTS_N_INSNS (4),            /* fp_add */
840169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
841169689Skan      COSTS_N_INSNS (5),            /* fp_mult_df */
842169689Skan      COSTS_N_INSNS (17),           /* fp_div_sf */
843169689Skan      COSTS_N_INSNS (32),           /* fp_div_df */
844169689Skan      COSTS_N_INSNS (4),            /* int_mult_si */
845169689Skan      COSTS_N_INSNS (11),           /* int_mult_di */
846169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
847169689Skan      COSTS_N_INSNS (68),           /* int_div_di */
848169689Skan                       1,           /* branch_cost */
849169689Skan                       4            /* memory_latency */
850169689Skan    },
851169689Skan    { /* 20KC */
852169689Skan      DEFAULT_COSTS
853169689Skan    },
854169689Skan    { /* 24k */
855169689Skan      COSTS_N_INSNS (8),            /* fp_add */
856169689Skan      COSTS_N_INSNS (8),            /* fp_mult_sf */
857169689Skan      COSTS_N_INSNS (10),           /* fp_mult_df */
858169689Skan      COSTS_N_INSNS (34),           /* fp_div_sf */
859169689Skan      COSTS_N_INSNS (64),           /* fp_div_df */
860169689Skan      COSTS_N_INSNS (5),            /* int_mult_si */
861169689Skan      COSTS_N_INSNS (5),            /* int_mult_di */
862169689Skan      COSTS_N_INSNS (41),           /* int_div_si */
863169689Skan      COSTS_N_INSNS (41),           /* int_div_di */
864169689Skan                       1,           /* branch_cost */
865169689Skan                       4            /* memory_latency */
866169689Skan    },
867169689Skan    { /* 24kx */
868169689Skan      COSTS_N_INSNS (4),            /* fp_add */
869169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
870169689Skan      COSTS_N_INSNS (5),            /* fp_mult_df */
871169689Skan      COSTS_N_INSNS (17),           /* fp_div_sf */
872169689Skan      COSTS_N_INSNS (32),           /* fp_div_df */
873169689Skan      COSTS_N_INSNS (5),            /* int_mult_si */
874169689Skan      COSTS_N_INSNS (5),            /* int_mult_di */
875169689Skan      COSTS_N_INSNS (41),           /* int_div_si */
876169689Skan      COSTS_N_INSNS (41),           /* int_div_di */
877169689Skan                       1,           /* branch_cost */
878169689Skan                       4            /* memory_latency */
879169689Skan    },
880169689Skan    { /* M4k */
881169689Skan      DEFAULT_COSTS
882169689Skan    },
883169689Skan    { /* R3900 */
884169689Skan      COSTS_N_INSNS (2),            /* fp_add */
885169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
886169689Skan      COSTS_N_INSNS (5),            /* fp_mult_df */
887169689Skan      COSTS_N_INSNS (12),           /* fp_div_sf */
888169689Skan      COSTS_N_INSNS (19),           /* fp_div_df */
889169689Skan      COSTS_N_INSNS (2),            /* int_mult_si */
890169689Skan      COSTS_N_INSNS (2),            /* int_mult_di */
891169689Skan      COSTS_N_INSNS (35),           /* int_div_si */
892169689Skan      COSTS_N_INSNS (35),           /* int_div_di */
893169689Skan                       1,           /* branch_cost */
894169689Skan                       4            /* memory_latency */
895169689Skan    },
896169689Skan    { /* R6000 */
897169689Skan      COSTS_N_INSNS (3),            /* fp_add */
898169689Skan      COSTS_N_INSNS (5),            /* fp_mult_sf */
899169689Skan      COSTS_N_INSNS (6),            /* fp_mult_df */
900169689Skan      COSTS_N_INSNS (15),           /* fp_div_sf */
901169689Skan      COSTS_N_INSNS (16),           /* fp_div_df */
902169689Skan      COSTS_N_INSNS (17),           /* int_mult_si */
903169689Skan      COSTS_N_INSNS (17),           /* int_mult_di */
904169689Skan      COSTS_N_INSNS (38),           /* int_div_si */
905169689Skan      COSTS_N_INSNS (38),           /* int_div_di */
906169689Skan                       2,           /* branch_cost */
907169689Skan                       6            /* memory_latency */
908169689Skan    },
909169689Skan    { /* R4000 */
910169689Skan       COSTS_N_INSNS (6),           /* fp_add */
911169689Skan       COSTS_N_INSNS (7),           /* fp_mult_sf */
912169689Skan       COSTS_N_INSNS (8),           /* fp_mult_df */
913169689Skan       COSTS_N_INSNS (23),          /* fp_div_sf */
914169689Skan       COSTS_N_INSNS (36),          /* fp_div_df */
915169689Skan       COSTS_N_INSNS (10),          /* int_mult_si */
916169689Skan       COSTS_N_INSNS (10),          /* int_mult_di */
917169689Skan       COSTS_N_INSNS (69),          /* int_div_si */
918169689Skan       COSTS_N_INSNS (69),          /* int_div_di */
919169689Skan                        2,          /* branch_cost */
920169689Skan                        6           /* memory_latency */
921169689Skan    },
922169689Skan    { /* R4100 */
923169689Skan      DEFAULT_COSTS
924169689Skan    },
925169689Skan    { /* R4111 */
926169689Skan      DEFAULT_COSTS
927169689Skan    },
928169689Skan    { /* R4120 */
929169689Skan      DEFAULT_COSTS
930169689Skan    },
931169689Skan    { /* R4130 */
932169689Skan      /* The only costs that appear to be updated here are
933169689Skan	 integer multiplication.  */
934169689Skan      SOFT_FP_COSTS,
935169689Skan      COSTS_N_INSNS (4),            /* int_mult_si */
936169689Skan      COSTS_N_INSNS (6),            /* int_mult_di */
937169689Skan      COSTS_N_INSNS (69),           /* int_div_si */
938169689Skan      COSTS_N_INSNS (69),           /* int_div_di */
939169689Skan                       1,           /* branch_cost */
940169689Skan                       4            /* memory_latency */
941169689Skan    },
942169689Skan    { /* R4300 */
943169689Skan      DEFAULT_COSTS
944169689Skan    },
945169689Skan    { /* R4600 */
946169689Skan      DEFAULT_COSTS
947169689Skan    },
948169689Skan    { /* R4650 */
949169689Skan      DEFAULT_COSTS
950169689Skan    },
951169689Skan    { /* R5000 */
952169689Skan      COSTS_N_INSNS (6),            /* fp_add */
953169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
954169689Skan      COSTS_N_INSNS (5),            /* fp_mult_df */
955169689Skan      COSTS_N_INSNS (23),           /* fp_div_sf */
956169689Skan      COSTS_N_INSNS (36),           /* fp_div_df */
957169689Skan      COSTS_N_INSNS (5),            /* int_mult_si */
958169689Skan      COSTS_N_INSNS (5),            /* int_mult_di */
959169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
960169689Skan      COSTS_N_INSNS (36),           /* int_div_di */
961169689Skan                       1,           /* branch_cost */
962169689Skan                       4            /* memory_latency */
963169689Skan    },
964169689Skan    { /* R5400 */
965169689Skan      COSTS_N_INSNS (6),            /* fp_add */
966169689Skan      COSTS_N_INSNS (5),            /* fp_mult_sf */
967169689Skan      COSTS_N_INSNS (6),            /* fp_mult_df */
968169689Skan      COSTS_N_INSNS (30),           /* fp_div_sf */
969169689Skan      COSTS_N_INSNS (59),           /* fp_div_df */
970169689Skan      COSTS_N_INSNS (3),            /* int_mult_si */
971169689Skan      COSTS_N_INSNS (4),            /* int_mult_di */
972169689Skan      COSTS_N_INSNS (42),           /* int_div_si */
973169689Skan      COSTS_N_INSNS (74),           /* int_div_di */
974169689Skan                       1,           /* branch_cost */
975169689Skan                       4            /* memory_latency */
976169689Skan    },
977169689Skan    { /* R5500 */
978169689Skan      COSTS_N_INSNS (6),            /* fp_add */
979169689Skan      COSTS_N_INSNS (5),            /* fp_mult_sf */
980169689Skan      COSTS_N_INSNS (6),            /* fp_mult_df */
981169689Skan      COSTS_N_INSNS (30),           /* fp_div_sf */
982169689Skan      COSTS_N_INSNS (59),           /* fp_div_df */
983169689Skan      COSTS_N_INSNS (5),            /* int_mult_si */
984169689Skan      COSTS_N_INSNS (9),            /* int_mult_di */
985169689Skan      COSTS_N_INSNS (42),           /* int_div_si */
986169689Skan      COSTS_N_INSNS (74),           /* int_div_di */
987169689Skan                       1,           /* branch_cost */
988169689Skan                       4            /* memory_latency */
989169689Skan    },
990169689Skan    { /* R7000 */
991169689Skan      /* The only costs that are changed here are
992169689Skan	 integer multiplication.  */
993169689Skan      COSTS_N_INSNS (6),            /* fp_add */
994169689Skan      COSTS_N_INSNS (7),            /* fp_mult_sf */
995169689Skan      COSTS_N_INSNS (8),            /* fp_mult_df */
996169689Skan      COSTS_N_INSNS (23),           /* fp_div_sf */
997169689Skan      COSTS_N_INSNS (36),           /* fp_div_df */
998169689Skan      COSTS_N_INSNS (5),            /* int_mult_si */
999169689Skan      COSTS_N_INSNS (9),            /* int_mult_di */
1000169689Skan      COSTS_N_INSNS (69),           /* int_div_si */
1001169689Skan      COSTS_N_INSNS (69),           /* int_div_di */
1002169689Skan                       1,           /* branch_cost */
1003169689Skan                       4            /* memory_latency */
1004169689Skan    },
1005169689Skan    { /* R8000 */
1006169689Skan      DEFAULT_COSTS
1007169689Skan    },
1008169689Skan    { /* R9000 */
1009169689Skan      /* The only costs that are changed here are
1010169689Skan	 integer multiplication.  */
1011169689Skan      COSTS_N_INSNS (6),            /* fp_add */
1012169689Skan      COSTS_N_INSNS (7),            /* fp_mult_sf */
1013169689Skan      COSTS_N_INSNS (8),            /* fp_mult_df */
1014169689Skan      COSTS_N_INSNS (23),           /* fp_div_sf */
1015169689Skan      COSTS_N_INSNS (36),           /* fp_div_df */
1016169689Skan      COSTS_N_INSNS (3),            /* int_mult_si */
1017169689Skan      COSTS_N_INSNS (8),            /* int_mult_di */
1018169689Skan      COSTS_N_INSNS (69),           /* int_div_si */
1019169689Skan      COSTS_N_INSNS (69),           /* int_div_di */
1020169689Skan                       1,           /* branch_cost */
1021169689Skan                       4            /* memory_latency */
1022169689Skan    },
1023169689Skan    { /* SB1 */
1024169689Skan      /* These costs are the same as the SB-1A below.  */
1025169689Skan      COSTS_N_INSNS (4),            /* fp_add */
1026169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
1027169689Skan      COSTS_N_INSNS (4),            /* fp_mult_df */
1028169689Skan      COSTS_N_INSNS (24),           /* fp_div_sf */
1029169689Skan      COSTS_N_INSNS (32),           /* fp_div_df */
1030169689Skan      COSTS_N_INSNS (3),            /* int_mult_si */
1031169689Skan      COSTS_N_INSNS (4),            /* int_mult_di */
1032169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
1033169689Skan      COSTS_N_INSNS (68),           /* int_div_di */
1034169689Skan                       1,           /* branch_cost */
1035169689Skan                       4            /* memory_latency */
1036169689Skan    },
1037169689Skan    { /* SB1-A */
1038169689Skan      /* These costs are the same as the SB-1 above.  */
1039169689Skan      COSTS_N_INSNS (4),            /* fp_add */
1040169689Skan      COSTS_N_INSNS (4),            /* fp_mult_sf */
1041169689Skan      COSTS_N_INSNS (4),            /* fp_mult_df */
1042169689Skan      COSTS_N_INSNS (24),           /* fp_div_sf */
1043169689Skan      COSTS_N_INSNS (32),           /* fp_div_df */
1044169689Skan      COSTS_N_INSNS (3),            /* int_mult_si */
1045169689Skan      COSTS_N_INSNS (4),            /* int_mult_di */
1046169689Skan      COSTS_N_INSNS (36),           /* int_div_si */
1047169689Skan      COSTS_N_INSNS (68),           /* int_div_di */
1048169689Skan                       1,           /* branch_cost */
1049169689Skan                       4            /* memory_latency */
1050169689Skan    },
1051169689Skan    { /* SR71000 */
1052169689Skan      DEFAULT_COSTS
1053169689Skan    },
1054169689Skan  };
1055169689Skan
1056169689Skan
1057169689Skan/* Nonzero if -march should decide the default value of MASK_SOFT_FLOAT.  */
1058169689Skan#ifndef MIPS_MARCH_CONTROLS_SOFT_FLOAT
1059169689Skan#define MIPS_MARCH_CONTROLS_SOFT_FLOAT 0
1060169689Skan#endif
1061169689Skan
1062169689Skan/* Initialize the GCC target structure.  */
1063169689Skan#undef TARGET_ASM_ALIGNED_HI_OP
1064169689Skan#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
1065169689Skan#undef TARGET_ASM_ALIGNED_SI_OP
1066169689Skan#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
1067169689Skan#undef TARGET_ASM_ALIGNED_DI_OP
1068169689Skan#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
1069169689Skan
1070169689Skan#undef TARGET_ASM_FUNCTION_PROLOGUE
1071169689Skan#define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
1072169689Skan#undef TARGET_ASM_FUNCTION_EPILOGUE
1073169689Skan#define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
1074169689Skan#undef TARGET_ASM_SELECT_RTX_SECTION
1075169689Skan#define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
1076169689Skan#undef TARGET_ASM_FUNCTION_RODATA_SECTION
1077169689Skan#define TARGET_ASM_FUNCTION_RODATA_SECTION mips_function_rodata_section
1078169689Skan
1079169689Skan#undef TARGET_SCHED_REORDER
1080169689Skan#define TARGET_SCHED_REORDER mips_sched_reorder
1081169689Skan#undef TARGET_SCHED_VARIABLE_ISSUE
1082169689Skan#define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
1083169689Skan#undef TARGET_SCHED_ADJUST_COST
1084169689Skan#define TARGET_SCHED_ADJUST_COST mips_adjust_cost
1085169689Skan#undef TARGET_SCHED_ISSUE_RATE
1086169689Skan#define TARGET_SCHED_ISSUE_RATE mips_issue_rate
1087169689Skan#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1088169689Skan#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
1089169689Skan  mips_multipass_dfa_lookahead
1090169689Skan
1091169689Skan#undef TARGET_DEFAULT_TARGET_FLAGS
1092169689Skan#define TARGET_DEFAULT_TARGET_FLAGS		\
1093169689Skan  (TARGET_DEFAULT				\
1094169689Skan   | TARGET_CPU_DEFAULT				\
1095169689Skan   | TARGET_ENDIAN_DEFAULT			\
1096169689Skan   | TARGET_FP_EXCEPTIONS_DEFAULT		\
1097169689Skan   | MASK_CHECK_ZERO_DIV			\
1098169689Skan   | MASK_FUSED_MADD)
1099169689Skan#undef TARGET_HANDLE_OPTION
1100169689Skan#define TARGET_HANDLE_OPTION mips_handle_option
1101169689Skan
1102169689Skan#undef TARGET_FUNCTION_OK_FOR_SIBCALL
1103169689Skan#define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
1104169689Skan
1105169689Skan#undef TARGET_VALID_POINTER_MODE
1106169689Skan#define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
1107169689Skan#undef TARGET_RTX_COSTS
1108169689Skan#define TARGET_RTX_COSTS mips_rtx_costs
1109169689Skan#undef TARGET_ADDRESS_COST
1110169689Skan#define TARGET_ADDRESS_COST mips_address_cost
1111169689Skan
1112169689Skan#undef TARGET_IN_SMALL_DATA_P
1113169689Skan#define TARGET_IN_SMALL_DATA_P mips_in_small_data_p
1114169689Skan
1115169689Skan#undef TARGET_MACHINE_DEPENDENT_REORG
1116169689Skan#define TARGET_MACHINE_DEPENDENT_REORG mips_reorg
1117169689Skan
1118169689Skan#undef TARGET_ASM_FILE_START
1119169689Skan#undef TARGET_ASM_FILE_END
1120169689Skan#define TARGET_ASM_FILE_START mips_file_start
1121169689Skan#define TARGET_ASM_FILE_END mips_file_end
1122169689Skan#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
1123169689Skan#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
1124169689Skan
1125169689Skan#undef TARGET_INIT_LIBFUNCS
1126169689Skan#define TARGET_INIT_LIBFUNCS mips_init_libfuncs
1127169689Skan
1128169689Skan#undef TARGET_BUILD_BUILTIN_VA_LIST
1129169689Skan#define TARGET_BUILD_BUILTIN_VA_LIST mips_build_builtin_va_list
1130169689Skan#undef TARGET_GIMPLIFY_VA_ARG_EXPR
1131169689Skan#define TARGET_GIMPLIFY_VA_ARG_EXPR mips_gimplify_va_arg_expr
1132169689Skan
1133169689Skan#undef TARGET_PROMOTE_FUNCTION_ARGS
1134169689Skan#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
1135169689Skan#undef TARGET_PROMOTE_FUNCTION_RETURN
1136169689Skan#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
1137169689Skan#undef TARGET_PROMOTE_PROTOTYPES
1138169689Skan#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
1139169689Skan
1140169689Skan#undef TARGET_RETURN_IN_MEMORY
1141169689Skan#define TARGET_RETURN_IN_MEMORY mips_return_in_memory
1142169689Skan#undef TARGET_RETURN_IN_MSB
1143169689Skan#define TARGET_RETURN_IN_MSB mips_return_in_msb
1144169689Skan
1145169689Skan#undef TARGET_ASM_OUTPUT_MI_THUNK
1146169689Skan#define TARGET_ASM_OUTPUT_MI_THUNK mips_output_mi_thunk
1147169689Skan#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1148169689Skan#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
1149169689Skan
1150169689Skan#undef TARGET_SETUP_INCOMING_VARARGS
1151169689Skan#define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
1152169689Skan#undef TARGET_STRICT_ARGUMENT_NAMING
1153169689Skan#define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
1154169689Skan#undef TARGET_MUST_PASS_IN_STACK
1155169689Skan#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
1156169689Skan#undef TARGET_PASS_BY_REFERENCE
1157169689Skan#define TARGET_PASS_BY_REFERENCE mips_pass_by_reference
1158169689Skan#undef TARGET_CALLEE_COPIES
1159169689Skan#define TARGET_CALLEE_COPIES mips_callee_copies
1160169689Skan#undef TARGET_ARG_PARTIAL_BYTES
1161169689Skan#define TARGET_ARG_PARTIAL_BYTES mips_arg_partial_bytes
1162169689Skan
1163169689Skan#undef TARGET_MODE_REP_EXTENDED
1164169689Skan#define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
1165169689Skan
1166169689Skan#undef TARGET_VECTOR_MODE_SUPPORTED_P
1167169689Skan#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
1168169689Skan
1169169689Skan#undef TARGET_INIT_BUILTINS
1170169689Skan#define TARGET_INIT_BUILTINS mips_init_builtins
1171169689Skan#undef TARGET_EXPAND_BUILTIN
1172169689Skan#define TARGET_EXPAND_BUILTIN mips_expand_builtin
1173169689Skan
1174169689Skan#undef TARGET_HAVE_TLS
1175169689Skan#define TARGET_HAVE_TLS HAVE_AS_TLS
1176169689Skan
1177169689Skan#undef TARGET_CANNOT_FORCE_CONST_MEM
1178169689Skan#define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem
1179169689Skan
1180169689Skan#undef TARGET_ENCODE_SECTION_INFO
1181169689Skan#define TARGET_ENCODE_SECTION_INFO mips_encode_section_info
1182169689Skan
1183169689Skan#undef TARGET_ATTRIBUTE_TABLE
1184169689Skan#define TARGET_ATTRIBUTE_TABLE mips_attribute_table
1185169689Skan
1186169689Skan#undef TARGET_EXTRA_LIVE_ON_ENTRY
1187169689Skan#define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
1188169689Skan
1189169689Skan#undef TARGET_MIN_ANCHOR_OFFSET
1190169689Skan#define TARGET_MIN_ANCHOR_OFFSET -32768
1191169689Skan#undef TARGET_MAX_ANCHOR_OFFSET
1192169689Skan#define TARGET_MAX_ANCHOR_OFFSET 32767
1193169689Skan#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1194169689Skan#define TARGET_USE_BLOCKS_FOR_CONSTANT_P mips_use_blocks_for_constant_p
1195169689Skan#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
1196169689Skan#define TARGET_USE_ANCHORS_FOR_SYMBOL_P mips_use_anchors_for_symbol_p
1197169689Skan
1198169689Skanstruct gcc_target targetm = TARGET_INITIALIZER;
1199169689Skan
1200169689Skan/* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF.  */
1201169689Skan
1202169689Skanstatic enum mips_symbol_type
1203169689Skanmips_classify_symbol (rtx x)
1204169689Skan{
1205169689Skan  if (GET_CODE (x) == LABEL_REF)
1206169689Skan    {
1207169689Skan      if (TARGET_MIPS16)
1208169689Skan	return SYMBOL_CONSTANT_POOL;
1209169689Skan      if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
1210169689Skan	return SYMBOL_GOT_LOCAL;
1211169689Skan      return SYMBOL_GENERAL;
1212169689Skan    }
1213169689Skan
1214169689Skan  gcc_assert (GET_CODE (x) == SYMBOL_REF);
1215169689Skan
1216169689Skan  if (SYMBOL_REF_TLS_MODEL (x))
1217169689Skan    return SYMBOL_TLS;
1218169689Skan
1219169689Skan  if (CONSTANT_POOL_ADDRESS_P (x))
1220169689Skan    {
1221169689Skan      if (TARGET_MIPS16)
1222169689Skan	return SYMBOL_CONSTANT_POOL;
1223169689Skan
1224169689Skan      if (GET_MODE_SIZE (get_pool_mode (x)) <= mips_section_threshold)
1225169689Skan	return SYMBOL_SMALL_DATA;
1226169689Skan    }
1227169689Skan
1228169689Skan  /* Do not use small-data accesses for weak symbols; they may end up
1229169689Skan     being zero.  */
1230169689Skan  if (SYMBOL_REF_SMALL_P (x)
1231169689Skan      && !SYMBOL_REF_WEAK (x))
1232169689Skan    return SYMBOL_SMALL_DATA;
1233169689Skan
1234169689Skan  if (TARGET_ABICALLS)
1235169689Skan    {
1236169689Skan      if (SYMBOL_REF_DECL (x) == 0)
1237169689Skan	{
1238169689Skan	  if (!SYMBOL_REF_LOCAL_P (x))
1239169689Skan	    return SYMBOL_GOT_GLOBAL;
1240169689Skan	}
1241169689Skan      else
1242169689Skan	{
1243169689Skan	  /* Don't use GOT accesses for locally-binding symbols if
1244169689Skan	     TARGET_ABSOLUTE_ABICALLS.  Otherwise, there are three
1245169689Skan	     cases to consider:
1246169689Skan
1247169689Skan		- o32 PIC (either with or without explicit relocs)
1248169689Skan		- n32/n64 PIC without explicit relocs
1249169689Skan		- n32/n64 PIC with explicit relocs
1250169689Skan
1251169689Skan	     In the first case, both local and global accesses will use an
1252169689Skan	     R_MIPS_GOT16 relocation.  We must correctly predict which of
1253169689Skan	     the two semantics (local or global) the assembler and linker
1254169689Skan	     will apply.  The choice doesn't depend on the symbol's
1255169689Skan	     visibility, so we deliberately ignore decl_visibility and
1256169689Skan	     binds_local_p here.
1257169689Skan
1258169689Skan	     In the second case, the assembler will not use R_MIPS_GOT16
1259169689Skan	     relocations, but it chooses between local and global accesses
1260169689Skan	     in the same way as for o32 PIC.
1261169689Skan
1262169689Skan	     In the third case we have more freedom since both forms of
1263169689Skan	     access will work for any kind of symbol.  However, there seems
1264169689Skan	     little point in doing things differently.  */
1265169689Skan	  if (DECL_P (SYMBOL_REF_DECL (x))
1266169689Skan	      && TREE_PUBLIC (SYMBOL_REF_DECL (x))
1267169689Skan	      && !(TARGET_ABSOLUTE_ABICALLS
1268169689Skan		   && targetm.binds_local_p (SYMBOL_REF_DECL (x))))
1269169689Skan	    return SYMBOL_GOT_GLOBAL;
1270169689Skan	}
1271169689Skan
1272169689Skan      if (!TARGET_ABSOLUTE_ABICALLS)
1273169689Skan	return SYMBOL_GOT_LOCAL;
1274169689Skan    }
1275169689Skan
1276169689Skan  return SYMBOL_GENERAL;
1277169689Skan}
1278169689Skan
1279169689Skan
1280169689Skan/* Split X into a base and a constant offset, storing them in *BASE
1281169689Skan   and *OFFSET respectively.  */
1282169689Skan
1283169689Skanstatic void
1284169689Skanmips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
1285169689Skan{
1286169689Skan  *offset = 0;
1287169689Skan
1288169689Skan  if (GET_CODE (x) == CONST)
1289169689Skan    {
1290169689Skan      x = XEXP (x, 0);
1291169689Skan      if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
1292169689Skan	{
1293169689Skan	  *offset += INTVAL (XEXP (x, 1));
1294169689Skan	  x = XEXP (x, 0);
1295169689Skan	}
1296169689Skan    }
1297169689Skan  *base = x;
1298169689Skan}
1299169689Skan
1300234855Sgonzo/* Classify symbolic expression X, given that it appears in context
1301234855Sgonzo   CONTEXT.  */
1302169689Skan
1303234855Sgonzostatic enum mips_symbol_type
1304234855Sgonzomips_classify_symbolic_expression (rtx x)
1305234855Sgonzo{
1306234855Sgonzo  HOST_WIDE_INT offset;
1307234855Sgonzo
1308234855Sgonzo  mips_split_const (x, &x, &offset);
1309234855Sgonzo  if (UNSPEC_ADDRESS_P (x))
1310234855Sgonzo    return UNSPEC_ADDRESS_TYPE (x);
1311234855Sgonzo
1312234855Sgonzo  return mips_classify_symbol (x);
1313234855Sgonzo}
1314234855Sgonzo
1315169689Skan/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
1316169689Skan   to the same object as SYMBOL, or to the same object_block.  */
1317169689Skan
1318169689Skanstatic bool
1319169689Skanmips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
1320169689Skan{
1321169689Skan  if (GET_CODE (symbol) != SYMBOL_REF)
1322169689Skan    return false;
1323169689Skan
1324169689Skan  if (CONSTANT_POOL_ADDRESS_P (symbol)
1325169689Skan      && offset >= 0
1326169689Skan      && offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
1327169689Skan    return true;
1328169689Skan
1329169689Skan  if (SYMBOL_REF_DECL (symbol) != 0
1330169689Skan      && offset >= 0
1331169689Skan      && offset < int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
1332169689Skan    return true;
1333169689Skan
1334169689Skan  if (SYMBOL_REF_HAS_BLOCK_INFO_P (symbol)
1335169689Skan      && SYMBOL_REF_BLOCK (symbol)
1336169689Skan      && SYMBOL_REF_BLOCK_OFFSET (symbol) >= 0
1337169689Skan      && ((unsigned HOST_WIDE_INT) offset + SYMBOL_REF_BLOCK_OFFSET (symbol)
1338169689Skan	  < (unsigned HOST_WIDE_INT) SYMBOL_REF_BLOCK (symbol)->size))
1339169689Skan    return true;
1340169689Skan
1341169689Skan  return false;
1342169689Skan}
1343169689Skan
1344169689Skan
1345169689Skan/* Return true if X is a symbolic constant that can be calculated in
1346169689Skan   the same way as a bare symbol.  If it is, store the type of the
1347169689Skan   symbol in *SYMBOL_TYPE.  */
1348169689Skan
1349169689Skanbool
1350169689Skanmips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
1351169689Skan{
1352169689Skan  HOST_WIDE_INT offset;
1353169689Skan
1354169689Skan  mips_split_const (x, &x, &offset);
1355169689Skan  if (UNSPEC_ADDRESS_P (x))
1356169689Skan    *symbol_type = UNSPEC_ADDRESS_TYPE (x);
1357169689Skan  else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
1358169689Skan    {
1359169689Skan      *symbol_type = mips_classify_symbol (x);
1360169689Skan      if (*symbol_type == SYMBOL_TLS)
1361169689Skan	return false;
1362169689Skan    }
1363169689Skan  else
1364169689Skan    return false;
1365169689Skan
1366169689Skan  if (offset == 0)
1367169689Skan    return true;
1368169689Skan
1369169689Skan  /* Check whether a nonzero offset is valid for the underlying
1370169689Skan     relocations.  */
1371169689Skan  switch (*symbol_type)
1372169689Skan    {
1373169689Skan    case SYMBOL_GENERAL:
1374169689Skan    case SYMBOL_64_HIGH:
1375169689Skan    case SYMBOL_64_MID:
1376169689Skan    case SYMBOL_64_LOW:
1377169689Skan      /* If the target has 64-bit pointers and the object file only
1378169689Skan	 supports 32-bit symbols, the values of those symbols will be
1379169689Skan	 sign-extended.  In this case we can't allow an arbitrary offset
1380169689Skan	 in case the 32-bit value X + OFFSET has a different sign from X.  */
1381169689Skan      if (Pmode == DImode && !ABI_HAS_64BIT_SYMBOLS)
1382169689Skan	return mips_offset_within_object_p (x, offset);
1383169689Skan
1384169689Skan      /* In other cases the relocations can handle any offset.  */
1385169689Skan      return true;
1386169689Skan
1387169689Skan    case SYMBOL_CONSTANT_POOL:
1388169689Skan      /* Allow constant pool references to be converted to LABEL+CONSTANT.
1389169689Skan	 In this case, we no longer have access to the underlying constant,
1390169689Skan	 but the original symbol-based access was known to be valid.  */
1391169689Skan      if (GET_CODE (x) == LABEL_REF)
1392169689Skan	return true;
1393169689Skan
1394169689Skan      /* Fall through.  */
1395169689Skan
1396169689Skan    case SYMBOL_SMALL_DATA:
1397169689Skan      /* Make sure that the offset refers to something within the
1398169689Skan	 underlying object.  This should guarantee that the final
1399169689Skan	 PC- or GP-relative offset is within the 16-bit limit.  */
1400169689Skan      return mips_offset_within_object_p (x, offset);
1401169689Skan
1402169689Skan    case SYMBOL_GOT_LOCAL:
1403169689Skan    case SYMBOL_GOTOFF_PAGE:
1404169689Skan      /* The linker should provide enough local GOT entries for a
1405169689Skan	 16-bit offset.  Larger offsets may lead to GOT overflow.  */
1406169689Skan      return SMALL_OPERAND (offset);
1407169689Skan
1408169689Skan    case SYMBOL_GOT_GLOBAL:
1409169689Skan    case SYMBOL_GOTOFF_GLOBAL:
1410169689Skan    case SYMBOL_GOTOFF_CALL:
1411169689Skan    case SYMBOL_GOTOFF_LOADGP:
1412169689Skan    case SYMBOL_TLSGD:
1413169689Skan    case SYMBOL_TLSLDM:
1414169689Skan    case SYMBOL_DTPREL:
1415169689Skan    case SYMBOL_TPREL:
1416169689Skan    case SYMBOL_GOTTPREL:
1417169689Skan    case SYMBOL_TLS:
1418169689Skan      return false;
1419169689Skan    }
1420169689Skan  gcc_unreachable ();
1421169689Skan}
1422169689Skan
1423169689Skan
1424169689Skan/* This function is used to implement REG_MODE_OK_FOR_BASE_P.  */
1425169689Skan
1426169689Skanint
1427169689Skanmips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, int strict)
1428169689Skan{
1429169689Skan  if (regno >= FIRST_PSEUDO_REGISTER)
1430169689Skan    {
1431169689Skan      if (!strict)
1432169689Skan	return true;
1433169689Skan      regno = reg_renumber[regno];
1434169689Skan    }
1435169689Skan
1436169689Skan  /* These fake registers will be eliminated to either the stack or
1437169689Skan     hard frame pointer, both of which are usually valid base registers.
1438169689Skan     Reload deals with the cases where the eliminated form isn't valid.  */
1439169689Skan  if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
1440169689Skan    return true;
1441169689Skan
1442169689Skan  /* In mips16 mode, the stack pointer can only address word and doubleword
1443169689Skan     values, nothing smaller.  There are two problems here:
1444169689Skan
1445169689Skan       (a) Instantiating virtual registers can introduce new uses of the
1446169689Skan	   stack pointer.  If these virtual registers are valid addresses,
1447169689Skan	   the stack pointer should be too.
1448169689Skan
1449169689Skan       (b) Most uses of the stack pointer are not made explicit until
1450169689Skan	   FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
1451169689Skan	   We don't know until that stage whether we'll be eliminating to the
1452169689Skan	   stack pointer (which needs the restriction) or the hard frame
1453169689Skan	   pointer (which doesn't).
1454169689Skan
1455169689Skan     All in all, it seems more consistent to only enforce this restriction
1456169689Skan     during and after reload.  */
1457169689Skan  if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
1458169689Skan    return !strict || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
1459169689Skan
1460169689Skan  return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
1461169689Skan}
1462169689Skan
1463169689Skan
1464169689Skan/* Return true if X is a valid base register for the given mode.
1465169689Skan   Allow only hard registers if STRICT.  */
1466169689Skan
1467169689Skanstatic bool
1468169689Skanmips_valid_base_register_p (rtx x, enum machine_mode mode, int strict)
1469169689Skan{
1470169689Skan  if (!strict && GET_CODE (x) == SUBREG)
1471169689Skan    x = SUBREG_REG (x);
1472169689Skan
1473169689Skan  return (REG_P (x)
1474169689Skan	  && mips_regno_mode_ok_for_base_p (REGNO (x), mode, strict));
1475169689Skan}
1476169689Skan
1477169689Skan
1478169689Skan/* Return true if symbols of type SYMBOL_TYPE can directly address a value
1479169689Skan   with mode MODE.  This is used for both symbolic and LO_SUM addresses.  */
1480169689Skan
1481169689Skanstatic bool
1482169689Skanmips_symbolic_address_p (enum mips_symbol_type symbol_type,
1483169689Skan			 enum machine_mode mode)
1484169689Skan{
1485169689Skan  switch (symbol_type)
1486169689Skan    {
1487169689Skan    case SYMBOL_GENERAL:
1488169689Skan      return !TARGET_MIPS16;
1489169689Skan
1490169689Skan    case SYMBOL_SMALL_DATA:
1491169689Skan      return true;
1492169689Skan
1493169689Skan    case SYMBOL_CONSTANT_POOL:
1494169689Skan      /* PC-relative addressing is only available for lw and ld.  */
1495169689Skan      return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
1496169689Skan
1497169689Skan    case SYMBOL_GOT_LOCAL:
1498169689Skan      return true;
1499169689Skan
1500169689Skan    case SYMBOL_GOT_GLOBAL:
1501169689Skan      /* The address will have to be loaded from the GOT first.  */
1502169689Skan      return false;
1503169689Skan
1504169689Skan    case SYMBOL_GOTOFF_PAGE:
1505169689Skan    case SYMBOL_GOTOFF_GLOBAL:
1506169689Skan    case SYMBOL_GOTOFF_CALL:
1507169689Skan    case SYMBOL_GOTOFF_LOADGP:
1508169689Skan    case SYMBOL_TLS:
1509169689Skan    case SYMBOL_TLSGD:
1510169689Skan    case SYMBOL_TLSLDM:
1511169689Skan    case SYMBOL_DTPREL:
1512169689Skan    case SYMBOL_GOTTPREL:
1513169689Skan    case SYMBOL_TPREL:
1514169689Skan    case SYMBOL_64_HIGH:
1515169689Skan    case SYMBOL_64_MID:
1516169689Skan    case SYMBOL_64_LOW:
1517169689Skan      return true;
1518169689Skan    }
1519169689Skan  gcc_unreachable ();
1520169689Skan}
1521169689Skan
1522169689Skan
1523169689Skan/* Return true if X is a valid address for machine mode MODE.  If it is,
1524169689Skan   fill in INFO appropriately.  STRICT is true if we should only accept
1525169689Skan   hard base registers.  */
1526169689Skan
1527169689Skanstatic bool
1528169689Skanmips_classify_address (struct mips_address_info *info, rtx x,
1529169689Skan		       enum machine_mode mode, int strict)
1530169689Skan{
1531169689Skan  switch (GET_CODE (x))
1532169689Skan    {
1533169689Skan    case REG:
1534169689Skan    case SUBREG:
1535169689Skan      info->type = ADDRESS_REG;
1536169689Skan      info->reg = x;
1537169689Skan      info->offset = const0_rtx;
1538169689Skan      return mips_valid_base_register_p (info->reg, mode, strict);
1539169689Skan
1540169689Skan    case PLUS:
1541169689Skan      info->type = ADDRESS_REG;
1542169689Skan      info->reg = XEXP (x, 0);
1543169689Skan      info->offset = XEXP (x, 1);
1544169689Skan      return (mips_valid_base_register_p (info->reg, mode, strict)
1545169689Skan	      && const_arith_operand (info->offset, VOIDmode));
1546169689Skan
1547169689Skan    case LO_SUM:
1548169689Skan      info->type = ADDRESS_LO_SUM;
1549169689Skan      info->reg = XEXP (x, 0);
1550169689Skan      info->offset = XEXP (x, 1);
1551234855Sgonzo      /* We have to trust the creator of the LO_SUM to do something vaguely
1552234855Sgonzo	 sane.  Target-independent code that creates a LO_SUM should also
1553234855Sgonzo	 create and verify the matching HIGH.  Target-independent code that
1554234855Sgonzo	 adds an offset to a LO_SUM must prove that the offset will not
1555234855Sgonzo	 induce a carry.  Failure to do either of these things would be
1556234855Sgonzo	 a bug, and we are not required to check for it here.  The MIPS
1557234855Sgonzo	 backend itself should only create LO_SUMs for valid symbolic
1558234855Sgonzo	 constants, with the high part being either a HIGH or a copy
1559234855Sgonzo	 of _gp. */
1560234855Sgonzo      info->symbol_type = mips_classify_symbolic_expression (info->offset);
1561169689Skan      return (mips_valid_base_register_p (info->reg, mode, strict)
1562169689Skan	      && mips_symbolic_address_p (info->symbol_type, mode)
1563169689Skan	      && mips_lo_relocs[info->symbol_type] != 0);
1564169689Skan
1565169689Skan    case CONST_INT:
1566169689Skan      /* Small-integer addresses don't occur very often, but they
1567169689Skan	 are legitimate if $0 is a valid base register.  */
1568169689Skan      info->type = ADDRESS_CONST_INT;
1569169689Skan      return !TARGET_MIPS16 && SMALL_INT (x);
1570169689Skan
1571169689Skan    case CONST:
1572169689Skan    case LABEL_REF:
1573169689Skan    case SYMBOL_REF:
1574169689Skan      info->type = ADDRESS_SYMBOLIC;
1575169689Skan      return (mips_symbolic_constant_p (x, &info->symbol_type)
1576169689Skan	      && mips_symbolic_address_p (info->symbol_type, mode)
1577169689Skan	      && !mips_split_p[info->symbol_type]);
1578169689Skan
1579169689Skan    default:
1580169689Skan      return false;
1581169689Skan    }
1582169689Skan}
1583169689Skan
1584169689Skan/* Return true if X is a thread-local symbol.  */
1585169689Skan
1586169689Skanstatic bool
1587169689Skanmips_tls_operand_p (rtx x)
1588169689Skan{
1589169689Skan  return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
1590169689Skan}
1591169689Skan
1592169689Skan/* Return true if X can not be forced into a constant pool.  */
1593169689Skan
1594169689Skanstatic int
1595169689Skanmips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
1596169689Skan{
1597169689Skan  return mips_tls_operand_p (*x);
1598169689Skan}
1599169689Skan
1600169689Skan/* Return true if X can not be forced into a constant pool.  */
1601169689Skan
1602169689Skanstatic bool
1603169689Skanmips_cannot_force_const_mem (rtx x)
1604169689Skan{
1605169689Skan  rtx base;
1606169689Skan  HOST_WIDE_INT offset;
1607169689Skan
1608169689Skan  if (!TARGET_MIPS16)
1609169689Skan    {
1610169689Skan      /* As an optimization, reject constants that mips_legitimize_move
1611169689Skan	 can expand inline.
1612169689Skan
1613169689Skan	 Suppose we have a multi-instruction sequence that loads constant C
1614169689Skan	 into register R.  If R does not get allocated a hard register, and
1615169689Skan	 R is used in an operand that allows both registers and memory
1616169689Skan	 references, reload will consider forcing C into memory and using
1617169689Skan	 one of the instruction's memory alternatives.  Returning false
1618169689Skan	 here will force it to use an input reload instead.  */
1619169689Skan      if (GET_CODE (x) == CONST_INT)
1620169689Skan	return true;
1621169689Skan
1622169689Skan      mips_split_const (x, &base, &offset);
1623169689Skan      if (symbolic_operand (base, VOIDmode) && SMALL_OPERAND (offset))
1624169689Skan	return true;
1625169689Skan    }
1626169689Skan
1627169689Skan  if (TARGET_HAVE_TLS && for_each_rtx (&x, &mips_tls_symbol_ref_1, 0))
1628169689Skan    return true;
1629169689Skan
1630169689Skan  return false;
1631169689Skan}
1632169689Skan
1633169689Skan/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P.  MIPS16 uses per-function
1634169689Skan   constant pools, but normal-mode code doesn't need to.  */
1635169689Skan
1636169689Skanstatic bool
1637169689Skanmips_use_blocks_for_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED,
1638169689Skan				rtx x ATTRIBUTE_UNUSED)
1639169689Skan{
1640169689Skan  return !TARGET_MIPS16;
1641169689Skan}
1642169689Skan
1643169689Skan/* Return the number of instructions needed to load a symbol of the
1644169689Skan   given type into a register.  If valid in an address, the same number
1645169689Skan   of instructions are needed for loads and stores.  Treat extended
1646169689Skan   mips16 instructions as two instructions.  */
1647169689Skan
1648169689Skanstatic int
1649169689Skanmips_symbol_insns (enum mips_symbol_type type)
1650169689Skan{
1651169689Skan  switch (type)
1652169689Skan    {
1653169689Skan    case SYMBOL_GENERAL:
1654169689Skan      /* In mips16 code, general symbols must be fetched from the
1655169689Skan	 constant pool.  */
1656169689Skan      if (TARGET_MIPS16)
1657169689Skan	return 0;
1658169689Skan
1659169689Skan      /* When using 64-bit symbols, we need 5 preparatory instructions,
1660169689Skan	 such as:
1661169689Skan
1662169689Skan	     lui     $at,%highest(symbol)
1663169689Skan	     daddiu  $at,$at,%higher(symbol)
1664169689Skan	     dsll    $at,$at,16
1665169689Skan	     daddiu  $at,$at,%hi(symbol)
1666169689Skan	     dsll    $at,$at,16
1667169689Skan
1668169689Skan	 The final address is then $at + %lo(symbol).  With 32-bit
1669169689Skan	 symbols we just need a preparatory lui.  */
1670169689Skan      return (ABI_HAS_64BIT_SYMBOLS ? 6 : 2);
1671169689Skan
1672169689Skan    case SYMBOL_SMALL_DATA:
1673169689Skan      return 1;
1674169689Skan
1675169689Skan    case SYMBOL_CONSTANT_POOL:
1676169689Skan      /* This case is for mips16 only.  Assume we'll need an
1677169689Skan	 extended instruction.  */
1678169689Skan      return 2;
1679169689Skan
1680169689Skan    case SYMBOL_GOT_LOCAL:
1681169689Skan    case SYMBOL_GOT_GLOBAL:
1682169689Skan      /* Unless -funit-at-a-time is in effect, we can't be sure whether
1683169689Skan	 the local/global classification is accurate.  See override_options
1684169689Skan	 for details.
1685169689Skan
1686169689Skan	 The worst cases are:
1687169689Skan
1688169689Skan	 (1) For local symbols when generating o32 or o64 code.  The assembler
1689169689Skan	     will use:
1690169689Skan
1691169689Skan		 lw	      $at,%got(symbol)
1692169689Skan		 nop
1693169689Skan
1694169689Skan	     ...and the final address will be $at + %lo(symbol).
1695169689Skan
1696169689Skan	 (2) For global symbols when -mxgot.  The assembler will use:
1697169689Skan
1698169689Skan	         lui     $at,%got_hi(symbol)
1699169689Skan	         (d)addu $at,$at,$gp
1700169689Skan
1701169689Skan	     ...and the final address will be $at + %got_lo(symbol).  */
1702169689Skan      return 3;
1703169689Skan
1704169689Skan    case SYMBOL_GOTOFF_PAGE:
1705169689Skan    case SYMBOL_GOTOFF_GLOBAL:
1706169689Skan    case SYMBOL_GOTOFF_CALL:
1707169689Skan    case SYMBOL_GOTOFF_LOADGP:
1708169689Skan    case SYMBOL_64_HIGH:
1709169689Skan    case SYMBOL_64_MID:
1710169689Skan    case SYMBOL_64_LOW:
1711169689Skan    case SYMBOL_TLSGD:
1712169689Skan    case SYMBOL_TLSLDM:
1713169689Skan    case SYMBOL_DTPREL:
1714169689Skan    case SYMBOL_GOTTPREL:
1715169689Skan    case SYMBOL_TPREL:
1716169689Skan      /* Check whether the offset is a 16- or 32-bit value.  */
1717169689Skan      return mips_split_p[type] ? 2 : 1;
1718169689Skan
1719169689Skan    case SYMBOL_TLS:
1720169689Skan      /* We don't treat a bare TLS symbol as a constant.  */
1721169689Skan      return 0;
1722169689Skan    }
1723169689Skan  gcc_unreachable ();
1724169689Skan}
1725169689Skan
1726169689Skan/* Return true if X is a legitimate $sp-based address for mode MDOE.  */
1727169689Skan
1728169689Skanbool
1729169689Skanmips_stack_address_p (rtx x, enum machine_mode mode)
1730169689Skan{
1731169689Skan  struct mips_address_info addr;
1732169689Skan
1733169689Skan  return (mips_classify_address (&addr, x, mode, false)
1734169689Skan	  && addr.type == ADDRESS_REG
1735169689Skan	  && addr.reg == stack_pointer_rtx);
1736169689Skan}
1737169689Skan
1738169689Skan/* Return true if a value at OFFSET bytes from BASE can be accessed
1739169689Skan   using an unextended mips16 instruction.  MODE is the mode of the
1740169689Skan   value.
1741169689Skan
1742169689Skan   Usually the offset in an unextended instruction is a 5-bit field.
1743169689Skan   The offset is unsigned and shifted left once for HIs, twice
1744169689Skan   for SIs, and so on.  An exception is SImode accesses off the
1745169689Skan   stack pointer, which have an 8-bit immediate field.  */
1746169689Skan
1747169689Skanstatic bool
1748169689Skanmips16_unextended_reference_p (enum machine_mode mode, rtx base, rtx offset)
1749169689Skan{
1750169689Skan  if (TARGET_MIPS16
1751169689Skan      && GET_CODE (offset) == CONST_INT
1752169689Skan      && INTVAL (offset) >= 0
1753169689Skan      && (INTVAL (offset) & (GET_MODE_SIZE (mode) - 1)) == 0)
1754169689Skan    {
1755169689Skan      if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx)
1756169689Skan	return INTVAL (offset) < 256 * GET_MODE_SIZE (mode);
1757169689Skan      return INTVAL (offset) < 32 * GET_MODE_SIZE (mode);
1758169689Skan    }
1759169689Skan  return false;
1760169689Skan}
1761169689Skan
1762169689Skan
1763169689Skan/* Return the number of instructions needed to load or store a value
1764169689Skan   of mode MODE at X.  Return 0 if X isn't valid for MODE.
1765169689Skan
1766169689Skan   For mips16 code, count extended instructions as two instructions.  */
1767169689Skan
1768169689Skanint
1769169689Skanmips_address_insns (rtx x, enum machine_mode mode)
1770169689Skan{
1771169689Skan  struct mips_address_info addr;
1772169689Skan  int factor;
1773169689Skan
1774169689Skan  if (mode == BLKmode)
1775169689Skan    /* BLKmode is used for single unaligned loads and stores.  */
1776169689Skan    factor = 1;
1777169689Skan  else
1778169689Skan    /* Each word of a multi-word value will be accessed individually.  */
1779169689Skan    factor = (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
1780169689Skan
1781169689Skan  if (mips_classify_address (&addr, x, mode, false))
1782169689Skan    switch (addr.type)
1783169689Skan      {
1784169689Skan      case ADDRESS_REG:
1785169689Skan	if (TARGET_MIPS16
1786169689Skan	    && !mips16_unextended_reference_p (mode, addr.reg, addr.offset))
1787169689Skan	  return factor * 2;
1788169689Skan	return factor;
1789169689Skan
1790169689Skan      case ADDRESS_LO_SUM:
1791169689Skan	return (TARGET_MIPS16 ? factor * 2 : factor);
1792169689Skan
1793169689Skan      case ADDRESS_CONST_INT:
1794169689Skan	return factor;
1795169689Skan
1796169689Skan      case ADDRESS_SYMBOLIC:
1797169689Skan	return factor * mips_symbol_insns (addr.symbol_type);
1798169689Skan      }
1799169689Skan  return 0;
1800169689Skan}
1801169689Skan
1802169689Skan
1803169689Skan/* Likewise for constant X.  */
1804169689Skan
1805169689Skanint
1806169689Skanmips_const_insns (rtx x)
1807169689Skan{
1808169689Skan  struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
1809169689Skan  enum mips_symbol_type symbol_type;
1810169689Skan  HOST_WIDE_INT offset;
1811169689Skan
1812169689Skan  switch (GET_CODE (x))
1813169689Skan    {
1814169689Skan    case HIGH:
1815169689Skan      if (TARGET_MIPS16
1816169689Skan	  || !mips_symbolic_constant_p (XEXP (x, 0), &symbol_type)
1817169689Skan	  || !mips_split_p[symbol_type])
1818169689Skan	return 0;
1819169689Skan
1820169689Skan      return 1;
1821169689Skan
1822169689Skan    case CONST_INT:
1823169689Skan      if (TARGET_MIPS16)
1824169689Skan	/* Unsigned 8-bit constants can be loaded using an unextended
1825169689Skan	   LI instruction.  Unsigned 16-bit constants can be loaded
1826169689Skan	   using an extended LI.  Negative constants must be loaded
1827169689Skan	   using LI and then negated.  */
1828169689Skan	return (INTVAL (x) >= 0 && INTVAL (x) < 256 ? 1
1829169689Skan		: SMALL_OPERAND_UNSIGNED (INTVAL (x)) ? 2
1830169689Skan		: INTVAL (x) > -256 && INTVAL (x) < 0 ? 2
1831169689Skan		: SMALL_OPERAND_UNSIGNED (-INTVAL (x)) ? 3
1832169689Skan		: 0);
1833169689Skan
1834169689Skan      return mips_build_integer (codes, INTVAL (x));
1835169689Skan
1836169689Skan    case CONST_DOUBLE:
1837169689Skan    case CONST_VECTOR:
1838169689Skan      return (!TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0);
1839169689Skan
1840169689Skan    case CONST:
1841169689Skan      if (CONST_GP_P (x))
1842169689Skan	return 1;
1843169689Skan
1844169689Skan      /* See if we can refer to X directly.  */
1845169689Skan      if (mips_symbolic_constant_p (x, &symbol_type))
1846169689Skan	return mips_symbol_insns (symbol_type);
1847169689Skan
1848169689Skan      /* Otherwise try splitting the constant into a base and offset.
1849169689Skan	 16-bit offsets can be added using an extra addiu.  Larger offsets
1850169689Skan	 must be calculated separately and then added to the base.  */
1851169689Skan      mips_split_const (x, &x, &offset);
1852169689Skan      if (offset != 0)
1853169689Skan	{
1854169689Skan	  int n = mips_const_insns (x);
1855169689Skan	  if (n != 0)
1856169689Skan	    {
1857169689Skan	      if (SMALL_OPERAND (offset))
1858169689Skan		return n + 1;
1859169689Skan	      else
1860169689Skan		return n + 1 + mips_build_integer (codes, offset);
1861169689Skan	    }
1862169689Skan	}
1863169689Skan      return 0;
1864169689Skan
1865169689Skan    case SYMBOL_REF:
1866169689Skan    case LABEL_REF:
1867169689Skan      return mips_symbol_insns (mips_classify_symbol (x));
1868169689Skan
1869169689Skan    default:
1870169689Skan      return 0;
1871169689Skan    }
1872169689Skan}
1873169689Skan
1874169689Skan
1875169689Skan/* Return the number of instructions needed for memory reference X.
1876169689Skan   Count extended mips16 instructions as two instructions.  */
1877169689Skan
1878169689Skanint
1879169689Skanmips_fetch_insns (rtx x)
1880169689Skan{
1881169689Skan  gcc_assert (MEM_P (x));
1882169689Skan  return mips_address_insns (XEXP (x, 0), GET_MODE (x));
1883169689Skan}
1884169689Skan
1885169689Skan
1886169689Skan/* Return the number of instructions needed for an integer division.  */
1887169689Skan
1888169689Skanint
1889169689Skanmips_idiv_insns (void)
1890169689Skan{
1891169689Skan  int count;
1892169689Skan
1893169689Skan  count = 1;
1894169689Skan  if (TARGET_CHECK_ZERO_DIV)
1895169689Skan    {
1896169689Skan      if (GENERATE_DIVIDE_TRAPS)
1897169689Skan        count++;
1898169689Skan      else
1899169689Skan        count += 2;
1900169689Skan    }
1901169689Skan
1902169689Skan  if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
1903169689Skan    count++;
1904169689Skan  return count;
1905169689Skan}
1906169689Skan
1907169689Skan/* This function is used to implement GO_IF_LEGITIMATE_ADDRESS.  It
1908169689Skan   returns a nonzero value if X is a legitimate address for a memory
1909169689Skan   operand of the indicated MODE.  STRICT is nonzero if this function
1910169689Skan   is called during reload.  */
1911169689Skan
1912169689Skanbool
1913169689Skanmips_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
1914169689Skan{
1915169689Skan  struct mips_address_info addr;
1916169689Skan
1917169689Skan  return mips_classify_address (&addr, x, mode, strict);
1918169689Skan}
1919169689Skan
1920169689Skan
1921169689Skan/* Copy VALUE to a register and return that register.  If new psuedos
1922169689Skan   are allowed, copy it into a new register, otherwise use DEST.  */
1923169689Skan
1924169689Skanstatic rtx
1925169689Skanmips_force_temporary (rtx dest, rtx value)
1926169689Skan{
1927169689Skan  if (!no_new_pseudos)
1928169689Skan    return force_reg (Pmode, value);
1929169689Skan  else
1930169689Skan    {
1931169689Skan      emit_move_insn (copy_rtx (dest), value);
1932169689Skan      return dest;
1933169689Skan    }
1934169689Skan}
1935169689Skan
1936169689Skan
1937169689Skan/* Return a LO_SUM expression for ADDR.  TEMP is as for mips_force_temporary
1938169689Skan   and is used to load the high part into a register.  */
1939169689Skan
1940169689Skanrtx
1941169689Skanmips_split_symbol (rtx temp, rtx addr)
1942169689Skan{
1943169689Skan  rtx high;
1944169689Skan
1945169689Skan  if (TARGET_MIPS16)
1946169689Skan    high = mips16_gp_pseudo_reg ();
1947169689Skan  else
1948169689Skan    high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
1949169689Skan  return gen_rtx_LO_SUM (Pmode, high, addr);
1950169689Skan}
1951169689Skan
1952169689Skan
1953169689Skan/* Return an UNSPEC address with underlying address ADDRESS and symbol
1954169689Skan   type SYMBOL_TYPE.  */
1955169689Skan
1956169689Skanrtx
1957169689Skanmips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
1958169689Skan{
1959169689Skan  rtx base;
1960169689Skan  HOST_WIDE_INT offset;
1961169689Skan
1962169689Skan  mips_split_const (address, &base, &offset);
1963169689Skan  base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
1964169689Skan			 UNSPEC_ADDRESS_FIRST + symbol_type);
1965169689Skan  return plus_constant (gen_rtx_CONST (Pmode, base), offset);
1966169689Skan}
1967169689Skan
1968169689Skan
1969169689Skan/* If mips_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
1970169689Skan   high part to BASE and return the result.  Just return BASE otherwise.
1971169689Skan   TEMP is available as a temporary register if needed.
1972169689Skan
1973169689Skan   The returned expression can be used as the first operand to a LO_SUM.  */
1974169689Skan
1975169689Skanstatic rtx
1976169689Skanmips_unspec_offset_high (rtx temp, rtx base, rtx addr,
1977169689Skan			 enum mips_symbol_type symbol_type)
1978169689Skan{
1979169689Skan  if (mips_split_p[symbol_type])
1980169689Skan    {
1981169689Skan      addr = gen_rtx_HIGH (Pmode, mips_unspec_address (addr, symbol_type));
1982169689Skan      addr = mips_force_temporary (temp, addr);
1983169689Skan      return mips_force_temporary (temp, gen_rtx_PLUS (Pmode, addr, base));
1984169689Skan    }
1985169689Skan  return base;
1986169689Skan}
1987169689Skan
1988169689Skan
1989169689Skan/* Return a legitimate address for REG + OFFSET.  TEMP is as for
1990169689Skan   mips_force_temporary; it is only needed when OFFSET is not a
1991169689Skan   SMALL_OPERAND.  */
1992169689Skan
1993169689Skanstatic rtx
1994169689Skanmips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
1995169689Skan{
1996169689Skan  if (!SMALL_OPERAND (offset))
1997169689Skan    {
1998169689Skan      rtx high;
1999169689Skan      if (TARGET_MIPS16)
2000169689Skan	{
2001169689Skan	  /* Load the full offset into a register so that we can use
2002169689Skan	     an unextended instruction for the address itself.  */
2003169689Skan	  high = GEN_INT (offset);
2004169689Skan	  offset = 0;
2005169689Skan	}
2006169689Skan      else
2007169689Skan	{
2008169689Skan	  /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.  */
2009169689Skan	  high = GEN_INT (CONST_HIGH_PART (offset));
2010169689Skan	  offset = CONST_LOW_PART (offset);
2011169689Skan	}
2012169689Skan      high = mips_force_temporary (temp, high);
2013169689Skan      reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg));
2014169689Skan    }
2015169689Skan  return plus_constant (reg, offset);
2016169689Skan}
2017169689Skan
2018169689Skan/* Emit a call to __tls_get_addr.  SYM is the TLS symbol we are
2019169689Skan   referencing, and TYPE is the symbol type to use (either global
2020169689Skan   dynamic or local dynamic).  V0 is an RTX for the return value
2021169689Skan   location.  The entire insn sequence is returned.  */
2022169689Skan
2023169689Skanstatic GTY(()) rtx mips_tls_symbol;
2024169689Skan
2025169689Skanstatic rtx
2026169689Skanmips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
2027169689Skan{
2028169689Skan  rtx insn, loc, tga, a0;
2029169689Skan
2030169689Skan  a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
2031169689Skan
2032169689Skan  if (!mips_tls_symbol)
2033169689Skan    mips_tls_symbol = init_one_libfunc ("__tls_get_addr");
2034169689Skan
2035169689Skan  loc = mips_unspec_address (sym, type);
2036169689Skan
2037169689Skan  start_sequence ();
2038169689Skan
2039169689Skan  emit_insn (gen_rtx_SET (Pmode, a0,
2040169689Skan			  gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc)));
2041169689Skan  tga = gen_rtx_MEM (Pmode, mips_tls_symbol);
2042169689Skan  insn = emit_call_insn (gen_call_value (v0, tga, const0_rtx, const0_rtx));
2043169689Skan  CONST_OR_PURE_CALL_P (insn) = 1;
2044169689Skan  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), v0);
2045169689Skan  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
2046169689Skan  insn = get_insns ();
2047169689Skan
2048169689Skan  end_sequence ();
2049169689Skan
2050169689Skan  return insn;
2051169689Skan}
2052169689Skan
2053169689Skan/* Generate the code to access LOC, a thread local SYMBOL_REF.  The
2054169689Skan   return value will be a valid address and move_operand (either a REG
2055169689Skan   or a LO_SUM).  */
2056169689Skan
2057169689Skanstatic rtx
2058169689Skanmips_legitimize_tls_address (rtx loc)
2059169689Skan{
2060169689Skan  rtx dest, insn, v0, v1, tmp1, tmp2, eqv;
2061169689Skan  enum tls_model model;
2062169689Skan
2063169689Skan  v0 = gen_rtx_REG (Pmode, GP_RETURN);
2064169689Skan  v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
2065169689Skan
2066169689Skan  model = SYMBOL_REF_TLS_MODEL (loc);
2067169689Skan  /* Only TARGET_ABICALLS code can have more than one module; other
2068169689Skan     code must be be static and should not use a GOT.  All TLS models
2069169689Skan     reduce to local exec in this situation.  */
2070169689Skan  if (!TARGET_ABICALLS)
2071169689Skan    model = TLS_MODEL_LOCAL_EXEC;
2072169689Skan
2073169689Skan  switch (model)
2074169689Skan    {
2075169689Skan    case TLS_MODEL_GLOBAL_DYNAMIC:
2076169689Skan      insn = mips_call_tls_get_addr (loc, SYMBOL_TLSGD, v0);
2077169689Skan      dest = gen_reg_rtx (Pmode);
2078169689Skan      emit_libcall_block (insn, dest, v0, loc);
2079169689Skan      break;
2080169689Skan
2081169689Skan    case TLS_MODEL_LOCAL_DYNAMIC:
2082169689Skan      insn = mips_call_tls_get_addr (loc, SYMBOL_TLSLDM, v0);
2083169689Skan      tmp1 = gen_reg_rtx (Pmode);
2084169689Skan
2085169689Skan      /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
2086169689Skan	 share the LDM result with other LD model accesses.  */
2087169689Skan      eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
2088169689Skan			    UNSPEC_TLS_LDM);
2089169689Skan      emit_libcall_block (insn, tmp1, v0, eqv);
2090169689Skan
2091169689Skan      tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL);
2092169689Skan      dest = gen_rtx_LO_SUM (Pmode, tmp2,
2093169689Skan			     mips_unspec_address (loc, SYMBOL_DTPREL));
2094169689Skan      break;
2095169689Skan
2096169689Skan    case TLS_MODEL_INITIAL_EXEC:
2097169689Skan      tmp1 = gen_reg_rtx (Pmode);
2098169689Skan      tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
2099169689Skan      if (Pmode == DImode)
2100169689Skan	{
2101169689Skan	  emit_insn (gen_tls_get_tp_di (v1));
2102169689Skan	  emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
2103169689Skan	}
2104169689Skan      else
2105169689Skan	{
2106169689Skan	  emit_insn (gen_tls_get_tp_si (v1));
2107169689Skan	  emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
2108169689Skan	}
2109169689Skan      dest = gen_reg_rtx (Pmode);
2110169689Skan      emit_insn (gen_add3_insn (dest, tmp1, v1));
2111169689Skan      break;
2112169689Skan
2113169689Skan    case TLS_MODEL_LOCAL_EXEC:
2114169689Skan      if (Pmode == DImode)
2115169689Skan	emit_insn (gen_tls_get_tp_di (v1));
2116169689Skan      else
2117169689Skan	emit_insn (gen_tls_get_tp_si (v1));
2118169689Skan
2119169689Skan      tmp1 = mips_unspec_offset_high (NULL, v1, loc, SYMBOL_TPREL);
2120169689Skan      dest = gen_rtx_LO_SUM (Pmode, tmp1,
2121169689Skan			     mips_unspec_address (loc, SYMBOL_TPREL));
2122169689Skan      break;
2123169689Skan
2124169689Skan    default:
2125169689Skan      gcc_unreachable ();
2126169689Skan    }
2127169689Skan
2128169689Skan  return dest;
2129169689Skan}
2130169689Skan
2131169689Skan/* This function is used to implement LEGITIMIZE_ADDRESS.  If *XLOC can
2132169689Skan   be legitimized in a way that the generic machinery might not expect,
2133169689Skan   put the new address in *XLOC and return true.  MODE is the mode of
2134169689Skan   the memory being accessed.  */
2135169689Skan
2136169689Skanbool
2137169689Skanmips_legitimize_address (rtx *xloc, enum machine_mode mode)
2138169689Skan{
2139169689Skan  enum mips_symbol_type symbol_type;
2140169689Skan
2141169689Skan  if (mips_tls_operand_p (*xloc))
2142169689Skan    {
2143169689Skan      *xloc = mips_legitimize_tls_address (*xloc);
2144169689Skan      return true;
2145169689Skan    }
2146169689Skan
2147169689Skan  /* See if the address can split into a high part and a LO_SUM.  */
2148169689Skan  if (mips_symbolic_constant_p (*xloc, &symbol_type)
2149169689Skan      && mips_symbolic_address_p (symbol_type, mode)
2150169689Skan      && mips_split_p[symbol_type])
2151169689Skan    {
2152169689Skan      *xloc = mips_split_symbol (0, *xloc);
2153169689Skan      return true;
2154169689Skan    }
2155169689Skan
2156169689Skan  if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
2157169689Skan    {
2158169689Skan      /* Handle REG + CONSTANT using mips_add_offset.  */
2159169689Skan      rtx reg;
2160169689Skan
2161169689Skan      reg = XEXP (*xloc, 0);
2162169689Skan      if (!mips_valid_base_register_p (reg, mode, 0))
2163169689Skan	reg = copy_to_mode_reg (Pmode, reg);
2164169689Skan      *xloc = mips_add_offset (0, reg, INTVAL (XEXP (*xloc, 1)));
2165169689Skan      return true;
2166169689Skan    }
2167169689Skan
2168169689Skan  return false;
2169169689Skan}
2170169689Skan
2171169689Skan
2172169689Skan/* Subroutine of mips_build_integer (with the same interface).
2173169689Skan   Assume that the final action in the sequence should be a left shift.  */
2174169689Skan
2175169689Skanstatic unsigned int
2176169689Skanmips_build_shift (struct mips_integer_op *codes, HOST_WIDE_INT value)
2177169689Skan{
2178169689Skan  unsigned int i, shift;
2179169689Skan
2180169689Skan  /* Shift VALUE right until its lowest bit is set.  Shift arithmetically
2181169689Skan     since signed numbers are easier to load than unsigned ones.  */
2182169689Skan  shift = 0;
2183169689Skan  while ((value & 1) == 0)
2184169689Skan    value /= 2, shift++;
2185169689Skan
2186169689Skan  i = mips_build_integer (codes, value);
2187169689Skan  codes[i].code = ASHIFT;
2188169689Skan  codes[i].value = shift;
2189169689Skan  return i + 1;
2190169689Skan}
2191169689Skan
2192169689Skan
2193169689Skan/* As for mips_build_shift, but assume that the final action will be
2194169689Skan   an IOR or PLUS operation.  */
2195169689Skan
2196169689Skanstatic unsigned int
2197169689Skanmips_build_lower (struct mips_integer_op *codes, unsigned HOST_WIDE_INT value)
2198169689Skan{
2199169689Skan  unsigned HOST_WIDE_INT high;
2200169689Skan  unsigned int i;
2201169689Skan
2202169689Skan  high = value & ~(unsigned HOST_WIDE_INT) 0xffff;
2203169689Skan  if (!LUI_OPERAND (high) && (value & 0x18000) == 0x18000)
2204169689Skan    {
2205169689Skan      /* The constant is too complex to load with a simple lui/ori pair
2206169689Skan	 so our goal is to clear as many trailing zeros as possible.
2207169689Skan	 In this case, we know bit 16 is set and that the low 16 bits
2208169689Skan	 form a negative number.  If we subtract that number from VALUE,
2209169689Skan	 we will clear at least the lowest 17 bits, maybe more.  */
2210169689Skan      i = mips_build_integer (codes, CONST_HIGH_PART (value));
2211169689Skan      codes[i].code = PLUS;
2212169689Skan      codes[i].value = CONST_LOW_PART (value);
2213169689Skan    }
2214169689Skan  else
2215169689Skan    {
2216169689Skan      i = mips_build_integer (codes, high);
2217169689Skan      codes[i].code = IOR;
2218169689Skan      codes[i].value = value & 0xffff;
2219169689Skan    }
2220169689Skan  return i + 1;
2221169689Skan}
2222169689Skan
2223169689Skan
2224169689Skan/* Fill CODES with a sequence of rtl operations to load VALUE.
2225169689Skan   Return the number of operations needed.  */
2226169689Skan
2227169689Skanstatic unsigned int
2228169689Skanmips_build_integer (struct mips_integer_op *codes,
2229169689Skan		    unsigned HOST_WIDE_INT value)
2230169689Skan{
2231169689Skan  if (SMALL_OPERAND (value)
2232169689Skan      || SMALL_OPERAND_UNSIGNED (value)
2233169689Skan      || LUI_OPERAND (value))
2234169689Skan    {
2235169689Skan      /* The value can be loaded with a single instruction.  */
2236169689Skan      codes[0].code = UNKNOWN;
2237169689Skan      codes[0].value = value;
2238169689Skan      return 1;
2239169689Skan    }
2240169689Skan  else if ((value & 1) != 0 || LUI_OPERAND (CONST_HIGH_PART (value)))
2241169689Skan    {
2242169689Skan      /* Either the constant is a simple LUI/ORI combination or its
2243169689Skan	 lowest bit is set.  We don't want to shift in this case.  */
2244169689Skan      return mips_build_lower (codes, value);
2245169689Skan    }
2246169689Skan  else if ((value & 0xffff) == 0)
2247169689Skan    {
2248169689Skan      /* The constant will need at least three actions.  The lowest
2249169689Skan	 16 bits are clear, so the final action will be a shift.  */
2250169689Skan      return mips_build_shift (codes, value);
2251169689Skan    }
2252169689Skan  else
2253169689Skan    {
2254169689Skan      /* The final action could be a shift, add or inclusive OR.
2255169689Skan	 Rather than use a complex condition to select the best
2256169689Skan	 approach, try both mips_build_shift and mips_build_lower
2257169689Skan	 and pick the one that gives the shortest sequence.
2258169689Skan	 Note that this case is only used once per constant.  */
2259169689Skan      struct mips_integer_op alt_codes[MIPS_MAX_INTEGER_OPS];
2260169689Skan      unsigned int cost, alt_cost;
2261169689Skan
2262169689Skan      cost = mips_build_shift (codes, value);
2263169689Skan      alt_cost = mips_build_lower (alt_codes, value);
2264169689Skan      if (alt_cost < cost)
2265169689Skan	{
2266169689Skan	  memcpy (codes, alt_codes, alt_cost * sizeof (codes[0]));
2267169689Skan	  cost = alt_cost;
2268169689Skan	}
2269169689Skan      return cost;
2270169689Skan    }
2271169689Skan}
2272169689Skan
2273169689Skan
2274169689Skan/* Load VALUE into DEST, using TEMP as a temporary register if need be.  */
2275169689Skan
2276169689Skanvoid
2277169689Skanmips_move_integer (rtx dest, rtx temp, unsigned HOST_WIDE_INT value)
2278169689Skan{
2279169689Skan  struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
2280169689Skan  enum machine_mode mode;
2281169689Skan  unsigned int i, cost;
2282169689Skan  rtx x;
2283169689Skan
2284169689Skan  mode = GET_MODE (dest);
2285169689Skan  cost = mips_build_integer (codes, value);
2286169689Skan
2287169689Skan  /* Apply each binary operation to X.  Invariant: X is a legitimate
2288169689Skan     source operand for a SET pattern.  */
2289169689Skan  x = GEN_INT (codes[0].value);
2290169689Skan  for (i = 1; i < cost; i++)
2291169689Skan    {
2292169689Skan      if (no_new_pseudos)
2293169689Skan	{
2294169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, temp, x));
2295169689Skan	  x = temp;
2296169689Skan	}
2297169689Skan      else
2298169689Skan	x = force_reg (mode, x);
2299169689Skan      x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
2300169689Skan    }
2301169689Skan
2302169689Skan  emit_insn (gen_rtx_SET (VOIDmode, dest, x));
2303169689Skan}
2304169689Skan
2305169689Skan
2306169689Skan/* Subroutine of mips_legitimize_move.  Move constant SRC into register
2307169689Skan   DEST given that SRC satisfies immediate_operand but doesn't satisfy
2308169689Skan   move_operand.  */
2309169689Skan
2310169689Skanstatic void
2311169689Skanmips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
2312169689Skan{
2313169689Skan  rtx base;
2314169689Skan  HOST_WIDE_INT offset;
2315169689Skan
2316169689Skan  /* Split moves of big integers into smaller pieces.  */
2317169689Skan  if (splittable_const_int_operand (src, mode))
2318169689Skan    {
2319169689Skan      mips_move_integer (dest, dest, INTVAL (src));
2320169689Skan      return;
2321169689Skan    }
2322169689Skan
2323169689Skan  /* Split moves of symbolic constants into high/low pairs.  */
2324169689Skan  if (splittable_symbolic_operand (src, mode))
2325169689Skan    {
2326169689Skan      emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src)));
2327169689Skan      return;
2328169689Skan    }
2329169689Skan
2330169689Skan  if (mips_tls_operand_p (src))
2331169689Skan    {
2332169689Skan      emit_move_insn (dest, mips_legitimize_tls_address (src));
2333169689Skan      return;
2334169689Skan    }
2335169689Skan
2336169689Skan  /* If we have (const (plus symbol offset)), load the symbol first
2337169689Skan     and then add in the offset.  This is usually better than forcing
2338169689Skan     the constant into memory, at least in non-mips16 code.  */
2339169689Skan  mips_split_const (src, &base, &offset);
2340169689Skan  if (!TARGET_MIPS16
2341169689Skan      && offset != 0
2342169689Skan      && (!no_new_pseudos || SMALL_OPERAND (offset)))
2343169689Skan    {
2344169689Skan      base = mips_force_temporary (dest, base);
2345169689Skan      emit_move_insn (dest, mips_add_offset (0, base, offset));
2346169689Skan      return;
2347169689Skan    }
2348169689Skan
2349169689Skan  src = force_const_mem (mode, src);
2350169689Skan
2351169689Skan  /* When using explicit relocs, constant pool references are sometimes
2352169689Skan     not legitimate addresses.  */
2353169689Skan  if (!memory_operand (src, VOIDmode))
2354169689Skan    src = replace_equiv_address (src, mips_split_symbol (dest, XEXP (src, 0)));
2355169689Skan  emit_move_insn (dest, src);
2356169689Skan}
2357169689Skan
2358169689Skan
2359169689Skan/* If (set DEST SRC) is not a valid instruction, emit an equivalent
2360169689Skan   sequence that is valid.  */
2361169689Skan
2362169689Skanbool
2363169689Skanmips_legitimize_move (enum machine_mode mode, rtx dest, rtx src)
2364169689Skan{
2365169689Skan  if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
2366169689Skan    {
2367169689Skan      emit_move_insn (dest, force_reg (mode, src));
2368169689Skan      return true;
2369169689Skan    }
2370169689Skan
2371169689Skan  /* Check for individual, fully-reloaded mflo and mfhi instructions.  */
2372169689Skan  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
2373169689Skan      && REG_P (src) && MD_REG_P (REGNO (src))
2374169689Skan      && REG_P (dest) && GP_REG_P (REGNO (dest)))
2375169689Skan    {
2376169689Skan      int other_regno = REGNO (src) == HI_REGNUM ? LO_REGNUM : HI_REGNUM;
2377169689Skan      if (GET_MODE_SIZE (mode) <= 4)
2378169689Skan	emit_insn (gen_mfhilo_si (gen_rtx_REG (SImode, REGNO (dest)),
2379169689Skan				  gen_rtx_REG (SImode, REGNO (src)),
2380169689Skan				  gen_rtx_REG (SImode, other_regno)));
2381169689Skan      else
2382169689Skan	emit_insn (gen_mfhilo_di (gen_rtx_REG (DImode, REGNO (dest)),
2383169689Skan				  gen_rtx_REG (DImode, REGNO (src)),
2384169689Skan				  gen_rtx_REG (DImode, other_regno)));
2385169689Skan      return true;
2386169689Skan    }
2387169689Skan
2388169689Skan  /* We need to deal with constants that would be legitimate
2389169689Skan     immediate_operands but not legitimate move_operands.  */
2390169689Skan  if (CONSTANT_P (src) && !move_operand (src, mode))
2391169689Skan    {
2392169689Skan      mips_legitimize_const_move (mode, dest, src);
2393169689Skan      set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
2394169689Skan      return true;
2395169689Skan    }
2396169689Skan  return false;
2397169689Skan}
2398169689Skan
2399169689Skan/* We need a lot of little routines to check constant values on the
2400169689Skan   mips16.  These are used to figure out how long the instruction will
2401169689Skan   be.  It would be much better to do this using constraints, but
2402169689Skan   there aren't nearly enough letters available.  */
2403169689Skan
2404169689Skanstatic int
2405169689Skanm16_check_op (rtx op, int low, int high, int mask)
2406169689Skan{
2407169689Skan  return (GET_CODE (op) == CONST_INT
2408169689Skan	  && INTVAL (op) >= low
2409169689Skan	  && INTVAL (op) <= high
2410169689Skan	  && (INTVAL (op) & mask) == 0);
2411169689Skan}
2412169689Skan
2413169689Skanint
2414169689Skanm16_uimm3_b (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2415169689Skan{
2416169689Skan  return m16_check_op (op, 0x1, 0x8, 0);
2417169689Skan}
2418169689Skan
2419169689Skanint
2420169689Skanm16_simm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2421169689Skan{
2422169689Skan  return m16_check_op (op, - 0x8, 0x7, 0);
2423169689Skan}
2424169689Skan
2425169689Skanint
2426169689Skanm16_nsimm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2427169689Skan{
2428169689Skan  return m16_check_op (op, - 0x7, 0x8, 0);
2429169689Skan}
2430169689Skan
2431169689Skanint
2432169689Skanm16_simm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2433169689Skan{
2434169689Skan  return m16_check_op (op, - 0x10, 0xf, 0);
2435169689Skan}
2436169689Skan
2437169689Skanint
2438169689Skanm16_nsimm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2439169689Skan{
2440169689Skan  return m16_check_op (op, - 0xf, 0x10, 0);
2441169689Skan}
2442169689Skan
2443169689Skanint
2444169689Skanm16_uimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2445169689Skan{
2446169689Skan  return m16_check_op (op, (- 0x10) << 2, 0xf << 2, 3);
2447169689Skan}
2448169689Skan
2449169689Skanint
2450169689Skanm16_nuimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2451169689Skan{
2452169689Skan  return m16_check_op (op, (- 0xf) << 2, 0x10 << 2, 3);
2453169689Skan}
2454169689Skan
2455169689Skanint
2456169689Skanm16_simm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2457169689Skan{
2458169689Skan  return m16_check_op (op, - 0x80, 0x7f, 0);
2459169689Skan}
2460169689Skan
2461169689Skanint
2462169689Skanm16_nsimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2463169689Skan{
2464169689Skan  return m16_check_op (op, - 0x7f, 0x80, 0);
2465169689Skan}
2466169689Skan
2467169689Skanint
2468169689Skanm16_uimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2469169689Skan{
2470169689Skan  return m16_check_op (op, 0x0, 0xff, 0);
2471169689Skan}
2472169689Skan
2473169689Skanint
2474169689Skanm16_nuimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2475169689Skan{
2476169689Skan  return m16_check_op (op, - 0xff, 0x0, 0);
2477169689Skan}
2478169689Skan
2479169689Skanint
2480169689Skanm16_uimm8_m1_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2481169689Skan{
2482169689Skan  return m16_check_op (op, - 0x1, 0xfe, 0);
2483169689Skan}
2484169689Skan
2485169689Skanint
2486169689Skanm16_uimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2487169689Skan{
2488169689Skan  return m16_check_op (op, 0x0, 0xff << 2, 3);
2489169689Skan}
2490169689Skan
2491169689Skanint
2492169689Skanm16_nuimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2493169689Skan{
2494169689Skan  return m16_check_op (op, (- 0xff) << 2, 0x0, 3);
2495169689Skan}
2496169689Skan
2497169689Skanint
2498169689Skanm16_simm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2499169689Skan{
2500169689Skan  return m16_check_op (op, (- 0x80) << 3, 0x7f << 3, 7);
2501169689Skan}
2502169689Skan
2503169689Skanint
2504169689Skanm16_nsimm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
2505169689Skan{
2506169689Skan  return m16_check_op (op, (- 0x7f) << 3, 0x80 << 3, 7);
2507169689Skan}
2508169689Skan
2509169689Skanstatic bool
2510169689Skanmips_rtx_costs (rtx x, int code, int outer_code, int *total)
2511169689Skan{
2512169689Skan  enum machine_mode mode = GET_MODE (x);
2513169689Skan  bool float_mode_p = FLOAT_MODE_P (mode);
2514169689Skan
2515169689Skan  switch (code)
2516169689Skan    {
2517169689Skan    case CONST_INT:
2518169689Skan      if (TARGET_MIPS16)
2519169689Skan        {
2520169689Skan	  /* A number between 1 and 8 inclusive is efficient for a shift.
2521169689Skan	     Otherwise, we will need an extended instruction.  */
2522169689Skan	  if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
2523169689Skan	      || (outer_code) == LSHIFTRT)
2524169689Skan	    {
2525169689Skan	      if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
2526169689Skan		*total = 0;
2527169689Skan	      else
2528169689Skan		*total = COSTS_N_INSNS (1);
2529169689Skan	      return true;
2530169689Skan	    }
2531169689Skan
2532169689Skan	  /* We can use cmpi for an xor with an unsigned 16 bit value.  */
2533169689Skan	  if ((outer_code) == XOR
2534169689Skan	      && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
2535169689Skan	    {
2536169689Skan	      *total = 0;
2537169689Skan	      return true;
2538169689Skan	    }
2539169689Skan
2540169689Skan	  /* We may be able to use slt or sltu for a comparison with a
2541169689Skan	     signed 16 bit value.  (The boundary conditions aren't quite
2542169689Skan	     right, but this is just a heuristic anyhow.)  */
2543169689Skan	  if (((outer_code) == LT || (outer_code) == LE
2544169689Skan	       || (outer_code) == GE || (outer_code) == GT
2545169689Skan	       || (outer_code) == LTU || (outer_code) == LEU
2546169689Skan	       || (outer_code) == GEU || (outer_code) == GTU)
2547169689Skan	      && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
2548169689Skan	    {
2549169689Skan	      *total = 0;
2550169689Skan	      return true;
2551169689Skan	    }
2552169689Skan
2553169689Skan	  /* Equality comparisons with 0 are cheap.  */
2554169689Skan	  if (((outer_code) == EQ || (outer_code) == NE)
2555169689Skan	      && INTVAL (x) == 0)
2556169689Skan	    {
2557169689Skan	      *total = 0;
2558169689Skan	      return true;
2559169689Skan	    }
2560169689Skan
2561169689Skan	  /* Constants in the range 0...255 can be loaded with an unextended
2562169689Skan	     instruction.  They are therefore as cheap as a register move.
2563169689Skan
2564169689Skan	     Given the choice between "li R1,0...255" and "move R1,R2"
2565169689Skan	     (where R2 is a known constant), it is usually better to use "li",
2566169689Skan	     since we do not want to unnecessarily extend the lifetime
2567169689Skan	     of R2.  */
2568169689Skan	  if (outer_code == SET
2569169689Skan	      && INTVAL (x) >= 0
2570169689Skan	      && INTVAL (x) < 256)
2571169689Skan	    {
2572169689Skan	      *total = 0;
2573169689Skan	      return true;
2574169689Skan	    }
2575169689Skan	}
2576169689Skan      else
2577169689Skan	{
2578169689Skan	  /* These can be used anywhere. */
2579169689Skan	  *total = 0;
2580169689Skan	  return true;
2581169689Skan	}
2582169689Skan
2583169689Skan      /* Otherwise fall through to the handling below because
2584169689Skan	 we'll need to construct the constant.  */
2585169689Skan
2586169689Skan    case CONST:
2587169689Skan    case SYMBOL_REF:
2588169689Skan    case LABEL_REF:
2589169689Skan    case CONST_DOUBLE:
2590169689Skan      if (LEGITIMATE_CONSTANT_P (x))
2591169689Skan	{
2592169689Skan	  *total = COSTS_N_INSNS (1);
2593169689Skan	  return true;
2594169689Skan	}
2595169689Skan      else
2596169689Skan	{
2597169689Skan	  /* The value will need to be fetched from the constant pool.  */
2598169689Skan	  *total = CONSTANT_POOL_COST;
2599169689Skan	  return true;
2600169689Skan	}
2601169689Skan
2602169689Skan    case MEM:
2603169689Skan      {
2604169689Skan	/* If the address is legitimate, return the number of
2605169689Skan	   instructions it needs, otherwise use the default handling.  */
2606169689Skan	int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
2607169689Skan	if (n > 0)
2608169689Skan	  {
2609169689Skan	    *total = COSTS_N_INSNS (n + 1);
2610169689Skan	    return true;
2611169689Skan	  }
2612169689Skan	return false;
2613169689Skan      }
2614169689Skan
2615169689Skan    case FFS:
2616169689Skan      *total = COSTS_N_INSNS (6);
2617169689Skan      return true;
2618169689Skan
2619169689Skan    case NOT:
2620169689Skan      *total = COSTS_N_INSNS ((mode == DImode && !TARGET_64BIT) ? 2 : 1);
2621169689Skan      return true;
2622169689Skan
2623169689Skan    case AND:
2624169689Skan    case IOR:
2625169689Skan    case XOR:
2626169689Skan      if (mode == DImode && !TARGET_64BIT)
2627169689Skan        {
2628169689Skan          *total = COSTS_N_INSNS (2);
2629169689Skan          return true;
2630169689Skan        }
2631169689Skan      return false;
2632169689Skan
2633169689Skan    case ASHIFT:
2634169689Skan    case ASHIFTRT:
2635169689Skan    case LSHIFTRT:
2636169689Skan      if (mode == DImode && !TARGET_64BIT)
2637169689Skan        {
2638169689Skan          *total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT)
2639169689Skan                                  ? 4 : 12);
2640169689Skan          return true;
2641169689Skan        }
2642169689Skan      return false;
2643169689Skan
2644169689Skan    case ABS:
2645169689Skan      if (float_mode_p)
2646169689Skan        *total = COSTS_N_INSNS (1);
2647169689Skan      else
2648169689Skan        *total = COSTS_N_INSNS (4);
2649169689Skan      return true;
2650169689Skan
2651169689Skan    case LO_SUM:
2652169689Skan      *total = COSTS_N_INSNS (1);
2653169689Skan      return true;
2654169689Skan
2655169689Skan    case PLUS:
2656169689Skan    case MINUS:
2657169689Skan      if (float_mode_p)
2658169689Skan	{
2659169689Skan	  *total = mips_cost->fp_add;
2660169689Skan	  return true;
2661169689Skan	}
2662169689Skan
2663169689Skan      else if (mode == DImode && !TARGET_64BIT)
2664169689Skan        {
2665169689Skan          *total = COSTS_N_INSNS (4);
2666169689Skan          return true;
2667169689Skan        }
2668169689Skan      return false;
2669169689Skan
2670169689Skan    case NEG:
2671169689Skan      if (mode == DImode && !TARGET_64BIT)
2672169689Skan        {
2673169689Skan          *total = COSTS_N_INSNS (4);
2674169689Skan          return true;
2675169689Skan        }
2676169689Skan      return false;
2677169689Skan
2678169689Skan    case MULT:
2679169689Skan      if (mode == SFmode)
2680169689Skan	*total = mips_cost->fp_mult_sf;
2681169689Skan
2682169689Skan      else if (mode == DFmode)
2683169689Skan	*total = mips_cost->fp_mult_df;
2684169689Skan
2685169689Skan      else if (mode == SImode)
2686169689Skan	*total = mips_cost->int_mult_si;
2687169689Skan
2688169689Skan      else
2689169689Skan	*total = mips_cost->int_mult_di;
2690169689Skan
2691169689Skan      return true;
2692169689Skan
2693169689Skan    case DIV:
2694169689Skan    case MOD:
2695169689Skan      if (float_mode_p)
2696169689Skan	{
2697169689Skan	  if (mode == SFmode)
2698169689Skan	    *total = mips_cost->fp_div_sf;
2699169689Skan	  else
2700169689Skan	    *total = mips_cost->fp_div_df;
2701169689Skan
2702169689Skan	  return true;
2703169689Skan	}
2704169689Skan      /* Fall through.  */
2705169689Skan
2706169689Skan    case UDIV:
2707169689Skan    case UMOD:
2708169689Skan      if (mode == DImode)
2709169689Skan        *total = mips_cost->int_div_di;
2710169689Skan      else
2711169689Skan	*total = mips_cost->int_div_si;
2712169689Skan
2713169689Skan      return true;
2714169689Skan
2715169689Skan    case SIGN_EXTEND:
2716169689Skan      /* A sign extend from SImode to DImode in 64 bit mode is often
2717169689Skan         zero instructions, because the result can often be used
2718169689Skan         directly by another instruction; we'll call it one.  */
2719169689Skan      if (TARGET_64BIT && mode == DImode
2720169689Skan          && GET_MODE (XEXP (x, 0)) == SImode)
2721169689Skan        *total = COSTS_N_INSNS (1);
2722169689Skan      else
2723169689Skan        *total = COSTS_N_INSNS (2);
2724169689Skan      return true;
2725169689Skan
2726169689Skan    case ZERO_EXTEND:
2727169689Skan      if (TARGET_64BIT && mode == DImode
2728169689Skan          && GET_MODE (XEXP (x, 0)) == SImode)
2729169689Skan        *total = COSTS_N_INSNS (2);
2730169689Skan      else
2731169689Skan        *total = COSTS_N_INSNS (1);
2732169689Skan      return true;
2733169689Skan
2734169689Skan    case FLOAT:
2735169689Skan    case UNSIGNED_FLOAT:
2736169689Skan    case FIX:
2737169689Skan    case FLOAT_EXTEND:
2738169689Skan    case FLOAT_TRUNCATE:
2739169689Skan    case SQRT:
2740169689Skan      *total = mips_cost->fp_add;
2741169689Skan      return true;
2742169689Skan
2743169689Skan    default:
2744169689Skan      return false;
2745169689Skan    }
2746169689Skan}
2747169689Skan
2748169689Skan/* Provide the costs of an addressing mode that contains ADDR.
2749169689Skan   If ADDR is not a valid address, its cost is irrelevant.  */
2750169689Skan
2751169689Skanstatic int
2752169689Skanmips_address_cost (rtx addr)
2753169689Skan{
2754169689Skan  return mips_address_insns (addr, SImode);
2755169689Skan}
2756169689Skan
2757169689Skan/* Return one word of double-word value OP, taking into account the fixed
2758169689Skan   endianness of certain registers.  HIGH_P is true to select the high part,
2759169689Skan   false to select the low part.  */
2760169689Skan
2761169689Skanrtx
2762169689Skanmips_subword (rtx op, int high_p)
2763169689Skan{
2764169689Skan  unsigned int byte;
2765169689Skan  enum machine_mode mode;
2766169689Skan
2767169689Skan  mode = GET_MODE (op);
2768169689Skan  if (mode == VOIDmode)
2769169689Skan    mode = DImode;
2770169689Skan
2771169689Skan  if (TARGET_BIG_ENDIAN ? !high_p : high_p)
2772169689Skan    byte = UNITS_PER_WORD;
2773169689Skan  else
2774169689Skan    byte = 0;
2775169689Skan
2776169689Skan  if (REG_P (op))
2777169689Skan    {
2778169689Skan      if (FP_REG_P (REGNO (op)))
2779169689Skan	return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
2780169689Skan      if (ACC_HI_REG_P (REGNO (op)))
2781169689Skan	return gen_rtx_REG (word_mode, high_p ? REGNO (op) : REGNO (op) + 1);
2782169689Skan    }
2783169689Skan
2784169689Skan  if (MEM_P (op))
2785169689Skan    return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
2786169689Skan
2787169689Skan  return simplify_gen_subreg (word_mode, op, mode, byte);
2788169689Skan}
2789169689Skan
2790169689Skan
2791169689Skan/* Return true if a 64-bit move from SRC to DEST should be split into two.  */
2792169689Skan
2793169689Skanbool
2794169689Skanmips_split_64bit_move_p (rtx dest, rtx src)
2795169689Skan{
2796169689Skan  if (TARGET_64BIT)
2797169689Skan    return false;
2798169689Skan
2799169689Skan  /* FP->FP moves can be done in a single instruction.  */
2800169689Skan  if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
2801169689Skan    return false;
2802169689Skan
2803169689Skan  /* Check for floating-point loads and stores.  They can be done using
2804169689Skan     ldc1 and sdc1 on MIPS II and above.  */
2805169689Skan  if (mips_isa > 1)
2806169689Skan    {
2807169689Skan      if (FP_REG_RTX_P (dest) && MEM_P (src))
2808169689Skan	return false;
2809169689Skan      if (FP_REG_RTX_P (src) && MEM_P (dest))
2810169689Skan	return false;
2811169689Skan    }
2812169689Skan  return true;
2813169689Skan}
2814169689Skan
2815169689Skan
2816169689Skan/* Split a 64-bit move from SRC to DEST assuming that
2817169689Skan   mips_split_64bit_move_p holds.
2818169689Skan
2819169689Skan   Moves into and out of FPRs cause some difficulty here.  Such moves
2820169689Skan   will always be DFmode, since paired FPRs are not allowed to store
2821169689Skan   DImode values.  The most natural representation would be two separate
2822169689Skan   32-bit moves, such as:
2823169689Skan
2824169689Skan	(set (reg:SI $f0) (mem:SI ...))
2825169689Skan	(set (reg:SI $f1) (mem:SI ...))
2826169689Skan
2827169689Skan   However, the second insn is invalid because odd-numbered FPRs are
2828169689Skan   not allowed to store independent values.  Use the patterns load_df_low,
2829169689Skan   load_df_high and store_df_high instead.  */
2830169689Skan
2831169689Skanvoid
2832169689Skanmips_split_64bit_move (rtx dest, rtx src)
2833169689Skan{
2834169689Skan  if (FP_REG_RTX_P (dest))
2835169689Skan    {
2836169689Skan      /* Loading an FPR from memory or from GPRs.  */
2837169689Skan      emit_insn (gen_load_df_low (copy_rtx (dest), mips_subword (src, 0)));
2838169689Skan      emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
2839169689Skan				   copy_rtx (dest)));
2840169689Skan    }
2841169689Skan  else if (FP_REG_RTX_P (src))
2842169689Skan    {
2843169689Skan      /* Storing an FPR into memory or GPRs.  */
2844169689Skan      emit_move_insn (mips_subword (dest, 0), mips_subword (src, 0));
2845169689Skan      emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
2846169689Skan    }
2847169689Skan  else
2848169689Skan    {
2849169689Skan      /* The operation can be split into two normal moves.  Decide in
2850169689Skan	 which order to do them.  */
2851169689Skan      rtx low_dest;
2852169689Skan
2853169689Skan      low_dest = mips_subword (dest, 0);
2854169689Skan      if (REG_P (low_dest)
2855169689Skan	  && reg_overlap_mentioned_p (low_dest, src))
2856169689Skan	{
2857169689Skan	  emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2858169689Skan	  emit_move_insn (low_dest, mips_subword (src, 0));
2859169689Skan	}
2860169689Skan      else
2861169689Skan	{
2862169689Skan	  emit_move_insn (low_dest, mips_subword (src, 0));
2863169689Skan	  emit_move_insn (mips_subword (dest, 1), mips_subword (src, 1));
2864169689Skan	}
2865169689Skan    }
2866169689Skan}
2867169689Skan
2868169689Skan/* Return the appropriate instructions to move SRC into DEST.  Assume
2869169689Skan   that SRC is operand 1 and DEST is operand 0.  */
2870169689Skan
2871169689Skanconst char *
2872169689Skanmips_output_move (rtx dest, rtx src)
2873169689Skan{
2874169689Skan  enum rtx_code dest_code, src_code;
2875169689Skan  bool dbl_p;
2876169689Skan
2877169689Skan  dest_code = GET_CODE (dest);
2878169689Skan  src_code = GET_CODE (src);
2879169689Skan  dbl_p = (GET_MODE_SIZE (GET_MODE (dest)) == 8);
2880169689Skan
2881169689Skan  if (dbl_p && mips_split_64bit_move_p (dest, src))
2882169689Skan    return "#";
2883169689Skan
2884169689Skan  if ((src_code == REG && GP_REG_P (REGNO (src)))
2885169689Skan      || (!TARGET_MIPS16 && src == CONST0_RTX (GET_MODE (dest))))
2886169689Skan    {
2887169689Skan      if (dest_code == REG)
2888169689Skan	{
2889169689Skan	  if (GP_REG_P (REGNO (dest)))
2890169689Skan	    return "move\t%0,%z1";
2891169689Skan
2892169689Skan	  if (MD_REG_P (REGNO (dest)))
2893169689Skan	    return "mt%0\t%z1";
2894169689Skan
2895169689Skan	  if (DSP_ACC_REG_P (REGNO (dest)))
2896169689Skan	    {
2897169689Skan	      static char retval[] = "mt__\t%z1,%q0";
2898169689Skan	      retval[2] = reg_names[REGNO (dest)][4];
2899169689Skan	      retval[3] = reg_names[REGNO (dest)][5];
2900169689Skan	      return retval;
2901169689Skan	    }
2902169689Skan
2903169689Skan	  if (FP_REG_P (REGNO (dest)))
2904169689Skan	    return (dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0");
2905169689Skan
2906169689Skan	  if (ALL_COP_REG_P (REGNO (dest)))
2907169689Skan	    {
2908169689Skan	      static char retval[] = "dmtc_\t%z1,%0";
2909169689Skan
2910169689Skan	      retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2911169689Skan	      return (dbl_p ? retval : retval + 1);
2912169689Skan	    }
2913169689Skan	}
2914169689Skan      if (dest_code == MEM)
2915169689Skan	return (dbl_p ? "sd\t%z1,%0" : "sw\t%z1,%0");
2916169689Skan    }
2917169689Skan  if (dest_code == REG && GP_REG_P (REGNO (dest)))
2918169689Skan    {
2919169689Skan      if (src_code == REG)
2920169689Skan	{
2921169689Skan	  if (DSP_ACC_REG_P (REGNO (src)))
2922169689Skan	    {
2923169689Skan	      static char retval[] = "mf__\t%0,%q1";
2924169689Skan	      retval[2] = reg_names[REGNO (src)][4];
2925169689Skan	      retval[3] = reg_names[REGNO (src)][5];
2926169689Skan	      return retval;
2927169689Skan	    }
2928169689Skan
2929169689Skan	  if (ST_REG_P (REGNO (src)) && ISA_HAS_8CC)
2930169689Skan	    return "lui\t%0,0x3f80\n\tmovf\t%0,%.,%1";
2931169689Skan
2932169689Skan	  if (FP_REG_P (REGNO (src)))
2933169689Skan	    return (dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1");
2934169689Skan
2935169689Skan	  if (ALL_COP_REG_P (REGNO (src)))
2936169689Skan	    {
2937169689Skan	      static char retval[] = "dmfc_\t%0,%1";
2938169689Skan
2939169689Skan	      retval[4] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
2940169689Skan	      return (dbl_p ? retval : retval + 1);
2941169689Skan	    }
2942169689Skan	}
2943169689Skan
2944169689Skan      if (src_code == MEM)
2945169689Skan	return (dbl_p ? "ld\t%0,%1" : "lw\t%0,%1");
2946169689Skan
2947169689Skan      if (src_code == CONST_INT)
2948169689Skan	{
2949169689Skan	  /* Don't use the X format, because that will give out of
2950169689Skan	     range numbers for 64 bit hosts and 32 bit targets.  */
2951169689Skan	  if (!TARGET_MIPS16)
2952169689Skan	    return "li\t%0,%1\t\t\t# %X1";
2953169689Skan
2954169689Skan	  if (INTVAL (src) >= 0 && INTVAL (src) <= 0xffff)
2955169689Skan	    return "li\t%0,%1";
2956169689Skan
2957169689Skan	  if (INTVAL (src) < 0 && INTVAL (src) >= -0xffff)
2958169689Skan	    return "#";
2959169689Skan	}
2960169689Skan
2961169689Skan      if (src_code == HIGH)
2962169689Skan	return "lui\t%0,%h1";
2963169689Skan
2964169689Skan      if (CONST_GP_P (src))
2965169689Skan	return "move\t%0,%1";
2966169689Skan
2967169689Skan      if (symbolic_operand (src, VOIDmode))
2968169689Skan	return (dbl_p ? "dla\t%0,%1" : "la\t%0,%1");
2969169689Skan    }
2970169689Skan  if (src_code == REG && FP_REG_P (REGNO (src)))
2971169689Skan    {
2972169689Skan      if (dest_code == REG && FP_REG_P (REGNO (dest)))
2973169689Skan	{
2974169689Skan	  if (GET_MODE (dest) == V2SFmode)
2975169689Skan	    return "mov.ps\t%0,%1";
2976169689Skan	  else
2977169689Skan	    return (dbl_p ? "mov.d\t%0,%1" : "mov.s\t%0,%1");
2978169689Skan	}
2979169689Skan
2980169689Skan      if (dest_code == MEM)
2981169689Skan	return (dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0");
2982169689Skan    }
2983169689Skan  if (dest_code == REG && FP_REG_P (REGNO (dest)))
2984169689Skan    {
2985169689Skan      if (src_code == MEM)
2986169689Skan	return (dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1");
2987169689Skan    }
2988169689Skan  if (dest_code == REG && ALL_COP_REG_P (REGNO (dest)) && src_code == MEM)
2989169689Skan    {
2990169689Skan      static char retval[] = "l_c_\t%0,%1";
2991169689Skan
2992169689Skan      retval[1] = (dbl_p ? 'd' : 'w');
2993169689Skan      retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (dest));
2994169689Skan      return retval;
2995169689Skan    }
2996169689Skan  if (dest_code == MEM && src_code == REG && ALL_COP_REG_P (REGNO (src)))
2997169689Skan    {
2998169689Skan      static char retval[] = "s_c_\t%1,%0";
2999169689Skan
3000169689Skan      retval[1] = (dbl_p ? 'd' : 'w');
3001169689Skan      retval[3] = COPNUM_AS_CHAR_FROM_REGNUM (REGNO (src));
3002169689Skan      return retval;
3003169689Skan    }
3004169689Skan  gcc_unreachable ();
3005169689Skan}
3006169689Skan
3007169689Skan/* Restore $gp from its save slot.  Valid only when using o32 or
3008169689Skan   o64 abicalls.  */
3009169689Skan
3010169689Skanvoid
3011169689Skanmips_restore_gp (void)
3012169689Skan{
3013169689Skan  rtx address, slot;
3014169689Skan
3015169689Skan  gcc_assert (TARGET_ABICALLS && TARGET_OLDABI);
3016169689Skan
3017169689Skan  address = mips_add_offset (pic_offset_table_rtx,
3018169689Skan			     frame_pointer_needed
3019169689Skan			     ? hard_frame_pointer_rtx
3020169689Skan			     : stack_pointer_rtx,
3021169689Skan			     current_function_outgoing_args_size);
3022169689Skan  slot = gen_rtx_MEM (Pmode, address);
3023169689Skan
3024169689Skan  emit_move_insn (pic_offset_table_rtx, slot);
3025169689Skan  if (!TARGET_EXPLICIT_RELOCS)
3026169689Skan    emit_insn (gen_blockage ());
3027169689Skan}
3028169689Skan
3029169689Skan/* Emit an instruction of the form (set TARGET (CODE OP0 OP1)).  */
3030169689Skan
3031169689Skanstatic void
3032169689Skanmips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
3033169689Skan{
3034169689Skan  emit_insn (gen_rtx_SET (VOIDmode, target,
3035169689Skan			  gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
3036169689Skan}
3037169689Skan
3038169689Skan/* Return true if CMP1 is a suitable second operand for relational
3039169689Skan   operator CODE.  See also the *sCC patterns in mips.md.  */
3040169689Skan
3041169689Skanstatic bool
3042169689Skanmips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
3043169689Skan{
3044169689Skan  switch (code)
3045169689Skan    {
3046169689Skan    case GT:
3047169689Skan    case GTU:
3048169689Skan      return reg_or_0_operand (cmp1, VOIDmode);
3049169689Skan
3050169689Skan    case GE:
3051169689Skan    case GEU:
3052169689Skan      return !TARGET_MIPS16 && cmp1 == const1_rtx;
3053169689Skan
3054169689Skan    case LT:
3055169689Skan    case LTU:
3056169689Skan      return arith_operand (cmp1, VOIDmode);
3057169689Skan
3058169689Skan    case LE:
3059169689Skan      return sle_operand (cmp1, VOIDmode);
3060169689Skan
3061169689Skan    case LEU:
3062169689Skan      return sleu_operand (cmp1, VOIDmode);
3063169689Skan
3064169689Skan    default:
3065169689Skan      gcc_unreachable ();
3066169689Skan    }
3067169689Skan}
3068169689Skan
3069169689Skan/* Canonicalize LE or LEU comparisons into LT comparisons when
3070169689Skan   possible to avoid extra instructions or inverting the
3071169689Skan   comparison.  */
3072169689Skan
3073169689Skanstatic bool
3074169689Skanmips_canonicalize_comparison (enum rtx_code *code, rtx *cmp1,
3075169689Skan			      enum machine_mode mode)
3076169689Skan{
3077169689Skan  HOST_WIDE_INT original, plus_one;
3078169689Skan
3079169689Skan  if (GET_CODE (*cmp1) != CONST_INT)
3080169689Skan    return false;
3081169689Skan
3082169689Skan  original = INTVAL (*cmp1);
3083169689Skan  plus_one = trunc_int_for_mode ((unsigned HOST_WIDE_INT) original + 1, mode);
3084169689Skan
3085169689Skan  switch (*code)
3086169689Skan    {
3087169689Skan    case LE:
3088169689Skan      if (original < plus_one)
3089169689Skan	{
3090169689Skan	  *code = LT;
3091169689Skan	  *cmp1 = force_reg (mode, GEN_INT (plus_one));
3092169689Skan	  return true;
3093169689Skan	}
3094169689Skan      break;
3095169689Skan
3096169689Skan    case LEU:
3097169689Skan      if (plus_one != 0)
3098169689Skan	{
3099169689Skan	  *code = LTU;
3100169689Skan	  *cmp1 = force_reg (mode, GEN_INT (plus_one));
3101169689Skan	  return true;
3102169689Skan	}
3103169689Skan      break;
3104169689Skan
3105169689Skan    default:
3106169689Skan      return false;
3107169689Skan   }
3108169689Skan
3109169689Skan  return false;
3110169689Skan
3111169689Skan}
3112169689Skan
3113169689Skan/* Compare CMP0 and CMP1 using relational operator CODE and store the
3114169689Skan   result in TARGET.  CMP0 and TARGET are register_operands that have
3115169689Skan   the same integer mode.  If INVERT_PTR is nonnull, it's OK to set
3116169689Skan   TARGET to the inverse of the result and flip *INVERT_PTR instead.  */
3117169689Skan
3118169689Skanstatic void
3119169689Skanmips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
3120169689Skan			  rtx target, rtx cmp0, rtx cmp1)
3121169689Skan{
3122169689Skan  /* First see if there is a MIPS instruction that can do this operation
3123169689Skan     with CMP1 in its current form. If not, try to canonicalize the
3124169689Skan     comparison to LT. If that fails, try doing the same for the
3125169689Skan     inverse operation.  If that also fails, force CMP1 into a register
3126169689Skan     and try again.  */
3127169689Skan  if (mips_relational_operand_ok_p (code, cmp1))
3128169689Skan    mips_emit_binary (code, target, cmp0, cmp1);
3129169689Skan  else if (mips_canonicalize_comparison (&code, &cmp1, GET_MODE (target)))
3130169689Skan    mips_emit_binary (code, target, cmp0, cmp1);
3131169689Skan  else
3132169689Skan    {
3133169689Skan      enum rtx_code inv_code = reverse_condition (code);
3134169689Skan      if (!mips_relational_operand_ok_p (inv_code, cmp1))
3135169689Skan	{
3136169689Skan	  cmp1 = force_reg (GET_MODE (cmp0), cmp1);
3137169689Skan	  mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);
3138169689Skan	}
3139169689Skan      else if (invert_ptr == 0)
3140169689Skan	{
3141169689Skan	  rtx inv_target = gen_reg_rtx (GET_MODE (target));
3142169689Skan	  mips_emit_binary (inv_code, inv_target, cmp0, cmp1);
3143169689Skan	  mips_emit_binary (XOR, target, inv_target, const1_rtx);
3144169689Skan	}
3145169689Skan      else
3146169689Skan	{
3147169689Skan	  *invert_ptr = !*invert_ptr;
3148169689Skan	  mips_emit_binary (inv_code, target, cmp0, cmp1);
3149169689Skan	}
3150169689Skan    }
3151169689Skan}
3152169689Skan
3153169689Skan/* Return a register that is zero iff CMP0 and CMP1 are equal.
3154169689Skan   The register will have the same mode as CMP0.  */
3155169689Skan
3156169689Skanstatic rtx
3157169689Skanmips_zero_if_equal (rtx cmp0, rtx cmp1)
3158169689Skan{
3159169689Skan  if (cmp1 == const0_rtx)
3160169689Skan    return cmp0;
3161169689Skan
3162169689Skan  if (uns_arith_operand (cmp1, VOIDmode))
3163169689Skan    return expand_binop (GET_MODE (cmp0), xor_optab,
3164169689Skan			 cmp0, cmp1, 0, 0, OPTAB_DIRECT);
3165169689Skan
3166169689Skan  return expand_binop (GET_MODE (cmp0), sub_optab,
3167169689Skan		       cmp0, cmp1, 0, 0, OPTAB_DIRECT);
3168169689Skan}
3169169689Skan
3170169689Skan/* Convert *CODE into a code that can be used in a floating-point
3171169689Skan   scc instruction (c.<cond>.<fmt>).  Return true if the values of
3172169689Skan   the condition code registers will be inverted, with 0 indicating
3173169689Skan   that the condition holds.  */
3174169689Skan
3175169689Skanstatic bool
3176169689Skanmips_reverse_fp_cond_p (enum rtx_code *code)
3177169689Skan{
3178169689Skan  switch (*code)
3179169689Skan    {
3180169689Skan    case NE:
3181169689Skan    case LTGT:
3182169689Skan    case ORDERED:
3183169689Skan      *code = reverse_condition_maybe_unordered (*code);
3184169689Skan      return true;
3185169689Skan
3186169689Skan    default:
3187169689Skan      return false;
3188169689Skan    }
3189169689Skan}
3190169689Skan
3191169689Skan/* Convert a comparison into something that can be used in a branch or
3192169689Skan   conditional move.  cmp_operands[0] and cmp_operands[1] are the values
3193169689Skan   being compared and *CODE is the code used to compare them.
3194169689Skan
3195169689Skan   Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
3196169689Skan   If NEED_EQ_NE_P, then only EQ/NE comparisons against zero are possible,
3197169689Skan   otherwise any standard branch condition can be used.  The standard branch
3198169689Skan   conditions are:
3199169689Skan
3200169689Skan      - EQ/NE between two registers.
3201169689Skan      - any comparison between a register and zero.  */
3202169689Skan
3203169689Skanstatic void
3204169689Skanmips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
3205169689Skan{
3206169689Skan  if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT)
3207169689Skan    {
3208169689Skan      if (!need_eq_ne_p && cmp_operands[1] == const0_rtx)
3209169689Skan	{
3210169689Skan	  *op0 = cmp_operands[0];
3211169689Skan	  *op1 = cmp_operands[1];
3212169689Skan	}
3213169689Skan      else if (*code == EQ || *code == NE)
3214169689Skan	{
3215169689Skan	  if (need_eq_ne_p)
3216169689Skan	    {
3217169689Skan	      *op0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
3218169689Skan	      *op1 = const0_rtx;
3219169689Skan	    }
3220169689Skan	  else
3221169689Skan	    {
3222169689Skan	      *op0 = cmp_operands[0];
3223169689Skan	      *op1 = force_reg (GET_MODE (*op0), cmp_operands[1]);
3224169689Skan	    }
3225169689Skan	}
3226169689Skan      else
3227169689Skan	{
3228169689Skan	  /* The comparison needs a separate scc instruction.  Store the
3229169689Skan	     result of the scc in *OP0 and compare it against zero.  */
3230169689Skan	  bool invert = false;
3231169689Skan	  *op0 = gen_reg_rtx (GET_MODE (cmp_operands[0]));
3232169689Skan	  *op1 = const0_rtx;
3233169689Skan	  mips_emit_int_relational (*code, &invert, *op0,
3234169689Skan				    cmp_operands[0], cmp_operands[1]);
3235169689Skan	  *code = (invert ? EQ : NE);
3236169689Skan	}
3237169689Skan    }
3238169689Skan  else
3239169689Skan    {
3240169689Skan      enum rtx_code cmp_code;
3241169689Skan
3242169689Skan      /* Floating-point tests use a separate c.cond.fmt comparison to
3243169689Skan	 set a condition code register.  The branch or conditional move
3244169689Skan	 will then compare that register against zero.
3245169689Skan
3246169689Skan	 Set CMP_CODE to the code of the comparison instruction and
3247169689Skan	 *CODE to the code that the branch or move should use.  */
3248169689Skan      cmp_code = *code;
3249169689Skan      *code = mips_reverse_fp_cond_p (&cmp_code) ? EQ : NE;
3250169689Skan      *op0 = (ISA_HAS_8CC
3251169689Skan	      ? gen_reg_rtx (CCmode)
3252169689Skan	      : gen_rtx_REG (CCmode, FPSW_REGNUM));
3253169689Skan      *op1 = const0_rtx;
3254169689Skan      mips_emit_binary (cmp_code, *op0, cmp_operands[0], cmp_operands[1]);
3255169689Skan    }
3256169689Skan}
3257169689Skan
3258169689Skan/* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
3259169689Skan   Store the result in TARGET and return true if successful.
3260169689Skan
3261169689Skan   On 64-bit targets, TARGET may be wider than cmp_operands[0].  */
3262169689Skan
3263169689Skanbool
3264169689Skanmips_emit_scc (enum rtx_code code, rtx target)
3265169689Skan{
3266169689Skan  if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
3267169689Skan    return false;
3268169689Skan
3269169689Skan  target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
3270169689Skan  if (code == EQ || code == NE)
3271169689Skan    {
3272169689Skan      rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
3273169689Skan      mips_emit_binary (code, target, zie, const0_rtx);
3274169689Skan    }
3275169689Skan  else
3276169689Skan    mips_emit_int_relational (code, 0, target,
3277169689Skan			      cmp_operands[0], cmp_operands[1]);
3278169689Skan  return true;
3279169689Skan}
3280169689Skan
3281169689Skan/* Emit the common code for doing conditional branches.
3282169689Skan   operand[0] is the label to jump to.
3283169689Skan   The comparison operands are saved away by cmp{si,di,sf,df}.  */
3284169689Skan
3285169689Skanvoid
3286169689Skangen_conditional_branch (rtx *operands, enum rtx_code code)
3287169689Skan{
3288169689Skan  rtx op0, op1, condition;
3289169689Skan
3290169689Skan  mips_emit_compare (&code, &op0, &op1, TARGET_MIPS16);
3291169689Skan  condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
3292169689Skan  emit_jump_insn (gen_condjump (condition, operands[0]));
3293169689Skan}
3294169689Skan
3295169689Skan/* Implement:
3296169689Skan
3297169689Skan   (set temp (COND:CCV2 CMP_OP0 CMP_OP1))
3298169689Skan   (set DEST (unspec [TRUE_SRC FALSE_SRC temp] UNSPEC_MOVE_TF_PS))  */
3299169689Skan
3300169689Skanvoid
3301169689Skanmips_expand_vcondv2sf (rtx dest, rtx true_src, rtx false_src,
3302169689Skan		       enum rtx_code cond, rtx cmp_op0, rtx cmp_op1)
3303169689Skan{
3304169689Skan  rtx cmp_result;
3305169689Skan  bool reversed_p;
3306169689Skan
3307169689Skan  reversed_p = mips_reverse_fp_cond_p (&cond);
3308169689Skan  cmp_result = gen_reg_rtx (CCV2mode);
3309169689Skan  emit_insn (gen_scc_ps (cmp_result,
3310169689Skan			 gen_rtx_fmt_ee (cond, VOIDmode, cmp_op0, cmp_op1)));
3311169689Skan  if (reversed_p)
3312169689Skan    emit_insn (gen_mips_cond_move_tf_ps (dest, false_src, true_src,
3313169689Skan					 cmp_result));
3314169689Skan  else
3315169689Skan    emit_insn (gen_mips_cond_move_tf_ps (dest, true_src, false_src,
3316169689Skan					 cmp_result));
3317169689Skan}
3318169689Skan
3319169689Skan/* Emit the common code for conditional moves.  OPERANDS is the array
3320169689Skan   of operands passed to the conditional move define_expand.  */
3321169689Skan
3322169689Skanvoid
3323169689Skangen_conditional_move (rtx *operands)
3324169689Skan{
3325169689Skan  enum rtx_code code;
3326169689Skan  rtx op0, op1;
3327169689Skan
3328169689Skan  code = GET_CODE (operands[1]);
3329169689Skan  mips_emit_compare (&code, &op0, &op1, true);
3330169689Skan  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3331169689Skan			  gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
3332169689Skan						gen_rtx_fmt_ee (code,
3333169689Skan								GET_MODE (op0),
3334169689Skan								op0, op1),
3335169689Skan						operands[2], operands[3])));
3336169689Skan}
3337169689Skan
3338169689Skan/* Emit a conditional trap.  OPERANDS is the array of operands passed to
3339169689Skan   the conditional_trap expander.  */
3340169689Skan
3341169689Skanvoid
3342169689Skanmips_gen_conditional_trap (rtx *operands)
3343169689Skan{
3344169689Skan  rtx op0, op1;
3345169689Skan  enum rtx_code cmp_code = GET_CODE (operands[0]);
3346169689Skan  enum machine_mode mode = GET_MODE (cmp_operands[0]);
3347169689Skan
3348169689Skan  /* MIPS conditional trap machine instructions don't have GT or LE
3349169689Skan     flavors, so we must invert the comparison and convert to LT and
3350169689Skan     GE, respectively.  */
3351169689Skan  switch (cmp_code)
3352169689Skan    {
3353169689Skan    case GT: cmp_code = LT; break;
3354169689Skan    case LE: cmp_code = GE; break;
3355169689Skan    case GTU: cmp_code = LTU; break;
3356169689Skan    case LEU: cmp_code = GEU; break;
3357169689Skan    default: break;
3358169689Skan    }
3359169689Skan  if (cmp_code == GET_CODE (operands[0]))
3360169689Skan    {
3361169689Skan      op0 = cmp_operands[0];
3362169689Skan      op1 = cmp_operands[1];
3363169689Skan    }
3364169689Skan  else
3365169689Skan    {
3366169689Skan      op0 = cmp_operands[1];
3367169689Skan      op1 = cmp_operands[0];
3368169689Skan    }
3369169689Skan  op0 = force_reg (mode, op0);
3370169689Skan  if (!arith_operand (op1, mode))
3371169689Skan    op1 = force_reg (mode, op1);
3372169689Skan
3373169689Skan  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
3374169689Skan			      gen_rtx_fmt_ee (cmp_code, mode, op0, op1),
3375169689Skan			      operands[1]));
3376169689Skan}
3377169689Skan
3378169689Skan/* Load function address ADDR into register DEST.  SIBCALL_P is true
3379169689Skan   if the address is needed for a sibling call.  */
3380169689Skan
3381169689Skanstatic void
3382169689Skanmips_load_call_address (rtx dest, rtx addr, int sibcall_p)
3383169689Skan{
3384169689Skan  /* If we're generating PIC, and this call is to a global function,
3385169689Skan     try to allow its address to be resolved lazily.  This isn't
3386169689Skan     possible for NewABI sibcalls since the value of $gp on entry
3387169689Skan     to the stub would be our caller's gp, not ours.  */
3388169689Skan  if (TARGET_EXPLICIT_RELOCS
3389169689Skan      && !(sibcall_p && TARGET_NEWABI)
3390169689Skan      && global_got_operand (addr, VOIDmode))
3391169689Skan    {
3392169689Skan      rtx high, lo_sum_symbol;
3393169689Skan
3394169689Skan      high = mips_unspec_offset_high (dest, pic_offset_table_rtx,
3395169689Skan				      addr, SYMBOL_GOTOFF_CALL);
3396169689Skan      lo_sum_symbol = mips_unspec_address (addr, SYMBOL_GOTOFF_CALL);
3397169689Skan      if (Pmode == SImode)
3398169689Skan	emit_insn (gen_load_callsi (dest, high, lo_sum_symbol));
3399169689Skan      else
3400169689Skan	emit_insn (gen_load_calldi (dest, high, lo_sum_symbol));
3401169689Skan    }
3402169689Skan  else
3403169689Skan    emit_move_insn (dest, addr);
3404169689Skan}
3405169689Skan
3406169689Skan
3407169689Skan/* Expand a call or call_value instruction.  RESULT is where the
3408169689Skan   result will go (null for calls), ADDR is the address of the
3409169689Skan   function, ARGS_SIZE is the size of the arguments and AUX is
3410169689Skan   the value passed to us by mips_function_arg.  SIBCALL_P is true
3411169689Skan   if we are expanding a sibling call, false if we're expanding
3412169689Skan   a normal call.  */
3413169689Skan
3414169689Skanvoid
3415169689Skanmips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
3416169689Skan{
3417169689Skan  rtx orig_addr, pattern, insn;
3418169689Skan
3419169689Skan  orig_addr = addr;
3420169689Skan  if (!call_insn_operand (addr, VOIDmode))
3421169689Skan    {
3422169689Skan      addr = gen_reg_rtx (Pmode);
3423169689Skan      mips_load_call_address (addr, orig_addr, sibcall_p);
3424169689Skan    }
3425169689Skan
3426169689Skan  if (TARGET_MIPS16
3427169689Skan      && mips16_hard_float
3428169689Skan      && build_mips16_call_stub (result, addr, args_size,
3429169689Skan				 aux == 0 ? 0 : (int) GET_MODE (aux)))
3430169689Skan    return;
3431169689Skan
3432169689Skan  if (result == 0)
3433169689Skan    pattern = (sibcall_p
3434169689Skan	       ? gen_sibcall_internal (addr, args_size)
3435169689Skan	       : gen_call_internal (addr, args_size));
3436169689Skan  else if (GET_CODE (result) == PARALLEL && XVECLEN (result, 0) == 2)
3437169689Skan    {
3438169689Skan      rtx reg1, reg2;
3439169689Skan
3440169689Skan      reg1 = XEXP (XVECEXP (result, 0, 0), 0);
3441169689Skan      reg2 = XEXP (XVECEXP (result, 0, 1), 0);
3442169689Skan      pattern =
3443169689Skan	(sibcall_p
3444169689Skan	 ? gen_sibcall_value_multiple_internal (reg1, addr, args_size, reg2)
3445169689Skan	 : gen_call_value_multiple_internal (reg1, addr, args_size, reg2));
3446169689Skan    }
3447169689Skan  else
3448169689Skan    pattern = (sibcall_p
3449169689Skan	       ? gen_sibcall_value_internal (result, addr, args_size)
3450169689Skan	       : gen_call_value_internal (result, addr, args_size));
3451169689Skan
3452169689Skan  insn = emit_call_insn (pattern);
3453169689Skan
3454169689Skan  /* Lazy-binding stubs require $gp to be valid on entry.  */
3455169689Skan  if (global_got_operand (orig_addr, VOIDmode))
3456169689Skan    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
3457169689Skan}
3458169689Skan
3459169689Skan
3460169689Skan/* We can handle any sibcall when TARGET_SIBCALLS is true.  */
3461169689Skan
3462169689Skanstatic bool
3463169689Skanmips_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
3464169689Skan			      tree exp ATTRIBUTE_UNUSED)
3465169689Skan{
3466169689Skan  return TARGET_SIBCALLS;
3467169689Skan}
3468169689Skan
3469169689Skan/* Emit code to move general operand SRC into condition-code
3470169689Skan   register DEST.  SCRATCH is a scratch TFmode float register.
3471169689Skan   The sequence is:
3472169689Skan
3473169689Skan	FP1 = SRC
3474169689Skan	FP2 = 0.0f
3475169689Skan	DEST = FP2 < FP1
3476169689Skan
3477169689Skan   where FP1 and FP2 are single-precision float registers
3478169689Skan   taken from SCRATCH.  */
3479169689Skan
3480169689Skanvoid
3481169689Skanmips_emit_fcc_reload (rtx dest, rtx src, rtx scratch)
3482169689Skan{
3483169689Skan  rtx fp1, fp2;
3484169689Skan
3485169689Skan  /* Change the source to SFmode.  */
3486169689Skan  if (MEM_P (src))
3487169689Skan    src = adjust_address (src, SFmode, 0);
3488169689Skan  else if (REG_P (src) || GET_CODE (src) == SUBREG)
3489169689Skan    src = gen_rtx_REG (SFmode, true_regnum (src));
3490169689Skan
3491169689Skan  fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
3492169689Skan  fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + FP_INC);
3493169689Skan
3494169689Skan  emit_move_insn (copy_rtx (fp1), src);
3495169689Skan  emit_move_insn (copy_rtx (fp2), CONST0_RTX (SFmode));
3496169689Skan  emit_insn (gen_slt_sf (dest, fp2, fp1));
3497169689Skan}
3498169689Skan
3499169689Skan/* Emit code to change the current function's return address to
3500169689Skan   ADDRESS.  SCRATCH is available as a scratch register, if needed.
3501169689Skan   ADDRESS and SCRATCH are both word-mode GPRs.  */
3502169689Skan
3503169689Skanvoid
3504169689Skanmips_set_return_address (rtx address, rtx scratch)
3505169689Skan{
3506169689Skan  rtx slot_address;
3507169689Skan
3508169689Skan  compute_frame_size (get_frame_size ());
3509169689Skan  gcc_assert ((cfun->machine->frame.mask >> 31) & 1);
3510169689Skan  slot_address = mips_add_offset (scratch, stack_pointer_rtx,
3511169689Skan				  cfun->machine->frame.gp_sp_offset);
3512169689Skan
3513169689Skan  emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address);
3514169689Skan}
3515169689Skan
3516169689Skan/* Emit straight-line code to move LENGTH bytes from SRC to DEST.
3517169689Skan   Assume that the areas do not overlap.  */
3518169689Skan
3519169689Skanstatic void
3520169689Skanmips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
3521169689Skan{
3522169689Skan  HOST_WIDE_INT offset, delta;
3523169689Skan  unsigned HOST_WIDE_INT bits;
3524169689Skan  int i;
3525169689Skan  enum machine_mode mode;
3526169689Skan  rtx *regs;
3527169689Skan
3528169689Skan  /* Work out how many bits to move at a time.  If both operands have
3529169689Skan     half-word alignment, it is usually better to move in half words.
3530169689Skan     For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
3531169689Skan     and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
3532169689Skan     Otherwise move word-sized chunks.  */
3533169689Skan  if (MEM_ALIGN (src) == BITS_PER_WORD / 2
3534169689Skan      && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
3535169689Skan    bits = BITS_PER_WORD / 2;
3536169689Skan  else
3537169689Skan    bits = BITS_PER_WORD;
3538169689Skan
3539169689Skan  mode = mode_for_size (bits, MODE_INT, 0);
3540169689Skan  delta = bits / BITS_PER_UNIT;
3541169689Skan
3542169689Skan  /* Allocate a buffer for the temporary registers.  */
3543169689Skan  regs = alloca (sizeof (rtx) * length / delta);
3544169689Skan
3545169689Skan  /* Load as many BITS-sized chunks as possible.  Use a normal load if
3546169689Skan     the source has enough alignment, otherwise use left/right pairs.  */
3547169689Skan  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
3548169689Skan    {
3549169689Skan      regs[i] = gen_reg_rtx (mode);
3550169689Skan      if (MEM_ALIGN (src) >= bits)
3551169689Skan	emit_move_insn (regs[i], adjust_address (src, mode, offset));
3552169689Skan      else
3553169689Skan	{
3554169689Skan	  rtx part = adjust_address (src, BLKmode, offset);
3555169689Skan	  if (!mips_expand_unaligned_load (regs[i], part, bits, 0))
3556169689Skan	    gcc_unreachable ();
3557169689Skan	}
3558169689Skan    }
3559169689Skan
3560169689Skan  /* Copy the chunks to the destination.  */
3561169689Skan  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
3562169689Skan    if (MEM_ALIGN (dest) >= bits)
3563169689Skan      emit_move_insn (adjust_address (dest, mode, offset), regs[i]);
3564169689Skan    else
3565169689Skan      {
3566169689Skan	rtx part = adjust_address (dest, BLKmode, offset);
3567169689Skan	if (!mips_expand_unaligned_store (part, regs[i], bits, 0))
3568169689Skan	  gcc_unreachable ();
3569169689Skan      }
3570169689Skan
3571169689Skan  /* Mop up any left-over bytes.  */
3572169689Skan  if (offset < length)
3573169689Skan    {
3574169689Skan      src = adjust_address (src, BLKmode, offset);
3575169689Skan      dest = adjust_address (dest, BLKmode, offset);
3576169689Skan      move_by_pieces (dest, src, length - offset,
3577169689Skan		      MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0);
3578169689Skan    }
3579169689Skan}
3580169689Skan
3581169689Skan#define MAX_MOVE_REGS 4
3582169689Skan#define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
3583169689Skan
3584169689Skan
3585169689Skan/* Helper function for doing a loop-based block operation on memory
3586169689Skan   reference MEM.  Each iteration of the loop will operate on LENGTH
3587169689Skan   bytes of MEM.
3588169689Skan
3589169689Skan   Create a new base register for use within the loop and point it to
3590169689Skan   the start of MEM.  Create a new memory reference that uses this
3591169689Skan   register.  Store them in *LOOP_REG and *LOOP_MEM respectively.  */
3592169689Skan
3593169689Skanstatic void
3594169689Skanmips_adjust_block_mem (rtx mem, HOST_WIDE_INT length,
3595169689Skan		       rtx *loop_reg, rtx *loop_mem)
3596169689Skan{
3597169689Skan  *loop_reg = copy_addr_to_reg (XEXP (mem, 0));
3598169689Skan
3599169689Skan  /* Although the new mem does not refer to a known location,
3600169689Skan     it does keep up to LENGTH bytes of alignment.  */
3601169689Skan  *loop_mem = change_address (mem, BLKmode, *loop_reg);
3602169689Skan  set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
3603169689Skan}
3604169689Skan
3605169689Skan
3606169689Skan/* Move LENGTH bytes from SRC to DEST using a loop that moves MAX_MOVE_BYTES
3607169689Skan   per iteration.  LENGTH must be at least MAX_MOVE_BYTES.  Assume that the
3608169689Skan   memory regions do not overlap.  */
3609169689Skan
3610169689Skanstatic void
3611169689Skanmips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length)
3612169689Skan{
3613169689Skan  rtx label, src_reg, dest_reg, final_src;
3614169689Skan  HOST_WIDE_INT leftover;
3615169689Skan
3616169689Skan  leftover = length % MAX_MOVE_BYTES;
3617169689Skan  length -= leftover;
3618169689Skan
3619169689Skan  /* Create registers and memory references for use within the loop.  */
3620169689Skan  mips_adjust_block_mem (src, MAX_MOVE_BYTES, &src_reg, &src);
3621169689Skan  mips_adjust_block_mem (dest, MAX_MOVE_BYTES, &dest_reg, &dest);
3622169689Skan
3623169689Skan  /* Calculate the value that SRC_REG should have after the last iteration
3624169689Skan     of the loop.  */
3625169689Skan  final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
3626169689Skan				   0, 0, OPTAB_WIDEN);
3627169689Skan
3628169689Skan  /* Emit the start of the loop.  */
3629169689Skan  label = gen_label_rtx ();
3630169689Skan  emit_label (label);
3631169689Skan
3632169689Skan  /* Emit the loop body.  */
3633169689Skan  mips_block_move_straight (dest, src, MAX_MOVE_BYTES);
3634169689Skan
3635169689Skan  /* Move on to the next block.  */
3636169689Skan  emit_move_insn (src_reg, plus_constant (src_reg, MAX_MOVE_BYTES));
3637169689Skan  emit_move_insn (dest_reg, plus_constant (dest_reg, MAX_MOVE_BYTES));
3638169689Skan
3639169689Skan  /* Emit the loop condition.  */
3640169689Skan  if (Pmode == DImode)
3641169689Skan    emit_insn (gen_cmpdi (src_reg, final_src));
3642169689Skan  else
3643169689Skan    emit_insn (gen_cmpsi (src_reg, final_src));
3644169689Skan  emit_jump_insn (gen_bne (label));
3645169689Skan
3646169689Skan  /* Mop up any left-over bytes.  */
3647169689Skan  if (leftover)
3648169689Skan    mips_block_move_straight (dest, src, leftover);
3649169689Skan}
3650169689Skan
3651169689Skan/* Expand a movmemsi instruction.  */
3652169689Skan
3653169689Skanbool
3654169689Skanmips_expand_block_move (rtx dest, rtx src, rtx length)
3655169689Skan{
3656169689Skan  if (GET_CODE (length) == CONST_INT)
3657169689Skan    {
3658169689Skan      if (INTVAL (length) <= 2 * MAX_MOVE_BYTES)
3659169689Skan	{
3660169689Skan	  mips_block_move_straight (dest, src, INTVAL (length));
3661169689Skan	  return true;
3662169689Skan	}
3663169689Skan      else if (optimize)
3664169689Skan	{
3665169689Skan	  mips_block_move_loop (dest, src, INTVAL (length));
3666169689Skan	  return true;
3667169689Skan	}
3668169689Skan    }
3669169689Skan  return false;
3670169689Skan}
3671169689Skan
3672169689Skan/* Argument support functions.  */
3673169689Skan
3674169689Skan/* Initialize CUMULATIVE_ARGS for a function.  */
3675169689Skan
3676169689Skanvoid
3677169689Skaninit_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
3678169689Skan		      rtx libname ATTRIBUTE_UNUSED)
3679169689Skan{
3680169689Skan  static CUMULATIVE_ARGS zero_cum;
3681169689Skan  tree param, next_param;
3682169689Skan
3683169689Skan  *cum = zero_cum;
3684169689Skan  cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
3685169689Skan
3686169689Skan  /* Determine if this function has variable arguments.  This is
3687169689Skan     indicated by the last argument being 'void_type_mode' if there
3688169689Skan     are no variable arguments.  The standard MIPS calling sequence
3689169689Skan     passes all arguments in the general purpose registers in this case.  */
3690169689Skan
3691169689Skan  for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
3692169689Skan       param != 0; param = next_param)
3693169689Skan    {
3694169689Skan      next_param = TREE_CHAIN (param);
3695169689Skan      if (next_param == 0 && TREE_VALUE (param) != void_type_node)
3696169689Skan	cum->gp_reg_found = 1;
3697169689Skan    }
3698169689Skan}
3699169689Skan
3700169689Skan
3701169689Skan/* Fill INFO with information about a single argument.  CUM is the
3702169689Skan   cumulative state for earlier arguments.  MODE is the mode of this
3703169689Skan   argument and TYPE is its type (if known).  NAMED is true if this
3704169689Skan   is a named (fixed) argument rather than a variable one.  */
3705169689Skan
3706169689Skanstatic void
3707169689Skanmips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
3708169689Skan	       tree type, int named, struct mips_arg_info *info)
3709169689Skan{
3710169689Skan  bool doubleword_aligned_p;
3711169689Skan  unsigned int num_bytes, num_words, max_regs;
3712169689Skan
3713169689Skan  /* Work out the size of the argument.  */
3714169689Skan  num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
3715169689Skan  num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3716169689Skan
3717169689Skan  /* Decide whether it should go in a floating-point register, assuming
3718169689Skan     one is free.  Later code checks for availability.
3719169689Skan
3720169689Skan     The checks against UNITS_PER_FPVALUE handle the soft-float and
3721169689Skan     single-float cases.  */
3722169689Skan  switch (mips_abi)
3723169689Skan    {
3724169689Skan    case ABI_EABI:
3725169689Skan      /* The EABI conventions have traditionally been defined in terms
3726169689Skan	 of TYPE_MODE, regardless of the actual type.  */
3727169689Skan      info->fpr_p = ((GET_MODE_CLASS (mode) == MODE_FLOAT
3728169689Skan		      || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
3729169689Skan		     && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
3730169689Skan      break;
3731169689Skan
3732169689Skan    case ABI_32:
3733169689Skan    case ABI_O64:
3734169689Skan      /* Only leading floating-point scalars are passed in
3735169689Skan	 floating-point registers.  We also handle vector floats the same
3736169689Skan	 say, which is OK because they are not covered by the standard ABI.  */
3737169689Skan      info->fpr_p = (!cum->gp_reg_found
3738169689Skan		     && cum->arg_number < 2
3739169689Skan		     && (type == 0 || SCALAR_FLOAT_TYPE_P (type)
3740169689Skan			 || VECTOR_FLOAT_TYPE_P (type))
3741169689Skan		     && (GET_MODE_CLASS (mode) == MODE_FLOAT
3742169689Skan			 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
3743169689Skan		     && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
3744169689Skan      break;
3745169689Skan
3746169689Skan    case ABI_N32:
3747169689Skan    case ABI_64:
3748169689Skan      /* Scalar and complex floating-point types are passed in
3749169689Skan	 floating-point registers.  */
3750169689Skan      info->fpr_p = (named
3751169689Skan		     && (type == 0 || FLOAT_TYPE_P (type))
3752169689Skan		     && (GET_MODE_CLASS (mode) == MODE_FLOAT
3753169689Skan			 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3754169689Skan			 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
3755169689Skan		     && GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FPVALUE);
3756169689Skan
3757169689Skan      /* ??? According to the ABI documentation, the real and imaginary
3758169689Skan	 parts of complex floats should be passed in individual registers.
3759169689Skan	 The real and imaginary parts of stack arguments are supposed
3760169689Skan	 to be contiguous and there should be an extra word of padding
3761169689Skan	 at the end.
3762169689Skan
3763169689Skan	 This has two problems.  First, it makes it impossible to use a
3764169689Skan	 single "void *" va_list type, since register and stack arguments
3765169689Skan	 are passed differently.  (At the time of writing, MIPSpro cannot
3766169689Skan	 handle complex float varargs correctly.)  Second, it's unclear
3767169689Skan	 what should happen when there is only one register free.
3768169689Skan
3769169689Skan	 For now, we assume that named complex floats should go into FPRs
3770169689Skan	 if there are two FPRs free, otherwise they should be passed in the
3771169689Skan	 same way as a struct containing two floats.  */
3772169689Skan      if (info->fpr_p
3773169689Skan	  && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3774169689Skan	  && GET_MODE_UNIT_SIZE (mode) < UNITS_PER_FPVALUE)
3775169689Skan	{
3776169689Skan	  if (cum->num_gprs >= MAX_ARGS_IN_REGISTERS - 1)
3777169689Skan	    info->fpr_p = false;
3778169689Skan	  else
3779169689Skan	    num_words = 2;
3780169689Skan	}
3781169689Skan      break;
3782169689Skan
3783169689Skan    default:
3784169689Skan      gcc_unreachable ();
3785169689Skan    }
3786169689Skan
3787169689Skan  /* See whether the argument has doubleword alignment.  */
3788169689Skan  doubleword_aligned_p = FUNCTION_ARG_BOUNDARY (mode, type) > BITS_PER_WORD;
3789169689Skan
3790169689Skan  /* Set REG_OFFSET to the register count we're interested in.
3791169689Skan     The EABI allocates the floating-point registers separately,
3792169689Skan     but the other ABIs allocate them like integer registers.  */
3793169689Skan  info->reg_offset = (mips_abi == ABI_EABI && info->fpr_p
3794169689Skan		      ? cum->num_fprs
3795169689Skan		      : cum->num_gprs);
3796169689Skan
3797169689Skan  /* Advance to an even register if the argument is doubleword-aligned.  */
3798169689Skan  if (doubleword_aligned_p)
3799169689Skan    info->reg_offset += info->reg_offset & 1;
3800169689Skan
3801169689Skan  /* Work out the offset of a stack argument.  */
3802169689Skan  info->stack_offset = cum->stack_words;
3803169689Skan  if (doubleword_aligned_p)
3804169689Skan    info->stack_offset += info->stack_offset & 1;
3805169689Skan
3806169689Skan  max_regs = MAX_ARGS_IN_REGISTERS - info->reg_offset;
3807169689Skan
3808169689Skan  /* Partition the argument between registers and stack.  */
3809169689Skan  info->reg_words = MIN (num_words, max_regs);
3810169689Skan  info->stack_words = num_words - info->reg_words;
3811169689Skan}
3812169689Skan
3813169689Skan
3814169689Skan/* Implement FUNCTION_ARG_ADVANCE.  */
3815169689Skan
3816169689Skanvoid
3817169689Skanfunction_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
3818169689Skan		      tree type, int named)
3819169689Skan{
3820169689Skan  struct mips_arg_info info;
3821169689Skan
3822169689Skan  mips_arg_info (cum, mode, type, named, &info);
3823169689Skan
3824169689Skan  if (!info.fpr_p)
3825169689Skan    cum->gp_reg_found = true;
3826169689Skan
3827169689Skan  /* See the comment above the cumulative args structure in mips.h
3828169689Skan     for an explanation of what this code does.  It assumes the O32
3829169689Skan     ABI, which passes at most 2 arguments in float registers.  */
3830169689Skan  if (cum->arg_number < 2 && info.fpr_p)
3831169689Skan    cum->fp_code += (mode == SFmode ? 1 : 2) << ((cum->arg_number - 1) * 2);
3832169689Skan
3833169689Skan  if (mips_abi != ABI_EABI || !info.fpr_p)
3834169689Skan    cum->num_gprs = info.reg_offset + info.reg_words;
3835169689Skan  else if (info.reg_words > 0)
3836169689Skan    cum->num_fprs += FP_INC;
3837169689Skan
3838169689Skan  if (info.stack_words > 0)
3839169689Skan    cum->stack_words = info.stack_offset + info.stack_words;
3840169689Skan
3841169689Skan  cum->arg_number++;
3842169689Skan}
3843169689Skan
3844169689Skan/* Implement FUNCTION_ARG.  */
3845169689Skan
3846169689Skanstruct rtx_def *
3847169689Skanfunction_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
3848169689Skan	      tree type, int named)
3849169689Skan{
3850169689Skan  struct mips_arg_info info;
3851169689Skan
3852169689Skan  /* We will be called with a mode of VOIDmode after the last argument
3853169689Skan     has been seen.  Whatever we return will be passed to the call
3854169689Skan     insn.  If we need a mips16 fp_code, return a REG with the code
3855169689Skan     stored as the mode.  */
3856169689Skan  if (mode == VOIDmode)
3857169689Skan    {
3858169689Skan      if (TARGET_MIPS16 && cum->fp_code != 0)
3859169689Skan	return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0);
3860169689Skan
3861169689Skan      else
3862169689Skan	return 0;
3863169689Skan    }
3864169689Skan
3865169689Skan  mips_arg_info (cum, mode, type, named, &info);
3866169689Skan
3867169689Skan  /* Return straight away if the whole argument is passed on the stack.  */
3868169689Skan  if (info.reg_offset == MAX_ARGS_IN_REGISTERS)
3869169689Skan    return 0;
3870169689Skan
3871169689Skan  if (type != 0
3872169689Skan      && TREE_CODE (type) == RECORD_TYPE
3873169689Skan      && TARGET_NEWABI
3874169689Skan      && TYPE_SIZE_UNIT (type)
3875169689Skan      && host_integerp (TYPE_SIZE_UNIT (type), 1)
3876169689Skan      && named)
3877169689Skan    {
3878169689Skan      /* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
3879169689Skan	 structure contains a double in its entirety, then that 64 bit
3880169689Skan	 chunk is passed in a floating point register.  */
3881169689Skan      tree field;
3882169689Skan
3883169689Skan      /* First check to see if there is any such field.  */
3884169689Skan      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3885169689Skan	if (TREE_CODE (field) == FIELD_DECL
3886169689Skan	    && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
3887169689Skan	    && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
3888169689Skan	    && host_integerp (bit_position (field), 0)
3889169689Skan	    && int_bit_position (field) % BITS_PER_WORD == 0)
3890169689Skan	  break;
3891169689Skan
3892169689Skan      if (field != 0)
3893169689Skan	{
3894169689Skan	  /* Now handle the special case by returning a PARALLEL
3895169689Skan	     indicating where each 64 bit chunk goes.  INFO.REG_WORDS
3896169689Skan	     chunks are passed in registers.  */
3897169689Skan	  unsigned int i;
3898169689Skan	  HOST_WIDE_INT bitpos;
3899169689Skan	  rtx ret;
3900169689Skan
3901169689Skan	  /* assign_parms checks the mode of ENTRY_PARM, so we must
3902169689Skan	     use the actual mode here.  */
3903169689Skan	  ret = gen_rtx_PARALLEL (mode, rtvec_alloc (info.reg_words));
3904169689Skan
3905169689Skan	  bitpos = 0;
3906169689Skan	  field = TYPE_FIELDS (type);
3907169689Skan	  for (i = 0; i < info.reg_words; i++)
3908169689Skan	    {
3909169689Skan	      rtx reg;
3910169689Skan
3911169689Skan	      for (; field; field = TREE_CHAIN (field))
3912169689Skan		if (TREE_CODE (field) == FIELD_DECL
3913169689Skan		    && int_bit_position (field) >= bitpos)
3914169689Skan		  break;
3915169689Skan
3916169689Skan	      if (field
3917169689Skan		  && int_bit_position (field) == bitpos
3918169689Skan		  && TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
3919169689Skan		  && !TARGET_SOFT_FLOAT
3920169689Skan		  && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
3921169689Skan		reg = gen_rtx_REG (DFmode, FP_ARG_FIRST + info.reg_offset + i);
3922169689Skan	      else
3923169689Skan		reg = gen_rtx_REG (DImode, GP_ARG_FIRST + info.reg_offset + i);
3924169689Skan
3925169689Skan	      XVECEXP (ret, 0, i)
3926169689Skan		= gen_rtx_EXPR_LIST (VOIDmode, reg,
3927169689Skan				     GEN_INT (bitpos / BITS_PER_UNIT));
3928169689Skan
3929169689Skan	      bitpos += BITS_PER_WORD;
3930169689Skan	    }
3931169689Skan	  return ret;
3932169689Skan	}
3933169689Skan    }
3934169689Skan
3935169689Skan  /* Handle the n32/n64 conventions for passing complex floating-point
3936169689Skan     arguments in FPR pairs.  The real part goes in the lower register
3937169689Skan     and the imaginary part goes in the upper register.  */
3938169689Skan  if (TARGET_NEWABI
3939169689Skan      && info.fpr_p
3940169689Skan      && GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
3941169689Skan    {
3942169689Skan      rtx real, imag;
3943169689Skan      enum machine_mode inner;
3944169689Skan      int reg;
3945169689Skan
3946169689Skan      inner = GET_MODE_INNER (mode);
3947169689Skan      reg = FP_ARG_FIRST + info.reg_offset;
3948169689Skan      if (info.reg_words * UNITS_PER_WORD == GET_MODE_SIZE (inner))
3949169689Skan	{
3950169689Skan	  /* Real part in registers, imaginary part on stack.  */
3951169689Skan	  gcc_assert (info.stack_words == info.reg_words);
3952169689Skan	  return gen_rtx_REG (inner, reg);
3953169689Skan	}
3954169689Skan      else
3955169689Skan	{
3956169689Skan	  gcc_assert (info.stack_words == 0);
3957169689Skan	  real = gen_rtx_EXPR_LIST (VOIDmode,
3958169689Skan				    gen_rtx_REG (inner, reg),
3959169689Skan				    const0_rtx);
3960169689Skan	  imag = gen_rtx_EXPR_LIST (VOIDmode,
3961169689Skan				    gen_rtx_REG (inner,
3962169689Skan						 reg + info.reg_words / 2),
3963169689Skan				    GEN_INT (GET_MODE_SIZE (inner)));
3964169689Skan	  return gen_rtx_PARALLEL (mode, gen_rtvec (2, real, imag));
3965169689Skan	}
3966169689Skan    }
3967169689Skan
3968169689Skan  if (!info.fpr_p)
3969169689Skan    return gen_rtx_REG (mode, GP_ARG_FIRST + info.reg_offset);
3970169689Skan  else if (info.reg_offset == 1)
3971169689Skan    /* This code handles the special o32 case in which the second word
3972169689Skan       of the argument structure is passed in floating-point registers.  */
3973169689Skan    return gen_rtx_REG (mode, FP_ARG_FIRST + FP_INC);
3974169689Skan  else
3975169689Skan    return gen_rtx_REG (mode, FP_ARG_FIRST + info.reg_offset);
3976169689Skan}
3977169689Skan
3978169689Skan
3979169689Skan/* Implement TARGET_ARG_PARTIAL_BYTES.  */
3980169689Skan
3981169689Skanstatic int
3982169689Skanmips_arg_partial_bytes (CUMULATIVE_ARGS *cum,
3983169689Skan			enum machine_mode mode, tree type, bool named)
3984169689Skan{
3985169689Skan  struct mips_arg_info info;
3986169689Skan
3987169689Skan  mips_arg_info (cum, mode, type, named, &info);
3988169689Skan  return info.stack_words > 0 ? info.reg_words * UNITS_PER_WORD : 0;
3989169689Skan}
3990169689Skan
3991169689Skan
3992169689Skan/* Implement FUNCTION_ARG_BOUNDARY.  Every parameter gets at least
3993169689Skan   PARM_BOUNDARY bits of alignment, but will be given anything up
3994169689Skan   to STACK_BOUNDARY bits if the type requires it.  */
3995169689Skan
3996169689Skanint
3997169689Skanfunction_arg_boundary (enum machine_mode mode, tree type)
3998169689Skan{
3999169689Skan  unsigned int alignment;
4000169689Skan
4001169689Skan  alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
4002169689Skan  if (alignment < PARM_BOUNDARY)
4003169689Skan    alignment = PARM_BOUNDARY;
4004169689Skan  if (alignment > STACK_BOUNDARY)
4005169689Skan    alignment = STACK_BOUNDARY;
4006169689Skan  return alignment;
4007169689Skan}
4008169689Skan
4009169689Skan/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
4010169689Skan   upward rather than downward.  In other words, return true if the
4011169689Skan   first byte of the stack slot has useful data, false if the last
4012169689Skan   byte does.  */
4013169689Skan
4014169689Skanbool
4015169689Skanmips_pad_arg_upward (enum machine_mode mode, tree type)
4016169689Skan{
4017169689Skan  /* On little-endian targets, the first byte of every stack argument
4018169689Skan     is passed in the first byte of the stack slot.  */
4019169689Skan  if (!BYTES_BIG_ENDIAN)
4020169689Skan    return true;
4021169689Skan
4022169689Skan  /* Otherwise, integral types are padded downward: the last byte of a
4023169689Skan     stack argument is passed in the last byte of the stack slot.  */
4024169689Skan  if (type != 0
4025169689Skan      ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
4026169689Skan      : GET_MODE_CLASS (mode) == MODE_INT)
4027169689Skan    return false;
4028169689Skan
4029169689Skan  /* Big-endian o64 pads floating-point arguments downward.  */
4030169689Skan  if (mips_abi == ABI_O64)
4031169689Skan    if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
4032169689Skan      return false;
4033169689Skan
4034169689Skan  /* Other types are padded upward for o32, o64, n32 and n64.  */
4035169689Skan  if (mips_abi != ABI_EABI)
4036169689Skan    return true;
4037169689Skan
4038169689Skan  /* Arguments smaller than a stack slot are padded downward.  */
4039169689Skan  if (mode != BLKmode)
4040169689Skan    return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY);
4041169689Skan  else
4042169689Skan    return (int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT));
4043169689Skan}
4044169689Skan
4045169689Skan
4046169689Skan/* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...).  Return !BYTES_BIG_ENDIAN
4047169689Skan   if the least significant byte of the register has useful data.  Return
4048169689Skan   the opposite if the most significant byte does.  */
4049169689Skan
4050169689Skanbool
4051169689Skanmips_pad_reg_upward (enum machine_mode mode, tree type)
4052169689Skan{
4053169689Skan  /* No shifting is required for floating-point arguments.  */
4054169689Skan  if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
4055169689Skan    return !BYTES_BIG_ENDIAN;
4056169689Skan
4057169689Skan  /* Otherwise, apply the same padding to register arguments as we do
4058169689Skan     to stack arguments.  */
4059169689Skan  return mips_pad_arg_upward (mode, type);
4060169689Skan}
4061169689Skan
4062169689Skanstatic void
4063169689Skanmips_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
4064169689Skan			     tree type, int *pretend_size ATTRIBUTE_UNUSED,
4065169689Skan			     int no_rtl)
4066169689Skan{
4067169689Skan  CUMULATIVE_ARGS local_cum;
4068169689Skan  int gp_saved, fp_saved;
4069169689Skan
4070169689Skan  /* The caller has advanced CUM up to, but not beyond, the last named
4071169689Skan     argument.  Advance a local copy of CUM past the last "real" named
4072169689Skan     argument, to find out how many registers are left over.  */
4073169689Skan
4074169689Skan  local_cum = *cum;
4075169689Skan  FUNCTION_ARG_ADVANCE (local_cum, mode, type, 1);
4076169689Skan
4077169689Skan  /* Found out how many registers we need to save.  */
4078169689Skan  gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;
4079169689Skan  fp_saved = (EABI_FLOAT_VARARGS_P
4080169689Skan	      ? MAX_ARGS_IN_REGISTERS - local_cum.num_fprs
4081169689Skan	      : 0);
4082169689Skan
4083169689Skan  if (!no_rtl)
4084169689Skan    {
4085169689Skan      if (gp_saved > 0)
4086169689Skan	{
4087169689Skan	  rtx ptr, mem;
4088169689Skan
4089169689Skan	  ptr = plus_constant (virtual_incoming_args_rtx,
4090169689Skan			       REG_PARM_STACK_SPACE (cfun->decl)
4091169689Skan			       - gp_saved * UNITS_PER_WORD);
4092169689Skan	  mem = gen_rtx_MEM (BLKmode, ptr);
4093169689Skan	  set_mem_alias_set (mem, get_varargs_alias_set ());
4094169689Skan
4095169689Skan	  move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
4096169689Skan			       mem, gp_saved);
4097169689Skan	}
4098169689Skan      if (fp_saved > 0)
4099169689Skan	{
4100169689Skan	  /* We can't use move_block_from_reg, because it will use
4101169689Skan	     the wrong mode.  */
4102169689Skan	  enum machine_mode mode;
4103169689Skan	  int off, i;
4104169689Skan
4105169689Skan	  /* Set OFF to the offset from virtual_incoming_args_rtx of
4106169689Skan	     the first float register.  The FP save area lies below
4107169689Skan	     the integer one, and is aligned to UNITS_PER_FPVALUE bytes.  */
4108169689Skan	  off = -gp_saved * UNITS_PER_WORD;
4109169689Skan	  off &= ~(UNITS_PER_FPVALUE - 1);
4110169689Skan	  off -= fp_saved * UNITS_PER_FPREG;
4111169689Skan
4112169689Skan	  mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode;
4113169689Skan
4114169689Skan	  for (i = local_cum.num_fprs; i < MAX_ARGS_IN_REGISTERS; i += FP_INC)
4115169689Skan	    {
4116169689Skan	      rtx ptr, mem;
4117169689Skan
4118169689Skan	      ptr = plus_constant (virtual_incoming_args_rtx, off);
4119169689Skan	      mem = gen_rtx_MEM (mode, ptr);
4120169689Skan	      set_mem_alias_set (mem, get_varargs_alias_set ());
4121169689Skan	      emit_move_insn (mem, gen_rtx_REG (mode, FP_ARG_FIRST + i));
4122169689Skan	      off += UNITS_PER_HWFPVALUE;
4123169689Skan	    }
4124169689Skan	}
4125169689Skan    }
4126169689Skan  if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
4127169689Skan    cfun->machine->varargs_size = (gp_saved * UNITS_PER_WORD
4128169689Skan				   + fp_saved * UNITS_PER_FPREG);
4129169689Skan}
4130169689Skan
4131169689Skan/* Create the va_list data type.
4132169689Skan   We keep 3 pointers, and two offsets.
4133169689Skan   Two pointers are to the overflow area, which starts at the CFA.
4134169689Skan     One of these is constant, for addressing into the GPR save area below it.
4135169689Skan     The other is advanced up the stack through the overflow region.
4136169689Skan   The third pointer is to the GPR save area.  Since the FPR save area
4137169689Skan     is just below it, we can address FPR slots off this pointer.
4138169689Skan   We also keep two one-byte offsets, which are to be subtracted from the
4139169689Skan     constant pointers to yield addresses in the GPR and FPR save areas.
4140169689Skan     These are downcounted as float or non-float arguments are used,
4141169689Skan     and when they get to zero, the argument must be obtained from the
4142169689Skan     overflow region.
4143169689Skan   If !EABI_FLOAT_VARARGS_P, then no FPR save area exists, and a single
4144169689Skan     pointer is enough.  It's started at the GPR save area, and is
4145169689Skan     advanced, period.
4146169689Skan   Note that the GPR save area is not constant size, due to optimization
4147169689Skan     in the prologue.  Hence, we can't use a design with two pointers
4148169689Skan     and two offsets, although we could have designed this with two pointers
4149169689Skan     and three offsets.  */
4150169689Skan
4151169689Skanstatic tree
4152169689Skanmips_build_builtin_va_list (void)
4153169689Skan{
4154169689Skan  if (EABI_FLOAT_VARARGS_P)
4155169689Skan    {
4156169689Skan      tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff, f_res, record;
4157169689Skan      tree array, index;
4158169689Skan
4159169689Skan      record = (*lang_hooks.types.make_type) (RECORD_TYPE);
4160169689Skan
4161169689Skan      f_ovfl = build_decl (FIELD_DECL, get_identifier ("__overflow_argptr"),
4162169689Skan			  ptr_type_node);
4163169689Skan      f_gtop = build_decl (FIELD_DECL, get_identifier ("__gpr_top"),
4164169689Skan			  ptr_type_node);
4165169689Skan      f_ftop = build_decl (FIELD_DECL, get_identifier ("__fpr_top"),
4166169689Skan			  ptr_type_node);
4167169689Skan      f_goff = build_decl (FIELD_DECL, get_identifier ("__gpr_offset"),
4168169689Skan			  unsigned_char_type_node);
4169169689Skan      f_foff = build_decl (FIELD_DECL, get_identifier ("__fpr_offset"),
4170169689Skan			  unsigned_char_type_node);
4171169689Skan      /* Explicitly pad to the size of a pointer, so that -Wpadded won't
4172169689Skan	 warn on every user file.  */
4173169689Skan      index = build_int_cst (NULL_TREE, GET_MODE_SIZE (ptr_mode) - 2 - 1);
4174169689Skan      array = build_array_type (unsigned_char_type_node,
4175169689Skan			        build_index_type (index));
4176169689Skan      f_res = build_decl (FIELD_DECL, get_identifier ("__reserved"), array);
4177169689Skan
4178169689Skan      DECL_FIELD_CONTEXT (f_ovfl) = record;
4179169689Skan      DECL_FIELD_CONTEXT (f_gtop) = record;
4180169689Skan      DECL_FIELD_CONTEXT (f_ftop) = record;
4181169689Skan      DECL_FIELD_CONTEXT (f_goff) = record;
4182169689Skan      DECL_FIELD_CONTEXT (f_foff) = record;
4183169689Skan      DECL_FIELD_CONTEXT (f_res) = record;
4184169689Skan
4185169689Skan      TYPE_FIELDS (record) = f_ovfl;
4186169689Skan      TREE_CHAIN (f_ovfl) = f_gtop;
4187169689Skan      TREE_CHAIN (f_gtop) = f_ftop;
4188169689Skan      TREE_CHAIN (f_ftop) = f_goff;
4189169689Skan      TREE_CHAIN (f_goff) = f_foff;
4190169689Skan      TREE_CHAIN (f_foff) = f_res;
4191169689Skan
4192169689Skan      layout_type (record);
4193169689Skan      return record;
4194169689Skan    }
4195169689Skan  else if (TARGET_IRIX && TARGET_IRIX6)
4196169689Skan    /* On IRIX 6, this type is 'char *'.  */
4197169689Skan    return build_pointer_type (char_type_node);
4198169689Skan  else
4199169689Skan    /* Otherwise, we use 'void *'.  */
4200169689Skan    return ptr_type_node;
4201169689Skan}
4202169689Skan
4203169689Skan/* Implement va_start.  */
4204169689Skan
4205169689Skanvoid
4206169689Skanmips_va_start (tree valist, rtx nextarg)
4207169689Skan{
4208169689Skan  if (EABI_FLOAT_VARARGS_P)
4209169689Skan    {
4210169689Skan      const CUMULATIVE_ARGS *cum;
4211169689Skan      tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
4212169689Skan      tree ovfl, gtop, ftop, goff, foff;
4213169689Skan      tree t;
4214169689Skan      int gpr_save_area_size;
4215169689Skan      int fpr_save_area_size;
4216169689Skan      int fpr_offset;
4217169689Skan
4218169689Skan      cum = &current_function_args_info;
4219169689Skan      gpr_save_area_size
4220169689Skan	= (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD;
4221169689Skan      fpr_save_area_size
4222169689Skan	= (MAX_ARGS_IN_REGISTERS - cum->num_fprs) * UNITS_PER_FPREG;
4223169689Skan
4224169689Skan      f_ovfl = TYPE_FIELDS (va_list_type_node);
4225169689Skan      f_gtop = TREE_CHAIN (f_ovfl);
4226169689Skan      f_ftop = TREE_CHAIN (f_gtop);
4227169689Skan      f_goff = TREE_CHAIN (f_ftop);
4228169689Skan      f_foff = TREE_CHAIN (f_goff);
4229169689Skan
4230169689Skan      ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
4231169689Skan		     NULL_TREE);
4232169689Skan      gtop = build3 (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
4233169689Skan		     NULL_TREE);
4234169689Skan      ftop = build3 (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
4235169689Skan		     NULL_TREE);
4236169689Skan      goff = build3 (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
4237169689Skan		     NULL_TREE);
4238169689Skan      foff = build3 (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
4239169689Skan		     NULL_TREE);
4240169689Skan
4241169689Skan      /* Emit code to initialize OVFL, which points to the next varargs
4242169689Skan	 stack argument.  CUM->STACK_WORDS gives the number of stack
4243169689Skan	 words used by named arguments.  */
4244169689Skan      t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
4245169689Skan      if (cum->stack_words > 0)
4246169689Skan	t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), t,
4247169689Skan		    build_int_cst (NULL_TREE,
4248169689Skan				   cum->stack_words * UNITS_PER_WORD));
4249169689Skan      t = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
4250169689Skan      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4251169689Skan
4252169689Skan      /* Emit code to initialize GTOP, the top of the GPR save area.  */
4253169689Skan      t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
4254169689Skan      t = build2 (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
4255169689Skan      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4256169689Skan
4257169689Skan      /* Emit code to initialize FTOP, the top of the FPR save area.
4258169689Skan	 This address is gpr_save_area_bytes below GTOP, rounded
4259169689Skan	 down to the next fp-aligned boundary.  */
4260169689Skan      t = make_tree (TREE_TYPE (ftop), virtual_incoming_args_rtx);
4261169689Skan      fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
4262169689Skan      fpr_offset &= ~(UNITS_PER_FPVALUE - 1);
4263169689Skan      if (fpr_offset)
4264169689Skan	t = build2 (PLUS_EXPR, TREE_TYPE (ftop), t,
4265169689Skan		    build_int_cst (NULL_TREE, -fpr_offset));
4266169689Skan      t = build2 (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
4267169689Skan      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4268169689Skan
4269169689Skan      /* Emit code to initialize GOFF, the offset from GTOP of the
4270169689Skan	 next GPR argument.  */
4271169689Skan      t = build2 (MODIFY_EXPR, TREE_TYPE (goff), goff,
4272169689Skan		  build_int_cst (NULL_TREE, gpr_save_area_size));
4273169689Skan      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4274169689Skan
4275169689Skan      /* Likewise emit code to initialize FOFF, the offset from FTOP
4276169689Skan	 of the next FPR argument.  */
4277169689Skan      t = build2 (MODIFY_EXPR, TREE_TYPE (foff), foff,
4278169689Skan		  build_int_cst (NULL_TREE, fpr_save_area_size));
4279169689Skan      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4280169689Skan    }
4281169689Skan  else
4282169689Skan    {
4283169689Skan      nextarg = plus_constant (nextarg, -cfun->machine->varargs_size);
4284169689Skan      std_expand_builtin_va_start (valist, nextarg);
4285169689Skan    }
4286169689Skan}
4287169689Skan
4288169689Skan/* Implement va_arg.  */
4289169689Skan
4290169689Skanstatic tree
4291169689Skanmips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4292169689Skan{
4293169689Skan  HOST_WIDE_INT size, rsize;
4294169689Skan  tree addr;
4295169689Skan  bool indirect;
4296169689Skan
4297169689Skan  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0);
4298169689Skan
4299169689Skan  if (indirect)
4300169689Skan    type = build_pointer_type (type);
4301169689Skan
4302169689Skan  size = int_size_in_bytes (type);
4303169689Skan  rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
4304169689Skan
4305169689Skan  if (mips_abi != ABI_EABI || !EABI_FLOAT_VARARGS_P)
4306169689Skan    addr = std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
4307169689Skan  else
4308169689Skan    {
4309169689Skan      /* Not a simple merged stack.	 */
4310169689Skan
4311169689Skan      tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff;
4312169689Skan      tree ovfl, top, off, align;
4313169689Skan      HOST_WIDE_INT osize;
4314169689Skan      tree t, u;
4315169689Skan
4316169689Skan      f_ovfl = TYPE_FIELDS (va_list_type_node);
4317169689Skan      f_gtop = TREE_CHAIN (f_ovfl);
4318169689Skan      f_ftop = TREE_CHAIN (f_gtop);
4319169689Skan      f_goff = TREE_CHAIN (f_ftop);
4320169689Skan      f_foff = TREE_CHAIN (f_goff);
4321169689Skan
4322169689Skan      /* We maintain separate pointers and offsets for floating-point
4323169689Skan	 and integer arguments, but we need similar code in both cases.
4324169689Skan	 Let:
4325169689Skan
4326169689Skan	 TOP be the top of the register save area;
4327169689Skan	 OFF be the offset from TOP of the next register;
4328169689Skan	 ADDR_RTX be the address of the argument;
4329169689Skan	 RSIZE be the number of bytes used to store the argument
4330169689Skan	 when it's in the register save area;
4331169689Skan	 OSIZE be the number of bytes used to store it when it's
4332169689Skan	 in the stack overflow area; and
4333169689Skan	 PADDING be (BYTES_BIG_ENDIAN ? OSIZE - RSIZE : 0)
4334169689Skan
4335169689Skan	 The code we want is:
4336169689Skan
4337169689Skan	 1: off &= -rsize;	  // round down
4338169689Skan	 2: if (off != 0)
4339169689Skan	 3:   {
4340169689Skan	 4:	 addr_rtx = top - off;
4341169689Skan	 5:	 off -= rsize;
4342169689Skan	 6:   }
4343169689Skan	 7: else
4344169689Skan	 8:   {
4345169689Skan	 9:	 ovfl += ((intptr_t) ovfl + osize - 1) & -osize;
4346169689Skan	 10:	 addr_rtx = ovfl + PADDING;
4347169689Skan	 11:	 ovfl += osize;
4348169689Skan	 14:   }
4349169689Skan
4350169689Skan	 [1] and [9] can sometimes be optimized away.  */
4351169689Skan
4352169689Skan      ovfl = build3 (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
4353169689Skan		     NULL_TREE);
4354169689Skan
4355169689Skan      if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
4356169689Skan	  && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
4357169689Skan	{
4358169689Skan	  top = build3 (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
4359169689Skan		        NULL_TREE);
4360169689Skan	  off = build3 (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
4361169689Skan		        NULL_TREE);
4362169689Skan
4363169689Skan	  /* When floating-point registers are saved to the stack,
4364169689Skan	     each one will take up UNITS_PER_HWFPVALUE bytes, regardless
4365169689Skan	     of the float's precision.  */
4366169689Skan	  rsize = UNITS_PER_HWFPVALUE;
4367169689Skan
4368169689Skan	  /* Overflow arguments are padded to UNITS_PER_WORD bytes
4369169689Skan	     (= PARM_BOUNDARY bits).  This can be different from RSIZE
4370169689Skan	     in two cases:
4371169689Skan
4372169689Skan	     (1) On 32-bit targets when TYPE is a structure such as:
4373169689Skan
4374169689Skan	     struct s { float f; };
4375169689Skan
4376169689Skan	     Such structures are passed in paired FPRs, so RSIZE
4377169689Skan	     will be 8 bytes.  However, the structure only takes
4378169689Skan	     up 4 bytes of memory, so OSIZE will only be 4.
4379169689Skan
4380169689Skan	     (2) In combinations such as -mgp64 -msingle-float
4381169689Skan	     -fshort-double.  Doubles passed in registers
4382169689Skan	     will then take up 4 (UNITS_PER_HWFPVALUE) bytes,
4383169689Skan	     but those passed on the stack take up
4384169689Skan	     UNITS_PER_WORD bytes.  */
4385169689Skan	  osize = MAX (GET_MODE_SIZE (TYPE_MODE (type)), UNITS_PER_WORD);
4386169689Skan	}
4387169689Skan      else
4388169689Skan	{
4389169689Skan	  top = build3 (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
4390169689Skan		        NULL_TREE);
4391169689Skan	  off = build3 (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
4392169689Skan		        NULL_TREE);
4393169689Skan	  if (rsize > UNITS_PER_WORD)
4394169689Skan	    {
4395169689Skan	      /* [1] Emit code for: off &= -rsize.	*/
4396169689Skan	      t = build2 (BIT_AND_EXPR, TREE_TYPE (off), off,
4397169689Skan			  build_int_cst (NULL_TREE, -rsize));
4398169689Skan	      t = build2 (MODIFY_EXPR, TREE_TYPE (off), off, t);
4399169689Skan	      gimplify_and_add (t, pre_p);
4400169689Skan	    }
4401169689Skan	  osize = rsize;
4402169689Skan	}
4403169689Skan
4404169689Skan      /* [2] Emit code to branch if off == 0.  */
4405169689Skan      t = build2 (NE_EXPR, boolean_type_node, off,
4406169689Skan		  build_int_cst (TREE_TYPE (off), 0));
4407169689Skan      addr = build3 (COND_EXPR, ptr_type_node, t, NULL_TREE, NULL_TREE);
4408169689Skan
4409169689Skan      /* [5] Emit code for: off -= rsize.  We do this as a form of
4410169689Skan	 post-increment not available to C.  Also widen for the
4411169689Skan	 coming pointer arithmetic.  */
4412169689Skan      t = fold_convert (TREE_TYPE (off), build_int_cst (NULL_TREE, rsize));
4413169689Skan      t = build2 (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
4414169689Skan      t = fold_convert (sizetype, t);
4415169689Skan      t = fold_convert (TREE_TYPE (top), t);
4416169689Skan
4417169689Skan      /* [4] Emit code for: addr_rtx = top - off.  On big endian machines,
4418169689Skan	 the argument has RSIZE - SIZE bytes of leading padding.  */
4419169689Skan      t = build2 (MINUS_EXPR, TREE_TYPE (top), top, t);
4420169689Skan      if (BYTES_BIG_ENDIAN && rsize > size)
4421169689Skan	{
4422169689Skan	  u = fold_convert (TREE_TYPE (t), build_int_cst (NULL_TREE,
4423169689Skan							  rsize - size));
4424169689Skan	  t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
4425169689Skan	}
4426169689Skan      COND_EXPR_THEN (addr) = t;
4427169689Skan
4428169689Skan      if (osize > UNITS_PER_WORD)
4429169689Skan	{
4430169689Skan	  /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize.  */
4431169689Skan	  u = fold_convert (TREE_TYPE (ovfl),
4432169689Skan			    build_int_cst (NULL_TREE, osize - 1));
4433169689Skan	  t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
4434169689Skan	  u = fold_convert (TREE_TYPE (ovfl),
4435169689Skan			    build_int_cst (NULL_TREE, -osize));
4436169689Skan	  t = build2 (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
4437169689Skan	  align = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
4438169689Skan	}
4439169689Skan      else
4440169689Skan	align = NULL;
4441169689Skan
4442169689Skan      /* [10, 11].	Emit code to store ovfl in addr_rtx, then
4443169689Skan	 post-increment ovfl by osize.  On big-endian machines,
4444169689Skan	 the argument has OSIZE - SIZE bytes of leading padding.  */
4445169689Skan      u = fold_convert (TREE_TYPE (ovfl),
4446169689Skan			build_int_cst (NULL_TREE, osize));
4447169689Skan      t = build2 (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
4448169689Skan      if (BYTES_BIG_ENDIAN && osize > size)
4449169689Skan	{
4450169689Skan	  u = fold_convert (TREE_TYPE (t),
4451169689Skan			    build_int_cst (NULL_TREE, osize - size));
4452169689Skan	  t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
4453169689Skan	}
4454169689Skan
4455169689Skan      /* String [9] and [10,11] together.  */
4456169689Skan      if (align)
4457169689Skan	t = build2 (COMPOUND_EXPR, TREE_TYPE (t), align, t);
4458169689Skan      COND_EXPR_ELSE (addr) = t;
4459169689Skan
4460169689Skan      addr = fold_convert (build_pointer_type (type), addr);
4461169689Skan      addr = build_va_arg_indirect_ref (addr);
4462169689Skan    }
4463169689Skan
4464169689Skan  if (indirect)
4465169689Skan    addr = build_va_arg_indirect_ref (addr);
4466169689Skan
4467169689Skan  return addr;
4468169689Skan}
4469169689Skan
4470169689Skan/* Return true if it is possible to use left/right accesses for a
4471169689Skan   bitfield of WIDTH bits starting BITPOS bits into *OP.  When
4472169689Skan   returning true, update *OP, *LEFT and *RIGHT as follows:
4473169689Skan
4474169689Skan   *OP is a BLKmode reference to the whole field.
4475169689Skan
4476169689Skan   *LEFT is a QImode reference to the first byte if big endian or
4477169689Skan   the last byte if little endian.  This address can be used in the
4478169689Skan   left-side instructions (lwl, swl, ldl, sdl).
4479169689Skan
4480169689Skan   *RIGHT is a QImode reference to the opposite end of the field and
4481169689Skan   can be used in the patterning right-side instruction.  */
4482169689Skan
4483169689Skanstatic bool
4484169689Skanmips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
4485169689Skan			rtx *left, rtx *right)
4486169689Skan{
4487169689Skan  rtx first, last;
4488169689Skan
4489169689Skan  /* Check that the operand really is a MEM.  Not all the extv and
4490169689Skan     extzv predicates are checked.  */
4491169689Skan  if (!MEM_P (*op))
4492169689Skan    return false;
4493169689Skan
4494169689Skan  /* Check that the size is valid.  */
4495169689Skan  if (width != 32 && (!TARGET_64BIT || width != 64))
4496169689Skan    return false;
4497169689Skan
4498169689Skan  /* We can only access byte-aligned values.  Since we are always passed
4499169689Skan     a reference to the first byte of the field, it is not necessary to
4500169689Skan     do anything with BITPOS after this check.  */
4501169689Skan  if (bitpos % BITS_PER_UNIT != 0)
4502169689Skan    return false;
4503169689Skan
4504169689Skan  /* Reject aligned bitfields: we want to use a normal load or store
4505169689Skan     instead of a left/right pair.  */
4506169689Skan  if (MEM_ALIGN (*op) >= width)
4507169689Skan    return false;
4508169689Skan
4509169689Skan  /* Adjust *OP to refer to the whole field.  This also has the effect
4510169689Skan     of legitimizing *OP's address for BLKmode, possibly simplifying it.  */
4511169689Skan  *op = adjust_address (*op, BLKmode, 0);
4512169689Skan  set_mem_size (*op, GEN_INT (width / BITS_PER_UNIT));
4513169689Skan
4514169689Skan  /* Get references to both ends of the field.  We deliberately don't
4515169689Skan     use the original QImode *OP for FIRST since the new BLKmode one
4516169689Skan     might have a simpler address.  */
4517169689Skan  first = adjust_address (*op, QImode, 0);
4518169689Skan  last = adjust_address (*op, QImode, width / BITS_PER_UNIT - 1);
4519169689Skan
4520169689Skan  /* Allocate to LEFT and RIGHT according to endianness.  LEFT should
4521169689Skan     be the upper word and RIGHT the lower word.  */
4522169689Skan  if (TARGET_BIG_ENDIAN)
4523169689Skan    *left = first, *right = last;
4524169689Skan  else
4525169689Skan    *left = last, *right = first;
4526169689Skan
4527169689Skan  return true;
4528169689Skan}
4529169689Skan
4530169689Skan
4531169689Skan/* Try to emit the equivalent of (set DEST (zero_extract SRC WIDTH BITPOS)).
4532169689Skan   Return true on success.  We only handle cases where zero_extract is
4533169689Skan   equivalent to sign_extract.  */
4534169689Skan
4535169689Skanbool
4536169689Skanmips_expand_unaligned_load (rtx dest, rtx src, unsigned int width, int bitpos)
4537169689Skan{
4538169689Skan  rtx left, right, temp;
4539169689Skan
4540169689Skan  /* If TARGET_64BIT, the destination of a 32-bit load will be a
4541169689Skan     paradoxical word_mode subreg.  This is the only case in which
4542169689Skan     we allow the destination to be larger than the source.  */
4543169689Skan  if (GET_CODE (dest) == SUBREG
4544169689Skan      && GET_MODE (dest) == DImode
4545169689Skan      && SUBREG_BYTE (dest) == 0
4546169689Skan      && GET_MODE (SUBREG_REG (dest)) == SImode)
4547169689Skan    dest = SUBREG_REG (dest);
4548169689Skan
4549169689Skan  /* After the above adjustment, the destination must be the same
4550169689Skan     width as the source.  */
4551169689Skan  if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4552169689Skan    return false;
4553169689Skan
4554169689Skan  if (!mips_get_unaligned_mem (&src, width, bitpos, &left, &right))
4555169689Skan    return false;
4556169689Skan
4557169689Skan  temp = gen_reg_rtx (GET_MODE (dest));
4558169689Skan  if (GET_MODE (dest) == DImode)
4559169689Skan    {
4560169689Skan      emit_insn (gen_mov_ldl (temp, src, left));
4561169689Skan      emit_insn (gen_mov_ldr (dest, copy_rtx (src), right, temp));
4562169689Skan    }
4563169689Skan  else
4564169689Skan    {
4565169689Skan      emit_insn (gen_mov_lwl (temp, src, left));
4566169689Skan      emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
4567169689Skan    }
4568169689Skan  return true;
4569169689Skan}
4570169689Skan
4571169689Skan
4572169689Skan/* Try to expand (set (zero_extract DEST WIDTH BITPOS) SRC).  Return
4573169689Skan   true on success.  */
4574169689Skan
4575169689Skanbool
4576169689Skanmips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
4577169689Skan{
4578169689Skan  rtx left, right;
4579169689Skan  enum machine_mode mode;
4580169689Skan
4581169689Skan  if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right))
4582169689Skan    return false;
4583169689Skan
4584169689Skan  mode = mode_for_size (width, MODE_INT, 0);
4585169689Skan  src = gen_lowpart (mode, src);
4586169689Skan
4587169689Skan  if (mode == DImode)
4588169689Skan    {
4589169689Skan      emit_insn (gen_mov_sdl (dest, src, left));
4590169689Skan      emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
4591169689Skan    }
4592169689Skan  else
4593169689Skan    {
4594169689Skan      emit_insn (gen_mov_swl (dest, src, left));
4595169689Skan      emit_insn (gen_mov_swr (copy_rtx (dest), copy_rtx (src), right));
4596169689Skan    }
4597169689Skan  return true;
4598169689Skan}
4599169689Skan
4600169689Skan/* Return true if X is a MEM with the same size as MODE.  */
4601169689Skan
4602169689Skanbool
4603169689Skanmips_mem_fits_mode_p (enum machine_mode mode, rtx x)
4604169689Skan{
4605169689Skan  rtx size;
4606169689Skan
4607169689Skan  if (!MEM_P (x))
4608169689Skan    return false;
4609169689Skan
4610169689Skan  size = MEM_SIZE (x);
4611169689Skan  return size && INTVAL (size) == GET_MODE_SIZE (mode);
4612169689Skan}
4613169689Skan
4614169689Skan/* Return true if (zero_extract OP SIZE POSITION) can be used as the
4615169689Skan   source of an "ext" instruction or the destination of an "ins"
4616169689Skan   instruction.  OP must be a register operand and the following
4617169689Skan   conditions must hold:
4618169689Skan
4619169689Skan     0 <= POSITION < GET_MODE_BITSIZE (GET_MODE (op))
4620169689Skan     0 < SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
4621169689Skan     0 < POSITION + SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
4622169689Skan
4623169689Skan   Also reject lengths equal to a word as they are better handled
4624169689Skan   by the move patterns.  */
4625169689Skan
4626169689Skanbool
4627169689Skanmips_use_ins_ext_p (rtx op, rtx size, rtx position)
4628169689Skan{
4629169689Skan  HOST_WIDE_INT len, pos;
4630169689Skan
4631169689Skan  if (!ISA_HAS_EXT_INS
4632169689Skan      || !register_operand (op, VOIDmode)
4633169689Skan      || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD)
4634169689Skan    return false;
4635169689Skan
4636169689Skan  len = INTVAL (size);
4637169689Skan  pos = INTVAL (position);
4638169689Skan
4639169689Skan  if (len <= 0 || len >= GET_MODE_BITSIZE (GET_MODE (op))
4640169689Skan      || pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (op)))
4641169689Skan    return false;
4642169689Skan
4643169689Skan  return true;
4644169689Skan}
4645169689Skan
4646169689Skan/* Set up globals to generate code for the ISA or processor
4647169689Skan   described by INFO.  */
4648169689Skan
4649169689Skanstatic void
4650169689Skanmips_set_architecture (const struct mips_cpu_info *info)
4651169689Skan{
4652169689Skan  if (info != 0)
4653169689Skan    {
4654169689Skan      mips_arch_info = info;
4655169689Skan      mips_arch = info->cpu;
4656169689Skan      mips_isa = info->isa;
4657169689Skan    }
4658169689Skan}
4659169689Skan
4660169689Skan
4661169689Skan/* Likewise for tuning.  */
4662169689Skan
4663169689Skanstatic void
4664169689Skanmips_set_tune (const struct mips_cpu_info *info)
4665169689Skan{
4666169689Skan  if (info != 0)
4667169689Skan    {
4668169689Skan      mips_tune_info = info;
4669169689Skan      mips_tune = info->cpu;
4670169689Skan    }
4671169689Skan}
4672169689Skan
4673169689Skan/* Implement TARGET_HANDLE_OPTION.  */
4674169689Skan
4675169689Skanstatic bool
4676169689Skanmips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
4677169689Skan{
4678169689Skan  switch (code)
4679169689Skan    {
4680169689Skan    case OPT_mabi_:
4681169689Skan      if (strcmp (arg, "32") == 0)
4682169689Skan	mips_abi = ABI_32;
4683169689Skan      else if (strcmp (arg, "o64") == 0)
4684169689Skan	mips_abi = ABI_O64;
4685169689Skan      else if (strcmp (arg, "n32") == 0)
4686169689Skan	mips_abi = ABI_N32;
4687169689Skan      else if (strcmp (arg, "64") == 0)
4688169689Skan	mips_abi = ABI_64;
4689169689Skan      else if (strcmp (arg, "eabi") == 0)
4690169689Skan	mips_abi = ABI_EABI;
4691169689Skan      else
4692169689Skan	return false;
4693169689Skan      return true;
4694169689Skan
4695169689Skan    case OPT_march_:
4696169689Skan    case OPT_mtune_:
4697169689Skan      return mips_parse_cpu (arg) != 0;
4698169689Skan
4699169689Skan    case OPT_mips:
4700169689Skan      mips_isa_info = mips_parse_cpu (ACONCAT (("mips", arg, NULL)));
4701169689Skan      return mips_isa_info != 0;
4702169689Skan
4703169689Skan    case OPT_mno_flush_func:
4704169689Skan      mips_cache_flush_func = NULL;
4705169689Skan      return true;
4706169689Skan
4707169689Skan    default:
4708169689Skan      return true;
4709169689Skan    }
4710169689Skan}
4711169689Skan
4712169689Skan/* Set up the threshold for data to go into the small data area, instead
4713169689Skan   of the normal data area, and detect any conflicts in the switches.  */
4714169689Skan
4715169689Skanvoid
4716169689Skanoverride_options (void)
4717169689Skan{
4718169689Skan  int i, start, regno;
4719169689Skan  enum machine_mode mode;
4720169689Skan
4721169689Skan  mips_section_threshold = g_switch_set ? g_switch_value : MIPS_DEFAULT_GVALUE;
4722169689Skan
4723169689Skan  /* The following code determines the architecture and register size.
4724169689Skan     Similar code was added to GAS 2.14 (see tc-mips.c:md_after_parse_args()).
4725169689Skan     The GAS and GCC code should be kept in sync as much as possible.  */
4726169689Skan
4727169689Skan  if (mips_arch_string != 0)
4728169689Skan    mips_set_architecture (mips_parse_cpu (mips_arch_string));
4729169689Skan
4730169689Skan  if (mips_isa_info != 0)
4731169689Skan    {
4732169689Skan      if (mips_arch_info == 0)
4733169689Skan	mips_set_architecture (mips_isa_info);
4734169689Skan      else if (mips_arch_info->isa != mips_isa_info->isa)
4735169689Skan	error ("-%s conflicts with the other architecture options, "
4736169689Skan	       "which specify a %s processor",
4737169689Skan	       mips_isa_info->name,
4738169689Skan	       mips_cpu_info_from_isa (mips_arch_info->isa)->name);
4739169689Skan    }
4740169689Skan
4741169689Skan  if (mips_arch_info == 0)
4742169689Skan    {
4743169689Skan#ifdef MIPS_CPU_STRING_DEFAULT
4744169689Skan      mips_set_architecture (mips_parse_cpu (MIPS_CPU_STRING_DEFAULT));
4745169689Skan#else
4746169689Skan      mips_set_architecture (mips_cpu_info_from_isa (MIPS_ISA_DEFAULT));
4747169689Skan#endif
4748169689Skan    }
4749169689Skan
4750169689Skan  if (ABI_NEEDS_64BIT_REGS && !ISA_HAS_64BIT_REGS)
4751169689Skan    error ("-march=%s is not compatible with the selected ABI",
4752169689Skan	   mips_arch_info->name);
4753169689Skan
4754169689Skan  /* Optimize for mips_arch, unless -mtune selects a different processor.  */
4755169689Skan  if (mips_tune_string != 0)
4756169689Skan    mips_set_tune (mips_parse_cpu (mips_tune_string));
4757169689Skan
4758169689Skan  if (mips_tune_info == 0)
4759169689Skan    mips_set_tune (mips_arch_info);
4760169689Skan
4761169689Skan  /* Set cost structure for the processor.  */
4762169689Skan  mips_cost = &mips_rtx_cost_data[mips_tune];
4763169689Skan
4764169689Skan  if ((target_flags_explicit & MASK_64BIT) != 0)
4765169689Skan    {
4766169689Skan      /* The user specified the size of the integer registers.  Make sure
4767169689Skan	 it agrees with the ABI and ISA.  */
4768169689Skan      if (TARGET_64BIT && !ISA_HAS_64BIT_REGS)
4769169689Skan	error ("-mgp64 used with a 32-bit processor");
4770169689Skan      else if (!TARGET_64BIT && ABI_NEEDS_64BIT_REGS)
4771169689Skan	error ("-mgp32 used with a 64-bit ABI");
4772169689Skan      else if (TARGET_64BIT && ABI_NEEDS_32BIT_REGS)
4773169689Skan	error ("-mgp64 used with a 32-bit ABI");
4774169689Skan    }
4775169689Skan  else
4776169689Skan    {
4777169689Skan      /* Infer the integer register size from the ABI and processor.
4778169689Skan	 Restrict ourselves to 32-bit registers if that's all the
4779169689Skan	 processor has, or if the ABI cannot handle 64-bit registers.  */
4780169689Skan      if (ABI_NEEDS_32BIT_REGS || !ISA_HAS_64BIT_REGS)
4781169689Skan	target_flags &= ~MASK_64BIT;
4782169689Skan      else
4783169689Skan	target_flags |= MASK_64BIT;
4784169689Skan    }
4785169689Skan
4786169689Skan  if ((target_flags_explicit & MASK_FLOAT64) != 0)
4787169689Skan    {
4788169689Skan      /* Really, -mfp32 and -mfp64 are ornamental options.  There's
4789169689Skan	 only one right answer here.  */
4790169689Skan      if (TARGET_64BIT && TARGET_DOUBLE_FLOAT && !TARGET_FLOAT64)
4791169689Skan	error ("unsupported combination: %s", "-mgp64 -mfp32 -mdouble-float");
4792169689Skan      else if (!TARGET_64BIT && TARGET_FLOAT64)
4793169689Skan	error ("unsupported combination: %s", "-mgp32 -mfp64");
4794169689Skan      else if (TARGET_SINGLE_FLOAT && TARGET_FLOAT64)
4795169689Skan	error ("unsupported combination: %s", "-mfp64 -msingle-float");
4796169689Skan    }
4797169689Skan  else
4798169689Skan    {
4799169689Skan      /* -msingle-float selects 32-bit float registers.  Otherwise the
4800169689Skan	 float registers should be the same size as the integer ones.  */
4801169689Skan      if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
4802169689Skan	target_flags |= MASK_FLOAT64;
4803169689Skan      else
4804169689Skan	target_flags &= ~MASK_FLOAT64;
4805169689Skan    }
4806169689Skan
4807169689Skan  /* End of code shared with GAS.  */
4808169689Skan
4809169689Skan  if ((target_flags_explicit & MASK_LONG64) == 0)
4810169689Skan    {
4811169689Skan      if ((mips_abi == ABI_EABI && TARGET_64BIT) || mips_abi == ABI_64)
4812169689Skan	target_flags |= MASK_LONG64;
4813169689Skan      else
4814169689Skan	target_flags &= ~MASK_LONG64;
4815169689Skan    }
4816169689Skan
4817169689Skan  if (MIPS_MARCH_CONTROLS_SOFT_FLOAT
4818169689Skan      && (target_flags_explicit & MASK_SOFT_FLOAT) == 0)
4819169689Skan    {
4820169689Skan      /* For some configurations, it is useful to have -march control
4821169689Skan	 the default setting of MASK_SOFT_FLOAT.  */
4822169689Skan      switch ((int) mips_arch)
4823169689Skan	{
4824169689Skan	case PROCESSOR_R4100:
4825169689Skan	case PROCESSOR_R4111:
4826169689Skan	case PROCESSOR_R4120:
4827169689Skan	case PROCESSOR_R4130:
4828169689Skan	  target_flags |= MASK_SOFT_FLOAT;
4829169689Skan	  break;
4830169689Skan
4831169689Skan	default:
4832169689Skan	  target_flags &= ~MASK_SOFT_FLOAT;
4833169689Skan	  break;
4834169689Skan	}
4835169689Skan    }
4836169689Skan
4837169689Skan  if (!TARGET_OLDABI)
4838169689Skan    flag_pcc_struct_return = 0;
4839169689Skan
4840169689Skan  if ((target_flags_explicit & MASK_BRANCHLIKELY) == 0)
4841169689Skan    {
4842169689Skan      /* If neither -mbranch-likely nor -mno-branch-likely was given
4843169689Skan	 on the command line, set MASK_BRANCHLIKELY based on the target
4844169689Skan	 architecture.
4845169689Skan
4846169689Skan	 By default, we enable use of Branch Likely instructions on
4847169689Skan	 all architectures which support them with the following
4848169689Skan	 exceptions: when creating MIPS32 or MIPS64 code, and when
4849169689Skan	 tuning for architectures where their use tends to hurt
4850169689Skan	 performance.
4851169689Skan
4852169689Skan	 The MIPS32 and MIPS64 architecture specifications say "Software
4853169689Skan	 is strongly encouraged to avoid use of Branch Likely
4854169689Skan	 instructions, as they will be removed from a future revision
4855169689Skan	 of the [MIPS32 and MIPS64] architecture."  Therefore, we do not
4856169689Skan	 issue those instructions unless instructed to do so by
4857169689Skan	 -mbranch-likely.  */
4858169689Skan      if (ISA_HAS_BRANCHLIKELY
4859208737Sjmallett	  && !(ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64 || ISA_MIPS64R2)
4860169689Skan	  && !(TUNE_MIPS5500 || TUNE_SB1))
4861169689Skan	target_flags |= MASK_BRANCHLIKELY;
4862169689Skan      else
4863169689Skan	target_flags &= ~MASK_BRANCHLIKELY;
4864169689Skan    }
4865169689Skan  if (TARGET_BRANCHLIKELY && !ISA_HAS_BRANCHLIKELY)
4866169689Skan    warning (0, "generation of Branch Likely instructions enabled, but not supported by architecture");
4867169689Skan
4868169689Skan  /* The effect of -mabicalls isn't defined for the EABI.  */
4869169689Skan  if (mips_abi == ABI_EABI && TARGET_ABICALLS)
4870169689Skan    {
4871169689Skan      error ("unsupported combination: %s", "-mabicalls -mabi=eabi");
4872169689Skan      target_flags &= ~MASK_ABICALLS;
4873169689Skan    }
4874169689Skan
4875169689Skan  if (TARGET_ABICALLS)
4876169689Skan    {
4877169689Skan      /* We need to set flag_pic for executables as well as DSOs
4878169689Skan	 because we may reference symbols that are not defined in
4879169689Skan	 the final executable.  (MIPS does not use things like
4880169689Skan	 copy relocs, for example.)
4881169689Skan
4882169689Skan	 Also, there is a body of code that uses __PIC__ to distinguish
4883169689Skan	 between -mabicalls and -mno-abicalls code.  */
4884169689Skan      flag_pic = 1;
4885169689Skan      if (mips_section_threshold > 0)
4886169689Skan	warning (0, "%<-G%> is incompatible with %<-mabicalls%>");
4887169689Skan    }
4888169689Skan
4889169689Skan  /* mips_split_addresses is a half-way house between explicit
4890169689Skan     relocations and the traditional assembler macros.  It can
4891169689Skan     split absolute 32-bit symbolic constants into a high/lo_sum
4892169689Skan     pair but uses macros for other sorts of access.
4893169689Skan
4894169689Skan     Like explicit relocation support for REL targets, it relies
4895169689Skan     on GNU extensions in the assembler and the linker.
4896169689Skan
4897169689Skan     Although this code should work for -O0, it has traditionally
4898169689Skan     been treated as an optimization.  */
4899169689Skan  if (!TARGET_MIPS16 && TARGET_SPLIT_ADDRESSES
4900169689Skan      && optimize && !flag_pic
4901169689Skan      && !ABI_HAS_64BIT_SYMBOLS)
4902169689Skan    mips_split_addresses = 1;
4903169689Skan  else
4904169689Skan    mips_split_addresses = 0;
4905169689Skan
4906169689Skan  /* -mvr4130-align is a "speed over size" optimization: it usually produces
4907169689Skan     faster code, but at the expense of more nops.  Enable it at -O3 and
4908169689Skan     above.  */
4909169689Skan  if (optimize > 2 && (target_flags_explicit & MASK_VR4130_ALIGN) == 0)
4910169689Skan    target_flags |= MASK_VR4130_ALIGN;
4911169689Skan
4912169689Skan  /* When compiling for the mips16, we cannot use floating point.  We
4913169689Skan     record the original hard float value in mips16_hard_float.  */
4914169689Skan  if (TARGET_MIPS16)
4915169689Skan    {
4916169689Skan      if (TARGET_SOFT_FLOAT)
4917169689Skan	mips16_hard_float = 0;
4918169689Skan      else
4919169689Skan	mips16_hard_float = 1;
4920169689Skan      target_flags |= MASK_SOFT_FLOAT;
4921169689Skan
4922169689Skan      /* Don't run the scheduler before reload, since it tends to
4923169689Skan         increase register pressure.  */
4924169689Skan      flag_schedule_insns = 0;
4925169689Skan
4926169689Skan      /* Don't do hot/cold partitioning.  The constant layout code expects
4927169689Skan	 the whole function to be in a single section.  */
4928169689Skan      flag_reorder_blocks_and_partition = 0;
4929169689Skan
4930169689Skan      /* Silently disable -mexplicit-relocs since it doesn't apply
4931169689Skan	 to mips16 code.  Even so, it would overly pedantic to warn
4932169689Skan	 about "-mips16 -mexplicit-relocs", especially given that
4933169689Skan	 we use a %gprel() operator.  */
4934169689Skan      target_flags &= ~MASK_EXPLICIT_RELOCS;
4935169689Skan    }
4936169689Skan
4937169689Skan  /* When using explicit relocs, we call dbr_schedule from within
4938169689Skan     mips_reorg.  */
4939169689Skan  if (TARGET_EXPLICIT_RELOCS)
4940169689Skan    {
4941169689Skan      mips_flag_delayed_branch = flag_delayed_branch;
4942169689Skan      flag_delayed_branch = 0;
4943169689Skan    }
4944169689Skan
4945169689Skan#ifdef MIPS_TFMODE_FORMAT
4946169689Skan  REAL_MODE_FORMAT (TFmode) = &MIPS_TFMODE_FORMAT;
4947169689Skan#endif
4948169689Skan
4949169689Skan  /* Make sure that the user didn't turn off paired single support when
4950169689Skan     MIPS-3D support is requested.  */
4951169689Skan  if (TARGET_MIPS3D && (target_flags_explicit & MASK_PAIRED_SINGLE_FLOAT)
4952169689Skan      && !TARGET_PAIRED_SINGLE_FLOAT)
4953169689Skan    error ("-mips3d requires -mpaired-single");
4954169689Skan
4955169689Skan  /* If TARGET_MIPS3D, enable MASK_PAIRED_SINGLE_FLOAT.  */
4956169689Skan  if (TARGET_MIPS3D)
4957169689Skan    target_flags |= MASK_PAIRED_SINGLE_FLOAT;
4958169689Skan
4959169689Skan  /* Make sure that when TARGET_PAIRED_SINGLE_FLOAT is true, TARGET_FLOAT64
4960169689Skan     and TARGET_HARD_FLOAT are both true.  */
4961169689Skan  if (TARGET_PAIRED_SINGLE_FLOAT && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT))
4962169689Skan    error ("-mips3d/-mpaired-single must be used with -mfp64 -mhard-float");
4963169689Skan
4964169689Skan  /* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
4965169689Skan     enabled.  */
4966169689Skan  if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
4967169689Skan    error ("-mips3d/-mpaired-single must be used with -mips64");
4968169689Skan
4969169689Skan  if (TARGET_MIPS16 && TARGET_DSP)
4970169689Skan    error ("-mips16 and -mdsp cannot be used together");
4971169689Skan
4972169689Skan  mips_print_operand_punct['?'] = 1;
4973169689Skan  mips_print_operand_punct['#'] = 1;
4974169689Skan  mips_print_operand_punct['/'] = 1;
4975169689Skan  mips_print_operand_punct['&'] = 1;
4976169689Skan  mips_print_operand_punct['!'] = 1;
4977169689Skan  mips_print_operand_punct['*'] = 1;
4978169689Skan  mips_print_operand_punct['@'] = 1;
4979169689Skan  mips_print_operand_punct['.'] = 1;
4980169689Skan  mips_print_operand_punct['('] = 1;
4981169689Skan  mips_print_operand_punct[')'] = 1;
4982169689Skan  mips_print_operand_punct['['] = 1;
4983169689Skan  mips_print_operand_punct[']'] = 1;
4984169689Skan  mips_print_operand_punct['<'] = 1;
4985169689Skan  mips_print_operand_punct['>'] = 1;
4986169689Skan  mips_print_operand_punct['{'] = 1;
4987169689Skan  mips_print_operand_punct['}'] = 1;
4988169689Skan  mips_print_operand_punct['^'] = 1;
4989169689Skan  mips_print_operand_punct['$'] = 1;
4990169689Skan  mips_print_operand_punct['+'] = 1;
4991169689Skan  mips_print_operand_punct['~'] = 1;
4992169689Skan
4993169689Skan  /* Set up array to map GCC register number to debug register number.
4994169689Skan     Ignore the special purpose register numbers.  */
4995169689Skan
4996169689Skan  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4997169689Skan    mips_dbx_regno[i] = -1;
4998169689Skan
4999169689Skan  start = GP_DBX_FIRST - GP_REG_FIRST;
5000169689Skan  for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
5001169689Skan    mips_dbx_regno[i] = i + start;
5002169689Skan
5003169689Skan  start = FP_DBX_FIRST - FP_REG_FIRST;
5004169689Skan  for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
5005169689Skan    mips_dbx_regno[i] = i + start;
5006169689Skan
5007169689Skan  mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
5008169689Skan  mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
5009169689Skan
5010169689Skan  /* Set up array giving whether a given register can hold a given mode.  */
5011169689Skan
5012169689Skan  for (mode = VOIDmode;
5013169689Skan       mode != MAX_MACHINE_MODE;
5014169689Skan       mode = (enum machine_mode) ((int)mode + 1))
5015169689Skan    {
5016169689Skan      register int size		     = GET_MODE_SIZE (mode);
5017169689Skan      register enum mode_class class = GET_MODE_CLASS (mode);
5018169689Skan
5019169689Skan      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
5020169689Skan	{
5021169689Skan	  register int temp;
5022169689Skan
5023169689Skan	  if (mode == CCV2mode)
5024169689Skan	    temp = (ISA_HAS_8CC
5025169689Skan		    && ST_REG_P (regno)
5026169689Skan		    && (regno - ST_REG_FIRST) % 2 == 0);
5027169689Skan
5028169689Skan	  else if (mode == CCV4mode)
5029169689Skan	    temp = (ISA_HAS_8CC
5030169689Skan		    && ST_REG_P (regno)
5031169689Skan		    && (regno - ST_REG_FIRST) % 4 == 0);
5032169689Skan
5033169689Skan	  else if (mode == CCmode)
5034169689Skan	    {
5035169689Skan	      if (! ISA_HAS_8CC)
5036169689Skan		temp = (regno == FPSW_REGNUM);
5037169689Skan	      else
5038169689Skan		temp = (ST_REG_P (regno) || GP_REG_P (regno)
5039169689Skan			|| FP_REG_P (regno));
5040169689Skan	    }
5041169689Skan
5042169689Skan	  else if (GP_REG_P (regno))
5043169689Skan	    temp = ((regno & 1) == 0 || size <= UNITS_PER_WORD);
5044169689Skan
5045169689Skan	  else if (FP_REG_P (regno))
5046169689Skan	    temp = ((regno % FP_INC) == 0)
5047169689Skan		    && (((class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT
5048169689Skan			  || class == MODE_VECTOR_FLOAT)
5049169689Skan			 && size <= UNITS_PER_FPVALUE)
5050169689Skan			/* Allow integer modes that fit into a single
5051169689Skan			   register.  We need to put integers into FPRs
5052169689Skan			   when using instructions like cvt and trunc.
5053169689Skan			   We can't allow sizes smaller than a word,
5054169689Skan			   the FPU has no appropriate load/store
5055169689Skan			   instructions for those.  */
5056169689Skan			|| (class == MODE_INT
5057169689Skan			    && size >= MIN_UNITS_PER_WORD
5058169689Skan			    && size <= UNITS_PER_FPREG)
5059169689Skan			/* Allow TFmode for CCmode reloads.  */
5060169689Skan			|| (ISA_HAS_8CC && mode == TFmode));
5061169689Skan
5062169689Skan          else if (ACC_REG_P (regno))
5063169689Skan	    temp = (INTEGRAL_MODE_P (mode)
5064169689Skan		    && (size <= UNITS_PER_WORD
5065169689Skan			|| (ACC_HI_REG_P (regno)
5066169689Skan			    && size == 2 * UNITS_PER_WORD)));
5067169689Skan
5068169689Skan	  else if (ALL_COP_REG_P (regno))
5069169689Skan	    temp = (class == MODE_INT && size <= UNITS_PER_WORD);
5070169689Skan	  else
5071169689Skan	    temp = 0;
5072169689Skan
5073169689Skan	  mips_hard_regno_mode_ok[(int)mode][regno] = temp;
5074169689Skan	}
5075169689Skan    }
5076169689Skan
5077169689Skan  /* Save GPR registers in word_mode sized hunks.  word_mode hasn't been
5078169689Skan     initialized yet, so we can't use that here.  */
5079169689Skan  gpr_mode = TARGET_64BIT ? DImode : SImode;
5080169689Skan
5081169689Skan  /* Provide default values for align_* for 64-bit targets.  */
5082169689Skan  if (TARGET_64BIT && !TARGET_MIPS16)
5083169689Skan    {
5084169689Skan      if (align_loops == 0)
5085169689Skan	align_loops = 8;
5086169689Skan      if (align_jumps == 0)
5087169689Skan	align_jumps = 8;
5088169689Skan      if (align_functions == 0)
5089169689Skan	align_functions = 8;
5090169689Skan    }
5091169689Skan
5092169689Skan  /* Function to allocate machine-dependent function status.  */
5093169689Skan  init_machine_status = &mips_init_machine_status;
5094169689Skan
5095169689Skan  if (ABI_HAS_64BIT_SYMBOLS)
5096169689Skan    {
5097169689Skan      if (TARGET_EXPLICIT_RELOCS)
5098169689Skan	{
5099169689Skan	  mips_split_p[SYMBOL_64_HIGH] = true;
5100169689Skan	  mips_hi_relocs[SYMBOL_64_HIGH] = "%highest(";
5101169689Skan	  mips_lo_relocs[SYMBOL_64_HIGH] = "%higher(";
5102169689Skan
5103169689Skan	  mips_split_p[SYMBOL_64_MID] = true;
5104169689Skan	  mips_hi_relocs[SYMBOL_64_MID] = "%higher(";
5105169689Skan	  mips_lo_relocs[SYMBOL_64_MID] = "%hi(";
5106169689Skan
5107169689Skan	  mips_split_p[SYMBOL_64_LOW] = true;
5108169689Skan	  mips_hi_relocs[SYMBOL_64_LOW] = "%hi(";
5109169689Skan	  mips_lo_relocs[SYMBOL_64_LOW] = "%lo(";
5110169689Skan
5111169689Skan	  mips_split_p[SYMBOL_GENERAL] = true;
5112169689Skan	  mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
5113169689Skan	}
5114169689Skan    }
5115169689Skan  else
5116169689Skan    {
5117169689Skan      if (TARGET_EXPLICIT_RELOCS || mips_split_addresses)
5118169689Skan	{
5119169689Skan	  mips_split_p[SYMBOL_GENERAL] = true;
5120169689Skan	  mips_hi_relocs[SYMBOL_GENERAL] = "%hi(";
5121169689Skan	  mips_lo_relocs[SYMBOL_GENERAL] = "%lo(";
5122169689Skan	}
5123169689Skan    }
5124169689Skan
5125169689Skan  if (TARGET_MIPS16)
5126169689Skan    {
5127169689Skan      /* The high part is provided by a pseudo copy of $gp.  */
5128169689Skan      mips_split_p[SYMBOL_SMALL_DATA] = true;
5129169689Skan      mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gprel(";
5130169689Skan    }
5131169689Skan
5132169689Skan  if (TARGET_EXPLICIT_RELOCS)
5133169689Skan    {
5134169689Skan      /* Small data constants are kept whole until after reload,
5135169689Skan	 then lowered by mips_rewrite_small_data.  */
5136169689Skan      mips_lo_relocs[SYMBOL_SMALL_DATA] = "%gp_rel(";
5137169689Skan
5138169689Skan      mips_split_p[SYMBOL_GOT_LOCAL] = true;
5139169689Skan      if (TARGET_NEWABI)
5140169689Skan	{
5141169689Skan	  mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got_page(";
5142169689Skan	  mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%got_ofst(";
5143169689Skan	}
5144169689Skan      else
5145169689Skan	{
5146169689Skan	  mips_lo_relocs[SYMBOL_GOTOFF_PAGE] = "%got(";
5147169689Skan	  mips_lo_relocs[SYMBOL_GOT_LOCAL] = "%lo(";
5148169689Skan	}
5149169689Skan
5150169689Skan      if (TARGET_XGOT)
5151169689Skan	{
5152169689Skan	  /* The HIGH and LO_SUM are matched by special .md patterns.  */
5153169689Skan	  mips_split_p[SYMBOL_GOT_GLOBAL] = true;
5154169689Skan
5155169689Skan	  mips_split_p[SYMBOL_GOTOFF_GLOBAL] = true;
5156169689Skan	  mips_hi_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_hi(";
5157169689Skan	  mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_lo(";
5158169689Skan
5159169689Skan	  mips_split_p[SYMBOL_GOTOFF_CALL] = true;
5160169689Skan	  mips_hi_relocs[SYMBOL_GOTOFF_CALL] = "%call_hi(";
5161169689Skan	  mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call_lo(";
5162169689Skan	}
5163169689Skan      else
5164169689Skan	{
5165169689Skan	  if (TARGET_NEWABI)
5166169689Skan	    mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got_disp(";
5167169689Skan	  else
5168169689Skan	    mips_lo_relocs[SYMBOL_GOTOFF_GLOBAL] = "%got(";
5169169689Skan	  mips_lo_relocs[SYMBOL_GOTOFF_CALL] = "%call16(";
5170169689Skan	}
5171169689Skan    }
5172169689Skan
5173169689Skan  if (TARGET_NEWABI)
5174169689Skan    {
5175169689Skan      mips_split_p[SYMBOL_GOTOFF_LOADGP] = true;
5176169689Skan      mips_hi_relocs[SYMBOL_GOTOFF_LOADGP] = "%hi(%neg(%gp_rel(";
5177169689Skan      mips_lo_relocs[SYMBOL_GOTOFF_LOADGP] = "%lo(%neg(%gp_rel(";
5178169689Skan    }
5179169689Skan
5180169689Skan  /* Thread-local relocation operators.  */
5181169689Skan  mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd(";
5182169689Skan  mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm(";
5183169689Skan  mips_split_p[SYMBOL_DTPREL] = 1;
5184169689Skan  mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi(";
5185169689Skan  mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo(";
5186169689Skan  mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel(";
5187169689Skan  mips_split_p[SYMBOL_TPREL] = 1;
5188169689Skan  mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi(";
5189169689Skan  mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo(";
5190169689Skan
5191169689Skan  /* We don't have a thread pointer access instruction on MIPS16, or
5192169689Skan     appropriate TLS relocations.  */
5193169689Skan  if (TARGET_MIPS16)
5194169689Skan    targetm.have_tls = false;
5195169689Skan
5196169689Skan  /* Default to working around R4000 errata only if the processor
5197169689Skan     was selected explicitly.  */
5198169689Skan  if ((target_flags_explicit & MASK_FIX_R4000) == 0
5199169689Skan      && mips_matching_cpu_name_p (mips_arch_info->name, "r4000"))
5200169689Skan    target_flags |= MASK_FIX_R4000;
5201169689Skan
5202169689Skan  /* Default to working around R4400 errata only if the processor
5203169689Skan     was selected explicitly.  */
5204169689Skan  if ((target_flags_explicit & MASK_FIX_R4400) == 0
5205169689Skan      && mips_matching_cpu_name_p (mips_arch_info->name, "r4400"))
5206169689Skan    target_flags |= MASK_FIX_R4400;
5207169689Skan}
5208169689Skan
5209169689Skan/* Implement CONDITIONAL_REGISTER_USAGE.  */
5210169689Skan
5211169689Skanvoid
5212169689Skanmips_conditional_register_usage (void)
5213169689Skan{
5214169689Skan  if (!TARGET_DSP)
5215169689Skan    {
5216169689Skan      int regno;
5217169689Skan
5218169689Skan      for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++)
5219169689Skan	fixed_regs[regno] = call_used_regs[regno] = 1;
5220169689Skan    }
5221169689Skan  if (!TARGET_HARD_FLOAT)
5222169689Skan    {
5223169689Skan      int regno;
5224169689Skan
5225169689Skan      for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
5226169689Skan	fixed_regs[regno] = call_used_regs[regno] = 1;
5227169689Skan      for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++)
5228169689Skan	fixed_regs[regno] = call_used_regs[regno] = 1;
5229169689Skan    }
5230169689Skan  else if (! ISA_HAS_8CC)
5231169689Skan    {
5232169689Skan      int regno;
5233169689Skan
5234169689Skan      /* We only have a single condition code register.  We
5235169689Skan	 implement this by hiding all the condition code registers,
5236169689Skan	 and generating RTL that refers directly to ST_REG_FIRST.  */
5237169689Skan      for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++)
5238169689Skan	fixed_regs[regno] = call_used_regs[regno] = 1;
5239169689Skan    }
5240169689Skan  /* In mips16 mode, we permit the $t temporary registers to be used
5241169689Skan     for reload.  We prohibit the unused $s registers, since they
5242169689Skan     are caller saved, and saving them via a mips16 register would
5243169689Skan     probably waste more time than just reloading the value.  */
5244169689Skan  if (TARGET_MIPS16)
5245169689Skan    {
5246169689Skan      fixed_regs[18] = call_used_regs[18] = 1;
5247169689Skan      fixed_regs[19] = call_used_regs[19] = 1;
5248169689Skan      fixed_regs[20] = call_used_regs[20] = 1;
5249169689Skan      fixed_regs[21] = call_used_regs[21] = 1;
5250169689Skan      fixed_regs[22] = call_used_regs[22] = 1;
5251169689Skan      fixed_regs[23] = call_used_regs[23] = 1;
5252169689Skan      fixed_regs[26] = call_used_regs[26] = 1;
5253169689Skan      fixed_regs[27] = call_used_regs[27] = 1;
5254169689Skan      fixed_regs[30] = call_used_regs[30] = 1;
5255169689Skan    }
5256169689Skan  /* fp20-23 are now caller saved.  */
5257169689Skan  if (mips_abi == ABI_64)
5258169689Skan    {
5259169689Skan      int regno;
5260169689Skan      for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++)
5261169689Skan	call_really_used_regs[regno] = call_used_regs[regno] = 1;
5262169689Skan    }
5263169689Skan  /* Odd registers from fp21 to fp31 are now caller saved.  */
5264169689Skan  if (mips_abi == ABI_N32)
5265169689Skan    {
5266169689Skan      int regno;
5267169689Skan      for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
5268169689Skan	call_really_used_regs[regno] = call_used_regs[regno] = 1;
5269169689Skan    }
5270169689Skan}
5271169689Skan
5272169689Skan/* Allocate a chunk of memory for per-function machine-dependent data.  */
5273169689Skanstatic struct machine_function *
5274169689Skanmips_init_machine_status (void)
5275169689Skan{
5276169689Skan  return ((struct machine_function *)
5277169689Skan	  ggc_alloc_cleared (sizeof (struct machine_function)));
5278169689Skan}
5279169689Skan
5280169689Skan/* On the mips16, we want to allocate $24 (T_REG) before other
5281169689Skan   registers for instructions for which it is possible.  This helps
5282169689Skan   avoid shuffling registers around in order to set up for an xor,
5283169689Skan   encouraging the compiler to use a cmp instead.  */
5284169689Skan
5285169689Skanvoid
5286169689Skanmips_order_regs_for_local_alloc (void)
5287169689Skan{
5288169689Skan  register int i;
5289169689Skan
5290169689Skan  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5291169689Skan    reg_alloc_order[i] = i;
5292169689Skan
5293169689Skan  if (TARGET_MIPS16)
5294169689Skan    {
5295169689Skan      /* It really doesn't matter where we put register 0, since it is
5296169689Skan         a fixed register anyhow.  */
5297169689Skan      reg_alloc_order[0] = 24;
5298169689Skan      reg_alloc_order[24] = 0;
5299169689Skan    }
5300169689Skan}
5301169689Skan
5302169689Skan
5303169689Skan/* The MIPS debug format wants all automatic variables and arguments
5304169689Skan   to be in terms of the virtual frame pointer (stack pointer before
5305169689Skan   any adjustment in the function), while the MIPS 3.0 linker wants
5306169689Skan   the frame pointer to be the stack pointer after the initial
5307169689Skan   adjustment.  So, we do the adjustment here.  The arg pointer (which
5308169689Skan   is eliminated) points to the virtual frame pointer, while the frame
5309169689Skan   pointer (which may be eliminated) points to the stack pointer after
5310169689Skan   the initial adjustments.  */
5311169689Skan
5312169689SkanHOST_WIDE_INT
5313169689Skanmips_debugger_offset (rtx addr, HOST_WIDE_INT offset)
5314169689Skan{
5315169689Skan  rtx offset2 = const0_rtx;
5316169689Skan  rtx reg = eliminate_constant_term (addr, &offset2);
5317169689Skan
5318169689Skan  if (offset == 0)
5319169689Skan    offset = INTVAL (offset2);
5320169689Skan
5321169689Skan  if (reg == stack_pointer_rtx || reg == frame_pointer_rtx
5322169689Skan      || reg == hard_frame_pointer_rtx)
5323169689Skan    {
5324169689Skan      HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized)
5325169689Skan				  ? compute_frame_size (get_frame_size ())
5326169689Skan				  : cfun->machine->frame.total_size;
5327169689Skan
5328169689Skan      /* MIPS16 frame is smaller */
5329169689Skan      if (frame_pointer_needed && TARGET_MIPS16)
5330169689Skan	frame_size -= cfun->machine->frame.args_size;
5331169689Skan
5332169689Skan      offset = offset - frame_size;
5333169689Skan    }
5334169689Skan
5335169689Skan  /* sdbout_parms does not want this to crash for unrecognized cases.  */
5336169689Skan#if 0
5337169689Skan  else if (reg != arg_pointer_rtx)
5338169689Skan    fatal_insn ("mips_debugger_offset called with non stack/frame/arg pointer",
5339169689Skan		addr);
5340169689Skan#endif
5341169689Skan
5342169689Skan  return offset;
5343169689Skan}
5344169689Skan
5345169689Skan/* Implement the PRINT_OPERAND macro.  The MIPS-specific operand codes are:
5346169689Skan
5347169689Skan   'X'  OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
5348169689Skan   'x'  OP is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
5349169689Skan   'h'  OP is HIGH, prints %hi(X),
5350169689Skan   'd'  output integer constant in decimal,
5351169689Skan   'z'	if the operand is 0, use $0 instead of normal operand.
5352169689Skan   'D'  print second part of double-word register or memory operand.
5353169689Skan   'L'  print low-order register of double-word register operand.
5354169689Skan   'M'  print high-order register of double-word register operand.
5355169689Skan   'C'  print part of opcode for a branch condition.
5356169689Skan   'F'  print part of opcode for a floating-point branch condition.
5357169689Skan   'N'  print part of opcode for a branch condition, inverted.
5358169689Skan   'W'  print part of opcode for a floating-point branch condition, inverted.
5359169689Skan   'T'  print 'f' for (eq:CC ...), 't' for (ne:CC ...),
5360169689Skan	      'z' for (eq:?I ...), 'n' for (ne:?I ...).
5361169689Skan   't'  like 'T', but with the EQ/NE cases reversed
5362169689Skan   'Y'  for a CONST_INT X, print mips_fp_conditions[X]
5363169689Skan   'Z'  print the operand and a comma for ISA_HAS_8CC, otherwise print nothing
5364169689Skan   'R'  print the reloc associated with LO_SUM
5365169689Skan   'q'  print DSP accumulator registers
5366169689Skan
5367169689Skan   The punctuation characters are:
5368169689Skan
5369169689Skan   '('	Turn on .set noreorder
5370169689Skan   ')'	Turn on .set reorder
5371169689Skan   '['	Turn on .set noat
5372169689Skan   ']'	Turn on .set at
5373169689Skan   '<'	Turn on .set nomacro
5374169689Skan   '>'	Turn on .set macro
5375169689Skan   '{'	Turn on .set volatile (not GAS)
5376169689Skan   '}'	Turn on .set novolatile (not GAS)
5377169689Skan   '&'	Turn on .set noreorder if filling delay slots
5378169689Skan   '*'	Turn on both .set noreorder and .set nomacro if filling delay slots
5379169689Skan   '!'	Turn on .set nomacro if filling delay slots
5380169689Skan   '#'	Print nop if in a .set noreorder section.
5381169689Skan   '/'	Like '#', but does nothing within a delayed branch sequence
5382169689Skan   '?'	Print 'l' if we are to use a branch likely instead of normal branch.
5383169689Skan   '@'	Print the name of the assembler temporary register (at or $1).
5384169689Skan   '.'	Print the name of the register with a hard-wired zero (zero or $0).
5385169689Skan   '^'	Print the name of the pic call-through register (t9 or $25).
5386169689Skan   '$'	Print the name of the stack pointer register (sp or $29).
5387169689Skan   '+'	Print the name of the gp register (usually gp or $28).
5388169689Skan   '~'	Output a branch alignment to LABEL_ALIGN(NULL).  */
5389169689Skan
5390169689Skanvoid
5391169689Skanprint_operand (FILE *file, rtx op, int letter)
5392169689Skan{
5393169689Skan  register enum rtx_code code;
5394169689Skan
5395169689Skan  if (PRINT_OPERAND_PUNCT_VALID_P (letter))
5396169689Skan    {
5397169689Skan      switch (letter)
5398169689Skan	{
5399169689Skan	case '?':
5400169689Skan	  if (mips_branch_likely)
5401169689Skan	    putc ('l', file);
5402169689Skan	  break;
5403169689Skan
5404169689Skan	case '@':
5405169689Skan	  fputs (reg_names [GP_REG_FIRST + 1], file);
5406169689Skan	  break;
5407169689Skan
5408169689Skan	case '^':
5409169689Skan	  fputs (reg_names [PIC_FUNCTION_ADDR_REGNUM], file);
5410169689Skan	  break;
5411169689Skan
5412169689Skan	case '.':
5413169689Skan	  fputs (reg_names [GP_REG_FIRST + 0], file);
5414169689Skan	  break;
5415169689Skan
5416169689Skan	case '$':
5417169689Skan	  fputs (reg_names[STACK_POINTER_REGNUM], file);
5418169689Skan	  break;
5419169689Skan
5420169689Skan	case '+':
5421169689Skan	  fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
5422169689Skan	  break;
5423169689Skan
5424169689Skan	case '&':
5425169689Skan	  if (final_sequence != 0 && set_noreorder++ == 0)
5426169689Skan	    fputs (".set\tnoreorder\n\t", file);
5427169689Skan	  break;
5428169689Skan
5429169689Skan	case '*':
5430169689Skan	  if (final_sequence != 0)
5431169689Skan	    {
5432169689Skan	      if (set_noreorder++ == 0)
5433169689Skan		fputs (".set\tnoreorder\n\t", file);
5434169689Skan
5435169689Skan	      if (set_nomacro++ == 0)
5436169689Skan		fputs (".set\tnomacro\n\t", file);
5437169689Skan	    }
5438169689Skan	  break;
5439169689Skan
5440169689Skan	case '!':
5441169689Skan	  if (final_sequence != 0 && set_nomacro++ == 0)
5442169689Skan	    fputs ("\n\t.set\tnomacro", file);
5443169689Skan	  break;
5444169689Skan
5445169689Skan	case '#':
5446169689Skan	  if (set_noreorder != 0)
5447169689Skan	    fputs ("\n\tnop", file);
5448169689Skan	  break;
5449169689Skan
5450169689Skan	case '/':
5451169689Skan	  /* Print an extra newline so that the delayed insn is separated
5452169689Skan	     from the following ones.  This looks neater and is consistent
5453169689Skan	     with non-nop delayed sequences.  */
5454169689Skan	  if (set_noreorder != 0 && final_sequence == 0)
5455169689Skan	    fputs ("\n\tnop\n", file);
5456169689Skan	  break;
5457169689Skan
5458169689Skan	case '(':
5459169689Skan	  if (set_noreorder++ == 0)
5460169689Skan	    fputs (".set\tnoreorder\n\t", file);
5461169689Skan	  break;
5462169689Skan
5463169689Skan	case ')':
5464169689Skan	  if (set_noreorder == 0)
5465169689Skan	    error ("internal error: %%) found without a %%( in assembler pattern");
5466169689Skan
5467169689Skan	  else if (--set_noreorder == 0)
5468169689Skan	    fputs ("\n\t.set\treorder", file);
5469169689Skan
5470169689Skan	  break;
5471169689Skan
5472169689Skan	case '[':
5473169689Skan	  if (set_noat++ == 0)
5474169689Skan	    fputs (".set\tnoat\n\t", file);
5475169689Skan	  break;
5476169689Skan
5477169689Skan	case ']':
5478169689Skan	  if (set_noat == 0)
5479169689Skan	    error ("internal error: %%] found without a %%[ in assembler pattern");
5480169689Skan	  else if (--set_noat == 0)
5481169689Skan	    fputs ("\n\t.set\tat", file);
5482169689Skan
5483169689Skan	  break;
5484169689Skan
5485169689Skan	case '<':
5486169689Skan	  if (set_nomacro++ == 0)
5487169689Skan	    fputs (".set\tnomacro\n\t", file);
5488169689Skan	  break;
5489169689Skan
5490169689Skan	case '>':
5491169689Skan	  if (set_nomacro == 0)
5492169689Skan	    error ("internal error: %%> found without a %%< in assembler pattern");
5493169689Skan	  else if (--set_nomacro == 0)
5494169689Skan	    fputs ("\n\t.set\tmacro", file);
5495169689Skan
5496169689Skan	  break;
5497169689Skan
5498169689Skan	case '{':
5499169689Skan	  if (set_volatile++ == 0)
5500169689Skan	    fputs ("#.set\tvolatile\n\t", file);
5501169689Skan	  break;
5502169689Skan
5503169689Skan	case '}':
5504169689Skan	  if (set_volatile == 0)
5505169689Skan	    error ("internal error: %%} found without a %%{ in assembler pattern");
5506169689Skan	  else if (--set_volatile == 0)
5507169689Skan	    fputs ("\n\t#.set\tnovolatile", file);
5508169689Skan
5509169689Skan	  break;
5510169689Skan
5511169689Skan	case '~':
5512169689Skan	  {
5513169689Skan	    if (align_labels_log > 0)
5514169689Skan	      ASM_OUTPUT_ALIGN (file, align_labels_log);
5515169689Skan	  }
5516169689Skan	  break;
5517169689Skan
5518169689Skan	default:
5519169689Skan	  error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
5520169689Skan	  break;
5521169689Skan	}
5522169689Skan
5523169689Skan      return;
5524169689Skan    }
5525169689Skan
5526169689Skan  if (! op)
5527169689Skan    {
5528169689Skan      error ("PRINT_OPERAND null pointer");
5529169689Skan      return;
5530169689Skan    }
5531169689Skan
5532169689Skan  code = GET_CODE (op);
5533169689Skan
5534169689Skan  if (letter == 'C')
5535169689Skan    switch (code)
5536169689Skan      {
5537169689Skan      case EQ:	fputs ("eq",  file); break;
5538169689Skan      case NE:	fputs ("ne",  file); break;
5539169689Skan      case GT:	fputs ("gt",  file); break;
5540169689Skan      case GE:	fputs ("ge",  file); break;
5541169689Skan      case LT:	fputs ("lt",  file); break;
5542169689Skan      case LE:	fputs ("le",  file); break;
5543169689Skan      case GTU: fputs ("gtu", file); break;
5544169689Skan      case GEU: fputs ("geu", file); break;
5545169689Skan      case LTU: fputs ("ltu", file); break;
5546169689Skan      case LEU: fputs ("leu", file); break;
5547169689Skan      default:
5548169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%C", op);
5549169689Skan      }
5550169689Skan
5551169689Skan  else if (letter == 'N')
5552169689Skan    switch (code)
5553169689Skan      {
5554169689Skan      case EQ:	fputs ("ne",  file); break;
5555169689Skan      case NE:	fputs ("eq",  file); break;
5556169689Skan      case GT:	fputs ("le",  file); break;
5557169689Skan      case GE:	fputs ("lt",  file); break;
5558169689Skan      case LT:	fputs ("ge",  file); break;
5559169689Skan      case LE:	fputs ("gt",  file); break;
5560169689Skan      case GTU: fputs ("leu", file); break;
5561169689Skan      case GEU: fputs ("ltu", file); break;
5562169689Skan      case LTU: fputs ("geu", file); break;
5563169689Skan      case LEU: fputs ("gtu", file); break;
5564169689Skan      default:
5565169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%N", op);
5566169689Skan      }
5567169689Skan
5568169689Skan  else if (letter == 'F')
5569169689Skan    switch (code)
5570169689Skan      {
5571169689Skan      case EQ: fputs ("c1f", file); break;
5572169689Skan      case NE: fputs ("c1t", file); break;
5573169689Skan      default:
5574169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%F", op);
5575169689Skan      }
5576169689Skan
5577169689Skan  else if (letter == 'W')
5578169689Skan    switch (code)
5579169689Skan      {
5580169689Skan      case EQ: fputs ("c1t", file); break;
5581169689Skan      case NE: fputs ("c1f", file); break;
5582169689Skan      default:
5583169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%W", op);
5584169689Skan      }
5585169689Skan
5586169689Skan  else if (letter == 'h')
5587169689Skan    {
5588169689Skan      if (GET_CODE (op) == HIGH)
5589169689Skan	op = XEXP (op, 0);
5590169689Skan
5591169689Skan      print_operand_reloc (file, op, mips_hi_relocs);
5592169689Skan    }
5593169689Skan
5594169689Skan  else if (letter == 'R')
5595169689Skan    print_operand_reloc (file, op, mips_lo_relocs);
5596169689Skan
5597169689Skan  else if (letter == 'Y')
5598169689Skan    {
5599169689Skan      if (GET_CODE (op) == CONST_INT
5600169689Skan	  && ((unsigned HOST_WIDE_INT) INTVAL (op)
5601169689Skan	      < ARRAY_SIZE (mips_fp_conditions)))
5602169689Skan	fputs (mips_fp_conditions[INTVAL (op)], file);
5603169689Skan      else
5604169689Skan	output_operand_lossage ("invalid %%Y value");
5605169689Skan    }
5606169689Skan
5607169689Skan  else if (letter == 'Z')
5608169689Skan    {
5609169689Skan      if (ISA_HAS_8CC)
5610169689Skan	{
5611169689Skan	  print_operand (file, op, 0);
5612169689Skan	  fputc (',', file);
5613169689Skan	}
5614169689Skan    }
5615169689Skan
5616169689Skan  else if (letter == 'q')
5617169689Skan    {
5618169689Skan      int regnum;
5619169689Skan
5620169689Skan      if (code != REG)
5621169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
5622169689Skan
5623169689Skan      regnum = REGNO (op);
5624169689Skan      if (MD_REG_P (regnum))
5625169689Skan	fprintf (file, "$ac0");
5626169689Skan      else if (DSP_ACC_REG_P (regnum))
5627169689Skan	fprintf (file, "$ac%c", reg_names[regnum][3]);
5628169689Skan      else
5629169689Skan	fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
5630169689Skan    }
5631169689Skan
5632169689Skan  else if (code == REG || code == SUBREG)
5633169689Skan    {
5634169689Skan      register int regnum;
5635169689Skan
5636169689Skan      if (code == REG)
5637169689Skan	regnum = REGNO (op);
5638169689Skan      else
5639169689Skan	regnum = true_regnum (op);
5640169689Skan
5641169689Skan      if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
5642169689Skan	  || (letter == 'L' && WORDS_BIG_ENDIAN)
5643169689Skan	  || letter == 'D')
5644169689Skan	regnum++;
5645169689Skan
5646169689Skan      fprintf (file, "%s", reg_names[regnum]);
5647169689Skan    }
5648169689Skan
5649169689Skan  else if (code == MEM)
5650169689Skan    {
5651169689Skan      if (letter == 'D')
5652169689Skan	output_address (plus_constant (XEXP (op, 0), 4));
5653169689Skan      else
5654169689Skan	output_address (XEXP (op, 0));
5655169689Skan    }
5656169689Skan
5657169689Skan  else if (letter == 'x' && GET_CODE (op) == CONST_INT)
5658169689Skan    fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
5659169689Skan
5660169689Skan  else if (letter == 'X' && GET_CODE(op) == CONST_INT)
5661169689Skan    fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
5662169689Skan
5663169689Skan  else if (letter == 'd' && GET_CODE(op) == CONST_INT)
5664169689Skan    fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
5665169689Skan
5666169689Skan  else if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
5667169689Skan    fputs (reg_names[GP_REG_FIRST], file);
5668169689Skan
5669169689Skan  else if (letter == 'd' || letter == 'x' || letter == 'X')
5670169689Skan    output_operand_lossage ("invalid use of %%d, %%x, or %%X");
5671169689Skan
5672169689Skan  else if (letter == 'T' || letter == 't')
5673169689Skan    {
5674169689Skan      int truth = (code == NE) == (letter == 'T');
5675169689Skan      fputc ("zfnt"[truth * 2 + (GET_MODE (op) == CCmode)], file);
5676169689Skan    }
5677169689Skan
5678169689Skan  else if (CONST_GP_P (op))
5679169689Skan    fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
5680169689Skan
5681169689Skan  else
5682169689Skan    output_addr_const (file, op);
5683169689Skan}
5684169689Skan
5685169689Skan
5686169689Skan/* Print symbolic operand OP, which is part of a HIGH or LO_SUM.
5687169689Skan   RELOCS is the array of relocations to use.  */
5688169689Skan
5689169689Skanstatic void
5690169689Skanprint_operand_reloc (FILE *file, rtx op, const char **relocs)
5691169689Skan{
5692169689Skan  enum mips_symbol_type symbol_type;
5693169689Skan  const char *p;
5694169689Skan  rtx base;
5695169689Skan  HOST_WIDE_INT offset;
5696169689Skan
5697234855Sgonzo  symbol_type = mips_classify_symbolic_expression (op);
5698234855Sgonzo  if (relocs[symbol_type] == 0)
5699169689Skan    fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
5700169689Skan
5701169689Skan  /* If OP uses an UNSPEC address, we want to print the inner symbol.  */
5702169689Skan  mips_split_const (op, &base, &offset);
5703169689Skan  if (UNSPEC_ADDRESS_P (base))
5704169689Skan    op = plus_constant (UNSPEC_ADDRESS (base), offset);
5705169689Skan
5706169689Skan  fputs (relocs[symbol_type], file);
5707169689Skan  output_addr_const (file, op);
5708169689Skan  for (p = relocs[symbol_type]; *p != 0; p++)
5709169689Skan    if (*p == '(')
5710169689Skan      fputc (')', file);
5711169689Skan}
5712169689Skan
5713169689Skan/* Output address operand X to FILE.  */
5714169689Skan
5715169689Skanvoid
5716169689Skanprint_operand_address (FILE *file, rtx x)
5717169689Skan{
5718169689Skan  struct mips_address_info addr;
5719169689Skan
5720169689Skan  if (mips_classify_address (&addr, x, word_mode, true))
5721169689Skan    switch (addr.type)
5722169689Skan      {
5723169689Skan      case ADDRESS_REG:
5724169689Skan	print_operand (file, addr.offset, 0);
5725169689Skan	fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5726169689Skan	return;
5727169689Skan
5728169689Skan      case ADDRESS_LO_SUM:
5729169689Skan	print_operand (file, addr.offset, 'R');
5730169689Skan	fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
5731169689Skan	return;
5732169689Skan
5733169689Skan      case ADDRESS_CONST_INT:
5734169689Skan	output_addr_const (file, x);
5735169689Skan	fprintf (file, "(%s)", reg_names[0]);
5736169689Skan	return;
5737169689Skan
5738169689Skan      case ADDRESS_SYMBOLIC:
5739169689Skan	output_addr_const (file, x);
5740169689Skan	return;
5741169689Skan      }
5742169689Skan  gcc_unreachable ();
5743169689Skan}
5744169689Skan
5745169689Skan/* When using assembler macros, keep track of all of small-data externs
5746169689Skan   so that mips_file_end can emit the appropriate declarations for them.
5747169689Skan
5748169689Skan   In most cases it would be safe (though pointless) to emit .externs
5749169689Skan   for other symbols too.  One exception is when an object is within
5750169689Skan   the -G limit but declared by the user to be in a section other
5751169689Skan   than .sbss or .sdata.  */
5752169689Skan
5753169689Skanint
5754169689Skanmips_output_external (FILE *file ATTRIBUTE_UNUSED, tree decl, const char *name)
5755169689Skan{
5756169689Skan  register struct extern_list *p;
5757169689Skan
5758169689Skan  if (!TARGET_EXPLICIT_RELOCS && mips_in_small_data_p (decl))
5759169689Skan    {
5760169689Skan      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
5761169689Skan      p->next = extern_head;
5762169689Skan      p->name = name;
5763169689Skan      p->size = int_size_in_bytes (TREE_TYPE (decl));
5764169689Skan      extern_head = p;
5765169689Skan    }
5766169689Skan
5767169689Skan  if (TARGET_IRIX && mips_abi == ABI_32 && TREE_CODE (decl) == FUNCTION_DECL)
5768169689Skan    {
5769169689Skan      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
5770169689Skan      p->next = extern_head;
5771169689Skan      p->name = name;
5772169689Skan      p->size = -1;
5773169689Skan      extern_head = p;
5774169689Skan    }
5775169689Skan
5776169689Skan  return 0;
5777169689Skan}
5778169689Skan
5779169689Skan#if TARGET_IRIX
5780169689Skanstatic void
5781169689Skanirix_output_external_libcall (rtx fun)
5782169689Skan{
5783169689Skan  register struct extern_list *p;
5784169689Skan
5785169689Skan  if (mips_abi == ABI_32)
5786169689Skan    {
5787169689Skan      p = (struct extern_list *) ggc_alloc (sizeof (struct extern_list));
5788169689Skan      p->next = extern_head;
5789169689Skan      p->name = XSTR (fun, 0);
5790169689Skan      p->size = -1;
5791169689Skan      extern_head = p;
5792169689Skan    }
5793169689Skan}
5794169689Skan#endif
5795169689Skan
5796169689Skan/* Emit a new filename to a stream.  If we are smuggling stabs, try to
5797169689Skan   put out a MIPS ECOFF file and a stab.  */
5798169689Skan
5799169689Skanvoid
5800169689Skanmips_output_filename (FILE *stream, const char *name)
5801169689Skan{
5802169689Skan
5803169689Skan  /* If we are emitting DWARF-2, let dwarf2out handle the ".file"
5804169689Skan     directives.  */
5805169689Skan  if (write_symbols == DWARF2_DEBUG)
5806169689Skan    return;
5807169689Skan  else if (mips_output_filename_first_time)
5808169689Skan    {
5809169689Skan      mips_output_filename_first_time = 0;
5810169689Skan      num_source_filenames += 1;
5811169689Skan      current_function_file = name;
5812169689Skan      fprintf (stream, "\t.file\t%d ", num_source_filenames);
5813169689Skan      output_quoted_string (stream, name);
5814169689Skan      putc ('\n', stream);
5815169689Skan    }
5816169689Skan
5817169689Skan  /* If we are emitting stabs, let dbxout.c handle this (except for
5818169689Skan     the mips_output_filename_first_time case).  */
5819169689Skan  else if (write_symbols == DBX_DEBUG)
5820169689Skan    return;
5821169689Skan
5822169689Skan  else if (name != current_function_file
5823169689Skan	   && strcmp (name, current_function_file) != 0)
5824169689Skan    {
5825169689Skan      num_source_filenames += 1;
5826169689Skan      current_function_file = name;
5827169689Skan      fprintf (stream, "\t.file\t%d ", num_source_filenames);
5828169689Skan      output_quoted_string (stream, name);
5829169689Skan      putc ('\n', stream);
5830169689Skan    }
5831169689Skan}
5832169689Skan
5833169689Skan/* Output an ASCII string, in a space-saving way.  PREFIX is the string
5834169689Skan   that should be written before the opening quote, such as "\t.ascii\t"
5835169689Skan   for real string data or "\t# " for a comment.  */
5836169689Skan
5837169689Skanvoid
5838169689Skanmips_output_ascii (FILE *stream, const char *string_param, size_t len,
5839169689Skan		   const char *prefix)
5840169689Skan{
5841169689Skan  size_t i;
5842169689Skan  int cur_pos = 17;
5843169689Skan  register const unsigned char *string =
5844169689Skan    (const unsigned char *)string_param;
5845169689Skan
5846169689Skan  fprintf (stream, "%s\"", prefix);
5847169689Skan  for (i = 0; i < len; i++)
5848169689Skan    {
5849169689Skan      register int c = string[i];
5850169689Skan
5851169689Skan      if (ISPRINT (c))
5852169689Skan	{
5853169689Skan	  if (c == '\\' || c == '\"')
5854169689Skan	    {
5855169689Skan	      putc ('\\', stream);
5856169689Skan	      cur_pos++;
5857169689Skan	    }
5858169689Skan	  putc (c, stream);
5859169689Skan	  cur_pos++;
5860169689Skan	}
5861169689Skan      else
5862169689Skan	{
5863169689Skan	  fprintf (stream, "\\%03o", c);
5864169689Skan	  cur_pos += 4;
5865169689Skan	}
5866169689Skan
5867169689Skan      if (cur_pos > 72 && i+1 < len)
5868169689Skan	{
5869169689Skan	  cur_pos = 17;
5870169689Skan	  fprintf (stream, "\"\n%s\"", prefix);
5871169689Skan	}
5872169689Skan    }
5873169689Skan  fprintf (stream, "\"\n");
5874169689Skan}
5875169689Skan
5876169689Skan/* Implement TARGET_ASM_FILE_START.  */
5877169689Skan
5878169689Skanstatic void
5879169689Skanmips_file_start (void)
5880169689Skan{
5881169689Skan  default_file_start ();
5882169689Skan
5883169689Skan  if (!TARGET_IRIX)
5884169689Skan    {
5885169689Skan      /* Generate a special section to describe the ABI switches used to
5886169689Skan	 produce the resultant binary.  This used to be done by the assembler
5887169689Skan	 setting bits in the ELF header's flags field, but we have run out of
5888169689Skan	 bits.  GDB needs this information in order to be able to correctly
5889169689Skan	 debug these binaries.  See the function mips_gdbarch_init() in
5890169689Skan	 gdb/mips-tdep.c.  This is unnecessary for the IRIX 5/6 ABIs and
5891169689Skan	 causes unnecessary IRIX 6 ld warnings.  */
5892169689Skan      const char * abi_string = NULL;
5893169689Skan
5894169689Skan      switch (mips_abi)
5895169689Skan	{
5896169689Skan	case ABI_32:   abi_string = "abi32"; break;
5897169689Skan	case ABI_N32:  abi_string = "abiN32"; break;
5898169689Skan	case ABI_64:   abi_string = "abi64"; break;
5899169689Skan	case ABI_O64:  abi_string = "abiO64"; break;
5900169689Skan	case ABI_EABI: abi_string = TARGET_64BIT ? "eabi64" : "eabi32"; break;
5901169689Skan	default:
5902169689Skan	  gcc_unreachable ();
5903169689Skan	}
5904169689Skan      /* Note - we use fprintf directly rather than calling switch_to_section
5905169689Skan	 because in this way we can avoid creating an allocated section.  We
5906169689Skan	 do not want this section to take up any space in the running
5907169689Skan	 executable.  */
5908169689Skan      fprintf (asm_out_file, "\t.section .mdebug.%s\n", abi_string);
5909169689Skan
5910169689Skan      /* There is no ELF header flag to distinguish long32 forms of the
5911169689Skan	 EABI from long64 forms.  Emit a special section to help tools
5912169689Skan	 such as GDB.  Do the same for o64, which is sometimes used with
5913169689Skan	 -mlong64.  */
5914169689Skan      if (mips_abi == ABI_EABI || mips_abi == ABI_O64)
5915169689Skan	fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n",
5916169689Skan		 TARGET_LONG64 ? 64 : 32);
5917169689Skan
5918169689Skan      /* Restore the default section.  */
5919169689Skan      fprintf (asm_out_file, "\t.previous\n");
5920169689Skan    }
5921169689Skan
5922169689Skan  /* Generate the pseudo ops that System V.4 wants.  */
5923169689Skan  if (TARGET_ABICALLS)
5924169689Skan    fprintf (asm_out_file, "\t.abicalls\n");
5925169689Skan
5926169689Skan  if (TARGET_MIPS16)
5927169689Skan    fprintf (asm_out_file, "\t.set\tmips16\n");
5928169689Skan
5929169689Skan  if (flag_verbose_asm)
5930169689Skan    fprintf (asm_out_file, "\n%s -G value = %d, Arch = %s, ISA = %d\n",
5931169689Skan	     ASM_COMMENT_START,
5932169689Skan	     mips_section_threshold, mips_arch_info->name, mips_isa);
5933169689Skan}
5934169689Skan
5935169689Skan#ifdef BSS_SECTION_ASM_OP
5936169689Skan/* Implement ASM_OUTPUT_ALIGNED_BSS.  This differs from the default only
5937169689Skan   in the use of sbss.  */
5938169689Skan
5939169689Skanvoid
5940169689Skanmips_output_aligned_bss (FILE *stream, tree decl, const char *name,
5941169689Skan			 unsigned HOST_WIDE_INT size, int align)
5942169689Skan{
5943169689Skan  extern tree last_assemble_variable_decl;
5944169689Skan
5945169689Skan  if (mips_in_small_data_p (decl))
5946169689Skan    switch_to_section (get_named_section (NULL, ".sbss", 0));
5947169689Skan  else
5948169689Skan    switch_to_section (bss_section);
5949169689Skan  ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
5950169689Skan  last_assemble_variable_decl = decl;
5951169689Skan  ASM_DECLARE_OBJECT_NAME (stream, name, decl);
5952169689Skan  ASM_OUTPUT_SKIP (stream, size != 0 ? size : 1);
5953169689Skan}
5954169689Skan#endif
5955169689Skan
5956169689Skan/* Implement TARGET_ASM_FILE_END.  When using assembler macros, emit
5957169689Skan   .externs for any small-data variables that turned out to be external.  */
5958169689Skan
5959169689Skanstatic void
5960169689Skanmips_file_end (void)
5961169689Skan{
5962169689Skan  tree name_tree;
5963169689Skan  struct extern_list *p;
5964169689Skan
5965169689Skan  if (extern_head)
5966169689Skan    {
5967169689Skan      fputs ("\n", asm_out_file);
5968169689Skan
5969169689Skan      for (p = extern_head; p != 0; p = p->next)
5970169689Skan	{
5971169689Skan	  name_tree = get_identifier (p->name);
5972169689Skan
5973169689Skan	  /* Positively ensure only one .extern for any given symbol.  */
5974169689Skan	  if (!TREE_ASM_WRITTEN (name_tree)
5975169689Skan	      && TREE_SYMBOL_REFERENCED (name_tree))
5976169689Skan	    {
5977169689Skan	      TREE_ASM_WRITTEN (name_tree) = 1;
5978169689Skan	      /* In IRIX 5 or IRIX 6 for the O32 ABI, we must output a
5979169689Skan		 `.global name .text' directive for every used but
5980169689Skan		 undefined function.  If we don't, the linker may perform
5981169689Skan		 an optimization (skipping over the insns that set $gp)
5982169689Skan		 when it is unsafe.  */
5983169689Skan	      if (TARGET_IRIX && mips_abi == ABI_32 && p->size == -1)
5984169689Skan		{
5985169689Skan		  fputs ("\t.globl ", asm_out_file);
5986169689Skan		  assemble_name (asm_out_file, p->name);
5987169689Skan		  fputs (" .text\n", asm_out_file);
5988169689Skan		}
5989169689Skan	      else
5990169689Skan		{
5991169689Skan		  fputs ("\t.extern\t", asm_out_file);
5992169689Skan		  assemble_name (asm_out_file, p->name);
5993169689Skan		  fprintf (asm_out_file, ", %d\n", p->size);
5994169689Skan		}
5995169689Skan	    }
5996169689Skan	}
5997169689Skan    }
5998169689Skan}
5999169689Skan
6000169689Skan/* Implement ASM_OUTPUT_ALIGNED_DECL_COMMON.  This is usually the same as the
6001169689Skan   elfos.h version, but we also need to handle -muninit-const-in-rodata.  */
6002169689Skan
6003169689Skanvoid
6004169689Skanmips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
6005169689Skan				 unsigned HOST_WIDE_INT size,
6006169689Skan				 unsigned int align)
6007169689Skan{
6008169689Skan  /* If the target wants uninitialized const declarations in
6009169689Skan     .rdata then don't put them in .comm.  */
6010169689Skan  if (TARGET_EMBEDDED_DATA && TARGET_UNINIT_CONST_IN_RODATA
6011169689Skan      && TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl)
6012169689Skan      && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
6013169689Skan    {
6014169689Skan      if (TREE_PUBLIC (decl) && DECL_NAME (decl))
6015169689Skan	targetm.asm_out.globalize_label (stream, name);
6016169689Skan
6017169689Skan      switch_to_section (readonly_data_section);
6018169689Skan      ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
6019169689Skan      mips_declare_object (stream, name, "",
6020169689Skan			   ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
6021169689Skan			   size);
6022169689Skan    }
6023169689Skan  else
6024169689Skan    mips_declare_common_object (stream, name, "\n\t.comm\t",
6025169689Skan				size, align, true);
6026169689Skan}
6027169689Skan
6028169689Skan/* Declare a common object of SIZE bytes using asm directive INIT_STRING.
6029169689Skan   NAME is the name of the object and ALIGN is the required alignment
6030169689Skan   in bytes.  TAKES_ALIGNMENT_P is true if the directive takes a third
6031169689Skan   alignment argument.  */
6032169689Skan
6033169689Skanvoid
6034169689Skanmips_declare_common_object (FILE *stream, const char *name,
6035169689Skan			    const char *init_string,
6036169689Skan			    unsigned HOST_WIDE_INT size,
6037169689Skan			    unsigned int align, bool takes_alignment_p)
6038169689Skan{
6039169689Skan  if (!takes_alignment_p)
6040169689Skan    {
6041169689Skan      size += (align / BITS_PER_UNIT) - 1;
6042169689Skan      size -= size % (align / BITS_PER_UNIT);
6043169689Skan      mips_declare_object (stream, name, init_string,
6044169689Skan			   "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size);
6045169689Skan    }
6046169689Skan  else
6047169689Skan    mips_declare_object (stream, name, init_string,
6048169689Skan			 "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
6049169689Skan			 size, align / BITS_PER_UNIT);
6050169689Skan}
6051169689Skan
6052169689Skan/* Emit either a label, .comm, or .lcomm directive.  When using assembler
6053169689Skan   macros, mark the symbol as written so that mips_file_end won't emit an
6054169689Skan   .extern for it.  STREAM is the output file, NAME is the name of the
6055169689Skan   symbol, INIT_STRING is the string that should be written before the
6056169689Skan   symbol and FINAL_STRING is the string that should be written after it.
6057169689Skan   FINAL_STRING is a printf() format that consumes the remaining arguments.  */
6058169689Skan
6059169689Skanvoid
6060169689Skanmips_declare_object (FILE *stream, const char *name, const char *init_string,
6061169689Skan		     const char *final_string, ...)
6062169689Skan{
6063169689Skan  va_list ap;
6064169689Skan
6065169689Skan  fputs (init_string, stream);
6066169689Skan  assemble_name (stream, name);
6067169689Skan  va_start (ap, final_string);
6068169689Skan  vfprintf (stream, final_string, ap);
6069169689Skan  va_end (ap);
6070169689Skan
6071169689Skan  if (!TARGET_EXPLICIT_RELOCS)
6072169689Skan    {
6073169689Skan      tree name_tree = get_identifier (name);
6074169689Skan      TREE_ASM_WRITTEN (name_tree) = 1;
6075169689Skan    }
6076169689Skan}
6077169689Skan
6078169689Skan#ifdef ASM_OUTPUT_SIZE_DIRECTIVE
6079169689Skanextern int size_directive_output;
6080169689Skan
6081169689Skan/* Implement ASM_DECLARE_OBJECT_NAME.  This is like most of the standard ELF
6082169689Skan   definitions except that it uses mips_declare_object() to emit the label.  */
6083169689Skan
6084169689Skanvoid
6085169689Skanmips_declare_object_name (FILE *stream, const char *name,
6086169689Skan			  tree decl ATTRIBUTE_UNUSED)
6087169689Skan{
6088169689Skan#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
6089169689Skan  ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
6090169689Skan#endif
6091169689Skan
6092169689Skan  size_directive_output = 0;
6093169689Skan  if (!flag_inhibit_size_directive && DECL_SIZE (decl))
6094169689Skan    {
6095169689Skan      HOST_WIDE_INT size;
6096169689Skan
6097169689Skan      size_directive_output = 1;
6098169689Skan      size = int_size_in_bytes (TREE_TYPE (decl));
6099169689Skan      ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
6100169689Skan    }
6101169689Skan
6102169689Skan  mips_declare_object (stream, name, "", ":\n");
6103169689Skan}
6104169689Skan
6105169689Skan/* Implement ASM_FINISH_DECLARE_OBJECT.  This is generic ELF stuff.  */
6106169689Skan
6107169689Skanvoid
6108169689Skanmips_finish_declare_object (FILE *stream, tree decl, int top_level, int at_end)
6109169689Skan{
6110169689Skan  const char *name;
6111169689Skan
6112169689Skan  name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
6113169689Skan  if (!flag_inhibit_size_directive
6114169689Skan      && DECL_SIZE (decl) != 0
6115169689Skan      && !at_end && top_level
6116169689Skan      && DECL_INITIAL (decl) == error_mark_node
6117169689Skan      && !size_directive_output)
6118169689Skan    {
6119169689Skan      HOST_WIDE_INT size;
6120169689Skan
6121169689Skan      size_directive_output = 1;
6122169689Skan      size = int_size_in_bytes (TREE_TYPE (decl));
6123169689Skan      ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
6124169689Skan    }
6125169689Skan}
6126169689Skan#endif
6127169689Skan
6128169689Skan/* Return true if X is a small data address that can be rewritten
6129169689Skan   as a LO_SUM.  */
6130169689Skan
6131169689Skanstatic bool
6132169689Skanmips_rewrite_small_data_p (rtx x)
6133169689Skan{
6134169689Skan  enum mips_symbol_type symbol_type;
6135169689Skan
6136169689Skan  return (TARGET_EXPLICIT_RELOCS
6137169689Skan	  && mips_symbolic_constant_p (x, &symbol_type)
6138169689Skan	  && symbol_type == SYMBOL_SMALL_DATA);
6139169689Skan}
6140169689Skan
6141169689Skan
6142169689Skan/* A for_each_rtx callback for mips_small_data_pattern_p.  */
6143169689Skan
6144169689Skanstatic int
6145169689Skanmips_small_data_pattern_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
6146169689Skan{
6147169689Skan  if (GET_CODE (*loc) == LO_SUM)
6148169689Skan    return -1;
6149169689Skan
6150169689Skan  return mips_rewrite_small_data_p (*loc);
6151169689Skan}
6152169689Skan
6153169689Skan/* Return true if OP refers to small data symbols directly, not through
6154169689Skan   a LO_SUM.  */
6155169689Skan
6156169689Skanbool
6157169689Skanmips_small_data_pattern_p (rtx op)
6158169689Skan{
6159169689Skan  return for_each_rtx (&op, mips_small_data_pattern_1, 0);
6160169689Skan}
6161169689Skan
6162169689Skan/* A for_each_rtx callback, used by mips_rewrite_small_data.  */
6163169689Skan
6164169689Skanstatic int
6165169689Skanmips_rewrite_small_data_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
6166169689Skan{
6167169689Skan  if (mips_rewrite_small_data_p (*loc))
6168169689Skan    *loc = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, *loc);
6169169689Skan
6170169689Skan  if (GET_CODE (*loc) == LO_SUM)
6171169689Skan    return -1;
6172169689Skan
6173169689Skan  return 0;
6174169689Skan}
6175169689Skan
6176169689Skan/* If possible, rewrite OP so that it refers to small data using
6177169689Skan   explicit relocations.  */
6178169689Skan
6179169689Skanrtx
6180169689Skanmips_rewrite_small_data (rtx op)
6181169689Skan{
6182169689Skan  op = copy_insn (op);
6183169689Skan  for_each_rtx (&op, mips_rewrite_small_data_1, 0);
6184169689Skan  return op;
6185169689Skan}
6186169689Skan
6187169689Skan/* Return true if the current function has an insn that implicitly
6188169689Skan   refers to $gp.  */
6189169689Skan
6190169689Skanstatic bool
6191169689Skanmips_function_has_gp_insn (void)
6192169689Skan{
6193169689Skan  /* Don't bother rechecking if we found one last time.  */
6194169689Skan  if (!cfun->machine->has_gp_insn_p)
6195169689Skan    {
6196169689Skan      rtx insn;
6197169689Skan
6198169689Skan      push_topmost_sequence ();
6199169689Skan      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6200169689Skan	if (INSN_P (insn)
6201169689Skan	    && GET_CODE (PATTERN (insn)) != USE
6202169689Skan	    && GET_CODE (PATTERN (insn)) != CLOBBER
6203169689Skan	    && (get_attr_got (insn) != GOT_UNSET
6204169689Skan		|| small_data_pattern (PATTERN (insn), VOIDmode)))
6205169689Skan	  break;
6206169689Skan      pop_topmost_sequence ();
6207169689Skan
6208169689Skan      cfun->machine->has_gp_insn_p = (insn != 0);
6209169689Skan    }
6210169689Skan  return cfun->machine->has_gp_insn_p;
6211169689Skan}
6212169689Skan
6213169689Skan
6214169689Skan/* Return the register that should be used as the global pointer
6215169689Skan   within this function.  Return 0 if the function doesn't need
6216169689Skan   a global pointer.  */
6217169689Skan
6218169689Skanstatic unsigned int
6219169689Skanmips_global_pointer (void)
6220169689Skan{
6221169689Skan  unsigned int regno;
6222169689Skan
6223169689Skan  /* $gp is always available in non-abicalls code.  */
6224169689Skan  if (!TARGET_ABICALLS)
6225169689Skan    return GLOBAL_POINTER_REGNUM;
6226169689Skan
6227169689Skan  /* We must always provide $gp when it is used implicitly.  */
6228169689Skan  if (!TARGET_EXPLICIT_RELOCS)
6229169689Skan    return GLOBAL_POINTER_REGNUM;
6230169689Skan
6231169689Skan  /* FUNCTION_PROFILER includes a jal macro, so we need to give it
6232169689Skan     a valid gp.  */
6233169689Skan  if (current_function_profile)
6234169689Skan    return GLOBAL_POINTER_REGNUM;
6235169689Skan
6236169689Skan  /* If the function has a nonlocal goto, $gp must hold the correct
6237169689Skan     global pointer for the target function.  */
6238169689Skan  if (current_function_has_nonlocal_goto)
6239169689Skan    return GLOBAL_POINTER_REGNUM;
6240169689Skan
6241169689Skan  /* If the gp is never referenced, there's no need to initialize it.
6242169689Skan     Note that reload can sometimes introduce constant pool references
6243169689Skan     into a function that otherwise didn't need them.  For example,
6244169689Skan     suppose we have an instruction like:
6245169689Skan
6246169689Skan	  (set (reg:DF R1) (float:DF (reg:SI R2)))
6247169689Skan
6248169689Skan     If R2 turns out to be constant such as 1, the instruction may have a
6249169689Skan     REG_EQUAL note saying that R1 == 1.0.  Reload then has the option of
6250169689Skan     using this constant if R2 doesn't get allocated to a register.
6251169689Skan
6252169689Skan     In cases like these, reload will have added the constant to the pool
6253169689Skan     but no instruction will yet refer to it.  */
6254169689Skan  if (!regs_ever_live[GLOBAL_POINTER_REGNUM]
6255169689Skan      && !current_function_uses_const_pool
6256169689Skan      && !mips_function_has_gp_insn ())
6257169689Skan    return 0;
6258169689Skan
6259169689Skan  /* We need a global pointer, but perhaps we can use a call-clobbered
6260169689Skan     register instead of $gp.  */
6261169689Skan  if (TARGET_NEWABI && current_function_is_leaf)
6262169689Skan    for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
6263169689Skan      if (!regs_ever_live[regno]
6264169689Skan	  && call_used_regs[regno]
6265169689Skan	  && !fixed_regs[regno]
6266169689Skan	  && regno != PIC_FUNCTION_ADDR_REGNUM)
6267169689Skan	return regno;
6268169689Skan
6269169689Skan  return GLOBAL_POINTER_REGNUM;
6270169689Skan}
6271169689Skan
6272169689Skan
6273169689Skan/* Return true if the current function must save REGNO.  */
6274169689Skan
6275169689Skanstatic bool
6276169689Skanmips_save_reg_p (unsigned int regno)
6277169689Skan{
6278169689Skan  /* We only need to save $gp for NewABI PIC.  */
6279169689Skan  if (regno == GLOBAL_POINTER_REGNUM)
6280169689Skan    return (TARGET_ABICALLS && TARGET_NEWABI
6281169689Skan	    && cfun->machine->global_pointer == regno);
6282169689Skan
6283169689Skan  /* Check call-saved registers.  */
6284169689Skan  if (regs_ever_live[regno] && !call_used_regs[regno])
6285169689Skan    return true;
6286169689Skan
6287169689Skan  /* We need to save the old frame pointer before setting up a new one.  */
6288169689Skan  if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
6289169689Skan    return true;
6290169689Skan
6291169689Skan  /* We need to save the incoming return address if it is ever clobbered
6292169689Skan     within the function.  */
6293169689Skan  if (regno == GP_REG_FIRST + 31 && regs_ever_live[regno])
6294169689Skan    return true;
6295169689Skan
6296169689Skan  if (TARGET_MIPS16)
6297169689Skan    {
6298169689Skan      tree return_type;
6299169689Skan
6300169689Skan      return_type = DECL_RESULT (current_function_decl);
6301169689Skan
6302169689Skan      /* $18 is a special case in mips16 code.  It may be used to call
6303169689Skan	 a function which returns a floating point value, but it is
6304169689Skan	 marked in call_used_regs.  */
6305169689Skan      if (regno == GP_REG_FIRST + 18 && regs_ever_live[regno])
6306169689Skan	return true;
6307169689Skan
6308169689Skan      /* $31 is also a special case.  It will be used to copy a return
6309169689Skan	 value into the floating point registers if the return value is
6310169689Skan	 floating point.  */
6311169689Skan      if (regno == GP_REG_FIRST + 31
6312169689Skan	  && mips16_hard_float
6313169689Skan	  && !aggregate_value_p (return_type, current_function_decl)
6314169689Skan	  && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
6315169689Skan	  && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE)
6316169689Skan	return true;
6317169689Skan    }
6318169689Skan
6319169689Skan  return false;
6320169689Skan}
6321169689Skan
6322169689Skan
6323169689Skan/* Return the bytes needed to compute the frame pointer from the current
6324169689Skan   stack pointer.  SIZE is the size (in bytes) of the local variables.
6325169689Skan
6326169689Skan   MIPS stack frames look like:
6327169689Skan
6328169689Skan             Before call		        After call
6329169689Skan        +-----------------------+	+-----------------------+
6330169689Skan   high |			|       |      			|
6331169689Skan   mem. |		        |	|			|
6332169689Skan        |  caller's temps.    	|       |  caller's temps.    	|
6333169689Skan	|       		|       |       	        |
6334169689Skan        +-----------------------+	+-----------------------+
6335169689Skan 	|       		|	|		        |
6336169689Skan        |  arguments on stack.  |	|  arguments on stack.  |
6337169689Skan	|       		|	|			|
6338169689Skan        +-----------------------+	+-----------------------+
6339169689Skan 	|  4 words to save     	|	|  4 words to save	|
6340169689Skan	|  arguments passed	|	|  arguments passed	|
6341169689Skan	|  in registers, even	|	|  in registers, even	|
6342169689Skan    SP->|  if not passed.       |  VFP->|  if not passed.	|
6343169689Skan	+-----------------------+       +-----------------------+
6344169689Skan					|		        |
6345169689Skan                                        |  fp register save     |
6346169689Skan					|			|
6347169689Skan					+-----------------------+
6348169689Skan					|		        |
6349169689Skan                                        |  gp register save     |
6350169689Skan                                        |       		|
6351169689Skan					+-----------------------+
6352169689Skan					|			|
6353169689Skan					|  local variables	|
6354169689Skan					|			|
6355169689Skan					+-----------------------+
6356169689Skan					|			|
6357169689Skan                                        |  alloca allocations   |
6358169689Skan        				|			|
6359169689Skan					+-----------------------+
6360169689Skan					|			|
6361169689Skan					|  GP save for V.4 abi	|
6362169689Skan					|			|
6363169689Skan					+-----------------------+
6364169689Skan					|			|
6365169689Skan                                        |  arguments on stack   |
6366169689Skan        				|		        |
6367169689Skan					+-----------------------+
6368169689Skan                                        |  4 words to save      |
6369169689Skan					|  arguments passed     |
6370169689Skan                                        |  in registers, even   |
6371169689Skan   low                              SP->|  if not passed.       |
6372169689Skan   memory        			+-----------------------+
6373169689Skan
6374169689Skan*/
6375169689Skan
6376169689SkanHOST_WIDE_INT
6377169689Skancompute_frame_size (HOST_WIDE_INT size)
6378169689Skan{
6379169689Skan  unsigned int regno;
6380169689Skan  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
6381169689Skan  HOST_WIDE_INT var_size;	/* # bytes that variables take up */
6382169689Skan  HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */
6383169689Skan  HOST_WIDE_INT cprestore_size; /* # bytes that the cprestore slot takes up */
6384169689Skan  HOST_WIDE_INT gp_reg_rounded;	/* # bytes needed to store gp after rounding */
6385169689Skan  HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */
6386169689Skan  HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */
6387169689Skan  unsigned int mask;		/* mask of saved gp registers */
6388169689Skan  unsigned int fmask;		/* mask of saved fp registers */
6389169689Skan
6390169689Skan  cfun->machine->global_pointer = mips_global_pointer ();
6391169689Skan
6392169689Skan  gp_reg_size = 0;
6393169689Skan  fp_reg_size = 0;
6394169689Skan  mask = 0;
6395169689Skan  fmask	= 0;
6396169689Skan  var_size = MIPS_STACK_ALIGN (size);
6397169689Skan  args_size = current_function_outgoing_args_size;
6398169689Skan  cprestore_size = MIPS_STACK_ALIGN (STARTING_FRAME_OFFSET) - args_size;
6399169689Skan
6400169689Skan  /* The space set aside by STARTING_FRAME_OFFSET isn't needed in leaf
6401169689Skan     functions.  If the function has local variables, we're committed
6402169689Skan     to allocating it anyway.  Otherwise reclaim it here.  */
6403169689Skan  if (var_size == 0 && current_function_is_leaf)
6404169689Skan    cprestore_size = args_size = 0;
6405169689Skan
6406169689Skan  /* The MIPS 3.0 linker does not like functions that dynamically
6407169689Skan     allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
6408169689Skan     looks like we are trying to create a second frame pointer to the
6409169689Skan     function, so allocate some stack space to make it happy.  */
6410169689Skan
6411169689Skan  if (args_size == 0 && current_function_calls_alloca)
6412169689Skan    args_size = 4 * UNITS_PER_WORD;
6413169689Skan
6414169689Skan  total_size = var_size + args_size + cprestore_size;
6415169689Skan
6416169689Skan  /* Calculate space needed for gp registers.  */
6417169689Skan  for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
6418169689Skan    if (mips_save_reg_p (regno))
6419169689Skan      {
6420169689Skan	gp_reg_size += GET_MODE_SIZE (gpr_mode);
6421169689Skan	mask |= 1 << (regno - GP_REG_FIRST);
6422169689Skan      }
6423169689Skan
6424169689Skan  /* We need to restore these for the handler.  */
6425169689Skan  if (current_function_calls_eh_return)
6426169689Skan    {
6427169689Skan      unsigned int i;
6428169689Skan      for (i = 0; ; ++i)
6429169689Skan	{
6430169689Skan	  regno = EH_RETURN_DATA_REGNO (i);
6431169689Skan	  if (regno == INVALID_REGNUM)
6432169689Skan	    break;
6433169689Skan	  gp_reg_size += GET_MODE_SIZE (gpr_mode);
6434169689Skan	  mask |= 1 << (regno - GP_REG_FIRST);
6435169689Skan	}
6436169689Skan    }
6437169689Skan
6438169689Skan  /* This loop must iterate over the same space as its companion in
6439169689Skan     save_restore_insns.  */
6440169689Skan  for (regno = (FP_REG_LAST - FP_INC + 1);
6441169689Skan       regno >= FP_REG_FIRST;
6442169689Skan       regno -= FP_INC)
6443169689Skan    {
6444169689Skan      if (mips_save_reg_p (regno))
6445169689Skan	{
6446169689Skan	  fp_reg_size += FP_INC * UNITS_PER_FPREG;
6447169689Skan	  fmask |= ((1 << FP_INC) - 1) << (regno - FP_REG_FIRST);
6448169689Skan	}
6449169689Skan    }
6450169689Skan
6451169689Skan  gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
6452169689Skan  total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
6453169689Skan
6454169689Skan  /* Add in the space required for saving incoming register arguments.  */
6455169689Skan  total_size += current_function_pretend_args_size;
6456169689Skan  total_size += MIPS_STACK_ALIGN (cfun->machine->varargs_size);
6457169689Skan
6458169689Skan  /* Save other computed information.  */
6459169689Skan  cfun->machine->frame.total_size = total_size;
6460169689Skan  cfun->machine->frame.var_size = var_size;
6461169689Skan  cfun->machine->frame.args_size = args_size;
6462169689Skan  cfun->machine->frame.cprestore_size = cprestore_size;
6463169689Skan  cfun->machine->frame.gp_reg_size = gp_reg_size;
6464169689Skan  cfun->machine->frame.fp_reg_size = fp_reg_size;
6465169689Skan  cfun->machine->frame.mask = mask;
6466169689Skan  cfun->machine->frame.fmask = fmask;
6467169689Skan  cfun->machine->frame.initialized = reload_completed;
6468169689Skan  cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD;
6469169689Skan  cfun->machine->frame.num_fp = fp_reg_size / (FP_INC * UNITS_PER_FPREG);
6470169689Skan
6471169689Skan  if (mask)
6472169689Skan    {
6473169689Skan      HOST_WIDE_INT offset;
6474169689Skan
6475169689Skan      offset = (args_size + cprestore_size + var_size
6476169689Skan		+ gp_reg_size - GET_MODE_SIZE (gpr_mode));
6477169689Skan      cfun->machine->frame.gp_sp_offset = offset;
6478169689Skan      cfun->machine->frame.gp_save_offset = offset - total_size;
6479169689Skan    }
6480169689Skan  else
6481169689Skan    {
6482169689Skan      cfun->machine->frame.gp_sp_offset = 0;
6483169689Skan      cfun->machine->frame.gp_save_offset = 0;
6484169689Skan    }
6485169689Skan
6486169689Skan  if (fmask)
6487169689Skan    {
6488169689Skan      HOST_WIDE_INT offset;
6489169689Skan
6490169689Skan      offset = (args_size + cprestore_size + var_size
6491169689Skan		+ gp_reg_rounded + fp_reg_size
6492169689Skan		- FP_INC * UNITS_PER_FPREG);
6493169689Skan      cfun->machine->frame.fp_sp_offset = offset;
6494169689Skan      cfun->machine->frame.fp_save_offset = offset - total_size;
6495169689Skan    }
6496169689Skan  else
6497169689Skan    {
6498169689Skan      cfun->machine->frame.fp_sp_offset = 0;
6499169689Skan      cfun->machine->frame.fp_save_offset = 0;
6500169689Skan    }
6501169689Skan
6502169689Skan  /* Ok, we're done.  */
6503169689Skan  return total_size;
6504169689Skan}
6505169689Skan
6506169689Skan/* Implement INITIAL_ELIMINATION_OFFSET.  FROM is either the frame
6507169689Skan   pointer or argument pointer.  TO is either the stack pointer or
6508169689Skan   hard frame pointer.  */
6509169689Skan
6510169689SkanHOST_WIDE_INT
6511169689Skanmips_initial_elimination_offset (int from, int to)
6512169689Skan{
6513169689Skan  HOST_WIDE_INT offset;
6514169689Skan
6515169689Skan  compute_frame_size (get_frame_size ());
6516169689Skan
6517169689Skan  /* Set OFFSET to the offset from the stack pointer.  */
6518169689Skan  switch (from)
6519169689Skan    {
6520169689Skan    case FRAME_POINTER_REGNUM:
6521169689Skan      offset = 0;
6522169689Skan      break;
6523169689Skan
6524169689Skan    case ARG_POINTER_REGNUM:
6525169689Skan      offset = (cfun->machine->frame.total_size
6526169689Skan		- current_function_pretend_args_size);
6527169689Skan      break;
6528169689Skan
6529169689Skan    default:
6530169689Skan      gcc_unreachable ();
6531169689Skan    }
6532169689Skan
6533169689Skan  if (TARGET_MIPS16 && to == HARD_FRAME_POINTER_REGNUM)
6534169689Skan    offset -= cfun->machine->frame.args_size;
6535169689Skan
6536169689Skan  return offset;
6537169689Skan}
6538169689Skan
6539169689Skan/* Implement RETURN_ADDR_RTX.  Note, we do not support moving
6540169689Skan   back to a previous frame.  */
6541169689Skanrtx
6542169689Skanmips_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
6543169689Skan{
6544169689Skan  if (count != 0)
6545169689Skan    return const0_rtx;
6546169689Skan
6547169689Skan  return get_hard_reg_initial_val (Pmode, GP_REG_FIRST + 31);
6548169689Skan}
6549169689Skan
6550169689Skan/* Use FN to save or restore register REGNO.  MODE is the register's
6551169689Skan   mode and OFFSET is the offset of its save slot from the current
6552169689Skan   stack pointer.  */
6553169689Skan
6554169689Skanstatic void
6555169689Skanmips_save_restore_reg (enum machine_mode mode, int regno,
6556169689Skan		       HOST_WIDE_INT offset, mips_save_restore_fn fn)
6557169689Skan{
6558169689Skan  rtx mem;
6559169689Skan
6560169689Skan  mem = gen_frame_mem (mode, plus_constant (stack_pointer_rtx, offset));
6561169689Skan
6562169689Skan  fn (gen_rtx_REG (mode, regno), mem);
6563169689Skan}
6564169689Skan
6565169689Skan
6566169689Skan/* Call FN for each register that is saved by the current function.
6567169689Skan   SP_OFFSET is the offset of the current stack pointer from the start
6568169689Skan   of the frame.  */
6569169689Skan
6570169689Skanstatic void
6571169689Skanmips_for_each_saved_reg (HOST_WIDE_INT sp_offset, mips_save_restore_fn fn)
6572169689Skan{
6573169689Skan#define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
6574169689Skan
6575169689Skan  enum machine_mode fpr_mode;
6576169689Skan  HOST_WIDE_INT offset;
6577169689Skan  int regno;
6578169689Skan
6579169689Skan  /* Save registers starting from high to low.  The debuggers prefer at least
6580169689Skan     the return register be stored at func+4, and also it allows us not to
6581169689Skan     need a nop in the epilog if at least one register is reloaded in
6582169689Skan     addition to return address.  */
6583169689Skan  offset = cfun->machine->frame.gp_sp_offset - sp_offset;
6584169689Skan  for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
6585169689Skan    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
6586169689Skan      {
6587169689Skan	mips_save_restore_reg (gpr_mode, regno, offset, fn);
6588169689Skan	offset -= GET_MODE_SIZE (gpr_mode);
6589169689Skan      }
6590169689Skan
6591169689Skan  /* This loop must iterate over the same space as its companion in
6592169689Skan     compute_frame_size.  */
6593169689Skan  offset = cfun->machine->frame.fp_sp_offset - sp_offset;
6594169689Skan  fpr_mode = (TARGET_SINGLE_FLOAT ? SFmode : DFmode);
6595169689Skan  for (regno = (FP_REG_LAST - FP_INC + 1);
6596169689Skan       regno >= FP_REG_FIRST;
6597169689Skan       regno -= FP_INC)
6598169689Skan    if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
6599169689Skan      {
6600169689Skan	mips_save_restore_reg (fpr_mode, regno, offset, fn);
6601169689Skan	offset -= GET_MODE_SIZE (fpr_mode);
6602169689Skan      }
6603169689Skan#undef BITSET_P
6604169689Skan}
6605169689Skan
6606169689Skan/* If we're generating n32 or n64 abicalls, and the current function
6607169689Skan   does not use $28 as its global pointer, emit a cplocal directive.
6608169689Skan   Use pic_offset_table_rtx as the argument to the directive.  */
6609169689Skan
6610169689Skanstatic void
6611169689Skanmips_output_cplocal (void)
6612169689Skan{
6613169689Skan  if (!TARGET_EXPLICIT_RELOCS
6614169689Skan      && cfun->machine->global_pointer > 0
6615169689Skan      && cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
6616169689Skan    output_asm_insn (".cplocal %+", 0);
6617169689Skan}
6618169689Skan
6619169689Skan/* Return the style of GP load sequence that is being used for the
6620169689Skan   current function.  */
6621169689Skan
6622169689Skanenum mips_loadgp_style
6623169689Skanmips_current_loadgp_style (void)
6624169689Skan{
6625169689Skan  if (!TARGET_ABICALLS || cfun->machine->global_pointer == 0)
6626169689Skan    return LOADGP_NONE;
6627169689Skan
6628169689Skan  if (TARGET_ABSOLUTE_ABICALLS)
6629169689Skan    return LOADGP_ABSOLUTE;
6630169689Skan
6631169689Skan  return TARGET_NEWABI ? LOADGP_NEWABI : LOADGP_OLDABI;
6632169689Skan}
6633169689Skan
6634169689Skan/* The __gnu_local_gp symbol.  */
6635169689Skan
6636169689Skanstatic GTY(()) rtx mips_gnu_local_gp;
6637169689Skan
6638169689Skan/* If we're generating n32 or n64 abicalls, emit instructions
6639169689Skan   to set up the global pointer.  */
6640169689Skan
6641169689Skanstatic void
6642169689Skanmips_emit_loadgp (void)
6643169689Skan{
6644169689Skan  rtx addr, offset, incoming_address;
6645169689Skan
6646169689Skan  switch (mips_current_loadgp_style ())
6647169689Skan    {
6648169689Skan    case LOADGP_ABSOLUTE:
6649169689Skan      if (mips_gnu_local_gp == NULL)
6650169689Skan	{
6651169689Skan	  mips_gnu_local_gp = gen_rtx_SYMBOL_REF (Pmode, "__gnu_local_gp");
6652169689Skan	  SYMBOL_REF_FLAGS (mips_gnu_local_gp) |= SYMBOL_FLAG_LOCAL;
6653169689Skan	}
6654169689Skan      emit_insn (gen_loadgp_noshared (mips_gnu_local_gp));
6655169689Skan      break;
6656169689Skan
6657169689Skan    case LOADGP_NEWABI:
6658169689Skan      addr = XEXP (DECL_RTL (current_function_decl), 0);
6659169689Skan      offset = mips_unspec_address (addr, SYMBOL_GOTOFF_LOADGP);
6660169689Skan      incoming_address = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
6661169689Skan      emit_insn (gen_loadgp (offset, incoming_address));
6662169689Skan      if (!TARGET_EXPLICIT_RELOCS)
6663169689Skan	emit_insn (gen_loadgp_blockage ());
6664169689Skan      break;
6665169689Skan
6666169689Skan    default:
6667169689Skan      break;
6668169689Skan    }
6669169689Skan}
6670169689Skan
6671169689Skan/* Set up the stack and frame (if desired) for the function.  */
6672169689Skan
6673169689Skanstatic void
6674169689Skanmips_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
6675169689Skan{
6676169689Skan  const char *fnname;
6677169689Skan  HOST_WIDE_INT tsize = cfun->machine->frame.total_size;
6678169689Skan
6679169689Skan#ifdef SDB_DEBUGGING_INFO
6680169689Skan  if (debug_info_level != DINFO_LEVEL_TERSE && write_symbols == SDB_DEBUG)
6681169689Skan    SDB_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
6682169689Skan#endif
6683169689Skan
6684169689Skan  /* In mips16 mode, we may need to generate a 32 bit to handle
6685169689Skan     floating point arguments.  The linker will arrange for any 32 bit
6686169689Skan     functions to call this stub, which will then jump to the 16 bit
6687169689Skan     function proper.  */
6688169689Skan  if (TARGET_MIPS16 && !TARGET_SOFT_FLOAT
6689169689Skan      && current_function_args_info.fp_code != 0)
6690169689Skan    build_mips16_function_stub (file);
6691169689Skan
6692169689Skan  if (!FUNCTION_NAME_ALREADY_DECLARED)
6693169689Skan    {
6694169689Skan      /* Get the function name the same way that toplev.c does before calling
6695169689Skan	 assemble_start_function.  This is needed so that the name used here
6696169689Skan	 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME.  */
6697169689Skan      fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
6698169689Skan
6699169689Skan      if (!flag_inhibit_size_directive)
6700169689Skan	{
6701169689Skan	  fputs ("\t.ent\t", file);
6702169689Skan	  assemble_name (file, fnname);
6703169689Skan	  fputs ("\n", file);
6704169689Skan	}
6705169689Skan
6706169689Skan      assemble_name (file, fnname);
6707169689Skan      fputs (":\n", file);
6708169689Skan    }
6709169689Skan
6710169689Skan  /* Stop mips_file_end from treating this function as external.  */
6711169689Skan  if (TARGET_IRIX && mips_abi == ABI_32)
6712169689Skan    TREE_ASM_WRITTEN (DECL_NAME (cfun->decl)) = 1;
6713169689Skan
6714169689Skan  if (!flag_inhibit_size_directive)
6715169689Skan    {
6716169689Skan      /* .frame FRAMEREG, FRAMESIZE, RETREG */
6717169689Skan      fprintf (file,
6718169689Skan	       "\t.frame\t%s," HOST_WIDE_INT_PRINT_DEC ",%s\t\t"
6719169689Skan	       "# vars= " HOST_WIDE_INT_PRINT_DEC ", regs= %d/%d"
6720169689Skan	       ", args= " HOST_WIDE_INT_PRINT_DEC
6721169689Skan	       ", gp= " HOST_WIDE_INT_PRINT_DEC "\n",
6722169689Skan	       (reg_names[(frame_pointer_needed)
6723169689Skan			  ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
6724169689Skan	       ((frame_pointer_needed && TARGET_MIPS16)
6725169689Skan		? tsize - cfun->machine->frame.args_size
6726169689Skan		: tsize),
6727169689Skan	       reg_names[GP_REG_FIRST + 31],
6728169689Skan	       cfun->machine->frame.var_size,
6729169689Skan	       cfun->machine->frame.num_gp,
6730169689Skan	       cfun->machine->frame.num_fp,
6731169689Skan	       cfun->machine->frame.args_size,
6732169689Skan	       cfun->machine->frame.cprestore_size);
6733169689Skan
6734169689Skan      /* .mask MASK, GPOFFSET; .fmask FPOFFSET */
6735169689Skan      fprintf (file, "\t.mask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
6736169689Skan	       cfun->machine->frame.mask,
6737169689Skan	       cfun->machine->frame.gp_save_offset);
6738169689Skan      fprintf (file, "\t.fmask\t0x%08x," HOST_WIDE_INT_PRINT_DEC "\n",
6739169689Skan	       cfun->machine->frame.fmask,
6740169689Skan	       cfun->machine->frame.fp_save_offset);
6741169689Skan
6742169689Skan      /* Require:
6743169689Skan	 OLD_SP == *FRAMEREG + FRAMESIZE => can find old_sp from nominated FP reg.
6744169689Skan	 HIGHEST_GP_SAVED == *FRAMEREG + FRAMESIZE + GPOFFSET => can find saved regs.  */
6745169689Skan    }
6746169689Skan
6747169689Skan  if (mips_current_loadgp_style () == LOADGP_OLDABI)
6748169689Skan    {
6749169689Skan      /* Handle the initialization of $gp for SVR4 PIC.  */
6750169689Skan      if (!cfun->machine->all_noreorder_p)
6751169689Skan	output_asm_insn ("%(.cpload\t%^%)", 0);
6752169689Skan      else
6753169689Skan	output_asm_insn ("%(.cpload\t%^\n\t%<", 0);
6754169689Skan    }
6755169689Skan  else if (cfun->machine->all_noreorder_p)
6756169689Skan    output_asm_insn ("%(%<", 0);
6757169689Skan
6758169689Skan  /* Tell the assembler which register we're using as the global
6759169689Skan     pointer.  This is needed for thunks, since they can use either
6760169689Skan     explicit relocs or assembler macros.  */
6761169689Skan  mips_output_cplocal ();
6762169689Skan}
6763169689Skan
6764169689Skan/* Make the last instruction frame related and note that it performs
6765169689Skan   the operation described by FRAME_PATTERN.  */
6766169689Skan
6767169689Skanstatic void
6768169689Skanmips_set_frame_expr (rtx frame_pattern)
6769169689Skan{
6770169689Skan  rtx insn;
6771169689Skan
6772169689Skan  insn = get_last_insn ();
6773169689Skan  RTX_FRAME_RELATED_P (insn) = 1;
6774169689Skan  REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
6775169689Skan				      frame_pattern,
6776169689Skan				      REG_NOTES (insn));
6777169689Skan}
6778169689Skan
6779169689Skan
6780169689Skan/* Return a frame-related rtx that stores REG at MEM.
6781169689Skan   REG must be a single register.  */
6782169689Skan
6783169689Skanstatic rtx
6784169689Skanmips_frame_set (rtx mem, rtx reg)
6785169689Skan{
6786169689Skan  rtx set;
6787169689Skan
6788169689Skan  /* If we're saving the return address register and the dwarf return
6789169689Skan     address column differs from the hard register number, adjust the
6790169689Skan     note reg to refer to the former.  */
6791169689Skan  if (REGNO (reg) == GP_REG_FIRST + 31
6792169689Skan      && DWARF_FRAME_RETURN_COLUMN != GP_REG_FIRST + 31)
6793169689Skan    reg = gen_rtx_REG (GET_MODE (reg), DWARF_FRAME_RETURN_COLUMN);
6794169689Skan
6795169689Skan  set = gen_rtx_SET (VOIDmode, mem, reg);
6796169689Skan  RTX_FRAME_RELATED_P (set) = 1;
6797169689Skan
6798169689Skan  return set;
6799169689Skan}
6800169689Skan
6801169689Skan
6802169689Skan/* Save register REG to MEM.  Make the instruction frame-related.  */
6803169689Skan
6804169689Skanstatic void
6805169689Skanmips_save_reg (rtx reg, rtx mem)
6806169689Skan{
6807169689Skan  if (GET_MODE (reg) == DFmode && !TARGET_FLOAT64)
6808169689Skan    {
6809169689Skan      rtx x1, x2;
6810169689Skan
6811169689Skan      if (mips_split_64bit_move_p (mem, reg))
6812169689Skan	mips_split_64bit_move (mem, reg);
6813169689Skan      else
6814169689Skan	emit_move_insn (mem, reg);
6815169689Skan
6816169689Skan      x1 = mips_frame_set (mips_subword (mem, 0), mips_subword (reg, 0));
6817169689Skan      x2 = mips_frame_set (mips_subword (mem, 1), mips_subword (reg, 1));
6818169689Skan      mips_set_frame_expr (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x1, x2)));
6819169689Skan    }
6820169689Skan  else
6821169689Skan    {
6822169689Skan      if (TARGET_MIPS16
6823169689Skan	  && REGNO (reg) != GP_REG_FIRST + 31
6824169689Skan	  && !M16_REG_P (REGNO (reg)))
6825169689Skan	{
6826169689Skan	  /* Save a non-mips16 register by moving it through a temporary.
6827169689Skan	     We don't need to do this for $31 since there's a special
6828169689Skan	     instruction for it.  */
6829169689Skan	  emit_move_insn (MIPS_PROLOGUE_TEMP (GET_MODE (reg)), reg);
6830169689Skan	  emit_move_insn (mem, MIPS_PROLOGUE_TEMP (GET_MODE (reg)));
6831169689Skan	}
6832169689Skan      else
6833169689Skan	emit_move_insn (mem, reg);
6834169689Skan
6835169689Skan      mips_set_frame_expr (mips_frame_set (mem, reg));
6836169689Skan    }
6837169689Skan}
6838169689Skan
6839169689Skan
6840169689Skan/* Expand the prologue into a bunch of separate insns.  */
6841169689Skan
6842169689Skanvoid
6843169689Skanmips_expand_prologue (void)
6844169689Skan{
6845169689Skan  HOST_WIDE_INT size;
6846169689Skan
6847169689Skan  if (cfun->machine->global_pointer > 0)
6848169689Skan    REGNO (pic_offset_table_rtx) = cfun->machine->global_pointer;
6849169689Skan
6850169689Skan  size = compute_frame_size (get_frame_size ());
6851169689Skan
6852169689Skan  /* Save the registers.  Allocate up to MIPS_MAX_FIRST_STACK_STEP
6853169689Skan     bytes beforehand; this is enough to cover the register save area
6854169689Skan     without going out of range.  */
6855169689Skan  if ((cfun->machine->frame.mask | cfun->machine->frame.fmask) != 0)
6856169689Skan    {
6857169689Skan      HOST_WIDE_INT step1;
6858169689Skan
6859169689Skan      step1 = MIN (size, MIPS_MAX_FIRST_STACK_STEP);
6860169689Skan      RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6861169689Skan						     stack_pointer_rtx,
6862169689Skan						     GEN_INT (-step1)))) = 1;
6863169689Skan      size -= step1;
6864169689Skan      mips_for_each_saved_reg (size, mips_save_reg);
6865169689Skan    }
6866169689Skan
6867169689Skan  /* Allocate the rest of the frame.  */
6868169689Skan  if (size > 0)
6869169689Skan    {
6870169689Skan      if (SMALL_OPERAND (-size))
6871169689Skan	RTX_FRAME_RELATED_P (emit_insn (gen_add3_insn (stack_pointer_rtx,
6872169689Skan						       stack_pointer_rtx,
6873169689Skan						       GEN_INT (-size)))) = 1;
6874169689Skan      else
6875169689Skan	{
6876169689Skan	  emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode), GEN_INT (size));
6877169689Skan	  if (TARGET_MIPS16)
6878169689Skan	    {
6879169689Skan	      /* There are no instructions to add or subtract registers
6880169689Skan		 from the stack pointer, so use the frame pointer as a
6881169689Skan		 temporary.  We should always be using a frame pointer
6882169689Skan		 in this case anyway.  */
6883169689Skan	      gcc_assert (frame_pointer_needed);
6884169689Skan	      emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6885169689Skan	      emit_insn (gen_sub3_insn (hard_frame_pointer_rtx,
6886169689Skan					hard_frame_pointer_rtx,
6887169689Skan					MIPS_PROLOGUE_TEMP (Pmode)));
6888169689Skan	      emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
6889169689Skan	    }
6890169689Skan	  else
6891169689Skan	    emit_insn (gen_sub3_insn (stack_pointer_rtx,
6892169689Skan				      stack_pointer_rtx,
6893169689Skan				      MIPS_PROLOGUE_TEMP (Pmode)));
6894169689Skan
6895169689Skan	  /* Describe the combined effect of the previous instructions.  */
6896169689Skan	  mips_set_frame_expr
6897169689Skan	    (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
6898169689Skan			  plus_constant (stack_pointer_rtx, -size)));
6899169689Skan	}
6900169689Skan    }
6901169689Skan
6902169689Skan  /* Set up the frame pointer, if we're using one.  In mips16 code,
6903169689Skan     we point the frame pointer ahead of the outgoing argument area.
6904169689Skan     This should allow more variables & incoming arguments to be
6905169689Skan     accessed with unextended instructions.  */
6906169689Skan  if (frame_pointer_needed)
6907169689Skan    {
6908169689Skan      if (TARGET_MIPS16 && cfun->machine->frame.args_size != 0)
6909169689Skan	{
6910169689Skan	  rtx offset = GEN_INT (cfun->machine->frame.args_size);
6911169689Skan	  if (SMALL_OPERAND (cfun->machine->frame.args_size))
6912169689Skan	    RTX_FRAME_RELATED_P
6913169689Skan	      (emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
6914169689Skan					 stack_pointer_rtx,
6915169689Skan					 offset))) = 1;
6916169689Skan	  else
6917169689Skan	    {
6918169689Skan	      emit_move_insn (MIPS_PROLOGUE_TEMP (Pmode), offset);
6919169689Skan	      emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
6920169689Skan	      emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
6921169689Skan					hard_frame_pointer_rtx,
6922169689Skan					MIPS_PROLOGUE_TEMP (Pmode)));
6923169689Skan	      mips_set_frame_expr
6924169689Skan		(gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
6925169689Skan			      plus_constant (stack_pointer_rtx,
6926169689Skan					     cfun->machine->frame.args_size)));
6927169689Skan	    }
6928169689Skan	}
6929169689Skan      else
6930169689Skan	RTX_FRAME_RELATED_P (emit_move_insn (hard_frame_pointer_rtx,
6931169689Skan					     stack_pointer_rtx)) = 1;
6932169689Skan    }
6933169689Skan
6934169689Skan  mips_emit_loadgp ();
6935169689Skan
6936169689Skan  /* If generating o32/o64 abicalls, save $gp on the stack.  */
6937169689Skan  if (TARGET_ABICALLS && !TARGET_NEWABI && !current_function_is_leaf)
6938169689Skan    emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size)));
6939169689Skan
6940169689Skan  /* If we are profiling, make sure no instructions are scheduled before
6941169689Skan     the call to mcount.  */
6942169689Skan
6943169689Skan  if (current_function_profile)
6944169689Skan    emit_insn (gen_blockage ());
6945169689Skan}
6946169689Skan
6947169689Skan/* Do any necessary cleanup after a function to restore stack, frame,
6948169689Skan   and regs.  */
6949169689Skan
6950169689Skan#define RA_MASK BITMASK_HIGH	/* 1 << 31 */
6951169689Skan
6952169689Skanstatic void
6953169689Skanmips_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
6954169689Skan			       HOST_WIDE_INT size ATTRIBUTE_UNUSED)
6955169689Skan{
6956169689Skan  /* Reinstate the normal $gp.  */
6957169689Skan  REGNO (pic_offset_table_rtx) = GLOBAL_POINTER_REGNUM;
6958169689Skan  mips_output_cplocal ();
6959169689Skan
6960169689Skan  if (cfun->machine->all_noreorder_p)
6961169689Skan    {
6962169689Skan      /* Avoid using %>%) since it adds excess whitespace.  */
6963169689Skan      output_asm_insn (".set\tmacro", 0);
6964169689Skan      output_asm_insn (".set\treorder", 0);
6965169689Skan      set_noreorder = set_nomacro = 0;
6966169689Skan    }
6967169689Skan
6968169689Skan  if (!FUNCTION_NAME_ALREADY_DECLARED && !flag_inhibit_size_directive)
6969169689Skan    {
6970169689Skan      const char *fnname;
6971169689Skan
6972169689Skan      /* Get the function name the same way that toplev.c does before calling
6973169689Skan	 assemble_start_function.  This is needed so that the name used here
6974169689Skan	 exactly matches the name used in ASM_DECLARE_FUNCTION_NAME.  */
6975169689Skan      fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
6976169689Skan      fputs ("\t.end\t", file);
6977169689Skan      assemble_name (file, fnname);
6978169689Skan      fputs ("\n", file);
6979169689Skan    }
6980169689Skan}
6981169689Skan
6982169689Skan/* Emit instructions to restore register REG from slot MEM.  */
6983169689Skan
6984169689Skanstatic void
6985169689Skanmips_restore_reg (rtx reg, rtx mem)
6986169689Skan{
6987169689Skan  /* There's no mips16 instruction to load $31 directly.  Load into
6988169689Skan     $7 instead and adjust the return insn appropriately.  */
6989169689Skan  if (TARGET_MIPS16 && REGNO (reg) == GP_REG_FIRST + 31)
6990169689Skan    reg = gen_rtx_REG (GET_MODE (reg), 7);
6991169689Skan
6992169689Skan  if (TARGET_MIPS16 && !M16_REG_P (REGNO (reg)))
6993169689Skan    {
6994169689Skan      /* Can't restore directly; move through a temporary.  */
6995169689Skan      emit_move_insn (MIPS_EPILOGUE_TEMP (GET_MODE (reg)), mem);
6996169689Skan      emit_move_insn (reg, MIPS_EPILOGUE_TEMP (GET_MODE (reg)));
6997169689Skan    }
6998169689Skan  else
6999169689Skan    emit_move_insn (reg, mem);
7000169689Skan}
7001169689Skan
7002169689Skan
7003169689Skan/* Expand the epilogue into a bunch of separate insns.  SIBCALL_P is true
7004169689Skan   if this epilogue precedes a sibling call, false if it is for a normal
7005169689Skan   "epilogue" pattern.  */
7006169689Skan
7007169689Skanvoid
7008169689Skanmips_expand_epilogue (int sibcall_p)
7009169689Skan{
7010169689Skan  HOST_WIDE_INT step1, step2;
7011169689Skan  rtx base, target;
7012169689Skan
7013169689Skan  if (!sibcall_p && mips_can_use_return_insn ())
7014169689Skan    {
7015169689Skan      emit_jump_insn (gen_return ());
7016169689Skan      return;
7017169689Skan    }
7018169689Skan
7019169689Skan  /* Split the frame into two.  STEP1 is the amount of stack we should
7020169689Skan     deallocate before restoring the registers.  STEP2 is the amount we
7021169689Skan     should deallocate afterwards.
7022169689Skan
7023169689Skan     Start off by assuming that no registers need to be restored.  */
7024169689Skan  step1 = cfun->machine->frame.total_size;
7025169689Skan  step2 = 0;
7026169689Skan
7027169689Skan  /* Work out which register holds the frame address.  Account for the
7028169689Skan     frame pointer offset used by mips16 code.  */
7029169689Skan  if (!frame_pointer_needed)
7030169689Skan    base = stack_pointer_rtx;
7031169689Skan  else
7032169689Skan    {
7033169689Skan      base = hard_frame_pointer_rtx;
7034169689Skan      if (TARGET_MIPS16)
7035169689Skan	step1 -= cfun->machine->frame.args_size;
7036169689Skan    }
7037169689Skan
7038169689Skan  /* If we need to restore registers, deallocate as much stack as
7039169689Skan     possible in the second step without going out of range.  */
7040169689Skan  if ((cfun->machine->frame.mask | cfun->machine->frame.fmask) != 0)
7041169689Skan    {
7042169689Skan      step2 = MIN (step1, MIPS_MAX_FIRST_STACK_STEP);
7043169689Skan      step1 -= step2;
7044169689Skan    }
7045169689Skan
7046169689Skan  /* Set TARGET to BASE + STEP1.  */
7047169689Skan  target = base;
7048169689Skan  if (step1 > 0)
7049169689Skan    {
7050169689Skan      rtx adjust;
7051169689Skan
7052169689Skan      /* Get an rtx for STEP1 that we can add to BASE.  */
7053169689Skan      adjust = GEN_INT (step1);
7054169689Skan      if (!SMALL_OPERAND (step1))
7055169689Skan	{
7056169689Skan	  emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode), adjust);
7057169689Skan	  adjust = MIPS_EPILOGUE_TEMP (Pmode);
7058169689Skan	}
7059169689Skan
7060169689Skan      /* Normal mode code can copy the result straight into $sp.  */
7061169689Skan      if (!TARGET_MIPS16)
7062169689Skan	target = stack_pointer_rtx;
7063169689Skan
7064169689Skan      emit_insn (gen_add3_insn (target, base, adjust));
7065169689Skan    }
7066169689Skan
7067169689Skan  /* Copy TARGET into the stack pointer.  */
7068169689Skan  if (target != stack_pointer_rtx)
7069169689Skan    emit_move_insn (stack_pointer_rtx, target);
7070169689Skan
7071169689Skan  /* If we're using addressing macros for n32/n64 abicalls, $gp is
7072169689Skan     implicitly used by all SYMBOL_REFs.  We must emit a blockage
7073169689Skan     insn before restoring it.  */
7074169689Skan  if (TARGET_ABICALLS && TARGET_NEWABI && !TARGET_EXPLICIT_RELOCS)
7075169689Skan    emit_insn (gen_blockage ());
7076169689Skan
7077169689Skan  /* Restore the registers.  */
7078169689Skan  mips_for_each_saved_reg (cfun->machine->frame.total_size - step2,
7079169689Skan			   mips_restore_reg);
7080169689Skan
7081169689Skan  /* Deallocate the final bit of the frame.  */
7082169689Skan  if (step2 > 0)
7083169689Skan    emit_insn (gen_add3_insn (stack_pointer_rtx,
7084169689Skan			      stack_pointer_rtx,
7085169689Skan			      GEN_INT (step2)));
7086169689Skan
7087169689Skan  /* Add in the __builtin_eh_return stack adjustment.  We need to
7088169689Skan     use a temporary in mips16 code.  */
7089169689Skan  if (current_function_calls_eh_return)
7090169689Skan    {
7091169689Skan      if (TARGET_MIPS16)
7092169689Skan	{
7093169689Skan	  emit_move_insn (MIPS_EPILOGUE_TEMP (Pmode), stack_pointer_rtx);
7094169689Skan	  emit_insn (gen_add3_insn (MIPS_EPILOGUE_TEMP (Pmode),
7095169689Skan				    MIPS_EPILOGUE_TEMP (Pmode),
7096169689Skan				    EH_RETURN_STACKADJ_RTX));
7097169689Skan	  emit_move_insn (stack_pointer_rtx, MIPS_EPILOGUE_TEMP (Pmode));
7098169689Skan	}
7099169689Skan      else
7100169689Skan	emit_insn (gen_add3_insn (stack_pointer_rtx,
7101169689Skan				  stack_pointer_rtx,
7102169689Skan				  EH_RETURN_STACKADJ_RTX));
7103169689Skan    }
7104169689Skan
7105169689Skan  if (!sibcall_p)
7106169689Skan    {
7107169689Skan      /* The mips16 loads the return address into $7, not $31.  */
7108169689Skan      if (TARGET_MIPS16 && (cfun->machine->frame.mask & RA_MASK) != 0)
7109169689Skan	emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
7110169689Skan							  GP_REG_FIRST + 7)));
7111169689Skan      else
7112169689Skan	emit_jump_insn (gen_return_internal (gen_rtx_REG (Pmode,
7113169689Skan							  GP_REG_FIRST + 31)));
7114169689Skan    }
7115169689Skan}
7116169689Skan
7117169689Skan/* Return nonzero if this function is known to have a null epilogue.
7118169689Skan   This allows the optimizer to omit jumps to jumps if no stack
7119169689Skan   was created.  */
7120169689Skan
7121169689Skanint
7122169689Skanmips_can_use_return_insn (void)
7123169689Skan{
7124169689Skan  tree return_type;
7125169689Skan
7126169689Skan  if (! reload_completed)
7127169689Skan    return 0;
7128169689Skan
7129169689Skan  if (regs_ever_live[31] || current_function_profile)
7130169689Skan    return 0;
7131169689Skan
7132169689Skan  return_type = DECL_RESULT (current_function_decl);
7133169689Skan
7134169689Skan  /* In mips16 mode, a function which returns a floating point value
7135169689Skan     needs to arrange to copy the return value into the floating point
7136169689Skan     registers.  */
7137169689Skan  if (TARGET_MIPS16
7138169689Skan      && mips16_hard_float
7139169689Skan      && ! aggregate_value_p (return_type, current_function_decl)
7140169689Skan      && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
7141169689Skan      && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE)
7142169689Skan    return 0;
7143169689Skan
7144169689Skan  if (cfun->machine->frame.initialized)
7145169689Skan    return cfun->machine->frame.total_size == 0;
7146169689Skan
7147169689Skan  return compute_frame_size (get_frame_size ()) == 0;
7148169689Skan}
7149169689Skan
7150169689Skan/* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
7151169689Skan   in order to avoid duplicating too much logic from elsewhere.  */
7152169689Skan
7153169689Skanstatic void
7154169689Skanmips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
7155169689Skan		      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
7156169689Skan		      tree function)
7157169689Skan{
7158169689Skan  rtx this, temp1, temp2, insn, fnaddr;
7159169689Skan
7160169689Skan  /* Pretend to be a post-reload pass while generating rtl.  */
7161169689Skan  no_new_pseudos = 1;
7162169689Skan  reload_completed = 1;
7163169689Skan  reset_block_changes ();
7164169689Skan
7165169689Skan  /* Pick a global pointer for -mabicalls.  Use $15 rather than $28
7166169689Skan     for TARGET_NEWABI since the latter is a call-saved register.  */
7167169689Skan  if (TARGET_ABICALLS)
7168169689Skan    cfun->machine->global_pointer
7169169689Skan      = REGNO (pic_offset_table_rtx)
7170169689Skan      = TARGET_NEWABI ? 15 : GLOBAL_POINTER_REGNUM;
7171169689Skan
7172169689Skan  /* Set up the global pointer for n32 or n64 abicalls.  */
7173169689Skan  mips_emit_loadgp ();
7174169689Skan
7175169689Skan  /* We need two temporary registers in some cases.  */
7176169689Skan  temp1 = gen_rtx_REG (Pmode, 2);
7177169689Skan  temp2 = gen_rtx_REG (Pmode, 3);
7178169689Skan
7179169689Skan  /* Find out which register contains the "this" pointer.  */
7180169689Skan  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
7181169689Skan    this = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
7182169689Skan  else
7183169689Skan    this = gen_rtx_REG (Pmode, GP_ARG_FIRST);
7184169689Skan
7185169689Skan  /* Add DELTA to THIS.  */
7186169689Skan  if (delta != 0)
7187169689Skan    {
7188169689Skan      rtx offset = GEN_INT (delta);
7189169689Skan      if (!SMALL_OPERAND (delta))
7190169689Skan	{
7191169689Skan	  emit_move_insn (temp1, offset);
7192169689Skan	  offset = temp1;
7193169689Skan	}
7194169689Skan      emit_insn (gen_add3_insn (this, this, offset));
7195169689Skan    }
7196169689Skan
7197169689Skan  /* If needed, add *(*THIS + VCALL_OFFSET) to THIS.  */
7198169689Skan  if (vcall_offset != 0)
7199169689Skan    {
7200169689Skan      rtx addr;
7201169689Skan
7202169689Skan      /* Set TEMP1 to *THIS.  */
7203169689Skan      emit_move_insn (temp1, gen_rtx_MEM (Pmode, this));
7204169689Skan
7205169689Skan      /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET.  */
7206169689Skan      addr = mips_add_offset (temp2, temp1, vcall_offset);
7207169689Skan
7208169689Skan      /* Load the offset and add it to THIS.  */
7209169689Skan      emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr));
7210169689Skan      emit_insn (gen_add3_insn (this, this, temp1));
7211169689Skan    }
7212169689Skan
7213169689Skan  /* Jump to the target function.  Use a sibcall if direct jumps are
7214169689Skan     allowed, otherwise load the address into a register first.  */
7215169689Skan  fnaddr = XEXP (DECL_RTL (function), 0);
7216169689Skan  if (TARGET_MIPS16 || TARGET_ABICALLS || TARGET_LONG_CALLS)
7217169689Skan    {
7218169689Skan      /* This is messy.  gas treats "la $25,foo" as part of a call
7219169689Skan	 sequence and may allow a global "foo" to be lazily bound.
7220169689Skan	 The general move patterns therefore reject this combination.
7221169689Skan
7222169689Skan	 In this context, lazy binding would actually be OK for o32 and o64,
7223169689Skan	 but it's still wrong for n32 and n64; see mips_load_call_address.
7224169689Skan	 We must therefore load the address via a temporary register if
7225169689Skan	 mips_dangerous_for_la25_p.
7226169689Skan
7227169689Skan	 If we jump to the temporary register rather than $25, the assembler
7228169689Skan	 can use the move insn to fill the jump's delay slot.  */
7229169689Skan      if (TARGET_ABICALLS && !mips_dangerous_for_la25_p (fnaddr))
7230169689Skan	temp1 = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM);
7231169689Skan      mips_load_call_address (temp1, fnaddr, true);
7232169689Skan
7233169689Skan      if (TARGET_ABICALLS && REGNO (temp1) != PIC_FUNCTION_ADDR_REGNUM)
7234169689Skan	emit_move_insn (gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM), temp1);
7235169689Skan      emit_jump_insn (gen_indirect_jump (temp1));
7236169689Skan    }
7237169689Skan  else
7238169689Skan    {
7239169689Skan      insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
7240169689Skan      SIBLING_CALL_P (insn) = 1;
7241169689Skan    }
7242169689Skan
7243169689Skan  /* Run just enough of rest_of_compilation.  This sequence was
7244169689Skan     "borrowed" from alpha.c.  */
7245169689Skan  insn = get_insns ();
7246169689Skan  insn_locators_initialize ();
7247169689Skan  split_all_insns_noflow ();
7248169689Skan  if (TARGET_MIPS16)
7249169689Skan    mips16_lay_out_constants ();
7250169689Skan  shorten_branches (insn);
7251169689Skan  final_start_function (insn, file, 1);
7252169689Skan  final (insn, file, 1);
7253169689Skan  final_end_function ();
7254169689Skan
7255169689Skan  /* Clean up the vars set above.  Note that final_end_function resets
7256169689Skan     the global pointer for us.  */
7257169689Skan  reload_completed = 0;
7258169689Skan  no_new_pseudos = 0;
7259169689Skan}
7260169689Skan
7261169689Skan/* Returns nonzero if X contains a SYMBOL_REF.  */
7262169689Skan
7263169689Skanstatic int
7264169689Skansymbolic_expression_p (rtx x)
7265169689Skan{
7266169689Skan  if (GET_CODE (x) == SYMBOL_REF)
7267169689Skan    return 1;
7268169689Skan
7269169689Skan  if (GET_CODE (x) == CONST)
7270169689Skan    return symbolic_expression_p (XEXP (x, 0));
7271169689Skan
7272169689Skan  if (UNARY_P (x))
7273169689Skan    return symbolic_expression_p (XEXP (x, 0));
7274169689Skan
7275169689Skan  if (ARITHMETIC_P (x))
7276169689Skan    return (symbolic_expression_p (XEXP (x, 0))
7277169689Skan	    || symbolic_expression_p (XEXP (x, 1)));
7278169689Skan
7279169689Skan  return 0;
7280169689Skan}
7281169689Skan
7282169689Skan/* Choose the section to use for the constant rtx expression X that has
7283169689Skan   mode MODE.  */
7284169689Skan
7285169689Skanstatic section *
7286169689Skanmips_select_rtx_section (enum machine_mode mode, rtx x,
7287169689Skan			 unsigned HOST_WIDE_INT align)
7288169689Skan{
7289169689Skan  if (TARGET_MIPS16)
7290169689Skan    {
7291169689Skan      /* In mips16 mode, the constant table always goes in the same section
7292169689Skan         as the function, so that constants can be loaded using PC relative
7293169689Skan         addressing.  */
7294169689Skan      return function_section (current_function_decl);
7295169689Skan    }
7296169689Skan  else if (TARGET_EMBEDDED_DATA)
7297169689Skan    {
7298169689Skan      /* For embedded applications, always put constants in read-only data,
7299169689Skan	 in order to reduce RAM usage.  */
7300169689Skan      return mergeable_constant_section (mode, align, 0);
7301169689Skan    }
7302169689Skan  else
7303169689Skan    {
7304169689Skan      /* For hosted applications, always put constants in small data if
7305169689Skan	 possible, as this gives the best performance.  */
7306169689Skan      /* ??? Consider using mergeable small data sections.  */
7307169689Skan
7308169689Skan      if (GET_MODE_SIZE (mode) <= (unsigned) mips_section_threshold
7309169689Skan	  && mips_section_threshold > 0)
7310169689Skan	return get_named_section (NULL, ".sdata", 0);
7311169689Skan      else if (flag_pic && symbolic_expression_p (x))
7312169689Skan	return get_named_section (NULL, ".data.rel.ro", 3);
7313169689Skan      else
7314169689Skan	return mergeable_constant_section (mode, align, 0);
7315169689Skan    }
7316169689Skan}
7317169689Skan
7318169689Skan/* Implement TARGET_ASM_FUNCTION_RODATA_SECTION.
7319169689Skan
7320169689Skan   The complication here is that, with the combination TARGET_ABICALLS
7321169689Skan   && !TARGET_GPWORD, jump tables will use absolute addresses, and should
7322169689Skan   therefore not be included in the read-only part of a DSO.  Handle such
7323169689Skan   cases by selecting a normal data section instead of a read-only one.
7324169689Skan   The logic apes that in default_function_rodata_section.  */
7325169689Skan
7326169689Skanstatic section *
7327169689Skanmips_function_rodata_section (tree decl)
7328169689Skan{
7329169689Skan  if (!TARGET_ABICALLS || TARGET_GPWORD)
7330169689Skan    return default_function_rodata_section (decl);
7331169689Skan
7332169689Skan  if (decl && DECL_SECTION_NAME (decl))
7333169689Skan    {
7334169689Skan      const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
7335169689Skan      if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
7336169689Skan	{
7337169689Skan	  char *rname = ASTRDUP (name);
7338169689Skan	  rname[14] = 'd';
7339169689Skan	  return get_section (rname, SECTION_LINKONCE | SECTION_WRITE, decl);
7340169689Skan	}
7341169689Skan      else if (flag_function_sections && flag_data_sections
7342169689Skan	       && strncmp (name, ".text.", 6) == 0)
7343169689Skan	{
7344169689Skan	  char *rname = ASTRDUP (name);
7345169689Skan	  memcpy (rname + 1, "data", 4);
7346169689Skan	  return get_section (rname, SECTION_WRITE, decl);
7347169689Skan	}
7348169689Skan    }
7349169689Skan  return data_section;
7350169689Skan}
7351169689Skan
7352169689Skan/* Implement TARGET_IN_SMALL_DATA_P.  This function controls whether
7353169689Skan   locally-defined objects go in a small data section.  It also controls
7354169689Skan   the setting of the SYMBOL_REF_SMALL_P flag, which in turn helps
7355169689Skan   mips_classify_symbol decide when to use %gp_rel(...)($gp) accesses.  */
7356169689Skan
7357169689Skanstatic bool
7358169689Skanmips_in_small_data_p (tree decl)
7359169689Skan{
7360169689Skan  HOST_WIDE_INT size;
7361169689Skan
7362169689Skan  if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
7363169689Skan    return false;
7364169689Skan
7365169689Skan  /* We don't yet generate small-data references for -mabicalls.  See related
7366169689Skan     -G handling in override_options.  */
7367169689Skan  if (TARGET_ABICALLS)
7368169689Skan    return false;
7369169689Skan
7370169689Skan  if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
7371169689Skan    {
7372169689Skan      const char *name;
7373169689Skan
7374169689Skan      /* Reject anything that isn't in a known small-data section.  */
7375169689Skan      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
7376169689Skan      if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
7377169689Skan	return false;
7378169689Skan
7379169689Skan      /* If a symbol is defined externally, the assembler will use the
7380169689Skan	 usual -G rules when deciding how to implement macros.  */
7381169689Skan      if (TARGET_EXPLICIT_RELOCS || !DECL_EXTERNAL (decl))
7382169689Skan	return true;
7383169689Skan    }
7384169689Skan  else if (TARGET_EMBEDDED_DATA)
7385169689Skan    {
7386169689Skan      /* Don't put constants into the small data section: we want them
7387169689Skan	 to be in ROM rather than RAM.  */
7388169689Skan      if (TREE_CODE (decl) != VAR_DECL)
7389169689Skan	return false;
7390169689Skan
7391169689Skan      if (TREE_READONLY (decl)
7392169689Skan	  && !TREE_SIDE_EFFECTS (decl)
7393169689Skan	  && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
7394169689Skan	return false;
7395169689Skan    }
7396169689Skan
7397169689Skan  size = int_size_in_bytes (TREE_TYPE (decl));
7398169689Skan  return (size > 0 && size <= mips_section_threshold);
7399169689Skan}
7400169689Skan
7401169689Skan/* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P.  We don't want to use
7402169689Skan   anchors for small data: the GP register acts as an anchor in that
7403169689Skan   case.  We also don't want to use them for PC-relative accesses,
7404169689Skan   where the PC acts as an anchor.  */
7405169689Skan
7406169689Skanstatic bool
7407169689Skanmips_use_anchors_for_symbol_p (rtx symbol)
7408169689Skan{
7409169689Skan  switch (mips_classify_symbol (symbol))
7410169689Skan    {
7411169689Skan    case SYMBOL_CONSTANT_POOL:
7412169689Skan    case SYMBOL_SMALL_DATA:
7413169689Skan      return false;
7414169689Skan
7415169689Skan    default:
7416169689Skan      return true;
7417169689Skan    }
7418169689Skan}
7419169689Skan
7420169689Skan/* See whether VALTYPE is a record whose fields should be returned in
7421169689Skan   floating-point registers.  If so, return the number of fields and
7422169689Skan   list them in FIELDS (which should have two elements).  Return 0
7423169689Skan   otherwise.
7424169689Skan
7425169689Skan   For n32 & n64, a structure with one or two fields is returned in
7426169689Skan   floating-point registers as long as every field has a floating-point
7427169689Skan   type.  */
7428169689Skan
7429169689Skanstatic int
7430169689Skanmips_fpr_return_fields (tree valtype, tree *fields)
7431169689Skan{
7432169689Skan  tree field;
7433169689Skan  int i;
7434169689Skan
7435169689Skan  if (!TARGET_NEWABI)
7436169689Skan    return 0;
7437169689Skan
7438169689Skan  if (TREE_CODE (valtype) != RECORD_TYPE)
7439169689Skan    return 0;
7440169689Skan
7441169689Skan  i = 0;
7442169689Skan  for (field = TYPE_FIELDS (valtype); field != 0; field = TREE_CHAIN (field))
7443169689Skan    {
7444169689Skan      if (TREE_CODE (field) != FIELD_DECL)
7445169689Skan	continue;
7446169689Skan
7447169689Skan      if (TREE_CODE (TREE_TYPE (field)) != REAL_TYPE)
7448169689Skan	return 0;
7449169689Skan
7450169689Skan      if (i == 2)
7451169689Skan	return 0;
7452169689Skan
7453169689Skan      fields[i++] = field;
7454169689Skan    }
7455169689Skan  return i;
7456169689Skan}
7457169689Skan
7458169689Skan
7459169689Skan/* Implement TARGET_RETURN_IN_MSB.  For n32 & n64, we should return
7460169689Skan   a value in the most significant part of $2/$3 if:
7461169689Skan
7462169689Skan      - the target is big-endian;
7463169689Skan
7464169689Skan      - the value has a structure or union type (we generalize this to
7465169689Skan	cover aggregates from other languages too); and
7466169689Skan
7467169689Skan      - the structure is not returned in floating-point registers.  */
7468169689Skan
7469169689Skanstatic bool
7470169689Skanmips_return_in_msb (tree valtype)
7471169689Skan{
7472169689Skan  tree fields[2];
7473169689Skan
7474169689Skan  return (TARGET_NEWABI
7475169689Skan	  && TARGET_BIG_ENDIAN
7476169689Skan	  && AGGREGATE_TYPE_P (valtype)
7477169689Skan	  && mips_fpr_return_fields (valtype, fields) == 0);
7478169689Skan}
7479169689Skan
7480169689Skan
7481169689Skan/* Return a composite value in a pair of floating-point registers.
7482169689Skan   MODE1 and OFFSET1 are the mode and byte offset for the first value,
7483169689Skan   likewise MODE2 and OFFSET2 for the second.  MODE is the mode of the
7484169689Skan   complete value.
7485169689Skan
7486169689Skan   For n32 & n64, $f0 always holds the first value and $f2 the second.
7487169689Skan   Otherwise the values are packed together as closely as possible.  */
7488169689Skan
7489169689Skanstatic rtx
7490169689Skanmips_return_fpr_pair (enum machine_mode mode,
7491169689Skan		      enum machine_mode mode1, HOST_WIDE_INT offset1,
7492169689Skan		      enum machine_mode mode2, HOST_WIDE_INT offset2)
7493169689Skan{
7494169689Skan  int inc;
7495169689Skan
7496169689Skan  inc = (TARGET_NEWABI ? 2 : FP_INC);
7497169689Skan  return gen_rtx_PARALLEL
7498169689Skan    (mode,
7499169689Skan     gen_rtvec (2,
7500169689Skan		gen_rtx_EXPR_LIST (VOIDmode,
7501169689Skan				   gen_rtx_REG (mode1, FP_RETURN),
7502169689Skan				   GEN_INT (offset1)),
7503169689Skan		gen_rtx_EXPR_LIST (VOIDmode,
7504169689Skan				   gen_rtx_REG (mode2, FP_RETURN + inc),
7505169689Skan				   GEN_INT (offset2))));
7506169689Skan
7507169689Skan}
7508169689Skan
7509169689Skan
7510169689Skan/* Implement FUNCTION_VALUE and LIBCALL_VALUE.  For normal calls,
7511169689Skan   VALTYPE is the return type and MODE is VOIDmode.  For libcalls,
7512169689Skan   VALTYPE is null and MODE is the mode of the return value.  */
7513169689Skan
7514169689Skanrtx
7515169689Skanmips_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
7516169689Skan		     enum machine_mode mode)
7517169689Skan{
7518169689Skan  if (valtype)
7519169689Skan    {
7520169689Skan      tree fields[2];
7521169689Skan      int unsignedp;
7522169689Skan
7523169689Skan      mode = TYPE_MODE (valtype);
7524169689Skan      unsignedp = TYPE_UNSIGNED (valtype);
7525169689Skan
7526169689Skan      /* Since we define TARGET_PROMOTE_FUNCTION_RETURN that returns
7527169689Skan	 true, we must promote the mode just as PROMOTE_MODE does.  */
7528169689Skan      mode = promote_mode (valtype, mode, &unsignedp, 1);
7529169689Skan
7530169689Skan      /* Handle structures whose fields are returned in $f0/$f2.  */
7531169689Skan      switch (mips_fpr_return_fields (valtype, fields))
7532169689Skan	{
7533169689Skan	case 1:
7534169689Skan	  return gen_rtx_REG (mode, FP_RETURN);
7535169689Skan
7536169689Skan	case 2:
7537169689Skan	  return mips_return_fpr_pair (mode,
7538169689Skan				       TYPE_MODE (TREE_TYPE (fields[0])),
7539169689Skan				       int_byte_position (fields[0]),
7540169689Skan				       TYPE_MODE (TREE_TYPE (fields[1])),
7541169689Skan				       int_byte_position (fields[1]));
7542169689Skan	}
7543169689Skan
7544169689Skan      /* If a value is passed in the most significant part of a register, see
7545169689Skan	 whether we have to round the mode up to a whole number of words.  */
7546169689Skan      if (mips_return_in_msb (valtype))
7547169689Skan	{
7548169689Skan	  HOST_WIDE_INT size = int_size_in_bytes (valtype);
7549169689Skan	  if (size % UNITS_PER_WORD != 0)
7550169689Skan	    {
7551169689Skan	      size += UNITS_PER_WORD - size % UNITS_PER_WORD;
7552169689Skan	      mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
7553169689Skan	    }
7554169689Skan	}
7555169689Skan
7556169689Skan      /* For EABI, the class of return register depends entirely on MODE.
7557169689Skan	 For example, "struct { some_type x; }" and "union { some_type x; }"
7558169689Skan	 are returned in the same way as a bare "some_type" would be.
7559169689Skan	 Other ABIs only use FPRs for scalar, complex or vector types.  */
7560169689Skan      if (mips_abi != ABI_EABI && !FLOAT_TYPE_P (valtype))
7561169689Skan	return gen_rtx_REG (mode, GP_RETURN);
7562169689Skan    }
7563169689Skan
7564169689Skan  if ((GET_MODE_CLASS (mode) == MODE_FLOAT
7565169689Skan       || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
7566169689Skan      && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE)
7567169689Skan    return gen_rtx_REG (mode, FP_RETURN);
7568169689Skan
7569169689Skan  /* Handle long doubles for n32 & n64.  */
7570169689Skan  if (mode == TFmode)
7571169689Skan    return mips_return_fpr_pair (mode,
7572169689Skan				 DImode, 0,
7573169689Skan				 DImode, GET_MODE_SIZE (mode) / 2);
7574169689Skan
7575169689Skan  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
7576169689Skan      && GET_MODE_SIZE (mode) <= UNITS_PER_HWFPVALUE * 2)
7577169689Skan    return mips_return_fpr_pair (mode,
7578169689Skan				 GET_MODE_INNER (mode), 0,
7579169689Skan				 GET_MODE_INNER (mode),
7580169689Skan				 GET_MODE_SIZE (mode) / 2);
7581169689Skan
7582169689Skan  return gen_rtx_REG (mode, GP_RETURN);
7583169689Skan}
7584169689Skan
7585169689Skan/* Return nonzero when an argument must be passed by reference.  */
7586169689Skan
7587169689Skanstatic bool
7588169689Skanmips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7589169689Skan			enum machine_mode mode, tree type,
7590169689Skan			bool named ATTRIBUTE_UNUSED)
7591169689Skan{
7592169689Skan  if (mips_abi == ABI_EABI)
7593169689Skan    {
7594169689Skan      int size;
7595169689Skan
7596169689Skan      /* ??? How should SCmode be handled?  */
7597169689Skan      if (mode == DImode || mode == DFmode)
7598169689Skan	return 0;
7599169689Skan
7600169689Skan      size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
7601169689Skan      return size == -1 || size > UNITS_PER_WORD;
7602169689Skan    }
7603169689Skan  else
7604169689Skan    {
7605169689Skan      /* If we have a variable-sized parameter, we have no choice.  */
7606169689Skan      return targetm.calls.must_pass_in_stack (mode, type);
7607169689Skan    }
7608169689Skan}
7609169689Skan
7610169689Skanstatic bool
7611169689Skanmips_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
7612169689Skan		    enum machine_mode mode ATTRIBUTE_UNUSED,
7613169689Skan		    tree type ATTRIBUTE_UNUSED, bool named)
7614169689Skan{
7615169689Skan  return mips_abi == ABI_EABI && named;
7616169689Skan}
7617169689Skan
7618169689Skan/* Return true if registers of class CLASS cannot change from mode FROM
7619169689Skan   to mode TO.  */
7620169689Skan
7621169689Skanbool
7622169689Skanmips_cannot_change_mode_class (enum machine_mode from,
7623169689Skan			       enum machine_mode to, enum reg_class class)
7624169689Skan{
7625169689Skan  if (MIN (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) <= UNITS_PER_WORD
7626169689Skan      && MAX (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) > UNITS_PER_WORD)
7627169689Skan    {
7628169689Skan      if (TARGET_BIG_ENDIAN)
7629169689Skan	{
7630169689Skan	  /* When a multi-word value is stored in paired floating-point
7631169689Skan	     registers, the first register always holds the low word.
7632169689Skan	     We therefore can't allow FPRs to change between single-word
7633169689Skan	     and multi-word modes.  */
7634169689Skan	  if (FP_INC > 1 && reg_classes_intersect_p (FP_REGS, class))
7635169689Skan	    return true;
7636169689Skan	}
7637169689Skan      else
7638169689Skan	{
7639169689Skan	  /* LO_REGNO == HI_REGNO + 1, so if a multi-word value is stored
7640169689Skan	     in LO and HI, the high word always comes first.  We therefore
7641169689Skan	     can't allow values stored in HI to change between single-word
7642169689Skan	     and multi-word modes.
7643169689Skan	     This rule applies to both the original HI/LO pair and the new
7644169689Skan	     DSP accumulators.  */
7645169689Skan	  if (reg_classes_intersect_p (ACC_REGS, class))
7646169689Skan	    return true;
7647169689Skan	}
7648169689Skan    }
7649169689Skan  /* Loading a 32-bit value into a 64-bit floating-point register
7650169689Skan     will not sign-extend the value, despite what LOAD_EXTEND_OP says.
7651169689Skan     We can't allow 64-bit float registers to change from SImode to
7652169689Skan     to a wider mode.  */
7653169689Skan  if (TARGET_FLOAT64
7654169689Skan      && from == SImode
7655169689Skan      && GET_MODE_SIZE (to) >= UNITS_PER_WORD
7656169689Skan      && reg_classes_intersect_p (FP_REGS, class))
7657169689Skan    return true;
7658169689Skan  return false;
7659169689Skan}
7660169689Skan
7661169689Skan/* Return true if X should not be moved directly into register $25.
7662169689Skan   We need this because many versions of GAS will treat "la $25,foo" as
7663169689Skan   part of a call sequence and so allow a global "foo" to be lazily bound.  */
7664169689Skan
7665169689Skanbool
7666169689Skanmips_dangerous_for_la25_p (rtx x)
7667169689Skan{
7668169689Skan  HOST_WIDE_INT offset;
7669169689Skan
7670169689Skan  if (TARGET_EXPLICIT_RELOCS)
7671169689Skan    return false;
7672169689Skan
7673169689Skan  mips_split_const (x, &x, &offset);
7674169689Skan  return global_got_operand (x, VOIDmode);
7675169689Skan}
7676169689Skan
7677169689Skan/* Implement PREFERRED_RELOAD_CLASS.  */
7678169689Skan
7679169689Skanenum reg_class
7680169689Skanmips_preferred_reload_class (rtx x, enum reg_class class)
7681169689Skan{
7682169689Skan  if (mips_dangerous_for_la25_p (x) && reg_class_subset_p (LEA_REGS, class))
7683169689Skan    return LEA_REGS;
7684169689Skan
7685169689Skan  if (TARGET_HARD_FLOAT
7686169689Skan      && FLOAT_MODE_P (GET_MODE (x))
7687169689Skan      && reg_class_subset_p (FP_REGS, class))
7688169689Skan    return FP_REGS;
7689169689Skan
7690169689Skan  if (reg_class_subset_p (GR_REGS, class))
7691169689Skan    class = GR_REGS;
7692169689Skan
7693169689Skan  if (TARGET_MIPS16 && reg_class_subset_p (M16_REGS, class))
7694169689Skan    class = M16_REGS;
7695169689Skan
7696169689Skan  return class;
7697169689Skan}
7698169689Skan
7699169689Skan/* This function returns the register class required for a secondary
7700169689Skan   register when copying between one of the registers in CLASS, and X,
7701169689Skan   using MODE.  If IN_P is nonzero, the copy is going from X to the
7702169689Skan   register, otherwise the register is the source.  A return value of
7703169689Skan   NO_REGS means that no secondary register is required.  */
7704169689Skan
7705169689Skanenum reg_class
7706169689Skanmips_secondary_reload_class (enum reg_class class,
7707169689Skan			     enum machine_mode mode, rtx x, int in_p)
7708169689Skan{
7709169689Skan  enum reg_class gr_regs = TARGET_MIPS16 ? M16_REGS : GR_REGS;
7710169689Skan  int regno = -1;
7711169689Skan  int gp_reg_p;
7712169689Skan
7713169689Skan  if (REG_P (x)|| GET_CODE (x) == SUBREG)
7714169689Skan    regno = true_regnum (x);
7715169689Skan
7716169689Skan  gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
7717169689Skan
7718169689Skan  if (mips_dangerous_for_la25_p (x))
7719169689Skan    {
7720169689Skan      gr_regs = LEA_REGS;
7721169689Skan      if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], 25))
7722169689Skan	return gr_regs;
7723169689Skan    }
7724169689Skan
7725169689Skan  /* Copying from HI or LO to anywhere other than a general register
7726169689Skan     requires a general register.
7727169689Skan     This rule applies to both the original HI/LO pair and the new
7728169689Skan     DSP accumulators.  */
7729169689Skan  if (reg_class_subset_p (class, ACC_REGS))
7730169689Skan    {
7731169689Skan      if (TARGET_MIPS16 && in_p)
7732169689Skan	{
7733169689Skan	  /* We can't really copy to HI or LO at all in mips16 mode.  */
7734169689Skan	  return M16_REGS;
7735169689Skan	}
7736169689Skan      return gp_reg_p ? NO_REGS : gr_regs;
7737169689Skan    }
7738169689Skan  if (ACC_REG_P (regno))
7739169689Skan    {
7740169689Skan      if (TARGET_MIPS16 && ! in_p)
7741169689Skan	{
7742169689Skan	  /* We can't really copy to HI or LO at all in mips16 mode.  */
7743169689Skan	  return M16_REGS;
7744169689Skan	}
7745169689Skan      return class == gr_regs ? NO_REGS : gr_regs;
7746169689Skan    }
7747169689Skan
7748169689Skan  /* We can only copy a value to a condition code register from a
7749169689Skan     floating point register, and even then we require a scratch
7750169689Skan     floating point register.  We can only copy a value out of a
7751169689Skan     condition code register into a general register.  */
7752169689Skan  if (class == ST_REGS)
7753169689Skan    {
7754169689Skan      if (in_p)
7755169689Skan	return FP_REGS;
7756169689Skan      return gp_reg_p ? NO_REGS : gr_regs;
7757169689Skan    }
7758169689Skan  if (ST_REG_P (regno))
7759169689Skan    {
7760169689Skan      if (! in_p)
7761169689Skan	return FP_REGS;
7762169689Skan      return class == gr_regs ? NO_REGS : gr_regs;
7763169689Skan    }
7764169689Skan
7765169689Skan  if (class == FP_REGS)
7766169689Skan    {
7767169689Skan      if (MEM_P (x))
7768169689Skan	{
7769169689Skan	  /* In this case we can use lwc1, swc1, ldc1 or sdc1.  */
7770169689Skan	  return NO_REGS;
7771169689Skan	}
7772169689Skan      else if (CONSTANT_P (x) && GET_MODE_CLASS (mode) == MODE_FLOAT)
7773169689Skan	{
7774169689Skan	  /* We can use the l.s and l.d macros to load floating-point
7775169689Skan	     constants.  ??? For l.s, we could probably get better
7776169689Skan	     code by returning GR_REGS here.  */
7777169689Skan	  return NO_REGS;
7778169689Skan	}
7779169689Skan      else if (gp_reg_p || x == CONST0_RTX (mode))
7780169689Skan	{
7781169689Skan	  /* In this case we can use mtc1, mfc1, dmtc1 or dmfc1.  */
7782169689Skan	  return NO_REGS;
7783169689Skan	}
7784169689Skan      else if (FP_REG_P (regno))
7785169689Skan	{
7786169689Skan	  /* In this case we can use mov.s or mov.d.  */
7787169689Skan	  return NO_REGS;
7788169689Skan	}
7789169689Skan      else
7790169689Skan	{
7791169689Skan	  /* Otherwise, we need to reload through an integer register.  */
7792169689Skan	  return gr_regs;
7793169689Skan	}
7794169689Skan    }
7795169689Skan
7796169689Skan  /* In mips16 mode, going between memory and anything but M16_REGS
7797169689Skan     requires an M16_REG.  */
7798169689Skan  if (TARGET_MIPS16)
7799169689Skan    {
7800169689Skan      if (class != M16_REGS && class != M16_NA_REGS)
7801169689Skan	{
7802169689Skan	  if (gp_reg_p)
7803169689Skan	    return NO_REGS;
7804169689Skan	  return M16_REGS;
7805169689Skan	}
7806169689Skan      if (! gp_reg_p)
7807169689Skan	{
7808169689Skan	  if (class == M16_REGS || class == M16_NA_REGS)
7809169689Skan	    return NO_REGS;
7810169689Skan	  return M16_REGS;
7811169689Skan	}
7812169689Skan    }
7813169689Skan
7814169689Skan  return NO_REGS;
7815169689Skan}
7816169689Skan
7817169689Skan/* Implement CLASS_MAX_NREGS.
7818169689Skan
7819169689Skan   Usually all registers are word-sized.  The only supported exception
7820169689Skan   is -mgp64 -msingle-float, which has 64-bit words but 32-bit float
7821169689Skan   registers.  A word-based calculation is correct even in that case,
7822169689Skan   since -msingle-float disallows multi-FPR values.
7823169689Skan
7824169689Skan   The FP status registers are an exception to this rule.  They are always
7825169689Skan   4 bytes wide as they only hold condition code modes, and CCmode is always
7826169689Skan   considered to be 4 bytes wide.  */
7827169689Skan
7828169689Skanint
7829169689Skanmips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
7830169689Skan		      enum machine_mode mode)
7831169689Skan{
7832169689Skan  if (class == ST_REGS)
7833169689Skan    return (GET_MODE_SIZE (mode) + 3) / 4;
7834169689Skan  else
7835169689Skan    return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
7836169689Skan}
7837169689Skan
7838169689Skanstatic bool
7839169689Skanmips_valid_pointer_mode (enum machine_mode mode)
7840169689Skan{
7841169689Skan  return (mode == SImode || (TARGET_64BIT && mode == DImode));
7842169689Skan}
7843169689Skan
7844169689Skan/* Target hook for vector_mode_supported_p.  */
7845169689Skan
7846169689Skanstatic bool
7847169689Skanmips_vector_mode_supported_p (enum machine_mode mode)
7848169689Skan{
7849169689Skan  switch (mode)
7850169689Skan    {
7851169689Skan    case V2SFmode:
7852169689Skan      return TARGET_PAIRED_SINGLE_FLOAT;
7853169689Skan
7854169689Skan    case V2HImode:
7855169689Skan    case V4QImode:
7856169689Skan      return TARGET_DSP;
7857169689Skan
7858169689Skan    default:
7859169689Skan      return false;
7860169689Skan    }
7861169689Skan}
7862169689Skan
7863169689Skan/* If we can access small data directly (using gp-relative relocation
7864169689Skan   operators) return the small data pointer, otherwise return null.
7865169689Skan
7866169689Skan   For each mips16 function which refers to GP relative symbols, we
7867169689Skan   use a pseudo register, initialized at the start of the function, to
7868169689Skan   hold the $gp value.  */
7869169689Skan
7870169689Skanstatic rtx
7871169689Skanmips16_gp_pseudo_reg (void)
7872169689Skan{
7873169689Skan  if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
7874169689Skan    {
7875169689Skan      rtx unspec;
7876169689Skan      rtx insn, scan;
7877169689Skan
7878169689Skan      cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
7879169689Skan
7880169689Skan      /* We want to initialize this to a value which gcc will believe
7881169689Skan         is constant.  */
7882169689Skan      start_sequence ();
7883169689Skan      unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_GP);
7884169689Skan      emit_move_insn (cfun->machine->mips16_gp_pseudo_rtx,
7885169689Skan		      gen_rtx_CONST (Pmode, unspec));
7886169689Skan      insn = get_insns ();
7887169689Skan      end_sequence ();
7888169689Skan
7889169689Skan      push_topmost_sequence ();
7890169689Skan      /* We need to emit the initialization after the FUNCTION_BEG
7891169689Skan         note, so that it will be integrated.  */
7892169689Skan      for (scan = get_insns (); scan != NULL_RTX; scan = NEXT_INSN (scan))
7893169689Skan	if (NOTE_P (scan)
7894169689Skan	    && NOTE_LINE_NUMBER (scan) == NOTE_INSN_FUNCTION_BEG)
7895169689Skan	  break;
7896169689Skan      if (scan == NULL_RTX)
7897169689Skan	scan = get_insns ();
7898169689Skan      insn = emit_insn_after (insn, scan);
7899169689Skan      pop_topmost_sequence ();
7900169689Skan    }
7901169689Skan
7902169689Skan  return cfun->machine->mips16_gp_pseudo_rtx;
7903169689Skan}
7904169689Skan
7905169689Skan/* Write out code to move floating point arguments in or out of
7906169689Skan   general registers.  Output the instructions to FILE.  FP_CODE is
7907169689Skan   the code describing which arguments are present (see the comment at
7908169689Skan   the definition of CUMULATIVE_ARGS in mips.h).  FROM_FP_P is nonzero if
7909169689Skan   we are copying from the floating point registers.  */
7910169689Skan
7911169689Skanstatic void
7912169689Skanmips16_fp_args (FILE *file, int fp_code, int from_fp_p)
7913169689Skan{
7914169689Skan  const char *s;
7915169689Skan  int gparg, fparg;
7916169689Skan  unsigned int f;
7917169689Skan
7918169689Skan  /* This code only works for the original 32 bit ABI and the O64 ABI.  */
7919169689Skan  gcc_assert (TARGET_OLDABI);
7920169689Skan
7921169689Skan  if (from_fp_p)
7922169689Skan    s = "mfc1";
7923169689Skan  else
7924169689Skan    s = "mtc1";
7925169689Skan  gparg = GP_ARG_FIRST;
7926169689Skan  fparg = FP_ARG_FIRST;
7927169689Skan  for (f = (unsigned int) fp_code; f != 0; f >>= 2)
7928169689Skan    {
7929169689Skan      if ((f & 3) == 1)
7930169689Skan	{
7931169689Skan	  if ((fparg & 1) != 0)
7932169689Skan	    ++fparg;
7933169689Skan	  fprintf (file, "\t%s\t%s,%s\n", s,
7934169689Skan		   reg_names[gparg], reg_names[fparg]);
7935169689Skan	}
7936169689Skan      else if ((f & 3) == 2)
7937169689Skan	{
7938169689Skan	  if (TARGET_64BIT)
7939169689Skan	    fprintf (file, "\td%s\t%s,%s\n", s,
7940169689Skan		     reg_names[gparg], reg_names[fparg]);
7941169689Skan	  else
7942169689Skan	    {
7943169689Skan	      if ((fparg & 1) != 0)
7944169689Skan		++fparg;
7945169689Skan	      if (TARGET_BIG_ENDIAN)
7946169689Skan		fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
7947169689Skan			 reg_names[gparg], reg_names[fparg + 1], s,
7948169689Skan			 reg_names[gparg + 1], reg_names[fparg]);
7949169689Skan	      else
7950169689Skan		fprintf (file, "\t%s\t%s,%s\n\t%s\t%s,%s\n", s,
7951169689Skan			 reg_names[gparg], reg_names[fparg], s,
7952169689Skan			 reg_names[gparg + 1], reg_names[fparg + 1]);
7953169689Skan	      ++gparg;
7954169689Skan	      ++fparg;
7955169689Skan	    }
7956169689Skan	}
7957169689Skan      else
7958169689Skan	gcc_unreachable ();
7959169689Skan
7960169689Skan      ++gparg;
7961169689Skan      ++fparg;
7962169689Skan    }
7963169689Skan}
7964169689Skan
7965169689Skan/* Build a mips16 function stub.  This is used for functions which
7966169689Skan   take arguments in the floating point registers.  It is 32 bit code
7967169689Skan   that moves the floating point args into the general registers, and
7968169689Skan   then jumps to the 16 bit code.  */
7969169689Skan
7970169689Skanstatic void
7971169689Skanbuild_mips16_function_stub (FILE *file)
7972169689Skan{
7973169689Skan  const char *fnname;
7974169689Skan  char *secname, *stubname;
7975169689Skan  tree stubid, stubdecl;
7976169689Skan  int need_comma;
7977169689Skan  unsigned int f;
7978169689Skan
7979169689Skan  fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
7980169689Skan  secname = (char *) alloca (strlen (fnname) + 20);
7981169689Skan  sprintf (secname, ".mips16.fn.%s", fnname);
7982169689Skan  stubname = (char *) alloca (strlen (fnname) + 20);
7983169689Skan  sprintf (stubname, "__fn_stub_%s", fnname);
7984169689Skan  stubid = get_identifier (stubname);
7985169689Skan  stubdecl = build_decl (FUNCTION_DECL, stubid,
7986169689Skan			 build_function_type (void_type_node, NULL_TREE));
7987169689Skan  DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
7988169689Skan
7989169689Skan  fprintf (file, "\t# Stub function for %s (", current_function_name ());
7990169689Skan  need_comma = 0;
7991169689Skan  for (f = (unsigned int) current_function_args_info.fp_code; f != 0; f >>= 2)
7992169689Skan    {
7993169689Skan      fprintf (file, "%s%s",
7994169689Skan	       need_comma ? ", " : "",
7995169689Skan	       (f & 3) == 1 ? "float" : "double");
7996169689Skan      need_comma = 1;
7997169689Skan    }
7998169689Skan  fprintf (file, ")\n");
7999169689Skan
8000169689Skan  fprintf (file, "\t.set\tnomips16\n");
8001169689Skan  switch_to_section (function_section (stubdecl));
8002169689Skan  ASM_OUTPUT_ALIGN (file, floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT));
8003169689Skan
8004169689Skan  /* ??? If FUNCTION_NAME_ALREADY_DECLARED is defined, then we are
8005169689Skan     within a .ent, and we cannot emit another .ent.  */
8006169689Skan  if (!FUNCTION_NAME_ALREADY_DECLARED)
8007169689Skan    {
8008169689Skan      fputs ("\t.ent\t", file);
8009169689Skan      assemble_name (file, stubname);
8010169689Skan      fputs ("\n", file);
8011169689Skan    }
8012169689Skan
8013169689Skan  assemble_name (file, stubname);
8014169689Skan  fputs (":\n", file);
8015169689Skan
8016169689Skan  /* We don't want the assembler to insert any nops here.  */
8017169689Skan  fprintf (file, "\t.set\tnoreorder\n");
8018169689Skan
8019169689Skan  mips16_fp_args (file, current_function_args_info.fp_code, 1);
8020169689Skan
8021169689Skan  fprintf (asm_out_file, "\t.set\tnoat\n");
8022169689Skan  fprintf (asm_out_file, "\tla\t%s,", reg_names[GP_REG_FIRST + 1]);
8023169689Skan  assemble_name (file, fnname);
8024169689Skan  fprintf (file, "\n");
8025169689Skan  fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 1]);
8026169689Skan  fprintf (asm_out_file, "\t.set\tat\n");
8027169689Skan
8028169689Skan  /* Unfortunately, we can't fill the jump delay slot.  We can't fill
8029169689Skan     with one of the mfc1 instructions, because the result is not
8030169689Skan     available for one instruction, so if the very first instruction
8031169689Skan     in the function refers to the register, it will see the wrong
8032169689Skan     value.  */
8033169689Skan  fprintf (file, "\tnop\n");
8034169689Skan
8035169689Skan  fprintf (file, "\t.set\treorder\n");
8036169689Skan
8037169689Skan  if (!FUNCTION_NAME_ALREADY_DECLARED)
8038169689Skan    {
8039169689Skan      fputs ("\t.end\t", file);
8040169689Skan      assemble_name (file, stubname);
8041169689Skan      fputs ("\n", file);
8042169689Skan    }
8043169689Skan
8044169689Skan  fprintf (file, "\t.set\tmips16\n");
8045169689Skan
8046169689Skan  switch_to_section (function_section (current_function_decl));
8047169689Skan}
8048169689Skan
8049169689Skan/* We keep a list of functions for which we have already built stubs
8050169689Skan   in build_mips16_call_stub.  */
8051169689Skan
8052169689Skanstruct mips16_stub
8053169689Skan{
8054169689Skan  struct mips16_stub *next;
8055169689Skan  char *name;
8056169689Skan  int fpret;
8057169689Skan};
8058169689Skan
8059169689Skanstatic struct mips16_stub *mips16_stubs;
8060169689Skan
8061169689Skan/* Build a call stub for a mips16 call.  A stub is needed if we are
8062169689Skan   passing any floating point values which should go into the floating
8063169689Skan   point registers.  If we are, and the call turns out to be to a 32
8064169689Skan   bit function, the stub will be used to move the values into the
8065169689Skan   floating point registers before calling the 32 bit function.  The
8066169689Skan   linker will magically adjust the function call to either the 16 bit
8067169689Skan   function or the 32 bit stub, depending upon where the function call
8068169689Skan   is actually defined.
8069169689Skan
8070169689Skan   Similarly, we need a stub if the return value might come back in a
8071169689Skan   floating point register.
8072169689Skan
8073169689Skan   RETVAL is the location of the return value, or null if this is
8074169689Skan   a call rather than a call_value.  FN is the address of the
8075169689Skan   function and ARG_SIZE is the size of the arguments.  FP_CODE
8076169689Skan   is the code built by function_arg.  This function returns a nonzero
8077169689Skan   value if it builds the call instruction itself.  */
8078169689Skan
8079169689Skanint
8080169689Skanbuild_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
8081169689Skan{
8082169689Skan  int fpret;
8083169689Skan  const char *fnname;
8084169689Skan  char *secname, *stubname;
8085169689Skan  struct mips16_stub *l;
8086169689Skan  tree stubid, stubdecl;
8087169689Skan  int need_comma;
8088169689Skan  unsigned int f;
8089169689Skan
8090169689Skan  /* We don't need to do anything if we aren't in mips16 mode, or if
8091169689Skan     we were invoked with the -msoft-float option.  */
8092169689Skan  if (! TARGET_MIPS16 || ! mips16_hard_float)
8093169689Skan    return 0;
8094169689Skan
8095169689Skan  /* Figure out whether the value might come back in a floating point
8096169689Skan     register.  */
8097169689Skan  fpret = (retval != 0
8098169689Skan	   && GET_MODE_CLASS (GET_MODE (retval)) == MODE_FLOAT
8099169689Skan	   && GET_MODE_SIZE (GET_MODE (retval)) <= UNITS_PER_FPVALUE);
8100169689Skan
8101169689Skan  /* We don't need to do anything if there were no floating point
8102169689Skan     arguments and the value will not be returned in a floating point
8103169689Skan     register.  */
8104169689Skan  if (fp_code == 0 && ! fpret)
8105169689Skan    return 0;
8106169689Skan
8107169689Skan  /* We don't need to do anything if this is a call to a special
8108169689Skan     mips16 support function.  */
8109169689Skan  if (GET_CODE (fn) == SYMBOL_REF
8110169689Skan      && strncmp (XSTR (fn, 0), "__mips16_", 9) == 0)
8111169689Skan    return 0;
8112169689Skan
8113169689Skan  /* This code will only work for o32 and o64 abis.  The other ABI's
8114169689Skan     require more sophisticated support.  */
8115169689Skan  gcc_assert (TARGET_OLDABI);
8116169689Skan
8117169689Skan  /* We can only handle SFmode and DFmode floating point return
8118169689Skan     values.  */
8119169689Skan  if (fpret)
8120169689Skan    gcc_assert (GET_MODE (retval) == SFmode || GET_MODE (retval) == DFmode);
8121169689Skan
8122169689Skan  /* If we're calling via a function pointer, then we must always call
8123169689Skan     via a stub.  There are magic stubs provided in libgcc.a for each
8124169689Skan     of the required cases.  Each of them expects the function address
8125169689Skan     to arrive in register $2.  */
8126169689Skan
8127169689Skan  if (GET_CODE (fn) != SYMBOL_REF)
8128169689Skan    {
8129169689Skan      char buf[30];
8130169689Skan      tree id;
8131169689Skan      rtx stub_fn, insn;
8132169689Skan
8133169689Skan      /* ??? If this code is modified to support other ABI's, we need
8134169689Skan         to handle PARALLEL return values here.  */
8135169689Skan
8136169689Skan      sprintf (buf, "__mips16_call_stub_%s%d",
8137169689Skan	       (fpret
8138169689Skan		? (GET_MODE (retval) == SFmode ? "sf_" : "df_")
8139169689Skan		: ""),
8140169689Skan	       fp_code);
8141169689Skan      id = get_identifier (buf);
8142169689Skan      stub_fn = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (id));
8143169689Skan
8144169689Skan      emit_move_insn (gen_rtx_REG (Pmode, 2), fn);
8145169689Skan
8146169689Skan      if (retval == NULL_RTX)
8147169689Skan	insn = gen_call_internal (stub_fn, arg_size);
8148169689Skan      else
8149169689Skan	insn = gen_call_value_internal (retval, stub_fn, arg_size);
8150169689Skan      insn = emit_call_insn (insn);
8151169689Skan
8152169689Skan      /* Put the register usage information on the CALL.  */
8153169689Skan      CALL_INSN_FUNCTION_USAGE (insn) =
8154169689Skan	gen_rtx_EXPR_LIST (VOIDmode,
8155169689Skan			   gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 2)),
8156169689Skan			   CALL_INSN_FUNCTION_USAGE (insn));
8157169689Skan
8158169689Skan      /* If we are handling a floating point return value, we need to
8159169689Skan         save $18 in the function prologue.  Putting a note on the
8160169689Skan         call will mean that regs_ever_live[$18] will be true if the
8161169689Skan         call is not eliminated, and we can check that in the prologue
8162169689Skan         code.  */
8163169689Skan      if (fpret)
8164169689Skan	CALL_INSN_FUNCTION_USAGE (insn) =
8165169689Skan	  gen_rtx_EXPR_LIST (VOIDmode,
8166169689Skan			     gen_rtx_USE (VOIDmode,
8167169689Skan					  gen_rtx_REG (word_mode, 18)),
8168169689Skan			     CALL_INSN_FUNCTION_USAGE (insn));
8169169689Skan
8170169689Skan      /* Return 1 to tell the caller that we've generated the call
8171169689Skan         insn.  */
8172169689Skan      return 1;
8173169689Skan    }
8174169689Skan
8175169689Skan  /* We know the function we are going to call.  If we have already
8176169689Skan     built a stub, we don't need to do anything further.  */
8177169689Skan
8178169689Skan  fnname = XSTR (fn, 0);
8179169689Skan  for (l = mips16_stubs; l != NULL; l = l->next)
8180169689Skan    if (strcmp (l->name, fnname) == 0)
8181169689Skan      break;
8182169689Skan
8183169689Skan  if (l == NULL)
8184169689Skan    {
8185169689Skan      /* Build a special purpose stub.  When the linker sees a
8186169689Skan	 function call in mips16 code, it will check where the target
8187169689Skan	 is defined.  If the target is a 32 bit call, the linker will
8188169689Skan	 search for the section defined here.  It can tell which
8189169689Skan	 symbol this section is associated with by looking at the
8190169689Skan	 relocation information (the name is unreliable, since this
8191169689Skan	 might be a static function).  If such a section is found, the
8192169689Skan	 linker will redirect the call to the start of the magic
8193169689Skan	 section.
8194169689Skan
8195169689Skan	 If the function does not return a floating point value, the
8196169689Skan	 special stub section is named
8197169689Skan	     .mips16.call.FNNAME
8198169689Skan
8199169689Skan	 If the function does return a floating point value, the stub
8200169689Skan	 section is named
8201169689Skan	     .mips16.call.fp.FNNAME
8202169689Skan	 */
8203169689Skan
8204169689Skan      secname = (char *) alloca (strlen (fnname) + 40);
8205169689Skan      sprintf (secname, ".mips16.call.%s%s",
8206169689Skan	       fpret ? "fp." : "",
8207169689Skan	       fnname);
8208169689Skan      stubname = (char *) alloca (strlen (fnname) + 20);
8209169689Skan      sprintf (stubname, "__call_stub_%s%s",
8210169689Skan	       fpret ? "fp_" : "",
8211169689Skan	       fnname);
8212169689Skan      stubid = get_identifier (stubname);
8213169689Skan      stubdecl = build_decl (FUNCTION_DECL, stubid,
8214169689Skan			     build_function_type (void_type_node, NULL_TREE));
8215169689Skan      DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
8216169689Skan
8217169689Skan      fprintf (asm_out_file, "\t# Stub function to call %s%s (",
8218169689Skan	       (fpret
8219169689Skan		? (GET_MODE (retval) == SFmode ? "float " : "double ")
8220169689Skan		: ""),
8221169689Skan	       fnname);
8222169689Skan      need_comma = 0;
8223169689Skan      for (f = (unsigned int) fp_code; f != 0; f >>= 2)
8224169689Skan	{
8225169689Skan	  fprintf (asm_out_file, "%s%s",
8226169689Skan		   need_comma ? ", " : "",
8227169689Skan		   (f & 3) == 1 ? "float" : "double");
8228169689Skan	  need_comma = 1;
8229169689Skan	}
8230169689Skan      fprintf (asm_out_file, ")\n");
8231169689Skan
8232169689Skan      fprintf (asm_out_file, "\t.set\tnomips16\n");
8233169689Skan      assemble_start_function (stubdecl, stubname);
8234169689Skan
8235169689Skan      if (!FUNCTION_NAME_ALREADY_DECLARED)
8236169689Skan	{
8237169689Skan	  fputs ("\t.ent\t", asm_out_file);
8238169689Skan	  assemble_name (asm_out_file, stubname);
8239169689Skan	  fputs ("\n", asm_out_file);
8240169689Skan
8241169689Skan	  assemble_name (asm_out_file, stubname);
8242169689Skan	  fputs (":\n", asm_out_file);
8243169689Skan	}
8244169689Skan
8245169689Skan      /* We build the stub code by hand.  That's the only way we can
8246169689Skan	 do it, since we can't generate 32 bit code during a 16 bit
8247169689Skan	 compilation.  */
8248169689Skan
8249169689Skan      /* We don't want the assembler to insert any nops here.  */
8250169689Skan      fprintf (asm_out_file, "\t.set\tnoreorder\n");
8251169689Skan
8252169689Skan      mips16_fp_args (asm_out_file, fp_code, 0);
8253169689Skan
8254169689Skan      if (! fpret)
8255169689Skan	{
8256169689Skan	  fprintf (asm_out_file, "\t.set\tnoat\n");
8257169689Skan	  fprintf (asm_out_file, "\tla\t%s,%s\n", reg_names[GP_REG_FIRST + 1],
8258169689Skan		   fnname);
8259169689Skan	  fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 1]);
8260169689Skan	  fprintf (asm_out_file, "\t.set\tat\n");
8261169689Skan	  /* Unfortunately, we can't fill the jump delay slot.  We
8262169689Skan	     can't fill with one of the mtc1 instructions, because the
8263169689Skan	     result is not available for one instruction, so if the
8264169689Skan	     very first instruction in the function refers to the
8265169689Skan	     register, it will see the wrong value.  */
8266169689Skan	  fprintf (asm_out_file, "\tnop\n");
8267169689Skan	}
8268169689Skan      else
8269169689Skan	{
8270169689Skan	  fprintf (asm_out_file, "\tmove\t%s,%s\n",
8271169689Skan		   reg_names[GP_REG_FIRST + 18], reg_names[GP_REG_FIRST + 31]);
8272169689Skan	  fprintf (asm_out_file, "\tjal\t%s\n", fnname);
8273169689Skan	  /* As above, we can't fill the delay slot.  */
8274169689Skan	  fprintf (asm_out_file, "\tnop\n");
8275169689Skan	  if (GET_MODE (retval) == SFmode)
8276169689Skan	    fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
8277169689Skan		     reg_names[GP_REG_FIRST + 2], reg_names[FP_REG_FIRST + 0]);
8278169689Skan	  else
8279169689Skan	    {
8280169689Skan	      if (TARGET_BIG_ENDIAN)
8281169689Skan		{
8282169689Skan		  fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
8283169689Skan			   reg_names[GP_REG_FIRST + 2],
8284169689Skan			   reg_names[FP_REG_FIRST + 1]);
8285169689Skan		  fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
8286169689Skan			   reg_names[GP_REG_FIRST + 3],
8287169689Skan			   reg_names[FP_REG_FIRST + 0]);
8288169689Skan		}
8289169689Skan	      else
8290169689Skan		{
8291169689Skan		  fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
8292169689Skan			   reg_names[GP_REG_FIRST + 2],
8293169689Skan			   reg_names[FP_REG_FIRST + 0]);
8294169689Skan		  fprintf (asm_out_file, "\tmfc1\t%s,%s\n",
8295169689Skan			   reg_names[GP_REG_FIRST + 3],
8296169689Skan			   reg_names[FP_REG_FIRST + 1]);
8297169689Skan		}
8298169689Skan	    }
8299169689Skan	  fprintf (asm_out_file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 18]);
8300169689Skan	  /* As above, we can't fill the delay slot.  */
8301169689Skan	  fprintf (asm_out_file, "\tnop\n");
8302169689Skan	}
8303169689Skan
8304169689Skan      fprintf (asm_out_file, "\t.set\treorder\n");
8305169689Skan
8306169689Skan#ifdef ASM_DECLARE_FUNCTION_SIZE
8307169689Skan      ASM_DECLARE_FUNCTION_SIZE (asm_out_file, stubname, stubdecl);
8308169689Skan#endif
8309169689Skan
8310169689Skan      if (!FUNCTION_NAME_ALREADY_DECLARED)
8311169689Skan	{
8312169689Skan	  fputs ("\t.end\t", asm_out_file);
8313169689Skan	  assemble_name (asm_out_file, stubname);
8314169689Skan	  fputs ("\n", asm_out_file);
8315169689Skan	}
8316169689Skan
8317169689Skan      fprintf (asm_out_file, "\t.set\tmips16\n");
8318169689Skan
8319169689Skan      /* Record this stub.  */
8320169689Skan      l = (struct mips16_stub *) xmalloc (sizeof *l);
8321169689Skan      l->name = xstrdup (fnname);
8322169689Skan      l->fpret = fpret;
8323169689Skan      l->next = mips16_stubs;
8324169689Skan      mips16_stubs = l;
8325169689Skan    }
8326169689Skan
8327169689Skan  /* If we expect a floating point return value, but we've built a
8328169689Skan     stub which does not expect one, then we're in trouble.  We can't
8329169689Skan     use the existing stub, because it won't handle the floating point
8330169689Skan     value.  We can't build a new stub, because the linker won't know
8331169689Skan     which stub to use for the various calls in this object file.
8332169689Skan     Fortunately, this case is illegal, since it means that a function
8333169689Skan     was declared in two different ways in a single compilation.  */
8334169689Skan  if (fpret && ! l->fpret)
8335169689Skan    error ("cannot handle inconsistent calls to %qs", fnname);
8336169689Skan
8337169689Skan  /* If we are calling a stub which handles a floating point return
8338169689Skan     value, we need to arrange to save $18 in the prologue.  We do
8339169689Skan     this by marking the function call as using the register.  The
8340169689Skan     prologue will later see that it is used, and emit code to save
8341169689Skan     it.  */
8342169689Skan
8343169689Skan  if (l->fpret)
8344169689Skan    {
8345169689Skan      rtx insn;
8346169689Skan
8347169689Skan      if (retval == NULL_RTX)
8348169689Skan	insn = gen_call_internal (fn, arg_size);
8349169689Skan      else
8350169689Skan	insn = gen_call_value_internal (retval, fn, arg_size);
8351169689Skan      insn = emit_call_insn (insn);
8352169689Skan
8353169689Skan      CALL_INSN_FUNCTION_USAGE (insn) =
8354169689Skan	gen_rtx_EXPR_LIST (VOIDmode,
8355169689Skan			   gen_rtx_USE (VOIDmode, gen_rtx_REG (word_mode, 18)),
8356169689Skan			   CALL_INSN_FUNCTION_USAGE (insn));
8357169689Skan
8358169689Skan      /* Return 1 to tell the caller that we've generated the call
8359169689Skan         insn.  */
8360169689Skan      return 1;
8361169689Skan    }
8362169689Skan
8363169689Skan  /* Return 0 to let the caller generate the call insn.  */
8364169689Skan  return 0;
8365169689Skan}
8366169689Skan
8367169689Skan/* An entry in the mips16 constant pool.  VALUE is the pool constant,
8368169689Skan   MODE is its mode, and LABEL is the CODE_LABEL associated with it.  */
8369169689Skan
8370169689Skanstruct mips16_constant {
8371169689Skan  struct mips16_constant *next;
8372169689Skan  rtx value;
8373169689Skan  rtx label;
8374169689Skan  enum machine_mode mode;
8375169689Skan};
8376169689Skan
8377169689Skan/* Information about an incomplete mips16 constant pool.  FIRST is the
8378169689Skan   first constant, HIGHEST_ADDRESS is the highest address that the first
8379169689Skan   byte of the pool can have, and INSN_ADDRESS is the current instruction
8380169689Skan   address.  */
8381169689Skan
8382169689Skanstruct mips16_constant_pool {
8383169689Skan  struct mips16_constant *first;
8384169689Skan  int highest_address;
8385169689Skan  int insn_address;
8386169689Skan};
8387169689Skan
8388169689Skan/* Add constant VALUE to POOL and return its label.  MODE is the
8389169689Skan   value's mode (used for CONST_INTs, etc.).  */
8390169689Skan
8391169689Skanstatic rtx
8392169689Skanadd_constant (struct mips16_constant_pool *pool,
8393169689Skan	      rtx value, enum machine_mode mode)
8394169689Skan{
8395169689Skan  struct mips16_constant **p, *c;
8396169689Skan  bool first_of_size_p;
8397169689Skan
8398169689Skan  /* See whether the constant is already in the pool.  If so, return the
8399169689Skan     existing label, otherwise leave P pointing to the place where the
8400169689Skan     constant should be added.
8401169689Skan
8402169689Skan     Keep the pool sorted in increasing order of mode size so that we can
8403169689Skan     reduce the number of alignments needed.  */
8404169689Skan  first_of_size_p = true;
8405169689Skan  for (p = &pool->first; *p != 0; p = &(*p)->next)
8406169689Skan    {
8407169689Skan      if (mode == (*p)->mode && rtx_equal_p (value, (*p)->value))
8408169689Skan	return (*p)->label;
8409169689Skan      if (GET_MODE_SIZE (mode) < GET_MODE_SIZE ((*p)->mode))
8410169689Skan	break;
8411169689Skan      if (GET_MODE_SIZE (mode) == GET_MODE_SIZE ((*p)->mode))
8412169689Skan	first_of_size_p = false;
8413169689Skan    }
8414169689Skan
8415169689Skan  /* In the worst case, the constant needed by the earliest instruction
8416169689Skan     will end up at the end of the pool.  The entire pool must then be
8417169689Skan     accessible from that instruction.
8418169689Skan
8419169689Skan     When adding the first constant, set the pool's highest address to
8420169689Skan     the address of the first out-of-range byte.  Adjust this address
8421169689Skan     downwards each time a new constant is added.  */
8422169689Skan  if (pool->first == 0)
8423169689Skan    /* For pc-relative lw, addiu and daddiu instructions, the base PC value
8424169689Skan       is the address of the instruction with the lowest two bits clear.
8425169689Skan       The base PC value for ld has the lowest three bits clear.  Assume
8426169689Skan       the worst case here.  */
8427169689Skan    pool->highest_address = pool->insn_address - (UNITS_PER_WORD - 2) + 0x8000;
8428169689Skan  pool->highest_address -= GET_MODE_SIZE (mode);
8429169689Skan  if (first_of_size_p)
8430169689Skan    /* Take into account the worst possible padding due to alignment.  */
8431169689Skan    pool->highest_address -= GET_MODE_SIZE (mode) - 1;
8432169689Skan
8433169689Skan  /* Create a new entry.  */
8434169689Skan  c = (struct mips16_constant *) xmalloc (sizeof *c);
8435169689Skan  c->value = value;
8436169689Skan  c->mode = mode;
8437169689Skan  c->label = gen_label_rtx ();
8438169689Skan  c->next = *p;
8439169689Skan  *p = c;
8440169689Skan
8441169689Skan  return c->label;
8442169689Skan}
8443169689Skan
8444169689Skan/* Output constant VALUE after instruction INSN and return the last
8445169689Skan   instruction emitted.  MODE is the mode of the constant.  */
8446169689Skan
8447169689Skanstatic rtx
8448169689Skandump_constants_1 (enum machine_mode mode, rtx value, rtx insn)
8449169689Skan{
8450169689Skan  switch (GET_MODE_CLASS (mode))
8451169689Skan    {
8452169689Skan    case MODE_INT:
8453169689Skan      {
8454169689Skan	rtx size = GEN_INT (GET_MODE_SIZE (mode));
8455169689Skan	return emit_insn_after (gen_consttable_int (value, size), insn);
8456169689Skan      }
8457169689Skan
8458169689Skan    case MODE_FLOAT:
8459169689Skan      return emit_insn_after (gen_consttable_float (value), insn);
8460169689Skan
8461169689Skan    case MODE_VECTOR_FLOAT:
8462169689Skan    case MODE_VECTOR_INT:
8463169689Skan      {
8464169689Skan	int i;
8465169689Skan	for (i = 0; i < CONST_VECTOR_NUNITS (value); i++)
8466169689Skan	  insn = dump_constants_1 (GET_MODE_INNER (mode),
8467169689Skan				   CONST_VECTOR_ELT (value, i), insn);
8468169689Skan	return insn;
8469169689Skan      }
8470169689Skan
8471169689Skan    default:
8472169689Skan      gcc_unreachable ();
8473169689Skan    }
8474169689Skan}
8475169689Skan
8476169689Skan
8477169689Skan/* Dump out the constants in CONSTANTS after INSN.  */
8478169689Skan
8479169689Skanstatic void
8480169689Skandump_constants (struct mips16_constant *constants, rtx insn)
8481169689Skan{
8482169689Skan  struct mips16_constant *c, *next;
8483169689Skan  int align;
8484169689Skan
8485169689Skan  align = 0;
8486169689Skan  for (c = constants; c != NULL; c = next)
8487169689Skan    {
8488169689Skan      /* If necessary, increase the alignment of PC.  */
8489169689Skan      if (align < GET_MODE_SIZE (c->mode))
8490169689Skan	{
8491169689Skan	  int align_log = floor_log2 (GET_MODE_SIZE (c->mode));
8492169689Skan	  insn = emit_insn_after (gen_align (GEN_INT (align_log)), insn);
8493169689Skan	}
8494169689Skan      align = GET_MODE_SIZE (c->mode);
8495169689Skan
8496169689Skan      insn = emit_label_after (c->label, insn);
8497169689Skan      insn = dump_constants_1 (c->mode, c->value, insn);
8498169689Skan
8499169689Skan      next = c->next;
8500169689Skan      free (c);
8501169689Skan    }
8502169689Skan
8503169689Skan  emit_barrier_after (insn);
8504169689Skan}
8505169689Skan
8506169689Skan/* Return the length of instruction INSN.  */
8507169689Skan
8508169689Skanstatic int
8509169689Skanmips16_insn_length (rtx insn)
8510169689Skan{
8511169689Skan  if (JUMP_P (insn))
8512169689Skan    {
8513169689Skan      rtx body = PATTERN (insn);
8514169689Skan      if (GET_CODE (body) == ADDR_VEC)
8515169689Skan	return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 0);
8516169689Skan      if (GET_CODE (body) == ADDR_DIFF_VEC)
8517169689Skan	return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, 1);
8518169689Skan    }
8519169689Skan  return get_attr_length (insn);
8520169689Skan}
8521169689Skan
8522169689Skan/* Rewrite *X so that constant pool references refer to the constant's
8523169689Skan   label instead.  DATA points to the constant pool structure.  */
8524169689Skan
8525169689Skanstatic int
8526169689Skanmips16_rewrite_pool_refs (rtx *x, void *data)
8527169689Skan{
8528169689Skan  struct mips16_constant_pool *pool = data;
8529169689Skan  if (GET_CODE (*x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (*x))
8530169689Skan    *x = gen_rtx_LABEL_REF (Pmode, add_constant (pool,
8531169689Skan						 get_pool_constant (*x),
8532169689Skan						 get_pool_mode (*x)));
8533169689Skan  return 0;
8534169689Skan}
8535169689Skan
8536169689Skan/* Build MIPS16 constant pools.  */
8537169689Skan
8538169689Skanstatic void
8539169689Skanmips16_lay_out_constants (void)
8540169689Skan{
8541169689Skan  struct mips16_constant_pool pool;
8542169689Skan  rtx insn, barrier;
8543169689Skan
8544169689Skan  barrier = 0;
8545169689Skan  memset (&pool, 0, sizeof (pool));
8546169689Skan  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8547169689Skan    {
8548169689Skan      /* Rewrite constant pool references in INSN.  */
8549169689Skan      if (INSN_P (insn))
8550169689Skan	for_each_rtx (&PATTERN (insn), mips16_rewrite_pool_refs, &pool);
8551169689Skan
8552169689Skan      pool.insn_address += mips16_insn_length (insn);
8553169689Skan
8554169689Skan      if (pool.first != NULL)
8555169689Skan	{
8556169689Skan	  /* If there are no natural barriers between the first user of
8557169689Skan	     the pool and the highest acceptable address, we'll need to
8558169689Skan	     create a new instruction to jump around the constant pool.
8559169689Skan	     In the worst case, this instruction will be 4 bytes long.
8560169689Skan
8561169689Skan	     If it's too late to do this transformation after INSN,
8562169689Skan	     do it immediately before INSN.  */
8563169689Skan	  if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
8564169689Skan	    {
8565169689Skan	      rtx label, jump;
8566169689Skan
8567169689Skan	      label = gen_label_rtx ();
8568169689Skan
8569169689Skan	      jump = emit_jump_insn_before (gen_jump (label), insn);
8570169689Skan	      JUMP_LABEL (jump) = label;
8571169689Skan	      LABEL_NUSES (label) = 1;
8572169689Skan	      barrier = emit_barrier_after (jump);
8573169689Skan
8574169689Skan	      emit_label_after (label, barrier);
8575169689Skan	      pool.insn_address += 4;
8576169689Skan	    }
8577169689Skan
8578169689Skan	  /* See whether the constant pool is now out of range of the first
8579169689Skan	     user.  If so, output the constants after the previous barrier.
8580169689Skan	     Note that any instructions between BARRIER and INSN (inclusive)
8581169689Skan	     will use negative offsets to refer to the pool.  */
8582169689Skan	  if (pool.insn_address > pool.highest_address)
8583169689Skan	    {
8584169689Skan	      dump_constants (pool.first, barrier);
8585169689Skan	      pool.first = NULL;
8586169689Skan	      barrier = 0;
8587169689Skan	    }
8588169689Skan	  else if (BARRIER_P (insn))
8589169689Skan	    barrier = insn;
8590169689Skan	}
8591169689Skan    }
8592169689Skan  dump_constants (pool.first, get_last_insn ());
8593169689Skan}
8594169689Skan
8595169689Skan/* A temporary variable used by for_each_rtx callbacks, etc.  */
8596169689Skanstatic rtx mips_sim_insn;
8597169689Skan
8598169689Skan/* A structure representing the state of the processor pipeline.
8599169689Skan   Used by the mips_sim_* family of functions.  */
8600169689Skanstruct mips_sim {
8601169689Skan  /* The maximum number of instructions that can be issued in a cycle.
8602169689Skan     (Caches mips_issue_rate.)  */
8603169689Skan  unsigned int issue_rate;
8604169689Skan
8605169689Skan  /* The current simulation time.  */
8606169689Skan  unsigned int time;
8607169689Skan
8608169689Skan  /* How many more instructions can be issued in the current cycle.  */
8609169689Skan  unsigned int insns_left;
8610169689Skan
8611169689Skan  /* LAST_SET[X].INSN is the last instruction to set register X.
8612169689Skan     LAST_SET[X].TIME is the time at which that instruction was issued.
8613169689Skan     INSN is null if no instruction has yet set register X.  */
8614169689Skan  struct {
8615169689Skan    rtx insn;
8616169689Skan    unsigned int time;
8617169689Skan  } last_set[FIRST_PSEUDO_REGISTER];
8618169689Skan
8619169689Skan  /* The pipeline's current DFA state.  */
8620169689Skan  state_t dfa_state;
8621169689Skan};
8622169689Skan
8623169689Skan/* Reset STATE to the initial simulation state.  */
8624169689Skan
8625169689Skanstatic void
8626169689Skanmips_sim_reset (struct mips_sim *state)
8627169689Skan{
8628169689Skan  state->time = 0;
8629169689Skan  state->insns_left = state->issue_rate;
8630169689Skan  memset (&state->last_set, 0, sizeof (state->last_set));
8631169689Skan  state_reset (state->dfa_state);
8632169689Skan}
8633169689Skan
8634169689Skan/* Initialize STATE before its first use.  DFA_STATE points to an
8635169689Skan   allocated but uninitialized DFA state.  */
8636169689Skan
8637169689Skanstatic void
8638169689Skanmips_sim_init (struct mips_sim *state, state_t dfa_state)
8639169689Skan{
8640169689Skan  state->issue_rate = mips_issue_rate ();
8641169689Skan  state->dfa_state = dfa_state;
8642169689Skan  mips_sim_reset (state);
8643169689Skan}
8644169689Skan
8645169689Skan/* Advance STATE by one clock cycle.  */
8646169689Skan
8647169689Skanstatic void
8648169689Skanmips_sim_next_cycle (struct mips_sim *state)
8649169689Skan{
8650169689Skan  state->time++;
8651169689Skan  state->insns_left = state->issue_rate;
8652169689Skan  state_transition (state->dfa_state, 0);
8653169689Skan}
8654169689Skan
8655169689Skan/* Advance simulation state STATE until instruction INSN can read
8656169689Skan   register REG.  */
8657169689Skan
8658169689Skanstatic void
8659169689Skanmips_sim_wait_reg (struct mips_sim *state, rtx insn, rtx reg)
8660169689Skan{
8661169689Skan  unsigned int i;
8662169689Skan
8663169689Skan  for (i = 0; i < HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)); i++)
8664169689Skan    if (state->last_set[REGNO (reg) + i].insn != 0)
8665169689Skan      {
8666169689Skan	unsigned int t;
8667169689Skan
8668169689Skan	t = state->last_set[REGNO (reg) + i].time;
8669169689Skan	t += insn_latency (state->last_set[REGNO (reg) + i].insn, insn);
8670169689Skan	while (state->time < t)
8671169689Skan	  mips_sim_next_cycle (state);
8672169689Skan    }
8673169689Skan}
8674169689Skan
8675169689Skan/* A for_each_rtx callback.  If *X is a register, advance simulation state
8676169689Skan   DATA until mips_sim_insn can read the register's value.  */
8677169689Skan
8678169689Skanstatic int
8679169689Skanmips_sim_wait_regs_2 (rtx *x, void *data)
8680169689Skan{
8681169689Skan  if (REG_P (*x))
8682169689Skan    mips_sim_wait_reg (data, mips_sim_insn, *x);
8683169689Skan  return 0;
8684169689Skan}
8685169689Skan
8686169689Skan/* Call mips_sim_wait_regs_2 (R, DATA) for each register R mentioned in *X.  */
8687169689Skan
8688169689Skanstatic void
8689169689Skanmips_sim_wait_regs_1 (rtx *x, void *data)
8690169689Skan{
8691169689Skan  for_each_rtx (x, mips_sim_wait_regs_2, data);
8692169689Skan}
8693169689Skan
8694169689Skan/* Advance simulation state STATE until all of INSN's register
8695169689Skan   dependencies are satisfied.  */
8696169689Skan
8697169689Skanstatic void
8698169689Skanmips_sim_wait_regs (struct mips_sim *state, rtx insn)
8699169689Skan{
8700169689Skan  mips_sim_insn = insn;
8701169689Skan  note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
8702169689Skan}
8703169689Skan
8704169689Skan/* Advance simulation state STATE until the units required by
8705169689Skan   instruction INSN are available.  */
8706169689Skan
8707169689Skanstatic void
8708169689Skanmips_sim_wait_units (struct mips_sim *state, rtx insn)
8709169689Skan{
8710169689Skan  state_t tmp_state;
8711169689Skan
8712169689Skan  tmp_state = alloca (state_size ());
8713169689Skan  while (state->insns_left == 0
8714169689Skan	 || (memcpy (tmp_state, state->dfa_state, state_size ()),
8715169689Skan	     state_transition (tmp_state, insn) >= 0))
8716169689Skan    mips_sim_next_cycle (state);
8717169689Skan}
8718169689Skan
8719169689Skan/* Advance simulation state STATE until INSN is ready to issue.  */
8720169689Skan
8721169689Skanstatic void
8722169689Skanmips_sim_wait_insn (struct mips_sim *state, rtx insn)
8723169689Skan{
8724169689Skan  mips_sim_wait_regs (state, insn);
8725169689Skan  mips_sim_wait_units (state, insn);
8726169689Skan}
8727169689Skan
8728169689Skan/* mips_sim_insn has just set X.  Update the LAST_SET array
8729169689Skan   in simulation state DATA.  */
8730169689Skan
8731169689Skanstatic void
8732169689Skanmips_sim_record_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
8733169689Skan{
8734169689Skan  struct mips_sim *state;
8735169689Skan  unsigned int i;
8736169689Skan
8737169689Skan  state = data;
8738169689Skan  if (REG_P (x))
8739169689Skan    for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
8740169689Skan      {
8741169689Skan	state->last_set[REGNO (x) + i].insn = mips_sim_insn;
8742169689Skan	state->last_set[REGNO (x) + i].time = state->time;
8743169689Skan      }
8744169689Skan}
8745169689Skan
8746169689Skan/* Issue instruction INSN in scheduler state STATE.  Assume that INSN
8747169689Skan   can issue immediately (i.e., that mips_sim_wait_insn has already
8748169689Skan   been called).  */
8749169689Skan
8750169689Skanstatic void
8751169689Skanmips_sim_issue_insn (struct mips_sim *state, rtx insn)
8752169689Skan{
8753169689Skan  state_transition (state->dfa_state, insn);
8754169689Skan  state->insns_left--;
8755169689Skan
8756169689Skan  mips_sim_insn = insn;
8757169689Skan  note_stores (PATTERN (insn), mips_sim_record_set, state);
8758169689Skan}
8759169689Skan
8760169689Skan/* Simulate issuing a NOP in state STATE.  */
8761169689Skan
8762169689Skanstatic void
8763169689Skanmips_sim_issue_nop (struct mips_sim *state)
8764169689Skan{
8765169689Skan  if (state->insns_left == 0)
8766169689Skan    mips_sim_next_cycle (state);
8767169689Skan  state->insns_left--;
8768169689Skan}
8769169689Skan
8770169689Skan/* Update simulation state STATE so that it's ready to accept the instruction
8771169689Skan   after INSN.  INSN should be part of the main rtl chain, not a member of a
8772169689Skan   SEQUENCE.  */
8773169689Skan
8774169689Skanstatic void
8775169689Skanmips_sim_finish_insn (struct mips_sim *state, rtx insn)
8776169689Skan{
8777169689Skan  /* If INSN is a jump with an implicit delay slot, simulate a nop.  */
8778169689Skan  if (JUMP_P (insn))
8779169689Skan    mips_sim_issue_nop (state);
8780169689Skan
8781169689Skan  switch (GET_CODE (SEQ_BEGIN (insn)))
8782169689Skan    {
8783169689Skan    case CODE_LABEL:
8784169689Skan    case CALL_INSN:
8785169689Skan      /* We can't predict the processor state after a call or label.  */
8786169689Skan      mips_sim_reset (state);
8787169689Skan      break;
8788169689Skan
8789169689Skan    case JUMP_INSN:
8790169689Skan      /* The delay slots of branch likely instructions are only executed
8791169689Skan	 when the branch is taken.  Therefore, if the caller has simulated
8792169689Skan	 the delay slot instruction, STATE does not really reflect the state
8793169689Skan	 of the pipeline for the instruction after the delay slot.  Also,
8794169689Skan	 branch likely instructions tend to incur a penalty when not taken,
8795169689Skan	 so there will probably be an extra delay between the branch and
8796169689Skan	 the instruction after the delay slot.  */
8797169689Skan      if (INSN_ANNULLED_BRANCH_P (SEQ_BEGIN (insn)))
8798169689Skan	mips_sim_reset (state);
8799169689Skan      break;
8800169689Skan
8801169689Skan    default:
8802169689Skan      break;
8803169689Skan    }
8804169689Skan}
8805169689Skan
8806169689Skan/* The VR4130 pipeline issues aligned pairs of instructions together,
8807169689Skan   but it stalls the second instruction if it depends on the first.
8808169689Skan   In order to cut down the amount of logic required, this dependence
8809169689Skan   check is not based on a full instruction decode.  Instead, any non-SPECIAL
8810169689Skan   instruction is assumed to modify the register specified by bits 20-16
8811169689Skan   (which is usually the "rt" field).
8812169689Skan
8813169689Skan   In beq, beql, bne and bnel instructions, the rt field is actually an
8814169689Skan   input, so we can end up with a false dependence between the branch
8815169689Skan   and its delay slot.  If this situation occurs in instruction INSN,
8816169689Skan   try to avoid it by swapping rs and rt.  */
8817169689Skan
8818169689Skanstatic void
8819169689Skanvr4130_avoid_branch_rt_conflict (rtx insn)
8820169689Skan{
8821169689Skan  rtx first, second;
8822169689Skan
8823169689Skan  first = SEQ_BEGIN (insn);
8824169689Skan  second = SEQ_END (insn);
8825169689Skan  if (JUMP_P (first)
8826169689Skan      && NONJUMP_INSN_P (second)
8827169689Skan      && GET_CODE (PATTERN (first)) == SET
8828169689Skan      && GET_CODE (SET_DEST (PATTERN (first))) == PC
8829169689Skan      && GET_CODE (SET_SRC (PATTERN (first))) == IF_THEN_ELSE)
8830169689Skan    {
8831169689Skan      /* Check for the right kind of condition.  */
8832169689Skan      rtx cond = XEXP (SET_SRC (PATTERN (first)), 0);
8833169689Skan      if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
8834169689Skan	  && REG_P (XEXP (cond, 0))
8835169689Skan	  && REG_P (XEXP (cond, 1))
8836169689Skan	  && reg_referenced_p (XEXP (cond, 1), PATTERN (second))
8837169689Skan	  && !reg_referenced_p (XEXP (cond, 0), PATTERN (second)))
8838169689Skan	{
8839169689Skan	  /* SECOND mentions the rt register but not the rs register.  */
8840169689Skan	  rtx tmp = XEXP (cond, 0);
8841169689Skan	  XEXP (cond, 0) = XEXP (cond, 1);
8842169689Skan	  XEXP (cond, 1) = tmp;
8843169689Skan	}
8844169689Skan    }
8845169689Skan}
8846169689Skan
8847169689Skan/* Implement -mvr4130-align.  Go through each basic block and simulate the
8848169689Skan   processor pipeline.  If we find that a pair of instructions could execute
8849169689Skan   in parallel, and the first of those instruction is not 8-byte aligned,
8850169689Skan   insert a nop to make it aligned.  */
8851169689Skan
8852169689Skanstatic void
8853169689Skanvr4130_align_insns (void)
8854169689Skan{
8855169689Skan  struct mips_sim state;
8856169689Skan  rtx insn, subinsn, last, last2, next;
8857169689Skan  bool aligned_p;
8858169689Skan
8859169689Skan  dfa_start ();
8860169689Skan
8861169689Skan  /* LAST is the last instruction before INSN to have a nonzero length.
8862169689Skan     LAST2 is the last such instruction before LAST.  */
8863169689Skan  last = 0;
8864169689Skan  last2 = 0;
8865169689Skan
8866169689Skan  /* ALIGNED_P is true if INSN is known to be at an aligned address.  */
8867169689Skan  aligned_p = true;
8868169689Skan
8869169689Skan  mips_sim_init (&state, alloca (state_size ()));
8870169689Skan  for (insn = get_insns (); insn != 0; insn = next)
8871169689Skan    {
8872169689Skan      unsigned int length;
8873169689Skan
8874169689Skan      next = NEXT_INSN (insn);
8875169689Skan
8876169689Skan      /* See the comment above vr4130_avoid_branch_rt_conflict for details.
8877169689Skan	 This isn't really related to the alignment pass, but we do it on
8878169689Skan	 the fly to avoid a separate instruction walk.  */
8879169689Skan      vr4130_avoid_branch_rt_conflict (insn);
8880169689Skan
8881169689Skan      if (USEFUL_INSN_P (insn))
8882169689Skan	FOR_EACH_SUBINSN (subinsn, insn)
8883169689Skan	  {
8884169689Skan	    mips_sim_wait_insn (&state, subinsn);
8885169689Skan
8886169689Skan	    /* If we want this instruction to issue in parallel with the
8887169689Skan	       previous one, make sure that the previous instruction is
8888169689Skan	       aligned.  There are several reasons why this isn't worthwhile
8889169689Skan	       when the second instruction is a call:
8890169689Skan
8891169689Skan	          - Calls are less likely to be performance critical,
8892169689Skan		  - There's a good chance that the delay slot can execute
8893169689Skan		    in parallel with the call.
8894169689Skan	          - The return address would then be unaligned.
8895169689Skan
8896169689Skan	       In general, if we're going to insert a nop between instructions
8897169689Skan	       X and Y, it's better to insert it immediately after X.  That
8898169689Skan	       way, if the nop makes Y aligned, it will also align any labels
8899169689Skan	       between X and Y.  */
8900169689Skan	    if (state.insns_left != state.issue_rate
8901169689Skan		&& !CALL_P (subinsn))
8902169689Skan	      {
8903169689Skan		if (subinsn == SEQ_BEGIN (insn) && aligned_p)
8904169689Skan		  {
8905169689Skan		    /* SUBINSN is the first instruction in INSN and INSN is
8906169689Skan		       aligned.  We want to align the previous instruction
8907169689Skan		       instead, so insert a nop between LAST2 and LAST.
8908169689Skan
8909169689Skan		       Note that LAST could be either a single instruction
8910169689Skan		       or a branch with a delay slot.  In the latter case,
8911169689Skan		       LAST, like INSN, is already aligned, but the delay
8912169689Skan		       slot must have some extra delay that stops it from
8913169689Skan		       issuing at the same time as the branch.  We therefore
8914169689Skan		       insert a nop before the branch in order to align its
8915169689Skan		       delay slot.  */
8916169689Skan		    emit_insn_after (gen_nop (), last2);
8917169689Skan		    aligned_p = false;
8918169689Skan		  }
8919169689Skan		else if (subinsn != SEQ_BEGIN (insn) && !aligned_p)
8920169689Skan		  {
8921169689Skan		    /* SUBINSN is the delay slot of INSN, but INSN is
8922169689Skan		       currently unaligned.  Insert a nop between
8923169689Skan		       LAST and INSN to align it.  */
8924169689Skan		    emit_insn_after (gen_nop (), last);
8925169689Skan		    aligned_p = true;
8926169689Skan		  }
8927169689Skan	      }
8928169689Skan	    mips_sim_issue_insn (&state, subinsn);
8929169689Skan	  }
8930169689Skan      mips_sim_finish_insn (&state, insn);
8931169689Skan
8932169689Skan      /* Update LAST, LAST2 and ALIGNED_P for the next instruction.  */
8933169689Skan      length = get_attr_length (insn);
8934169689Skan      if (length > 0)
8935169689Skan	{
8936169689Skan	  /* If the instruction is an asm statement or multi-instruction
8937169689Skan	     mips.md patern, the length is only an estimate.  Insert an
8938169689Skan	     8 byte alignment after it so that the following instructions
8939169689Skan	     can be handled correctly.  */
8940169689Skan	  if (NONJUMP_INSN_P (SEQ_BEGIN (insn))
8941169689Skan	      && (recog_memoized (insn) < 0 || length >= 8))
8942169689Skan	    {
8943169689Skan	      next = emit_insn_after (gen_align (GEN_INT (3)), insn);
8944169689Skan	      next = NEXT_INSN (next);
8945169689Skan	      mips_sim_next_cycle (&state);
8946169689Skan	      aligned_p = true;
8947169689Skan	    }
8948169689Skan	  else if (length & 4)
8949169689Skan	    aligned_p = !aligned_p;
8950169689Skan	  last2 = last;
8951169689Skan	  last = insn;
8952169689Skan	}
8953169689Skan
8954169689Skan      /* See whether INSN is an aligned label.  */
8955169689Skan      if (LABEL_P (insn) && label_to_alignment (insn) >= 3)
8956169689Skan	aligned_p = true;
8957169689Skan    }
8958169689Skan  dfa_finish ();
8959169689Skan}
8960169689Skan
8961169689Skan/* Subroutine of mips_reorg.  If there is a hazard between INSN
8962169689Skan   and a previous instruction, avoid it by inserting nops after
8963169689Skan   instruction AFTER.
8964169689Skan
8965169689Skan   *DELAYED_REG and *HILO_DELAY describe the hazards that apply at
8966169689Skan   this point.  If *DELAYED_REG is non-null, INSN must wait a cycle
8967169689Skan   before using the value of that register.  *HILO_DELAY counts the
8968169689Skan   number of instructions since the last hilo hazard (that is,
8969169689Skan   the number of instructions since the last mflo or mfhi).
8970169689Skan
8971169689Skan   After inserting nops for INSN, update *DELAYED_REG and *HILO_DELAY
8972169689Skan   for the next instruction.
8973169689Skan
8974169689Skan   LO_REG is an rtx for the LO register, used in dependence checking.  */
8975169689Skan
8976169689Skanstatic void
8977169689Skanmips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
8978169689Skan		   rtx *delayed_reg, rtx lo_reg)
8979169689Skan{
8980169689Skan  rtx pattern, set;
8981169689Skan  int nops, ninsns;
8982169689Skan
8983169689Skan  if (!INSN_P (insn))
8984169689Skan    return;
8985169689Skan
8986169689Skan  pattern = PATTERN (insn);
8987169689Skan
8988169689Skan  /* Do not put the whole function in .set noreorder if it contains
8989169689Skan     an asm statement.  We don't know whether there will be hazards
8990169689Skan     between the asm statement and the gcc-generated code.  */
8991169689Skan  if (GET_CODE (pattern) == ASM_INPUT || asm_noperands (pattern) >= 0)
8992169689Skan    cfun->machine->all_noreorder_p = false;
8993169689Skan
8994169689Skan  /* Ignore zero-length instructions (barriers and the like).  */
8995169689Skan  ninsns = get_attr_length (insn) / 4;
8996169689Skan  if (ninsns == 0)
8997169689Skan    return;
8998169689Skan
8999169689Skan  /* Work out how many nops are needed.  Note that we only care about
9000169689Skan     registers that are explicitly mentioned in the instruction's pattern.
9001169689Skan     It doesn't matter that calls use the argument registers or that they
9002169689Skan     clobber hi and lo.  */
9003169689Skan  if (*hilo_delay < 2 && reg_set_p (lo_reg, pattern))
9004169689Skan    nops = 2 - *hilo_delay;
9005169689Skan  else if (*delayed_reg != 0 && reg_referenced_p (*delayed_reg, pattern))
9006169689Skan    nops = 1;
9007169689Skan  else
9008169689Skan    nops = 0;
9009169689Skan
9010169689Skan  /* Insert the nops between this instruction and the previous one.
9011169689Skan     Each new nop takes us further from the last hilo hazard.  */
9012169689Skan  *hilo_delay += nops;
9013169689Skan  while (nops-- > 0)
9014169689Skan    emit_insn_after (gen_hazard_nop (), after);
9015169689Skan
9016169689Skan  /* Set up the state for the next instruction.  */
9017169689Skan  *hilo_delay += ninsns;
9018169689Skan  *delayed_reg = 0;
9019169689Skan  if (INSN_CODE (insn) >= 0)
9020169689Skan    switch (get_attr_hazard (insn))
9021169689Skan      {
9022169689Skan      case HAZARD_NONE:
9023169689Skan	break;
9024169689Skan
9025169689Skan      case HAZARD_HILO:
9026169689Skan	*hilo_delay = 0;
9027169689Skan	break;
9028169689Skan
9029169689Skan      case HAZARD_DELAY:
9030169689Skan	set = single_set (insn);
9031169689Skan	gcc_assert (set != 0);
9032169689Skan	*delayed_reg = SET_DEST (set);
9033169689Skan	break;
9034169689Skan      }
9035169689Skan}
9036169689Skan
9037169689Skan
9038169689Skan/* Go through the instruction stream and insert nops where necessary.
9039169689Skan   See if the whole function can then be put into .set noreorder &
9040169689Skan   .set nomacro.  */
9041169689Skan
9042169689Skanstatic void
9043169689Skanmips_avoid_hazards (void)
9044169689Skan{
9045169689Skan  rtx insn, last_insn, lo_reg, delayed_reg;
9046169689Skan  int hilo_delay, i;
9047169689Skan
9048169689Skan  /* Force all instructions to be split into their final form.  */
9049169689Skan  split_all_insns_noflow ();
9050169689Skan
9051169689Skan  /* Recalculate instruction lengths without taking nops into account.  */
9052169689Skan  cfun->machine->ignore_hazard_length_p = true;
9053169689Skan  shorten_branches (get_insns ());
9054169689Skan
9055169689Skan  cfun->machine->all_noreorder_p = true;
9056169689Skan
9057169689Skan  /* Profiled functions can't be all noreorder because the profiler
9058169689Skan     support uses assembler macros.  */
9059169689Skan  if (current_function_profile)
9060169689Skan    cfun->machine->all_noreorder_p = false;
9061169689Skan
9062169689Skan  /* Code compiled with -mfix-vr4120 can't be all noreorder because
9063169689Skan     we rely on the assembler to work around some errata.  */
9064169689Skan  if (TARGET_FIX_VR4120)
9065169689Skan    cfun->machine->all_noreorder_p = false;
9066169689Skan
9067169689Skan  /* The same is true for -mfix-vr4130 if we might generate mflo or
9068169689Skan     mfhi instructions.  Note that we avoid using mflo and mfhi if
9069169689Skan     the VR4130 macc and dmacc instructions are available instead;
9070169689Skan     see the *mfhilo_{si,di}_macc patterns.  */
9071169689Skan  if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
9072169689Skan    cfun->machine->all_noreorder_p = false;
9073169689Skan
9074169689Skan  last_insn = 0;
9075169689Skan  hilo_delay = 2;
9076169689Skan  delayed_reg = 0;
9077169689Skan  lo_reg = gen_rtx_REG (SImode, LO_REGNUM);
9078169689Skan
9079169689Skan  for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
9080169689Skan    if (INSN_P (insn))
9081169689Skan      {
9082169689Skan	if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9083169689Skan	  for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9084169689Skan	    mips_avoid_hazard (last_insn, XVECEXP (PATTERN (insn), 0, i),
9085169689Skan			       &hilo_delay, &delayed_reg, lo_reg);
9086169689Skan	else
9087169689Skan	  mips_avoid_hazard (last_insn, insn, &hilo_delay,
9088169689Skan			     &delayed_reg, lo_reg);
9089169689Skan
9090169689Skan	last_insn = insn;
9091169689Skan      }
9092169689Skan}
9093169689Skan
9094169689Skan
9095169689Skan/* Implement TARGET_MACHINE_DEPENDENT_REORG.  */
9096169689Skan
9097169689Skanstatic void
9098169689Skanmips_reorg (void)
9099169689Skan{
9100169689Skan  if (TARGET_MIPS16)
9101169689Skan    mips16_lay_out_constants ();
9102169689Skan  else if (TARGET_EXPLICIT_RELOCS)
9103169689Skan    {
9104169689Skan      if (mips_flag_delayed_branch)
9105169689Skan	dbr_schedule (get_insns ());
9106169689Skan      mips_avoid_hazards ();
9107169689Skan      if (TUNE_MIPS4130 && TARGET_VR4130_ALIGN)
9108169689Skan	vr4130_align_insns ();
9109169689Skan    }
9110169689Skan}
9111169689Skan
9112169689Skan/* This function does three things:
9113169689Skan
9114169689Skan   - Register the special divsi3 and modsi3 functions if -mfix-vr4120.
9115169689Skan   - Register the mips16 hardware floating point stubs.
9116169689Skan   - Register the gofast functions if selected using --enable-gofast.  */
9117169689Skan
9118169689Skan#include "config/gofast.h"
9119169689Skan
9120169689Skanstatic void
9121169689Skanmips_init_libfuncs (void)
9122169689Skan{
9123169689Skan  if (TARGET_FIX_VR4120)
9124169689Skan    {
9125169689Skan      set_optab_libfunc (sdiv_optab, SImode, "__vr4120_divsi3");
9126169689Skan      set_optab_libfunc (smod_optab, SImode, "__vr4120_modsi3");
9127169689Skan    }
9128169689Skan
9129169689Skan  if (TARGET_MIPS16 && mips16_hard_float)
9130169689Skan    {
9131169689Skan      set_optab_libfunc (add_optab, SFmode, "__mips16_addsf3");
9132169689Skan      set_optab_libfunc (sub_optab, SFmode, "__mips16_subsf3");
9133169689Skan      set_optab_libfunc (smul_optab, SFmode, "__mips16_mulsf3");
9134169689Skan      set_optab_libfunc (sdiv_optab, SFmode, "__mips16_divsf3");
9135169689Skan
9136169689Skan      set_optab_libfunc (eq_optab, SFmode, "__mips16_eqsf2");
9137169689Skan      set_optab_libfunc (ne_optab, SFmode, "__mips16_nesf2");
9138169689Skan      set_optab_libfunc (gt_optab, SFmode, "__mips16_gtsf2");
9139169689Skan      set_optab_libfunc (ge_optab, SFmode, "__mips16_gesf2");
9140169689Skan      set_optab_libfunc (lt_optab, SFmode, "__mips16_ltsf2");
9141169689Skan      set_optab_libfunc (le_optab, SFmode, "__mips16_lesf2");
9142169689Skan
9143169689Skan      set_conv_libfunc (sfix_optab, SImode, SFmode, "__mips16_fix_truncsfsi");
9144169689Skan      set_conv_libfunc (sfloat_optab, SFmode, SImode, "__mips16_floatsisf");
9145169689Skan
9146169689Skan      if (TARGET_DOUBLE_FLOAT)
9147169689Skan	{
9148169689Skan	  set_optab_libfunc (add_optab, DFmode, "__mips16_adddf3");
9149169689Skan	  set_optab_libfunc (sub_optab, DFmode, "__mips16_subdf3");
9150169689Skan	  set_optab_libfunc (smul_optab, DFmode, "__mips16_muldf3");
9151169689Skan	  set_optab_libfunc (sdiv_optab, DFmode, "__mips16_divdf3");
9152169689Skan
9153169689Skan	  set_optab_libfunc (eq_optab, DFmode, "__mips16_eqdf2");
9154169689Skan	  set_optab_libfunc (ne_optab, DFmode, "__mips16_nedf2");
9155169689Skan	  set_optab_libfunc (gt_optab, DFmode, "__mips16_gtdf2");
9156169689Skan	  set_optab_libfunc (ge_optab, DFmode, "__mips16_gedf2");
9157169689Skan	  set_optab_libfunc (lt_optab, DFmode, "__mips16_ltdf2");
9158169689Skan	  set_optab_libfunc (le_optab, DFmode, "__mips16_ledf2");
9159169689Skan
9160169689Skan	  set_conv_libfunc (sext_optab, DFmode, SFmode, "__mips16_extendsfdf2");
9161169689Skan	  set_conv_libfunc (trunc_optab, SFmode, DFmode, "__mips16_truncdfsf2");
9162169689Skan
9163169689Skan	  set_conv_libfunc (sfix_optab, SImode, DFmode, "__mips16_fix_truncdfsi");
9164169689Skan	  set_conv_libfunc (sfloat_optab, DFmode, SImode, "__mips16_floatsidf");
9165169689Skan	}
9166169689Skan    }
9167169689Skan  else
9168169689Skan    gofast_maybe_init_libfuncs ();
9169169689Skan}
9170169689Skan
9171169689Skan/* Return a number assessing the cost of moving a register in class
9172169689Skan   FROM to class TO.  The classes are expressed using the enumeration
9173169689Skan   values such as `GENERAL_REGS'.  A value of 2 is the default; other
9174169689Skan   values are interpreted relative to that.
9175169689Skan
9176169689Skan   It is not required that the cost always equal 2 when FROM is the
9177169689Skan   same as TO; on some machines it is expensive to move between
9178169689Skan   registers if they are not general registers.
9179169689Skan
9180169689Skan   If reload sees an insn consisting of a single `set' between two
9181169689Skan   hard registers, and if `REGISTER_MOVE_COST' applied to their
9182169689Skan   classes returns a value of 2, reload does not check to ensure that
9183169689Skan   the constraints of the insn are met.  Setting a cost of other than
9184169689Skan   2 will allow reload to verify that the constraints are met.  You
9185169689Skan   should do this if the `movM' pattern's constraints do not allow
9186169689Skan   such copying.
9187169689Skan
9188169689Skan   ??? We make the cost of moving from HI/LO into general
9189169689Skan   registers the same as for one of moving general registers to
9190169689Skan   HI/LO for TARGET_MIPS16 in order to prevent allocating a
9191169689Skan   pseudo to HI/LO.  This might hurt optimizations though, it
9192169689Skan   isn't clear if it is wise.  And it might not work in all cases.  We
9193169689Skan   could solve the DImode LO reg problem by using a multiply, just
9194169689Skan   like reload_{in,out}si.  We could solve the SImode/HImode HI reg
9195169689Skan   problem by using divide instructions.  divu puts the remainder in
9196169689Skan   the HI reg, so doing a divide by -1 will move the value in the HI
9197169689Skan   reg for all values except -1.  We could handle that case by using a
9198169689Skan   signed divide, e.g.  -1 / 2 (or maybe 1 / -2?).  We'd have to emit
9199169689Skan   a compare/branch to test the input value to see which instruction
9200169689Skan   we need to use.  This gets pretty messy, but it is feasible.  */
9201169689Skan
9202169689Skanint
9203169689Skanmips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
9204169689Skan			 enum reg_class to, enum reg_class from)
9205169689Skan{
9206169689Skan  if (from == M16_REGS && GR_REG_CLASS_P (to))
9207169689Skan    return 2;
9208169689Skan  else if (from == M16_NA_REGS && GR_REG_CLASS_P (to))
9209169689Skan    return 2;
9210169689Skan  else if (GR_REG_CLASS_P (from))
9211169689Skan    {
9212169689Skan      if (to == M16_REGS)
9213169689Skan	return 2;
9214169689Skan      else if (to == M16_NA_REGS)
9215169689Skan	return 2;
9216169689Skan      else if (GR_REG_CLASS_P (to))
9217169689Skan	{
9218169689Skan	  if (TARGET_MIPS16)
9219169689Skan	    return 4;
9220169689Skan	  else
9221169689Skan	    return 2;
9222169689Skan	}
9223169689Skan      else if (to == FP_REGS)
9224169689Skan	return 4;
9225169689Skan      else if (reg_class_subset_p (to, ACC_REGS))
9226169689Skan	{
9227169689Skan	  if (TARGET_MIPS16)
9228169689Skan	    return 12;
9229169689Skan	  else
9230169689Skan	    return 6;
9231169689Skan	}
9232169689Skan      else if (COP_REG_CLASS_P (to))
9233169689Skan	{
9234169689Skan	  return 5;
9235169689Skan	}
9236169689Skan    }
9237169689Skan  else if (from == FP_REGS)
9238169689Skan    {
9239169689Skan      if (GR_REG_CLASS_P (to))
9240169689Skan	return 4;
9241169689Skan      else if (to == FP_REGS)
9242169689Skan	return 2;
9243169689Skan      else if (to == ST_REGS)
9244169689Skan	return 8;
9245169689Skan    }
9246169689Skan  else if (reg_class_subset_p (from, ACC_REGS))
9247169689Skan    {
9248169689Skan      if (GR_REG_CLASS_P (to))
9249169689Skan	{
9250169689Skan	  if (TARGET_MIPS16)
9251169689Skan	    return 12;
9252169689Skan	  else
9253169689Skan	    return 6;
9254169689Skan	}
9255169689Skan    }
9256169689Skan  else if (from == ST_REGS && GR_REG_CLASS_P (to))
9257169689Skan    return 4;
9258169689Skan  else if (COP_REG_CLASS_P (from))
9259169689Skan    {
9260169689Skan      return 5;
9261169689Skan    }
9262169689Skan
9263169689Skan  /* Fall through.
9264169689Skan     ??? What cases are these? Shouldn't we return 2 here?  */
9265169689Skan
9266169689Skan  return 12;
9267169689Skan}
9268169689Skan
9269169689Skan/* Return the length of INSN.  LENGTH is the initial length computed by
9270169689Skan   attributes in the machine-description file.  */
9271169689Skan
9272169689Skanint
9273169689Skanmips_adjust_insn_length (rtx insn, int length)
9274169689Skan{
9275169689Skan  /* A unconditional jump has an unfilled delay slot if it is not part
9276169689Skan     of a sequence.  A conditional jump normally has a delay slot, but
9277169689Skan     does not on MIPS16.  */
9278169689Skan  if (CALL_P (insn) || (TARGET_MIPS16 ? simplejump_p (insn) : JUMP_P (insn)))
9279169689Skan    length += 4;
9280169689Skan
9281169689Skan  /* See how many nops might be needed to avoid hardware hazards.  */
9282169689Skan  if (!cfun->machine->ignore_hazard_length_p && INSN_CODE (insn) >= 0)
9283169689Skan    switch (get_attr_hazard (insn))
9284169689Skan      {
9285169689Skan      case HAZARD_NONE:
9286169689Skan	break;
9287169689Skan
9288169689Skan      case HAZARD_DELAY:
9289169689Skan	length += 4;
9290169689Skan	break;
9291169689Skan
9292169689Skan      case HAZARD_HILO:
9293169689Skan	length += 8;
9294169689Skan	break;
9295169689Skan      }
9296169689Skan
9297169689Skan  /* All MIPS16 instructions are a measly two bytes.  */
9298169689Skan  if (TARGET_MIPS16)
9299169689Skan    length /= 2;
9300169689Skan
9301169689Skan  return length;
9302169689Skan}
9303169689Skan
9304169689Skan
9305169689Skan/* Return an asm sequence to start a noat block and load the address
9306169689Skan   of a label into $1.  */
9307169689Skan
9308169689Skanconst char *
9309169689Skanmips_output_load_label (void)
9310169689Skan{
9311169689Skan  if (TARGET_EXPLICIT_RELOCS)
9312169689Skan    switch (mips_abi)
9313169689Skan      {
9314169689Skan      case ABI_N32:
9315169689Skan	return "%[lw\t%@,%%got_page(%0)(%+)\n\taddiu\t%@,%@,%%got_ofst(%0)";
9316169689Skan
9317169689Skan      case ABI_64:
9318169689Skan	return "%[ld\t%@,%%got_page(%0)(%+)\n\tdaddiu\t%@,%@,%%got_ofst(%0)";
9319169689Skan
9320169689Skan      default:
9321169689Skan	if (ISA_HAS_LOAD_DELAY)
9322169689Skan	  return "%[lw\t%@,%%got(%0)(%+)%#\n\taddiu\t%@,%@,%%lo(%0)";
9323169689Skan	return "%[lw\t%@,%%got(%0)(%+)\n\taddiu\t%@,%@,%%lo(%0)";
9324169689Skan      }
9325169689Skan  else
9326169689Skan    {
9327169689Skan      if (Pmode == DImode)
9328169689Skan	return "%[dla\t%@,%0";
9329169689Skan      else
9330169689Skan	return "%[la\t%@,%0";
9331169689Skan    }
9332169689Skan}
9333169689Skan
9334169689Skan/* Return the assembly code for INSN, which has the operands given by
9335169689Skan   OPERANDS, and which branches to OPERANDS[1] if some condition is true.
9336169689Skan   BRANCH_IF_TRUE is the asm template that should be used if OPERANDS[1]
9337169689Skan   is in range of a direct branch.  BRANCH_IF_FALSE is an inverted
9338169689Skan   version of BRANCH_IF_TRUE.  */
9339169689Skan
9340169689Skanconst char *
9341169689Skanmips_output_conditional_branch (rtx insn, rtx *operands,
9342169689Skan				const char *branch_if_true,
9343169689Skan				const char *branch_if_false)
9344169689Skan{
9345169689Skan  unsigned int length;
9346169689Skan  rtx taken, not_taken;
9347169689Skan
9348169689Skan  length = get_attr_length (insn);
9349169689Skan  if (length <= 8)
9350169689Skan    {
9351169689Skan      /* Just a simple conditional branch.  */
9352169689Skan      mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
9353169689Skan      return branch_if_true;
9354169689Skan    }
9355169689Skan
9356169689Skan  /* Generate a reversed branch around a direct jump.  This fallback does
9357169689Skan     not use branch-likely instructions.  */
9358169689Skan  mips_branch_likely = false;
9359169689Skan  not_taken = gen_label_rtx ();
9360169689Skan  taken = operands[1];
9361169689Skan
9362169689Skan  /* Generate the reversed branch to NOT_TAKEN.  */
9363169689Skan  operands[1] = not_taken;
9364169689Skan  output_asm_insn (branch_if_false, operands);
9365169689Skan
9366169689Skan  /* If INSN has a delay slot, we must provide delay slots for both the
9367169689Skan     branch to NOT_TAKEN and the conditional jump.  We must also ensure
9368169689Skan     that INSN's delay slot is executed in the appropriate cases.  */
9369169689Skan  if (final_sequence)
9370169689Skan    {
9371169689Skan      /* This first delay slot will always be executed, so use INSN's
9372169689Skan	 delay slot if is not annulled.  */
9373169689Skan      if (!INSN_ANNULLED_BRANCH_P (insn))
9374169689Skan	{
9375169689Skan	  final_scan_insn (XVECEXP (final_sequence, 0, 1),
9376169689Skan			   asm_out_file, optimize, 1, NULL);
9377169689Skan	  INSN_DELETED_P (XVECEXP (final_sequence, 0, 1)) = 1;
9378169689Skan	}
9379169689Skan      else
9380169689Skan	output_asm_insn ("nop", 0);
9381169689Skan      fprintf (asm_out_file, "\n");
9382169689Skan    }
9383169689Skan
9384169689Skan  /* Output the unconditional branch to TAKEN.  */
9385169689Skan  if (length <= 16)
9386169689Skan    output_asm_insn ("j\t%0%/", &taken);
9387169689Skan  else
9388169689Skan    {
9389169689Skan      output_asm_insn (mips_output_load_label (), &taken);
9390169689Skan      output_asm_insn ("jr\t%@%]%/", 0);
9391169689Skan    }
9392169689Skan
9393169689Skan  /* Now deal with its delay slot; see above.  */
9394169689Skan  if (final_sequence)
9395169689Skan    {
9396169689Skan      /* This delay slot will only be executed if the branch is taken.
9397169689Skan	 Use INSN's delay slot if is annulled.  */
9398169689Skan      if (INSN_ANNULLED_BRANCH_P (insn))
9399169689Skan	{
9400169689Skan	  final_scan_insn (XVECEXP (final_sequence, 0, 1),
9401169689Skan			   asm_out_file, optimize, 1, NULL);
9402169689Skan	  INSN_DELETED_P (XVECEXP (final_sequence, 0, 1)) = 1;
9403169689Skan	}
9404169689Skan      else
9405169689Skan	output_asm_insn ("nop", 0);
9406169689Skan      fprintf (asm_out_file, "\n");
9407169689Skan    }
9408169689Skan
9409169689Skan  /* Output NOT_TAKEN.  */
9410169689Skan  (*targetm.asm_out.internal_label) (asm_out_file, "L",
9411169689Skan				     CODE_LABEL_NUMBER (not_taken));
9412169689Skan  return "";
9413169689Skan}
9414169689Skan
9415169689Skan/* Return the assembly code for INSN, which branches to OPERANDS[1]
9416169689Skan   if some ordered condition is true.  The condition is given by
9417169689Skan   OPERANDS[0] if !INVERTED_P, otherwise it is the inverse of
9418169689Skan   OPERANDS[0].  OPERANDS[2] is the comparison's first operand;
9419169689Skan   its second is always zero.  */
9420169689Skan
9421169689Skanconst char *
9422169689Skanmips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p)
9423169689Skan{
9424169689Skan  const char *branch[2];
9425169689Skan
9426169689Skan  /* Make BRANCH[1] branch to OPERANDS[1] when the condition is true.
9427169689Skan     Make BRANCH[0] branch on the inverse condition.  */
9428169689Skan  switch (GET_CODE (operands[0]))
9429169689Skan    {
9430169689Skan      /* These cases are equivalent to comparisons against zero.  */
9431169689Skan    case LEU:
9432169689Skan      inverted_p = !inverted_p;
9433169689Skan      /* Fall through.  */
9434169689Skan    case GTU:
9435169689Skan      branch[!inverted_p] = MIPS_BRANCH ("bne", "%2,%.,%1");
9436169689Skan      branch[inverted_p] = MIPS_BRANCH ("beq", "%2,%.,%1");
9437169689Skan      break;
9438169689Skan
9439169689Skan      /* These cases are always true or always false.  */
9440169689Skan    case LTU:
9441169689Skan      inverted_p = !inverted_p;
9442169689Skan      /* Fall through.  */
9443169689Skan    case GEU:
9444169689Skan      branch[!inverted_p] = MIPS_BRANCH ("beq", "%.,%.,%1");
9445169689Skan      branch[inverted_p] = MIPS_BRANCH ("bne", "%.,%.,%1");
9446169689Skan      break;
9447169689Skan
9448169689Skan    default:
9449169689Skan      branch[!inverted_p] = MIPS_BRANCH ("b%C0z", "%2,%1");
9450169689Skan      branch[inverted_p] = MIPS_BRANCH ("b%N0z", "%2,%1");
9451169689Skan      break;
9452169689Skan    }
9453169689Skan  return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
9454169689Skan}
9455169689Skan
9456169689Skan/* Used to output div or ddiv instruction DIVISION, which has the operands
9457169689Skan   given by OPERANDS.  Add in a divide-by-zero check if needed.
9458169689Skan
9459169689Skan   When working around R4000 and R4400 errata, we need to make sure that
9460169689Skan   the division is not immediately followed by a shift[1][2].  We also
9461169689Skan   need to stop the division from being put into a branch delay slot[3].
9462169689Skan   The easiest way to avoid both problems is to add a nop after the
9463169689Skan   division.  When a divide-by-zero check is needed, this nop can be
9464169689Skan   used to fill the branch delay slot.
9465169689Skan
9466169689Skan   [1] If a double-word or a variable shift executes immediately
9467169689Skan       after starting an integer division, the shift may give an
9468169689Skan       incorrect result.  See quotations of errata #16 and #28 from
9469169689Skan       "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
9470169689Skan       in mips.md for details.
9471169689Skan
9472169689Skan   [2] A similar bug to [1] exists for all revisions of the
9473169689Skan       R4000 and the R4400 when run in an MC configuration.
9474169689Skan       From "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0":
9475169689Skan
9476169689Skan       "19. In this following sequence:
9477169689Skan
9478169689Skan		    ddiv		(or ddivu or div or divu)
9479169689Skan		    dsll32		(or dsrl32, dsra32)
9480169689Skan
9481169689Skan	    if an MPT stall occurs, while the divide is slipping the cpu
9482169689Skan	    pipeline, then the following double shift would end up with an
9483169689Skan	    incorrect result.
9484169689Skan
9485169689Skan	    Workaround: The compiler needs to avoid generating any
9486169689Skan	    sequence with divide followed by extended double shift."
9487169689Skan
9488169689Skan       This erratum is also present in "MIPS R4400MC Errata, Processor
9489169689Skan       Revision 1.0" and "MIPS R4400MC Errata, Processor Revision 2.0
9490169689Skan       & 3.0" as errata #10 and #4, respectively.
9491169689Skan
9492169689Skan   [3] From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0"
9493169689Skan       (also valid for MIPS R4000MC processors):
9494169689Skan
9495169689Skan       "52. R4000SC: This bug does not apply for the R4000PC.
9496169689Skan
9497169689Skan	    There are two flavors of this bug:
9498169689Skan
9499169689Skan	    1) If the instruction just after divide takes an RF exception
9500169689Skan	       (tlb-refill, tlb-invalid) and gets an instruction cache
9501169689Skan	       miss (both primary and secondary) and the line which is
9502169689Skan	       currently in secondary cache at this index had the first
9503169689Skan	       data word, where the bits 5..2 are set, then R4000 would
9504169689Skan	       get a wrong result for the div.
9505169689Skan
9506169689Skan	    ##1
9507169689Skan		    nop
9508169689Skan		    div	r8, r9
9509169689Skan		    -------------------		# end-of page. -tlb-refill
9510169689Skan		    nop
9511169689Skan	    ##2
9512169689Skan		    nop
9513169689Skan		    div	r8, r9
9514169689Skan		    -------------------		# end-of page. -tlb-invalid
9515169689Skan		    nop
9516169689Skan
9517169689Skan	    2) If the divide is in the taken branch delay slot, where the
9518169689Skan	       target takes RF exception and gets an I-cache miss for the
9519169689Skan	       exception vector or where I-cache miss occurs for the
9520169689Skan	       target address, under the above mentioned scenarios, the
9521169689Skan	       div would get wrong results.
9522169689Skan
9523169689Skan	    ##1
9524169689Skan		    j	r2		# to next page mapped or unmapped
9525169689Skan		    div	r8,r9		# this bug would be there as long
9526169689Skan					# as there is an ICache miss and
9527169689Skan		    nop			# the "data pattern" is present
9528169689Skan
9529169689Skan	    ##2
9530169689Skan		    beq	r0, r0, NextPage	# to Next page
9531169689Skan		    div	r8,r9
9532169689Skan		    nop
9533169689Skan
9534169689Skan	    This bug is present for div, divu, ddiv, and ddivu
9535169689Skan	    instructions.
9536169689Skan
9537169689Skan	    Workaround: For item 1), OS could make sure that the next page
9538169689Skan	    after the divide instruction is also mapped.  For item 2), the
9539169689Skan	    compiler could make sure that the divide instruction is not in
9540169689Skan	    the branch delay slot."
9541169689Skan
9542169689Skan       These processors have PRId values of 0x00004220 and 0x00004300 for
9543169689Skan       the R4000 and 0x00004400, 0x00004500 and 0x00004600 for the R4400.  */
9544169689Skan
9545169689Skanconst char *
9546169689Skanmips_output_division (const char *division, rtx *operands)
9547169689Skan{
9548169689Skan  const char *s;
9549169689Skan
9550169689Skan  s = division;
9551169689Skan  if (TARGET_FIX_R4000 || TARGET_FIX_R4400)
9552169689Skan    {
9553169689Skan      output_asm_insn (s, operands);
9554169689Skan      s = "nop";
9555169689Skan    }
9556169689Skan  if (TARGET_CHECK_ZERO_DIV)
9557169689Skan    {
9558169689Skan      if (TARGET_MIPS16)
9559169689Skan	{
9560169689Skan	  output_asm_insn (s, operands);
9561169689Skan	  s = "bnez\t%2,1f\n\tbreak\t7\n1:";
9562169689Skan	}
9563169689Skan      else if (GENERATE_DIVIDE_TRAPS)
9564169689Skan        {
9565169689Skan	  output_asm_insn (s, operands);
9566169689Skan	  s = "teq\t%2,%.,7";
9567169689Skan        }
9568169689Skan      else
9569169689Skan	{
9570169689Skan	  output_asm_insn ("%(bne\t%2,%.,1f", operands);
9571169689Skan	  output_asm_insn (s, operands);
9572169689Skan	  s = "break\t7%)\n1:";
9573169689Skan	}
9574169689Skan    }
9575169689Skan  return s;
9576169689Skan}
9577169689Skan
9578169689Skan/* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL
9579169689Skan   with a final "000" replaced by "k".  Ignore case.
9580169689Skan
9581169689Skan   Note: this function is shared between GCC and GAS.  */
9582169689Skan
9583169689Skanstatic bool
9584169689Skanmips_strict_matching_cpu_name_p (const char *canonical, const char *given)
9585169689Skan{
9586169689Skan  while (*given != 0 && TOLOWER (*given) == TOLOWER (*canonical))
9587169689Skan    given++, canonical++;
9588169689Skan
9589169689Skan  return ((*given == 0 && *canonical == 0)
9590169689Skan	  || (strcmp (canonical, "000") == 0 && strcasecmp (given, "k") == 0));
9591169689Skan}
9592169689Skan
9593169689Skan
9594169689Skan/* Return true if GIVEN matches CANONICAL, where GIVEN is a user-supplied
9595169689Skan   CPU name.  We've traditionally allowed a lot of variation here.
9596169689Skan
9597169689Skan   Note: this function is shared between GCC and GAS.  */
9598169689Skan
9599169689Skanstatic bool
9600169689Skanmips_matching_cpu_name_p (const char *canonical, const char *given)
9601169689Skan{
9602169689Skan  /* First see if the name matches exactly, or with a final "000"
9603169689Skan     turned into "k".  */
9604169689Skan  if (mips_strict_matching_cpu_name_p (canonical, given))
9605169689Skan    return true;
9606169689Skan
9607169689Skan  /* If not, try comparing based on numerical designation alone.
9608169689Skan     See if GIVEN is an unadorned number, or 'r' followed by a number.  */
9609169689Skan  if (TOLOWER (*given) == 'r')
9610169689Skan    given++;
9611169689Skan  if (!ISDIGIT (*given))
9612169689Skan    return false;
9613169689Skan
9614169689Skan  /* Skip over some well-known prefixes in the canonical name,
9615169689Skan     hoping to find a number there too.  */
9616169689Skan  if (TOLOWER (canonical[0]) == 'v' && TOLOWER (canonical[1]) == 'r')
9617169689Skan    canonical += 2;
9618169689Skan  else if (TOLOWER (canonical[0]) == 'r' && TOLOWER (canonical[1]) == 'm')
9619169689Skan    canonical += 2;
9620169689Skan  else if (TOLOWER (canonical[0]) == 'r')
9621169689Skan    canonical += 1;
9622169689Skan
9623169689Skan  return mips_strict_matching_cpu_name_p (canonical, given);
9624169689Skan}
9625169689Skan
9626169689Skan
9627169689Skan/* Return the mips_cpu_info entry for the processor or ISA given
9628169689Skan   by CPU_STRING.  Return null if the string isn't recognized.
9629169689Skan
9630169689Skan   A similar function exists in GAS.  */
9631169689Skan
9632169689Skanstatic const struct mips_cpu_info *
9633169689Skanmips_parse_cpu (const char *cpu_string)
9634169689Skan{
9635169689Skan  const struct mips_cpu_info *p;
9636169689Skan  const char *s;
9637169689Skan
9638169689Skan  /* In the past, we allowed upper-case CPU names, but it doesn't
9639169689Skan     work well with the multilib machinery.  */
9640169689Skan  for (s = cpu_string; *s != 0; s++)
9641169689Skan    if (ISUPPER (*s))
9642169689Skan      {
9643169689Skan	warning (0, "the cpu name must be lower case");
9644169689Skan	break;
9645169689Skan      }
9646169689Skan
9647169689Skan  /* 'from-abi' selects the most compatible architecture for the given
9648169689Skan     ABI: MIPS I for 32-bit ABIs and MIPS III for 64-bit ABIs.  For the
9649169689Skan     EABIs, we have to decide whether we're using the 32-bit or 64-bit
9650169689Skan     version.  Look first at the -mgp options, if given, otherwise base
9651169689Skan     the choice on MASK_64BIT in TARGET_DEFAULT.  */
9652169689Skan  if (strcasecmp (cpu_string, "from-abi") == 0)
9653169689Skan    return mips_cpu_info_from_isa (ABI_NEEDS_32BIT_REGS ? 1
9654169689Skan				   : ABI_NEEDS_64BIT_REGS ? 3
9655169689Skan				   : (TARGET_64BIT ? 3 : 1));
9656169689Skan
9657169689Skan  /* 'default' has traditionally been a no-op.  Probably not very useful.  */
9658169689Skan  if (strcasecmp (cpu_string, "default") == 0)
9659169689Skan    return 0;
9660169689Skan
9661169689Skan  for (p = mips_cpu_info_table; p->name != 0; p++)
9662169689Skan    if (mips_matching_cpu_name_p (p->name, cpu_string))
9663169689Skan      return p;
9664169689Skan
9665169689Skan  return 0;
9666169689Skan}
9667169689Skan
9668169689Skan
9669169689Skan/* Return the processor associated with the given ISA level, or null
9670169689Skan   if the ISA isn't valid.  */
9671169689Skan
9672169689Skanstatic const struct mips_cpu_info *
9673169689Skanmips_cpu_info_from_isa (int isa)
9674169689Skan{
9675169689Skan  const struct mips_cpu_info *p;
9676169689Skan
9677169689Skan  for (p = mips_cpu_info_table; p->name != 0; p++)
9678169689Skan    if (p->isa == isa)
9679169689Skan      return p;
9680169689Skan
9681169689Skan  return 0;
9682169689Skan}
9683169689Skan
9684169689Skan/* Implement HARD_REGNO_NREGS.  The size of FP registers is controlled
9685169689Skan   by UNITS_PER_FPREG.  The size of FP status registers is always 4, because
9686169689Skan   they only hold condition code modes, and CCmode is always considered to
9687169689Skan   be 4 bytes wide.  All other registers are word sized.  */
9688169689Skan
9689169689Skanunsigned int
9690169689Skanmips_hard_regno_nregs (int regno, enum machine_mode mode)
9691169689Skan{
9692169689Skan  if (ST_REG_P (regno))
9693169689Skan    return ((GET_MODE_SIZE (mode) + 3) / 4);
9694169689Skan  else if (! FP_REG_P (regno))
9695169689Skan    return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
9696169689Skan  else
9697169689Skan    return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
9698169689Skan}
9699169689Skan
9700169689Skan/* Implement TARGET_RETURN_IN_MEMORY.  Under the old (i.e., 32 and O64 ABIs)
9701169689Skan   all BLKmode objects are returned in memory.  Under the new (N32 and
9702169689Skan   64-bit MIPS ABIs) small structures are returned in a register.
9703169689Skan   Objects with varying size must still be returned in memory, of
9704169689Skan   course.  */
9705169689Skan
9706169689Skanstatic bool
9707169689Skanmips_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
9708169689Skan{
9709169689Skan  if (TARGET_OLDABI)
9710169689Skan    return (TYPE_MODE (type) == BLKmode);
9711169689Skan  else
9712169689Skan    return ((int_size_in_bytes (type) > (2 * UNITS_PER_WORD))
9713169689Skan	    || (int_size_in_bytes (type) == -1));
9714169689Skan}
9715169689Skan
9716169689Skanstatic bool
9717169689Skanmips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
9718169689Skan{
9719169689Skan  return !TARGET_OLDABI;
9720169689Skan}
9721169689Skan
9722169689Skan/* Return true if INSN is a multiply-add or multiply-subtract
9723169689Skan   instruction and PREV assigns to the accumulator operand.  */
9724169689Skan
9725169689Skanbool
9726169689Skanmips_linked_madd_p (rtx prev, rtx insn)
9727169689Skan{
9728169689Skan  rtx x;
9729169689Skan
9730169689Skan  x = single_set (insn);
9731169689Skan  if (x == 0)
9732169689Skan    return false;
9733169689Skan
9734169689Skan  x = SET_SRC (x);
9735169689Skan
9736169689Skan  if (GET_CODE (x) == PLUS
9737169689Skan      && GET_CODE (XEXP (x, 0)) == MULT
9738169689Skan      && reg_set_p (XEXP (x, 1), prev))
9739169689Skan    return true;
9740169689Skan
9741169689Skan  if (GET_CODE (x) == MINUS
9742169689Skan      && GET_CODE (XEXP (x, 1)) == MULT
9743169689Skan      && reg_set_p (XEXP (x, 0), prev))
9744169689Skan    return true;
9745169689Skan
9746169689Skan  return false;
9747169689Skan}
9748169689Skan
9749169689Skan/* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
9750169689Skan   that may clobber hi or lo.  */
9751169689Skan
9752169689Skanstatic rtx mips_macc_chains_last_hilo;
9753169689Skan
9754169689Skan/* A TUNE_MACC_CHAINS helper function.  Record that instruction INSN has
9755169689Skan   been scheduled, updating mips_macc_chains_last_hilo appropriately.  */
9756169689Skan
9757169689Skanstatic void
9758169689Skanmips_macc_chains_record (rtx insn)
9759169689Skan{
9760169689Skan  if (get_attr_may_clobber_hilo (insn))
9761169689Skan    mips_macc_chains_last_hilo = insn;
9762169689Skan}
9763169689Skan
9764169689Skan/* A TUNE_MACC_CHAINS helper function.  Search ready queue READY, which
9765169689Skan   has NREADY elements, looking for a multiply-add or multiply-subtract
9766169689Skan   instruction that is cumulative with mips_macc_chains_last_hilo.
9767169689Skan   If there is one, promote it ahead of anything else that might
9768169689Skan   clobber hi or lo.  */
9769169689Skan
9770169689Skanstatic void
9771169689Skanmips_macc_chains_reorder (rtx *ready, int nready)
9772169689Skan{
9773169689Skan  int i, j;
9774169689Skan
9775169689Skan  if (mips_macc_chains_last_hilo != 0)
9776169689Skan    for (i = nready - 1; i >= 0; i--)
9777169689Skan      if (mips_linked_madd_p (mips_macc_chains_last_hilo, ready[i]))
9778169689Skan	{
9779169689Skan	  for (j = nready - 1; j > i; j--)
9780169689Skan	    if (recog_memoized (ready[j]) >= 0
9781169689Skan		&& get_attr_may_clobber_hilo (ready[j]))
9782169689Skan	      {
9783169689Skan		mips_promote_ready (ready, i, j);
9784169689Skan		break;
9785169689Skan	      }
9786169689Skan	  break;
9787169689Skan	}
9788169689Skan}
9789169689Skan
9790169689Skan/* The last instruction to be scheduled.  */
9791169689Skan
9792169689Skanstatic rtx vr4130_last_insn;
9793169689Skan
9794169689Skan/* A note_stores callback used by vr4130_true_reg_dependence_p.  DATA
9795169689Skan   points to an rtx that is initially an instruction.  Nullify the rtx
9796169689Skan   if the instruction uses the value of register X.  */
9797169689Skan
9798169689Skanstatic void
9799169689Skanvr4130_true_reg_dependence_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
9800169689Skan{
9801169689Skan  rtx *insn_ptr = data;
9802169689Skan  if (REG_P (x)
9803169689Skan      && *insn_ptr != 0
9804169689Skan      && reg_referenced_p (x, PATTERN (*insn_ptr)))
9805169689Skan    *insn_ptr = 0;
9806169689Skan}
9807169689Skan
9808169689Skan/* Return true if there is true register dependence between vr4130_last_insn
9809169689Skan   and INSN.  */
9810169689Skan
9811169689Skanstatic bool
9812169689Skanvr4130_true_reg_dependence_p (rtx insn)
9813169689Skan{
9814169689Skan  note_stores (PATTERN (vr4130_last_insn),
9815169689Skan	       vr4130_true_reg_dependence_p_1, &insn);
9816169689Skan  return insn == 0;
9817169689Skan}
9818169689Skan
9819169689Skan/* A TUNE_MIPS4130 helper function.  Given that INSN1 is at the head of
9820169689Skan   the ready queue and that INSN2 is the instruction after it, return
9821169689Skan   true if it is worth promoting INSN2 ahead of INSN1.  Look for cases
9822169689Skan   in which INSN1 and INSN2 can probably issue in parallel, but for
9823169689Skan   which (INSN2, INSN1) should be less sensitive to instruction
9824169689Skan   alignment than (INSN1, INSN2).  See 4130.md for more details.  */
9825169689Skan
9826169689Skanstatic bool
9827169689Skanvr4130_swap_insns_p (rtx insn1, rtx insn2)
9828169689Skan{
9829169689Skan  rtx dep;
9830169689Skan
9831169689Skan  /* Check for the following case:
9832169689Skan
9833169689Skan     1) there is some other instruction X with an anti dependence on INSN1;
9834169689Skan     2) X has a higher priority than INSN2; and
9835169689Skan     3) X is an arithmetic instruction (and thus has no unit restrictions).
9836169689Skan
9837169689Skan     If INSN1 is the last instruction blocking X, it would better to
9838169689Skan     choose (INSN1, X) over (INSN2, INSN1).  */
9839169689Skan  for (dep = INSN_DEPEND (insn1); dep != 0; dep = XEXP (dep, 1))
9840169689Skan    if (REG_NOTE_KIND (dep) == REG_DEP_ANTI
9841169689Skan	&& INSN_PRIORITY (XEXP (dep, 0)) > INSN_PRIORITY (insn2)
9842169689Skan	&& recog_memoized (XEXP (dep, 0)) >= 0
9843169689Skan	&& get_attr_vr4130_class (XEXP (dep, 0)) == VR4130_CLASS_ALU)
9844169689Skan      return false;
9845169689Skan
9846169689Skan  if (vr4130_last_insn != 0
9847169689Skan      && recog_memoized (insn1) >= 0
9848169689Skan      && recog_memoized (insn2) >= 0)
9849169689Skan    {
9850169689Skan      /* See whether INSN1 and INSN2 use different execution units,
9851169689Skan	 or if they are both ALU-type instructions.  If so, they can
9852169689Skan	 probably execute in parallel.  */
9853169689Skan      enum attr_vr4130_class class1 = get_attr_vr4130_class (insn1);
9854169689Skan      enum attr_vr4130_class class2 = get_attr_vr4130_class (insn2);
9855169689Skan      if (class1 != class2 || class1 == VR4130_CLASS_ALU)
9856169689Skan	{
9857169689Skan	  /* If only one of the instructions has a dependence on
9858169689Skan	     vr4130_last_insn, prefer to schedule the other one first.  */
9859169689Skan	  bool dep1 = vr4130_true_reg_dependence_p (insn1);
9860169689Skan	  bool dep2 = vr4130_true_reg_dependence_p (insn2);
9861169689Skan	  if (dep1 != dep2)
9862169689Skan	    return dep1;
9863169689Skan
9864169689Skan	  /* Prefer to schedule INSN2 ahead of INSN1 if vr4130_last_insn
9865169689Skan	     is not an ALU-type instruction and if INSN1 uses the same
9866169689Skan	     execution unit.  (Note that if this condition holds, we already
9867169689Skan	     know that INSN2 uses a different execution unit.)  */
9868169689Skan	  if (class1 != VR4130_CLASS_ALU
9869169689Skan	      && recog_memoized (vr4130_last_insn) >= 0
9870169689Skan	      && class1 == get_attr_vr4130_class (vr4130_last_insn))
9871169689Skan	    return true;
9872169689Skan	}
9873169689Skan    }
9874169689Skan  return false;
9875169689Skan}
9876169689Skan
9877169689Skan/* A TUNE_MIPS4130 helper function.  (READY, NREADY) describes a ready
9878169689Skan   queue with at least two instructions.  Swap the first two if
9879169689Skan   vr4130_swap_insns_p says that it could be worthwhile.  */
9880169689Skan
9881169689Skanstatic void
9882169689Skanvr4130_reorder (rtx *ready, int nready)
9883169689Skan{
9884169689Skan  if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
9885169689Skan    mips_promote_ready (ready, nready - 2, nready - 1);
9886169689Skan}
9887169689Skan
9888169689Skan/* Remove the instruction at index LOWER from ready queue READY and
9889169689Skan   reinsert it in front of the instruction at index HIGHER.  LOWER must
9890169689Skan   be <= HIGHER.  */
9891169689Skan
9892169689Skanstatic void
9893169689Skanmips_promote_ready (rtx *ready, int lower, int higher)
9894169689Skan{
9895169689Skan  rtx new_head;
9896169689Skan  int i;
9897169689Skan
9898169689Skan  new_head = ready[lower];
9899169689Skan  for (i = lower; i < higher; i++)
9900169689Skan    ready[i] = ready[i + 1];
9901169689Skan  ready[i] = new_head;
9902169689Skan}
9903169689Skan
9904169689Skan/* Implement TARGET_SCHED_REORDER.  */
9905169689Skan
9906169689Skanstatic int
9907169689Skanmips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9908169689Skan		    rtx *ready, int *nreadyp, int cycle)
9909169689Skan{
9910169689Skan  if (!reload_completed && TUNE_MACC_CHAINS)
9911169689Skan    {
9912169689Skan      if (cycle == 0)
9913169689Skan	mips_macc_chains_last_hilo = 0;
9914169689Skan      if (*nreadyp > 0)
9915169689Skan	mips_macc_chains_reorder (ready, *nreadyp);
9916169689Skan    }
9917169689Skan  if (reload_completed && TUNE_MIPS4130 && !TARGET_VR4130_ALIGN)
9918169689Skan    {
9919169689Skan      if (cycle == 0)
9920169689Skan	vr4130_last_insn = 0;
9921169689Skan      if (*nreadyp > 1)
9922169689Skan	vr4130_reorder (ready, *nreadyp);
9923169689Skan    }
9924169689Skan  return mips_issue_rate ();
9925169689Skan}
9926169689Skan
9927169689Skan/* Implement TARGET_SCHED_VARIABLE_ISSUE.  */
9928169689Skan
9929169689Skanstatic int
9930169689Skanmips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
9931169689Skan		     rtx insn, int more)
9932169689Skan{
9933169689Skan  switch (GET_CODE (PATTERN (insn)))
9934169689Skan    {
9935169689Skan    case USE:
9936169689Skan    case CLOBBER:
9937169689Skan      /* Don't count USEs and CLOBBERs against the issue rate.  */
9938169689Skan      break;
9939169689Skan
9940169689Skan    default:
9941169689Skan      more--;
9942169689Skan      if (!reload_completed && TUNE_MACC_CHAINS)
9943169689Skan	mips_macc_chains_record (insn);
9944169689Skan      vr4130_last_insn = insn;
9945169689Skan      break;
9946169689Skan    }
9947169689Skan  return more;
9948169689Skan}
9949169689Skan
9950169689Skan/* Implement TARGET_SCHED_ADJUST_COST.  We assume that anti and output
9951169689Skan   dependencies have no cost.  */
9952169689Skan
9953169689Skanstatic int
9954169689Skanmips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
9955169689Skan		  rtx dep ATTRIBUTE_UNUSED, int cost)
9956169689Skan{
9957169689Skan  if (REG_NOTE_KIND (link) != 0)
9958169689Skan    return 0;
9959169689Skan  return cost;
9960169689Skan}
9961169689Skan
9962169689Skan/* Return the number of instructions that can be issued per cycle.  */
9963169689Skan
9964169689Skanstatic int
9965169689Skanmips_issue_rate (void)
9966169689Skan{
9967169689Skan  switch (mips_tune)
9968169689Skan    {
9969169689Skan    case PROCESSOR_R4130:
9970169689Skan    case PROCESSOR_R5400:
9971169689Skan    case PROCESSOR_R5500:
9972169689Skan    case PROCESSOR_R7000:
9973169689Skan    case PROCESSOR_R9000:
9974208737Sjmallett    case PROCESSOR_OCTEON:
9975169689Skan      return 2;
9976169689Skan
9977169689Skan    case PROCESSOR_SB1:
9978169689Skan    case PROCESSOR_SB1A:
9979169689Skan      /* This is actually 4, but we get better performance if we claim 3.
9980169689Skan	 This is partly because of unwanted speculative code motion with the
9981169689Skan	 larger number, and partly because in most common cases we can't
9982169689Skan	 reach the theoretical max of 4.  */
9983169689Skan      return 3;
9984169689Skan
9985169689Skan    default:
9986169689Skan      return 1;
9987169689Skan    }
9988169689Skan}
9989169689Skan
9990169689Skan/* Implements TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD.  This should
9991169689Skan   be as wide as the scheduling freedom in the DFA.  */
9992169689Skan
9993169689Skanstatic int
9994169689Skanmips_multipass_dfa_lookahead (void)
9995169689Skan{
9996169689Skan  /* Can schedule up to 4 of the 6 function units in any one cycle.  */
9997169689Skan  if (TUNE_SB1)
9998169689Skan    return 4;
9999169689Skan
10000169689Skan  return 0;
10001169689Skan}
10002169689Skan
10003169689Skan/* Implements a store data bypass check.  We need this because the cprestore
10004169689Skan   pattern is type store, but defined using an UNSPEC.  This UNSPEC causes the
10005169689Skan   default routine to abort.  We just return false for that case.  */
10006169689Skan/* ??? Should try to give a better result here than assuming false.  */
10007169689Skan
10008169689Skanint
10009169689Skanmips_store_data_bypass_p (rtx out_insn, rtx in_insn)
10010169689Skan{
10011169689Skan  if (GET_CODE (PATTERN (in_insn)) == UNSPEC_VOLATILE)
10012169689Skan    return false;
10013169689Skan
10014169689Skan  return ! store_data_bypass_p (out_insn, in_insn);
10015169689Skan}
10016169689Skan
10017169689Skan/* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY),
10018169689Skan   return the first operand of the associated "pref" or "prefx" insn.  */
10019169689Skan
10020169689Skanrtx
10021169689Skanmips_prefetch_cookie (rtx write, rtx locality)
10022169689Skan{
10023169689Skan  /* store_streamed / load_streamed.  */
10024169689Skan  if (INTVAL (locality) <= 0)
10025169689Skan    return GEN_INT (INTVAL (write) + 4);
10026169689Skan
10027169689Skan  /* store / load.  */
10028169689Skan  if (INTVAL (locality) <= 2)
10029169689Skan    return write;
10030169689Skan
10031169689Skan  /* store_retained / load_retained.  */
10032169689Skan  return GEN_INT (INTVAL (write) + 6);
10033169689Skan}
10034169689Skan
10035169689Skan/* MIPS builtin function support. */
10036169689Skan
10037169689Skanstruct builtin_description
10038169689Skan{
10039169689Skan  /* The code of the main .md file instruction.  See mips_builtin_type
10040169689Skan     for more information.  */
10041169689Skan  enum insn_code icode;
10042169689Skan
10043169689Skan  /* The floating-point comparison code to use with ICODE, if any.  */
10044169689Skan  enum mips_fp_condition cond;
10045169689Skan
10046169689Skan  /* The name of the builtin function.  */
10047169689Skan  const char *name;
10048169689Skan
10049169689Skan  /* Specifies how the function should be expanded.  */
10050169689Skan  enum mips_builtin_type builtin_type;
10051169689Skan
10052169689Skan  /* The function's prototype.  */
10053169689Skan  enum mips_function_type function_type;
10054169689Skan
10055169689Skan  /* The target flags required for this function.  */
10056169689Skan  int target_flags;
10057169689Skan};
10058169689Skan
10059169689Skan/* Define a MIPS_BUILTIN_DIRECT function for instruction CODE_FOR_mips_<INSN>.
10060169689Skan   FUNCTION_TYPE and TARGET_FLAGS are builtin_description fields.  */
10061169689Skan#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS)		\
10062169689Skan  { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
10063169689Skan    MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, TARGET_FLAGS }
10064169689Skan
10065169689Skan/* Define __builtin_mips_<INSN>_<COND>_{s,d}, both of which require
10066169689Skan   TARGET_FLAGS.  */
10067169689Skan#define CMP_SCALAR_BUILTINS(INSN, COND, TARGET_FLAGS)			\
10068169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_s, MIPS_FP_COND_ ## COND,		\
10069169689Skan    "__builtin_mips_" #INSN "_" #COND "_s",				\
10070169689Skan    MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, TARGET_FLAGS },	\
10071169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_d, MIPS_FP_COND_ ## COND,		\
10072169689Skan    "__builtin_mips_" #INSN "_" #COND "_d",				\
10073169689Skan    MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, TARGET_FLAGS }
10074169689Skan
10075169689Skan/* Define __builtin_mips_{any,all,upper,lower}_<INSN>_<COND>_ps.
10076169689Skan   The lower and upper forms require TARGET_FLAGS while the any and all
10077169689Skan   forms require MASK_MIPS3D.  */
10078169689Skan#define CMP_PS_BUILTINS(INSN, COND, TARGET_FLAGS)			\
10079169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10080169689Skan    "__builtin_mips_any_" #INSN "_" #COND "_ps",			\
10081169689Skan    MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },	\
10082169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10083169689Skan    "__builtin_mips_all_" #INSN "_" #COND "_ps",			\
10084169689Skan    MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, MASK_MIPS3D },	\
10085169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10086169689Skan    "__builtin_mips_lower_" #INSN "_" #COND "_ps",			\
10087169689Skan    MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, TARGET_FLAGS },	\
10088169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10089169689Skan    "__builtin_mips_upper_" #INSN "_" #COND "_ps",			\
10090169689Skan    MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, TARGET_FLAGS }
10091169689Skan
10092169689Skan/* Define __builtin_mips_{any,all}_<INSN>_<COND>_4s.  The functions
10093169689Skan   require MASK_MIPS3D.  */
10094169689Skan#define CMP_4S_BUILTINS(INSN, COND)					\
10095169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_4s, MIPS_FP_COND_ ## COND,		\
10096169689Skan    "__builtin_mips_any_" #INSN "_" #COND "_4s",			\
10097169689Skan    MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,		\
10098169689Skan    MASK_MIPS3D },							\
10099169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_4s, MIPS_FP_COND_ ## COND,		\
10100169689Skan    "__builtin_mips_all_" #INSN "_" #COND "_4s",			\
10101169689Skan    MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF,		\
10102169689Skan    MASK_MIPS3D }
10103169689Skan
10104169689Skan/* Define __builtin_mips_mov{t,f}_<INSN>_<COND>_ps.  The comparison
10105169689Skan   instruction requires TARGET_FLAGS.  */
10106169689Skan#define MOVTF_BUILTINS(INSN, COND, TARGET_FLAGS)			\
10107169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10108169689Skan    "__builtin_mips_movt_" #INSN "_" #COND "_ps",			\
10109169689Skan    MIPS_BUILTIN_MOVT, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,		\
10110169689Skan    TARGET_FLAGS },							\
10111169689Skan  { CODE_FOR_mips_ ## INSN ## _cond_ps, MIPS_FP_COND_ ## COND,		\
10112169689Skan    "__builtin_mips_movf_" #INSN "_" #COND "_ps",			\
10113169689Skan    MIPS_BUILTIN_MOVF, MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF,		\
10114169689Skan    TARGET_FLAGS }
10115169689Skan
10116169689Skan/* Define all the builtins related to c.cond.fmt condition COND.  */
10117169689Skan#define CMP_BUILTINS(COND)						\
10118169689Skan  MOVTF_BUILTINS (c, COND, MASK_PAIRED_SINGLE_FLOAT),			\
10119169689Skan  MOVTF_BUILTINS (cabs, COND, MASK_MIPS3D),				\
10120169689Skan  CMP_SCALAR_BUILTINS (cabs, COND, MASK_MIPS3D),			\
10121169689Skan  CMP_PS_BUILTINS (c, COND, MASK_PAIRED_SINGLE_FLOAT),			\
10122169689Skan  CMP_PS_BUILTINS (cabs, COND, MASK_MIPS3D),				\
10123169689Skan  CMP_4S_BUILTINS (c, COND),						\
10124169689Skan  CMP_4S_BUILTINS (cabs, COND)
10125169689Skan
10126169689Skanstatic const struct builtin_description mips_bdesc[] =
10127169689Skan{
10128169689Skan  DIRECT_BUILTIN (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10129169689Skan  DIRECT_BUILTIN (pul_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10130169689Skan  DIRECT_BUILTIN (plu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10131169689Skan  DIRECT_BUILTIN (puu_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10132169689Skan  DIRECT_BUILTIN (cvt_ps_s, MIPS_V2SF_FTYPE_SF_SF, MASK_PAIRED_SINGLE_FLOAT),
10133169689Skan  DIRECT_BUILTIN (cvt_s_pl, MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10134169689Skan  DIRECT_BUILTIN (cvt_s_pu, MIPS_SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10135169689Skan  DIRECT_BUILTIN (abs_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT),
10136169689Skan
10137169689Skan  DIRECT_BUILTIN (alnv_ps, MIPS_V2SF_FTYPE_V2SF_V2SF_INT,
10138169689Skan		  MASK_PAIRED_SINGLE_FLOAT),
10139169689Skan  DIRECT_BUILTIN (addr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
10140169689Skan  DIRECT_BUILTIN (mulr_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
10141169689Skan  DIRECT_BUILTIN (cvt_pw_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
10142169689Skan  DIRECT_BUILTIN (cvt_ps_pw, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
10143169689Skan
10144169689Skan  DIRECT_BUILTIN (recip1_s, MIPS_SF_FTYPE_SF, MASK_MIPS3D),
10145169689Skan  DIRECT_BUILTIN (recip1_d, MIPS_DF_FTYPE_DF, MASK_MIPS3D),
10146169689Skan  DIRECT_BUILTIN (recip1_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
10147169689Skan  DIRECT_BUILTIN (recip2_s, MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D),
10148169689Skan  DIRECT_BUILTIN (recip2_d, MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D),
10149169689Skan  DIRECT_BUILTIN (recip2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
10150169689Skan
10151169689Skan  DIRECT_BUILTIN (rsqrt1_s, MIPS_SF_FTYPE_SF, MASK_MIPS3D),
10152169689Skan  DIRECT_BUILTIN (rsqrt1_d, MIPS_DF_FTYPE_DF, MASK_MIPS3D),
10153169689Skan  DIRECT_BUILTIN (rsqrt1_ps, MIPS_V2SF_FTYPE_V2SF, MASK_MIPS3D),
10154169689Skan  DIRECT_BUILTIN (rsqrt2_s, MIPS_SF_FTYPE_SF_SF, MASK_MIPS3D),
10155169689Skan  DIRECT_BUILTIN (rsqrt2_d, MIPS_DF_FTYPE_DF_DF, MASK_MIPS3D),
10156169689Skan  DIRECT_BUILTIN (rsqrt2_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_MIPS3D),
10157169689Skan
10158169689Skan  MIPS_FP_CONDITIONS (CMP_BUILTINS)
10159169689Skan};
10160169689Skan
10161169689Skan/* Builtin functions for the SB-1 processor.  */
10162169689Skan
10163169689Skan#define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
10164169689Skan
10165169689Skanstatic const struct builtin_description sb1_bdesc[] =
10166169689Skan{
10167169689Skan  DIRECT_BUILTIN (sqrt_ps, MIPS_V2SF_FTYPE_V2SF, MASK_PAIRED_SINGLE_FLOAT)
10168169689Skan};
10169169689Skan
10170169689Skan/* Builtin functions for DSP ASE.  */
10171169689Skan
10172169689Skan#define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
10173169689Skan#define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
10174169689Skan#define CODE_FOR_mips_subq_ph CODE_FOR_subv2hi3
10175169689Skan#define CODE_FOR_mips_subu_qb CODE_FOR_subv4qi3
10176169689Skan
10177169689Skan/* Define a MIPS_BUILTIN_DIRECT_NO_TARGET function for instruction
10178169689Skan   CODE_FOR_mips_<INSN>.  FUNCTION_TYPE and TARGET_FLAGS are
10179169689Skan   builtin_description fields.  */
10180169689Skan#define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS)	\
10181169689Skan  { CODE_FOR_mips_ ## INSN, 0, "__builtin_mips_" #INSN,			\
10182169689Skan    MIPS_BUILTIN_DIRECT_NO_TARGET, FUNCTION_TYPE, TARGET_FLAGS }
10183169689Skan
10184169689Skan/* Define __builtin_mips_bposge<VALUE>.  <VALUE> is 32 for the MIPS32 DSP
10185169689Skan   branch instruction.  TARGET_FLAGS is a builtin_description field.  */
10186169689Skan#define BPOSGE_BUILTIN(VALUE, TARGET_FLAGS)				\
10187169689Skan  { CODE_FOR_mips_bposge, 0, "__builtin_mips_bposge" #VALUE,		\
10188169689Skan    MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, TARGET_FLAGS }
10189169689Skan
10190169689Skanstatic const struct builtin_description dsp_bdesc[] =
10191169689Skan{
10192169689Skan  DIRECT_BUILTIN (addq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10193169689Skan  DIRECT_BUILTIN (addq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10194169689Skan  DIRECT_BUILTIN (addq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10195169689Skan  DIRECT_BUILTIN (addu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
10196169689Skan  DIRECT_BUILTIN (addu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
10197169689Skan  DIRECT_BUILTIN (subq_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10198169689Skan  DIRECT_BUILTIN (subq_s_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10199169689Skan  DIRECT_BUILTIN (subq_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10200169689Skan  DIRECT_BUILTIN (subu_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
10201169689Skan  DIRECT_BUILTIN (subu_s_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
10202169689Skan  DIRECT_BUILTIN (addsc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10203169689Skan  DIRECT_BUILTIN (addwc, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10204169689Skan  DIRECT_BUILTIN (modsub, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10205169689Skan  DIRECT_BUILTIN (raddu_w_qb, MIPS_SI_FTYPE_V4QI, MASK_DSP),
10206169689Skan  DIRECT_BUILTIN (absq_s_ph, MIPS_V2HI_FTYPE_V2HI, MASK_DSP),
10207169689Skan  DIRECT_BUILTIN (absq_s_w, MIPS_SI_FTYPE_SI, MASK_DSP),
10208169689Skan  DIRECT_BUILTIN (precrq_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
10209169689Skan  DIRECT_BUILTIN (precrq_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
10210169689Skan  DIRECT_BUILTIN (precrq_rs_ph_w, MIPS_V2HI_FTYPE_SI_SI, MASK_DSP),
10211169689Skan  DIRECT_BUILTIN (precrqu_s_qb_ph, MIPS_V4QI_FTYPE_V2HI_V2HI, MASK_DSP),
10212169689Skan  DIRECT_BUILTIN (preceq_w_phl, MIPS_SI_FTYPE_V2HI, MASK_DSP),
10213169689Skan  DIRECT_BUILTIN (preceq_w_phr, MIPS_SI_FTYPE_V2HI, MASK_DSP),
10214169689Skan  DIRECT_BUILTIN (precequ_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10215169689Skan  DIRECT_BUILTIN (precequ_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10216169689Skan  DIRECT_BUILTIN (precequ_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10217169689Skan  DIRECT_BUILTIN (precequ_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10218169689Skan  DIRECT_BUILTIN (preceu_ph_qbl, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10219169689Skan  DIRECT_BUILTIN (preceu_ph_qbr, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10220169689Skan  DIRECT_BUILTIN (preceu_ph_qbla, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10221169689Skan  DIRECT_BUILTIN (preceu_ph_qbra, MIPS_V2HI_FTYPE_V4QI, MASK_DSP),
10222169689Skan  DIRECT_BUILTIN (shll_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
10223169689Skan  DIRECT_BUILTIN (shll_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
10224169689Skan  DIRECT_BUILTIN (shll_s_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
10225169689Skan  DIRECT_BUILTIN (shll_s_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10226169689Skan  DIRECT_BUILTIN (shrl_qb, MIPS_V4QI_FTYPE_V4QI_SI, MASK_DSP),
10227169689Skan  DIRECT_BUILTIN (shra_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
10228169689Skan  DIRECT_BUILTIN (shra_r_ph, MIPS_V2HI_FTYPE_V2HI_SI, MASK_DSP),
10229169689Skan  DIRECT_BUILTIN (shra_r_w, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10230169689Skan  DIRECT_BUILTIN (muleu_s_ph_qbl, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
10231169689Skan  DIRECT_BUILTIN (muleu_s_ph_qbr, MIPS_V2HI_FTYPE_V4QI_V2HI, MASK_DSP),
10232169689Skan  DIRECT_BUILTIN (mulq_rs_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10233169689Skan  DIRECT_BUILTIN (muleq_s_w_phl, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
10234169689Skan  DIRECT_BUILTIN (muleq_s_w_phr, MIPS_SI_FTYPE_V2HI_V2HI, MASK_DSP),
10235169689Skan  DIRECT_BUILTIN (dpau_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
10236169689Skan  DIRECT_BUILTIN (dpau_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
10237169689Skan  DIRECT_BUILTIN (dpsu_h_qbl, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
10238169689Skan  DIRECT_BUILTIN (dpsu_h_qbr, MIPS_DI_FTYPE_DI_V4QI_V4QI, MASK_DSP),
10239169689Skan  DIRECT_BUILTIN (dpaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10240169689Skan  DIRECT_BUILTIN (dpsq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10241169689Skan  DIRECT_BUILTIN (mulsaq_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10242169689Skan  DIRECT_BUILTIN (dpaq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
10243169689Skan  DIRECT_BUILTIN (dpsq_sa_l_w, MIPS_DI_FTYPE_DI_SI_SI, MASK_DSP),
10244169689Skan  DIRECT_BUILTIN (maq_s_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10245169689Skan  DIRECT_BUILTIN (maq_s_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10246169689Skan  DIRECT_BUILTIN (maq_sa_w_phl, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10247169689Skan  DIRECT_BUILTIN (maq_sa_w_phr, MIPS_DI_FTYPE_DI_V2HI_V2HI, MASK_DSP),
10248169689Skan  DIRECT_BUILTIN (bitrev, MIPS_SI_FTYPE_SI, MASK_DSP),
10249169689Skan  DIRECT_BUILTIN (insv, MIPS_SI_FTYPE_SI_SI, MASK_DSP),
10250169689Skan  DIRECT_BUILTIN (repl_qb, MIPS_V4QI_FTYPE_SI, MASK_DSP),
10251169689Skan  DIRECT_BUILTIN (repl_ph, MIPS_V2HI_FTYPE_SI, MASK_DSP),
10252169689Skan  DIRECT_NO_TARGET_BUILTIN (cmpu_eq_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
10253169689Skan  DIRECT_NO_TARGET_BUILTIN (cmpu_lt_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
10254169689Skan  DIRECT_NO_TARGET_BUILTIN (cmpu_le_qb, MIPS_VOID_FTYPE_V4QI_V4QI, MASK_DSP),
10255169689Skan  DIRECT_BUILTIN (cmpgu_eq_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
10256169689Skan  DIRECT_BUILTIN (cmpgu_lt_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
10257169689Skan  DIRECT_BUILTIN (cmpgu_le_qb, MIPS_SI_FTYPE_V4QI_V4QI, MASK_DSP),
10258169689Skan  DIRECT_NO_TARGET_BUILTIN (cmp_eq_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
10259169689Skan  DIRECT_NO_TARGET_BUILTIN (cmp_lt_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
10260169689Skan  DIRECT_NO_TARGET_BUILTIN (cmp_le_ph, MIPS_VOID_FTYPE_V2HI_V2HI, MASK_DSP),
10261169689Skan  DIRECT_BUILTIN (pick_qb, MIPS_V4QI_FTYPE_V4QI_V4QI, MASK_DSP),
10262169689Skan  DIRECT_BUILTIN (pick_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10263169689Skan  DIRECT_BUILTIN (packrl_ph, MIPS_V2HI_FTYPE_V2HI_V2HI, MASK_DSP),
10264169689Skan  DIRECT_BUILTIN (extr_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10265169689Skan  DIRECT_BUILTIN (extr_r_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10266169689Skan  DIRECT_BUILTIN (extr_rs_w, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10267169689Skan  DIRECT_BUILTIN (extr_s_h, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10268169689Skan  DIRECT_BUILTIN (extp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10269169689Skan  DIRECT_BUILTIN (extpdp, MIPS_SI_FTYPE_DI_SI, MASK_DSP),
10270169689Skan  DIRECT_BUILTIN (shilo, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
10271169689Skan  DIRECT_BUILTIN (mthlip, MIPS_DI_FTYPE_DI_SI, MASK_DSP),
10272169689Skan  DIRECT_NO_TARGET_BUILTIN (wrdsp, MIPS_VOID_FTYPE_SI_SI, MASK_DSP),
10273169689Skan  DIRECT_BUILTIN (rddsp, MIPS_SI_FTYPE_SI, MASK_DSP),
10274169689Skan  DIRECT_BUILTIN (lbux, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
10275169689Skan  DIRECT_BUILTIN (lhx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
10276169689Skan  DIRECT_BUILTIN (lwx, MIPS_SI_FTYPE_PTR_SI, MASK_DSP),
10277169689Skan  BPOSGE_BUILTIN (32, MASK_DSP)
10278169689Skan};
10279169689Skan
10280169689Skan/* This helps provide a mapping from builtin function codes to bdesc
10281169689Skan   arrays.  */
10282169689Skan
10283169689Skanstruct bdesc_map
10284169689Skan{
10285169689Skan  /* The builtin function table that this entry describes.  */
10286169689Skan  const struct builtin_description *bdesc;
10287169689Skan
10288169689Skan  /* The number of entries in the builtin function table.  */
10289169689Skan  unsigned int size;
10290169689Skan
10291169689Skan  /* The target processor that supports these builtin functions.
10292169689Skan     PROCESSOR_MAX means we enable them for all processors.  */
10293169689Skan  enum processor_type proc;
10294169689Skan};
10295169689Skan
10296169689Skanstatic const struct bdesc_map bdesc_arrays[] =
10297169689Skan{
10298169689Skan  { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_MAX },
10299169689Skan  { sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 },
10300169689Skan  { dsp_bdesc, ARRAY_SIZE (dsp_bdesc), PROCESSOR_MAX }
10301169689Skan};
10302169689Skan
10303169689Skan/* Take the head of argument list *ARGLIST and convert it into a form
10304169689Skan   suitable for input operand OP of instruction ICODE.  Return the value
10305169689Skan   and point *ARGLIST at the next element of the list.  */
10306169689Skan
10307169689Skanstatic rtx
10308169689Skanmips_prepare_builtin_arg (enum insn_code icode,
10309169689Skan			  unsigned int op, tree *arglist)
10310169689Skan{
10311169689Skan  rtx value;
10312169689Skan  enum machine_mode mode;
10313169689Skan
10314169689Skan  value = expand_normal (TREE_VALUE (*arglist));
10315169689Skan  mode = insn_data[icode].operand[op].mode;
10316169689Skan  if (!insn_data[icode].operand[op].predicate (value, mode))
10317169689Skan    {
10318169689Skan      value = copy_to_mode_reg (mode, value);
10319169689Skan      /* Check the predicate again.  */
10320169689Skan      if (!insn_data[icode].operand[op].predicate (value, mode))
10321169689Skan	{
10322169689Skan	  error ("invalid argument to builtin function");
10323169689Skan	  return const0_rtx;
10324169689Skan	}
10325169689Skan    }
10326169689Skan
10327169689Skan  *arglist = TREE_CHAIN (*arglist);
10328169689Skan  return value;
10329169689Skan}
10330169689Skan
10331169689Skan/* Return an rtx suitable for output operand OP of instruction ICODE.
10332169689Skan   If TARGET is non-null, try to use it where possible.  */
10333169689Skan
10334169689Skanstatic rtx
10335169689Skanmips_prepare_builtin_target (enum insn_code icode, unsigned int op, rtx target)
10336169689Skan{
10337169689Skan  enum machine_mode mode;
10338169689Skan
10339169689Skan  mode = insn_data[icode].operand[op].mode;
10340169689Skan  if (target == 0 || !insn_data[icode].operand[op].predicate (target, mode))
10341169689Skan    target = gen_reg_rtx (mode);
10342169689Skan
10343169689Skan  return target;
10344169689Skan}
10345169689Skan
10346169689Skan/* Expand builtin functions.  This is called from TARGET_EXPAND_BUILTIN.  */
10347169689Skan
10348169689Skanrtx
10349169689Skanmips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
10350169689Skan		     enum machine_mode mode ATTRIBUTE_UNUSED,
10351169689Skan		     int ignore ATTRIBUTE_UNUSED)
10352169689Skan{
10353169689Skan  enum insn_code icode;
10354169689Skan  enum mips_builtin_type type;
10355169689Skan  tree fndecl, arglist;
10356169689Skan  unsigned int fcode;
10357169689Skan  const struct builtin_description *bdesc;
10358169689Skan  const struct bdesc_map *m;
10359169689Skan
10360169689Skan  fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
10361169689Skan  arglist = TREE_OPERAND (exp, 1);
10362169689Skan  fcode = DECL_FUNCTION_CODE (fndecl);
10363169689Skan
10364169689Skan  bdesc = NULL;
10365169689Skan  for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++)
10366169689Skan    {
10367169689Skan      if (fcode < m->size)
10368169689Skan	{
10369169689Skan	  bdesc = m->bdesc;
10370169689Skan	  icode = bdesc[fcode].icode;
10371169689Skan	  type = bdesc[fcode].builtin_type;
10372169689Skan	  break;
10373169689Skan	}
10374169689Skan      fcode -= m->size;
10375169689Skan    }
10376169689Skan  if (bdesc == NULL)
10377169689Skan    return 0;
10378169689Skan
10379169689Skan  switch (type)
10380169689Skan    {
10381169689Skan    case MIPS_BUILTIN_DIRECT:
10382169689Skan      return mips_expand_builtin_direct (icode, target, arglist, true);
10383169689Skan
10384169689Skan    case MIPS_BUILTIN_DIRECT_NO_TARGET:
10385169689Skan      return mips_expand_builtin_direct (icode, target, arglist, false);
10386169689Skan
10387169689Skan    case MIPS_BUILTIN_MOVT:
10388169689Skan    case MIPS_BUILTIN_MOVF:
10389169689Skan      return mips_expand_builtin_movtf (type, icode, bdesc[fcode].cond,
10390169689Skan					target, arglist);
10391169689Skan
10392169689Skan    case MIPS_BUILTIN_CMP_ANY:
10393169689Skan    case MIPS_BUILTIN_CMP_ALL:
10394169689Skan    case MIPS_BUILTIN_CMP_UPPER:
10395169689Skan    case MIPS_BUILTIN_CMP_LOWER:
10396169689Skan    case MIPS_BUILTIN_CMP_SINGLE:
10397169689Skan      return mips_expand_builtin_compare (type, icode, bdesc[fcode].cond,
10398169689Skan					  target, arglist);
10399169689Skan
10400169689Skan    case MIPS_BUILTIN_BPOSGE32:
10401169689Skan      return mips_expand_builtin_bposge (type, target);
10402169689Skan
10403169689Skan    default:
10404169689Skan      return 0;
10405169689Skan    }
10406169689Skan}
10407169689Skan
10408169689Skan/* Init builtin functions.  This is called from TARGET_INIT_BUILTIN.  */
10409169689Skan
10410169689Skanvoid
10411169689Skanmips_init_builtins (void)
10412169689Skan{
10413169689Skan  const struct builtin_description *d;
10414169689Skan  const struct bdesc_map *m;
10415169689Skan  tree types[(int) MIPS_MAX_FTYPE_MAX];
10416169689Skan  tree V2SF_type_node;
10417169689Skan  tree V2HI_type_node;
10418169689Skan  tree V4QI_type_node;
10419169689Skan  unsigned int offset;
10420169689Skan
10421169689Skan  /* We have only builtins for -mpaired-single, -mips3d and -mdsp.  */
10422169689Skan  if (!TARGET_PAIRED_SINGLE_FLOAT && !TARGET_DSP)
10423169689Skan    return;
10424169689Skan
10425169689Skan  if (TARGET_PAIRED_SINGLE_FLOAT)
10426169689Skan    {
10427169689Skan      V2SF_type_node = build_vector_type_for_mode (float_type_node, V2SFmode);
10428169689Skan
10429169689Skan      types[MIPS_V2SF_FTYPE_V2SF]
10430169689Skan	= build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
10431169689Skan
10432169689Skan      types[MIPS_V2SF_FTYPE_V2SF_V2SF]
10433169689Skan	= build_function_type_list (V2SF_type_node,
10434169689Skan				    V2SF_type_node, V2SF_type_node, NULL_TREE);
10435169689Skan
10436169689Skan      types[MIPS_V2SF_FTYPE_V2SF_V2SF_INT]
10437169689Skan	= build_function_type_list (V2SF_type_node,
10438169689Skan				    V2SF_type_node, V2SF_type_node,
10439169689Skan				    integer_type_node, NULL_TREE);
10440169689Skan
10441169689Skan      types[MIPS_V2SF_FTYPE_V2SF_V2SF_V2SF_V2SF]
10442169689Skan	= build_function_type_list (V2SF_type_node,
10443169689Skan				    V2SF_type_node, V2SF_type_node,
10444169689Skan				    V2SF_type_node, V2SF_type_node, NULL_TREE);
10445169689Skan
10446169689Skan      types[MIPS_V2SF_FTYPE_SF_SF]
10447169689Skan	= build_function_type_list (V2SF_type_node,
10448169689Skan				    float_type_node, float_type_node, NULL_TREE);
10449169689Skan
10450169689Skan      types[MIPS_INT_FTYPE_V2SF_V2SF]
10451169689Skan	= build_function_type_list (integer_type_node,
10452169689Skan				    V2SF_type_node, V2SF_type_node, NULL_TREE);
10453169689Skan
10454169689Skan      types[MIPS_INT_FTYPE_V2SF_V2SF_V2SF_V2SF]
10455169689Skan	= build_function_type_list (integer_type_node,
10456169689Skan				    V2SF_type_node, V2SF_type_node,
10457169689Skan				    V2SF_type_node, V2SF_type_node, NULL_TREE);
10458169689Skan
10459169689Skan      types[MIPS_INT_FTYPE_SF_SF]
10460169689Skan	= build_function_type_list (integer_type_node,
10461169689Skan				    float_type_node, float_type_node, NULL_TREE);
10462169689Skan
10463169689Skan      types[MIPS_INT_FTYPE_DF_DF]
10464169689Skan	= build_function_type_list (integer_type_node,
10465169689Skan				    double_type_node, double_type_node, NULL_TREE);
10466169689Skan
10467169689Skan      types[MIPS_SF_FTYPE_V2SF]
10468169689Skan	= build_function_type_list (float_type_node, V2SF_type_node, NULL_TREE);
10469169689Skan
10470169689Skan      types[MIPS_SF_FTYPE_SF]
10471169689Skan	= build_function_type_list (float_type_node,
10472169689Skan				    float_type_node, NULL_TREE);
10473169689Skan
10474169689Skan      types[MIPS_SF_FTYPE_SF_SF]
10475169689Skan	= build_function_type_list (float_type_node,
10476169689Skan				    float_type_node, float_type_node, NULL_TREE);
10477169689Skan
10478169689Skan      types[MIPS_DF_FTYPE_DF]
10479169689Skan	= build_function_type_list (double_type_node,
10480169689Skan				    double_type_node, NULL_TREE);
10481169689Skan
10482169689Skan      types[MIPS_DF_FTYPE_DF_DF]
10483169689Skan	= build_function_type_list (double_type_node,
10484169689Skan				    double_type_node, double_type_node, NULL_TREE);
10485169689Skan    }
10486169689Skan
10487169689Skan  if (TARGET_DSP)
10488169689Skan    {
10489169689Skan      V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
10490169689Skan      V4QI_type_node = build_vector_type_for_mode (intQI_type_node, V4QImode);
10491169689Skan
10492169689Skan      types[MIPS_V2HI_FTYPE_V2HI_V2HI]
10493169689Skan	= build_function_type_list (V2HI_type_node,
10494169689Skan				    V2HI_type_node, V2HI_type_node,
10495169689Skan				    NULL_TREE);
10496169689Skan
10497169689Skan      types[MIPS_SI_FTYPE_SI_SI]
10498169689Skan	= build_function_type_list (intSI_type_node,
10499169689Skan				    intSI_type_node, intSI_type_node,
10500169689Skan				    NULL_TREE);
10501169689Skan
10502169689Skan      types[MIPS_V4QI_FTYPE_V4QI_V4QI]
10503169689Skan	= build_function_type_list (V4QI_type_node,
10504169689Skan				    V4QI_type_node, V4QI_type_node,
10505169689Skan				    NULL_TREE);
10506169689Skan
10507169689Skan      types[MIPS_SI_FTYPE_V4QI]
10508169689Skan	= build_function_type_list (intSI_type_node,
10509169689Skan				    V4QI_type_node,
10510169689Skan				    NULL_TREE);
10511169689Skan
10512169689Skan      types[MIPS_V2HI_FTYPE_V2HI]
10513169689Skan	= build_function_type_list (V2HI_type_node,
10514169689Skan				    V2HI_type_node,
10515169689Skan				    NULL_TREE);
10516169689Skan
10517169689Skan      types[MIPS_SI_FTYPE_SI]
10518169689Skan	= build_function_type_list (intSI_type_node,
10519169689Skan				    intSI_type_node,
10520169689Skan				    NULL_TREE);
10521169689Skan
10522169689Skan      types[MIPS_V4QI_FTYPE_V2HI_V2HI]
10523169689Skan	= build_function_type_list (V4QI_type_node,
10524169689Skan				    V2HI_type_node, V2HI_type_node,
10525169689Skan				    NULL_TREE);
10526169689Skan
10527169689Skan      types[MIPS_V2HI_FTYPE_SI_SI]
10528169689Skan	= build_function_type_list (V2HI_type_node,
10529169689Skan				    intSI_type_node, intSI_type_node,
10530169689Skan				    NULL_TREE);
10531169689Skan
10532169689Skan      types[MIPS_SI_FTYPE_V2HI]
10533169689Skan	= build_function_type_list (intSI_type_node,
10534169689Skan				    V2HI_type_node,
10535169689Skan				    NULL_TREE);
10536169689Skan
10537169689Skan      types[MIPS_V2HI_FTYPE_V4QI]
10538169689Skan	= build_function_type_list (V2HI_type_node,
10539169689Skan				    V4QI_type_node,
10540169689Skan				    NULL_TREE);
10541169689Skan
10542169689Skan      types[MIPS_V4QI_FTYPE_V4QI_SI]
10543169689Skan	= build_function_type_list (V4QI_type_node,
10544169689Skan				    V4QI_type_node, intSI_type_node,
10545169689Skan				    NULL_TREE);
10546169689Skan
10547169689Skan      types[MIPS_V2HI_FTYPE_V2HI_SI]
10548169689Skan	= build_function_type_list (V2HI_type_node,
10549169689Skan				    V2HI_type_node, intSI_type_node,
10550169689Skan				    NULL_TREE);
10551169689Skan
10552169689Skan      types[MIPS_V2HI_FTYPE_V4QI_V2HI]
10553169689Skan	= build_function_type_list (V2HI_type_node,
10554169689Skan				    V4QI_type_node, V2HI_type_node,
10555169689Skan				    NULL_TREE);
10556169689Skan
10557169689Skan      types[MIPS_SI_FTYPE_V2HI_V2HI]
10558169689Skan	= build_function_type_list (intSI_type_node,
10559169689Skan				    V2HI_type_node, V2HI_type_node,
10560169689Skan				    NULL_TREE);
10561169689Skan
10562169689Skan      types[MIPS_DI_FTYPE_DI_V4QI_V4QI]
10563169689Skan	= build_function_type_list (intDI_type_node,
10564169689Skan				    intDI_type_node, V4QI_type_node, V4QI_type_node,
10565169689Skan				    NULL_TREE);
10566169689Skan
10567169689Skan      types[MIPS_DI_FTYPE_DI_V2HI_V2HI]
10568169689Skan	= build_function_type_list (intDI_type_node,
10569169689Skan				    intDI_type_node, V2HI_type_node, V2HI_type_node,
10570169689Skan				    NULL_TREE);
10571169689Skan
10572169689Skan      types[MIPS_DI_FTYPE_DI_SI_SI]
10573169689Skan	= build_function_type_list (intDI_type_node,
10574169689Skan				    intDI_type_node, intSI_type_node, intSI_type_node,
10575169689Skan				    NULL_TREE);
10576169689Skan
10577169689Skan      types[MIPS_V4QI_FTYPE_SI]
10578169689Skan	= build_function_type_list (V4QI_type_node,
10579169689Skan				    intSI_type_node,
10580169689Skan				    NULL_TREE);
10581169689Skan
10582169689Skan      types[MIPS_V2HI_FTYPE_SI]
10583169689Skan	= build_function_type_list (V2HI_type_node,
10584169689Skan				    intSI_type_node,
10585169689Skan				    NULL_TREE);
10586169689Skan
10587169689Skan      types[MIPS_VOID_FTYPE_V4QI_V4QI]
10588169689Skan	= build_function_type_list (void_type_node,
10589169689Skan				    V4QI_type_node, V4QI_type_node,
10590169689Skan				    NULL_TREE);
10591169689Skan
10592169689Skan      types[MIPS_SI_FTYPE_V4QI_V4QI]
10593169689Skan	= build_function_type_list (intSI_type_node,
10594169689Skan				    V4QI_type_node, V4QI_type_node,
10595169689Skan				    NULL_TREE);
10596169689Skan
10597169689Skan      types[MIPS_VOID_FTYPE_V2HI_V2HI]
10598169689Skan	= build_function_type_list (void_type_node,
10599169689Skan				    V2HI_type_node, V2HI_type_node,
10600169689Skan				    NULL_TREE);
10601169689Skan
10602169689Skan      types[MIPS_SI_FTYPE_DI_SI]
10603169689Skan	= build_function_type_list (intSI_type_node,
10604169689Skan				    intDI_type_node, intSI_type_node,
10605169689Skan				    NULL_TREE);
10606169689Skan
10607169689Skan      types[MIPS_DI_FTYPE_DI_SI]
10608169689Skan	= build_function_type_list (intDI_type_node,
10609169689Skan				    intDI_type_node, intSI_type_node,
10610169689Skan				    NULL_TREE);
10611169689Skan
10612169689Skan      types[MIPS_VOID_FTYPE_SI_SI]
10613169689Skan	= build_function_type_list (void_type_node,
10614169689Skan				    intSI_type_node, intSI_type_node,
10615169689Skan				    NULL_TREE);
10616169689Skan
10617169689Skan      types[MIPS_SI_FTYPE_PTR_SI]
10618169689Skan	= build_function_type_list (intSI_type_node,
10619169689Skan				    ptr_type_node, intSI_type_node,
10620169689Skan				    NULL_TREE);
10621169689Skan
10622169689Skan      types[MIPS_SI_FTYPE_VOID]
10623169689Skan	= build_function_type (intSI_type_node, void_list_node);
10624169689Skan    }
10625169689Skan
10626169689Skan  /* Iterate through all of the bdesc arrays, initializing all of the
10627169689Skan     builtin functions.  */
10628169689Skan
10629169689Skan  offset = 0;
10630169689Skan  for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++)
10631169689Skan    {
10632169689Skan      if (m->proc == PROCESSOR_MAX || (m->proc == mips_arch))
10633169689Skan	for (d = m->bdesc; d < &m->bdesc[m->size]; d++)
10634169689Skan	  if ((d->target_flags & target_flags) == d->target_flags)
10635169689Skan	    lang_hooks.builtin_function (d->name, types[d->function_type],
10636169689Skan					 d - m->bdesc + offset,
10637169689Skan					 BUILT_IN_MD, NULL, NULL);
10638169689Skan      offset += m->size;
10639169689Skan    }
10640169689Skan}
10641169689Skan
10642169689Skan/* Expand a MIPS_BUILTIN_DIRECT function.  ICODE is the code of the
10643169689Skan   .md pattern and ARGLIST is the list of function arguments.  TARGET,
10644169689Skan   if nonnull, suggests a good place to put the result.
10645169689Skan   HAS_TARGET indicates the function must return something.  */
10646169689Skan
10647169689Skanstatic rtx
10648169689Skanmips_expand_builtin_direct (enum insn_code icode, rtx target, tree arglist,
10649169689Skan			    bool has_target)
10650169689Skan{
10651169689Skan  rtx ops[MAX_RECOG_OPERANDS];
10652169689Skan  int i = 0;
10653169689Skan
10654169689Skan  if (has_target)
10655169689Skan    {
10656169689Skan      /* We save target to ops[0].  */
10657169689Skan      ops[0] = mips_prepare_builtin_target (icode, 0, target);
10658169689Skan      i = 1;
10659169689Skan    }
10660169689Skan
10661169689Skan  /* We need to test if arglist is not zero.  Some instructions have extra
10662169689Skan     clobber registers.  */
10663169689Skan  for (; i < insn_data[icode].n_operands && arglist != 0; i++)
10664169689Skan    ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
10665169689Skan
10666169689Skan  switch (i)
10667169689Skan    {
10668169689Skan    case 2:
10669169689Skan      emit_insn (GEN_FCN (icode) (ops[0], ops[1]));
10670169689Skan      break;
10671169689Skan
10672169689Skan    case 3:
10673169689Skan      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2]));
10674169689Skan      break;
10675169689Skan
10676169689Skan    case 4:
10677169689Skan      emit_insn (GEN_FCN (icode) (ops[0], ops[1], ops[2], ops[3]));
10678169689Skan      break;
10679169689Skan
10680169689Skan    default:
10681169689Skan      gcc_unreachable ();
10682169689Skan    }
10683169689Skan  return target;
10684169689Skan}
10685169689Skan
10686169689Skan/* Expand a __builtin_mips_movt_*_ps() or __builtin_mips_movf_*_ps()
10687169689Skan   function (TYPE says which).  ARGLIST is the list of arguments to the
10688169689Skan   function, ICODE is the instruction that should be used to compare
10689169689Skan   the first two arguments, and COND is the condition it should test.
10690169689Skan   TARGET, if nonnull, suggests a good place to put the result.  */
10691169689Skan
10692169689Skanstatic rtx
10693169689Skanmips_expand_builtin_movtf (enum mips_builtin_type type,
10694169689Skan			   enum insn_code icode, enum mips_fp_condition cond,
10695169689Skan			   rtx target, tree arglist)
10696169689Skan{
10697169689Skan  rtx cmp_result, op0, op1;
10698169689Skan
10699169689Skan  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10700169689Skan  op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10701169689Skan  op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10702169689Skan  emit_insn (GEN_FCN (icode) (cmp_result, op0, op1, GEN_INT (cond)));
10703169689Skan
10704169689Skan  icode = CODE_FOR_mips_cond_move_tf_ps;
10705169689Skan  target = mips_prepare_builtin_target (icode, 0, target);
10706169689Skan  if (type == MIPS_BUILTIN_MOVT)
10707169689Skan    {
10708169689Skan      op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10709169689Skan      op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10710169689Skan    }
10711169689Skan  else
10712169689Skan    {
10713169689Skan      op0 = mips_prepare_builtin_arg (icode, 1, &arglist);
10714169689Skan      op1 = mips_prepare_builtin_arg (icode, 2, &arglist);
10715169689Skan    }
10716169689Skan  emit_insn (gen_mips_cond_move_tf_ps (target, op0, op1, cmp_result));
10717169689Skan  return target;
10718169689Skan}
10719169689Skan
10720169689Skan/* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
10721169689Skan   into TARGET otherwise.  Return TARGET.  */
10722169689Skan
10723169689Skanstatic rtx
10724169689Skanmips_builtin_branch_and_move (rtx condition, rtx target,
10725169689Skan			      rtx value_if_true, rtx value_if_false)
10726169689Skan{
10727169689Skan  rtx true_label, done_label;
10728169689Skan
10729169689Skan  true_label = gen_label_rtx ();
10730169689Skan  done_label = gen_label_rtx ();
10731169689Skan
10732169689Skan  /* First assume that CONDITION is false.  */
10733169689Skan  emit_move_insn (target, value_if_false);
10734169689Skan
10735169689Skan  /* Branch to TRUE_LABEL if CONDITION is true and DONE_LABEL otherwise.  */
10736169689Skan  emit_jump_insn (gen_condjump (condition, true_label));
10737169689Skan  emit_jump_insn (gen_jump (done_label));
10738169689Skan  emit_barrier ();
10739169689Skan
10740169689Skan  /* Fix TARGET if CONDITION is true.  */
10741169689Skan  emit_label (true_label);
10742169689Skan  emit_move_insn (target, value_if_true);
10743169689Skan
10744169689Skan  emit_label (done_label);
10745169689Skan  return target;
10746169689Skan}
10747169689Skan
10748169689Skan/* Expand a comparison builtin of type BUILTIN_TYPE.  ICODE is the code
10749169689Skan   of the comparison instruction and COND is the condition it should test.
10750169689Skan   ARGLIST is the list of function arguments and TARGET, if nonnull,
10751169689Skan   suggests a good place to put the boolean result.  */
10752169689Skan
10753169689Skanstatic rtx
10754169689Skanmips_expand_builtin_compare (enum mips_builtin_type builtin_type,
10755169689Skan			     enum insn_code icode, enum mips_fp_condition cond,
10756169689Skan			     rtx target, tree arglist)
10757169689Skan{
10758169689Skan  rtx offset, condition, cmp_result, ops[MAX_RECOG_OPERANDS];
10759169689Skan  int i;
10760169689Skan
10761169689Skan  if (target == 0 || GET_MODE (target) != SImode)
10762169689Skan    target = gen_reg_rtx (SImode);
10763169689Skan
10764169689Skan  /* Prepare the operands to the comparison.  */
10765169689Skan  cmp_result = mips_prepare_builtin_target (icode, 0, 0);
10766169689Skan  for (i = 1; i < insn_data[icode].n_operands - 1; i++)
10767169689Skan    ops[i] = mips_prepare_builtin_arg (icode, i, &arglist);
10768169689Skan
10769169689Skan  switch (insn_data[icode].n_operands)
10770169689Skan    {
10771169689Skan    case 4:
10772169689Skan      emit_insn (GEN_FCN (icode) (cmp_result, ops[1], ops[2], GEN_INT (cond)));
10773169689Skan      break;
10774169689Skan
10775169689Skan    case 6:
10776169689Skan      emit_insn (GEN_FCN (icode) (cmp_result, ops[1], ops[2],
10777169689Skan				  ops[3], ops[4], GEN_INT (cond)));
10778169689Skan      break;
10779169689Skan
10780169689Skan    default:
10781169689Skan      gcc_unreachable ();
10782169689Skan    }
10783169689Skan
10784169689Skan  /* If the comparison sets more than one register, we define the result
10785169689Skan     to be 0 if all registers are false and -1 if all registers are true.
10786169689Skan     The value of the complete result is indeterminate otherwise.  */
10787169689Skan  switch (builtin_type)
10788169689Skan    {
10789169689Skan    case MIPS_BUILTIN_CMP_ALL:
10790169689Skan      condition = gen_rtx_NE (VOIDmode, cmp_result, constm1_rtx);
10791169689Skan      return mips_builtin_branch_and_move (condition, target,
10792169689Skan					   const0_rtx, const1_rtx);
10793169689Skan
10794169689Skan    case MIPS_BUILTIN_CMP_UPPER:
10795169689Skan    case MIPS_BUILTIN_CMP_LOWER:
10796169689Skan      offset = GEN_INT (builtin_type == MIPS_BUILTIN_CMP_UPPER);
10797169689Skan      condition = gen_single_cc (cmp_result, offset);
10798169689Skan      return mips_builtin_branch_and_move (condition, target,
10799169689Skan					   const1_rtx, const0_rtx);
10800169689Skan
10801169689Skan    default:
10802169689Skan      condition = gen_rtx_NE (VOIDmode, cmp_result, const0_rtx);
10803169689Skan      return mips_builtin_branch_and_move (condition, target,
10804169689Skan					   const1_rtx, const0_rtx);
10805169689Skan    }
10806169689Skan}
10807169689Skan
10808169689Skan/* Expand a bposge builtin of type BUILTIN_TYPE.  TARGET, if nonnull,
10809169689Skan   suggests a good place to put the boolean result.  */
10810169689Skan
10811169689Skanstatic rtx
10812169689Skanmips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
10813169689Skan{
10814169689Skan  rtx condition, cmp_result;
10815169689Skan  int cmp_value;
10816169689Skan
10817169689Skan  if (target == 0 || GET_MODE (target) != SImode)
10818169689Skan    target = gen_reg_rtx (SImode);
10819169689Skan
10820169689Skan  cmp_result = gen_rtx_REG (CCDSPmode, CCDSP_PO_REGNUM);
10821169689Skan
10822169689Skan  if (builtin_type == MIPS_BUILTIN_BPOSGE32)
10823169689Skan    cmp_value = 32;
10824169689Skan  else
10825169689Skan    gcc_assert (0);
10826169689Skan
10827169689Skan  condition = gen_rtx_GE (VOIDmode, cmp_result, GEN_INT (cmp_value));
10828169689Skan  return mips_builtin_branch_and_move (condition, target,
10829169689Skan				       const1_rtx, const0_rtx);
10830169689Skan}
10831169689Skan
10832169689Skan/* Set SYMBOL_REF_FLAGS for the SYMBOL_REF inside RTL, which belongs to DECL.
10833169689Skan   FIRST is true if this is the first time handling this decl.  */
10834169689Skan
10835169689Skanstatic void
10836169689Skanmips_encode_section_info (tree decl, rtx rtl, int first)
10837169689Skan{
10838169689Skan  default_encode_section_info (decl, rtl, first);
10839169689Skan
10840169689Skan  if (TREE_CODE (decl) == FUNCTION_DECL
10841169689Skan      && lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
10842169689Skan    {
10843169689Skan      rtx symbol = XEXP (rtl, 0);
10844169689Skan      SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
10845169689Skan    }
10846169689Skan}
10847169689Skan
10848169689Skan/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  PIC_FUNCTION_ADDR_REGNUM is live
10849169689Skan   on entry to a function when generating -mshared abicalls code.  */
10850169689Skan
10851169689Skanstatic void
10852169689Skanmips_extra_live_on_entry (bitmap regs)
10853169689Skan{
10854169689Skan  if (TARGET_ABICALLS && !TARGET_ABSOLUTE_ABICALLS)
10855169689Skan    bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);
10856169689Skan}
10857169689Skan
10858169689Skan/* SImode values are represented as sign-extended to DImode.  */
10859169689Skan
10860169689Skanint
10861169689Skanmips_mode_rep_extended (enum machine_mode mode, enum machine_mode mode_rep)
10862169689Skan{
10863169689Skan  if (TARGET_64BIT && mode == SImode && mode_rep == DImode)
10864169689Skan    return SIGN_EXTEND;
10865169689Skan
10866169689Skan  return UNKNOWN;
10867169689Skan}
10868169689Skan
10869169689Skan#include "gt-mips.h"
10870