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

📄 arm.c

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* The following are used in the arm.md file as equivalents to bits   in the above two flag variables.  *//* Nonzero if this chip supports the ARM Architecture 3M extensions.  */int arm_arch3m = 0;/* Nonzero if this chip supports the ARM Architecture 4 extensions.  */int arm_arch4 = 0;/* Nonzero if this chip supports the ARM Architecture 4t extensions.  */int arm_arch4t = 0;/* Nonzero if this chip supports the ARM Architecture 5 extensions.  */int arm_arch5 = 0;/* Nonzero if this chip supports the ARM Architecture 5E extensions.  */int arm_arch5e = 0;/* Nonzero if this chip supports the ARM Architecture 6 extensions.  */int arm_arch6 = 0;/* Nonzero if this chip can benefit from load scheduling.  */int arm_ld_sched = 0;/* Nonzero if this chip is a StrongARM.  */int arm_is_strong = 0;/* Nonzero if this chip is a Cirrus variant.  */int arm_arch_cirrus = 0;/* Nonzero if this chip supports Intel Wireless MMX technology.  */int arm_arch_iwmmxt = 0;/* Nonzero if this chip is an XScale.  */int arm_arch_xscale = 0;/* Nonzero if tuning for XScale  */int arm_tune_xscale = 0;/* Nonzero if this chip is an ARM6 or an ARM7.  */int arm_is_6_or_7 = 0;/* Nonzero if generating Thumb instructions.  */int thumb_code = 0;/* Nonzero if we should define __THUMB_INTERWORK__ in the   preprocessor.   XXX This is a bit of a hack, it's intended to help work around   problems in GLD which doesn't understand that armv5t code is   interworking clean.  */int arm_cpp_interwork = 0;/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we   must report the mode of the memory reference from PRINT_OPERAND to   PRINT_OPERAND_ADDRESS.  */enum machine_mode output_memory_reference_mode;/* The register number to be used for the PIC offset register.  */const char * arm_pic_register_string = NULL;int arm_pic_register = INVALID_REGNUM;/* Set to 1 when a return insn is output, this means that the epilogue   is not needed.  */int return_used_this_function;/* Set to 1 after arm_reorg has started.  Reset to start at the start of   the next function.  */static int after_arm_reorg = 0;/* The maximum number of insns to be used when loading a constant.  */static int arm_constant_limit = 3;/* For an explanation of these variables, see final_prescan_insn below.  */int arm_ccfsm_state;enum arm_cond_code arm_current_cc;rtx arm_target_insn;int arm_target_label;/* The condition codes of the ARM, and the inverse function.  */static const char * const arm_condition_codes[] ={  "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",  "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"};#define streq(string1, string2) (strcmp (string1, string2) == 0)/* Initialization code.  */struct processors{  const char *const name;  enum processor_type core;  const char *arch;  const unsigned long flags;  bool (* rtx_costs) (rtx, int, int, int *);};/* Not all of these give usefully different compilation alternatives,   but there is no simple way of generalizing them.  */static const struct processors all_cores[] ={  /* ARM Cores */#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \  {NAME, arm_none, #ARCH, FLAGS | FL_FOR_ARCH##ARCH, arm_##COSTS##_rtx_costs},#include "arm-cores.def"#undef ARM_CORE  {NULL, arm_none, NULL, 0, NULL}};static const struct processors all_architectures[] ={  /* ARM Architectures */  /* We don't specify rtx_costs here as it will be figured out     from the core.  */  {"armv2",   arm2,       "2",   FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},  {"armv2a",  arm2,       "2",   FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},  {"armv3",   arm6,       "3",   FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3, NULL},  {"armv3m",  arm7m,      "3M",  FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3M, NULL},  {"armv4",   arm7tdmi,   "4",   FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH4, NULL},  /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no     implementations that support it, so we will leave it out for now.  */  {"armv4t",  arm7tdmi,   "4T",  FL_CO_PROC |             FL_FOR_ARCH4T, NULL},  {"armv5",   arm10tdmi,  "5",   FL_CO_PROC |             FL_FOR_ARCH5, NULL},  {"armv5t",  arm10tdmi,  "5T",  FL_CO_PROC |             FL_FOR_ARCH5T, NULL},  {"armv5e",  arm1026ejs, "5E",  FL_CO_PROC |             FL_FOR_ARCH5E, NULL},  {"armv5te", arm1026ejs, "5TE", FL_CO_PROC |             FL_FOR_ARCH5TE, NULL},  {"armv6",   arm1136js,  "6",   FL_CO_PROC |             FL_FOR_ARCH6, NULL},  {"armv6j",  arm1136js,  "6J",  FL_CO_PROC |             FL_FOR_ARCH6J, NULL},  {"armv6k",  mpcore,	  "6K",  FL_CO_PROC |             FL_FOR_ARCH6K, NULL},  {"armv6z",  arm1176jzs, "6Z",  FL_CO_PROC |             FL_FOR_ARCH6Z, NULL},  {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC |             FL_FOR_ARCH6ZK, NULL},  {"ep9312",  ep9312,     "4T",  FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},  {"iwmmxt",  iwmmxt,     "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},  {NULL, arm_none, NULL, 0 , NULL}};/* This is a magic structure.  The 'string' field is magically filled in   with a pointer to the value specified by the user on the command line   assuming that the user has specified such a value.  */struct arm_cpu_select arm_select[] ={  /* string	  name            processors  */  { NULL,	"-mcpu=",	all_cores  },  { NULL,	"-march=",	all_architectures },  { NULL,	"-mtune=",	all_cores }};/* Defines representing the indexes into the above table.  */#define ARM_OPT_SET_CPU 0#define ARM_OPT_SET_ARCH 1#define ARM_OPT_SET_TUNE 2/* The name of the proprocessor macro to define for this architecture.  */char arm_arch_name[] = "__ARM_ARCH_0UNK__";struct fpu_desc{  const char * name;  enum fputype fpu;};/* Available values for for -mfpu=.  */static const struct fpu_desc all_fpus[] ={  {"fpa",	FPUTYPE_FPA},  {"fpe2",	FPUTYPE_FPA_EMU2},  {"fpe3",	FPUTYPE_FPA_EMU2},  {"maverick",	FPUTYPE_MAVERICK},  {"vfp",	FPUTYPE_VFP}};/* Floating point models used by the different hardware.   See fputype in arm.h.  */static const enum fputype fp_model_for_fpu[] ={  /* No FP hardware.  */  ARM_FP_MODEL_UNKNOWN,		/* FPUTYPE_NONE  */  ARM_FP_MODEL_FPA,		/* FPUTYPE_FPA  */  ARM_FP_MODEL_FPA,		/* FPUTYPE_FPA_EMU2  */  ARM_FP_MODEL_FPA,		/* FPUTYPE_FPA_EMU3  */  ARM_FP_MODEL_MAVERICK,	/* FPUTYPE_MAVERICK  */  ARM_FP_MODEL_VFP		/* FPUTYPE_VFP  */};struct float_abi{  const char * name;  enum float_abi_type abi_type;};/* Available values for -mfloat-abi=.  */static const struct float_abi all_float_abis[] ={  {"soft",	ARM_FLOAT_ABI_SOFT},  {"softfp",	ARM_FLOAT_ABI_SOFTFP},  {"hard",	ARM_FLOAT_ABI_HARD}};struct abi_name{  const char *name;  enum arm_abi_type abi_type;};/* Available values for -mabi=.  */static const struct abi_name arm_all_abis[] ={  {"apcs-gnu",    ARM_ABI_APCS},  {"atpcs",   ARM_ABI_ATPCS},  {"aapcs",   ARM_ABI_AAPCS},  {"iwmmxt",  ARM_ABI_IWMMXT}};/* Return the number of bits set in VALUE.  */static unsignedbit_count (unsigned long value){  unsigned long count = 0;  while (value)    {      count++;      value &= value - 1;  /* Clear the least-significant set bit.  */    }  return count;}/* Set up library functions unique to ARM.  */static voidarm_init_libfuncs (void){  /* There are no special library functions unless we are using the     ARM BPABI.  */  if (!TARGET_BPABI)    return;  /* The functions below are described in Section 4 of the "Run-Time     ABI for the ARM architecture", Version 1.0.  */  /* Double-precision floating-point arithmetic.  Table 2.  */  set_optab_libfunc (add_optab, DFmode, "__aeabi_dadd");  set_optab_libfunc (sdiv_optab, DFmode, "__aeabi_ddiv");  set_optab_libfunc (smul_optab, DFmode, "__aeabi_dmul");  set_optab_libfunc (neg_optab, DFmode, "__aeabi_dneg");  set_optab_libfunc (sub_optab, DFmode, "__aeabi_dsub");  /* Double-precision comparisons.  Table 3.  */  set_optab_libfunc (eq_optab, DFmode, "__aeabi_dcmpeq");  set_optab_libfunc (ne_optab, DFmode, NULL);  set_optab_libfunc (lt_optab, DFmode, "__aeabi_dcmplt");  set_optab_libfunc (le_optab, DFmode, "__aeabi_dcmple");  set_optab_libfunc (ge_optab, DFmode, "__aeabi_dcmpge");  set_optab_libfunc (gt_optab, DFmode, "__aeabi_dcmpgt");  set_optab_libfunc (unord_optab, DFmode, "__aeabi_dcmpun");  /* Single-precision floating-point arithmetic.  Table 4.  */  set_optab_libfunc (add_optab, SFmode, "__aeabi_fadd");  set_optab_libfunc (sdiv_optab, SFmode, "__aeabi_fdiv");  set_optab_libfunc (smul_optab, SFmode, "__aeabi_fmul");  set_optab_libfunc (neg_optab, SFmode, "__aeabi_fneg");  set_optab_libfunc (sub_optab, SFmode, "__aeabi_fsub");  /* Single-precision comparisons.  Table 5.  */  set_optab_libfunc (eq_optab, SFmode, "__aeabi_fcmpeq");  set_optab_libfunc (ne_optab, SFmode, NULL);  set_optab_libfunc (lt_optab, SFmode, "__aeabi_fcmplt");  set_optab_libfunc (le_optab, SFmode, "__aeabi_fcmple");  set_optab_libfunc (ge_optab, SFmode, "__aeabi_fcmpge");  set_optab_libfunc (gt_optab, SFmode, "__aeabi_fcmpgt");  set_optab_libfunc (unord_optab, SFmode, "__aeabi_fcmpun");  /* Floating-point to integer conversions.  Table 6.  */  set_conv_libfunc (sfix_optab, SImode, DFmode, "__aeabi_d2iz");  set_conv_libfunc (ufix_optab, SImode, DFmode, "__aeabi_d2uiz");  set_conv_libfunc (sfix_optab, DImode, DFmode, "__aeabi_d2lz");  set_conv_libfunc (ufix_optab, DImode, DFmode, "__aeabi_d2ulz");  set_conv_libfunc (sfix_optab, SImode, SFmode, "__aeabi_f2iz");  set_conv_libfunc (ufix_optab, SImode, SFmode, "__aeabi_f2uiz");  set_conv_libfunc (sfix_optab, DImode, SFmode, "__aeabi_f2lz");  set_conv_libfunc (ufix_optab, DImode, SFmode, "__aeabi_f2ulz");  /* Conversions between floating types.  Table 7.  */  set_conv_libfunc (trunc_optab, SFmode, DFmode, "__aeabi_d2f");  set_conv_libfunc (sext_optab, DFmode, SFmode, "__aeabi_f2d");  /* Integer to floating-point conversions.  Table 8.  */  set_conv_libfunc (sfloat_optab, DFmode, SImode, "__aeabi_i2d");  set_conv_libfunc (ufloat_optab, DFmode, SImode, "__aeabi_ui2d");  set_conv_libfunc (sfloat_optab, DFmode, DImode, "__aeabi_l2d");  set_conv_libfunc (ufloat_optab, DFmode, DImode, "__aeabi_ul2d");  set_conv_libfunc (sfloat_optab, SFmode, SImode, "__aeabi_i2f");  set_conv_libfunc (ufloat_optab, SFmode, SImode, "__aeabi_ui2f");  set_conv_libfunc (sfloat_optab, SFmode, DImode, "__aeabi_l2f");  set_conv_libfunc (ufloat_optab, SFmode, DImode, "__aeabi_ul2f");  /* Long long.  Table 9.  */  set_optab_libfunc (smul_optab, DImode, "__aeabi_lmul");  set_optab_libfunc (sdivmod_optab, DImode, "__aeabi_ldivmod");  set_optab_libfunc (udivmod_optab, DImode, "__aeabi_uldivmod");  set_optab_libfunc (ashl_optab, DImode, "__aeabi_llsl");  set_optab_libfunc (lshr_optab, DImode, "__aeabi_llsr");  set_optab_libfunc (ashr_optab, DImode, "__aeabi_lasr");  set_optab_libfunc (cmp_optab, DImode, "__aeabi_lcmp");  set_optab_libfunc (ucmp_optab, DImode, "__aeabi_ulcmp");  /* Integer (32/32->32) division.  \S 4.3.1.  */  set_optab_libfunc (sdivmod_optab, SImode, "__aeabi_idivmod");  set_optab_libfunc (udivmod_optab, SImode, "__aeabi_uidivmod");  /* The divmod functions are designed so that they can be used for     plain division, even though they return both the quotient and the     remainder.  The quotient is returned in the usual location (i.e.,     r0 for SImode, {r0, r1} for DImode), just as would be expected     for an ordinary division routine.  Because the AAPCS calling     conventions specify that all of { r0, r1, r2, r3 } are     callee-saved registers, there is no need to tell the compiler     explicitly that those registers are clobbered by these     routines.  */  set_optab_libfunc (sdiv_optab, DImode, "__aeabi_ldivmod");  set_optab_libfunc (udiv_optab, DImode, "__aeabi_uldivmod");  set_optab_libfunc (sdiv_optab, SImode, "__aeabi_idivmod");  set_optab_libfunc (udiv_optab, SImode, "__aeabi_uidivmod");}/* Fix up any incompatible options that the user has specified.   This has now turned into a maze.  */voidarm_override_options (void){  unsigned i;  enum processor_type target_arch_cpu = arm_none;  /* Set up the flags based on the cpu/architecture selected by the user.  */  for (i = ARRAY_SIZE (arm_select); i--;)    {      struct arm_cpu_select * ptr = arm_select + i;      if (ptr->string != NULL && ptr->string[0] != '\0')        {	  const struct processors * sel;          for (sel = ptr->processors; sel->name != NULL; sel++)            if (streq (ptr->string, sel->name))              {		/* Set the architecture define.  */		if (i != ARM_OPT_SET_TUNE)		  sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);		/* Determine the processor core for which we should		   tune code-generation.  */		if (/* -mcpu= is a sensible default.  */		    i == ARM_OPT_SET_CPU		    /* -mtune= overrides -mcpu= and -march=.  */		    || i == ARM_OPT_SET_TUNE)		  arm_tune = (enum processor_type) (sel - ptr->processors);		/* Remember the CPU associated with this architecture.		   If no other option is used to set the CPU type,		   we'll use this to guess the most suitable tuning		   options.  */		if (i == ARM_OPT_SET_ARCH)		  target_arch_cpu = sel->core;				if (i != ARM_OPT_SET_TUNE)		  {		    /* If we have been given an architecture and a processor		       make sure that they are compatible.  We only generate		       a warning though, and we prefer the CPU over the		       architecture.  */		    if (insn_flags != 0 && (insn_flags ^ sel->flags))		      warning ("switch -mcpu=%s conflicts with -march= switch",			       ptr->string);		    insn_flags = sel->flags;		  }                break;              }          if (sel->name == NULL)            error ("bad value (%s) for %s switch", ptr->string, ptr->name);        }    }  /* Guess the tuning options from the architecture if necessary.  */  if (arm_tune == arm_none)    arm_tune = target_arch_cpu;  /* If the user did not specify a processor, choose one for them.  */  if (insn_flags == 0)    {      const struct processors * sel;      unsigned int        sought;      enum processor_type cpu;      cpu = TARGET_CPU_DEFAULT;      if (cpu == arm_none)	{#ifdef SUBTARGET_CPU_DEFAULT	  /* Use the subtarget default CPU if none was specified by	     configure.  */	  cpu = SUBTARGET_CPU_DEFAULT;#endif	  /* Default to ARM6.  */	  if (cpu == arm_none)

⌨️ 快捷键说明

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