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: take 3: implement HI/SI logic operations and sign/zero extension by define_insn_and_split


Hi,

in this third version of the splitting patch, I now have removed a bug in the 
xor-Patterns that showed up in rare occasions for bitfield operations (they 
used to generate nested subreg expressions). I also have cleaned up the 
patterns a bit so that they now are more compliant with the gcc coding style.

Yours,

Björn


2005-05-05 ?Bjoern Haase ?<bjoern.m.haase@web.de>

????????* config/avr/avr.md: 
????????add define_constants 
????????(UNSP_STRLENHI): add define_constant
????????(UNSP_READ_PMEM): add define_constant
????????(UNSP_GEN_SIGN): add define_constant
????????(*generate_extension_byte): add
? ? ? ? (strlenhi): use UNSP_STRLENHI
? ? ? ? (andhi3): replace define_insn by define_insn_and_split 
????????(andsi3): Likewise.
????????(iorhi3): Likewise.
????????(*iorhi3_clobber): Likewise.
????????(iorsi3): Likewise. 
????????(*iorsi3_clobber): Likewise.
????????(xorhi3): replace define_insn by define_expand
????????(xorsi3): Likewise.
????????(extendqihi2): replace define_insn by define_insn_and_split
????????(extendqisi2): Likewise.
????????(extendhisi2): Likewise.
????????(zero_extendqihi2): Likewise.
????????(zero_extendqisi2): Likewise.
????????(zero_extendhisi2): Likewise.
????????(*tablejump_rjmp): use UNSP_READ_PMEM
????????(*tablejump_enh): Likewise.
????????(*tablejump): Likewise.
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	5 May 2005 22:01:11 -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,127 @@
   "@
 	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)"
+  [(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 +1320,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)" 
+  [(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 +1394,40 @@
   [(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")])
+  "
+   if ( (!REG_P (operands[0])) || (!REG_P (operands[2])))
+     FAIL;
+  "
+)
 
-(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")])
-
+  "
+   if ( (!REG_P (operands[0])) || (!REG_P (operands[2])))
+     FAIL;
+  "
+)
+   
 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
 ;; arithmetic shift left
 
@@ -1486,33 +1755,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 +1828,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 +2505,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 +2527,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 +2542,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 +2576,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]