static bool replace_oldest_value_addr (rtx *loc, enum reg_class cl, enum machine_mode mode, addr_space_t as, rtx insn, struct value_data *vd) { rtx x = *loc; RTX_CODE code = GET_CODE (x); const char *fmt; int i, j; bool changed = false; switch (code) { case PLUS: if (DEBUG_INSN_P (insn)) break; { rtx orig_op0 = XEXP (x, 0); rtx orig_op1 = XEXP (x, 1); RTX_CODE code0 = GET_CODE (orig_op0); RTX_CODE code1 = GET_CODE (orig_op1); rtx op0 = orig_op0; rtx op1 = orig_op1; rtx *locI = NULL; rtx *locB = NULL; enum rtx_code index_code = SCRATCH; if (GET_CODE (op0) == SUBREG) { op0 = SUBREG_REG (op0); code0 = GET_CODE (op0); } if (GET_CODE (op1) == SUBREG) { op1 = SUBREG_REG (op1); code1 = GET_CODE (op1); } if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE || code0 == ZERO_EXTEND || code1 == MEM) { locI = &XEXP (x, 0); locB = &XEXP (x, 1); index_code = GET_CODE (*locI); } else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE || code1 == ZERO_EXTEND || code0 == MEM) { locI = &XEXP (x, 1); locB = &XEXP (x, 0); index_code = GET_CODE (*locI); } else if (code0 == CONST_INT || code0 == CONST || code0 == SYMBOL_REF || code0 == LABEL_REF) { locB = &XEXP (x, 1); index_code = GET_CODE (XEXP (x, 0)); } else if (code1 == CONST_INT || code1 == CONST || code1 == SYMBOL_REF || code1 == LABEL_REF) { locB = &XEXP (x, 0); index_code = GET_CODE (XEXP (x, 1)); } else if (code0 == REG && code1 == REG) { int index_op; unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; locI = &XEXP (x, index_op); locB = &XEXP (x, !index_op); index_code = GET_CODE (*locI); } else if (code0 == REG) { locI = &XEXP (x, 0); locB = &XEXP (x, 1); index_code = GET_CODE (*locI); } else if (code1 == REG) { locI = &XEXP (x, 1); locB = &XEXP (x, 0); index_code = GET_CODE (*locI); } if (locI) changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode, as, insn, vd); if (locB) changed |= replace_oldest_value_addr (locB, base_reg_class (mode, as, PLUS, index_code), mode, as, insn, vd); return changed; } case POST_INC: case POST_DEC: case POST_MODIFY: case PRE_INC: case PRE_DEC: case PRE_MODIFY: return false; case MEM: return replace_oldest_value_mem (x, insn, vd); case REG: return replace_oldest_value_reg (loc, cl, insn, vd); default: break; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, as, insn, vd); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl, mode, as, insn, vd); } return changed; }
bool crx_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr, bool strict) { enum crx_addrtype addrtype; struct crx_address address; if (TARGET_DEBUG_ADDR) { fprintf (stderr, "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n", GET_MODE_NAME (mode), strict); debug_rtx (addr); } addrtype = crx_decompose_address (addr, &address); if (addrtype == CRX_POST_INC && GET_MODE_SIZE (mode) > UNITS_PER_WORD) return FALSE; if (TARGET_DEBUG_ADDR) { const char *typestr; switch (addrtype) { case CRX_INVALID: typestr = "Invalid"; break; case CRX_REG_REL: typestr = "Register relative"; break; case CRX_POST_INC: typestr = "Post-increment"; break; case CRX_SCALED_INDX: typestr = "Scaled index"; break; case CRX_ABSOLUTE: typestr = "Absolute"; break; default: abort (); } fprintf (stderr, "CRX Address type: %s\n", typestr); } if (addrtype == CRX_INVALID) return FALSE; if (strict) { if (address.base && !REGNO_OK_FOR_BASE_P (REGNO (address.base))) { if (TARGET_DEBUG_ADDR) fprintf (stderr, "Base register not strict\n"); return FALSE; } if (address.index && !REGNO_OK_FOR_INDEX_P (REGNO (address.index))) { if (TARGET_DEBUG_ADDR) fprintf (stderr, "Index register not strict\n"); return FALSE; } } return TRUE; }