📄 s390.h
字号:
Integer modes > word size fit into successive GPRs, starting with an even-numbered register. SImode and DImode fit into FPRs as well. Floating point modes <= word size fit into any FPR or GPR. Floating point modes > word size (i.e. DFmode on 32-bit) fit into any FPR, or an even-odd GPR pair. TFmode fits only into an even-odd FPR pair. Complex floating point modes fit either into two FPRs, or into successive GPRs (again starting with an even number). TCmode fits only into two successive even-odd FPR pairs. Condition code modes fit only into the CC register. */#define HARD_REGNO_NREGS(REGNO, MODE) \ (FP_REGNO_P(REGNO)? \ (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? \ 2 * ((GET_MODE_SIZE(MODE) / 2 + 8 - 1) / 8) : \ ((GET_MODE_SIZE(MODE) + 8 - 1) / 8)) : \ GENERAL_REGNO_P(REGNO)? \ ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \ ACCESS_REGNO_P(REGNO)? \ ((GET_MODE_SIZE(MODE) + 4 - 1) / 4) : \ 1)#define HARD_REGNO_MODE_OK(REGNO, MODE) \ (FP_REGNO_P(REGNO)? \ (((MODE) == SImode || (MODE) == DImode \ || GET_MODE_CLASS(MODE) == MODE_FLOAT \ || GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) \ && (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \ GENERAL_REGNO_P(REGNO)? \ ((HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) \ && (((MODE) != TFmode && (MODE) != TCmode) || TARGET_64BIT)) : \ CC_REGNO_P(REGNO)? \ GET_MODE_CLASS (MODE) == MODE_CC : \ FRAME_REGNO_P(REGNO)? \ (enum machine_mode) (MODE) == Pmode : \ ACCESS_REGNO_P(REGNO)? \ (((MODE) == SImode || ((enum machine_mode) (MODE) == Pmode)) \ && (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \ 0)#define HARD_REGNO_RENAME_OK(FROM, TO) \ s390_hard_regno_rename_ok (FROM, TO)#define MODES_TIEABLE_P(MODE1, MODE2) \ (((MODE1) == SFmode || (MODE1) == DFmode) \ == ((MODE2) == SFmode || (MODE2) == DFmode))/* Maximum number of registers to represent a value of mode MODE in a register of class CLASS. */#define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == FP_REGS ? \ (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? \ 2 * (GET_MODE_SIZE (MODE) / 2 + 8 - 1) / 8 : \ (GET_MODE_SIZE (MODE) + 8 - 1) / 8) : \ (CLASS) == ACCESS_REGS ? \ (GET_MODE_SIZE (MODE) + 4 - 1) / 4 : \ (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)/* If a 4-byte value is loaded into a FPR, it is placed into the *upper* half of the register, not the lower. Therefore, we cannot use SUBREGs to switch between modes in FP registers. Likewise for access registers, since they have only half the word size on 64-bit. */#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ ? ((reg_classes_intersect_p (FP_REGS, CLASS) \ && (GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8)) \ || reg_classes_intersect_p (ACCESS_REGS, CLASS)) : 0)/* Register classes. *//* We use the following register classes: GENERAL_REGS All general purpose registers ADDR_REGS All general purpose registers except %r0 (These registers can be used in address generation) FP_REGS All floating point registers CC_REGS The condition code register ACCESS_REGS The access registers GENERAL_FP_REGS Union of GENERAL_REGS and FP_REGS ADDR_FP_REGS Union of ADDR_REGS and FP_REGS GENERAL_CC_REGS Union of GENERAL_REGS and CC_REGS ADDR_CC_REGS Union of ADDR_REGS and CC_REGS NO_REGS No registers ALL_REGS All registers Note that the 'fake' frame pointer and argument pointer registers are included amongst the address registers here. */enum reg_class{ NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, ACCESS_REGS, ADDR_CC_REGS, GENERAL_CC_REGS, FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS, ALL_REGS, LIM_REG_CLASSES};#define N_REG_CLASSES (int) LIM_REG_CLASSES#define REG_CLASS_NAMES \{ "NO_REGS", "CC_REGS", "ADDR_REGS", "GENERAL_REGS", "ACCESS_REGS", \ "ADDR_CC_REGS", "GENERAL_CC_REGS", \ "FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" }/* Class -> register mapping. */#define REG_CLASS_CONTENTS \{ \ { 0x00000000, 0x00000000 }, /* NO_REGS */ \ { 0x00000000, 0x00000002 }, /* CC_REGS */ \ { 0x0000fffe, 0x0000000d }, /* ADDR_REGS */ \ { 0x0000ffff, 0x0000000d }, /* GENERAL_REGS */ \ { 0x00000000, 0x00000030 }, /* ACCESS_REGS */ \ { 0x0000fffe, 0x0000000f }, /* ADDR_CC_REGS */ \ { 0x0000ffff, 0x0000000f }, /* GENERAL_CC_REGS */ \ { 0xffff0000, 0x00000000 }, /* FP_REGS */ \ { 0xfffffffe, 0x0000000d }, /* ADDR_FP_REGS */ \ { 0xffffffff, 0x0000000d }, /* GENERAL_FP_REGS */ \ { 0xffffffff, 0x0000003f }, /* ALL_REGS */ \}/* Register -> class mapping. */extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])/* ADDR_REGS can be used as base or index register. */#define INDEX_REG_CLASS ADDR_REGS#define BASE_REG_CLASS ADDR_REGS/* Check whether REGNO is a hard register of the suitable class or a pseudo register currently allocated to one such. */#define REGNO_OK_FOR_INDEX_P(REGNO) \ (((REGNO) < FIRST_PSEUDO_REGISTER \ && REGNO_REG_CLASS ((REGNO)) == ADDR_REGS) \ || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16))#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)/* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. */#define PREFERRED_RELOAD_CLASS(X, CLASS) \ s390_preferred_reload_class ((X), (CLASS))/* We need a secondary reload when loading a PLUS which is not a valid operand for LOAD ADDRESS. */#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ s390_secondary_input_reload_class ((CLASS), (MODE), (IN))/* We need a secondary reload when storing a double-word to a non-offsettable memory address. */#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT) \ s390_secondary_output_reload_class ((CLASS), (MODE), (OUT))/* We need secondary memory to move data between GPRs and FPRs. */#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ ((CLASS1) != (CLASS2) && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS))/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit because the movsi and movsf patterns don't handle r/f moves. */#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_BITSIZE (MODE) < 32 \ ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ : MODE)/* Define various machine-dependent constraint letters. */#define REG_CLASS_FROM_LETTER(C) \ ((C) == 'a' ? ADDR_REGS : \ (C) == 'd' ? GENERAL_REGS : \ (C) == 'f' ? FP_REGS : \ (C) == 'c' ? CC_REGS : \ (C) == 't' ? ACCESS_REGS : NO_REGS)#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ s390_const_ok_for_constraint_p ((VALUE), (C), (STR))#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \ s390_const_double_ok_for_constraint_p ((VALUE), (C), (STR))#define EXTRA_CONSTRAINT_STR(OP, C, STR) \ s390_extra_constraint_str ((OP), (C), (STR))#define EXTRA_MEMORY_CONSTRAINT(C, STR) \ ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T' || (C) == 'A')#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \ ((C) == 'U' || (C) == 'W' || (C) == 'Y')#define CONSTRAINT_LEN(C, STR) \ ((C) == 'N' ? 5 : \ (C) == 'O' ? 2 : \ (C) == 'A' ? 2 : \ (C) == 'B' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))/* Stack layout and calling conventions. *//* Our stack grows from higher to lower addresses. However, local variables are accessed by positive offsets, and function arguments are stored at increasing addresses. */#define STACK_GROWS_DOWNWARD#define FRAME_GROWS_DOWNWARD 1/* #undef ARGS_GROW_DOWNWARD *//* The basic stack layout looks like this: the stack pointer points to the register save area for called functions. Above that area is the location to place outgoing arguments. Above those follow dynamic allocations (alloca), and finally the local variables. *//* Offset from stack-pointer to first location of outgoing args. */#define STACK_POINTER_OFFSET (TARGET_64BIT ? 160 : 96)/* Offset within stack frame to start allocating local variables at. */#define STARTING_FRAME_OFFSET 0/* Offset from the stack pointer register to an item dynamically allocated on the stack, e.g., by `alloca'. */extern int current_function_outgoing_args_size;#define STACK_DYNAMIC_OFFSET(FUNDECL) \ (STACK_POINTER_OFFSET + current_function_outgoing_args_size)/* Offset of first parameter from the argument pointer register value. We have a fake argument pointer register that points directly to the argument area. */#define FIRST_PARM_OFFSET(FNDECL) 0/* Defining this macro makes __builtin_frame_address(0) and __builtin_return_address(0) work with -fomit-frame-pointer. */#define INITIAL_FRAME_ADDRESS_RTX \ (TARGET_PACKED_STACK ? \ plus_constant (arg_pointer_rtx, -UNITS_PER_WORD) : \ plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))/* The return address of the current frame is retrieved from the initial value of register RETURN_REGNUM. For frames farther back, we use the stack slot where the corresponding RETURN_REGNUM register was saved. */#define DYNAMIC_CHAIN_ADDRESS(FRAME) \ (TARGET_PACKED_STACK ? \ plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME))#define RETURN_ADDR_RTX(COUNT, FRAME) \ s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))/* In 31-bit mode, we need to mask off the high bit of return addresses. */#define MASK_RETURN_ADDR (TARGET_64BIT ? constm1_rtx : GEN_INT (0x7fffffff))/* Exception handling. *//* Describe calling conventions for DWARF-2 exception handling. */#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_REGNUM)#define INCOMING_FRAME_SP_OFFSET STACK_POINTER_OFFSET#define DWARF_FRAME_RETURN_COLUMN 14/* Describe how we implement __builtin_eh_return. */#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)#define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx) /* Select a format to encode pointers in exception handling data. */#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ (flag_pic \ ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4 \ : DW_EH_PE_absptr)/* Frame registers. */#define STACK_POINTER_REGNUM 15#define FRAME_POINTER_REGNUM 34#define HARD_FRAME_POINTER_REGNUM 11#define ARG_POINTER_REGNUM 32#define RETURN_ADDRESS_POINTER_REGNUM 35/* The static chain must be call-clobbered, but not used for function argument passing. As register 1 is clobbered by the trampoline code, we only have one option. */#define STATIC_CHAIN_REGNUM 0/* Number of hardware registers that go into the DWARF-2 unwind info. To avoid ABI incompatibility, this number must not change even as 'fake' hard registers are added or removed. */#define DWARF_FRAME_REGISTERS 34/* Frame pointer and argument pointer elimination. */#define FRAME_POINTER_REQUIRED 0#define ELIMINABLE_REGS \{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \ { BASE_REGNUM, BASE_REGNUM }}#define CAN_ELIMINATE(FROM, TO) \ s390_can_eliminate ((FROM), (TO))#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ (OFFSET) = s390_initial_elimination_offset ((FROM), (TO))/* Stack arguments. *//* We need current_function_outgoing_args to be valid. */#define ACCUMULATE_OUTGOING_ARGS 1/* Return doesn't modify the stack. */#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0/* Register arguments. */typedef struct s390_arg_structure{ int gprs; /* gpr so far */ int fprs; /* fpr so far */}CUMULATIVE_ARGS;#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN, N_NAMED_ARGS) \ ((CUM).gprs=0, (CUM).fprs=0)#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ s390_function_arg_advance (&CUM, MODE, TYPE, NAMED)#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ s390_function_arg (&CUM, MODE, TYPE, NAMED)/* Arguments can be placed in general registers 2 to 6, or in floating point registers 0 and 2. */#define FUNCTION_ARG_REGNO_P(N) (((N) >=2 && (N) <7) || \ (N) == 16 || (N) == 17)/* Scalar return values. */#define FUNCTION_VALUE(VALTYPE, FUNC) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -