This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: expanding movdi into 2 x movsi
Jim Wilson <wilson@specifixinc.com> writes:
> Jan Hoogerbrugge wrote:
> > I this a gcc bug? Is there an easy workarond by defining a
> > define_expand "movdi" that maps the move to 2 SImode moves? Any
> > suggestions for a port where I can borrow some code from?
>
> This does appear to be a gcc bug. However, since you are the only one
> that has a copy of your port, you will probably have to be the one to
> debug it.
>
> Yes, you can probably work around the problem by defining your own
> movdi pattern. You can borrow a movdi pattern from any target that
> defines one. Since I don't know your target, I can't suggest which
> one would be best to look at. Most of them are pretty similar. Try
> arm. It is the first common 32-bit target alphabetically. alpha is a
> 64-bit target, and arc isn't a common target.
Example of movdi from one 32 bits port.
(define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
"{
if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& GET_CODE (operands[0]) == MEM
&& !no_new_pseudos)
operands[1] = force_reg (DImode, operands[1]);
}
"
)
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "move_operand" "=r,r,m,r,m")
(match_operand:DI 1 "move_operand" " r,m,r,i,i"))]
""
"@
#
#
#
#
#")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "register_operand" ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"{
if (REGNO (operands[0]) < REGNO (operands[1]))
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[3] = gen_highpart (SImode, operands[1]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[5] = gen_lowpart (SImode, operands[1]);
}
else
{
operands[2] = gen_lowpart (SImode, operands[0]);
operands[3] = gen_lowpart (SImode, operands[1]);
operands[4] = gen_highpart (SImode, operands[0]);
operands[5] = gen_highpart (SImode, operands[1]);
}
}")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "memory_operand" ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"{
operands[2] = gen_highpart (SImode, operands[0]);
operands[3] = gen_highpart (SImode, operands[1]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[5] = gen_lowpart (SImode, operands[1]);
if (reg_mentioned_p (operands[2], operands[3]))
{
rtx tem;
tem = operands[4];
operands[4] = operands[2];
operands[2] = tem;
tem = operands[5];
operands[5] = operands[3];
operands[3] = tem;
}
}")
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
(match_operand:DI 1 "register_operand" ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"{
operands[2] = gen_highpart (SImode, operands[0]);
operands[3] = gen_highpart (SImode, operands[1]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[5] = gen_lowpart (SImode, operands[1]);
}")
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "immediate_operand" ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"{
operands[2] = gen_highpart (SImode, operands[0]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
operands[5] = gen_lowpart (SImode, operands[1]);
}")
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
(match_operand:DI 1 "immediate_operand" ""))]
""
[(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 5))]
"{
operands[2] = gen_highpart (SImode, operands[0]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
operands[5] = gen_lowpart (SImode, operands[1]);
}")
Denis.