⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mips.c

📁 linux下编程用 编译软件
💻 C
📖 第 1 页 / 共 5 页
字号:
				tree, bool);static int mips_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode mode,				   tree, bool);static bool mips_valid_pointer_mode (enum machine_mode);static bool mips_vector_mode_supported_p (enum machine_mode);static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree *);static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);static rtx mips_expand_builtin (tree, rtx, rtx, enum machine_mode, int);static void mips_init_builtins (void);static rtx mips_expand_builtin_direct (enum insn_code, rtx, tree, bool);static rtx mips_expand_builtin_movtf (enum mips_builtin_type,				      enum insn_code, enum mips_fp_condition,				      rtx, tree);static rtx mips_expand_builtin_compare (enum mips_builtin_type,					enum insn_code, enum mips_fp_condition,					rtx, tree);static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);static void mips_encode_section_info (tree, rtx, int);/* Structure to be filled in by compute_frame_size with register   save masks, and offsets for the current function.  */struct mips_frame_info GTY(()){  HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */  HOST_WIDE_INT var_size;	/* # bytes that variables take up */  HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */  HOST_WIDE_INT cprestore_size;	/* # bytes that the .cprestore slot takes up */  HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */  HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */  unsigned int mask;		/* mask of saved gp registers */  unsigned int fmask;		/* mask of saved fp registers */  HOST_WIDE_INT gp_save_offset;	/* offset from vfp to store gp registers */  HOST_WIDE_INT fp_save_offset;	/* offset from vfp to store fp registers */  HOST_WIDE_INT gp_sp_offset;	/* offset from new sp to store gp registers */  HOST_WIDE_INT fp_sp_offset;	/* offset from new sp to store fp registers */  bool initialized;		/* true if frame size already calculated */  int num_gp;			/* number of gp registers saved */  int num_fp;			/* number of fp registers saved */};struct machine_function GTY(()) {  /* Pseudo-reg holding the value of $28 in a mips16 function which     refers to GP relative global variables.  */  rtx mips16_gp_pseudo_rtx;  /* The number of extra stack bytes taken up by register varargs.     This area is allocated by the callee at the very top of the frame.  */  int varargs_size;  /* Current frame information, calculated by compute_frame_size.  */  struct mips_frame_info frame;  /* The register to use as the global pointer within this function.  */  unsigned int global_pointer;  /* True if mips_adjust_insn_length should ignore an instruction's     hazard attribute.  */  bool ignore_hazard_length_p;  /* True if the whole function is suitable for .set noreorder and     .set nomacro.  */  bool all_noreorder_p;  /* True if the function is known to have an instruction that needs $gp.  */  bool has_gp_insn_p;};/* Information about a single argument.  */struct mips_arg_info{  /* True if the argument is passed in a floating-point register, or     would have been if we hadn't run out of registers.  */  bool fpr_p;  /* The number of words passed in registers, rounded up.  */  unsigned int reg_words;  /* For EABI, the offset of the first register from GP_ARG_FIRST or     FP_ARG_FIRST.  For other ABIs, the offset of the first register from     the start of the ABI's argument structure (see the CUMULATIVE_ARGS     comment for details).     The value is MAX_ARGS_IN_REGISTERS if the argument is passed entirely     on the stack.  */  unsigned int reg_offset;  /* The number of words that must be passed on the stack, rounded up.  */  unsigned int stack_words;  /* The offset from the start of the stack overflow area of the argument's     first stack word.  Only meaningful when STACK_WORDS is nonzero.  */  unsigned int stack_offset;};/* Information about an address described by mips_address_type.   ADDRESS_CONST_INT       No fields are used.   ADDRESS_REG       REG is the base register and OFFSET is the constant offset.   ADDRESS_LO_SUM       REG is the register that contains the high part of the address,       OFFSET is the symbolic address being referenced and SYMBOL_TYPE       is the type of OFFSET's symbol.   ADDRESS_SYMBOLIC       SYMBOL_TYPE is the type of symbol being referenced.  */struct mips_address_info{  enum mips_address_type type;  rtx reg;  rtx offset;  enum mips_symbol_type symbol_type;};/* One stage in a constant building sequence.  These sequences have   the form:	A = VALUE[0]	A = A CODE[1] VALUE[1]	A = A CODE[2] VALUE[2]	...   where A is an accumulator, each CODE[i] is a binary rtl operation   and each VALUE[i] is a constant integer.  */struct mips_integer_op {  enum rtx_code code;  unsigned HOST_WIDE_INT value;};/* The largest number of operations needed to load an integer constant.   The worst accepted case for 64-bit constants is LUI,ORI,SLL,ORI,SLL,ORI.   When the lowest bit is clear, we can try, but reject a sequence with   an extra SLL at the end.  */#define MIPS_MAX_INTEGER_OPS 7/* Global variables for machine-dependent things.  *//* Threshold for data being put into the small data/bss area, instead   of the normal data area.  */int mips_section_threshold = -1;/* Count the number of .file directives, so that .loc is up to date.  */int num_source_filenames = 0;/* Count the number of sdb related labels are generated (to find block   start and end boundaries).  */int sdb_label_count = 0;/* Next label # for each statement for Silicon Graphics IRIS systems.  */int sym_lineno = 0;/* Linked list of all externals that are to be emitted when optimizing   for the global pointer if they haven't been declared by the end of   the program with an appropriate .comm or initialization.  */struct extern_list GTY (()){  struct extern_list *next;	/* next external */  const char *name;		/* name of the external */  int size;			/* size in bytes */};static GTY (()) struct extern_list *extern_head = 0;/* Name of the file containing the current function.  */const char *current_function_file = "";/* Number of nested .set noreorder, noat, nomacro, and volatile requests.  */int set_noreorder;int set_noat;int set_nomacro;int set_volatile;/* The next branch instruction is a branch likely, not branch normal.  */int mips_branch_likely;/* The operands passed to the last cmpMM expander.  */rtx cmp_operands[2];/* The target cpu for code generation.  */enum processor_type mips_arch;const struct mips_cpu_info *mips_arch_info;/* The target cpu for optimization and scheduling.  */enum processor_type mips_tune;const struct mips_cpu_info *mips_tune_info;/* Which instruction set architecture to use.  */int mips_isa;/* Which ABI to use.  */int mips_abi = MIPS_ABI_DEFAULT;/* Cost information to use.  */const struct mips_rtx_cost_data *mips_cost;/* Whether we are generating mips16 hard float code.  In mips16 mode   we always set TARGET_SOFT_FLOAT; this variable is nonzero if   -msoft-float was not specified by the user, which means that we   should arrange to call mips32 hard floating point code.  */int mips16_hard_float;/* The architecture selected by -mipsN.  */static const struct mips_cpu_info *mips_isa_info;/* If TRUE, we split addresses into their high and low parts in the RTL.  */int mips_split_addresses;/* Mode used for saving/restoring general purpose registers.  */static enum machine_mode gpr_mode;/* Array giving truth value on whether or not a given hard register   can support a given mode.  */char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];/* List of all MIPS punctuation characters used by print_operand.  */char mips_print_operand_punct[256];/* Map GCC register number to debugger register number.  */int mips_dbx_regno[FIRST_PSEUDO_REGISTER];/* A copy of the original flag_delayed_branch: see override_options.  */static int mips_flag_delayed_branch;static GTY (()) int mips_output_filename_first_time = 1;/* mips_split_p[X] is true if symbols of type X can be split by   mips_split_symbol().  */static bool mips_split_p[NUM_SYMBOL_TYPES];/* mips_lo_relocs[X] is the relocation to use when a symbol of type X   appears in a LO_SUM.  It can be null if such LO_SUMs aren't valid or   if they are matched by a special .md file pattern.  */static const char *mips_lo_relocs[NUM_SYMBOL_TYPES];/* Likewise for HIGHs.  */static const char *mips_hi_relocs[NUM_SYMBOL_TYPES];/* Map hard register number to register class */const enum reg_class mips_regno_to_class[] ={  LEA_REGS,	LEA_REGS,	M16_NA_REGS,	V1_REG,  M16_REGS,	M16_REGS,	M16_REGS,	M16_REGS,  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,  M16_NA_REGS,	M16_NA_REGS,	LEA_REGS,	LEA_REGS,  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,  T_REG,	PIC_FN_ADDR_REG, LEA_REGS,	LEA_REGS,  LEA_REGS,	LEA_REGS,	LEA_REGS,	LEA_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,  HI_REG,	LO_REG,		NO_REGS,	ST_REGS,  ST_REGS,	ST_REGS,	ST_REGS,	ST_REGS,  ST_REGS,	ST_REGS,	ST_REGS,	NO_REGS,  NO_REGS,	ALL_REGS,	ALL_REGS,	NO_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP0_REGS,	COP0_REGS,	COP0_REGS,	COP0_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP2_REGS,	COP2_REGS,	COP2_REGS,	COP2_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  COP3_REGS,	COP3_REGS,	COP3_REGS,	COP3_REGS,  DSP_ACC_REGS,	DSP_ACC_REGS,	DSP_ACC_REGS,	DSP_ACC_REGS,  DSP_ACC_REGS,	DSP_ACC_REGS,	ALL_REGS,	ALL_REGS,  ALL_REGS,	ALL_REGS,	ALL_REGS,	ALL_REGS};/* Map register constraint character to register class.  */enum reg_class mips_char_to_class[256];/* Table of machine dependent attributes.  */const struct attribute_spec mips_attribute_table[] ={  { "long_call",   0, 0, false, true,  true,  NULL },  { NULL,	   0, 0, false, false, false, NULL }};/* A table describing all the processors gcc knows about.  Names are   matched in the order listed.  The first mention of an ISA level is   taken as the canonical name for that ISA.   To ease comparison, please keep this table in the same order as   gas's mips_cpu_info_table[].  */const struct mips_cpu_info mips_cpu_info_table[] = {  /* Entries for generic ISAs */  { "mips1", PROCESSOR_R3000, 1 },  { "mips2", PROCESSOR_R6000, 2 },  { "mips3", PROCESSOR_R4000, 3 },  { "mips4", PROCESSOR_R8000, 4 },  { "mips32", PROCESSOR_4KC, 32 },  { "mips32r2", PROCESSOR_M4K, 33 },  { "mips64", PROCESSOR_5KC, 64 },  /* MIPS I */  { "r3000", PROCESSOR_R3000, 1 },  { "r2000", PROCESSOR_R3000, 1 }, /* = r3000 */  { "r3900", PROCESSOR_R3900, 1 },  /* MIPS II */  { "r6000", PROCESSOR_R6000, 2 },  /* MIPS III */  { "r4000", PROCESSOR_R4000, 3 },  { "vr4100", PROCESSOR_R4100, 3 },  { "vr4111", PROCESSOR_R4111, 3 },  { "vr4120", PROCESSOR_R4120, 3 },  { "vr4130", PROCESSOR_R4130, 3 },  { "vr4300", PROCESSOR_R4300, 3 },  { "r4400", PROCESSOR_R4000, 3 }, /* = r4000 */  { "r4600", PROCESSOR_R4600, 3 },  { "orion", PROCESSOR_R4600, 3 }, /* = r4600 */  { "r4650", PROCESSOR_R4650, 3 },  /* MIPS IV */  { "r8000", PROCESSOR_R8000, 4 },  { "vr5000", PROCESSOR_R5000, 4 },  { "vr5400", PROCESSOR_R5400, 4 },  { "vr5500", PROCESSOR_R5500, 4 },  { "rm7000", PROCESSOR_R7000, 4 },  { "rm9000", PROCESSOR_R9000, 4 },  /* MIPS32 */  { "4kc", PROCESSOR_4KC, 32 },  { "4km", PROCESSOR_4KC, 32 }, /* = 4kc */  { "4kp", PROCESSOR_4KP, 32 },  /* MIPS32 Release 2 */  { "m4k", PROCESSOR_M4K, 33 },  { "24k", PROCESSOR_24K, 33 },  { "24kc", PROCESSOR_24K, 33 },  /* 24K  no FPU */  { "24kf", PROCESSOR_24K, 33 },  /* 24K 1:2 FPU */  { "24kx", PROCESSOR_24KX, 33 }, /* 24K 1:1 FPU */  /* MIPS64 */  { "5kc", PROCESSOR_5KC, 64 },  { "5kf", PROCESSOR_5KF, 64 },  { "20kc", PROCESSOR_20KC, 64 },  { "sb1", PROCESSOR_SB1, 64 },  { "sr71000", PROCESSOR_SR71000, 64 },  /* End marker */  { 0, 0, 0 }};/* Default costs. If these are used for a processor we should look   up the actual costs.  */#define DEFAULT_COSTS COSTS_N_INSNS (6),  /* fp_add */       \                      COSTS_N_INSNS (7),  /* fp_mult_sf */   \                      COSTS_N_INSNS (8),  /* fp_mult_df */   \                      COSTS_N_INSNS (23), /* fp_div_sf */    \                      COSTS_N_INSNS (36), /* fp_div_df */    \                      COSTS_N_INSNS (10), /* int_mult_si */  \                      COSTS_N_INSNS (10), /* int_mult_di */  \                      COSTS_N_INSNS (69), /* int_div_si */   \                      COSTS_N_INSNS (69), /* int_div_di */   \                                       2, /* branch_cost */  \                                       4  /* memory_latency *//* Need to replace these with the costs of calling the appropriate

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -