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

📄 arm.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
   This has now turned into a maze.  */voidarm_override_options (){  unsigned i;    /* 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))              {		if (i == 2)		  tune_flags = sel->flags;		else		  {		    /* 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);        }    }    /* If the user did not specify a processor, choose one for them.  */  if (insn_flags == 0)    {      const struct processors * sel;      unsigned int        sought;      static const struct cpu_default      {	const int cpu;	const char *const name;      }      cpu_defaults[] =      {	{ TARGET_CPU_arm2,      "arm2" },	{ TARGET_CPU_arm6,      "arm6" },	{ TARGET_CPU_arm610,    "arm610" },	{ TARGET_CPU_arm710,	"arm710" },	{ TARGET_CPU_arm7m,     "arm7m" },	{ TARGET_CPU_arm7500fe, "arm7500fe" },	{ TARGET_CPU_arm7tdmi,  "arm7tdmi" },	{ TARGET_CPU_arm8,      "arm8" },	{ TARGET_CPU_arm810,    "arm810" },	{ TARGET_CPU_arm9,      "arm9" },	{ TARGET_CPU_strongarm, "strongarm" },	{ TARGET_CPU_xscale,    "xscale" },	{ TARGET_CPU_generic,   "arm" },	{ 0, 0 }      };      const struct cpu_default * def;	        /* Find the default.  */      for (def = cpu_defaults; def->name; def++)	if (def->cpu == TARGET_CPU_DEFAULT)	  break;      /* Make sure we found the default CPU.  */      if (def->name == NULL)	abort ();            /* Find the default CPU's flags.  */      for (sel = all_cores; sel->name != NULL; sel++)	if (streq (def->name, sel->name))	  break;            if (sel->name == NULL)	abort ();      insn_flags = sel->flags;            /* Now check to see if the user has specified some command line	 switch that require certain abilities from the cpu.  */      sought = 0;            if (TARGET_INTERWORK || TARGET_THUMB)	{	  sought |= (FL_THUMB | FL_MODE32);	  	  /* Force apcs-32 to be used for interworking.  */	  target_flags |= ARM_FLAG_APCS_32;	  /* There are no ARM processors that support both APCS-26 and	     interworking.  Therefore we force FL_MODE26 to be removed	     from insn_flags here (if it was set), so that the search	     below will always be able to find a compatible processor.  */	  insn_flags &= ~FL_MODE26;	}      else if (!TARGET_APCS_32)	sought |= FL_MODE26;            if (sought != 0 && ((sought & insn_flags) != sought))	{	  /* Try to locate a CPU type that supports all of the abilities	     of the default CPU, plus the extra abilities requested by	     the user.  */	  for (sel = all_cores; sel->name != NULL; sel++)	    if ((sel->flags & sought) == (sought | insn_flags))	      break;	  if (sel->name == NULL)	    {	      unsigned current_bit_count = 0;	      const struct processors * best_fit = NULL;	      	      /* Ideally we would like to issue an error message here		 saying that it was not possible to find a CPU compatible		 with the default CPU, but which also supports the command		 line options specified by the programmer, and so they		 ought to use the -mcpu=<name> command line option to		 override the default CPU type.		 Unfortunately this does not work with multilibing.  We		 need to be able to support multilibs for -mapcs-26 and for		 -mthumb-interwork and there is no CPU that can support both		 options.  Instead if we cannot find a cpu that has both the		 characteristics of the default cpu and the given command line		 options we scan the array again looking for a best match.  */	      for (sel = all_cores; sel->name != NULL; sel++)		if ((sel->flags & sought) == sought)		  {		    unsigned count;		    count = bit_count (sel->flags & insn_flags);		    if (count >= current_bit_count)		      {			best_fit = sel;			current_bit_count = count;		      }		  }	      if (best_fit == NULL)		abort ();	      else		sel = best_fit;	    }	  insn_flags = sel->flags;	}    }    /* If tuning has not been specified, tune for whichever processor or     architecture has been selected.  */  if (tune_flags == 0)    tune_flags = insn_flags;  /* Make sure that the processor choice does not conflict with any of the     other command line choices.  */  if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))    {      /* If APCS-32 was not the default then it must have been set by the	 user, so issue a warning message.  If the user has specified	 "-mapcs-32 -mcpu=arm2" then we loose here.  */      if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)	warning ("target CPU does not support APCS-32" );      target_flags &= ~ARM_FLAG_APCS_32;    }  else if (!TARGET_APCS_32 && !(insn_flags & FL_MODE26))    {      warning ("target CPU does not support APCS-26" );      target_flags |= ARM_FLAG_APCS_32;    }    if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))    {      warning ("target CPU does not support interworking" );      target_flags &= ~ARM_FLAG_INTERWORK;    }    if (TARGET_THUMB && !(insn_flags & FL_THUMB))    {      warning ("target CPU does not support THUMB instructions");      target_flags &= ~ARM_FLAG_THUMB;    }  if (TARGET_APCS_FRAME && TARGET_THUMB)    {      /* warning ("ignoring -mapcs-frame because -mthumb was used"); */      target_flags &= ~ARM_FLAG_APCS_FRAME;    }  /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done     from here where no function is being compiled currently.  */  if ((target_flags & (THUMB_FLAG_LEAF_BACKTRACE | THUMB_FLAG_BACKTRACE))      && TARGET_ARM)    warning ("enabling backtrace support is only meaningful when compiling for the Thumb");  if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)    warning ("enabling callee interworking support is only meaningful when compiling for the Thumb");  if (TARGET_ARM && TARGET_CALLER_INTERWORKING)    warning ("enabling caller interworking support is only meaningful when compiling for the Thumb");  /* If interworking is enabled then APCS-32 must be selected as well.  */  if (TARGET_INTERWORK)    {      if (!TARGET_APCS_32)	warning ("interworking forces APCS-32 to be used" );      target_flags |= ARM_FLAG_APCS_32;    }    if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)    {      warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");      target_flags |= ARM_FLAG_APCS_FRAME;    }    if (TARGET_POKE_FUNCTION_NAME)    target_flags |= ARM_FLAG_APCS_FRAME;    if (TARGET_APCS_REENT && flag_pic)    error ("-fpic and -mapcs-reent are incompatible");    if (TARGET_APCS_REENT)    warning ("APCS reentrant code not supported.  Ignored");    /* If this target is normally configured to use APCS frames, warn if they     are turned off and debugging is turned on.  */  if (TARGET_ARM      && write_symbols != NO_DEBUG      && !TARGET_APCS_FRAME      && (TARGET_DEFAULT & ARM_FLAG_APCS_FRAME))    warning ("-g with -mno-apcs-frame may not give sensible debugging");    /* If stack checking is disabled, we can use r10 as the PIC register,     which keeps r9 available.  */  if (flag_pic)    arm_pic_register = TARGET_APCS_STACK ? 9 : 10;    if (TARGET_APCS_FLOAT)    warning ("passing floating point arguments in fp regs not yet supported");    /* Initialize boolean versions of the flags, for use in the arm.md file.  */  arm_fast_multiply = (insn_flags & FL_FAST_MULT) != 0;  arm_arch4         = (insn_flags & FL_ARCH4) != 0;  arm_arch5         = (insn_flags & FL_ARCH5) != 0;  arm_arch5e        = (insn_flags & FL_ARCH5E) != 0;  arm_arch_xscale   = (insn_flags & FL_XSCALE) != 0;  arm_ld_sched      = (tune_flags & FL_LDSCHED) != 0;  arm_is_strong     = (tune_flags & FL_STRONG) != 0;  thumb_code	    = (TARGET_ARM == 0);  arm_is_6_or_7     = (((tune_flags & (FL_MODE26 | FL_MODE32))		       && !(tune_flags & FL_ARCH4))) != 0;  arm_tune_xscale   = (tune_flags & FL_XSCALE) != 0;  /* Default value for floating point code... if no co-processor     bus, then schedule for emulated floating point.  Otherwise,     assume the user has an FPA.     Note: this does not prevent use of floating point instructions,     -msoft-float does that.  */  arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;    if (target_fp_name)    {      if (streq (target_fp_name, "2"))	arm_fpu_arch = FP_SOFT2;      else if (streq (target_fp_name, "3"))	arm_fpu_arch = FP_SOFT3;      else	error ("invalid floating point emulation option: -mfpe-%s",	       target_fp_name);    }  else    arm_fpu_arch = FP_DEFAULT;    if (TARGET_FPE && arm_fpu != FP_HARD)    arm_fpu = FP_SOFT2;    /* For arm2/3 there is no need to do any scheduling if there is only     a floating point emulator, or we are doing software floating-point.  */  if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)      && (tune_flags & FL_MODE32) == 0)    flag_schedule_insns = flag_schedule_insns_after_reload = 0;    arm_prgmode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;    if (structure_size_string != NULL)    {      int size = strtol (structure_size_string, NULL, 0);            if (size == 8 || size == 32)	arm_structure_size_boundary = size;      else	warning ("structure size boundary can only be set to 8 or 32");    }  if (arm_pic_register_string != NULL)    {      int pic_register = decode_reg_name (arm_pic_register_string);      if (!flag_pic)	warning ("-mpic-register= is useless without -fpic");      /* Prevent the user from choosing an obviously stupid PIC register.  */      else if (pic_register < 0 || call_used_regs[pic_register]	       || pic_register == HARD_FRAME_POINTER_REGNUM	       || pic_register == STACK_POINTER_REGNUM	       || pic_register >= PC_REGNUM)	error ("unable to use '%s' for PIC register", arm_pic_register_string);      else	arm_pic_register = pic_register;    }  if (TARGET_THUMB && flag_schedule_insns)    {      /* Don't warn since it's on by default in -O2.  */      flag_schedule_insns = 0;    }  /* If optimizing for space, don't synthesize constants.     For processors with load scheduling, it never costs more than 2 cycles     to load a constant, and the load scheduler may well reduce that to 1.  */  if (optimize_size || (tune_flags & FL_LDSCHED))    arm_constant_limit = 1;    if (arm_arch_xscale)    arm_constant_limit = 2;  /* If optimizing for size, bump the number of instructions that we     are prepared to conditionally execute (even on a StrongARM).      Otherwise for the StrongARM, which has early execution of branches,     a sequence that is worth skipping is shorter.  */  if (optimize_size)    max_insns_skipped = 6;  else if (arm_is_strong)    max_insns_skipped = 3;  /* Register global variables with the garbage collector.  */  arm_add_gc_roots ();}static voidarm_add_gc_roots (){  gcc_obstack_init(&minipool_obstack);  minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);}/* A table of known ARM exception types.   For use with the interrupt function attribute.  */typedef struct{  const char *const arg;  const unsigned long return_value;}isr_attribute_arg;static const isr_attribute_arg isr_attribute_args [] ={  { "IRQ",   ARM_FT_ISR },  { "irq",   ARM_FT_ISR },  { "FIQ",   ARM_FT_FIQ },  { "fiq",   ARM_FT_FIQ },  { "ABORT", ARM_FT_ISR },  { "abort", ARM_FT_ISR },  { "ABORT", ARM_FT_ISR },  { "abort", ARM_FT_ISR },  { "UNDEF", ARM_FT_EXCEPTION },  { "undef", ARM_FT_EXCEPTION },  { "SWI",   ARM_FT_EXCEPTION },  { "swi",   ARM_FT_EXCEPTION },  { NULL,    ARM_FT_NORMAL }};/* Returns the (interrupt) function type of the current   function, or ARM_FT_UNKNOWN if the type cannot be determined.  */static unsigned longarm_isr_value (argument)     tree argument;{  const isr_attribute_arg * ptr;  const char *              arg;  /* No argument - default to IRQ.  */  if (argument == NULL_TREE)    return ARM_FT_ISR;  /* Get the value of the argument.  */  if (TREE_VALUE (argument) == NULL_TREE      || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)    return ARM_FT_UNKNOWN;  arg = TREE_STRING_POINTER (TREE_VALUE (argument));  /* Check it against the list of known arguments.  */  for (ptr = isr_attribute_args; ptr->arg != NULL; ptr ++)    if (streq (arg, ptr->arg))      return ptr->return_value;  /* An unrecognized interrupt type.  */  return ARM_FT_UNKNOWN;}/* Computes the type of the current function.  */static unsigned longarm_compute_func_type (){  unsigned long type = ARM_FT_UNKNOWN;  tree a;  tree attr;    if (TREE_CODE (current_function_decl) != FUNCTION_DECL)    abort ();  /* Decide if the current function is volatile.  Such functions     never return, and many memory cycles can be saved by not storing     register values that will never be needed again.  This optimization     was added to speed up context switching in a kernel application.  */  if (optimize > 0      && current_function_nothrow

⌨️ 快捷键说明

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