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

📄 arm.h

📁 Mac OS X 10.4.9 for x86 Source Code gcc 实现源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
#define PREFERRED_RELOAD_CLASS(X, CLASS)	\  (TARGET_ARM ? (CLASS) :			\   ((CLASS) == BASE_REGS ? (CLASS) : LO_REGS))/* Must leave BASE_REGS reloads alone */#define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\  ((CLASS) != LO_REGS && (CLASS) != BASE_REGS				\   ? ((true_regnum (X) == -1 ? LO_REGS					\       : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS	\       : NO_REGS)) 							\   : NO_REGS)#define THUMB_SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X)		\  ((CLASS) != LO_REGS && (CLASS) != BASE_REGS				\   ? ((true_regnum (X) == -1 ? LO_REGS					\       : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS	\       : NO_REGS)) 							\   : NO_REGS)/* Return the register class of a scratch register needed to copy IN into   or out of a register in CLASS in MODE.  If it can be done directly,   NO_REGS is returned.  */#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X)		\  /* Restrict which direct reloads are allowed for VFP regs.  */ \  ((TARGET_VFP && TARGET_HARD_FLOAT				\    && (CLASS) == VFP_REGS)					\   ? vfp_secondary_reload_class (MODE, X)			\   : TARGET_ARM							\   ? (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \    ? GENERAL_REGS : NO_REGS)					\   : THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))/* If we need to load shorts byte-at-a-time, then we need a scratch.  */#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\  /* Restrict which direct reloads are allowed for VFP regs.  */ \  ((TARGET_VFP && TARGET_HARD_FLOAT				\    && (CLASS) == VFP_REGS)					\    ? vfp_secondary_reload_class (MODE, X) :			\  /* Cannot load constants into Cirrus registers.  */		\   (TARGET_MAVERICK && TARGET_HARD_FLOAT			\     && (CLASS) == CIRRUS_REGS					\     && (CONSTANT_P (X) || GET_CODE (X) == SYMBOL_REF))		\    ? GENERAL_REGS :						\  (TARGET_ARM ?							\   (((CLASS) == IWMMXT_REGS || (CLASS) == IWMMXT_GR_REGS)	\      && CONSTANT_P (X))					\   ? GENERAL_REGS :						\   (((MODE) == HImode && ! arm_arch4				\     && (GET_CODE (X) == MEM					\	 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG)	\	     && true_regnum (X) == -1)))			\    ? GENERAL_REGS : NO_REGS)					\   : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))/* Try a machine-dependent way of reloading an illegitimate address   operand.  If we find one, push the reload and jump to WIN.  This   macro is used in only one place: `find_reloads_address' in reload.c.   For the ARM, we wish to handle large displacements off a base   register by splitting the addend across a MOV and the mem insn.   This can cut the number of reloads needed.  */#define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN)	   \  do									   \    {									   \      if (GET_CODE (X) == PLUS						   \	  && GET_CODE (XEXP (X, 0)) == REG				   \	  && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER		   \	  && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)			   \	  && GET_CODE (XEXP (X, 1)) == CONST_INT)			   \	{								   \	  HOST_WIDE_INT val = INTVAL (XEXP (X, 1));			   \	  HOST_WIDE_INT low, high;					   \									   \	  if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT))	   \	    low = ((val & 0xf) ^ 0x8) - 0x8;				   \	  else if (TARGET_MAVERICK && TARGET_HARD_FLOAT)		   \	    /* Need to be careful, -256 is not a valid offset.  */	   \	    low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);		   \	  else if (MODE == SImode					   \		   || (MODE == SFmode && TARGET_SOFT_FLOAT)		   \		   || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \	    /* Need to be careful, -4096 is not a valid offset.  */	   \	    low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff);		   \	  else if ((MODE == HImode || MODE == QImode) && arm_arch4)	   \	    /* Need to be careful, -256 is not a valid offset.  */	   \	    low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);		   \	  else if (GET_MODE_CLASS (MODE) == MODE_FLOAT			   \		   && TARGET_HARD_FLOAT && TARGET_FPA)			   \	    /* Need to be careful, -1024 is not a valid offset.  */	   \	    low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff);		   \	  else								   \	    break;							   \									   \	  high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff)	   \		   ^ (unsigned HOST_WIDE_INT) 0x80000000)		   \		  - (unsigned HOST_WIDE_INT) 0x80000000);		   \	  /* Check for overflow or zero */				   \	  if (low == 0 || high == 0 || (high + low != val))		   \	    break;							   \									   \	  /* Reload the high part into a base reg; leave the low part	   \	     in the mem.  */						   \	  X = gen_rtx_PLUS (GET_MODE (X),				   \			    gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),	   \					  GEN_INT (high)),		   \			    GEN_INT (low));				   \	  push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL,	   \		       MODE_BASE_REG_CLASS (MODE), GET_MODE (X), 	   \		       VOIDmode, 0, 0, OPNUM, TYPE);			   \	  goto WIN;							   \	}								   \    }									   \  while (0)/* XXX If an HImode FP+large_offset address is converted to an HImode   SP+large_offset address, then reload won't know how to fix it.  It sees   only that SP isn't valid for HImode, and so reloads the SP into an index   register, but the resulting address is still invalid because the offset   is too big.  We fix it here instead by reloading the entire address.  *//* We could probably achieve better results by defining PROMOTE_MODE to help   cope with the variances between the Thumb's signed and unsigned byte and   halfword load instructions.  */#define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN)	\{									\  if (GET_CODE (X) == PLUS						\      && GET_MODE_SIZE (MODE) < 4					\      && GET_CODE (XEXP (X, 0)) == REG					\      && XEXP (X, 0) == stack_pointer_rtx				\      && GET_CODE (XEXP (X, 1)) == CONST_INT				\      && ! thumb_legitimate_offset_p (MODE, INTVAL (XEXP (X, 1))))	\    {									\      rtx orig_X = X;							\      X = copy_rtx (X);							\      push_reload (orig_X, NULL_RTX, &X, NULL,				\		   MODE_BASE_REG_CLASS (MODE),				\		   Pmode, VOIDmode, 0, 0, OPNUM, TYPE);			\      goto WIN;								\    }									\}#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN)   \  if (TARGET_ARM)							   \    ARM_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN); \  else									   \    THUMB_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN)/* Return the maximum number of consecutive registers   needed to represent mode MODE in a register of class CLASS.   ARM regs are UNITS_PER_WORD bits while FPA regs can hold any FP mode */#define CLASS_MAX_NREGS(CLASS, MODE)  \  (((CLASS) == FPA_REGS || (CLASS) == CIRRUS_REGS) ? 1 : ARM_NUM_REGS (MODE))/* If defined, gives a class of registers that cannot be used as the   operand of a SUBREG that changes the mode of the object illegally.  *//* Moves between FPA_REGS and GENERAL_REGS are two memory insns.  */#define REGISTER_MOVE_COST(MODE, FROM, TO)		\  (TARGET_ARM ?						\   ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 :	\    (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 :	\    (FROM) == VFP_REGS && (TO) != VFP_REGS ? 10 :  \    (FROM) != VFP_REGS && (TO) == VFP_REGS ? 10 :  \    (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 :  \    (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 :  \    (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 :  \    (FROM) == CIRRUS_REGS && (TO) != CIRRUS_REGS ? 20 :	\    (FROM) != CIRRUS_REGS && (TO) == CIRRUS_REGS ? 20 :	\   2)							\   :							\   ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)/* Stack layout; function entry, exit and calling.  *//* Define this if pushing a word on the stack   makes the stack pointer a smaller address.  */#define STACK_GROWS_DOWNWARD  1/* Define this if the nominal address of the stack frame   is at the high-address end of the local variables;   that is, each additional local variable allocated   goes at a more negative offset in the frame.  */#define FRAME_GROWS_DOWNWARD 1/* The amount of scratch space needed by _interwork_{r7,r11}_call_via_rN().   When present, it is one word in size, and sits at the top of the frame,   between the soft frame pointer and either r7 or r11.   We only need _interwork_rM_call_via_rN() for -mcaller-super-interworking,   and only then if some outgoing arguments are passed on the stack.  It would   be tempting to also check whether the stack arguments are passed by indirect   calls, but there seems to be no reason in principle why a post-reload pass   couldn't convert a direct call into an indirect one.  */#define CALLER_INTERWORKING_SLOT_SIZE			\  (TARGET_CALLER_INTERWORKING				\   && current_function_outgoing_args_size != 0		\   ? UNITS_PER_WORD : 0)/* Offset within stack frame to start allocating local variables at.   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the   first local allocated.  Otherwise, it is the offset to the BEGINNING   of the first local allocated.  */#define STARTING_FRAME_OFFSET  0/* If we generate an insn to push BYTES bytes,   this says how many the stack pointer really advances by.  *//* The push insns do not do this rounding implicitly.   So don't define this.  *//* #define PUSH_ROUNDING(NPUSHED)  ROUND_UP_WORD (NPUSHED) *//* Define this if the maximum size of all the outgoing args is to be   accumulated and pushed during the prologue.  The amount can be   found in the variable current_function_outgoing_args_size.  */#define ACCUMULATE_OUTGOING_ARGS 1/* Offset of first parameter from the argument pointer register value.  */#define FIRST_PARM_OFFSET(FNDECL)  (TARGET_ARM ? 4 : 0)/* Value is the number of byte of arguments automatically   popped when returning from a subroutine call.   FUNDECL is the declaration node of the function (as a tree),   FUNTYPE is the data type of the function (as a tree),   or for a library call it is an identifier node for the subroutine name.   SIZE is the number of bytes of arguments passed on the stack.   On the ARM, the caller does not pop any of its arguments that were passed   on the stack.  */#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE)  0/* Define how to find the value returned by a library function   assuming the value has mode MODE.  */#define LIBCALL_VALUE(MODE)  \  (TARGET_ARM && TARGET_HARD_FLOAT_ABI && TARGET_FPA			\   && GET_MODE_CLASS (MODE) == MODE_FLOAT				\   ? gen_rtx_REG (MODE, FIRST_FPA_REGNUM)				\   : TARGET_ARM && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK		\     && GET_MODE_CLASS (MODE) == MODE_FLOAT				\   ? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM) 			\   : TARGET_IWMMXT_ABI && arm_vector_mode_supported_p (MODE)    	\   ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) 				\   : gen_rtx_REG (MODE, ARG_REGISTER (1)))/* Define how to find the value returned by a function.   VALTYPE is the data type of the value (as a tree).   If the precise function being called is known, FUNC is its FUNCTION_DECL;   otherwise, FUNC is 0.  */#define FUNCTION_VALUE(VALTYPE, FUNC) \  arm_function_value (VALTYPE, FUNC);/* 1 if N is a possible register number for a function value.   On the ARM, only r0 and f0 can return results.  *//* On a Cirrus chip, mvf0 can return results.  */#define FUNCTION_VALUE_REGNO_P(REGNO)  \  ((REGNO) == ARG_REGISTER (1) \   || (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM)		\       && TARGET_HARD_FLOAT_ABI && TARGET_MAVERICK)			\   || ((REGNO) == FIRST_IWMMXT_REGNUM && TARGET_IWMMXT_ABI) \   || (TARGET_ARM && ((REGNO) == FIRST_FPA_REGNUM)			\       && TARGET_HARD_FLOAT_ABI && TARGET_FPA))/* Amount of memory needed for an untyped call to save all possible return   registers.  */#define APPLY_RESULT_SIZE arm_apply_result_size()/* How large values are returned *//* A C expression which can inhibit the returning of certain function values   in registers, based on the type of value.  */#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return   values must be in memory.  On the ARM, they need only do so if larger   than a word, or if they contain elements offset from zero in the struct.  */#define DEFAULT_PCC_STRUCT_RETURN 0/* Flags for the call/call_value rtl operations set up by function_arg.  */#define CALL_NORMAL		0x00000000	/* No special processing.  */#define CALL_LONG		0x00000001	/* Always call indirect.  */#define CALL_SHORT		0x00000002	/* Never call indirect.  *//* These bits describe the different types of function supported   by the ARM backend.  They are exclusive.  i.e. a function cannot be both a   normal function and an interworked function, for example.  Knowing the   type of a function is important for determining its prologue and   epilogue sequences.   Note value 7 is currently unassigned.  Also note that the interrupt   function types all have bit 2 set, so that they can be tested for easily.   Note that 0 is deliberately chosen for ARM_FT_UNKNOWN so that when the   machine_function structure is initialized (to zero) func_type will   default to unknown.  This will force the first use of arm_current_func_type   to call arm_compute_func_type.  */#define ARM_FT_UNKNOWN		 0 /* Type has not yet been determined.  */#define ARM_FT_NORMAL		 1 /* Your normal, straightforward function.  */#define ARM_FT_INTERWORKED	 2 /* A function that supports interworking.  */#define ARM_FT_ISR		 4 /* An interrupt service routine.  */#define ARM_FT_FIQ		 5 /* A fast interrupt service routine.  */#define ARM_FT_EXCEPTION	 6 /* An ARM exception handler (subcase of ISR).  */#define ARM_FT_TYPE_MASK	((1 << 3) - 1)/* In addition functions can have several type modifiers,   outlined by these bit masks:  */#define ARM_FT_INTERRUPT	(1 << 2) /* Note overlap with FT_ISR and above.  */#define ARM_FT_NAKED		(1 << 3) /* No prologue or epilogue.  */#define ARM_FT_VOLATILE		(1 << 4) /* Does not return.  */#define ARM_FT_NESTED		(1 << 5) /* Embedded inside another func.  *//* Some macros to test these flags.  */#define ARM_FUNC_TYPE(t)	(t & ARM_FT_TYPE_MASK)#define IS_INTERRUPT(t)		(t & ARM_FT_INTERRUPT)#define IS_VOLATILE(t)     	(t & ARM_FT_VOLATILE)#define IS_NAKED(t)        	(t & ARM_FT_NAKED)#define IS_NESTED(t)       	(t & ARM_FT_NESTED)/* Structure used to hold the function stack frame layout.  Offsets are   relative to the stack pointer on function entry.  Positive offsets are   in the direction of stack growth.   Only soft_frame is used in thumb mode.  */typedef struct arm_stack_offsets GTY(()){  int saved_args;	/* ARG_POINTER_REGNUM.  */  int frame;		/* ARM_HARD_FRAME_POINTER_REGNUM.  */  int saved_regs;  int soft_frame;	/* FRAME_POINTER_REGNUM.  */  int outgoing_args;	/* STACK_POINTER_REGNUM.  */}arm_stack_offsets;/* A C structure for machine-specific, per-function data.   This is added to the cfun structure.  */typedef struct machine_function GTY(()){  /* Additional stack adjustment in __builtin_eh_throw.  */  rtx eh_epilogue_sp_ofs;  /* Records if LR has to be saved for far jumps.  */  int far_jump_used

⌨️ 快捷键说明

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