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 = ¤t_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