📄 mips.h
字号:
/* 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. */#define PREFERRED_RELOAD_CLASS(X,CLASS) \ ((GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ || GET_MODE_CLASS (GET_MODE (X)) == MODE_COMPLEX_FLOAT) \ ? (TARGET_SOFT_FLOAT ? GR_REGS : FP_REGS) \ : ((GET_MODE (X) == VOIDmode) \ ? GR_REGS \ : CLASS))/* Certain machines have the property that some registers cannot be copied to some other registers without using memory. Define this macro on those machines to be a C expression that is non-zero if objects of mode MODE in registers of CLASS1 can only be copied to registers of class CLASS2 by storing a register of CLASS1 into memory and loading that memory location into a register of CLASS2. Do not define this macro if its value would always be zero. */#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ (!TARGET_DEBUG_H_MODE \ && GET_MODE_CLASS (MODE) == MODE_INT \ && ((CLASS1 == FP_REGS && CLASS2 == GR_REGS) \ || (CLASS1 == GR_REGS && CLASS2 == FP_REGS)))/* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */#define CLASS_MAX_NREGS(CLASS, MODE) \ ((((MODE) == DFmode) || ((MODE) == SFmode)) ? 2 \ : ((MODE) == VOIDmode)? ((CLASS) == FP_REGS ? 2 : 1) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))/* If defined, this is a C expression whose value should be nonzero if the insn INSN has the effect of mysteriously clobbering the contents of hard register number REGNO. By "mysterious" we mean that the insn's RTL expression doesn't describe such an effect. If this macro is not defined, it means that no insn clobbers registers mysteriously. This is the usual situation; all else being equal, it is best for the RTL expression to show all the activity. *//* #define INSN_CLOBBERS_REGNO_P(INSN, REGNO) *//* Stack layout; function entry, exit and calling. *//* 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. *//* #define FRAME_GROWS_DOWNWARD *//* Offset within stack frame to start allocating local variables at. If FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local allocated. Otherwise, it is the offset to the BEGINNING of the first local allocated. */#define STARTING_FRAME_OFFSET current_function_outgoing_args_size/* Offset from the stack pointer register to an item dynamically allocated on the stack, e.g., by `alloca'. The default value for this macro is `STACK_POINTER_OFFSET' plus the length of the outgoing arguments. The default is correct for most machines. See `function.c' for details. The MIPS ABI states that functions which dynamically allocate the stack must not have 0 for STACK_DYNAMIC_OFFSET, since it looks like we are trying to create a second frame pointer to the function, so allocate some stack space to make it happy. However, the linker currently complains about linking any code that dynamically allocates stack space, and there seems to be a bug in STACK_DYNAMIC_OFFSET, so don't define this right now. */#if 0#define STACK_DYNAMIC_OFFSET(FUNDECL) \ ((current_function_outgoing_args_size == 0 && current_function_calls_alloca) \ ? 4*UNITS_PER_WORD \ : current_function_outgoing_args_size)#endif/* Structure to be filled in by compute_frame_size with register save masks, and offsets for the current function. */struct mips_frame_info{ long total_size; /* # bytes that the entire frame takes up */ long var_size; /* # bytes that variables take up */ long args_size; /* # bytes that outgoing arguments take up */ long extra_size; /* # bytes of extra gunk */ int gp_reg_size; /* # bytes needed to store gp regs */ int fp_reg_size; /* # bytes needed to store fp regs */ long mask; /* mask of saved gp registers */ long fmask; /* mask of saved fp registers */ long gp_save_offset; /* offset from vfp to store gp registers */ long fp_save_offset; /* offset from vfp to store fp registers */ long gp_sp_offset; /* offset from new sp to store gp registers */ long fp_sp_offset; /* offset from new sp to store fp registers */ int initialized; /* != 0 if frame size already calculated */ int num_gp; /* number of gp registers saved */ int num_fp; /* number of fp registers saved */};extern struct mips_frame_info current_frame_info;/* Store in the variable DEPTH the initial difference between the frame pointer reg contents and the stack pointer reg contents, as of the start of the function body. This depends on the layout of the fixed parts of the stack frame and on how registers are saved. *//* #define INITIAL_FRAME_POINTER_OFFSET(VAR) \ ((VAR) = compute_frame_size (get_frame_size ())) *//* If defined, this macro specifies a table of register pairs used to eliminate unneeded registers that point into the stack frame. If it is not defined, the only elimination attempted by the compiler is to replace references to the frame pointer with references to the stack pointer. The definition of this macro is a list of structure initializations, each of which specifies an original and replacement register. On some machines, the position of the argument pointer is not known until the compilation is completed. In such a case, a separate hard register must be used for the argument pointer. This register can be eliminated by replacing it with either the frame pointer or the argument pointer, depending on whether or not the frame pointer has been eliminated. In this case, you might specify: #define ELIMINABLE_REGS \ {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} Note that the elimination of the argument pointer with the stack pointer is specified first since that is the preferred elimination. */#define ELIMINABLE_REGS \{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}/* A C expression that returns non-zero if the compiler is allowed to try to replace register number FROM-REG with register number TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is defined, and will usually be the constant 1, since most of the cases preventing register elimination are things that the compiler already knows about. */#define CAN_ELIMINATE(FROM, TO) \ (!frame_pointer_needed \ || ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the initial difference between the specified pair of registers. This macro must be defined if `ELIMINABLE_REGS' is defined. */#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \{ compute_frame_size (get_frame_size ()); \ if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ (OFFSET) = 0; \ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ (OFFSET) = current_frame_info.total_size; \ else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ (OFFSET) = current_frame_info.total_size; \ else \ abort (); \}/* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. On the vax, sp@- in a byte insn really pushes a word. *//* #define PUSH_ROUNDING(BYTES) 0 *//* If defined, the maximum amount of space required for outgoing arguments will be computed and placed into the variable `current_function_outgoing_args_size'. No space will be pushed onto the stack for each call; instead, the function prologue should increase the stack frame size by this amount. It is not proper to define both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS'. */#define ACCUMULATE_OUTGOING_ARGS/* Offset from the argument pointer register to the first argument's address. On some machines it may depend on the data type of the function. If `ARGS_GROW_DOWNWARD', this is the offset to the location above the first argument's address. On the MIPS, we must skip the first argument position if we are returning a structure or a union, to account for it's address being passed in $4. However, at the current time, this produces a compiler that can't bootstrap, so comment it out for now. */#if 0#define FIRST_PARM_OFFSET(FNDECL) \ (FNDECL != 0 \ && TREE_TYPE (FNDECL) != 0 \ && TREE_TYPE (TREE_TYPE (FNDECL)) != 0 \ && (TREE_CODE (TREE_TYPE (TREE_TYPE (FNDECL))) == RECORD_TYPE \ || TREE_CODE (TREE_TYPE (TREE_TYPE (FNDECL))) == UNION_TYPE) \ ? UNITS_PER_WORD \ : 0)#else#define FIRST_PARM_OFFSET(FNDECL) 0#endif/* When a parameter is passed in a register, stack space is still allocated for it. For the MIPS, stack space must be allocated, cf Asm Lang Prog Guide page 7-8. BEWARE that some space is also allocated for non existing arguments in register. In case an argument list is of form GF used registers are a0 (a2,a3), but we should push over a1... */#define REG_PARM_STACK_SPACE(FNDECL) ((4*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL))/* Define this if it is the responsibility of the caller to allocate the area reserved for arguments passed in registers. If `ACCUMULATE_OUTGOING_ARGS' is also defined, the only effect of this macro is to determine whether the space is included in `current_function_outgoing_args_size'. */#define OUTGOING_REG_PARM_STACK_SPACE/* Align stack frames on 64 bits (Double Word ). */#define STACK_BOUNDARY 64/* Make sure 16 bytes are always allocated on the stack. */#ifndef STACK_ARGS_ADJUST#define STACK_ARGS_ADJUST(SIZE) \{ \ if (SIZE.constant < 16) \ SIZE.constant = 16; \}#endif/* A C expression that should indicate the number of bytes of its own arguments that a function function pops on returning, or 0 if the function pops no arguments and the caller must therefore pop them all after the function returns. FUNTYPE is a C variable whose value is a tree node that describes the function in question. Normally it is a node of type `FUNCTION_TYPE' that describes the data type of the function. From this it is possible to obtain the data types of the value and arguments (if known). When a call to a library function is being considered, FUNTYPE will contain an identifier node for the library function. Thus, if you need to distinguish among various library functions, you can do so by their names. Note that "library function" in this context means a function used to perform arithmetic, whose name is known specially in the compiler and was not mentioned in the C code being compiled. STACK-SIZE is the number of bytes of arguments passed on the stack. If a variable number of bytes is passed, it is zero, and argument popping will always be the responsibility of the calling function. */#define RETURN_POPS_ARGS(FUNTYPE, SIZE) 0/* Symbolic macros for the registers used to return integer and floating point values. */#define GP_RETURN (GP_REG_FIRST + 2)#define FP_RETURN ((TARGET_SOFT_FLOAT) ? GP_RETURN : (FP_REG_FIRST + 0))/* Symbolic macros for the first/last argument registers. */#define GP_ARG_FIRST (GP_REG_FIRST + 4)#define GP_ARG_LAST (GP_REG_FIRST + 7)#define FP_ARG_FIRST (FP_REG_FIRST + 12)#define FP_ARG_LAST (FP_REG_FIRST + 15)#define MAX_ARGS_IN_REGISTERS 4/* Define how to find the value returned by a library function assuming the value has mode MODE. */#define LIBCALL_VALUE(MODE) \ gen_rtx (REG, MODE, \ (GET_MODE_CLASS (MODE) == MODE_FLOAT) \ ? FP_RETURN \ : GP_RETURN)/* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). If the precise function being called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. */#define FUNCTION_VALUE(VALTYPE, FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE))/* 1 if N is a possible register number for a function value. On the MIPS, R2 R3 and F0 F2 are the only register thus used. Currently, R2 and F0 are only implemented here (C has no complex type) */#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_RETURN || (N) == FP_RETURN)/* 1 if N is a possible register number for function argument passing. */#define FUNCTION_ARG_REGNO_P(N) (((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST) \ || ((N) >= FP_ARG_FIRST && (N) <= FP_ARG_LAST \ && (0 == (N) % 2)))/* A C expression which can inhibit the returning of certain function values in registers, based on the type of value. A nonzero value says to return the function value in memory, just as large structures are always returned. Here TYPE will be a C expression of type `tree', representing the data type of the value. Note that values of mode `BLKmode' are returned in memory regardless of this macro. Also, the option `-fpcc-struct-return' takes effect regardless of this macro. On most systems, it is possible to leave the macro undefined; this causes a default definition to be used, whose value is the constant 0. GCC normally converts 1 byte structures into chars, 2 byte structs into shorts, and 4 byte structs into ints, and returns them this way. Defining the following macro overrides this, to give us MIPS cc compatibility. */#define RETURN_IN_MEMORY(TYPE) \ ((TREE_CODE (TYPE) == RECORD_TYPE) || (TREE_CODE (TYPE) == UNION_TYPE))/* A code distinguishing the floating point format of the target machine. There are three defined values: IEEE_FLOAT_FORMAT, VAX_FLOAT_FORMAT, and UNKNOWN_FLOAT_FORMAT. */#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT/* Define a data type for recording info about an argument list during the scan of that argument list. This data type should hold all necessary information about the function itself
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -