⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xtensa.h

📁 linux下的gcc编译器
💻 H
📖 第 1 页 / 共 5 页
字号:
    fprintf (STREAM, "\tmovsp\tsp, a9\n");				\									\    /* jump to the instruction following the entry */			\    fprintf (STREAM, "\taddi\ta8, a8, 3\n");				\    fprintf (STREAM, "\tjx\ta8\n");					\    fprintf (STREAM, "\t.end no-generics\n");				\  } while (0)/* Size in bytes of the trampoline, as an integer.  */#define TRAMPOLINE_SIZE 49/* Alignment required for trampolines, in bits.  */#define TRAMPOLINE_ALIGNMENT (32)/* A C statement to initialize the variable parts of a trampoline.  */#define INITIALIZE_TRAMPOLINE(ADDR, FUNC, CHAIN)			\  do {									\    rtx addr = ADDR;							\    emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 8)), FUNC); \    emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, 12)), CHAIN); \    emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__xtensa_sync_caches"), \		       0, VOIDmode, 1, addr, Pmode);			\  } while (0)/* Define the `__builtin_va_list' type for the ABI.  */#define BUILD_VA_LIST_TYPE(VALIST) \  (VALIST) = xtensa_build_va_list ()/* If defined, is a C expression that produces the machine-specific   code for a call to '__builtin_saveregs'.  This code will be moved   to the very beginning of the function, before any parameter access   are made.  The return value of this function should be an RTX that   contains the value to use as the return of '__builtin_saveregs'. */#define EXPAND_BUILTIN_SAVEREGS \  xtensa_builtin_saveregs/* Implement `va_start' for varargs and stdarg.  */#define EXPAND_BUILTIN_VA_START(valist, nextarg) \  xtensa_va_start (valist, nextarg)/* Implement `va_arg'.  */#define EXPAND_BUILTIN_VA_ARG(valist, type) \  xtensa_va_arg (valist, type)/* If defined, a C expression that produces the machine-specific code   to setup the stack so that arbitrary frames can be accessed.   On Xtensa, a stack back-trace must always begin from the stack pointer,   so that the register overflow save area can be located.  However, the   stack-walking code in GCC always begins from the hard_frame_pointer   register, not the stack pointer.  The frame pointer is usually equal   to the stack pointer, but the __builtin_return_address and   __builtin_frame_address functions will not work if count > 0 and   they are called from a routine that uses alloca.  These functions   are not guaranteed to work at all if count > 0 so maybe that is OK.   A nicer solution would be to allow the architecture-specific files to   specify whether to start from the stack pointer or frame pointer.  That   would also allow us to skip the machine->accesses_prev_frame stuff that   we currently need to ensure that there is a frame pointer when these   builtin functions are used. */#define SETUP_FRAME_ADDRESSES  xtensa_setup_frame_addresses/* A C expression whose value is RTL representing the address in a   stack frame where the pointer to the caller's frame is stored.   Assume that FRAMEADDR is an RTL expression for the address of the   stack frame itself.   For Xtensa, there is no easy way to get the frame pointer if it is   not equivalent to the stack pointer.  Moreover, the result of this   macro is used for continuing to walk back up the stack, so it must   return the stack pointer address.  Thus, there is some inconsistency   here in that __builtin_frame_address will return the frame pointer   when count == 0 and the stack pointer when count > 0. */#define DYNAMIC_CHAIN_ADDRESS(frame)					\  gen_rtx (PLUS, Pmode, frame,						\	   gen_rtx_CONST_INT (VOIDmode, -3 * UNITS_PER_WORD))/* Define this if the return address of a particular stack frame is   accessed from the frame pointer of the previous stack frame. */#define RETURN_ADDR_IN_PREVIOUS_FRAME/* A C expression whose value is RTL representing the value of the   return address for the frame COUNT steps up from the current   frame, after the prologue.  */#define RETURN_ADDR_RTX  xtensa_return_addr/* Addressing modes, and classification of registers for them.  *//* C expressions which are nonzero if register number NUM is suitable   for use as a base or index register in operand addresses.  It may   be either a suitable hard register or a pseudo register that has   been allocated such a hard register. The difference between an   index register and a base register is that the index register may   be scaled. */#define REGNO_OK_FOR_BASE_P(NUM) \  (GP_REG_P (NUM) || GP_REG_P ((unsigned) reg_renumber[NUM]))#define REGNO_OK_FOR_INDEX_P(NUM) 0/* C expressions that are nonzero if X (assumed to be a `reg' RTX) is   valid for use as a base or index 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'.  This usually requires two   variant definitions, of which `REG_OK_STRICT' controls the one   actually used. The difference between an index register and a base   register is that the index register may be scaled. */#ifdef REG_OK_STRICT#define REG_OK_FOR_INDEX_P(X) 0#define REG_OK_FOR_BASE_P(X) \  REGNO_OK_FOR_BASE_P (REGNO (X))#else /* !REG_OK_STRICT */#define REG_OK_FOR_INDEX_P(X) 0#define REG_OK_FOR_BASE_P(X) \  ((REGNO (X) >= FIRST_PSEUDO_REGISTER) || (GP_REG_P (REGNO (X))))#endif /* !REG_OK_STRICT *//* Maximum number of registers that can appear in a valid memory address.  */#define MAX_REGS_PER_ADDRESS 1/* Identify valid Xtensa addresses.  */#define GO_IF_LEGITIMATE_ADDRESS(MODE, ADDR, LABEL)			\  do {									\    rtx xinsn = (ADDR);							\									\    /* allow constant pool addresses */					\    if ((MODE) != BLKmode && GET_MODE_SIZE (MODE) >= UNITS_PER_WORD	\	&& constantpool_address_p (xinsn))				\      goto LABEL;							\									\    while (GET_CODE (xinsn) == SUBREG)					\      xinsn = SUBREG_REG (xinsn);					\									\    /* allow base registers */						\    if (GET_CODE (xinsn) == REG && REG_OK_FOR_BASE_P (xinsn))		\      goto LABEL;							\									\    /* check for "register + offset" addressing */			\    if (GET_CODE (xinsn) == PLUS)					\      {									\	rtx xplus0 = XEXP (xinsn, 0);					\	rtx xplus1 = XEXP (xinsn, 1);					\	enum rtx_code code0;						\	enum rtx_code code1;						\									\	while (GET_CODE (xplus0) == SUBREG)				\	  xplus0 = SUBREG_REG (xplus0);					\	code0 = GET_CODE (xplus0);					\									\	while (GET_CODE (xplus1) == SUBREG)				\	  xplus1 = SUBREG_REG (xplus1);					\	code1 = GET_CODE (xplus1);					\									\	/* swap operands if necessary so the register is first */	\	if (code0 != REG && code1 == REG)				\	  {								\	    xplus0 = XEXP (xinsn, 1);					\	    xplus1 = XEXP (xinsn, 0);					\	    code0 = GET_CODE (xplus0);					\	    code1 = GET_CODE (xplus1);					\	  }								\									\	if (code0 == REG && REG_OK_FOR_BASE_P (xplus0)			\	    && code1 == CONST_INT					\	    && xtensa_mem_offset (INTVAL (xplus1), (MODE)))		\	  {								\	    goto LABEL;							\	  }								\      }									\  } while (0)/* A C expression that is 1 if the RTX X is a constant which is a   valid address.  This is defined to be the same as 'CONSTANT_P (X)',   but rejecting CONST_DOUBLE.  */#define CONSTANT_ADDRESS_P(X)						\  ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\    || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH		\    || (GET_CODE (X) == CONST)))/* Nonzero if the constant value X is a legitimate general operand.   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */#define LEGITIMATE_CONSTANT_P(X) 1/* A C expression that is nonzero if X is a legitimate immediate   operand on the target machine when generating position independent   code.  */#define LEGITIMATE_PIC_OPERAND_P(X)					\  ((GET_CODE (X) != SYMBOL_REF || SYMBOL_REF_FLAG (X))			\   && GET_CODE (X) != LABEL_REF						\   && GET_CODE (X) != CONST)/* Tell GCC how to use ADDMI to generate addresses.  */#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)				\  do {									\    rtx xinsn = (X);							\    if (GET_CODE (xinsn) == PLUS)					\      { 								\	rtx plus0 = XEXP (xinsn, 0);					\	rtx plus1 = XEXP (xinsn, 1);					\									\	if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)		\	  {								\	    plus0 = XEXP (xinsn, 1);					\	    plus1 = XEXP (xinsn, 0);					\	  }								\									\	if (GET_CODE (plus0) == REG					\	    && GET_CODE (plus1) == CONST_INT				\	    && !xtensa_mem_offset (INTVAL (plus1), MODE)		\	    && !xtensa_simm8 (INTVAL (plus1))				\	    && xtensa_mem_offset (INTVAL (plus1) & 0xff, MODE)		\	    && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))		\	  {								\	    rtx temp = gen_reg_rtx (Pmode);				\	    emit_insn (gen_rtx (SET, Pmode, temp,			\				gen_rtx (PLUS, Pmode, plus0,		\					 GEN_INT (INTVAL (plus1) & ~0xff)))); \	    (X) = gen_rtx (PLUS, Pmode, temp,				\			   GEN_INT (INTVAL (plus1) & 0xff));		\	    goto WIN;							\	  }								\      }									\  } while (0)/* Treat constant-pool references as "mode dependent" since they can   only be accessed with SImode loads.  This works around a bug in the   combiner where a constant pool reference is temporarily converted   to an HImode load, which is then assumed to zero-extend based on   our definition of LOAD_EXTEND_OP.  This is wrong because the high   bits of a 16-bit value in the constant pool are now sign-extended   by default.  */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)			\  do {									\    if (constantpool_address_p (ADDR))					\      goto LABEL;							\  } while (0)/* Specify the machine mode that this machine uses   for the index in the tablejump instruction.  */#define CASE_VECTOR_MODE (SImode)/* Define this if the tablejump instruction expects the table   to contain offsets from the address of the table.   Do not define this if the table should contain absolute addresses.  *//* #define CASE_VECTOR_PC_RELATIVE *//* Define this as 1 if 'char' should by default be signed; else as 0.  */#define DEFAULT_SIGNED_CHAR 0/* Max number of bytes we can move from memory to memory   in one reasonably fast instruction.  */#define MOVE_MAX 4#define MAX_MOVE_MAX 4/* Prefer word-sized loads.  */#define SLOW_BYTE_ACCESS 1/* Xtensa doesn't have any instructions that set integer values based on the   results of comparisons, but the simplification code in the combiner also   uses this macro.  The value should be either 1 or -1 to enable some   optimizations in the combiner; I'm not sure which is better for us.   Since we've been using 1 for a while, it should probably stay that way for   compatibility.  */#define STORE_FLAG_VALUE 1/* Shift instructions ignore all but the low-order few bits.  */#define SHIFT_COUNT_TRUNCATED 1/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits   is done just by pretending it is already truncated. */#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1/* Specify the machine mode that pointers have.   After generation of rtl, the compiler makes no further distinction   between pointers and any other objects of this machine mode.  */#define Pmode SImode/* A function address in a call instruction is a word address (for   indexing purposes) so give the MEM rtx a words's mode.  */#define FUNCTION_MODE SImode/* A C expression that evaluates to true if it is ok to perform a   sibling call to DECL.  *//* TODO: fix this up to allow at least some sibcalls */#define FUNCTION_OK_FOR_SIBCALL(DECL) 0/* Xtensa constant costs.  */#define CONST_COSTS(X, CODE, OUTER_CODE)				\  case CONST_INT:							\    switch (OUTER_CODE)							\      {									\      case SET:								\	if (xtensa_simm12b (INTVAL (X))) return 4;			\	break;								\      case PLUS:							\	if (xtensa_simm8 (INTVAL (X))) return 0;			\	if (xtensa_simm8x256 (INTVAL (X))) return 0;			\	break;								\      case AND:								\	if (xtensa_mask_immediate (INTVAL (X))) return 0;		\	break;								\      case COMPARE:							\	if ((INTVAL (X) == 0) || xtensa_b4const (INTVAL (X))) return 0;	\	break;								\      case ASHIFT:							\      case ASHIFTRT:							\      case LSHIFTRT:							\      case ROTATE:							\      case ROTATERT:							\        /* no way to tell if X is the 2nd operand so be conservative */	\      default: break;							\      }									\    if (xtensa_simm12b (INTVAL (X))) return 5;				\    return 6;								\  case CONST:								\  case LABEL_REF:							\  case SYMBOL_REF:							\    return 5;								\  case CONST_DOUBLE:							\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -