📄 sparc.h
字号:
((C) == 'f' ? FP_REGS : (C) == 'e' ? FP_REGS : NO_REGS)#endif/* 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. For SPARC, `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. */#define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x1000) < 0x2000)#define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? (unsigned) ((VALUE) + 0x1000) < 0x2000 \ : (C) == 'J' ? (VALUE) == 0 \ : (C) == 'K' ? ((VALUE) & 0x3ff) == 0 \ : 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) \ : (C) == 'H' ? arith_double_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 any FP constant if an 'E' constraint fails to match it. */#define PREFERRED_RELOAD_CLASS(X,CLASS) \ (CONSTANT_P (X) \ && (FP_REG_CLASS_P (CLASS) \ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \ || HOST_BITS_PER_INT != BITS_PER_WORD))) \ ? NO_REGS : (CLASS))/* Return the register class of a scratch register needed to load IN into a register of class CLASS in MODE. On the SPARC, when PIC, we need a temporary when loading some addresses into a register. Also, 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. */#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 : 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 : 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, gen_rtx (PLUS, Pmode, frame_pointer_rtx, \ GEN_INT (STARTING_FRAME_OFFSET))))/* Get_secondary_mem widens it's 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_V9 \ ? (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. These two macros are used only in other macro definitions below. MODE is the mode of the argument. !v9: All args are passed in %o0-%o5. v9: Non-float args are passed in %o0-5 and float args are passed in %f0-%f15. */#define NPARM_REGS(MODE) \ (TARGET_V9 ? (GET_MODE_CLASS (MODE) == MODE_FLOAT ? 16 : 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_V9 ? (SPARC_STACK_BIAS - 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, plus a reserved space of 8. */#define FIRST_PARM_OFFSET(FNDECL) \ (TARGET_V9 ? (SPARC_STACK_BIAS + 136) \ : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))/* When a parameter is passed in a register, stack space is still allocated for it. */#ifndef SPARCV9#define REG_PARM_STACK_SPACE(DECL) (NPARM_REGS (SImode) * UNITS_PER_WORD)#endif/* 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/* 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_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))#define BASE_OUTGOING_VALUE_REG(MODE) \ (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \ : TARGET_FRW ? 8 : 24) \ : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \ : (TARGET_FRW ? 8 : 24)))#define BASE_PASSING_ARG_REG(MODE) \ (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 : 8) \ : (8))#define BASE_INCOMING_ARG_REG(MODE) \ (TARGET_V9 ? (TARGET_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT ? 32 \ : TARGET_FRW ? 8 : 24) \ : (TARGET_FRW ? 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_FRW || (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_FRW || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)/* 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) \ gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_RETURN_VALUE_REG (TYPE_MODE (VALTYPE)))/* But the called function leaves it in the first "input" register. */#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \ gen_rtx (REG, TYPE_MODE (VALTYPE), BASE_OUTGOING_VALUE_REG (TYPE_MODE (VALTYPE)))/* 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, BASE_RETURN_VALUE_REG (MODE))/* 1 if N is a possible register number for a function value as seen by the caller. On SPARC, the first "output" reg is used for integer values, and the first floating point register is used for floating point values. */#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32)/* Define the size of space to allocate for the return value of an untyped_call. */#define APPLY_RESULT_SIZE 16/* 1 if N is a possible register number for function argument passing. On SPARC, these are the "output" registers. v9 also uses %f0-%f15. */#define FUNCTION_ARG_REGNO_P(N) \ (TARGET_V9 ? (((N) < 14 && (N) > 7) || (N) > 31 && (N) < 48) \ : ((N) < 14 && (N) > 7))/* 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 and about the args processed so far, enough to enable macros such as FUNCTION_ARG to determine where the next arg should go. On SPARC (!v9), this is a single integer, which is a number of words of arguments scanned so far (including the invisible argument, if any, which holds the structure-value-address). Thus 7 or more means all following args should go on the stack. For v9, we record how many of each type has been passed. Different types get passed differently. - Float args are passed in %f0-15, after which they go to the stack where floats and doubles are passed 8 byte aligned and long doubles are passed 16 byte aligned. - All aggregates are passed by reference. The callee copies the structure if necessary, except if stdarg/varargs and the struct matches the ellipse in which case the caller makes a copy. - Any non-float argument might be split between memory and reg %o5. ??? I don't think this can ever happen now that structs are no longer passed in regs. For v9 return values: - For all aggregates, the caller allocates space for the return value, and passes the pointer as an implicit first argument, which is allocated like all other arguments. - The unimp instruction stuff for structure returns is gone. */#ifdef SPARCV9enum sparc_arg_class { SPARC_ARG_INT = 0, SPARC_ARG_FLOAT = 1 };struct sparc_args { int arg_count[2]; /* must be int! (for __builtin_args_info) */};#define CUMULATIVE_ARGS struct sparc_args/* Return index into CUMULATIVE_ARGS. */#define GET_SPARC_ARG_CLASS(MODE) \ (GET_MODE_CLASS (MODE) == MODE_FLOAT ? SPARC_ARG_FLOAT : SPARC_ARG_INT)/* Round a register number up to a proper boundary for an arg of mode MODE. This macro is only used in this file. The "& (0x10000 - ...)" is used to round up to the next appropriate reg. */#define ROUND_REG(CUM, MODE) \ (GET_MODE_CLASS (MODE) != MODE_FLOAT \ ? (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)] \ : ((CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)] \ + GET_MODE_UNIT_SIZE (MODE) / 4 - 1) \ & (0x10000 - GET_MODE_UNIT_SIZE (MODE) / 4))#define ROUND_ADVANCE(SIZE) \ (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)#else /* ! SPARCV9 */#define CUMULATIVE_ARGS int#define ROUND_REG(CUM, MODE) (CUM)#define ROUND_ADVANCE(SIZE) \ ((SIZE + UNITS_PER_WORD - 1) / UNITS_PER_WORD)#endif /* ! SPARCV9 *//* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. For a library call, FNTYPE is 0. On SPARC, the offset always starts at 0: the first parm reg is always the same reg. */#ifdef SPARCV9extern int sparc_arg_count,sparc_n_named_args;#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ do { \ (CUM).arg_count[(int) SPARC_ARG_INT] = 0; \ (CUM).arg_count[(int) SPARC_ARG_FLOAT] = 0; \ sparc_arg_count = 0; \ sparc_n_named_args = \ ((FNTYPE) && TYPE_ARG_TYPES (FNTYPE) \ ? (list_length (TYPE_ARG_TYPES (FNTYPE)) \ + (TREE_CODE (TREE_TYPE (FNTYPE)) == RECORD_TYPE \ || TREE_CODE (TREE_TYPE (FNTYPE)) == UNION_TYPE)) \ /* Can't tell, treat 'em all as named. */ \ : 10000); \ } while (0)#else#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) ((CUM) = 0)#endif/* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. (TYPE is null for libcalls where that information may not be available.) */#ifdef SPARCV9#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ do { \ (CUM).arg_count[(int) GET_SPARC_ARG_CLASS (MODE)] = \ ROUND_REG ((CUM), (MODE)) \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -