📄 pa.h
字号:
&& (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \ : 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. */#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)/* Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE. If it can be done directly, NO_REGS is returned. */#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ secondary_reload_class (CLASS, MODE, IN)/* On the PA 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. */#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ gen_rtx (MEM, MODE, gen_rtx (PLUS, Pmode, stack_pointer_rtx, GEN_INT (-16)))/* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. */#define CLASS_MAX_NREGS(CLASS, MODE) \ (!TARGET_SNAKE && (CLASS) == FP_REGS ? 1 : \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))/* 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 *//* Believe it or not. */#define ARGS_GROW_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 8/* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. On the HP-PA, don't define this because there are no push insns. *//* #define PUSH_ROUNDING(BYTES) *//* Offset of first parameter from the argument pointer register value. This value will be negated because the arguments grow down. Also note that on STACK_GROWS_UPWARD machines (such as this one) this is the distance from the frame pointer to the end of the first argument, not it's beginning. To get the real offset of the first argument, the size of the argument must be added. ??? Have to check on this.*/#define FIRST_PARM_OFFSET(FNDECL) -32/* Absolute value of offset from top-of-stack address to location to store the function parameter if it can't go in a register. Addresses for following parameters are computed relative to this one. */#define FIRST_PARM_CALLER_OFFSET(FNDECL) -32/* When a parameter is passed in a register, stack space is still allocated for it. */#define REG_PARM_STACK_SPACE(DECL) 16/* Define this if the above stack space is to be considered part of the space allocated by the caller. */#define OUTGOING_REG_PARM_STACK_SPACE/* 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/* The weird HPPA calling conventions require a minimum of 48 bytes on the stack: 16 bytes for register saves, and 32 bytes for magic. This is the difference between the logical top of stack and the actual sp. */#define STACK_POINTER_OFFSET -32#define STACK_DYNAMIC_OFFSET(FNDECL) \ ((STACK_POINTER_OFFSET) - current_function_outgoing_args_size)/* Value is 1 if returning from a function call automatically pops the arguments described by the number-of-args field in the 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. */#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0/* 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 the HP-PA the value is found in register(s) 28(-29), unless the mode is SF or DF. Then the value is returned in fr4 (32, ) */#define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx (REG, TYPE_MODE (VALTYPE), ((! TARGET_SOFT_FLOAT \ && (TYPE_MODE (VALTYPE) == SFmode || \ TYPE_MODE (VALTYPE) == DFmode)) ? \ 32 : 28))/* 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, \ (! TARGET_SOFT_FLOAT \ && ((MODE) == SFmode || (MODE) == DFmode) ? 32 : 28))/* 1 if N is a possible register number for a function value as seen by the caller. */#define FUNCTION_VALUE_REGNO_P(N) \ ((N) == 28 || (! TARGET_SOFT_FLOAT && (N) == 32))/* 1 if N is a possible register number for function argument passing. */#define FUNCTION_ARG_REGNO_P(N) \ (((N) >= 23 && (N) <= 26) || (! TARGET_SOFT_FLOAT && (N) >= 32 && (N) <= 39))/* 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 the HP-PA, 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 4 or more means all following args should go on the stack. */struct hppa_args {int words, nargs_prototype; };#define CUMULATIVE_ARGS struct hppa_args/* 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. */#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ (CUM).words = 0, \ (CUM).nargs_prototype = (FNTYPE && TYPE_ARG_TYPES (FNTYPE) \ ? (list_length (TYPE_ARG_TYPES (FNTYPE)) - 1 \ + (TYPE_MODE (TREE_TYPE (FNTYPE)) == BLKmode \ || RETURN_IN_MEMORY (TREE_TYPE (FNTYPE)))) \ : 0)/* Similar, but when scanning the definition of a procedure. We always set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,IGNORE) \ (CUM).words = 0, \ (CUM).nargs_prototype = 1000/* Figure out the size in words of the function argument. */#define FUNCTION_ARG_SIZE(MODE, TYPE) \ ((((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))+3)/4)/* 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.) */#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \{ (CUM).nargs_prototype--; \ ((((CUM).words & 01) && (TYPE) != 0 \ && FUNCTION_ARG_SIZE(MODE, TYPE) > 1) \ && (CUM).words++), \ (CUM).words += FUNCTION_ARG_SIZE(MODE, TYPE); \}/* Determine where to put an argument to a function. Value is zero to push the argument on the stack, or a hard register in which to store the argument. MODE is the argument's machine mode. TYPE is the data type of the argument (as a tree). This is null for libcalls where that information may not be available. CUM is a variable of type CUMULATIVE_ARGS which gives info about the preceding args and about the function being called. NAMED is nonzero if this argument is a named parameter (otherwise it is an extra parameter matching an ellipsis). On the HP-PA the first four words of args are normally in registers and the rest are pushed. But any arg that won't entirely fit in regs is pushed. Arguments passed in registers are either 1 or 2 words long. The caller must make a distinction between calls to explicitly named functions and calls through pointers to functions -- the conventions are different! Calls through pointers to functions only use general registers for the first four argument words. Of course all this is different for the portable runtime model HP wants everyone to use for ELF. Ugh. Here's a quick description of how it's supposed to work. 1) callee side remains unchanged. It expects integer args to be in the integer registers, float args in the float registers and unnamed args in integer registers. 2) caller side now depends on if the function being called has a prototype in scope (rather than if it's being called indirectly). 2a) If there is a prototype in scope, then arguments are passed according to their type (ints in integer registers, floats in float registers, unnamed args in integer registers. 2b) If there is no prototype in scope, then floating point arguments are passed in both integer and float registers. egad. FYI: The portable parameter passing conventions are almost exactly like the standard parameter passing conventions on the RS6000. That's why you'll see lots of similar code in rs6000.h. */#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding ((MODE), (TYPE))/* Do not expect to understand this without reading it several times. I'm tempted to try and simply it, but I worry about breaking something. */#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ (4 >= ((CUM).words + FUNCTION_ARG_SIZE ((MODE), (TYPE))) \ ? (!TARGET_PORTABLE_RUNTIME || (TYPE) == 0 \ || !FLOAT_MODE_P (MODE) || TARGET_SOFT_FLOAT \ || (CUM).nargs_prototype > 0) \ ? gen_rtx (REG, (MODE), \ (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \ ? (((!current_call_is_indirect \ || TARGET_PORTABLE_RUNTIME) \ && (MODE) == DFmode \ && ! TARGET_SOFT_FLOAT) \ ? ((CUM).words ? 38 : 34) \ : ((CUM).words ? 23 : 25)) \ : (((!current_call_is_indirect \ || TARGET_PORTABLE_RUNTIME) \ && (MODE) == SFmode \ && ! TARGET_SOFT_FLOAT) \ ? (32 + 2 * (CUM).words) \ : (27 - (CUM).words - FUNCTION_ARG_SIZE ((MODE), \ (TYPE))))))\ /* We are calling a non-prototyped function with floating point \ arguments using the portable conventions. */ \ : gen_rtx (EXPR_LIST, VOIDmode, \ gen_rtx (REG, (MODE), \ (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \ ? ((CUM).words ? 38 : 34) \ : (32 + 2 * (CUM).words))), \ gen_rtx (REG, (MODE), \ (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \ ? ((CUM).words ? 23 : 25) \ : (27 - (CUM).words - FUNCTION_ARG_SIZE ((MODE),\ (TYPE)))))) \ /* Pass this parameter in the stack. */ \ : 0)/* For an arg passed partly in registers and partly in memory, this is the number of registers used. For args passed entirely in registers or entirely in memory, zero. */#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0/* If defined, a C expression that gives the alignment boundary, in bits, of an argument with the specified mode and type. If it is not defined, `PARM_BOUNDARY' is used for all arguments. */#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ (((TYPE) != 0) \ ? (((int_size_in_bytes (TYPE)) + 3) / 4) * BITS_PER_WORD \ : ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \ ? PARM_BOUNDARY \ : GET_MODE_ALIGNMENT(MODE)))/* Arguments larger than eight bytes are passed by invisible reference */#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ ((TYPE) && int_size_in_bytes (TYPE) > 8) #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ ((TYPE) && int_size_in_bytes (TYPE) > 8)extern struct rtx_def *hppa_compare_op0, *hppa_compare_op1;extern enum cmp_type hppa_branch_type;/* Output the label for a function definition. */#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED#define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \ do { fprintf (FILE, ",ARGW%d=FR", (ARG0)); \ fprintf (FILE, ",ARGW%d=FU", (ARG1));} while (0)#else#define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \ do { fprintf (FILE, ",ARGW%d=FU", (ARG0)); \ fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)#endif#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ do { tree fntype = TREE_TYPE (TREE_TYPE (DECL)); \ tree tree_type = TREE_TYPE (DECL); \ tree parm; \ int i; \ if (TREE_PUBLIC (DECL) || TARGET_GAS) \ { extern int current_function_varargs; \ if (TREE_PUBLIC (DECL)) \ { \ fputs ("\t.EXPORT ", FILE); \ assemble_name (FILE, NAME); \ fputs (",ENTRY,PRIV_LEV=3", FILE); \ } \ else \ { \ fputs ("\t.PARAM ", FILE); \ assemble_name (FILE, NAME); \ } \ if (TARGET_PORTABLE_RUNTIME) \ { \ fputs (",ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,", FILE); \ fputs ("RTNVAL=NO\n", FILE); \ break; \ } \ for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \ parm = TREE_CHAIN (parm)) \ { \ if (TYPE_MODE (DECL_ARG_TYPE (parm)) == SFmode \ && ! TARGET_SOFT_FLOAT) \ fprintf (FILE, ",ARGW%d=FR", i++); \ else if (TYPE_MODE (DECL_ARG_TYPE (parm)) == DFmode \ && ! TARGET_SOFT_FLOAT) \ { \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -