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]

[PATCH] AVR: rev.2: implement HI/SI logic operations and sign/zero extension by define_insn_and_split instead of define_insn


Hello Denis,

here is again the patch considering your remarks. I have been able to remove 
most of the explicit insn templates in the define_insn_and_split patterns. 
However, I did not succeed in removing them completely. A single case makes 
problem: lable reference immediates. This case still remains handled by the 
shortened unsplitted instruction patterns. I have also experimented with 
using gen_lowpart/gen_highpart. When using them I got about 40 additional 
regressions due to ICE in gen_lowpart/gen_highpart. Namely, these functions 
seem to fail on subreg input operands and as well on immediate label 
references. Also the resulting code did not get smaller. So I decided to 
stick to the explicit subreg expressions.

I have tested the patch on the testsuite setup using the atmega128 simulator 
and did not observe any regression.

Yours,

BjÃrn

BTW, what is happening with Andy's RTL-prologue/epilogue patch? IMHO, the 
patch would be ready for check-in on mainline 4.1.?



2005-15-04  Bjoern Haase <bjoern.m.haase@web.de>

 	* config/avr/avr.md:
 	replace magic numbers for unspec numbering by (define_constants ).
 	add new unspec for generation of sign extension byte.
 	extend define_insn to define_insn_and_split for the patterns...
 	"andhi" (here also tiny change in define_insn pattern), "andsi"
 	"iorhi", "iorhi_clobber", "iorsi", "iorsi_clobber"
 	"extendqihi2", "extendqisi2", "extendhisi2"
 	"zero_extendqihi2", "zero_extendqisi2", "zero_extendhisi2"
 	replace "xorhi" and "xorsi" patterns by expanders
Index: avr.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.md,v
retrieving revision 1.51
diff -u -r1.51 avr.md
--- avr.md	13 Mar 2005 10:09:53 -0000	1.51
+++ avr.md	17 Apr 2005 09:58:58 -0000
@@ -35,8 +35,15 @@
 ;;  ~  Output 'r' if not AVR_MEGA.
 
 ;; UNSPEC usage:
-;;  0  Length of a string, see "strlenhi".
-;;  1  Read from a word address in program memory, see "casesi".
+;;  0   Length of a string, see "strlenhi".
+;;  1   Read from a word address in program memory, see "casesi".
+;;  30  Generate sign byte sequence "clr %0 \; sbrs %1,7 \; com %0" 
+;;      for the sign_extend splitter 
+
+(define_constants 
+  [(UNSP_STRLENHI 0)
+   (UNSP_READ_PMEM 1)
+   (UNSP_GEN_SIGN 30)])
 
 ;; Condition code settings.
 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
@@ -478,7 +485,8 @@
     [(set (match_dup 4)
 	  (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
 		      (match_operand:QI 2 "const_int_operand" "")
-		      (match_operand:HI 3 "immediate_operand" "")] 0))
+		      (match_operand:HI 3 "immediate_operand" "")] 
+                     UNSP_STRLENHI))
      (set (match_dup 4) (plus:HI (match_dup 4)
 				 (const_int -1)))
      (set (match_operand:HI 0 "register_operand" "")
@@ -499,7 +507,8 @@
   [(set (match_operand:HI 0 "register_operand" "=e")
 	(unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
 		    (const_int 0)
-		    (match_operand:HI 2 "immediate_operand" "i")] 0))]
+		    (match_operand:HI 2 "immediate_operand" "i")] 
+                    UNSP_STRLENHI))]
   ""
   "ld __tmp_reg__,%a0+
 	tst __tmp_reg__
@@ -964,72 +973,145 @@
   [(set_attr "length" "1,1")
    (set_attr "cc" "set_zn,set_zn")])
 
-(define_insn "andhi3"
+(define_insn_and_split "andhi3"
   [(set (match_operand:HI 0 "register_operand" "=r,d,r")
 	  (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
-		  (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
+		  (match_operand:HI 2 "nonmemory_operand" "r,i,i")))
    (clobber (match_scratch:QI 3 "=X,X,&d"))]
   ""
   "*{
-  if (which_alternative==0)
-    return (AS2 (and,%A0,%A2) CR_TAB
-	    AS2 (and,%B0,%B2));
-  else if (which_alternative==1)
+  /* Emit unsplitted insn in case of label refs. */
+  if (which_alternative==1)
     {
-      if (GET_CODE (operands[2]) == CONST_INT)
-        {
-	  int mask = INTVAL (operands[2]);
-	  if ((mask & 0xff) != 0xff)
-	    output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
-	  if ((mask & 0xff00) != 0xff00)
-	    output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
-	  return \"\";
-        }
-        return (AS2 (andi,%A0,lo8(%2)) CR_TAB
-	        AS2 (andi,%B0,hi8(%2)));
+       return (AS2 (andi,%A0,lo8(%2)) CR_TAB
+               AS2 (andi,%B0,hi8(%2)));
      }
   return (AS2 (ldi,%3,lo8(%2)) CR_TAB
           AS2 (and,%A0,%3)     CR_TAB
-          AS1 (clr,%B0));
+          AS2 (ldi,%3,hi8(%2)) CR_TAB
+          AS2 (and,%B0,%3));
 }"
-  [(set_attr "length" "2,2,3")
-   (set_attr "cc" "set_n,clobber,set_n")])
+  "    reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (and:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (and:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+     {     
+       /* If operands[2] is a register, use the template above. */ 
+       /* In case of const ints optimize away andi reg,0xff and */
+       /* replace andi reg,0 by ldi reg,0 .  */
+       int value = INTVAL(operands[2]);
+       int j;
+       int bytes_of_mode = 2;
+       for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == 0)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+
+	    }
+	  else if (qi_immediate != -1)
+	    { 
+              /* check whether or not we can use andi.   */ 
+	      if ((REGNO (operands[0])+j) < 16)
+	        {                
+	     	  emit_insn (gen_movqi  (operands[3],
+	                                 immediate_operand));
+	          emit_insn (gen_andqi3 (subreg_operand,
+	                                 subreg_operand,
+			   	         operands[3]));
+		}
+	      else
+	        { 
+	          emit_insn (gen_andqi3 (subreg_operand,
+	                                 subreg_operand,
+			    	         immediate_operand));
+		}
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
+  [(set_attr "length" "2,2,4")
+   (set_attr "cc" "set_n,clobber,clobber")])
 
-(define_insn "andsi3"
+(define_insn_and_split "andsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,d")
 	(and:SI (match_operand:SI 1 "register_operand" "%0,0")
 		(match_operand:SI 2 "nonmemory_operand" "r,i")))]
   ""
   "*{
-  if (which_alternative==0)
-    return (AS2 (and, %0,%2)   CR_TAB
-	    AS2 (and, %B0,%B2) CR_TAB
-	    AS2 (and, %C0,%C2) CR_TAB
-	    AS2 (and, %D0,%D2));
-  else if (which_alternative==1)
-    {
-      if (GET_CODE (operands[2]) == CONST_INT)
-        {
-	  HOST_WIDE_INT mask = INTVAL (operands[2]);
-	  if ((mask & 0xff) != 0xff)
-	    output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
-	  if ((mask & 0xff00) != 0xff00)
-	    output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
-	  if ((mask & 0xff0000L) != 0xff0000L)
-	    output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
-	  if ((mask & 0xff000000L) != 0xff000000L)
-	    output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
-	  return \"\";
-        }
+      /* Emit unsplitted insn in case of label refs. */
       return (AS2 (andi, %A0,lo8(%2))  CR_TAB
               AS2 (andi, %B0,hi8(%2)) CR_TAB
 	      AS2 (andi, %C0,hlo8(%2)) CR_TAB
 	      AS2 (andi, %D0,hhi8(%2)));
-    }
-  return \"bug\";
 }"
+  "   reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (and:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (and:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))
+   (set (subreg:QI (match_dup 0) 2)
+        (and:QI (subreg:QI (match_dup 1) 2)
+                (subreg:QI (match_dup 2) 2)))
+   (set (subreg:QI (match_dup 0) 3)
+        (and:QI (subreg:QI (match_dup 1) 3)
+                (subreg:QI (match_dup 2) 3)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+    { 
+      /* If operands[2] is a register, use the template above.  */ 
+      int value = INTVAL(operands[2]);
+      int j;
+      int bytes_of_mode = 4;
+      for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == 0)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+
+	    }
+	  else if (qi_immediate != -1)
+	    { 
+	      emit_insn (gen_andqi3 (subreg_operand,
+	                             subreg_operand,
+				     immediate_operand));
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
   [(set_attr "length" "4,4")
-   (set_attr "cc" "set_n,set_n")])
+   (set_attr "cc" "set_n,clobber")])
 
 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ;; ior
@@ -1045,31 +1127,62 @@
   [(set_attr "length" "1,1")
    (set_attr "cc" "set_zn,set_zn")])
 
-(define_insn "iorhi3"
+(define_insn_and_split "iorhi3"
   [(set (match_operand:HI 0 "register_operand" "=r,d")
 	(ior:HI (match_operand:HI 1 "register_operand" "%0,0")
 		(match_operand:HI 2 "nonmemory_operand" "r,i")))]
   ""
   "*{
-  if (which_alternative==0)
-    return (AS2 (or,%A0,%A2) CR_TAB
-	    AS2 (or,%B0,%B2));
-  if (GET_CODE (operands[2]) == CONST_INT)
-     {
-	int mask = INTVAL (operands[2]);
-	if (mask & 0xff)
-	  output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
-	if (mask & 0xff00)
-	  output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
-	return \"\";
-      }
+   /* Emit unsplitted insn in case of label refs. */
    return (AS2 (ori,%0,lo8(%2)) CR_TAB
 	   AS2 (ori,%B0,hi8(%2)));
-}"  
+}"
+  "   reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (ior:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (ior:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+    {
+      /* If operands[2] is a register, use the template above.  */ 
+      int value = INTVAL(operands[2]);
+      int j;
+      int bytes_of_mode = 2;
+      for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == -1)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+
+	    }
+	  else if (qi_immediate != 0)
+	    { 
+	      emit_insn (gen_iorqi3 (subreg_operand,
+	                             subreg_operand,
+				     immediate_operand));
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
   [(set_attr "length" "2,2")
    (set_attr "cc" "set_n,clobber")])
 
-(define_insn "*iorhi3_clobber"
+(define_insn_and_split "*iorhi3_clobber"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
 	(ior:HI (match_operand:HI 1 "register_operand" "%0,0")
 		(match_operand:HI 2 "immediate_operand" "M,i")))
@@ -1078,42 +1191,126 @@
   "@
 	ldi %3,lo8(%2)\;or %A0,%3
 	ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
+  "   reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (ior:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (ior:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+    {     
+      /* If operands[2] is a register, use the template above.  */ 
+      int value = INTVAL(operands[2]);
+      int j;
+      int bytes_of_mode = 2;
+      for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == -1)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+	    }
+	  else if (qi_immediate != 0)
+	    {  
+              /* check whether or not we can use ori.   */ 
+	      if ((REGNO (operands[0])+j) < 16)
+	        {                
+	     	  emit_insn (gen_movqi  (operands[3],
+	                                 immediate_operand));
+	          emit_insn (gen_iorqi3 (subreg_operand,
+	                                 subreg_operand,
+			   	         operands[3]));
+		}
+	      else
+	        { 
+	          emit_insn (gen_iorqi3 (subreg_operand,
+	                                 subreg_operand,
+			    	         immediate_operand));
+		}
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
   [(set_attr "length" "2,4")
-   (set_attr "cc" "clobber,set_n")])
+   (set_attr "cc" "clobber,clobber")])
 
-(define_insn "iorsi3"
+(define_insn_and_split "iorsi3"
   [(set (match_operand:SI 0 "register_operand"        "=r,d")
 	(ior:SI (match_operand:SI 1 "register_operand" "%0,0")
 		(match_operand:SI 2 "nonmemory_operand" "r,i")))]
   ""
   "*{
-  if (which_alternative==0)
-    return (AS2 (or, %0,%2)   CR_TAB
-	    AS2 (or, %B0,%B2) CR_TAB
-	    AS2 (or, %C0,%C2) CR_TAB
-	    AS2 (or, %D0,%D2));
-  if (GET_CODE (operands[2]) == CONST_INT)
-     {
-	HOST_WIDE_INT mask = INTVAL (operands[2]);
-	if (mask & 0xff)
-	  output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
-	if (mask & 0xff00)
-	  output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
-	if (mask & 0xff0000L)
-	  output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
-	if (mask & 0xff000000L)
-	  output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
-	return \"\";
-      }
+  /* emit unsplitted insn in case of label refs. */
   return (AS2 (ori, %A0,lo8(%2))  CR_TAB
 	  AS2 (ori, %B0,hi8(%2)) CR_TAB
 	  AS2 (ori, %C0,hlo8(%2)) CR_TAB
 	  AS2 (ori, %D0,hhi8(%2)));
 }"
+  "   reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (ior:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (ior:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))
+   (set (subreg:QI (match_dup 0) 2)
+        (ior:QI (subreg:QI (match_dup 1) 2)
+                (subreg:QI (match_dup 2) 2)))
+   (set (subreg:QI (match_dup 0) 3)
+        (ior:QI (subreg:QI (match_dup 1) 3)
+                (subreg:QI (match_dup 2) 3)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+    { 
+      /* If operands[2] is a register, use the template above.  */ 
+      int value = INTVAL(operands[2]);
+      int j;
+      int bytes_of_mode = 4;
+      for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == -1)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+
+	    }
+	  else if (qi_immediate != 0)
+	    { 
+	      emit_insn (gen_iorqi3 (subreg_operand,
+	                             subreg_operand,
+				     immediate_operand));
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
   [(set_attr "length" "4,4")
    (set_attr "cc" "set_n,clobber")])
 
-(define_insn "*iorsi3_clobber"
+(define_insn_and_split "*iorsi3_clobber"
   [(set (match_operand:SI 0 "register_operand"        "=r,r")
 	(ior:SI (match_operand:SI 1 "register_operand" "%0,0")
 		(match_operand:SI 2 "immediate_operand" "M,i")))
@@ -1122,8 +1319,67 @@
   "@
 	ldi %3,lo8(%2)\;or %A0,%3
 	ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
+  "   reload_completed 
+   && ((GET_CODE(operands[2]) == CONST_INT) || REG_P(operands[2]))"
+  [(set (subreg:QI (match_dup 0) 0)
+        (ior:QI (subreg:QI (match_dup 1) 0)
+                (subreg:QI (match_dup 2) 0)))
+   (set (subreg:QI (match_dup 0) 1)
+        (ior:QI (subreg:QI (match_dup 1) 1)
+                (subreg:QI (match_dup 2) 1)))
+   (set (subreg:QI (match_dup 0) 2)
+        (ior:QI (subreg:QI (match_dup 1) 2)
+                (subreg:QI (match_dup 2) 2)))
+   (set (subreg:QI (match_dup 0) 3)
+        (ior:QI (subreg:QI (match_dup 1) 3)
+                (subreg:QI (match_dup 2) 3)))]
+  "if (GET_CODE(operands[2]) == CONST_INT)
+    {     
+      /* If operands[2] is a register, use the template above.  */ 
+      int value = INTVAL(operands[2]);
+      int j;
+      int bytes_of_mode = 4;
+      for (j=0; j < bytes_of_mode; j++)
+        { 
+	  rtx immediate_operand;
+	  rtx subreg_operand;
+	   
+	  int qi_immediate = (value & 0x000000FF);
+	  if (qi_immediate & 0x0080)
+	   qi_immediate -= 256;
+	  immediate_operand = GEN_INT (qi_immediate);
+	  subreg_operand = gen_rtx_SUBREG (QImode,operands[0],j);
+	  
+	  if (qi_immediate == -1)
+	    {
+	      emit_insn (gen_movqi (subreg_operand,
+	                            immediate_operand));
+	    }
+	  else if (qi_immediate != 0)
+	    {  
+              /* check whether or not we can use ori.   */ 
+	      if ((REGNO (operands[0])+j) < 16)
+	        {                
+	     	  emit_insn (gen_movqi  (operands[3],
+	                                 immediate_operand));
+	          emit_insn (gen_iorqi3 (subreg_operand,
+	                                 subreg_operand,
+			   	         operands[3]));
+		}
+	      else
+	        { 
+	          emit_insn (gen_iorqi3 (subreg_operand,
+	                                 subreg_operand,
+			    	         immediate_operand));
+		}
+	    }
+	  value = value >> 8;
+	}
+      DONE;
+    }
+  "
   [(set_attr "length" "2,8")
-   (set_attr "cc" "clobber,set_n")])
+   (set_attr "cc" "clobber,clobber")])
 
 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ;; xor
@@ -1137,28 +1393,32 @@
   [(set_attr "length" "1")
    (set_attr "cc" "set_zn")])
 
-(define_insn "xorhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-        (xor:HI (match_operand:HI 1 "register_operand" "%0")
-                (match_operand:HI 2 "register_operand" "r")))]
+(define_expand "xorhi3"
+ [(set (subreg:QI (match_operand:HI 0 "register_operand" "=r") 0)
+       (xor:QI (subreg:QI (match_operand:HI 1 "register_operand" "%0") 0)
+               (subreg:QI (match_operand:HI 2 "register_operand" "r")  0)))
+  (set (subreg:QI (match_dup 0) 1)
+       (xor:QI (subreg:QI (match_dup 1) 1)
+               (subreg:QI (match_dup 2) 1))) ]
   ""
-  "eor %0,%2
-	eor %B0,%B2"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_n")])
+  "")
 
-(define_insn "xorsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (xor:SI (match_operand:SI 1 "register_operand" "%0")
-                (match_operand:SI 2 "register_operand" "r")))]
+(define_expand "xorsi3"
+ [(set (subreg:QI (match_operand:SI 0 "register_operand" "=r") 0)
+       (xor:QI (subreg:QI (match_operand:SI 1 "register_operand" "%0") 0)
+               (subreg:QI (match_operand:SI 2 "register_operand" "r")  0)))
+  (set (subreg:QI (match_dup 0) 1)
+       (xor:QI (subreg:QI (match_dup 1) 1)
+               (subreg:QI (match_dup 2) 1))) 
+  (set (subreg:QI (match_dup 0) 2)
+       (xor:QI (subreg:QI (match_dup 1) 2)
+               (subreg:QI (match_dup 2) 2))) 
+  (set (subreg:QI (match_dup 0) 3)
+       (xor:QI (subreg:QI (match_dup 1) 3)
+               (subreg:QI (match_dup 2) 3)))]
   ""
-  "eor %0,%2
-	eor %B0,%B2
-	eor %C0,%C2
-	eor %D0,%D2"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_n")])
-
+  "")
+   
 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
 ;; arithmetic shift left
 
@@ -1486,33 +1746,69 @@
 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
 ;; sign extend
 
-(define_insn "extendqihi2"
+(define_insn "*generate_extension_byte"
+ [(set (match_operand:QI 0 "register_operand" "=&r,=r") 
+       (unspec:QI [(match_operand:QI 1 "register_operand" "r,r")] 
+                  UNSP_GEN_SIGN ))]
+ ""
+ "@
+  clr %0\;sbrc %1,7\;com %0
+  mov __tmp_reg__,%1\;clr %0\;sbrc __tmp_reg__,7\;com %0"
+ [(set_attr "length" "3,4")
+   (set_attr "cc" "clobber,clobber")])
+ 
+
+(define_insn_and_split "extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
         (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %B0\;sbrc %0,7\;com %B0
 	mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
+  "reload_completed"
+  [ (set (subreg:QI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:QI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 1)
+         (unspec:QI [(match_dup 1)] UNSP_GEN_SIGN))]
+  ""
   [(set_attr "length" "3,4")
    (set_attr "cc" "set_n,set_n")])
 
-(define_insn "extendqisi2"
+(define_insn_and_split "extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
         (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
 	mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
+  "reload_completed"
+  [ (set (subreg:QI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:QI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 1)
+         (unspec:QI [(match_dup 1)] UNSP_GEN_SIGN))
+    (set (subreg:QI (match_dup 0) 2)
+         (subreg:QI (match_dup 0) 1))
+    (set (subreg:QI (match_dup 0) 3)
+         (subreg:QI (match_dup 0) 1))]
+  ""  
   [(set_attr "length" "5,6")
    (set_attr "cc" "set_n,set_n")])
 
-(define_insn "extendhisi2"
+(define_insn_and_split "extendhisi2"
   [(set (match_operand:SI 0 "register_operand"               "=r,&r")
         (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
 	{mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
+  "reload_completed"
+  [ (set (subreg:HI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:HI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 2)
+         (unspec:QI [(subreg:QI (match_dup 1) 1)] UNSP_GEN_SIGN))
+    (set (subreg:QI (match_dup 0) 3)
+         (subreg:QI (match_dup 0) 2))]
+  ""  
   [(set_attr_alternative "length"
 			 [(const_int 4)
 			  (if_then_else (eq_attr "mcu_enhanced" "yes")
@@ -1523,33 +1819,57 @@
 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
 ;; zero extend
 
-(define_insn "zero_extendqihi2"
+(define_insn_and_split "zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
         (zero_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %B0
 	mov %A0,%A1\;clr %B0"
+  "reload_completed"
+  [ (set (subreg:QI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:QI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 1)
+         (const_int 0))]
+  ""
   [(set_attr "length" "1,2")
    (set_attr "cc" "set_n,set_n")])
 
-(define_insn "zero_extendqisi2"
+(define_insn_and_split "zero_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
         (zero_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %B0\;clr %C0\;clr %D0
 	mov %A0,%A1\;clr %B0\;clr %C0\;clr %D0"
+  "reload_completed"
+  [ (set (subreg:QI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:QI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 1)
+         (const_int 0))
+    (set (subreg:QI (match_dup 0) 2)
+         (const_int 0))
+    (set (subreg:QI (match_dup 0) 3)
+         (const_int 0))]
+  ""
   [(set_attr "length" "3,4")
    (set_attr "cc" "set_n,set_n")])
 
-(define_insn "zero_extendhisi2"
+(define_insn_and_split "zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,&r")
         (zero_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
   ""
   "@
 	clr %C0\;clr %D0
 	{mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;clr %D0"
+  "reload_completed"
+  [ (set (subreg:HI (match_operand:HI 0 "register_operand" "=r,r") 0)
+         (match_operand:HI 1 "register_operand" "0,*r"))
+    (set (subreg:QI (match_dup 0) 2)
+         (const_int 0))
+    (set (subreg:QI (match_dup 0) 3)
+         (const_int 0))]
+  ""
   [(set_attr_alternative "length"
 			 [(const_int 2)
 			  (if_then_else (eq_attr "mcu_enhanced" "yes")
@@ -2176,7 +2496,8 @@
 
 ;; Table made from "rjmp" instructions for <=8K devices.
 (define_insn "*tablejump_rjmp"
-  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] 1))
+  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] 
+                        UNSP_READ_PMEM))
    (use (label_ref (match_operand 1 "" "")))
    (clobber (match_dup 0))]
   "!AVR_MEGA"
@@ -2197,7 +2518,8 @@
    (set_attr "cc" "clobber")])
 
 (define_insn "*tablejump_enh"
-  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
+  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 
+                        UNSP_READ_PMEM))
    (use (label_ref (match_operand 1 "" "")))
    (clobber (match_dup 0))]
   "AVR_MEGA && AVR_ENHANCED"
@@ -2211,7 +2533,8 @@
    (set_attr "cc" "clobber")])
 
 (define_insn "*tablejump"
-  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
+  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 
+                        UNSP_READ_PMEM))
    (use (label_ref (match_operand 1 "" "")))
    (clobber (match_dup 0))]
   "AVR_MEGA"
@@ -2244,7 +2567,7 @@
    (set (match_dup 6)
 	(plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
 
-   (parallel [(set (pc) (unspec:HI [(match_dup 6)] 1))
+   (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSP_READ_PMEM))
 	      (use (label_ref (match_dup 3)))
 	      (clobber (match_dup 6))])]
   ""

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