static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
struct value_data *);
static bool replace_oldest_value_addr (rtx *, enum reg_class,
- enum machine_mode, rtx,
+ enum machine_mode, addr_space_t, rtx,
struct value_data *);
static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
offset = ((WORDS_BIG_ENDIAN ? wordoffset : 0)
+ (BYTES_BIG_ENDIAN ? byteoffset : 0));
- return gen_rtx_raw_REG (new_mode,
- regno + subreg_regno_offset (regno, orig_mode,
- offset,
- new_mode));
+ regno += subreg_regno_offset (regno, orig_mode, offset, new_mode);
+ if (HARD_REGNO_MODE_OK (regno, new_mode))
+ return gen_rtx_raw_REG (new_mode, regno);
}
return NULL_RTX;
}
static bool
replace_oldest_value_addr (rtx *loc, enum reg_class cl,
- enum machine_mode mode, rtx insn,
- struct value_data *vd)
+ enum machine_mode mode, addr_space_t as,
+ rtx insn, struct value_data *vd)
{
rtx x = *loc;
RTX_CODE code = GET_CODE (x);
unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
if (REGNO_OK_FOR_INDEX_P (regno1)
- && regno_ok_for_base_p (regno0, mode, PLUS, REG))
+ && 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, PLUS, REG))
+ && regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
index_op = 0;
- else if (regno_ok_for_base_p (regno0, mode, PLUS, REG)
+ 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, PLUS, REG))
+ else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG))
index_op = 0;
else
index_op = 1;
}
if (locI)
- changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode,
- insn, vd);
+ 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, PLUS,
+ base_reg_class (mode, as, PLUS,
index_code),
- mode, insn, vd);
+ mode, as, insn, vd);
return changed;
}
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode,
+ 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, insn, vd);
+ mode, as, insn, vd);
}
return changed;
if (DEBUG_INSN_P (insn))
cl = ALL_REGS;
else
- cl = base_reg_class (GET_MODE (x), MEM, SCRATCH);
+ cl = base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), MEM, SCRATCH);
return replace_oldest_value_addr (&XEXP (x, 0), cl,
- GET_MODE (x), insn, vd);
+ GET_MODE (x), MEM_ADDR_SPACE (x),
+ insn, vd);
}
/* Apply all queued updates for DEBUG_INSNs that change some reg to
if (!VAR_LOC_UNKNOWN_P (loc))
replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn),
ALL_REGS, GET_MODE (loc),
- insn, vd);
+ ADDR_SPACE_GENERIC, insn, vd);
}
if (insn == BB_END (bb))
if (hard_regno_nregs[regno][mode]
> hard_regno_nregs[regno][vd->e[regno].mode])
goto no_move_special_case;
+
+ /* And likewise, if we are narrowing on big endian the transformation
+ is also invalid. */
+ if (hard_regno_nregs[regno][mode]
+ < hard_regno_nregs[regno][vd->e[regno].mode]
+ && (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
+ ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+ goto no_move_special_case;
}
/* If the destination is also a register, try to find a source
changed = true;
goto did_replacement;
}
+ /* We need to re-extract as validate_change clobbers
+ recog_data. */
+ extract_insn (insn);
+ if (! constrain_operands (1))
+ fatal_insn_not_found (insn);
+ preprocess_constraints ();
}
/* Otherwise, try all valid registers and see if its valid. */
changed = true;
goto did_replacement;
}
+ /* We need to re-extract as validate_change clobbers
+ recog_data. */
+ extract_insn (insn);
+ if (! constrain_operands (1))
+ fatal_insn_not_found (insn);
+ preprocess_constraints ();
}
}
}
replaced[i]
= replace_oldest_value_addr (recog_data.operand_loc[i],
recog_op_alt[i][alt].cl,
- VOIDmode, insn, vd);
+ VOIDmode, ADDR_SPACE_GENERIC,
+ insn, vd);
else if (REG_P (recog_data.operand[i]))
replaced[i]
= replace_oldest_value_reg (recog_data.operand_loc[i],
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_df_finish
+ TODO_df_finish
| TODO_verify_rtl_sharing /* todo_flags_finish */
}
};