📄 arm.h
字号:
#define BYTES_BIG_ENDIAN (TARGET_BIG_END != 0)/* Define this if most significant word of a multiword number is the lowest numbered. This is always false, even when in big-endian mode. */#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS)/* LIBGCC2_WORDS_BIG_ENDIAN has to be a constant, so we define this based on processor pre-defineds when compiling libgcc2.c. */#if defined(__ARMEB__) && !defined(__ARMWEL__)#define LIBGCC2_WORDS_BIG_ENDIAN 1#else#define LIBGCC2_WORDS_BIG_ENDIAN 0#endif/* Define this if most significant word of doubles is the lowest numbered. The rules are different based on whether or not we use FPA-format or VFP-format doubles. */#define FLOAT_WORDS_BIG_ENDIAN (arm_float_words_big_endian ())#define UNITS_PER_WORD 4#define PARM_BOUNDARY 32#define STACK_BOUNDARY 32#define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32)#define FUNCTION_BOUNDARY 32/* The lowest bit is used to indicate Thumb-mode functions, so the vbit must go into the delta field of pointers to member functions. */#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta#define EMPTY_FIELD_BOUNDARY 32#define BIGGEST_ALIGNMENT 32/* Make strings word-aligned so strcpy from constants will be faster. */#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2) #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ ((TREE_CODE (EXP) == STRING_CST \ && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \ ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))/* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the value set in previous versions of this toolchain was 8, which produces more compact structures. The command line option -mstructure_size_boundary=<n> can be used to change this value. For compatibility with the ARM SDK however the value should be left at 32. ARM SDT Reference Manual (ARM DUI 0020D) page 2-20 says "Structures are aligned on word boundaries". */#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundaryextern int arm_structure_size_boundary;/* This is the value used to initialize arm_structure_size_boundary. If a particular arm target wants to change the default value it should change the definition of this macro, not STRUCTRUE_SIZE_BOUNDARY. See netbsd.h for an example of this. */#ifndef DEFAULT_STRUCTURE_SIZE_BOUNDARY#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 32#endif/* Used when parsing command line option -mstructure_size_boundary. */extern const char * structure_size_string;/* Nonzero if move instructions will actually fail to work when given unaligned data. */#define STRICT_ALIGNMENT 1/* Standard register usage. *//* Register allocation in ARM Procedure Call Standard (as used on RISCiX): (S - saved over call). r0 * argument word/integer result r1-r3 argument word r4-r8 S register variable r9 S (rfp) register variable (real frame pointer) r10 F S (sl) stack limit (used by -mapcs-stack-check) r11 F S (fp) argument pointer r12 (ip) temp workspace r13 F S (sp) lower end of current stack frame r14 (lr) link address/workspace r15 F (pc) program counter f0 floating point result f1-f3 floating point scratch f4-f7 S floating point variable cc This is NOT a real register, but is used internally to represent things that use or set the condition codes. sfp This isn't either. It is used during rtl generation since the offset between the frame pointer and the auto's isn't known until after register allocation. afp Nor this, we only need this because of non-local goto. Without it fp appears to be used and the elimination code won't get rid of sfp. It tracks fp exactly at all times. *: See CONDITIONAL_REGISTER_USAGE *//* The stack backtrace structure is as follows: fp points to here: | save code pointer | [fp] | return link value | [fp, #-4] | return sp value | [fp, #-8] | return fp value | [fp, #-12] [| saved r10 value |] [| saved r9 value |] [| saved r8 value |] [| saved r7 value |] [| saved r6 value |] [| saved r5 value |] [| saved r4 value |] [| saved r3 value |] [| saved r2 value |] [| saved r1 value |] [| saved r0 value |] [| saved f7 value |] three words [| saved f6 value |] three words [| saved f5 value |] three words [| saved f4 value |] three words r0-r3 are not normally saved in a C function. *//* 1 for registers that have pervasive standard uses and are not available for the register allocator. */#define FIXED_REGISTERS \{ \ 0,0,0,0,0,0,0,0, \ 0,0,0,0,0,1,0,1, \ 0,0,0,0,0,0,0,0, \ 1,1,1 \}/* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any registers that can be used without being saved. The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. The CC is not preserved over function calls on the ARM 6, so it is easier to assume this for all. SFP is preserved, since FP is. */#define CALL_USED_REGISTERS \{ \ 1,1,1,1,0,0,0,0, \ 0,0,0,0,1,1,1,1, \ 1,1,1,1,0,0,0,0, \ 1,1,1 \}#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE#define SUBTARGET_CONDITIONAL_REGISTER_USAGE#endif#define CONDITIONAL_REGISTER_USAGE \{ \ int regno; \ \ if (TARGET_SOFT_FLOAT || TARGET_THUMB) \ { \ for (regno = FIRST_ARM_FP_REGNUM; \ regno <= LAST_ARM_FP_REGNUM; ++regno) \ fixed_regs[regno] = call_used_regs[regno] = 1; \ } \ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \ { \ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ } \ else if (TARGET_APCS_STACK) \ { \ fixed_regs[10] = 1; \ call_used_regs[10] = 1; \ } \ if (TARGET_APCS_FRAME) \ { \ fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \ call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \ } \ SUBTARGET_CONDITIONAL_REGISTER_USAGE \} /* These are a couple of extensions to the formats accecpted by asm_fprintf: %@ prints out ASM_COMMENT_START %r prints out REGISTER_PREFIX reg_names[arg] */#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P) \ case '@': \ fputs (ASM_COMMENT_START, FILE); \ break; \ \ case 'r': \ fputs (REGISTER_PREFIX, FILE); \ fputs (reg_names [va_arg (ARGS, int)], FILE); \ break;/* Round X up to the nearest word. */#define ROUND_UP(X) (((X) + 3) & ~3)/* Convert fron bytes to ints. */#define ARM_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)/* The number of (integer) registers required to hold a quantity of type MODE. */#define ARM_NUM_REGS(MODE) \ ARM_NUM_INTS (GET_MODE_SIZE (MODE))/* The number of (integer) registers required to hold a quantity of TYPE MODE. */#define ARM_NUM_REGS2(MODE, TYPE) \ ARM_NUM_INTS ((MODE) == BLKmode ? \ int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))/* The number of (integer) argument register available. */#define NUM_ARG_REGS 4/* Return the regiser number of the N'th (integer) argument. */#define ARG_REGISTER(N) (N - 1)#if 0 /* FIXME: The ARM backend has special code to handle structure returns, and will reserve its own hidden first argument. So if this macro is enabled a *second* hidden argument will be reserved, which will break binary compatibility with old toolchains and also thunk handling. One day this should be fixed. *//* RTX for structure returns. NULL means use a hidden first argument. */#define STRUCT_VALUE 0#else/* Register in which address to store a structure value is passed to a function. */#define STRUCT_VALUE_REGNUM ARG_REGISTER (1)#endif/* Specify the registers used for certain standard purposes. The values of these macros are register numbers. *//* The number of the last argument register. */#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)/* The number of the last "lo" register (thumb). */#define LAST_LO_REGNUM 7/* The register that holds the return address in exception handlers. */#define EXCEPTION_LR_REGNUM 2/* The native (Norcroft) Pascal compiler for the ARM passes the static chain as an invisible last argument (possible since varargs don't exist in Pascal), so the following is not true. */#define STATIC_CHAIN_REGNUM (TARGET_ARM ? 12 : 9)/* Define this to be where the real frame pointer is if it is not possible to work out the offset between the frame pointer and the automatic variables until after register allocation has taken place. FRAME_POINTER_REGNUM should point to a special register that we will make sure is eliminated. For the Thumb we have another problem. The TPCS defines the frame pointer as r11, and GCC belives that it is always possible to use the frame pointer as base register for addressing purposes. (See comments in find_reloads_address()). But - the Thumb does not allow high registers, including r11, to be used as base address registers. Hence our problem. The solution used here, and in the old thumb port is to use r7 instead of r11 as the hard frame pointer and to have special code to generate backtrace structures on the stack (if required to do so via a command line option) using r11. This is the only 'user visable' use of r11 as a frame pointer. */#define ARM_HARD_FRAME_POINTER_REGNUM 11#define THUMB_HARD_FRAME_POINTER_REGNUM 7#define HARD_FRAME_POINTER_REGNUM \ (TARGET_ARM \ ? ARM_HARD_FRAME_POINTER_REGNUM \ : THUMB_HARD_FRAME_POINTER_REGNUM)#define FP_REGNUM HARD_FRAME_POINTER_REGNUM/* Register to use for pushing function arguments. */#define STACK_POINTER_REGNUM SP_REGNUM/* ARM floating pointer registers. */#define FIRST_ARM_FP_REGNUM 16#define LAST_ARM_FP_REGNUM 23/* Base register for access to local variables of the function. */#define FRAME_POINTER_REGNUM 25/* Base register for access to arguments of the function. */#define ARG_POINTER_REGNUM 26/* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */#define FIRST_PSEUDO_REGISTER 27/* Value should be nonzero if functions must have frame pointers. Zero means the frame pointer need not be set up (and parms may be accessed via the stack pointer) in functions that seem suitable. If we have to have a frame pointer we might as well make use of it. APCS says that the frame pointer does not need to be pushed in leaf functions, or simple tail call functions. */#define FRAME_POINTER_REQUIRED \ (current_function_has_nonlocal_label \ || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))/* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. This is ordinarily the length in words of a value of mode MODE but can be less for certain modes in special long registers. On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP mode. */#define HARD_REGNO_NREGS(REGNO, MODE) \ ((TARGET_ARM \ && REGNO >= FIRST_ARM_FP_REGNUM \ && REGNO != FRAME_POINTER_REGNUM \ && REGNO != ARG_POINTER_REGNUM) \ ? 1 : ARM_NUM_REGS (MODE))/* Return true if REGNO is suitable for holding a quantity of type MODE. */#define HARD_REGNO_MODE_OK(REGNO, MODE) \ arm_hard_regno_mode_ok ((REGNO), (MODE))/* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, for any hard reg, then this must be 0 for correct output. */#define MODES_TIEABLE_P(MODE1, MODE2) \ (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))/* The order in which register should be allocated. It is good to use ip since no saving is required (though calls clobber it) and it never contains function parameters. It is quite good to use lr since other calls may
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -