This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]