📄 fr30.h
字号:
{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \}/* A C expression that returns nonzero if the compiler is allowed to try to replace register number FROM with register number TO. 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) \ ((TO) == FRAME_POINTER_REGNUM || ! frame_pointer_needed)/* 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) \ (OFFSET) = fr30_compute_frame_size (FROM, TO)/*}}}*/ /*{{{ Passing Function Arguments on the Stack. */ /* 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. Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not proper. */#define ACCUMULATE_OUTGOING_ARGS 1/* A C expression that should indicate the number of bytes of its own arguments that a function pops on returning, or 0 if the function pops no arguments and the caller must therefore pop them all after the function returns. FUNDECL is a C variable whose value is a tree node that describes the function in question. Normally it is a node of type `FUNCTION_DECL' that describes the declaration of the function. From this it is possible to obtain the DECL_ATTRIBUTES of the function. 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. On the VAX, all functions always pop their arguments, so the definition of this macro is STACK-SIZE. On the 68000, using the standard calling convention, no functions pop their arguments, so the value of the macro is always 0 in this case. But an alternative calling convention is available in which functions that take a fixed number of arguments pop them but other functions (such as `printf') pop nothing (the caller pops all). When this convention is in use, FUNTYPE is examined to determine whether a function takes a fixed number of arguments. */#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0/*}}}*/ /*{{{ Function Arguments in Registers. */ /* The number of register assigned to holding function arguments. */ #define FR30_NUM_ARG_REGS 4#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ ( (NAMED) == 0 ? NULL_RTX \ : targetm.calls.must_pass_in_stack (MODE, TYPE) ? NULL_RTX \ : (CUM) >= FR30_NUM_ARG_REGS ? NULL_RTX \ : gen_rtx_REG (MODE, CUM + FIRST_ARG_REGNUM))/* A C type for declaring a variable that is used as the first argument of `FUNCTION_ARG' and other related values. For some target machines, the type `int' suffices and can hold the number of bytes of argument so far. There is no need to record in `CUMULATIVE_ARGS' anything about the arguments that have been passed on the stack. The compiler has other variables to keep track of that. For target machines on which all arguments are passed on the stack, there is no need to store anything in `CUMULATIVE_ARGS'; however, the data structure must exist and should not be empty, so use `int'. *//* On the FR30 this value is an accumulating count of the number of argument registers that have been filled with argument values, as opposed to say, the number of bytes of argument accumulated so far. */#define CUMULATIVE_ARGS int/* A C statement (sans semicolon) for initializing the variable CUM for the state at the beginning of the argument list. The variable has type `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type of the function which will receive the args, or 0 if the args are to a compiler support library function. The value of INDIRECT is nonzero when processing an indirect call, for example a call through a function pointer. The value of INDIRECT is zero for a call to an explicitly named function, a library function call, or when `INIT_CUMULATIVE_ARGS' is used to find arguments for the function being compiled. When processing a call to a compiler support library function, LIBNAME identifies which one. It is a `symbol_ref' rtx which contains the name of the function, as a string. LIBNAME is 0 when an ordinary C function call is being processed. Thus, each time this macro is called, either LIBNAME or FNTYPE is nonzero, but never both of them at once. */#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ (CUM) = 0/* A C statement (sans semicolon) to update the summarizer variable CUM to advance past an argument in the argument list. The values MODE, TYPE and NAMED describe that argument. Once this is done, the variable CUM is suitable for analyzing the *following* argument with `FUNCTION_ARG', etc. This macro need not do anything if the argument in question was passed on the stack. The compiler knows how to track the amount of stack space used for arguments without any special help. */#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ (CUM) += (NAMED) * fr30_num_arg_regs (MODE, TYPE)/* A C expression that is nonzero if REGNO is the number of a hard register in which function arguments are sometimes passed. This does *not* include implicit arguments such as the static chain and the structure-value address. On many machines, no registers can be used for this purpose since all function arguments are pushed on the stack. */#define FUNCTION_ARG_REGNO_P(REGNO) \ ((REGNO) >= FIRST_ARG_REGNUM && ((REGNO) < FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS))/*}}}*/ /*{{{ How Scalar Function Values are Returned. */ #define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx_REG (TYPE_MODE (VALTYPE), RETURN_VALUE_REGNUM)/* A C expression to create an RTX representing the place where a library function returns a value of mode MODE. If the precise function being called is known, FUNC is a tree node (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it possible to use a different value-returning convention for specific functions when all their calls are known. Note that "library function" in this context means a compiler support routine, used to perform arithmetic, whose name is known specially by the compiler and was not mentioned in the C code being compiled. The definition of `LIBRARY_VALUE' need not be concerned aggregate data types, because none of the library functions returns such types. */#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RETURN_VALUE_REGNUM)/* A C expression that is nonzero if REGNO is the number of a hard register in which the values of called function may come back. */#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RETURN_VALUE_REGNUM)/*}}}*/ /*{{{ How Large Values are Returned. */ /* Define this macro to be 1 if all structure and union return values must be in memory. Since this results in slower code, this should be defined only if needed for compatibility with other compilers or with an ABI. If you define this macro to be 0, then the conventions used for structure and union return values are decided by the `RETURN_IN_MEMORY' macro. If not defined, this defaults to the value 1. */#define DEFAULT_PCC_STRUCT_RETURN 1/*}}}*/ /*{{{ Generating Code for Profiling. */ /* A C statement or compound statement to output to FILE some assembler code to call the profiling subroutine `mcount'. Before calling, the assembler code must load the address of a counter variable into a register where `mcount' expects to find the address. The name of this variable is `LP' followed by the number LABELNO, so you would generate the name using `LP%d' in a `fprintf'. The details of how the address should be passed to `mcount' are determined by your operating system environment, not by GCC. To figure them out, compile a small program for profiling using the system's installed C compiler and look at the assembler code that results. */#define FUNCTION_PROFILER(FILE, LABELNO) \{ \ fprintf (FILE, "\t mov rp, r1\n" ); \ fprintf (FILE, "\t ldi:32 mcount, r0\n" ); \ fprintf (FILE, "\t call @r0\n" ); \ fprintf (FILE, ".word\tLP%d\n", LABELNO); \}/*}}}*/ /*{{{ Trampolines for Nested Functions. */ /* On the FR30, the trampoline is: nop ldi:32 STATIC, r12 nop ldi:32 FUNCTION, r0 jmp @r0 The no-ops are to guarantee that the static chain and final target are 32 bit aligned within the trampoline. That allows us to initialize those locations with simple SImode stores. The alternative would be to use HImode stores. */ /* A C statement to output, on the stream FILE, assembler code for a block of data that contains the constant parts of a trampoline. This code should not include a label--the label is taken care of automatically. */#define TRAMPOLINE_TEMPLATE(FILE) \{ \ fprintf (FILE, "\tnop\n"); \ fprintf (FILE, "\tldi:32\t#0, %s\n", reg_names [STATIC_CHAIN_REGNUM]); \ fprintf (FILE, "\tnop\n"); \ fprintf (FILE, "\tldi:32\t#0, %s\n", reg_names [COMPILER_SCRATCH_REGISTER]); \ fprintf (FILE, "\tjmp\t@%s\n", reg_names [COMPILER_SCRATCH_REGISTER]); \}/* A C expression for the size in bytes of the trampoline, as an integer. */#define TRAMPOLINE_SIZE 18/* We want the trampoline to be aligned on a 32bit boundary so that we can make sure the location of the static chain & target function within the trampoline is also aligned on a 32bit boundary. */#define TRAMPOLINE_ALIGNMENT 32/* A C statement to initialize the variable parts of a trampoline. ADDR is an RTX for the address of the trampoline; FNADDR is an RTX for the address of the nested function; STATIC_CHAIN is an RTX for the static chain value that should be passed to the function when it is called. */#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \do \{ \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (ADDR, 4)), STATIC_CHAIN);\ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (ADDR, 12)), FNADDR); \} while (0);/*}}}*/ /*{{{ Addressing Modes. */ /* A C expression that is 1 if the RTX X is a constant which is a valid address. On most machines, this can be defined as `CONSTANT_P (X)', but a few machines are more restrictive in which constant addresses are supported. `CONSTANT_P' accepts integer-values expressions whose values are not explicitly known, such as `symbol_ref', `label_ref', and `high' expressions and `const' arithmetic expressions, in addition to `const_int' and `const_double' expressions. */#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)/* A number, the maximum number of registers that can appear in a valid memory address. Note that it is up to you to specify a value equal to the maximum number that `GO_IF_LEGITIMATE_ADDRESS' would ever accept. */#define MAX_REGS_PER_ADDRESS 1/* A C compound statement with a conditional `goto LABEL;' executed if X (an RTX) is a legitimate memory address on the target machine for a memory operand of mode MODE. *//* On the FR30 we only have one real addressing mode - an address in a register. There are three special cases however: * indexed addressing using small positive offsets from the stack pointer * indexed addressing using small signed offsets from the frame pointer * register plus register addressing using R13 as the base register. At the moment we only support the first two of these special cases. */ #ifdef REG_OK_STRICT#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ do \ { \ if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \ goto LABEL; \ if (GET_CODE (X) == PLUS \ && ((MODE) == SImode || (MODE) == SFmode) \ && XEXP (X, 0) == stack_pointer_rtx \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && IN_RANGE (INTVAL (XEXP (X, 1)), 0, (1 << 6) - 4)) \ goto LABEL; \ if (GET_CODE (X) == PLUS \ && ((MODE) == SImode || (MODE) == SFmode) \ && XEXP (X, 0) == frame_pointer_rtx \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && IN_RANGE (INTVAL (XEXP (X, 1)), -(1 << 9), (1 << 9) - 4)) \ goto LABEL; \ } \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -