This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, x86_64]: Provide longlong.h definitions for 128bit operations
Rask Ingemann Lambertsen <rask@sygehus.dk> writes:
> On Thu, May 17, 2007 at 01:15:48PM +0200, Rask Ingemann Lambertsen wrote:
>
> > You must be running into some sort of target specific problem,
>
> The i386 back end is splitting adddi3 after reload, which is too late.
> I'm not sure that splitting before reload is early enough, but that is the
> easiest change to make.
With the new lower-subreg patch, insns like adddi3 should split before
reload when possible. But you can't use the existing split in
i386.md, because it relies on FLAGS_REG, and reload may accidentally
clobber FLAGS_REG. In my uncommitted follow-on patch to lower-subreg,
I did it like this:
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
(match_operand:DI 2 "general_operand" "")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
[(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
(plus:SI (plus:SI (match_dup 4) (match_dup 5))
(truncate:SI
(lshiftrt:DI
(plus:DI
(zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
(const_int 32)))))
(clobber (reg:CC FLAGS_REG))])]
{
split_di (operands + 0, 1, operands + 0, operands + 3);
split_di (operands + 1, 1, operands + 1, operands + 4);
split_di (operands + 2, 1, operands + 2, operands + 5);
})
(define_insn_and_split "*adddi3_2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,rm,r")
(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
(match_operand:SI 2 "general_operand" "ri,rm,ri,rm")))
(set (match_operand:SI 3 "nonimmediate_operand" "=rm,r,rm,r")
(plus:SI (plus:SI (match_operand:SI 4 "general_operand" "3,3,ri,rm")
(match_operand:SI 5 "general_operand" "ri,rm,3,3"))
(truncate:SI
(lshiftrt:DI
(plus:DI
(zero_extend:DI (match_dup 1))
(zero_extend:DI (match_dup 2)))
(const_int 32)))))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
"#"
"&& reload_completed"
[(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
UNSPEC_ADD_CARRY))
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
(parallel [(set (match_dup 3)
(plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
(match_dup 4))
(match_dup 5)))
(clobber (reg:CC FLAGS_REG))])]
{
/* We can only have one pair of commutative operands in an insn, so
we commute operands 4 and 5 manually. */
if (rtx_equal_p (operands[5], operands[3]))
{
rtx tmp = operands[4];
operands[4] = operands[5];
operands[5] = tmp;
}
})
Ian