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

📄 c4x.h

📁 linux下编程用 编译软件
💻 H
📖 第 1 页 / 共 4 页
字号:
   with "asm" statements.  */#define C4X_ARG0 -2#define C4X_LOC0 1/* Basic Stack Layout.  */     /* The stack grows upward, stack frame grows upward, and args grow   downward.  */#define STARTING_FRAME_OFFSET		C4X_LOC0#define FIRST_PARM_OFFSET(FNDECL)      (C4X_ARG0 + 1)#define ARGS_GROW_DOWNWARD#define STACK_POINTER_OFFSET 1/* Define this if pushing a word on the stack   makes the stack pointer a smaller address.  *//* #define STACK_GROWS_DOWNWARD.  *//* Like the dsp16xx, i370, i960, and we32k ports.  *//* Define this to nonzero 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 0/* Registers That Address the Stack Frame.  */#define STACK_POINTER_REGNUM	SP_REGNO	/* SP.  */#define FRAME_POINTER_REGNUM	AR3_REGNO	/* AR3.  */#define ARG_POINTER_REGNUM	AR3_REGNO	/* AR3.  */#define STATIC_CHAIN_REGNUM	AR0_REGNO	/* AR0.  *//* Eliminating Frame Pointer and Arg Pointer.  */#define FRAME_POINTER_REQUIRED	0#define INITIAL_FRAME_POINTER_OFFSET(DEPTH)			\{								\ int regno;							\ int offset = 0;						\  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)	\    if (regs_ever_live[regno] && ! call_used_regs[regno])	\      offset += TARGET_PRESERVE_FLOAT				\		&& IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1;	\  (DEPTH) = -(offset + get_frame_size ());			\}/* This is a hack...  We need to specify a register.  */#define	ELIMINABLE_REGS 					\  {{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }}#define	CAN_ELIMINATE(FROM, TO)					\  (! (((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \  || ((FROM) == FRAME_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM)))#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)	 	\{								\ int regno;							\ int offset = 0;						\  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)	\    if (regs_ever_live[regno] && ! call_used_regs[regno])	\      offset += TARGET_PRESERVE_FLOAT				\		&& IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1;	\  (OFFSET) = -(offset + get_frame_size ());			\}/* Passing Function Arguments on the Stack.  */#define	PUSH_ARGS 1#define PUSH_ROUNDING(BYTES) (BYTES)#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0/* The following structure is used by calls.c, function.c, c4x.c.  */typedef struct c4x_args{  int floats;  int ints;  int maxfloats;  int maxints;  int init;  int var;  int prototype;  int args;}CUMULATIVE_ARGS;#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \  (c4x_init_cumulative_args (&CUM, FNTYPE, LIBNAME))#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)	\  (c4x_function_arg_advance (&CUM, MODE, TYPE, NAMED))#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \  (c4x_function_arg(&CUM, MODE, TYPE, NAMED))/* Define the profitability of saving registers around calls.   We disable caller save to avoid a bug in flow.c (this also affects   other targets such as m68k).  Since we must use stf/sti,   the profitability is marginal anyway.  */#define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0/* 1 if N is a possible register number for function argument passing.  */#define FUNCTION_ARG_REGNO_P(REGNO) \	(  (   ((REGNO) == AR2_REGNO)	/* AR2.  */	\	    || ((REGNO) == R2_REGNO)	/* R2.  */	\	    || ((REGNO) == R3_REGNO)	/* R3.  */	\	    || ((REGNO) == RC_REGNO)	/* RC.  */	\	    || ((REGNO) == RS_REGNO)	/* RS.  */	\	    || ((REGNO) == RE_REGNO))	/* RE.  */	\	 ? 1						\	 : 0)/* How Scalar Function Values Are Returned.  */#define FUNCTION_VALUE(VALTYPE, FUNC) \	gen_rtx_REG (TYPE_MODE(VALTYPE), R0_REGNO)	/* Return in R0.  */#define LIBCALL_VALUE(MODE) \	gen_rtx_REG (MODE, R0_REGNO)	/* Return in R0.  */#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO)/* How Large Values Are Returned.  */#define DEFAULT_PCC_STRUCT_RETURN	0/* Generating Code for Profiling.  *//* Note that the generated assembly uses the ^ operator to load the 16   MSBs of the address.  This is not supported by the TI assembler.    The FUNCTION profiler needs a function mcount which gets passed   a pointer to the LABELNO.  */#define FUNCTION_PROFILER(FILE, LABELNO) 			\     if (! TARGET_C3X)						\     {								\	fprintf (FILE, "\tpush\tar2\n");			\	fprintf (FILE, "\tldhi\t^LP%d,ar2\n", (LABELNO));	\	fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO));		\	fprintf (FILE, "\tcall\tmcount\n");			\	fprintf (FILE, "\tpop\tar2\n");				\     }								\     else							\     {								\	fprintf (FILE, "\tpush\tar2\n");			\	fprintf (FILE, "\tldiu\t^LP%d,ar2\n", (LABELNO));	\	fprintf (FILE, "\tlsh\t16,ar2\n");			\	fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO));		\	fprintf (FILE, "\tcall\tmcount\n");			\	fprintf (FILE, "\tpop\tar2\n");				\     }/* CC_NOOVmode should be used when the first operand is a PLUS, MINUS, NEG   or MULT.   CCmode should be used when no special processing is needed.  */#define SELECT_CC_MODE(OP,X,Y) \  ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS		\    || GET_CODE (X) == NEG || GET_CODE (X) == MULT		\    || GET_MODE (X) == ABS					\    || GET_CODE (Y) == PLUS || GET_CODE (Y) == MINUS		\    || GET_CODE (Y) == NEG || GET_CODE (Y) == MULT		\    || GET_MODE (Y) == ABS)					\    ? CC_NOOVmode : CCmode)/* Addressing Modes.  */#define HAVE_POST_INCREMENT 1#define HAVE_PRE_INCREMENT 1#define HAVE_POST_DECREMENT 1#define HAVE_PRE_DECREMENT 1#define HAVE_PRE_MODIFY_REG 1#define HAVE_POST_MODIFY_REG 1#define HAVE_PRE_MODIFY_DISP 1#define HAVE_POST_MODIFY_DISP 1/* The number of insns that can be packed into a single opcode.  */#define PACK_INSNS 2/* Recognize any constant value that is a valid address.    We could allow arbitrary constant addresses in the large memory   model but for the small memory model we can only accept addresses   within the data page.  I suppose we could also allow   CONST PLUS SYMBOL_REF.  */#define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == SYMBOL_REF)/* Maximum number of registers that can appear in a valid memory   address.  */#define MAX_REGS_PER_ADDRESS	2/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx   and check its validity for a certain class.   We have two alternate definitions for each of them.   The usual definition accepts all pseudo regs; the other rejects   them unless they have been allocated suitable hard regs.   The symbol REG_OK_STRICT causes the latter definition to be used.   Most source files want to accept pseudo regs in the hope that   they will get allocated to the class that the insn wants them to be in.   Source files for reload pass need to be strict.   After reload, it makes no difference, since pseudo regs have   been eliminated by then.  */#ifndef REG_OK_STRICT/* Nonzero if X is a hard or pseudo reg that can be used as a base.  */#define REG_OK_FOR_BASE_P(X) IS_ADDR_OR_PSEUDO_REG(X)/* Nonzero if X is a hard or pseudo reg that can be used as an index.  */#define REG_OK_FOR_INDEX_P(X) IS_INDEX_OR_PSEUDO_REG(X)#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\{									\  if (c4x_legitimate_address_p (MODE, X, 0))				\    goto ADDR;								\}#else/* Nonzero if X is a hard reg that can be used as an index.  */#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))/* Nonzero if X is a hard reg that can be used as a base reg.  */#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\{									\  if (c4x_legitimate_address_p (MODE, X, 1))				\    goto ADDR;								\}#endif#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \{									\  rtx new;								\									\  new = c4x_legitimize_address (X, MODE);				\  if (new != NULL_RTX)							\  {									\    (X) = new;								\    goto WIN;								\  }									\}#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \{									\  if (MODE != HImode							\      && MODE != HFmode							\      && GET_MODE (X) != HImode						\      && GET_MODE (X) != HFmode						\      && (GET_CODE (X) == CONST						\          || GET_CODE (X) == SYMBOL_REF					\          || GET_CODE (X) == LABEL_REF))				\    {									\      if (! TARGET_SMALL)						\	{								\          int i;							\      	  (X) = gen_rtx_LO_SUM (GET_MODE (X),				\			      gen_rtx_HIGH (GET_MODE (X), X), X);	\          i = push_reload (XEXP (X, 0), NULL_RTX,			\			   &XEXP (X, 0), NULL,				\		           DP_REG, GET_MODE (X), VOIDmode, 0, 0,	\		           OPNUM, TYPE);				\          /* The only valid reg is DP. This is a fixed reg and will	\	     normally not be used so force it.  */			\          rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); 		\          rld[i].nocombine = 1; 					\        }								\      else								\        {								\          /* make_memloc in reload will substitute invalid memory       \             references.  We need to fix them up.  */                   \          (X) = gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, DP_REGNO), (X)); \        }								\      goto WIN;								\   }									\  else if (MODE != HImode						\           && MODE != HFmode						\           && GET_MODE (X) != HImode					\           && GET_MODE (X) != HFmode					\           && GET_CODE (X) == LO_SUM					\           && GET_CODE (XEXP (X,0)) == HIGH				\           && (GET_CODE (XEXP (XEXP (X,0),0)) == CONST			\               || GET_CODE (XEXP (XEXP (X,0),0)) == SYMBOL_REF		\               || GET_CODE (XEXP (XEXP (X,0),0)) == LABEL_REF))		\    {									\      if (! TARGET_SMALL)						\	{								\          int i = push_reload (XEXP (X, 0), NULL_RTX,			\			       &XEXP (X, 0), NULL,			\		               DP_REG, GET_MODE (X), VOIDmode, 0, 0,	\		               OPNUM, TYPE);				\          /* The only valid reg is DP. This is a fixed reg and will	\	     normally not be used so force it.  */			\          rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); 		\          rld[i].nocombine = 1; 					\        }								\      goto WIN;								\   }									\}/* No mode-dependent addresses on the C4x are autoincrements.  */#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)	\  if (GET_CODE (ADDR) == PRE_DEC	\      || GET_CODE (ADDR) == POST_DEC	\      || GET_CODE (ADDR) == PRE_INC	\      || GET_CODE (ADDR) == POST_INC	\      || GET_CODE (ADDR) == POST_MODIFY	\      || GET_CODE (ADDR) == PRE_MODIFY)	\    goto LABEL/* Nonzero if the constant value X is a legitimate general operand.   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.    The C4x can only load 16-bit immediate values, so we only allow a   restricted subset of CONST_INT and CONST_DOUBLE.  Disallow   LABEL_REF and SYMBOL_REF (except on the C40 with the big memory   model) so that the symbols will be forced into the constant pool.   On second thoughts, let's do this with the move expanders since   the alias analysis has trouble if we force constant addresses   into memory.*/#define LEGITIMATE_CONSTANT_P(X)				\  ((GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X))		\  || (GET_CODE (X) == CONST_INT)				\  || (GET_CODE (X) == SYMBOL_REF)				\  || (GET_CODE (X) == LABEL_REF)				\  || (GET_CODE (X) == CONST)					\  || (GET_CODE (X) == HIGH && ! TARGET_C3X)			\  || (GET_CODE (X) == LO_SUM && ! TARGET_C3X))#define LEGITIMATE_DISPLACEMENT_P(X) IS_DISP8_CONST (INTVAL (X))/* Describing Relative Cost of Operations.  */#define	CANONICALIZE_COMPARISON(CODE, OP0, OP1)		\if (REG_P (OP1) && ! REG_P (OP0))			\{							\  rtx tmp = OP0; OP0 = OP1 ; OP1 = tmp;			\  CODE = swap_condition (CODE);				\}#define EXT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, EXT_REGS))#define ADDR_CLASS_P(CLASS) (reg_class_subset_p (CLASS, ADDR_REGS))#define INDEX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, INDEX_REGS))#define EXPENSIVE_CLASS_P(CLASS) (ADDR_CLASS_P(CLASS) \                          || INDEX_CLASS_P(CLASS) || (CLASS) == SP_REG)/* Compute extra cost of moving data between one register class   and another.  */#define REGISTER_MOVE_COST(MODE, FROM, TO)	2/* Memory move cost is same as fast register move.  Maybe this should   be bumped up?.  */#define MEMORY_MOVE_COST(M,C,I)		4/* Branches are kind of expensive (even with delayed branching) so   make their cost higher.  */#define BRANCH_COST			8#define	WORD_REGISTER_OPERATIONS/* Dividing the Output into Sections.  */#define TEXT_SECTION_ASM_OP "\t.text"#define DATA_SECTION_ASM_OP "\t.data"#define READONLY_DATA_SECTION_ASM_OP "\t.sect\t\".const\""/* Do not use .init section so __main will be called on startup. This will   call __do_global_ctors and prepare for __do_global_dtors on exit.  */#if 0#define INIT_SECTION_ASM_OP  "\t.sect\t\".init\""#endif#define FINI_SECTION_ASM_OP  "\t.sect\t\".fini\""#undef EXTRA_SECTIONS#define EXTRA_SECTIONS in_init, in_fini#undef EXTRA_SECTION_FUNCTIONS#define EXTRA_SECTION_FUNCTIONS					\  INIT_SECTION_FUNCTION						\  FINI_SECTION_FUNCTION#define INIT_SECTION_FUNCTION					\extern void init_section (void);				\void								\init_section (void)						\{								\  if (in_section != in_init)					\    {								\      fprintf (asm_out_file, ";\t.init\n");			\      in_section = in_init;					\    }								\}#define FINI_SECTION_FUNCTION					\void								\fini_section ()							\{								\  if (in_section != in_fini)					\

⌨️ 快捷键说明

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