bool nds32_const_unspec_p (rtx x) { if (GET_CODE (x) == CONST) { x = XEXP (x, 0); if (GET_CODE (x) == PLUS) x = XEXP (x, 0); if (GET_CODE (x) == UNSPEC) { switch (XINT (x, 1)) { case UNSPEC_GOTINIT: case UNSPEC_GOT: case UNSPEC_GOTOFF: case UNSPEC_PLT: case UNSPEC_TLSGD: case UNSPEC_TLSLD: case UNSPEC_TLSIE: case UNSPEC_TLSLE: return false; default: return true; } } } if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) return false; return true; }
static inline int local_symbolic_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) #line 442 "../.././gcc/config/i386/predicates.md" { if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == PLUS && CONST_INT_P (XEXP (XEXP (op, 0), 1))) op = XEXP (XEXP (op, 0), 0); if (GET_CODE (op) == LABEL_REF) return 1; if (GET_CODE (op) != SYMBOL_REF) return 0; if (SYMBOL_REF_TLS_MODEL (op) != 0) return 0; if (SYMBOL_REF_LOCAL_P (op)) return 1; /* There is, however, a not insubstantial body of code in the rest of the compiler that assumes it can just stick the results of ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done. */ /* ??? This is a hack. Should update the body of the compiler to always create a DECL an invoke targetm.encode_section_info. */ if (strncmp (XSTR (op, 0), internal_label_prefix, internal_label_prefix_len) == 0) return 1; return 0; }
int tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) { return ((GET_CODE (op) == SYMBOL_REF) && ( #line 487 "../.././gcc/config/i386/predicates.md" (SYMBOL_REF_TLS_MODEL (op) != 0))) && ( (mode == VOIDmode || GET_MODE (op) == mode)); }
static inline int x86_64_zext_immediate_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) #line 221 "../.././gcc/config/i386/predicates.md" { switch (GET_CODE (op)) { case CONST_DOUBLE: if (HOST_BITS_PER_WIDE_INT == 32) return (GET_MODE (op) == VOIDmode && !CONST_DOUBLE_HIGH (op)); else return 0; case CONST_INT: if (HOST_BITS_PER_WIDE_INT == 32) return INTVAL (op) >= 0; else return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff); case SYMBOL_REF: /* For certain code models, the symbolic references are known to fit. */ /* TLS symbols are not constant. */ if (SYMBOL_REF_TLS_MODEL (op)) return false; return (ix86_cmodel == CM_SMALL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op))); case LABEL_REF: /* For certain code models, the code is near as well. */ return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM; case CONST: /* We also may accept the offsetted memory references in certain special cases. */ if (GET_CODE (XEXP (op, 0)) == PLUS) { rtx op1 = XEXP (XEXP (op, 0), 0); rtx op2 = XEXP (XEXP (op, 0), 1); if (ix86_cmodel == CM_LARGE) return 0; switch (GET_CODE (op1)) { case SYMBOL_REF: /* TLS symbols are not constant. */ if (SYMBOL_REF_TLS_MODEL (op1)) return 0; /* For small code model we may accept pretty large positive offsets, since one bit is available for free. Negative offsets are limited by the size of NULL pointer area specified by the ABI. */ if ((ix86_cmodel == CM_SMALL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op1))) && CONST_INT_P (op2) && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000 && trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2)) return 1; /* ??? For the kernel, we may accept adjustment of -0x10000000, since we know that it will just convert negative address space to positive, but perhaps this is not worthwhile. */ break; case LABEL_REF: /* These conditions are similar to SYMBOL_REF ones, just the constraints for code models differ. */ if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM) && CONST_INT_P (op2) && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000 && trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2)) return 1; break; default: return 0; } } break; default: gcc_unreachable (); } return 0; }
static inline int x86_64_immediate_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) #line 94 "../.././gcc/config/i386/predicates.md" { if (!TARGET_64BIT) return immediate_operand (op, mode); switch (GET_CODE (op)) { case CONST_INT: /* CONST_DOUBLES never match, since HOST_BITS_PER_WIDE_INT is known to be at least 32 and this all acceptable constants are represented as CONST_INT. */ if (HOST_BITS_PER_WIDE_INT == 32) return 1; else { HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (op), DImode); return trunc_int_for_mode (val, SImode) == val; } break; case SYMBOL_REF: /* For certain code models, the symbolic references are known to fit. in CM_SMALL_PIC model we know it fits if it is local to the shared library. Don't count TLS SYMBOL_REFs here, since they should fit only if inside of UNSPEC handled below. */ /* TLS symbols are not constant. */ if (SYMBOL_REF_TLS_MODEL (op)) return false; return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op))); case LABEL_REF: /* For certain code models, the code is near as well. */ return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_KERNEL); case CONST: /* We also may accept the offsetted memory references in certain special cases. */ if (GET_CODE (XEXP (op, 0)) == UNSPEC) switch (XINT (XEXP (op, 0), 1)) { case UNSPEC_GOTPCREL: case UNSPEC_DTPOFF: case UNSPEC_GOTNTPOFF: case UNSPEC_NTPOFF: return 1; default: break; } if (GET_CODE (XEXP (op, 0)) == PLUS) { rtx op1 = XEXP (XEXP (op, 0), 0); rtx op2 = XEXP (XEXP (op, 0), 1); HOST_WIDE_INT offset; if (ix86_cmodel == CM_LARGE) return 0; if (!CONST_INT_P (op2)) return 0; offset = trunc_int_for_mode (INTVAL (op2), DImode); switch (GET_CODE (op1)) { case SYMBOL_REF: /* TLS symbols are not constant. */ if (SYMBOL_REF_TLS_MODEL (op1)) return 0; /* For CM_SMALL assume that latest object is 16MB before end of 31bits boundary. We may also accept pretty large negative constants knowing that all objects are in the positive half of address space. */ if ((ix86_cmodel == CM_SMALL || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op1))) && offset < 16*1024*1024 && trunc_int_for_mode (offset, SImode) == offset) return 1; /* For CM_KERNEL we know that all object resist in the negative half of 32bits address space. We may not accept negative offsets, since they may be just off and we may accept pretty large positive ones. */ if (ix86_cmodel == CM_KERNEL && offset > 0 && trunc_int_for_mode (offset, SImode) == offset) return 1; break; case LABEL_REF: /* These conditions are similar to SYMBOL_REF ones, just the constraints for code models differ. */ if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM) && offset < 16*1024*1024 && trunc_int_for_mode (offset, SImode) == offset) return 1; if (ix86_cmodel == CM_KERNEL && offset > 0 && trunc_int_for_mode (offset, SImode) == offset) return 1; break; case UNSPEC: switch (XINT (op1, 1)) { case UNSPEC_DTPOFF: case UNSPEC_NTPOFF: if (offset > 0 && trunc_int_for_mode (offset, SImode) == offset) return 1; } break; default: break; } } break; default: gcc_unreachable (); } return 0; }