📄 s390.h
字号:
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", "ADDR_REGS", "GENERAL_REGS", \ "FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" }/* Class -> register mapping. */#define REG_CLASS_CONTENTS \{ \ { 0x00000000, 0x00000000 }, /* NO_REGS */ \ { 0x0000fffe, 0x00000005 }, /* ADDR_REGS */ \ { 0x0000ffff, 0x00000005 }, /* GENERAL_REGS */ \ { 0xffff0000, 0x00000000 }, /* FP_REGS */ \ { 0xfffffffe, 0x00000005 }, /* ADDR_FP_REGS */ \ { 0xffffffff, 0x00000005 }, /* GENERAL_FP_REGS */ \ { 0xffffffff, 0x00000007 }, /* 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 : NO_REGS)#define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? (unsigned long) (VALUE) < 256 : \ (C) == 'J' ? (unsigned long) (VALUE) < 4096 : \ (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : \ (C) == 'L' ? (unsigned long) (VALUE) < 65536 : 0)#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1#define EXTRA_CONSTRAINT(OP, C) \ ((C) == 'Q' ? q_constraint (OP) : \ (C) == 'S' ? larl_operand (OP, GET_MODE (OP)) : 0)#define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')/* 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/* #undef FRAME_GROWS_DOWNWARD *//* #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. */extern int current_function_outgoing_args_size;#define STARTING_FRAME_OFFSET \ (STACK_POINTER_OFFSET + current_function_outgoing_args_size)/* Offset from the stack pointer register to an item dynamically allocated on the stack, e.g., by `alloca'. */#define STACK_DYNAMIC_OFFSET(FUNDECL) (STARTING_FRAME_OFFSET)/* 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/* 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) \ ((FRAME) != hard_frame_pointer_rtx ? (FRAME) : \ plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET)) #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 ? GEN_INT (-1) : 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, plus_constant (arg_pointer_rtx, \ TARGET_64BIT? -48 : -40))/* 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/* 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 INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 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}} #define CAN_ELIMINATE(FROM, TO) (1)#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \{ if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ { (OFFSET) = 0; } \ else if ((FROM) == FRAME_POINTER_REGNUM \ && (TO) == HARD_FRAME_POINTER_REGNUM) \ { (OFFSET) = 0; } \ else if ((FROM) == ARG_POINTER_REGNUM \ && (TO) == HARD_FRAME_POINTER_REGNUM) \ { (OFFSET) = s390_arg_frame_offset (); } \ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ { (OFFSET) = s390_arg_frame_offset (); } \ else \ abort(); \}/* 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) \ ((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)#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ s390_function_arg_pass_by_reference (MODE, TYPE)#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0/* 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. */ /* We return scalars in general purpose register 2 for integral values, and floating point register 0 for fp values. */#define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \ && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \ || POINTER_TYPE_P (VALTYPE) \ ? word_mode : TYPE_MODE (VALTYPE), \ TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 16 : 2)/* Define how to find the value returned by a library function assuming the value has mode MODE. */#define RET_REG(MODE) ((GET_MODE_CLASS (MODE) == MODE_INT \ || TARGET_SOFT_FLOAT ) ? 2 : 16)#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, RET_REG (MODE))/* Only gpr 2 and fpr 0 are ever used as return registers. */#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)/* Aggregate return values. *//* The definition of this macro implies that there are cases where a scalar value cannot be returned in registers. */#define RETURN_IN_MEMORY(type) \ (TYPE_MODE (type) == BLKmode || \ GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_INT || \ GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT)/* Structure value address is passed as invisible first argument (gpr 2). */#define STRUCT_VALUE 0/* Function entry and exit. */ /* When returning from a function, the stack pointer does not matter. */#define EXIT_IGNORE_STACK 1/* Profiling. */#define FUNCTION_PROFILER(FILE, LABELNO) \ s390_function_profiler ((FILE), ((LABELNO)))#define PROFILE_BEFORE_PROLOGUE 1/* Implementing the varargs macros. */#define BUILD_VA_LIST_TYPE(VALIST) \ (VALIST) = s390_build_va_list ()#define EXPAND_BUILTIN_VA_START(valist, nextarg) \ s390_va_start (valist, nextarg)#define EXPAND_BUILTIN_VA_ARG(valist, type) \ s390_va_arg (valist, type)/* Trampolines for nested functions. */#define TRAMPOLINE_SIZE (TARGET_64BIT ? 36 : 20)#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \ s390_initialize_trampoline ((ADDR), (FNADDR), (CXT))#define TRAMPOLINE_TEMPLATE(FILE) \ s390_trampoline_template (FILE)/* Library calls. */ /* We should use memcpy, not bcopy. */#define TARGET_MEM_FUNCTIONS/* Addressing modes, and classification of registers for them. *//* Recognize any constant value that is a valid address. */#define CONSTANT_ADDRESS_P(X) 0/* Maximum number of registers that can appear in a valid memory address. */#define MAX_REGS_PER_ADDRESS 2/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. We have two alternate definitions for each of them. The usual definition accepts all pseudo regs; the other rejects them all. The symbol REG_OK_STRICT causes the latter definition to be used. Most source files want to accept pseudo regs in the hope that they will get allocated to the class that the insn wants them to be in. Some source files that are used after register allocation need to be strict. */#define REG_OK_FOR_INDEX_NONSTRICT_P(X) \((GET_MODE (X) == Pmode) && \ ((REGNO (X) >= FIRST_PSEUDO_REGISTER) \ || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS)) #define REG_OK_FOR_BASE_NONSTRICT_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X)#define REG_OK_FOR_INDEX_STRICT_P(X) \((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_INDEX_P (REGNO (X))))#define REG_OK_FOR_BASE_STRICT_P(X) \((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_BASE_P (REGNO (X))))#ifndef REG_OK_STRICT#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P(X)#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P(X)#else#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P(X)#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P(X)#endif/* S/390 has no mode dependent addresses. */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid memory address for an instruction. The MODE argument is the machine mode for the MEM expression that wants to use this address. */#ifdef REG_OK_STRICT#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \{ \ if (legitimate_address_p (MODE, X, 1)) \ goto ADDR; \}#else#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \{ \ if (legitimate_address_p (MODE, X, 0)) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -