On 13/02/15 17:04, Richard Henderson wrote:
On 02/13/2015 08:26 AM, Renlin Li wrote:
+ /* Complete overlap. We can remove the source ZERO_EXTEND. */
+ if (width == inner_size
+ && (regno < FIRST_PSEUDO_REGISTER)
+ && HARD_REGNO_MODE_OK (regno, mode))
+ {
+ rtx reg = gen_rtx_REG (mode, regno);
+ return gen_rtx_SET (VOIDmode, dest, reg);
What in the world are you doing here with the hard registers?
r~
Ah, So we don't have the convention to play with hard register in this pass?
This AND rtx here will be transformed into a zero_extend rtx from
sub_reg expression, and further into the form I have mentioned above, as
the hard register support this.
(and:SI (reg:SI 1 x1 [ y ])
(const_int 255 [0xff])))
I have modified my patch a little bit, Is the following method Okay?
if (GET_CODE (dest) == ZERO_EXTRACT
&& CONST_INT_P (XEXP (dest, 1))
&& CONST_INT_P (XEXP (dest, 2))
&& GET_CODE (src) == ZERO_EXTEND)
{
HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
mode = GET_MODE (dest);
/* handle sub_reg rtx. */
if (GET_CODE (XEXP (src, 0)) == SUBREG && REG_P (XEXP (XEXP (src,
0), 0)))
{
rtx reg = XEXP (XEXP (src, 0), 0);
unsigned int inner_size = GET_MODE_BITSIZE (GET_MODE (XEXP (src,
0)));
/* Complete overlap. We can remove the source ZERO_EXTEND. */
if (width == inner_size
&& mode == GET_MODE (reg))
return gen_rtx_SET (VOIDmode, dest, reg);
}
/* handle hard register case as sub_reg further is simplied. */
else if (REG_P (XEXP (src, 0)))
{
rtx tmp = XEXP (src, 0);
unsigned int inner_size = GET_MODE_BITSIZE (GET_MODE (tmp));
/* Complete overlap. We can remove the source ZERO_EXTEND. */
if (width == inner_size && can_change_dest_mode (tmp, 0, mode))
{
rtx reg = gen_rtx_REG (mode, REGNO (tmp));
return gen_rtx_SET (VOIDmode, dest, reg);
}
}
}
Is there a better way to do this here or somewhere else? or it's good
to implement it as a specific rtx insn?
A define split won't work in this case. This should handled in combine pass.
Thank you for any suggestions!
Regards,
Renlin Li