📄 arm.h
字号:
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 locals_base; /* THUMB_HARD_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; /* Records if ARG_POINTER was ever live. */ int arg_pointer_live; /* Records if the save of LR has been eliminated. */ int lr_save_eliminated; /* The size of the stack frame. Only valid after reload. */ arm_stack_offsets stack_offsets; /* Records the type of the current function. */ unsigned long func_type; /* Record if the function has a variable argument list. */ int uses_anonymous_args; /* Records if sibcalls are blocked because an argument register is needed to preserve stack alignment. */ int sibcall_blocked; /* Labels for per-function Thumb call-via stubs. One per potential calling register. We can never call via LR or PC. We can call via SP if a trampoline happens to be on the top of the stack. */ rtx call_via[14];}machine_function;/* As in the machine_function, a global set of call-via labels, for code that is in text_section(). */extern GTY(()) rtx thumb_call_via_label[14];/* 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. */typedef struct{ /* This is the number of registers of arguments scanned so far. */ int nregs; /* This is the number of iWMMXt register arguments scanned so far. */ int iwmmxt_nregs; int named_count; int nargs; /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT. */ int call_cookie; int can_split;} CUMULATIVE_ARGS;/* 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 TARGET_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) \ arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))#define FUNCTION_ARG_PADDING(MODE, TYPE) \ (arm_pad_arg_upward (MODE, TYPE) ? upward : downward)#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ (arm_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)/* For AAPCS, padding should never be below the argument. For other ABIs, * mimic the default. */#define PAD_VARARGS_DOWN \ ((TARGET_AAPCS_BASED) ? 0 : BYTES_BIG_ENDIAN)/* 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, FNDECL, N_NAMED_ARGS) \ arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))/* 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).nargs += 1; \ if (arm_vector_mode_supported_p (MODE) \ && (CUM).named_count > (CUM).nargs) \ (CUM).iwmmxt_nregs += 1; \ else \ (CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)/* If defined, a C expression that gives the alignment boundary, in bits, of an argument with the specified mode and type. If it is not defined, `PARM_BOUNDARY' is used for all arguments. */#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \ ((ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (MODE, TYPE)) \ ? DOUBLEWORD_ALIGNMENT \ : PARM_BOUNDARY )/* 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) \ (IN_RANGE ((REGNO), 0, 3) \ || (TARGET_IWMMXT_ABI \ && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))/* 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! Note - this version of the code is designed to work in both ARM and Thumb modes. */#ifndef ARM_FUNCTION_PROFILER#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \{ \ char temp[20]; \ rtx sym; \ \ asm_fprintf (STREAM, "\tmov\t%r, %r\n\tbl\t", \ IP_REGNUM, LR_REGNUM); \ assemble_name (STREAM, ARM_MCOUNT_NAME); \ fputc ('\n', STREAM); \ ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO); \ sym = gen_rtx_SYMBOL_REF (Pmode, temp); \ assemble_aligned_integer (UNITS_PER_WORD, sym); \}#endif#ifdef THUMB_FUNCTION_PROFILER#define FUNCTION_PROFILER(STREAM, LABELNO) \ if (TARGET_ARM) \ ARM_FUNCTION_PROFILER (STREAM, LABELNO) \ else \ THUMB_FUNCTION_PROFILER (STREAM, LABELNO)#else#define FUNCTION_PROFILER(STREAM, LABELNO) \ ARM_FUNCTION_PROFILER (STREAM, LABELNO)#endif/* 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#define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM)/* Determine if the epilogue should be output as RTL. You should override this if you define FUNCTION_EXTRA_EPILOGUE. */#define USE_RETURN_INSN(ISCOND) \ (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)/* 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. Note we have to use {ARM|THUMB}_HARD_FRAME_POINTER_REGNUM because the definition of HARD_FRAME_POINTER_REGNUM is not a constant. */#define ELIMINABLE_REGS \{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },\ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM },\ { ARG_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\ { ARG_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM },\ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },\ { FRAME_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\ { FRAME_POINTER_REGNUM, THUMB_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 or ARG_POINTER_REGNUM. */#define CAN_ELIMINATE(FROM, TO) \ (((TO) == FRAME_POINTER_REGNUM && (FROM) == ARG_POINTER_REGNUM) ? 0 : \ ((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : \ ((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \ ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 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) \ if (TARGET_ARM) \ (OFFSET) = arm_compute_initial_elimination_offset (FROM, TO); \ else \ (OFFSET) = thumb_compute_initial_elimination_offset (FROM, TO)/* Special case handling of the location of arguments passed on the stack. */#define DEBUGGER_ARG_OFFSET(value, addr) value ? value : arm_debugger_arg_offset (value, addr)/* Initialize data used by insn expanders. This is called from insn_emit, once for every function before code is generated. */#define INIT_EXPANDERS arm_init_expanders ()/* Ou
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -