📄 sparc.c
字号:
if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG) { if (mode != VOIDmode && mode != GET_MODE (op)) return 0; if (mode == VOIDmode && GET_MODE (op) != CCmode && GET_MODE (op) != CCXmode) return 0; return 1; } return fcc_reg_operand (op, mode);}/* Nonzero if OP can appear as the dest of a RESTORE insn. */intrestore_operand (op, mode) rtx op; enum machine_mode mode;{ return (GET_CODE (op) == REG && GET_MODE (op) == mode && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));}/* Call insn on SPARC can take a PC-relative constant address, or any regular memory address. */intcall_operand (op, mode) rtx op; enum machine_mode mode;{ if (GET_CODE (op) != MEM) abort (); op = XEXP (op, 0); return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));}intcall_operand_address (op, mode) rtx op; enum machine_mode mode;{ return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));}/* Returns 1 if OP is either a symbol reference or a sum of a symbol reference and a constant. */intsymbolic_operand (op, mode) register rtx op; enum machine_mode mode;{ switch (GET_CODE (op)) { case SYMBOL_REF: case LABEL_REF: return 1; case CONST: op = XEXP (op, 0); return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF || GET_CODE (XEXP (op, 0)) == LABEL_REF) && GET_CODE (XEXP (op, 1)) == CONST_INT); /* ??? This clause seems to be irrelevant. */ case CONST_DOUBLE: return GET_MODE (op) == mode; default: return 0; }}/* Return truth value of statement that OP is a symbolic memory operand of mode MODE. */intsymbolic_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); if (GET_CODE (op) != MEM) return 0; op = XEXP (op, 0); return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);}/* Return truth value of statement that OP is a LABEL_REF of mode MODE. */intlabel_ref_operand (op, mode) rtx op; enum machine_mode mode;{ if (GET_CODE (op) != LABEL_REF) return 0; if (GET_MODE (op) != mode) return 0; return 1;}/* Return 1 if the operand is an argument used in generating pic references in either the medium/low or medium/anywhere code models of sparc64. */intsp64_medium_pic_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ /* Check for (const (minus (symbol_ref:GOT) (const (minus (label) (pc))))). */ if (GET_CODE (op) != CONST) return 0; op = XEXP (op, 0); if (GET_CODE (op) != MINUS) return 0; if (GET_CODE (XEXP (op, 0)) != SYMBOL_REF) return 0; /* ??? Ensure symbol is GOT. */ if (GET_CODE (XEXP (op, 1)) != CONST) return 0; if (GET_CODE (XEXP (XEXP (op, 1), 0)) != MINUS) return 0; return 1;}/* Return 1 if the operand is a data segment reference. This includes the readonly data segment, or in other words anything but the text segment. This is needed in the medium/anywhere code model on v9. These values are accessed with EMBMEDANY_BASE_REG. */intdata_segment_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ switch (GET_CODE (op)) { case SYMBOL_REF : return ! SYMBOL_REF_FLAG (op); case PLUS : /* Assume canonical format of symbol + constant. Fall through. */ case CONST : return data_segment_operand (XEXP (op, 0)); default : return 0; }}/* Return 1 if the operand is a text segment reference. This is needed in the medium/anywhere code model on v9. */inttext_segment_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ switch (GET_CODE (op)) { case LABEL_REF : return 1; case SYMBOL_REF : return SYMBOL_REF_FLAG (op); case PLUS : /* Assume canonical format of symbol + constant. Fall through. */ case CONST : return text_segment_operand (XEXP (op, 0)); default : return 0; }}/* Return 1 if the operand is either a register or a memory operand that is not symbolic. */intreg_or_nonsymb_mem_operand (op, mode) register rtx op; enum machine_mode mode;{ if (register_operand (op, mode)) return 1; if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) return 1; return 0;}intsplittable_symbolic_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) != MEM) return 0; if (! symbolic_operand (XEXP (op, 0), Pmode)) return 0; return 1;}intsplittable_immediate_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) != MEM) return 0; if (! immediate_operand (XEXP (op, 0), Pmode)) return 0; return 1;}/* Return truth value of whether OP is EQ or NE. */inteq_or_neq (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == EQ || GET_CODE (op) == NE);}/* Return 1 if this is a comparison operator, but not an EQ, NE, GEU, or LTU for non-floating-point. We handle those specially. */intnormal_comp_operator (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ enum rtx_code code = GET_CODE (op); if (GET_RTX_CLASS (code) != '<') return 0; if (GET_MODE (XEXP (op, 0)) == CCFPmode || GET_MODE (XEXP (op, 0)) == CCFPEmode) return 1; return (code != NE && code != EQ && code != GEU && code != LTU);}/* Return 1 if this is a comparison operator. This allows the use of MATCH_OPERATOR to recognize all the branch insns. */intnoov_compare_op (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ enum rtx_code code = GET_CODE (op); if (GET_RTX_CLASS (code) != '<') return 0; if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode) /* These are the only branches which work with CC_NOOVmode. */ return (code == EQ || code == NE || code == GE || code == LT); return 1;}/* Nonzero if OP is a comparison operator suitable for use in v9 conditional move or branch on register contents instructions. */intv9_regcmp_op (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ enum rtx_code code = GET_CODE (op); if (GET_RTX_CLASS (code) != '<') return 0; return v9_regcmp_p (code);}/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */intextend_op (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;}/* Return nonzero if OP is an operator of mode MODE which can set the condition codes explicitly. We do not include PLUS and MINUS because these require CC_NOOVmode, which we handle explicitly. */intcc_arithop (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR) return 1; return 0;}/* Return nonzero if OP is an operator of mode MODE which can bitwise complement its second operand and set the condition codes explicitly. */intcc_arithopn (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ /* XOR is not here because combine canonicalizes (xor (not ...) ...) and (xor ... (not ...)) to (not (xor ...)). */ return (GET_CODE (op) == AND || GET_CODE (op) == IOR);}/* Return true if OP is a register, or is a CONST_INT that can fit in a signed 13 bit immediate field. This is an acceptable SImode operand for most 3 address instructions. */intarith_operand (op, mode) rtx op; enum machine_mode mode;{ int val; if (register_operand (op, mode)) return 1; if (GET_CODE (op) != CONST_INT) return 0; val = INTVAL (op) & 0xffffffff; return SPARC_SIMM13_P (val);}/* Return true if OP is a constant 4096 */intarith_4096_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ int val; if (GET_CODE (op) != CONST_INT) return 0; val = INTVAL (op) & 0xffffffff; return val == 4096;}/* Return true if OP is suitable as second operand for add/sub */intarith_add_operand (op, mode) rtx op; enum machine_mode mode;{ return arith_operand (op, mode) || arith_4096_operand (op, mode);}/* Return true if OP is a CONST_INT or a CONST_DOUBLE which can fit in the immediate field of OR and XOR instructions. Used for 64-bit constant formation patterns. */intconst64_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return ((GET_CODE (op) == CONST_INT && SPARC_SIMM13_P (INTVAL (op)))#if HOST_BITS_PER_WIDE_INT != 64 || (GET_CODE (op) == CONST_DOUBLE && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op)) && (CONST_DOUBLE_HIGH (op) == ((CONST_DOUBLE_LOW (op) & 0x80000000) != 0 ? (HOST_WIDE_INT)0xffffffff : 0)))#endif );}/* The same, but only for sethi instructions. */intconst64_high_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return ((GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xfffffc00) != 0 && SPARC_SETHI_P (INTVAL (op))#if HOST_BITS_PER_WIDE_INT != 64 /* Must be positive on non-64bit host else the optimizer is fooled into thinking that sethi sign extends, even though it does not. */ && INTVAL (op) >= 0#endif ) || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0 && (CONST_DOUBLE_LOW (op) & 0xfffffc00) != 0 && SPARC_SETHI_P (CONST_DOUBLE_LOW (op))));}/* Return true if OP is a register, or is a CONST_INT that can fit in a signed 11 bit immediate field. This is an acceptable SImode operand for the movcc instructions. */intarith11_operand (op, mode) rtx op; enum machine_mode mode;{ return (register_operand (op, mode) || (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op))));}/* Return true if OP is a register, or is a CONST_INT that can fit in a signed 10 bit immediate field. This is an acceptable SImode operand for the movrcc instructions. */intarith10_operand (op, mode) rtx op; enum machine_mode mode;{ return (register_operand (op, mode) || (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op))));}/* Return true if OP is a register, is a CONST_INT that fits in a 13 bit immediate field, or is a CONST_DOUBLE whose both parts fit in a 13 bit immediate field. v9: Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that can fit in a 13 bit immediate field. This is an acceptable DImode operand for most 3 address instructions. */intarith_double_operand (op, mode) rtx op; enum machine_mode mode;{ return (register_operand (op, mode) || (GET_CODE (op) == CONST_INT && SMALL_INT (op)) || (! TARGET_ARCH64 && GET_CODE (op) == CONST_DOUBLE && (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 && (unsigned HOST_WIDE_INT) (CONST_DOUBLE_HIGH (op) + 0x1000) < 0x2000) || (TARGET_ARCH64 && GET_CODE (op) == CONST_DOUBLE && (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 && ((CONST_DOUBLE_HIGH (op) == -1 && (CONST_DOUBLE_LOW (op) & 0x1000) == 0x1000) || (CONST_DOUBLE_HIGH (op) == 0 && (CONST_DOUBLE_LOW (op) & 0x1000) == 0))));}/* Return true if OP is a constant 4096 for DImode on ARCH64 */intarith_double_4096_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (TARGET_ARCH64 && ((GET_CODE (op) == CONST_INT && INTVAL (op) == 4096) || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 4096 && CONST_DOUBLE_HIGH (op) == 0)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -