📄 rs6000.h
字号:
One of the classes must always be named ALL_REGS and include all hard regs. If there is more than one class, another class must be named NO_REGS and contain no registers. The name GENERAL_REGS must be the name of a class (or an alias for another name such as ALL_REGS). This is the class of registers that is allowed by "g" or "r" in a register constraint. Also, registers outside this class are allocated only when instructions express preferences for them. The classes must be numbered in nondecreasing order; that is, a larger-numbered class must never be contained completely in a smaller-numbered class. For any two classes, it is very desirable that there be another class that represents their union. *//* The RS/6000 has three types of registers, fixed-point, floating-point, and condition registers, plus three special registers, MQ, CTR, and the link register. However, r0 is special in that it cannot be used as a base register. So make a class for registers valid as base registers. Also, cr0 is the only condition code register that can be used in arithmetic insns, so make a separate class for it. */enum reg_class{ NO_REGS, BASE_REGS, GENERAL_REGS, FLOAT_REGS, ALTIVEC_REGS, VRSAVE_REGS, NON_SPECIAL_REGS, MQ_REGS, LINK_REGS, CTR_REGS, LINK_OR_CTR_REGS, SPECIAL_REGS, SPEC_OR_GEN_REGS, CR0_REGS, CR_REGS, NON_FLOAT_REGS, XER_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", \ "BASE_REGS", \ "GENERAL_REGS", \ "FLOAT_REGS", \ "ALTIVEC_REGS", \ "VRSAVE_REGS", \ "NON_SPECIAL_REGS", \ "MQ_REGS", \ "LINK_REGS", \ "CTR_REGS", \ "LINK_OR_CTR_REGS", \ "SPECIAL_REGS", \ "SPEC_OR_GEN_REGS", \ "CR0_REGS", \ "CR_REGS", \ "NON_FLOAT_REGS", \ "XER_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, 0x00000000 }, /* NO_REGS */ \ { 0xfffffffe, 0x00000000, 0x00000008, 0x00000000 }, /* BASE_REGS */ \ { 0xffffffff, 0x00000000, 0x00000008, 0x00000000 }, /* GENERAL_REGS */ \ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \ { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */ \ { 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \ { 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \ { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \ { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \ { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \ { 0x00000000, 0x00000000, 0x00000007, 0x00002000 }, /* SPECIAL_REGS */ \ { 0xffffffff, 0x00000000, 0x0000000f, 0x00000000 }, /* SPEC_OR_GEN_REGS */ \ { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \ { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \ { 0xffffffff, 0x00000000, 0x0000efff, 0x00000000 }, /* NON_FLOAT_REGS */ \ { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */ \ { 0xffffffff, 0xffffffff, 0xffffffff, 0x00003fff } /* 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) \ ((REGNO) == 0 ? GENERAL_REGS \ : (REGNO) < 32 ? BASE_REGS \ : FP_REGNO_P (REGNO) ? FLOAT_REGS \ : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \ : (REGNO) == CR0_REGNO ? CR0_REGS \ : CR_REGNO_P (REGNO) ? CR_REGS \ : (REGNO) == MQ_REGNO ? MQ_REGS \ : (REGNO) == LINK_REGISTER_REGNUM ? LINK_REGS \ : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \ : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \ : (REGNO) == XER_REGNO ? XER_REGS \ : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \ : NO_REGS)/* The class value for index registers, and the one for base regs. */#define INDEX_REG_CLASS GENERAL_REGS#define BASE_REG_CLASS BASE_REGS/* Get reg_class from a letter such as appears in the machine description. */#define REG_CLASS_FROM_LETTER(C) \ ((C) == 'f' ? FLOAT_REGS \ : (C) == 'b' ? BASE_REGS \ : (C) == 'h' ? SPECIAL_REGS \ : (C) == 'q' ? MQ_REGS \ : (C) == 'c' ? CTR_REGS \ : (C) == 'l' ? LINK_REGS \ : (C) == 'v' ? ALTIVEC_REGS \ : (C) == 'x' ? CR0_REGS \ : (C) == 'y' ? CR_REGS \ : (C) == 'z' ? XER_REGS \ : NO_REGS)/* The letters I, J, K, L, M, N, and P 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' is a signed 16-bit constant `J' is a constant with only the high-order 16 bits non-zero `K' is a constant with only the low-order 16 bits non-zero `L' is a signed 16-bit constant shifted left 16 bits `M' is a constant that is greater than 31 `N' is a positive constant that is an exact power of two `O' is the constant zero `P' is a constant whose negation is a signed 16-bit constant */#define CONST_OK_FOR_LETTER_P(VALUE, C) \ ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \ : (C) == 'J' ? ((VALUE) & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0 \ : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \ : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \ && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0)) \ : (C) == 'M' ? (VALUE) > 31 \ : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0 \ : (C) == 'O' ? (VALUE) == 0 \ : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \ : 0)/* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. We flag for special constants when we can copy the constant into a general register in two insns for DF/DI and one insn for SF. 'H' is used for DI/DF constants that take 3 insns. */#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \ == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \ : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \ : 0)/* Optional extra constraints for this machine. 'Q' means that is a memory operand that is just an offset from a reg. 'R' is for AIX TOC entries. 'S' is a constant that can be placed into a 64-bit mask operand 'T' is a constant that can be placed into a 32-bit mask operand 'U' is for V.4 small data references. */#define EXTRA_CONSTRAINT(OP, C) \ ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \ : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \ : (C) == 'S' ? mask64_operand (OP, DImode) \ : (C) == 'T' ? mask_operand (OP, SImode) \ : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \ && small_data_operand (OP, GET_MODE (OP))) \ : 0)/* 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 on some machines in some cases it is preferable to use a more restrictive class. On the RS/6000, we have to return NO_REGS when we want to reload a floating-point CONST_DOUBLE to force it to be copied to memory. We also don't want to reload integer values into floating-point registers if we can at all help it. In fact, this can cause reload to abort, if it tries to generate a reload of CTR into a FP register and discovers it doesn't have the memory location required. ??? Would it be a good idea to have reload do the converse, that is try to reload floating modes into FP registers if possible? */#define PREFERRED_RELOAD_CLASS(X,CLASS) \ (((GET_CODE (X) == CONST_DOUBLE \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \ ? NO_REGS \ : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \ && (CLASS) == NON_SPECIAL_REGS) \ ? GENERAL_REGS \ : (CLASS)))/* 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_RELOAD_CLASS(CLASS,MODE,IN) \ secondary_reload_class (CLASS, MODE, IN)/* If we are copying between FP or AltiVec registers and anything else, we need a memory location. */#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS \ || (CLASS2) == FLOAT_REGS \ || (CLASS1) == ALTIVEC_REGS \ || (CLASS2) == ALTIVEC_REGS))/* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. On RS/6000, this is the size of MODE in words, except in the FP regs, where a single reg is enough for two words. */#define CLASS_MAX_NREGS(CLASS, MODE) \ (((CLASS) == FLOAT_REGS) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))/* 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. */#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))/* Stack layout; function entry, exit and calling. *//* Enumeration to give which calling sequence to use. */enum rs6000_abi { ABI_NONE, ABI_AIX, /* IBM's AIX */ ABI_AIX_NODESC, /* AIX calling sequence minus function descriptors */ ABI_V4, /* System V.4/eabi */ ABI_DARWIN /* Apple's Darwin (OS X kernel) */};extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget *//* Structure used to define the rs6000 stack */typedef struct rs6000_stack { int first_gp_reg_save; /* first callee saved GP register used */ int first_fp_reg_save; /* first callee saved FP register used */ int first_altivec_reg_save; /* first callee saved AltiVec register used */ int lr_save_p; /* true if the link reg needs to be saved */ int cr_save_p; /* true if the CR reg needs to be saved */ unsigned int vrsave_mask; /* mask of vec registers to save */ int toc_save_p; /* true if the TOC needs to be saved */ int push_p; /* true if we need to allocate stack space */ int calls_p; /* true if the function makes any calls */ enum rs6000_abi abi; /* which ABI to use */ int gp_save_offset; /* offset to save GP regs from initial SP */ int fp_save_offset; /* offset to save FP regs from initial SP */ int altivec_save_offset; /* offset to save AltiVec regs from inital SP */ int lr_save_offset; /* offset to save LR from initial SP */ int cr_save_offset; /* offset to save CR from initial SP */ int vrsave_save_offset; /* offset to save VRSAVE from initial SP */ int toc_save_offset; /* offset to save the TOC pointer */ int varargs_save_offset; /* offset to save the varargs registers */ int ehrd_offset; /* offset to EH return data */ int reg_size; /* register size (4 or 8) */ int varargs_size; /* size to hold V.4 args passed in regs */ int vars_size; /* variable save area size */ int parm_size; /* outgoing parameter size */ int save_size; /* save area size */ int fixed_size; /* fixed size of stack frame */ int gp_size; /* size of saved GP registers */ int fp_size; /* size of saved FP registers */ int altivec_size; /* size of saved AltiVec registers */ int cr_size; /* size to hold CR if not in save_size */ int lr_size; /* size to hold LR if not in save_size */ int vrsave_size; /* size to hold VRSAVE if not in save_size */ int altivec_padding_size; /* size of altivec alignment padding if not in save_size */ int toc_size; /* size to hold TOC if not in save_size */ int total_size; /* total bytes allocated for stack */} rs6000_stack_t;/* Define this if pushing a word on the stack makes the stack pointer a smaller address. */#define STACK_GROWS_DOWNWARD/* 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. On the RS/6000, we grow upwards, from the area after the outgoing arguments. *//* #define FRAME_GROWS_DOWNWARD *//* Size of the outgoing register save area */#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ || DEFAULT_ABI == ABI_AIX_NODESC \ || DEFAULT_ABI == ABI_DARWIN) \ ? (TARGET_64BIT ? 64 : 32) \ : 0)/* Size of the fixed area on the stack */#define RS6000_SAVE_AREA \ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \ << (TARGET_64BIT ? 1 : 0))/* MEM representing address to save the TOC register */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -