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