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

📄 mips.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Subroutines for insn-output.c for MIPS   Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998,   1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.   Contributed by A. Lichnewsky, lich@inria.inria.fr.   Changes by Michael Meissner, meissner@osf.org.   64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and   Brendan Eich, brendan@microunity.com.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* ??? The TARGET_FP_CALL_32 macros are intended to simulate a 32 bit   calling convention in 64 bit mode.  It doesn't work though, and should   be replaced with something better designed.  */#include "config.h"#include "system.h"#include <signal.h>#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-attr.h"#include "recog.h"#include "toplev.h"#include "output.h"#include "tree.h"#include "function.h"#include "expr.h"#include "flags.h"#include "reload.h"#include "output.h"#include "tm_p.h"#include "ggc.h"#include "gstab.h"#include "hashtab.h"#include "debug.h"#include "target.h"#include "target-def.h"#ifdef __GNU_STAB__#define STAB_CODE_TYPE enum __stab_debug_code#else#define STAB_CODE_TYPE int#endifextern tree   lookup_name PARAMS ((tree));/* Enumeration for all of the relational tests, so that we can build   arrays indexed by the test type, and not worry about the order   of EQ, NE, etc.  */enum internal_test {    ITEST_EQ,    ITEST_NE,    ITEST_GT,    ITEST_GE,    ITEST_LT,    ITEST_LE,    ITEST_GTU,    ITEST_GEU,    ITEST_LTU,    ITEST_LEU,    ITEST_MAX  };struct constant;struct mips_arg_info;static enum internal_test map_test_to_internal_test	PARAMS ((enum rtx_code));static void get_float_compare_codes PARAMS ((enum rtx_code, enum rtx_code *,					     enum rtx_code *));static int mips16_simple_memory_operand		PARAMS ((rtx, rtx,							enum machine_mode));static int m16_check_op				PARAMS ((rtx, int, int, int));static void block_move_loop			PARAMS ((rtx, rtx,							 unsigned int,							 int,							 rtx, rtx));static void block_move_call			PARAMS ((rtx, rtx, rtx));static void mips_arg_info		PARAMS ((const CUMULATIVE_ARGS *,						 enum machine_mode,						 tree, int,						 struct mips_arg_info *));static rtx mips_add_large_offset_to_sp		PARAMS ((HOST_WIDE_INT));static void mips_annotate_frame_insn		PARAMS ((rtx, rtx));static rtx mips_frame_set			PARAMS ((enum machine_mode,							 int, int));static void mips_emit_frame_related_store	PARAMS ((rtx, rtx,							 HOST_WIDE_INT));static void save_restore_insns			PARAMS ((int, rtx, long));static void mips16_output_gp_offset		PARAMS ((FILE *, rtx));static void mips16_fp_args			PARAMS ((FILE *, int, int));static void build_mips16_function_stub		PARAMS ((FILE *));static void mips16_optimize_gp			PARAMS ((rtx));static rtx add_constant				PARAMS ((struct constant **,							rtx,							enum machine_mode));static void dump_constants			PARAMS ((struct constant *,							rtx));static rtx mips_find_symbol			PARAMS ((rtx));static void abort_with_insn			PARAMS ((rtx, const char *))  ATTRIBUTE_NORETURN;static int symbolic_expression_p                PARAMS ((rtx));static bool mips_assemble_integer	  PARAMS ((rtx, unsigned int, int));static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void mips_set_architecture    PARAMS ((const struct mips_cpu_info *));static void mips_set_tune	     PARAMS ((const struct mips_cpu_info *));static bool mips_strict_matching_cpu_name_p	PARAMS ((const char *,							 const char *));static bool mips_matching_cpu_name_p		PARAMS ((const char *,							 const char *));static const struct mips_cpu_info *mips_parse_cpu   PARAMS ((const char *,							      const char *));static const struct mips_cpu_info *mips_cpu_info_from_isa PARAMS ((int));static void copy_file_data			PARAMS ((FILE *, FILE *));#ifdef TARGET_IRIX6static void iris6_asm_named_section_1		PARAMS ((const char *,							 unsigned int,							 unsigned int));static void iris6_asm_named_section		PARAMS ((const char *,							 unsigned int));static int iris_section_align_entry_eq		PARAMS ((const PTR, const PTR));static hashval_t iris_section_align_entry_hash	PARAMS ((const PTR));static int iris6_section_align_1		PARAMS ((void **, void *));#endifstatic int mips_adjust_cost			PARAMS ((rtx, rtx, rtx, int));static int mips_issue_rate			PARAMS ((void));static struct machine_function * mips_init_machine_status PARAMS ((void));static void mips_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT))	ATTRIBUTE_UNUSED;static void mips_unique_section			PARAMS ((tree, int))	ATTRIBUTE_UNUSED;static void mips_select_rtx_section PARAMS ((enum machine_mode, rtx,					     unsigned HOST_WIDE_INT));static int mips_use_dfa_pipeline_interface      PARAMS ((void));static void mips_encode_section_info		PARAMS ((tree, 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(()){  long total_size;		/* # bytes that the entire frame takes up */  long var_size;		/* # bytes that variables take up */  long args_size;		/* # bytes that outgoing arguments take up */  long extra_size;		/* # bytes of extra gunk */  int  gp_reg_size;		/* # bytes needed to store gp regs */  int  fp_reg_size;		/* # bytes needed to store fp regs */  long mask;			/* mask of saved gp registers */  long fmask;			/* mask of saved fp registers */  long gp_save_offset;		/* offset from vfp to store gp registers */  long fp_save_offset;		/* offset from vfp to store fp registers */  long gp_sp_offset;		/* offset from new sp to store gp registers */  long fp_sp_offset;		/* offset from new sp to store fp registers */  int  initialized;		/* != 0 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 address of the current function when     generating embedded PIC code.  Created by LEGITIMIZE_ADDRESS,     used by mips_finalize_pic if it was created.  */  rtx embedded_pic_fnaddr_rtx;  /* Pseudo-reg holding the value of $28 in a mips16 function which     refers to GP relative global variables.  */  rtx mips16_gp_pseudo_rtx;  /* Current frame information, calculated by compute_frame_size.  */  struct mips_frame_info frame;  /* Length of instructions in function; mips16 only.  */  long insns_len;};/* Information about a single argument.  */struct mips_arg_info{  /* True if the argument is a record or union type.  */  bool struct_p;  /* 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 argument's size, in bytes.  */  unsigned int num_bytes;  /* The number of words passed in registers, rounded up.  */  unsigned int reg_words;  /* The offset of the first register from GP_ARG_FIRST or FP_ARG_FIRST,     or 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;};/* Global variables for machine-dependent things.  *//* Threshold for data being put into the small data/bss area, instead   of the normal data area (references to the small data/bss area take   1 instruction, and use the global pointer, references to the normal   data area takes 2 instructions).  */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;/* Nonzero if inside of a function, because the stupid MIPS asm can't   handle .files inside of functions.  */int inside_function = 0;/* Files to separate the text and the data output, so that all of the data   can be emitted before the text, which will mean that the assembler will   generate smaller code, based on the global pointer.  */FILE *asm_out_data_file;FILE *asm_out_text_file;/* 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{  struct extern_list *next;	/* next external */  const char *name;		/* name of the external */  int size;			/* size in bytes */} *extern_head = 0;/* Name of the file containing the current function.  */const char *current_function_file = "";/* Warning given that Mips ECOFF can't support changing files   within a function.  */int file_in_function_warning = FALSE;/* Whether to suppress issuing .loc's because the user attempted   to change the filename within a function.  */int ignore_line_number = FALSE;/* 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;/* Count of delay slots and how many are filled.  */int dslots_load_total;int dslots_load_filled;int dslots_jump_total;int dslots_jump_filled;/* # of nops needed by previous insn */int dslots_number_nops;/* Number of 1/2/3 word references to data items (ie, not jal's).  */int num_refs[3];/* registers to check for load delay */rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4;/* Cached operands, and operator to compare for use in set/branch/trap   on condition codes.  */rtx branch_cmp[2];/* what type of branch to use */enum cmp_type branch_type;/* 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;/* Strings to hold which cpu and instruction set architecture to use.  */const char *mips_arch_string;   /* for -march=<xxx> */const char *mips_tune_string;   /* for -mtune=<xxx> */const char *mips_isa_string;	/* for -mips{1,2,3,4} */const char *mips_abi_string;	/* for -mabi={32,n32,64,eabi} *//* Whether we are generating mips16 code.  This is a synonym for   TARGET_MIPS16, and exists for use as an attribute.  */int mips16;/* This variable is set by -mno-mips16.  We only care whether   -mno-mips16 appears or not, and using a string in this fashion is   just a way to avoid using up another bit in target_flags.  */const char *mips_no_mips16_string;/* 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;/* This variable is set by -mentry.  We only care whether -mentry   appears or not, and using a string in this fashion is just a way to   avoid using up another bit in target_flags.  */const char *mips_entry_string;const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;/* Whether we should entry and exit pseudo-ops in mips16 mode.  */int mips_entry;/* If TRUE, we split addresses into their high and low parts in the RTL.  */int mips_split_addresses;/* Generating calls to position independent functions?  */enum mips_abicalls_type mips_abicalls;/* 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];/* The length of all strings seen when compiling for the mips16.  This   is used to tell how many strings are in the constant pool, so that   we can see if we may have an overflow.  This is reset each time the   constant pool is output.  */int mips_string_length;/* When generating mips16 code, a list of all strings that are to be   output after the current function.  */static GTY(()) rtx mips16_strings;/* In mips16 mode, we build a list of all the string constants we see   in a particular function.  */struct string_constant{  struct string_constant *next;  const char *label;};static struct string_constant *string_constants;/* 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];/* Buffer to use to enclose a load/store operation with %{ %} to   turn on .set volatile.  */static char volatile_buffer[60];/* Hardware names for the registers.  If -mrnames is used, this   will be overwritten with mips_sw_reg_names.  */char mips_reg_names[][8] ={ "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7", "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15", "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23", "$24",  "$25",  "$26",  "$27",  "$28",  "$sp",  "$fp",  "$31", "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7", "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", "$fcc5","$fcc6","$fcc7","$rap", "",     "",     "",     "", "$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7", "$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15", "$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23", "$c0r24","$c0r25","$c0r26","$c0r27","$c0r28","$c0r29","$c0r30","$c0r31", "$c2r0", "$c2r1", "$c2r2", "$c2r3", "$c2r4", "$c2r5", "$c2r6", "$c2r7", "$c2r8", "$c2r9", "$c2r10","$c2r11","$c2r12","$c2r13","$c2r14","$c2r15", "$c2r16","$c2r17","$c2r18","$c2r19","$c2r20","$c2r21","$c2r22","$c2r23", "$c2r24","$c2r25","$c2r26","$c2r27","$c2r28","$c2r29","$c2r30","$c2r31", "$c3r0", "$c3r1", "$c3r2", "$c3r3", "$c3r4", "$c3r5", "$c3r6", "$c3r7", "$c3r8", "$c3r9", "$c3r10","$c3r11","$c3r12","$c3r13","$c3r14","$c3r15", "$c3r16","$c3r17","$c3r18","$c3r19","$c3r20","$c3r21","$c3r22","$c3r23", "$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31"};/* Mips software names for the registers, used to overwrite the   mips_reg_names array.  */char mips_sw_reg_names[][8] ={  "$zero","$at",  "$v0",  "$v1",  "$a0",  "$a1",  "$a2",  "$a3",  "$t0",  "$t1",  "$t2",  "$t3",  "$t4",  "$t5",  "$t6",  "$t7",  "$s0",  "$s1",  "$s2",  "$s3",  "$s4",  "$s5",  "$s6",  "$s7",  "$t8",  "$t9",  "$k0",  "$k1",  "$gp",  "$sp",  "$fp",  "$ra",  "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",  "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",  "hi",   "lo",   "accum","$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",  "$fcc5","$fcc6","$fcc7","$rap", "",     "",     "",     "",  "$c0r0", "$c0r1", "$c0r2", "$c0r3", "$c0r4", "$c0r5", "$c0r6", "$c0r7",  "$c0r8", "$c0r9", "$c0r10","$c0r11","$c0r12","$c0r13","$c0r14","$c0r15",  "$c0r16","$c0r17","$c0r18","$c0r19","$c0r20","$c0r21","$c0r22","$c0r23",  "$c0r24","$c0r25","$c0r26","$c0r27","$c0r28","$c0r29","$c0r30","$c0r31",  "$c2r0", "$c2r1", "$c2r2", "$c2r3", "$c2r4", "$c2r5", "$c2r6", "$c2r7",  "$c2r8", "$c2r9", "$c2r10","$c2r11","$c2r12","$c2r13","$c2r14","$c2r15",  "$c2r16","$c2r17","$c2r18","$c2r19","$c2r20","$c2r21","$c2r22","$c2r23",  "$c2r24","$c2r25","$c2r26","$c2r27","$c2r28","$c2r29","$c2r30","$c2r31",  "$c3r0", "$c3r1", "$c3r2", "$c3r3", "$c3r4", "$c3r5", "$c3r6", "$c3r7",  "$c3r8", "$c3r9", "$c3r10","$c3r11","$c3r12","$c3r13","$c3r14","$c3r15",  "$c3r16","$c3r17","$c3r18","$c3r19","$c3r20","$c3r21","$c3r22","$c3r23",  "$c3r24","$c3r25","$c3r26","$c3r27","$c3r28","$c3r29","$c3r30","$c3r31"};/* Map hard register number to register class */const enum reg_class mips_regno_to_class[] =

⌨️ 快捷键说明

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