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 + -
显示快捷键?