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

📄 c4x.h

📁 gcc编译工具没有什么特别
💻 H
📖 第 1 页 / 共 5 页
字号:
#define FLOATUNSHIQF2_LIBCALL  "__ufloathiqf2"#define FIX_TRUNCQFHI2_LIBCALL "__fix_truncqfhi2"#define FIXUNS_TRUNCQFHI2_LIBCALL "__ufix_truncqfhi2"#define FLOATHIHF2_LIBCALL  "__floathihf2"#define FLOATUNSHIHF2_LIBCALL  "__ufloathihf2"#define FIX_TRUNCHFHI2_LIBCALL "__fix_trunchfhi2"#define FIXUNS_TRUNCHFHI2_LIBCALL "__ufix_trunchfhi2"#define FFS_LIBCALL	    "__ffs"#define TARGET_MEM_FUNCTIONS/* Add any extra modes needed to represent the condition code.   On the C4x, we have a "no-overflow" mode which is used when an ADD,   SUB, NEG, or MPY insn is used to set the condition code.  This is   to prevent the combiner from optimising away a following CMP of the   result with zero when a signed conditional branch or load insn   follows.   The problem is a subtle one and deals with the manner in which the   negative condition (N) flag is used on the C4x.  This flag does not   reflect the status of the actual result but of the ideal result had   no overflow occured (when considering signed operands).   For example, 0x7fffffff + 1 => 0x80000000 Z=0 V=1 N=0 C=0.  Here   the flags reflect the untruncated result, not the actual result.   While the actual result is less than zero, the N flag is not set   since the ideal result of the addition without truncation would   have been positive.      Note that the while the N flag is handled differently to most other   architectures, the use of it is self consistent and is not the   cause of the problem.   Logical operations set the N flag to the MSB of the result so if   the result is negative, N is 1.  However, integer and floating   point operations set the N flag to be the MSB of the result   exclusive ored with the overflow (V) flag.  Thus if an overflow   occurs and the result does not have the MSB set (i.e., the result   looks like a positive number), the N flag is set.  Conversely, if   an overflow occurs and the MSB of the result is set, N is set to 0.   Thus the N flag represents the sign of the result if it could have   been stored without overflow but does not represent the apparent   sign of the result.  Note that most architectures set the N flag to   be the MSB of the result.   The C4x approach to setting the N flag simplifies signed   conditional branches and loads which only have to test the state of   the N flag, whereas most architectures have to look at both the N   and V flags.  The disadvantage is that there is no flag giving the   status of the sign bit of the operation.  However, there are no   conditional load or branch instructions that make use of this   feature (e.g., BMI---branch minus) instruction.  Note that BN and   BLT are identical in the C4x.      To handle the problem where the N flag is set differently whenever   there is an overflow we use a different CC mode, CC_NOOVmode which   says that the CC reflects the comparison of the result against zero   if no overflow occured.   For example,    [(set (reg:CC_NOOV 21)         (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "")                                    (match_operand:QI 2 "src_operand" ""))                          (const_int 0)))    (set (match_operand:QI 0 "ext_reg_operand" "")         (minus:QI (match_dup 1)                   (match_dup 2)))]   Note that there is no problem for insns that don't return a result   like CMP, since the CC reflects the effect of operation.   An example of a potential problem is when GCC   converts   (LTU (MINUS (0x80000000) (0x7fffffff) (0x80000000)))   to         (LEU (MINUS (0x80000000) (0x7fffffff) (0x7fffffff)))   to         (GE  (MINUS (0x80000000) (0x7fffffff) (0x00000000)))   Now (MINUS (0x80000000) (0x7fffffff)) returns 0x00000001 but the   C4x sets the N flag since the result without overflow would have   been 0xffffffff when treating the operands as signed integers.   Thus (GE (MINUS (0x80000000) (0x7fffffff) (0x00000000))) sets the N   flag but (GE (0x00000001)) does not set the N flag.   The upshot is that we can not use signed branch and conditional   load instructions after an add, subtract, neg, abs or multiply.   We must emit a compare insn to check the result against 0.  */#define EXTRA_CC_MODES CC_NOOVmode/* Define the names for the modes specified above.  */#define EXTRA_CC_NAMES "CC_NOOV"/* 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)extern struct rtx_def *c4x_gen_compare_reg ();/* 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 MULTIPACK_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.  */extern int c4x_check_legit_addr ();#ifndef REG_OK_STRICT/* Nonzero if X is a hard or pseudo reg that can be used as an base.  */#define REG_OK_FOR_BASE_P(X) IS_ADDR_OR_PSEUDO_REG(REGNO(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(REGNO(X))#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\{									\  if (c4x_check_legit_addr (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_check_legit_addr (MODE, X, 1))				\    goto ADDR;								\}#endifextern struct rtx_def *c4x_legitimize_address ();#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \{									\  rtx new;								\  new = c4x_legitimize_address (X, MODE);				\  if (new != NULL_RTX)							\  {									\    (X) = new;								\    goto WIN;								\  }									\}extern struct rtx_def *c4x_legitimize_reload_address ();#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)     \{									\  rtx new;								\  new = c4x_legitimize_reload_address (X, MODE, insn);			\  if (new != NULL_RTX)							\  {									\    (X) = new;								\   /* We do not have to call push_reload because we do not require      \      any more reloads.  */						\    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 && c4x_I_constant (X))		\  || (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))/* Define this macro if references to a symbol must be treated   differently depending on something about the variable or   function named by the symbol (such as what section it is in).   The macro definition, if any, is executed immediately after the   rtl for DECL or other node is created.   The value of the rtl will be a `mem' whose address is a   `symbol_ref'.   The usual thing for this macro to do is to a flag in the   `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified   name string in the `symbol_ref' (if one bit is not enough   information).   On the C4x we use this to indicate if a symbol is in text or   data space.  */extern void c4x_encode_section_info ();#define ENCODE_SECTION_INFO(DECL) c4x_encode_section_info (DECL);/* Descripting Relative Cost of Operations  *//* Provide the costs of a rtl expression.  This is in the body of a   switch on CODE.    Note that we return, rather than break so that rtx_cost doesn't   include CONST_COSTS otherwise expand_mult will think that it is   cheaper to synthesise a multiply rather than to use a multiply   instruction.  I think this is because the algorithm synth_mult   doesn't take into account the loading of the operands, whereas the   calculation of mult_cost does. */#define RTX_COSTS(RTX, CODE, OUTER_CODE)				\    case PLUS:								\    case MINUS:								\    case AND:								\    case IOR:								\    case XOR:								\    case ASHIFT:							\    case ASHIFTRT:							\    case LSHIFTRT:							\    return COSTS_N_INSNS (1);						\    case MULT:								\    return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \			  || TARGET_MPYI ? 1 : 14);			\    case DIV:								\    case UDIV:								\    case MOD: 								\    case UMOD:								\    return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT	\			  ? 15 : 50);/* Compute the cost of computing a constant rtl expression RTX   whose rtx-code is CODE.  The body of this macro is a portion   of a switch statement.  If the code is computed here,   return it with a return statement.  Otherwise, break from the switch.   An insn is assumed to cost 4 units.   COSTS_N_INSNS (N) is defined as (N) * 4 - 2.   Some small integers are effectively free for the C40.  We should   also consider if we are using the small memory model.  With   the big memory model we require an extra insn for a constant   loaded from memory.     This is used by expand_binop to decide whether to force a constant   into a register.  If the cost is greater than 2 and the constant   is used within a short loop, it gets forced into a register.     Ideally, there should be some weighting as to how mnay times it is used   within the loop.  */#define SHIFT_CODE_P(C) ((C) == ASHIFT || (C) == ASHIFTRT || (C) == LSHIFTRT)#define LOGICAL_CODE_P(C) ((C) == NOT || (C) == AND \                           || (C) == IOR || (C) == XOR)#define NON_COMMUTATIVE_CODE_P ((C) == MINUS || (C) == COMPARE)#define CONST_COSTS(RTX,CODE,OUTER_CODE)			\	case CONST_INT:						\           if (c4x_J_constant (RTX))				\	     return 0;						\	   if (! TARGET_C3X					\	       && OUTER_CODE == AND				\               && GET_CODE (RTX) == CONST_INT			\	       && (INTVAL (RTX) == 255 || INTVAL (RTX) == 65535))	\	     return 0;						\	   if (! TARGET_C3X					\	       && (OUTER_CODE == ASHIFTRT || OUTER_CODE == LSHIFTRT)	\               && GET_CODE (RTX) == CONST_INT			\	       && (INTVAL (RTX) == 16 || INTVAL (RTX) == 24))	\	     return 0;						\           if (TARGET_C3X && SHIFT_CODE_P (OUTER_CODE))		\	     return 3;						\           if (LOGICAL_CODE_P (OUTER_CODE) 			\               ? c4x_L_constant (RTX) : c4x_I_constant (RTX))	\	     return 2;						\	case CONST:						\	case LABEL_REF:						\	case SYMBOL_REF:					\	   return 4;						\	case CONST_DOUBLE:					\	   if (c4x_H_constant (RTX))				\	     return 2;						\           if (GET_MODE (RTX) == QFmode)			\	     return 4;						\           else							\	     return 8;/* Compute the cost of an address.  This is meant to approximate the size   and/or execution delay of an insn using that address.  If the cost is   approximated by the RTL complexity, including CONST_COSTS above, as   is usually the case for CISC machines, this macro should not be defined.   For aggressively RISCy machines, only one insn format is allowed, so   this macro should be a constant.  The value of this macro only matters   for valid addresses.  We handle the most common address without    a call to c4x_address_cost.  */extern int c4x_address_cost ()

⌨️ 快捷键说明

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