📄 alpha.c
字号:
return local_symbol_p (op);}/* Return true if OP is a SYMBOL_REF or CONST referencing a variable known to be defined in this file in the small data area. */intsmall_symbolic_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ const char *str; if (! TARGET_SMALL_DATA) return 0; if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) return 0; if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) op = XEXP (XEXP (op, 0), 0); if (GET_CODE (op) != SYMBOL_REF) return 0; if (CONSTANT_POOL_ADDRESS_P (op)) return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value; else { str = XSTR (op, 0); return str[0] == '@' && str[1] == 's'; }}/* Return true if OP is a SYMBOL_REF or CONST referencing a variable not known (or known not) to be defined in this file. */intglobal_symbolic_operand (op, mode) rtx op; enum machine_mode mode;{ if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) return 0; if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) op = XEXP (XEXP (op, 0), 0); if (GET_CODE (op) != SYMBOL_REF) return 0; return ! local_symbol_p (op);}/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */intcall_operand (op, mode) rtx op; enum machine_mode mode;{ if (mode != Pmode) return 0; if (GET_CODE (op) == REG) { if (TARGET_ABI_OSF) { /* Disallow virtual registers to cope with pathalogical test cases such as compile/930117-1.c in which the virtual reg decomposes to the frame pointer. Which is a hard reg that is not $27. */ return (REGNO (op) == 27 || REGNO (op) > LAST_VIRTUAL_REGISTER); } else return 1; } if (TARGET_ABI_UNICOSMK) return 0; if (GET_CODE (op) == SYMBOL_REF) return 1; return 0;}/* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref, possibly with an offset. */intsymbolic_operand (op, mode) register rtx op; enum machine_mode mode;{ if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) return 0; if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF) return 1; if (GET_CODE (op) == CONST && GET_CODE (XEXP (op,0)) == PLUS && GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF && GET_CODE (XEXP (XEXP (op,0), 1)) == CONST_INT) return 1; return 0;}/* Return 1 if OP is a valid Alpha comparison operator. Here we know which comparisons are valid in which insn. */intalpha_comparison_operator (op, mode) register rtx op; enum machine_mode mode;{ enum rtx_code code = GET_CODE (op); if (mode != GET_MODE (op) && mode != VOIDmode) return 0; return (code == EQ || code == LE || code == LT || code == LEU || code == LTU);}/* Return 1 if OP is a valid Alpha comparison operator against zero. Here we know which comparisons are valid in which insn. */intalpha_zero_comparison_operator (op, mode) register rtx op; enum machine_mode mode;{ enum rtx_code code = GET_CODE (op); if (mode != GET_MODE (op) && mode != VOIDmode) return 0; return (code == EQ || code == NE || code == LE || code == LT || code == LEU || code == LTU);}/* Return 1 if OP is a valid Alpha swapped comparison operator. */intalpha_swapped_comparison_operator (op, mode) register rtx op; enum machine_mode mode;{ enum rtx_code code = GET_CODE (op); if ((mode != GET_MODE (op) && mode != VOIDmode) || GET_RTX_CLASS (code) != '<') return 0; code = swap_condition (code); return (code == EQ || code == LE || code == LT || code == LEU || code == LTU);}/* Return 1 if OP is a signed comparison operation. */intsigned_comparison_operator (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ enum rtx_code code = GET_CODE (op); if (mode != GET_MODE (op) && mode != VOIDmode) return 0; return (code == EQ || code == NE || code == LE || code == LT || code == GE || code == GT);}/* Return 1 if OP is a valid Alpha floating point comparison operator. Here we know which comparisons are valid in which insn. */intalpha_fp_comparison_operator (op, mode) register rtx op; enum machine_mode mode;{ enum rtx_code code = GET_CODE (op); if (mode != GET_MODE (op) && mode != VOIDmode) return 0; return (code == EQ || code == LE || code == LT || code == UNORDERED);}/* Return 1 if this is a divide or modulus operator. */intdivmod_operator (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ switch (GET_CODE (op)) { case DIV: case MOD: case UDIV: case UMOD: return 1; default: break; } return 0;}/* Return 1 if this memory address is a known aligned register plus a constant. It must be a valid address. This means that we can do this as an aligned reference plus some offset. Take into account what reload will do. */intaligned_memory_operand (op, mode) register rtx op; enum machine_mode mode;{ rtx base; if (reload_in_progress) { rtx tmp = op; if (GET_CODE (tmp) == SUBREG) tmp = SUBREG_REG (tmp); if (GET_CODE (tmp) == REG && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) { op = reg_equiv_memory_loc[REGNO (tmp)]; if (op == 0) return 0; } } if (GET_CODE (op) != MEM || GET_MODE (op) != mode) return 0; op = XEXP (op, 0); /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) sorts of constructs. Dig for the real base register. */ if (reload_in_progress && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 0)) == PLUS) base = XEXP (XEXP (op, 0), 0); else { if (! memory_address_p (mode, op)) return 0; base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); } return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);}/* Similar, but return 1 if OP is a MEM which is not alignable. */intunaligned_memory_operand (op, mode) register rtx op; enum machine_mode mode;{ rtx base; if (reload_in_progress) { rtx tmp = op; if (GET_CODE (tmp) == SUBREG) tmp = SUBREG_REG (tmp); if (GET_CODE (tmp) == REG && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) { op = reg_equiv_memory_loc[REGNO (tmp)]; if (op == 0) return 0; } } if (GET_CODE (op) != MEM || GET_MODE (op) != mode) return 0; op = XEXP (op, 0); /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) sorts of constructs. Dig for the real base register. */ if (reload_in_progress && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 0)) == PLUS) base = XEXP (XEXP (op, 0), 0); else { if (! memory_address_p (mode, op)) return 0; base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); } return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);}/* Return 1 if OP is either a register or an unaligned memory location. */intreg_or_unaligned_mem_operand (op, mode) rtx op; enum machine_mode mode;{ return register_operand (op, mode) || unaligned_memory_operand (op, mode);}/* Return 1 if OP is any memory location. During reload a pseudo matches. */intany_memory_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == MEM || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG) || (reload_in_progress && GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER) || (reload_in_progress && GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));}/* Returns 1 if OP is not an eliminable register. This exists to cure a pathological abort in the s8addq (et al) patterns, long foo () { long t; bar(); return (long) &t * 26107; } which run afoul of a hack in reload to cure a (presumably) similar problem with lea-type instructions on other targets. But there is one of us and many of them, so work around the problem by selectively preventing combine from making the optimization. */intreg_not_elim_operand (op, mode) register rtx op; enum machine_mode mode;{ rtx inner = op; if (GET_CODE (op) == SUBREG) inner = SUBREG_REG (op); if (inner == frame_pointer_rtx || inner == arg_pointer_rtx) return 0; return register_operand (op, mode);}/* Return 1 is OP is a memory location that is not a reference (using an AND) to an unaligned location. Take into account what reload will do. */intnormal_memory_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (reload_in_progress) { rtx tmp = op; if (GET_CODE (tmp) == SUBREG) tmp = SUBREG_REG (tmp); if (GET_CODE (tmp) == REG && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) { op = reg_equiv_memory_loc[REGNO (tmp)]; /* This may not have been assigned an equivalent address if it will be eliminated. In that case, it doesn't matter what we do. */ if (op == 0) return 1; } } return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;}/* Accept a register, but not a subreg of any kind. This allows us to avoid pathological cases in reload wrt data movement common in int->fp conversion. */intreg_no_subreg_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_CODE (op) != REG) return 0; return register_operand (op, mode);}/* Recognize an addition operation that includes a constant. Used to convince reload to canonize (plus (plus reg c1) c2) during register elimination. */intaddition_operation (op, mode) register rtx op; enum machine_mode mode;{ if (GET_MODE (op) != mode && mode != VOIDmode) return 0; if (GET_CODE (op) == PLUS && register_operand (XEXP (op, 0), mode) && GET_CODE (XEXP (op, 1)) == CONST_INT && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K')) return 1; return 0;}/* Implements CONST_OK_FOR_LETTER_P. Return true if the value matches the range defined for C in [I-P]. */boolalpha_const_ok_for_letter_p (value, c) HOST_WIDE_INT value; int c;{ switch (c) { case 'I': /* An unsigned 8 bit constant. */ return (unsigned HOST_WIDE_INT) value < 0x100; case 'J': /* The constant zero. */ return value == 0; case 'K': /* A signed 16 bit constant. */ return (unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000; case 'L': /* A shifted signed 16 bit constant appropriate for LDAH. */ return ((value & 0xffff) == 0 && ((value) >> 31 == -1 || value >> 31 == 0)); case 'M': /* A constant that can be AND'ed with using a ZAP insn. */ return zap_mask (value); case 'N': /* A complemented unsigned 8 bit constant. */ return (unsigned HOST_WIDE_INT) (~ value) < 0x100; case 'O': /* A negated unsigned 8 bit constant. */ return (unsigned HOST_WIDE_INT) (- value) < 0x100; case 'P': /* The constant 1, 2 or 3. */ return value == 1 || value == 2 || value == 3; default: return false; }}/* Implements CONST_DOUBLE_OK_FOR_LETTER_P. Return true if VALUE matches for C in [GH]. */boolalpha_const_double_ok_for_letter_p (value, c) rtx value; int c;{ switch (c) { case 'G': /* The floating point zero constant. */ return (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT && value == CONST0_RTX (GET_MODE (value))); case 'H': /* A valid operand of a ZAP insn. */ return (GET_MODE (value) == VOIDmode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -