fr30.h
来自「gcc3.2.1源代码」· C头文件 代码 · 共 1,431 行 · 第 1/5 页
H
1,431 行
The details of how the address should be passed to `mcount' are determined by your operating system environment, not by GNU CC. 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); \}/*}}}*/ /*{{{ Implementing the VARARGS Macros. */ /* This macro offers an alternative to using `__builtin_saveregs' and defining the macro `EXPAND_BUILTIN_SAVEREGS'. Use it to store the anonymous register arguments into the stack so that all the arguments appear to have been passed consecutively on the stack. Once this is done, you can use the standard implementation of varargs that works for machines that pass all their arguments on the stack. The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure, containing the values that obtain after processing of the named arguments. The arguments MODE and TYPE describe the last named argument--its machine mode and its data type as a tree node. The macro implementation should do two things: first, push onto the stack all the argument registers *not* used for the named arguments, and second, store the size of the data thus pushed into the `int'-valued variable whose name is supplied as the argument PRETEND_ARGS_SIZE. The value that you store here will serve as additional offset for setting up the stack frame. Because you must generate code to push the anonymous arguments at compile time without knowing their data types, `SETUP_INCOMING_VARARGS' is only useful on machines that have just a single category of argument register and use it uniformly for all data types. If the argument SECOND_TIME is nonzero, it means that the arguments of the function are being analyzed for the second time. This happens for an inline function, which is not actually compiled until the end of the source file. The macro `SETUP_INCOMING_VARARGS' should not generate any instructions in this case. */#define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_ARGS_SIZE, SECOND_TIME) \ if (! SECOND_TIME) \ fr30_setup_incoming_varargs (ARGS_SO_FAR, MODE, TYPE, & PRETEND_ARGS_SIZE)/* Define this macro if the location where a function argument is passed depends on whether or not it is a named argument. This macro controls how the NAMED argument to `FUNCTION_ARG' is set for varargs and stdarg functions. With this macro defined, the NAMED argument is always true for named arguments, and false for unnamed arguments. If this is not defined, but `SETUP_INCOMING_VARARGS' is defined, then all arguments are treated as named. Otherwise, all named arguments except the last are treated as named. */#define STRICT_ARGUMENT_NAMING 0/*}}}*/ /*{{{ 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 the static chain and final target are 32 bit ailgned 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. It usually pays to define several simpler macros to serve as subroutines for this one. Otherwise it may be too complicated to understand. This macro must exist in two variants: a strict variant and a non-strict one. The strict variant is used in the reload pass. It must be defined so that any pseudo-register that has not been allocated a hard register is considered a memory reference. In contexts where some kind of register is required, a pseudo-register with no hard register must be rejected. The non-strict variant is used in other passes. It must be defined to accept all pseudo-registers in every context where some kind of register is required. Compiler source files that want to use the strict variant of this macro define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT' conditional to define the strict variant in that case and the non-strict variant otherwise. Subroutines to check for acceptable registers for various purposes (one for base registers, one for index registers, and so on) are typically among the subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these subroutine macros need have two variants; the higher levels of macros may be the same whether strict or not. Normally, constant addresses which are the sum of a `symbol_ref' and an integer are stored inside a `const' RTX to mark them as constant. Therefore, there is no need to recognize such sums specifically as legitimate addresses. Normally you would simply recognize any `const' as legitimate. Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that are not marked with `const'. It assumes that a naked `plus' indicates indexing. If so, then you *must* reject such naked constant sums as illegitimate addresses, so that none of them will be given to `PRINT_OPERAND_ADDRESS'. On some machines, whether a symbolic address is legitimate depends on the section that the address refers to. On these machines, define the macro `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and then check for it here. When you see a `const', you will have to look inside it to find the `symbol_ref' in order to determine the section. The best way to modify the name string is by adding text to the beginning, with suitable punctuation to prevent any ambiguity. Allocate the new name in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to remove and decode the added text and output the name accordingly, and define `STRIP_NAME_ENCODING' to access the original name string. You can check the information stored here into the `symbol_ref' in the definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and `PRINT_OPERAND_ADDRESS'. Used in explow.c, recog.c, reload.c. *//* 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 addresing 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; \ } \ while (0)#else#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 \ || XEXP(X,0) == arg_pointer_rtx) \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && IN_RANGE (INTVAL (XEXP (X, 1)), -(1 << 9), (1 << 9) - 4)) \ goto LABEL; \ } \ while (0)#endif/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for use as a base register. For hard registers, it should always accept those which the hardware permits and reject the others. Whether the macro accepts or rejects pseudo registers must be controlled by `REG_OK_STRICT' as described above. This usually requires two variant definitions, of which `REG_OK_STRICT' controls the one actually used. */#ifdef REG_OK_STRICT#define REG_OK_FOR_BASE_P(X) (((unsigned) REGNO (X)) <= STACK_POINTER_REGNUM)#else#define REG_OK_FOR_BASE_P(X) 1#endif/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for use as an index register. The difference between an index register and a base register is that the index register may be scaled. If an address involves the sum of two registers, neither one of them scaled, then either one may be labeled the "base" and the other the "index"; but whichever labeling is used must fit the machine's constraints of which registers may serve in each capacity. The compiler will try both labelings, looking for one that is valid, and will reload one or both registers only if neither labeling works. */#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)/* A C compound statement that attempts to replace X with a valid memory address for an operand of mode MODE. WIN will be a C statement label elsewhere in the code; the macro definition may use GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); to avoid further processing if the address has become legitimate. X will always be the result of a call to `break_out_memory_refs', and OLDX will be the operand that was given to that function to produce X. The code generated by this macro should not alter the substructure of X. If it transforms X into a more legitimate form, it should assign X (which will always be a C variable) a new value. It is not necessary for this macro to come up with a legitimate address. The compiler has standard ways of doing so in all cases. In fact, it is safe for this macro to do nothing. But often a machine-dependent strategy can generate better code. */#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)/* A C statement or compound statement with a conditional `goto LABEL;' executed if memory address X (an RTX) can have different meanings depending on the machine mode of the memory reference it is used for or if the address is valid for some modes but not others. Autoincrement and autodecrement addresses typically have mode-dependent effects because the amount of the increment or decrement is the size of the
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?