📄 arm.c
字号:
if (!fpa_consts_inited) init_fpa_table (); REAL_VALUE_FROM_CONST_DOUBLE (r, x); if (REAL_VALUE_MINUS_ZERO (r)) return 0; for (i = 0; i < 8; i++) if (REAL_VALUES_EQUAL (r, values_fpa[i])) return 1; return 0;}/* Return TRUE if rtx X is a valid immediate FPU constant. */intneg_const_double_rtx_ok_for_fpu (x) rtx x;{ REAL_VALUE_TYPE r; int i; if (!fpa_consts_inited) init_fpa_table (); REAL_VALUE_FROM_CONST_DOUBLE (r, x); r = REAL_VALUE_NEGATE (r); if (REAL_VALUE_MINUS_ZERO (r)) return 0; for (i = 0; i < 8; i++) if (REAL_VALUES_EQUAL (r, values_fpa[i])) return 1; return 0;}/* Predicates for `match_operand' and `match_operator'. *//* s_register_operand is the same as register_operand, but it doesn't accept (SUBREG (MEM)...). This function exists because at the time it was put in it led to better code. SUBREG(MEM) always needs a reload in the places where s_register_operand is used, and this seemed to lead to excessive reloading. */ints_register_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_MODE (op) != mode && mode != VOIDmode) return 0; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); /* We don't consider registers whose class is NO_REGS to be a register operand. */ return (GET_CODE (op) == REG && (REGNO (op) >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));}/* Only accept reg, subreg(reg), const_int. */intreg_or_int_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_CODE (op) == CONST_INT) return 1; if (GET_MODE (op) != mode && mode != VOIDmode) return 0; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); /* We don't consider registers whose class is NO_REGS to be a register operand. */ return (GET_CODE (op) == REG && (REGNO (op) >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));}/* Return 1 if OP is an item in memory, given that we are in reload. */intreload_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ int regno = true_regnum (op); return (! CONSTANT_P (op) && (regno == -1 || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER)));}/* Return 1 if OP is a valid memory address, but not valid for a signed byte memory access (architecture V4) */intbad_signed_byte_operand (op, mode) rtx op; enum machine_mode mode;{ if (! memory_operand (op, mode) || GET_CODE (op) != MEM) return 0; op = XEXP (op, 0); /* A sum of anything more complex than reg + reg or reg + const is bad */ if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) && (! s_register_operand (XEXP (op, 0), VOIDmode) || (! s_register_operand (XEXP (op, 1), VOIDmode) && GET_CODE (XEXP (op, 1)) != CONST_INT))) return 1; /* Big constants are also bad */ if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT && (INTVAL (XEXP (op, 1)) > 0xff || -INTVAL (XEXP (op, 1)) > 0xff)) return 1; /* Everything else is good, or can will automatically be made so. */ return 0;}/* Return TRUE for valid operands for the rhs of an ARM instruction. */intarm_rhs_operand (op, mode) rtx op; enum machine_mode mode;{ return (s_register_operand (op, mode) || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));}/* Return TRUE for valid operands for the rhs of an ARM instruction, or a load. */intarm_rhsm_operand (op, mode) rtx op; enum machine_mode mode;{ return (s_register_operand (op, mode) || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))) || memory_operand (op, mode));}/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a constant that is valid when negated. */intarm_add_operand (op, mode) rtx op; enum machine_mode mode;{ return (s_register_operand (op, mode) || (GET_CODE (op) == CONST_INT && (const_ok_for_arm (INTVAL (op)) || const_ok_for_arm (-INTVAL (op)))));}intarm_not_operand (op, mode) rtx op; enum machine_mode mode;{ return (s_register_operand (op, mode) || (GET_CODE (op) == CONST_INT && (const_ok_for_arm (INTVAL (op)) || const_ok_for_arm (~INTVAL (op)))));}/* Return TRUE if the operand is a memory reference which contains an offsettable address. */intoffsettable_memory_operand (op, mode) register rtx op; enum machine_mode mode;{ if (mode == VOIDmode) mode = GET_MODE (op); return (mode == GET_MODE (op) && GET_CODE (op) == MEM && offsettable_address_p (reload_completed | reload_in_progress, mode, XEXP (op, 0)));}/* Return TRUE if the operand is a memory reference which is, or can be made word aligned by adjusting the offset. */intalignable_memory_operand (op, mode) register rtx op; enum machine_mode mode;{ rtx reg; if (mode == VOIDmode) mode = GET_MODE (op); if (mode != GET_MODE (op) || GET_CODE (op) != MEM) return 0; op = XEXP (op, 0); return ((GET_CODE (reg = op) == REG || (GET_CODE (op) == SUBREG && GET_CODE (reg = SUBREG_REG (op)) == REG) || (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT && (GET_CODE (reg = XEXP (op, 0)) == REG || (GET_CODE (XEXP (op, 0)) == SUBREG && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG)))) && REGNO_POINTER_ALIGN (REGNO (reg)) >= 4);}/* Similar to s_register_operand, but does not allow hard integer registers. */intf_register_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_MODE (op) != mode && mode != VOIDmode) return 0; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); /* We don't consider registers whose class is NO_REGS to be a register operand. */ return (GET_CODE (op) == REG && (REGNO (op) >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (REGNO (op)) == FPU_REGS));}/* Return TRUE for valid operands for the rhs of an FPU instruction. */intfpu_rhs_operand (op, mode) rtx op; enum machine_mode mode;{ if (s_register_operand (op, mode)) return TRUE; else if (GET_CODE (op) == CONST_DOUBLE) return (const_double_rtx_ok_for_fpu (op)); return FALSE;}intfpu_add_operand (op, mode) rtx op; enum machine_mode mode;{ if (s_register_operand (op, mode)) return TRUE; else if (GET_CODE (op) == CONST_DOUBLE) return (const_double_rtx_ok_for_fpu (op) || neg_const_double_rtx_ok_for_fpu (op)); return FALSE;}/* Return nonzero if OP is a constant power of two. */intpower_of_two_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) == CONST_INT) { HOST_WIDE_INT value = INTVAL(op); return value != 0 && (value & (value - 1)) == 0; } return FALSE;}/* Return TRUE for a valid operand of a DImode operation. Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address). Note that this disallows MEM(REG+REG), but allows MEM(PRE/POST_INC/DEC(REG)). */intdi_operand (op, mode) rtx op; enum machine_mode mode;{ if (s_register_operand (op, mode)) return TRUE; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); switch (GET_CODE (op)) { case CONST_DOUBLE: case CONST_INT: return TRUE; case MEM: return memory_address_p (DImode, XEXP (op, 0)); default: return FALSE; }}/* Return TRUE for a valid operand of a DFmode operation when -msoft-float. Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address). Note that this disallows MEM(REG+REG), but allows MEM(PRE/POST_INC/DEC(REG)). */intsoft_df_operand (op, mode) rtx op; enum machine_mode mode;{ if (s_register_operand (op, mode)) return TRUE; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); switch (GET_CODE (op)) { case CONST_DOUBLE: return TRUE; case MEM: return memory_address_p (DFmode, XEXP (op, 0)); default: return FALSE; }}/* Return TRUE for valid index operands. */intindex_operand (op, mode) rtx op; enum machine_mode mode;{ return (s_register_operand(op, mode) || (immediate_operand (op, mode) && INTVAL (op) < 4096 && INTVAL (op) > -4096));}/* Return TRUE for valid shifts by a constant. This also accepts any power of two on the (somewhat overly relaxed) assumption that the shift operator in this case was a mult. */intconst_shift_operand (op, mode) rtx op; enum machine_mode mode;{ return (power_of_two_operand (op, mode) || (immediate_operand (op, mode) && (INTVAL (op) < 32 && INTVAL (op) > 0)));}/* Return TRUE for arithmetic operators which can be combined with a multiply (shift). */intshiftable_operator (x, mode) rtx x; enum machine_mode mode;{ if (GET_MODE (x) != mode) return FALSE; else { enum rtx_code code = GET_CODE (x); return (code == PLUS || code == MINUS || code == IOR || code == XOR || code == AND); }}/* Return TRUE for shift operators. */intshift_operator (x, mode) rtx x; enum machine_mode mode;{ if (GET_MODE (x) != mode) return FALSE; else { enum rtx_code code = GET_CODE (x); if (code == MULT) return power_of_two_operand (XEXP (x, 1), mode); return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT || code == ROTATERT); }}int equality_operator (x, mode) rtx x; enum machine_mode mode ATTRIBUTE_UNUSED;{ return GET_CODE (x) == EQ || GET_CODE (x) == NE;}/* Return TRUE for SMIN SMAX UMIN UMAX operators. */intminmax_operator (x, mode) rtx x; enum machine_mode mode;{ enum rtx_code code = GET_CODE (x); if (GET_MODE (x) != mode) return FALSE; return code == SMIN || code == SMAX || code == UMIN || code == UMAX;}/* return TRUE if x is EQ or NE *//* Return TRUE if this is the condition code register, if we aren't given a mode, accept any class CCmode register */intcc_register (x, mode) rtx x; enum machine_mode mode;{ if (mode == VOIDmode) { mode = GET_MODE (x); if (GET_MODE_CLASS (mode) != MODE_CC) return FALSE; } if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24) return TRUE; return FALSE;}/* Return TRUE if this is the condition code register, if we aren't given a mode, accept any class CCmode register which indicates a dominance expression. */intdominant_cc_register (x, mode) rtx x; enum machine_mode mode;{ if (mode == VOIDmode) { mode = GET_MODE (x); if (GET_MODE_CLASS (mode) != MODE_CC) return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -