rtx gen_lowpart_general (machine_mode mode, rtx x) { rtx result = gen_lowpart_common (mode, x); if (result) return result; /* Handle SUBREGs and hard REGs that were rejected by simplify_gen_subreg. */ else if (REG_P (x) || GET_CODE (x) == SUBREG) { result = gen_lowpart_common (mode, copy_to_reg (x)); gcc_assert (result != 0); return result; } else { /* The only additional case we can do is MEM. */ gcc_assert (MEM_P (x)); /* The following exposes the use of "x" to CSE. */ scalar_int_mode xmode; if (is_a <scalar_int_mode> (GET_MODE (x), &xmode) && GET_MODE_SIZE (xmode) <= UNITS_PER_WORD && TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode) && !reload_completed) return gen_lowpart_general (mode, force_reg (xmode, x)); poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (x)); return adjust_address (x, mode, offset); } }
rtx gen_lowpart_general (machine_mode mode, rtx x) { rtx result = gen_lowpart_common (mode, x); if (result) return result; /* Handle SUBREGs and hard REGs that were rejected by simplify_gen_subreg. */ else if (REG_P (x) || GET_CODE (x) == SUBREG) { result = gen_lowpart_common (mode, copy_to_reg (x)); gcc_assert (result != 0); return result; } else { int offset = 0; /* The only additional case we can do is MEM. */ gcc_assert (MEM_P (x)); /* The following exposes the use of "x" to CSE. */ if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD && SCALAR_INT_MODE_P (GET_MODE (x)) && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (x)) && !reload_completed) return gen_lowpart_general (mode, force_reg (GET_MODE (x), x)); if (WORDS_BIG_ENDIAN) offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); if (BYTES_BIG_ENDIAN) /* Adjust the address so that the address-after-the-data is unchanged. */ offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); return adjust_address (x, mode, offset); } }
rtx gen_lowpart_general (enum machine_mode mode, rtx x) { rtx result = gen_lowpart_common (mode, x); if (result) return result; else if (REG_P (x)) { /* Must be a hard reg that's not valid in MODE. */ result = gen_lowpart_common (mode, copy_to_reg (x)); gcc_assert (result != 0); return result; } else { int offset = 0; /* The only additional case we can do is MEM. */ gcc_assert (MEM_P (x)); /* The following exposes the use of "x" to CSE. */ if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD && SCALAR_INT_MODE_P (GET_MODE (x)) && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), GET_MODE_BITSIZE (GET_MODE (x))) && ! no_new_pseudos) return gen_lowpart_general (mode, force_reg (GET_MODE (x), x)); if (WORDS_BIG_ENDIAN) offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); if (BYTES_BIG_ENDIAN) /* Adjust the address so that the address-after-the-data is unchanged. */ offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); return adjust_address (x, mode, offset); } }