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

📄 arm.h

📁 gcc编译工具没有什么特别
💻 H
📖 第 1 页 / 共 5 页
字号:
/* 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/* Offset of first parameter from the argument pointer register value.  */#define FIRST_PARM_OFFSET(FNDECL)  4/* 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 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)  \  (GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_FLOAT && TARGET_HARD_FLOAT \   ? gen_rtx_REG (TYPE_MODE (VALTYPE), 16) \   : gen_rtx_REG (TYPE_MODE (VALTYPE), 0))/* Define how to find the value returned by a library function   assuming the value has mode MODE.  */#define LIBCALL_VALUE(MODE)  \  (GET_MODE_CLASS (MODE) == MODE_FLOAT && TARGET_HARD_FLOAT \   ? gen_rtx_REG (MODE, 16) \   : gen_rtx_REG (MODE, 0))/* 1 if N is a possible register number for a function value.   On the ARM, only r0 and f0 can return results.  */#define FUNCTION_VALUE_REGNO_P(REGNO)  \  ((REGNO) == 0 || (((REGNO) == 16) && TARGET_HARD_FLOAT))/* 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/* Define where to put the arguments to a function.   Value is zero to push the argument on the stack,   or a hard register in which to store the argument.   MODE is the argument's machine mode.   TYPE is the data type of the argument (as a tree).    This is null for libcalls where that information may    not be available.   CUM is a variable of type CUMULATIVE_ARGS which gives info about    the preceding args and about the function being called.   NAMED is nonzero if this argument is a named parameter    (otherwise it is an extra parameter matching an ellipsis).   On the ARM, normally the first 16 bytes are passed in registers r0-r3; all   other arguments are passed on the stack.  If (NAMED == 0) (which happens   only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is   passed in the stack (function_prologue will indeed make it pass in the   stack if necessary).  */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)  \  ((NAMED)						\   ? ((CUM) >= 16 ? 0 : gen_rtx_REG (MODE, (CUM) / 4))	\   : 0)/* For an arg passed partly in registers and partly in memory,   this is the number of registers used.   For args passed entirely in registers or entirely in memory, zero.  */#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)  \  ((CUM) < 16 && 16 < (CUM) + ((MODE) != BLKmode            \			       ? GET_MODE_SIZE (MODE)       \			       : int_size_in_bytes (TYPE))  \   ? 4 - (CUM) / 4 : 0)/* A C type for declaring a variable that is used as the first argument of   `FUNCTION_ARG' and other related values.  For some target machines, the   type `int' suffices and can hold the number of bytes of argument so far.   On the ARM, this is the number of bytes of arguments scanned so far.  */#define CUMULATIVE_ARGS  int/* Initialize a variable CUM of type CUMULATIVE_ARGS   for a call to a function whose data type is FNTYPE.   For a library call, FNTYPE is 0.   On the ARM, the offset starts at 0.  */#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)  \  ((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 4 : 0))/* Update the data in CUM to advance over an argument   of mode MODE and data type TYPE.   (TYPE is null for libcalls where that information may not be available.)  */#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)  \  (CUM) += ((MODE) != BLKmode                       \	    ? (GET_MODE_SIZE (MODE) + 3) & ~3       \	    : (int_size_in_bytes (TYPE) + 3) & ~3)  \/* 1 if N is a possible register number for function argument passing.   On the ARM, r0-r3 are used to pass args.  */#define FUNCTION_ARG_REGNO_P(REGNO)  \  ((REGNO) >= 0 && (REGNO) <= 3)/* Perform any actions needed for a function that is receiving a variable   number of arguments.  CUM is as above.  MODE and TYPE are the mode and type   of the current parameter.  PRETEND_SIZE is a variable that should be set to   the amount of stack that must be pushed by the prolog to pretend that our   caller pushed it.   Normally, this macro will push all remaining incoming registers on the   stack and set PRETEND_SIZE to the length of the registers pushed.   On the ARM, PRETEND_SIZE is set in order to have the prologue push the last   named arg and all anonymous args onto the stack.   XXX I know the prologue shouldn't be pushing registers, but it is faster   that way.  */#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL)  \{									\  extern int current_function_anonymous_args;				\  current_function_anonymous_args = 1;					\  if ((CUM) < 16)							\    (PRETEND_SIZE) = 16 - (CUM);					\}/* Generate assembly output for the start of a function.  */#define FUNCTION_PROLOGUE(STREAM, SIZE)  \  output_func_prologue ((STREAM), (SIZE))/* If your target environment doesn't prefix user functions with an   underscore, you may wish to re-define this to prevent any conflicts.   e.g. AOF may prefix mcount with an underscore.  */#ifndef ARM_MCOUNT_NAME#define ARM_MCOUNT_NAME "*mcount"#endif/* Call the function profiler with a given profile label.  The Acorn   compiler puts this BEFORE the prolog but gcc puts it afterwards.   On the ARM the full profile code will look like:	.data	LP1		.word	0	.text		mov	ip, lr		bl	mcount		.word	LP1   profile_function() in final.c outputs the .data section, FUNCTION_PROFILER   will output the .text section.   The ``mov ip,lr'' seems like a good idea to stick with cc convention.   ``prof'' doesn't seem to mind about this!  */#define FUNCTION_PROFILER(STREAM,LABELNO)  				    \{									    \  char temp[20];							    \  rtx sym;								    \									    \  fprintf ((STREAM), "\tmov\t%s%s, %s%s\n\tbl\t",			    \	   REGISTER_PREFIX, reg_names[12] /* ip */,			    \	   REGISTER_PREFIX, reg_names[14] /* lr */);			    \  assemble_name ((STREAM), ARM_MCOUNT_NAME);				    \  fputc ('\n', (STREAM));						    \  ASM_GENERATE_INTERNAL_LABEL (temp, "LP", (LABELNO));			    \  sym = gen_rtx (SYMBOL_REF, Pmode, temp);				    \  ASM_OUTPUT_INT ((STREAM), sym);					    \}/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,   the stack pointer does not matter.  The value is tested only in   functions that have frame pointers.   No definition is equivalent to always zero.   On the ARM, the function epilogue recovers the stack pointer from the   frame.  */#define EXIT_IGNORE_STACK 1/* Generate the assembly code for function exit. */#define FUNCTION_EPILOGUE(STREAM, SIZE)  \  output_func_epilogue ((STREAM), (SIZE))/* Determine if the epilogue should be output as RTL.   You should override this if you define FUNCTION_EXTRA_EPILOGUE.  */#define USE_RETURN_INSN(ISCOND) use_return_insn (ISCOND)/* Definitions for register eliminations.   This is an array of structures.  Each structure initializes one pair   of eliminable registers.  The "from" register number is given first,   followed by "to".  Eliminations of the same "from" register are listed   in order of preference.   We have two registers that can be eliminated on the ARM.  First, the   arg pointer register can often be eliminated in favor of the stack   pointer register.  Secondly, the pseudo frame pointer register can always   be eliminated; it is replaced with either the stack or the real frame   pointer. */#define ELIMINABLE_REGS					\{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},		\ {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},	\ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},		\ {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}/* Given FROM and TO register numbers, say whether this elimination is allowed.   Frame pointer elimination is automatically handled.   All eliminations are permissible.  Note that ARG_POINTER_REGNUM and   HARD_FRAME_POINTER_REGNUM are in fact the same thing.  If we need a frame   pointer, we must eliminate FRAME_POINTER_REGNUM into   HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM.  */#define CAN_ELIMINATE(FROM, TO)		\  (((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : 1)/* Define the offset between two registers, one to be eliminated, and the other   its replacement, at the start of a routine.  */#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)			\{									\  int volatile_func = arm_volatile_func ();				\  if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\    (OFFSET) = 0;							\  else if ((FROM) == FRAME_POINTER_REGNUM				\	   && (TO) == STACK_POINTER_REGNUM)				\    (OFFSET) = (current_function_outgoing_args_size			\		+ ((get_frame_size () + 3) & ~3));			\  else									\    {									\      int regno;							\      int offset = 12;							\      int saved_hard_reg = 0;						\									\      if (! volatile_func)						\        {								\          for (regno = 0; regno <= 10; regno++)				\	    if (regs_ever_live[regno] && ! call_used_regs[regno])	\	      saved_hard_reg = 1, offset += 4;				\	  /* PIC register is a fixed reg, so call_used_regs set.  */	\	  if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])	\	    saved_hard_reg = 1, offset += 4;				\          for (regno = 16; regno <=23; regno++)				\	    if (regs_ever_live[regno] && ! call_used_regs[regno])	\	      offset += 12;						\	}								\      if ((FROM) == FRAME_POINTER_REGNUM)				\	(OFFSET) = -offset;						\      else								\	{								\	   if (! frame_pointer_needed)					\	     offset -= 16;						\	   if (! volatile_func						\	       && (regs_ever_live[14] || saved_hard_reg)) 		\	     offset += 4;						\	   offset += current_function_outgoing_args_size;		\	   (OFFSET) = ((get_frame_size () + 3) & ~3) + offset;		\         }								\    }									\}/* Output assembler code for a block containing the constant parts   of a trampoline, leaving space for the variable parts.   On the ARM, (if r8 is the static chain regnum, and remembering that   referencing pc adds an offset of 8) the trampoline looks like:	   ldr 		r8, [pc, #0]	   ldr		pc, [pc]	   .word	static chain value	   .word	function's address   ??? FIXME: When the trampoline returns, r8 will be clobbered.  */#define TRAMPOLINE_TEMPLATE(FILE)				\{								\  fprintf ((FILE), "\tldr\t%s%s, [%s%s, #0]\n",			\	   REGISTER_PREFIX, reg_names[STATIC_CHAIN_REGNUM],	\	   REGISTER_PREFIX, reg_names[PC_REGNUM]);		\  fprintf ((FILE), "\tldr\t%s%s, [%s%s, #0]\n",			\	   REGISTER_PREFIX, reg_names[PC_REGNUM],		\	   REGISTER_PREFIX, reg_names[PC_REGNUM]);		\  ASM_OUTPUT_INT ((FILE), const0_rtx);				\  ASM_OUTPUT_INT ((FILE), const0_rtx);				\}/* Length in units of the trampoline for entering a nested function.  */#define TRAMPOLINE_SIZE  16/* Alignment required for a trampoline in units.  */#define TRAMPOLINE_ALIGN  4/* Emit RTL insns to initialize the variable parts of a trampoline.   FNADDR is an RTX for the address of the function's pure code.   CXT is an RTX for the static chain value for the function.  */#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)  \{									\  emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 8)),	\		  (CXT));						\  emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 12)),	\		  (FNADDR));						\}/* Addressing modes, and classification of registers for them.  */#define HAVE_POST_INCREMENT  1#define HAVE_PRE_INCREMENT  1#define HAVE_POST_DECREMENT  1#define HAVE_PRE_DECREMENT  1/* Macros to check register numbers against specific register classes.  *//* These assume that REGNO is a hard or pseudo reg number.   They give nonzero only if REGNO is a hard reg of the suitable class   or a pseudo reg currently allocated to a suitable hard reg.   Since they use reg_renumber, they are safe only once reg_renumber   has been allocated, which happens in local-alloc.c.   On the ARM, don't allow the pc to be used.  */#define REGNO_OK_FOR_BASE_P(REGNO)				\  ((REGNO) < 15 || (REGNO) == FRAME_POINTER_REGNUM		\   || (REGNO) == ARG_POINTER_REGNUM				\   || (unsigned) reg_renumber[(REGNO)] < 15			\   || (unsigned) reg_renumber[(REGNO)] == FRAME_POINTER_REGNUM	\   || (unsigned) reg_renumber[(REGNO)] == ARG_POINTER_REGNUM)#define REGNO_OK_FOR_INDEX_P(REGNO) \  REGNO_OK_FOR_BASE_P(REGNO)/* Maximum number of registers that can appear in a valid memory address.   Shifts in addresses can't be by a register. */#define MAX_REGS_PER_ADDRESS 2/* Recognize any constant value that is a valid address.  *//* XXX We can address any constant, eventually...  */#ifdef AOF_ASSEMBLER#define CONSTANT_ADDRESS_P(X)		\  (GET_CODE (X) == SYMBOL_REF		\   && CONSTANT_POOL_ADDRESS_P (X))#else

⌨️ 快捷键说明

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