📄 sparc.h
字号:
#define REG_CLASS_FROM_LETTER(C) \(TARGET_V9 \ ? ((C) == 'f' ? FP_REGS \ : (C) == 'e' ? EXTRA_FP_REGS \ : (C) == 'c' ? FPCC_REGS \ : ((C) == 'd' && TARGET_VIS) ? FP_REGS\ : ((C) == 'b' && TARGET_VIS) ? EXTRA_FP_REGS\ : ((C) == 'h' && TARGET_V8PLUS) ? I64_REGS\ : NO_REGS) \ : ((C) == 'f' ? FP_REGS \ : (C) == 'e' ? FP_REGS \ : (C) == 'c' ? FPCC_REGS \ : NO_REGS))/* The letters I, J, K, L and M 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 used for the range of constants an insn can actually contain. `J' is used for the range which is just zero (since that is R0). `K' is used for constants which can be loaded with a single sethi insn. `L' is used for the range of constants supported by the movcc insns. `M' is used for the range of constants supported by the movrcc insns. `N' is like K, but for constants wider than 32 bits. `O' is used for the range which is just 4096. */#define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)#define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800)#define SPARC_SIMM13_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x1000 < 0x2000)/* 10 and 11 bit immediates are only used for a few specific insns. SMALL_INT is used throughout the port so we continue to use it. */#define SMALL_INT(X) (SPARC_SIMM13_P (INTVAL (X)))/* 13 bit immediate, considering only the low 32 bits */#define SMALL_INT32(X) (SPARC_SIMM13_P (trunc_int_for_mode \ (INTVAL (X), SImode)))#define SPARC_SETHI_P(X) \ (((unsigned HOST_WIDE_INT) (X) \ & ((unsigned HOST_WIDE_INT) 0x3ff - GET_MODE_MASK (SImode) - 1)) == 0)#define SPARC_SETHI32_P(X) \ (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))#define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? SPARC_SIMM13_P (VALUE) \ : (C) == 'J' ? (VALUE) == 0 \ : (C) == 'K' ? SPARC_SETHI32_P (VALUE) \ : (C) == 'L' ? SPARC_SIMM11_P (VALUE) \ : (C) == 'M' ? SPARC_SIMM10_P (VALUE) \ : (C) == 'N' ? SPARC_SETHI_P (VALUE) \ : (C) == 'O' ? (VALUE) == 4096 \ : 0)/* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. */#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'G' ? fp_zero_operand (VALUE, GET_MODE (VALUE)) \ : (C) == 'H' ? arith_double_operand (VALUE, DImode) \ : (C) == 'O' ? arith_double_4096_operand (VALUE, DImode) \ : 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. *//* - We can't load constants into FP registers. - We can't load FP constants into integer registers when soft-float, because there is no soft-float pattern with a r/F constraint. - We can't load FP constants into integer registers for TFmode unless it is 0.0L, because there is no movtf pattern with a r/F constraint. - Try and reload integer constants (symbolic or otherwise) back into registers directly, rather than having them dumped to memory. */#define PREFERRED_RELOAD_CLASS(X,CLASS) \ (CONSTANT_P (X) \ ? ((FP_REG_CLASS_P (CLASS) \ || (CLASS) == GENERAL_OR_FP_REGS \ || (CLASS) == GENERAL_OR_EXTRA_FP_REGS \ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && ! TARGET_FPU) \ || (GET_MODE (X) == TFmode \ && ! fp_zero_operand (X, TFmode))) \ ? NO_REGS \ : (!FP_REG_CLASS_P (CLASS) \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \ ? GENERAL_REGS \ : (CLASS)) \ : (CLASS))/* Return the register class of a scratch register needed to load IN into a register of class CLASS in MODE. We need a temporary when loading/storing a HImode/QImode value between memory and the FPU registers. This can happen when combine puts a paradoxical subreg in a float/fix conversion insn. We need a temporary when loading/storing a DFmode value between unaligned memory and the upper FPU registers. */#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ ((FP_REG_CLASS_P (CLASS) \ && ((MODE) == HImode || (MODE) == QImode) \ && (GET_CODE (IN) == MEM \ || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ && true_regnum (IN) == -1))) \ ? GENERAL_REGS \ : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode \ && GET_CODE (IN) == MEM && TARGET_ARCH32 \ && ! mem_min_alignment ((IN), 8)) \ ? FP_REGS \ : (((TARGET_CM_MEDANY \ && symbolic_operand ((IN), (MODE))) \ || (TARGET_CM_EMBMEDANY \ && text_segment_operand ((IN), (MODE)))) \ && !flag_pic) \ ? GENERAL_REGS \ : NO_REGS)#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \ ((FP_REG_CLASS_P (CLASS) \ && ((MODE) == HImode || (MODE) == QImode) \ && (GET_CODE (IN) == MEM \ || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ && true_regnum (IN) == -1))) \ ? GENERAL_REGS \ : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode \ && GET_CODE (IN) == MEM && TARGET_ARCH32 \ && ! mem_min_alignment ((IN), 8)) \ ? FP_REGS \ : (((TARGET_CM_MEDANY \ && symbolic_operand ((IN), (MODE))) \ || (TARGET_CM_EMBMEDANY \ && text_segment_operand ((IN), (MODE)))) \ && !flag_pic) \ ? GENERAL_REGS \ : NO_REGS)/* On SPARC it is not possible to directly move data between GENERAL_REGS and FP_REGS. */#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))/* Return the stack location to use for secondary memory needed reloads. We want to use the reserved location just below the frame pointer. However, we must ensure that there is a frame, so use assign_stack_local if the frame size is zero. */#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ (get_frame_size () == 0 \ ? assign_stack_local (MODE, GET_MODE_SIZE (MODE), 0) \ : gen_rtx_MEM (MODE, plus_constant (frame_pointer_rtx, \ STARTING_FRAME_OFFSET)))/* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 because the movsi and movsf patterns don't handle r/f moves. For v8 we copy the default definition. */#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (TARGET_ARCH64 \ ? (GET_MODE_BITSIZE (MODE) < 32 \ ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ : MODE) \ : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0) \ : MODE))/* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. *//* On SPARC, this is the size of MODE in words. */#define CLASS_MAX_NREGS(CLASS, MODE) \ (FP_REG_CLASS_P (CLASS) ? (GET_MODE_SIZE (MODE) + 3) / 4 \ : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)/* Stack layout; function entry, exit and calling. *//* Define the number of register that can hold parameters. This macro is only used in other macro definitions below and in sparc.c. MODE is the mode of the argument. !v9: All args are passed in %o0-%o5. v9: %o0-%o5 and %f0-%f31 are cumulatively used to pass values. See the description in sparc.c. */#define NPARM_REGS(MODE) \(TARGET_ARCH64 \ ? (GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 6) \ : 6)/* 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. *//* This allows space for one TFmode floating point value. */#define STARTING_FRAME_OFFSET \ (TARGET_ARCH64 ? -16 \ : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))/* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. On SPARC, don't define this because there are no push insns. *//* #define PUSH_ROUNDING(BYTES) *//* Offset of first parameter from the argument pointer register value. !v9: This is 64 for the ins and locals, plus 4 for the struct-return reg even if this function isn't going to use it. v9: This is 128 for the ins and locals. */#define FIRST_PARM_OFFSET(FNDECL) \ (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD)/* Offset from the argument pointer register value to the CFA. This is different from FIRST_PARM_OFFSET because the register window comes between the CFA and the arguments. */#define ARG_POINTER_CFA_OFFSET(FNDECL) 0/* When a parameter is passed in a register, stack space is still allocated for it. !v9: All 6 possible integer registers have backing store allocated. v9: Only space for the arguments passed is allocated. *//* ??? Ideally, we'd use zero here (as the minimum), but zero has special meaning to the backend. Further, we need to be able to detect if a varargs/unprototyped function is called, as they may want to spill more registers than we've provided space. Ugly, ugly. So for now we retain all 6 slots even for v9. */#define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD)/* Definitions for register elimination. *//* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */#define ELIMINABLE_REGS \ {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }/* The way this is structured, we can't eliminate SFP in favor of SP if the frame pointer is required: we want to use the SFP->HFP elimination in that case. But the test in update_eliminables doesn't know we are assuming below that we only do the former elimination. */#define CAN_ELIMINATE(FROM, TO) \ ((TO) == HARD_FRAME_POINTER_REGNUM || !FRAME_POINTER_REQUIRED)#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ do { \ (OFFSET) = 0; \ if ((TO) == STACK_POINTER_REGNUM) \ { \ /* Note, we always pretend that this is a leaf function \ because if it's not, there's no point in trying to \ eliminate the frame pointer. If it is a leaf \ function, we guessed right! */ \ if (TARGET_FLAT) \ (OFFSET) = \ sparc_flat_compute_frame_size (get_frame_size ()); \ else \ (OFFSET) = compute_frame_size (get_frame_size (), 1); \ } \ (OFFSET) += SPARC_STACK_BIAS; \ } while (0)/* Keep the stack pointer constant throughout the function. This is both an optimization and a necessity: longjmp doesn't behave itself when the stack pointer moves within the function! */#define ACCUMULATE_OUTGOING_ARGS 1/* Value is the number of bytes of arguments automatically popped when returning from a subroutine call. FUNDECL is the declaration node of the function (as a tree), FUNTYPE is the data type of the function (as a tree), or for a library call it is an identifier node for the subroutine name. SIZE is the number of bytes of arguments passed on the stack. */#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0/* Some subroutine macros specific to this machine. When !TARGET_FPU, put float return values in the general registers, since we don't have any fp registers. */#define BASE_RETURN_VALUE_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))#define BASE_OUTGOING_VALUE_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ : TARGET_FLAT ? 8 : 24) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \ : (TARGET_FLAT ? 8 : 24)))#define BASE_PASSING_ARG_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ : 8)/* ??? FIXME -- seems wrong for v9 structure passing... */#define BASE_INCOMING_ARG_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ : TARGET_FLAT ? 8 : 24) \ : (TARGET_FLAT ? 8 : 24))/* Define this macro if the target machine has "register windows". This C expression returns the register number as seen by the called function corresponding to register number OUT as seen by the calling function. Return OUT if register number OUT is not an outbound register. */#define INCOMING_REGNO(OUT) \ ((TARGET_FLAT || (OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16)/* Define this macro if the target machine has "register windows". This C expression returns the register number as seen by the calling function corresponding to register number IN as seen by the called function. Return IN if register number IN is not an inbound register. */#define OUTGOING_REGNO(IN) \ ((TARGET_FLAT || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)/* Define this macro if the target machine has register windows. This C expression returns true if the register is call-saved but is in the register window. */#define LOCAL_REGNO(REGNO) \ (TARGET_FLAT ? 0 : (REGNO) >= 16 && (REGNO) <= 31)/* 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. *//* On SPARC the value is found in the first "output" register. */#define FUNCTION_VALUE(VALTYPE, FUNC) \ funct
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -