📄 rs6000.c
字号:
if (GET_CODE (op) != REG) return 0; if (REGNO (op) == COUNT_REGISTER_REGNUM) return 1; if (REGNO (op) > FIRST_PSEUDO_REGISTER) return 1; return 0;}/* Returns 1 if op is memory location for float/int conversions that masquerades as a register. */intfpmem_operand(op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (GET_CODE (op) != REG) return 0; if (FPMEM_REGNO_P (REGNO (op))) return 1;#if 0 if (REGNO (op) > FIRST_PSEUDO_REGISTER) return 1;#endif return 0;}/* Return 1 if OP is a constant that can fit in a D field. */intshort_cint_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return ((GET_CODE (op) == CONST_INT && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000));}/* Similar for a unsigned D field. */intu_short_cint_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == CONST_INT && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff)) == 0);}/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */intnon_short_cint_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == CONST_INT && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);}/* Returns 1 if OP is a register that is not special (i.e., not MQ, ctr, or lr). */intgpc_reg_operand (op, mode) register rtx op; enum machine_mode mode;{ return (register_operand (op, mode) && (GET_CODE (op) != REG || (REGNO (op) >= 67 && !FPMEM_REGNO_P (REGNO (op))) || REGNO (op) < 64));}/* Returns 1 if OP is either a pseudo-register or a register denoting a CR field. */intcc_reg_operand (op, mode) register rtx op; enum machine_mode mode;{ return (register_operand (op, mode) && (GET_CODE (op) != REG || REGNO (op) >= FIRST_PSEUDO_REGISTER || CR_REGNO_P (REGNO (op))));}/* Returns 1 if OP is either a pseudo-register or a register denoting a CR field that isn't CR0. */intcc_reg_not_cr0_operand (op, mode) register rtx op; enum machine_mode mode;{ return (register_operand (op, mode) && (GET_CODE (op) != REG || REGNO (op) >= FIRST_PSEUDO_REGISTER || CR_REGNO_NOT_CR0_P (REGNO (op))));}/* Returns 1 if OP is either a constant integer valid for a D-field or a non-special register. If a register, it must be in the proper mode unless MODE is VOIDmode. */intreg_or_short_operand (op, mode) register rtx op; enum machine_mode mode;{ return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);}/* Similar, except check if the negation of the constant would be valid for a D-field. */intreg_or_neg_short_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_CODE (op) == CONST_INT) return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P'); return gpc_reg_operand (op, mode);}/* Return 1 if the operand is either a register or an integer whose high-order 16 bits are zero. */intreg_or_u_short_operand (op, mode) register rtx op; enum machine_mode mode;{ return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);}/* Return 1 is the operand is either a non-special register or ANY constant integer. */intreg_or_cint_operand (op, mode) register rtx op; enum machine_mode mode;{ return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));}/* Return 1 is the operand is either a non-special register or ANY 32-bit unsigned constant integer. */intreg_or_u_cint_operand (op, mode) register rtx op; enum machine_mode mode;{ return (gpc_reg_operand (op, mode) || (GET_CODE (op) == CONST_INT#if HOST_BITS_PER_WIDE_INT != 32 && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)#endif && INTVAL (op) > 0)#if HOST_BITS_PER_WIDE_INT == 32 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0)#endif );}/* Return 1 if the operand is an operand that can be loaded via the GOT */intgot_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST || GET_CODE (op) == LABEL_REF);}/* Return 1 if the operand is a simple references that can be loaded via the GOT (labels involving addition aren't allowed). */intgot_no_const_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);}/* Return the number of instructions it takes to form a constant in an integer register. */static intnum_insns_constant_wide (value) HOST_WIDE_INT value;{ /* signed constant loadable with {cal|addi} */ if (((unsigned HOST_WIDE_INT)value + 0x8000) < 0x10000) return 1;#if HOST_BITS_PER_WIDE_INT == 32 /* constant loadable with {cau|addis} */ else if ((value & 0xffff) == 0) return 1;#else /* constant loadable with {cau|addis} */ else if ((value & 0xffff) == 0 && (value & ~0xffffffff) == 0) return 1; else if (TARGET_64BIT) { HOST_WIDE_INT low = value & 0xffffffff; HOST_WIDE_INT high = value >> 32; if (high == 0 && (low & 0x80000000) == 0) return 2; else if (high == 0xffffffff && (low & 0x80000000) != 0) return 2; else if (!low) return num_insns_constant_wide (high) + 1; else return (num_insns_constant_wide (high) + num_insns_constant_wide (low) + 1); }#endif else return 2;}intnum_insns_constant (op, mode) rtx op; enum machine_mode mode;{ if (GET_CODE (op) == CONST_INT) return num_insns_constant_wide (INTVAL (op)); else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode) { long l; REAL_VALUE_TYPE rv; REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_SINGLE (rv, l); return num_insns_constant_wide ((HOST_WIDE_INT)l); } else if (GET_CODE (op) == CONST_DOUBLE) { HOST_WIDE_INT low; HOST_WIDE_INT high; long l[2]; REAL_VALUE_TYPE rv; int endian = (WORDS_BIG_ENDIAN == 0); if (mode == VOIDmode || mode == DImode) { high = CONST_DOUBLE_HIGH (op); low = CONST_DOUBLE_LOW (op); } else { REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_DOUBLE (rv, l); high = l[endian]; low = l[1 - endian]; } if (TARGET_32BIT) return (num_insns_constant_wide (low) + num_insns_constant_wide (high)); else { if (high == 0 && (low & 0x80000000) == 0) return num_insns_constant_wide (low); else if (((high & 0xffffffff) == 0xffffffff) && ((low & 0x80000000) != 0)) return num_insns_constant_wide (low); else if (mask64_operand (op, mode)) return 2; else if (low == 0) return num_insns_constant_wide (high) + 1; else return (num_insns_constant_wide (high) + num_insns_constant_wide (low) + 1); } } else abort ();}/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a register with one instruction per word. We only do this if we can safely read CONST_DOUBLE_{LOW,HIGH}. */inteasy_fp_constant (op, mode) register rtx op; register enum machine_mode mode;{ if (GET_CODE (op) != CONST_DOUBLE || GET_MODE (op) != mode || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode)) return 0; /* Consider all constants with -msoft-float to be easy */ if (TARGET_SOFT_FLOAT && mode != DImode) return 1; /* If we are using V.4 style PIC, consider all constants to be hard */ if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)) return 0;#ifdef TARGET_RELOCATABLE /* Similarly if we are using -mrelocatable, consider all constants to be hard */ if (TARGET_RELOCATABLE) return 0;#endif if (mode == DFmode) { long k[2]; REAL_VALUE_TYPE rv; REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_DOUBLE (rv, k); return (num_insns_constant_wide ((HOST_WIDE_INT)k[0]) == 1 && num_insns_constant_wide ((HOST_WIDE_INT)k[1]) == 1); } else if (mode == SFmode) { long l; REAL_VALUE_TYPE rv; REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_SINGLE (rv, l); return num_insns_constant_wide (l) == 1; } else if (mode == DImode) return ((TARGET_64BIT && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0) || (num_insns_constant (op, DImode) <= 2)); else abort ();}/* Return 1 if the operand is in volatile memory. Note that during the RTL generation phase, memory_operand does not return TRUE for volatile memory references. So this function allows us to recognize volatile references where its safe. */intvolatile_mem_operand (op, mode) register rtx op; enum machine_mode mode;{ if (GET_CODE (op) != MEM) return 0; if (!MEM_VOLATILE_P (op)) return 0; if (mode != GET_MODE (op)) return 0; if (reload_completed) return memory_operand (op, mode); if (reload_in_progress) return strict_memory_address_p (mode, XEXP (op, 0)); return memory_address_p (mode, XEXP (op, 0));}/* Return 1 if the operand is an offsettable memory operand. */intoffsettable_mem_operand (op, mode) register rtx op; enum machine_mode mode;{ return ((GET_CODE (op) == MEM) && offsettable_address_p (reload_completed || reload_in_progress, mode, XEXP (op, 0)));}/* Return 1 if the operand is either an easy FP constant (see above) or memory. */intmem_or_easy_const_operand (op, mode) register rtx op; enum machine_mode mode;{ return memory_operand (op, mode) || easy_fp_constant (op, mode);}/* Return 1 if the operand is either a non-special register or an item that can be used as the operand of an SI add insn. */intadd_operand (op, mode) register rtx op; enum machine_mode mode;{ return (reg_or_short_operand (op, mode) || (GET_CODE (op) == CONST_INT && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0));}/* Return 1 if OP is a constant but not a valid add_operand. */intnon_add_cint_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == CONST_INT && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000 && (INTVAL (op) & (~ (HOST_WIDE_INT) 0xffff0000)) != 0);}/* Return 1 if the operand is a non-special register or a constant that can be used as the operand of an OR or XOR insn on the RS/6000. */intlogical_operand (op, mode) register rtx op; enum machine_mode mode;{ return (gpc_reg_operand (op, mode) || (GET_CODE (op) == CONST_INT#if HOST_BITS_PER_WIDE_INT != 32 && INTVAL (op) > 0 && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)#endif && ((INTVAL (op) & GET_MODE_MASK (mode) & (~ (HOST_WIDE_INT) 0xffff)) == 0 || (INTVAL (op) & GET_MODE_MASK (mode) & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -