📄 arm.h
字号:
#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_FPA_REGNUM 16#define LAST_FPA_REGNUM 23#define FIRST_IWMMXT_GR_REGNUM 43#define LAST_IWMMXT_GR_REGNUM 46#define FIRST_IWMMXT_REGNUM 47#define LAST_IWMMXT_REGNUM 62#define IS_IWMMXT_REGNUM(REGNUM) \ (((REGNUM) >= FIRST_IWMMXT_REGNUM) && ((REGNUM) <= LAST_IWMMXT_REGNUM))#define IS_IWMMXT_GR_REGNUM(REGNUM) \ (((REGNUM) >= FIRST_IWMMXT_GR_REGNUM) && ((REGNUM) <= LAST_IWMMXT_GR_REGNUM))/* 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#define FIRST_CIRRUS_FP_REGNUM 27#define LAST_CIRRUS_FP_REGNUM 42#define IS_CIRRUS_REGNUM(REGNUM) \ (((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))#define FIRST_VFP_REGNUM 63#define LAST_VFP_REGNUM 94#define IS_VFP_REGNUM(REGNUM) \ (((REGNUM) >= FIRST_VFP_REGNUM) && ((REGNUM) <= LAST_VFP_REGNUM))/* The number of hard registers is 16 ARM + 8 FPA + 1 CC + 1 SFP + 1 AFP. *//* + 16 Cirrus registers take us up to 43. *//* Intel Wireless MMX Technology registers add 16 + 4 more. *//* VFP adds 32 + 1 more. */#define FIRST_PSEUDO_REGISTER 96/* 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; FPA regs can hold any FP mode. */#define HARD_REGNO_NREGS(REGNO, MODE) \ ((TARGET_ARM \ && REGNO >= FIRST_FPA_REGNUM \ && REGNO != FRAME_POINTER_REGNUM \ && REGNO != ARG_POINTER_REGNUM) \ && !IS_VFP_REGNUM (REGNO) \ ? 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))#define VALID_IWMMXT_REG_MODE(MODE) \ (arm_vector_mode_supported_p (MODE) || (MODE) == DImode)/* 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 clobber it anyway. Allocate r0 through r3 in reverse order since r3 is least likely to contain a function parameter; in addition results are returned in r0. */#define REG_ALLOC_ORDER \{ \ 3, 2, 1, 0, 12, 14, 4, 5, \ 6, 7, 8, 10, 9, 11, 13, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, \ 27, 28, 29, 30, 31, 32, 33, 34, \ 35, 36, 37, 38, 39, 40, 41, 42, \ 43, 44, 45, 46, 47, 48, 49, 50, \ 51, 52, 53, 54, 55, 56, 57, 58, \ 59, 60, 61, 62, \ 24, 25, 26, \ 78, 77, 76, 75, 74, 73, 72, 71, \ 70, 69, 68, 67, 66, 65, 64, 63, \ 79, 80, 81, 82, 83, 84, 85, 86, \ 87, 88, 89, 90, 91, 92, 93, 94, \ 95 \}/* Interrupt functions can only use registers that have already been saved by the prologue, even if they would normally be call-clobbered. */#define HARD_REGNO_RENAME_OK(SRC, DST) \ (! IS_INTERRUPT (cfun->machine->func_type) || \ regs_ever_live[DST])/* Register and constant classes. *//* Register classes: used to be simple, just all ARM regs or all FPA regs Now that the Thumb is involved it has become more complicated. */enum reg_class{ NO_REGS, FPA_REGS, CIRRUS_REGS, VFP_REGS, IWMMXT_GR_REGS, IWMMXT_REGS, LO_REGS, STACK_REG, BASE_REGS, HI_REGS, CC_REG, VFPCC_REG, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES};#define N_REG_CLASSES (int) LIM_REG_CLASSES/* Give names of register classes as strings for dump file. */#define REG_CLASS_NAMES \{ \ "NO_REGS", \ "FPA_REGS", \ "CIRRUS_REGS", \ "VFP_REGS", \ "IWMMXT_GR_REGS", \ "IWMMXT_REGS", \ "LO_REGS", \ "STACK_REG", \ "BASE_REGS", \ "HI_REGS", \ "CC_REG", \ "VFPCC_REG", \ "GENERAL_REGS", \ "ALL_REGS", \}/* Define which registers fit in which classes. This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. */#define REG_CLASS_CONTENTS \{ \ { 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ { 0x00FF0000, 0x00000000, 0x00000000 }, /* FPA_REGS */ \ { 0xF8000000, 0x000007FF, 0x00000000 }, /* CIRRUS_REGS */ \ { 0x00000000, 0x80000000, 0x7FFFFFFF }, /* VFP_REGS */ \ { 0x00000000, 0x00007800, 0x00000000 }, /* IWMMXT_GR_REGS */ \ { 0x00000000, 0x7FFF8000, 0x00000000 }, /* IWMMXT_REGS */ \ { 0x000000FF, 0x00000000, 0x00000000 }, /* LO_REGS */ \ { 0x00002000, 0x00000000, 0x00000000 }, /* STACK_REG */ \ { 0x000020FF, 0x00000000, 0x00000000 }, /* BASE_REGS */ \ { 0x0000FF00, 0x00000000, 0x00000000 }, /* HI_REGS */ \ { 0x01000000, 0x00000000, 0x00000000 }, /* CC_REG */ \ { 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \ { 0x0200FFFF, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \ { 0xFAFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \}/* The same information, inverted: Return the class number of the smallest class containing reg number REGNO. This could be a conditional expression or could index an array. */#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)/* FPA registers can't do subreg as all values are reformatted to internal precision. VFP registers may only be accessed in the mode they were set. */#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ ? reg_classes_intersect_p (FPA_REGS, (CLASS)) \ || reg_classes_intersect_p (VFP_REGS, (CLASS)) \ : 0)/* We need to define this for LO_REGS on thumb. Otherwise we can end up using r0-r4 for function arguments, r7 for the stack frame and don't have enough left over to do doubleword arithmetic. */#define CLASS_LIKELY_SPILLED_P(CLASS) \ ((TARGET_THUMB && (CLASS) == LO_REGS) \ || (CLASS) == CC_REG)/* The class value for index registers, and the one for base regs. */#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)/* For the Thumb the high registers cannot be used as base registers when addressing quantities in QI or HI mode; if we don't know the mode, then we must be conservative. */#define MODE_BASE_REG_CLASS(MODE) \ (TARGET_ARM ? GENERAL_REGS : \ (((MODE) == SImode) ? BASE_REGS : LO_REGS))/* For Thumb we can not support SP+reg addressing, so we return LO_REGS instead of BASE_REGS. */#define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows registers explicitly used in the rtl to be used as spill registers but prevents the compiler from extending the lifetime of these registers. */#define SMALL_REGISTER_CLASSES TARGET_THUMB/* Get reg_class from a letter such as appears in the machine description. We only need constraint `f' for FPA_REGS (`r' == GENERAL_REGS) for the ARM, but several more letters for the Thumb. */#define REG_CLASS_FROM_LETTER(C) \ ( (C) == 'f' ? FPA_REGS \ : (C) == 'v' ? CIRRUS_REGS \ : (C) == 'w' ? VFP_REGS \ : (C) == 'y' ? IWMMXT_REGS \ : (C) == 'z' ? IWMMXT_GR_REGS \ : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \ : TARGET_ARM ? NO_REGS \ : (C) == 'h' ? HI_REGS \ : (C) == 'b' ? BASE_REGS \ : (C) == 'k' ? STACK_REG \ : (C) == 'c' ? CC_REG \ : NO_REGS)/* The letters I, J, K, L and M in a register constraint string can be used to stand for particular ranges of immediate operands. This macro defines what the ranges are. C is the letter, and VALUE is a constant value. Return 1 if VALUE is in the range specified by C. I: immediate arithmetic operand (i.e. 8 bits shifted as required). J: valid indexing constants. K: ~value ok in rhs argument of data operand. L: -value ok in rhs argument of data operand. M: 0..32, or a power of 2 (for shifts, or mult done by shift). */#define CONST_OK_FOR_ARM_LETTER(VALUE, C) \ ((C) == 'I' ? const_ok_for_arm (VALUE) : \ (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) : \ (C) == 'K' ? (const_ok_for_arm (~(VALUE))) : \ (C) == 'L' ? (const_ok_for_arm (-(VALUE))) : \ (C) == 'M' ? (((VALUE >= 0 && VALUE <= 32)) \ || (((VALUE) & ((VALUE) - 1)) == 0)) \ : 0)#define CONST_OK_FOR_THUMB_LETTER(VAL, C) \ ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VAL) < 256 : \ (C) == 'J' ? (VAL) > -256 && (VAL) < 0 : \ (C) == 'K' ? thumb_shiftable_const (VAL) : \ (C) == 'L' ? (VAL) > -8 && (VAL) < 8 : \ (C) == 'M' ? ((unsigned HOST_WIDE_INT) (VAL) < 1024 \ && ((VAL) & 3) == 0) : \ (C) == 'N' ? ((unsigned HOST_WIDE_INT) (VAL) < 32) : \ (C) == 'O' ? ((VAL) >= -508 && (VAL) <= 508) \ : 0)#define CONST_OK_FOR_LETTER_P(VALUE, C) \ (TARGET_ARM ? \ CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))/* Constant letter 'G' for the FP immediate constants. 'H' means the same constant negated. */#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \ ((C) == 'G' ? arm_const_double_rtx (X) : \ (C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0)#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \ (TARGET_ARM ? \ CONST_DOUBLE_OK_FOR_ARM_LETTER (X, C) : 0)/* For the ARM, `Q' means that this is a memory operand that is just an offset from a register. `S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL address. This means that the symbol is in the text segment and can be accessed without using a load. 'D' Prefixes a number of const_double operands where: 'Da' is a constant that takes two ARM insns to load. 'Db' takes three ARM insns. 'Dc' takes four ARM insns, if we allow that in this compilation. 'U' Prefixes an extended memory constraint where: 'Uv' is an address valid for VFP load/store insns. 'Uy' is an address valid for iwmmxt load/store insns. 'Uq' is an address valid for ldrsb. */#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \ (((C) == 'D') ? (GET_CODE (OP) == CONST_DOUBLE \ && (((STR)[1] == 'a' \ && arm_const_double_inline_cost (OP) == 2) \ || ((STR)[1] == 'b' \ && arm_const_double_inline_cost (OP) == 3) \ || ((STR)[1] == 'c' \ && arm_const_double_inline_cost (OP) == 4 \ && !(optimize_size || arm_ld_sched)))) : \ ((C) == 'Q') ? (GET_CODE (OP) == MEM \ && GET_CODE (XEXP (OP, 0)) == REG) : \ ((C) == 'R') ? (GET_CODE (OP) == MEM \ && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \ ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \ ((C) == 'T') ? cirrus_memory_offset (OP) : \ ((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \ ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \ ((C) == 'U' && (STR)[1] == 'q') \ ? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \ : 0)#define CONSTRAINT_LEN(C,STR) \ (((C) == 'U' || (C) == 'D') ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR))#define EXTRA_CONSTRAINT_THUMB(X, C) \ ((C) == 'Q' ? (GET_CODE (X) == MEM \ && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0)#define EXTRA_CONSTRAINT_STR(X, C, STR) \ (TARGET_ARM \ ? EXTRA_CONSTRAINT_STR_ARM (X, C, STR) \ : EXTRA_CONSTRAINT_THUMB (X, C))#define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U')/* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. In general this is just CLASS, but for the Thumb we prefer a LO_REGS class or a subset. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -