📄 mips.h
字号:
braced groupings containing several integers. Each sub-initializer must be suitable as an initializer for the type `HARD_REG_SET' which is defined in `hard-reg-set.h'. */#define REG_CLASS_CONTENTS \{ \ { 0x00000000, 0x00000000, 0x00000000 }, /* no registers */ \ { 0xffffffff, 0x00000000, 0x00000000 }, /* integer registers */ \ { 0x00000000, 0xffffffff, 0x00000000 }, /* floating registers*/ \ { 0x00000000, 0x00000000, 0x00000001 }, /* hi register */ \ { 0x00000000, 0x00000000, 0x00000002 }, /* lo register */ \ { 0x00000000, 0x00000000, 0x00000004 }, /* hilo register */ \ { 0x00000000, 0x00000000, 0x00000003 }, /* mul/div registers */ \ { 0x00000000, 0x00000000, 0x00000008 }, /* status registers */ \ { 0xffffffff, 0xffffffff, 0x0000000f } /* all registers */ \}/* A C expression whose value is a register class containing hard register REGNO. In general there is more that one such class; choose a class which is "minimal", meaning that no smaller class also contains the register. */extern enum reg_class mips_regno_to_class[];#define REGNO_REG_CLASS(REGNO) mips_regno_to_class[ (REGNO) ]/* A macro whose definition is the name of the class to which a valid base register must belong. A base register is one used in an address which is the register value plus a displacement. */#define BASE_REG_CLASS GR_REGS/* A macro whose definition is the name of the class to which a valid index register must belong. An index register is one used in an address where its value is either multiplied by a scale factor or added to another register (as well as added to a displacement). */#define INDEX_REG_CLASS NO_REGS/* REGISTER AND CONSTANT CLASSES *//* Get reg_class from a letter such as appears in the machine description. DEFINED REGISTER CLASSES: 'd' General (aka integer) registers 'f' Floating point registers 'h' Hi register 'l' Lo register 'x' Multiply/divide registers 'a' HILO_REG 'z' FP Status register 'b' All registers */extern enum reg_class mips_char_to_class[];#define REG_CLASS_FROM_LETTER(C) mips_char_to_class[ (C) ]/* The letters I, J, K, L, M, N, O, 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. *//* For MIPS: `I' is used for the range of constants an arithmetic insn can actually contain (16 bits signed integers). `J' is used for the range which is just zero (ie, $r0). `K' is used for the range of constants a logical insn can actually contain (16 bit zero-extended integers). `L' is used for the range of constants that be loaded with lui (ie, the bottom 16 bits are zero). `M' is used for the range of constants that take two words to load (ie, not matched by `I', `K', and `L'). `N' is used for negative 16 bit constants. `O' is an exact power of 2 (not yet used in the md file). `P' is used for positive 16 bit constants. */#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000)#define SMALL_INT_UNSIGNED(X) ((unsigned HOST_WIDE_INT) (INTVAL (X)) < 0x10000)#define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? ((unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000) \ : (C) == 'J' ? ((VALUE) == 0) \ : (C) == 'K' ? ((unsigned HOST_WIDE_INT) (VALUE) < 0x10000) \ : (C) == 'L' ? (((VALUE) & 0x0000ffff) == 0 \ && (((VALUE) & ~2147483647) == 0 \ || ((VALUE) & ~2147483647) == ~2147483647)) \ : (C) == 'M' ? ((((VALUE) & ~0x0000ffff) != 0) \ && (((VALUE) & ~0x0000ffff) != ~0x0000ffff) \ && (((VALUE) & 0x0000ffff) != 0 \ || (((VALUE) & ~2147483647) != 0 \ && ((VALUE) & ~2147483647) != ~2147483647))) \ : (C) == 'N' ? (((VALUE) & ~0x0000ffff) == ~0x0000ffff) \ : (C) == 'O' ? (exact_log2 (VALUE) >= 0) \ : (C) == 'P' ? ((VALUE) != 0 && (((VALUE) & ~0x0000ffff) == 0)) \ : 0)/* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. *//* For Mips 'G' : Floating point 0 */#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'G' \ && (VALUE) == CONST0_RTX (GET_MODE (VALUE)))/* Letters in the range `Q' through `U' may be defined in a machine-dependent fashion to stand for arbitrary operand types. The machine description macro `EXTRA_CONSTRAINT' is passed the operand as its first argument and the constraint letter as its second operand. `Q' is for memory references which take more than 1 instruction. `R' is for memory references which take 1 word for the instruction. `S' is for references to extern items which are PIC for OSF/rose. */#define EXTRA_CONSTRAINT(OP,CODE) \ ((GET_CODE (OP) != MEM) ? FALSE \ : ((CODE) == 'Q') ? !simple_memory_operand (OP, GET_MODE (OP)) \ : ((CODE) == 'R') ? simple_memory_operand (OP, GET_MODE (OP)) \ : ((CODE) == 'S') ? (HALF_PIC_P () && CONSTANT_P (OP) \ && HALF_PIC_ADDRESS_P (OP)) \ : FALSE)/* 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) \ ((CLASS) != ALL_REGS \ ? (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_CLASS (GET_MODE (X)) == MODE_INT \ || 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))) \ || (TARGET_FLOAT64 && !TARGET_64BIT && (MODE) == DFmode \ && ((CLASS1 == GR_REGS && CLASS2 == FP_REGS) \ || (CLASS2 == GR_REGS && CLASS1 == FP_REGS))))/* The HI and LO registers can only be reloaded via the general registers. */#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ mips_secondary_reload_class (CLASS, MODE, X, 1)#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ mips_secondary_reload_class (CLASS, MODE, X, 0)/* Not declared above, with the other functions, because enum reg_class is not declared yet. */extern enum reg_class mips_secondary_reload_class ();/* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */#define CLASS_UNITS(mode, size) \ ((GET_MODE_SIZE (mode) + (size) - 1) / (size))#define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == FP_REGS \ ? (TARGET_FLOAT64 \ ? CLASS_UNITS (MODE, 8) \ : 2 * CLASS_UNITS (MODE, 8)) \ : CLASS_UNITS (MODE, 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. *//* Don't enable support for the 64 bit ABI calling convention. Some embedded code depends on the old 64 bit calling convention. */#define ABI_64BIT 0/* 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 \ + (TARGET_ABICALLS ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))/* 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 \ || (TO) == STACK_POINTER_REGNUM)) \ (OFFSET) = (current_frame_info.total_size \ - (ABI_64BIT && mips_isa >= 3 \ ? current_function_pretend_args_size \ : 0)); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -