public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Updated patch for DImode operations on i386
@ 1998-03-02  6:46 Bernd Schmidt
  1998-03-05 15:33 ` Jeffrey A Law
  0 siblings, 1 reply; 2+ messages in thread
From: Bernd Schmidt @ 1998-03-02  6:46 UTC (permalink / raw)
  To: egcs

Here's an updated patch for logical DImode operations on the i386.
Changes since the last one:
 - now the new patterns use exactly the same constrains as subdi3, to avoid
   reload problems
 - now uses change_address in split_di to create new MEMs, to preserve
   MEM_* bits.

Bernd

	* i386.c (ix86_logical_operator): New function.
	(split_di): Ensure that when a MEM is split, the resulting MEMs have
	SImode.
	* i386.md (anddi3, xordi3, iordi3): New patterns. Add a define_split
	to implement them.

Index: config/i386/i386.c
===================================================================
RCS file: /usr/local/cvs/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.1.3.7
diff -c -p -r1.1.3.7 i386.c
*** i386.c	1998/02/16 19:05:44	1.1.3.7
--- i386.c	1998/02/25 19:39:30
*************** arithmetic_comparison_operator (op, mode
*** 1698,1703 ****
--- 1698,1712 ----
  
    return (code != GT && code != LE);
  }
+ 
+ int
+ ix86_logical_operator (op, mode)
+      register rtx op;
+      enum machine_mode mode;
+ {
+   return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
+ }
+ 
  \f
  /* Returns 1 if OP contains a symbol reference */
  
*************** split_di (operands, num, lo_half, hi_hal
*** 3688,3704 ****
  {
    while (num--)
      {
!       if (GET_CODE (operands[num]) == REG)
  	{
! 	  lo_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]));
! 	  hi_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]) + 1);
  	}
!       else if (CONSTANT_P (operands[num]))
! 	split_double (operands[num], &lo_half[num], &hi_half[num]);
!       else if (offsettable_memref_p (operands[num]))
! 	{
! 	  lo_half[num] = operands[num];
! 	  hi_half[num] = adj_offsettable_operand (operands[num], 4);
  	}
        else
  	abort();
--- 3697,3716 ----
  {
    while (num--)
      {
!       rtx op = operands[num];
!       if (GET_CODE (op) == REG)
  	{
! 	  lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
! 	  hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
  	}
!       else if (CONSTANT_P (op))
! 	split_double (op, &lo_half[num], &hi_half[num]);
!       else if (offsettable_memref_p (op))
! 	{
! 	  rtx lo_addr = XEXP (op, 0);
! 	  rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
! 	  lo_half[num] = change_address (op, SImode, lo_addr);
! 	  hi_half[num] = change_address (op, SImode, hi_addr);
  	}
        else
  	abort();
Index: config/i386/i386.md
===================================================================
RCS file: /usr/local/cvs/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.1.3.7
diff -c -p -r1.1.3.7 i386.md
*** i386.md	1998/02/25 08:53:40	1.1.3.7
--- i386.md	1998/02/25 19:50:58
*************** byte_xor_operation:
*** 4241,4246 ****
--- 4241,4347 ----
    ""
    "* return AS2 (xor%B0,%2,%0);")
  \f
+ ;; logical operations for DImode
+ 
+ 
+ (define_insn "anddi3"
+   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ 	(and:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ 		(match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+    (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+   ""
+   "#")
+   
+ (define_insn "iordi3"
+   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ 	(ior:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ 		(match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+    (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+   ""
+   "#")
+   
+ (define_insn "xordi3"
+   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ 	(xor:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ 		(match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+    (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+   ""
+   "#")
+ 
+ (define_split
+   [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ 	(match_operator:DI 4 "ix86_logical_operator"
+ 	  [(match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ 	   (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")]))
+    (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+   "reload_completed"
+   [(const_int 0)]
+   "
+ {
+   rtx low[3], high[3], xops[7], temp;
+   rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3
+ 		      : GET_CODE (operands[4]) == IOR ? gen_iorsi3
+ 		      : GET_CODE (operands[4]) == XOR ? gen_xorsi3
+ 		      : 0);
+ 
+   if (rtx_equal_p (operands[0], operands[2]))
+     {
+       temp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = temp;
+     }
+ 
+   split_di (operands, 3, low, high);
+   if (!rtx_equal_p (operands[0], operands[1]))
+     {
+       xops[0] = high[0];
+       xops[1] = low[0];
+       xops[2] = high[1];
+       xops[3] = low[1];
+ 
+       if (GET_CODE (operands[0]) != MEM)
+ 	{
+ 	  emit_insn (gen_movsi (xops[1], xops[3]));
+ 	  emit_insn (gen_movsi (xops[0], xops[2]));
+ 	}
+       else
+ 	{
+ 	  xops[4] = high[2];
+ 	  xops[5] = low[2];
+ 	  xops[6] = operands[3];
+ 	  emit_insn (gen_movsi (xops[6], xops[3]));
+ 	  emit_insn ((*genfunc) (xops[6], xops[6], xops[5]));
+ 	  emit_insn (gen_movsi (xops[1], xops[6]));
+ 	  emit_insn (gen_movsi (xops[6], xops[2]));
+ 	  emit_insn ((*genfunc) (xops[6], xops[6], xops[4]));
+ 	  emit_insn (gen_movsi (xops[0], xops[6]));
+ 	  DONE;
+ 	}
+     }
+ 
+   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
+     {
+       xops[0] = high[0];
+       xops[1] = low[0];
+       xops[2] = high[2];
+       xops[3] = low[2];
+       xops[4] = operands[3];
+ 
+       emit_insn (gen_movsi (xops[4], xops[3]));
+       emit_insn ((*genfunc) (xops[1], xops[1], xops[4]));
+       emit_insn (gen_movsi (xops[4], xops[2]));
+       emit_insn ((*genfunc) (xops[0], xops[0], xops[4]));
+     }
+ 
+   else
+     {
+       emit_insn ((*genfunc) (low[0], low[0], low[2]));
+       emit_insn ((*genfunc) (high[0], high[0], high[2]));
+     }
+ 
+   DONE;
+ }")
+ 
  ;;- negation instructions
  
  (define_insn "negdi2"

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Updated patch for DImode operations on i386
  1998-03-02  6:46 Updated patch for DImode operations on i386 Bernd Schmidt
@ 1998-03-05 15:33 ` Jeffrey A Law
  0 siblings, 0 replies; 2+ messages in thread
From: Jeffrey A Law @ 1998-03-05 15:33 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: egcs

  In message <Pine.SOL.3.90.980302130935.10510G-100000@quincy.informatik.rwth-a
achen.de>you write:
  > Here's an updated patch for logical DImode operations on the i386.
  > Changes since the last one:
  >  - now the new patterns use exactly the same constrains as subdi3, to avoid
  >    reload problems
Actually, we probably want to mimic the adddi3 pattern's constraints
(which have changed recently to deal with another DImode problem).

Can you do that and give it a quick test and send me the final
patch (which I'll install unless someone objects between now and
then).

jeff

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1998-03-05 15:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-03-02  6:46 Updated patch for DImode operations on i386 Bernd Schmidt
1998-03-05 15:33 ` Jeffrey A Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).