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]

[csl-arm-branch] Add sign/zero extend instructions.


The attached patch adds patterns for the armv6 sign/zero extend instructions, 
including the extend and add insns.
It currently only implements the unrotated variants.

Tested with cross-compiler to arm-none-elf/mcpu=arm1136js.

Ok?

Paul

2003-12-23  Paul Brook  <paul@codesourcery.com>

	* config/arm/arm.c (arm_arch6j): New variable.
	(arm_override_options): Set it.
	(arm_emit_extendsi): New function.
	* config/arm/arm-protos.h (arm_emit_extendsi): Add prototype.
	* config/arm/arm.h (arm_arch6j): Declare.
	* config/arm/arm.md: Add sign/zero extend insns.
Index: gcc/config/arm/arm-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.60.4.3
diff -u -p -r1.60.4.3 arm-protos.h
--- gcc/config/arm/arm-protos.h	23 Dec 2003 22:08:30 -0000	1.60.4.3
+++ gcc/config/arm/arm-protos.h	23 Dec 2003 23:16:03 -0000
@@ -140,6 +140,7 @@ extern void arm_final_prescan_insn (rtx)
 extern int arm_go_if_legitimate_address (enum machine_mode, rtx);
 extern int arm_debugger_arg_offset (int, rtx);
 extern int arm_is_longcall_p (rtx, int, int);
+extern int arm_emit_extendsi (enum rtx_code, rtx, rtx);
 extern int    arm_emit_vector_const (FILE *, rtx);
 extern const char * arm_output_load_gr (rtx *);
 
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.303.2.8
diff -u -p -r1.303.2.8 arm.c
--- gcc/config/arm/arm.c	23 Dec 2003 23:03:27 -0000	1.303.2.8
+++ gcc/config/arm/arm.c	23 Dec 2003 23:16:06 -0000
@@ -325,6 +325,9 @@ int arm_arch5 = 0;
 /* Nonzero if this chip supports the ARM Architecture 5E extensions.  */
 int arm_arch5e = 0;
 
+/* Nonzero if this chip supports the ARM Architecture 6 extensions.  */
+int arm_arch6j = 0;
+
 /* Nonzero if this chip can benefit from load scheduling.  */
 int arm_ld_sched = 0;
 
@@ -779,6 +782,7 @@ arm_override_options (void)
   arm_arch4         = (insn_flags & FL_ARCH4) != 0;
   arm_arch5         = (insn_flags & FL_ARCH5) != 0;
   arm_arch5e        = (insn_flags & FL_ARCH5E) != 0;
+  arm_arch6j	    = (insn_flags & FL_ARCH6J) != 0;
   arm_arch_xscale     = (insn_flags & FL_XSCALE) != 0;
 
   arm_ld_sched      = (tune_flags & FL_LDSCHED) != 0;
@@ -13270,6 +13274,40 @@ arm_output_mi_thunk (FILE *file, tree th
       fputc ('\n', file);
     }
 }
+
+/* Emit RTL for a sign/zero extend insn.  */
+int
+arm_emit_extendsi (enum rtx_code code, rtx op0, rtx op1)
+{
+  rtx tmp;
+  rtx *p;
+
+  if (GET_CODE (op1) != SUBREG
+      || !arm_arch6j)
+    return 0;
+
+  p = &XEXP (op1, 0);
+  if (GET_CODE (*p) != REG)
+    return 0;
+
+  if (XINT (op1, 1) != 0)
+    return 0;
+
+  /* Put the low part of multiword regs into an SImode reg so we only
+     have to deal with subregs of SImode regs.  */
+  if (GET_MODE (*p) != SImode)
+    {
+      tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_rtx_SET (VOIDmode, tmp,
+		 gen_lowpart (SImode, *p)));
+      *p = tmp;
+    }
+
+  emit_insn (gen_rtx_SET (VOIDmode, op0,
+	     gen_rtx_fmt_e (code, SImode, op1)));
+  return 1;
+}
+
 
 int
 arm_emit_vector_const (FILE *file, rtx x)
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.210.2.4
diff -u -p -r1.210.2.4 arm.h
--- gcc/config/arm/arm.h	23 Dec 2003 22:08:30 -0000	1.210.2.4
+++ gcc/config/arm/arm.h	23 Dec 2003 23:16:07 -0000
@@ -692,6 +692,9 @@ extern int arm_arch5;
 
 /* Nonzero if this chip supports the ARM Architecture 5E extensions */
 extern int arm_arch5e;
+
+/* Nonzero if this chip supports the ARM Architecture 6 extensions */
+extern int arm_arch6j;
 
 /* Nonzero if this chip can benefit from load scheduling.  */
 extern int arm_ld_sched;
Index: gcc/config/arm/arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.145.2.7
diff -u -p -r1.145.2.7 arm.md
--- gcc/config/arm/arm.md	23 Dec 2003 22:08:31 -0000	1.145.2.7
+++ gcc/config/arm/arm.md	23 Dec 2003 23:16:08 -0000
@@ -3132,63 +3132,47 @@
   "TARGET_EITHER"
   "
   {
-    if (TARGET_ARM)
+    if ((TARGET_THUMB || arm_arch4) && GET_CODE (operands[1]) == MEM)
       {
-        if (arm_arch4 && GET_CODE (operands[1]) == MEM)
-          {
-           /* Note: We do not have to worry about TARGET_MMU_TRAPS
-	      here because the insn below will generate an LDRH instruction
-	      rather than an LDR instruction, so we cannot get an unaligned
-	      word access.  */
-            emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-			            gen_rtx_ZERO_EXTEND (SImode,
-							 operands[1])));
-            DONE;
-          }
-        if (TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
-          {
-            emit_insn (gen_movhi_bytes (operands[0], operands[1]));
-            DONE;
-          }
-        if (!s_register_operand (operands[1], HImode))
-          operands[1] = copy_to_mode_reg (HImode, operands[1]);
-        operands[1] = gen_lowpart (SImode, operands[1]);
-        operands[2] = gen_reg_rtx (SImode);
-      }
-    else /* TARGET_THUMB */
-      {
-        if (GET_CODE (operands[1]) == MEM)
-	  {
-	    rtx tmp;
-
-	    tmp = gen_rtx_ZERO_EXTEND (SImode, operands[1]);
-	    tmp = gen_rtx_SET (VOIDmode, operands[0], tmp);
-	    emit_insn (tmp);
-	  }
-	else
-	  {
-	    rtx ops[3];
-	    
-	    if (!s_register_operand (operands[1], HImode))
-	      operands[1] = copy_to_mode_reg (HImode, operands[1]);
-	    operands[1] = gen_lowpart (SImode, operands[1]);
-	    operands[2] = gen_reg_rtx (SImode);
-	    
-	    ops[0] = operands[2];
-	    ops[1] = operands[1];
-	    ops[2] = GEN_INT (16);
+       /* Note: We do not have to worry about TARGET_MMU_TRAPS
+	  here because the insn below will generate an LDRH instruction
+	  rather than an LDR instruction, so we cannot get an unaligned
+	  word access.  */
+	emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+				gen_rtx_ZERO_EXTEND (SImode,
+						     operands[1])));
+	DONE;
+      }
+    if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM)
+      {
+	emit_insn (gen_movhi_bytes (operands[0], operands[1]));
+	DONE;
+      }
+    if (arm_emit_extendsi (ZERO_EXTEND, operands[0], operands[1]))
+      DONE;
+    if (!s_register_operand (operands[1], HImode))
+      operands[1] = copy_to_mode_reg (HImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+    operands[2] = gen_reg_rtx (SImode);
 	    
-	    emit_insn (gen_rtx_SET (VOIDmode, ops[0],
-				    gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
+    if (TARGET_THUMB)
+      {
+	rtx ops[3];
+	
+	ops[0] = operands[2];
+	ops[1] = operands[1];
+	ops[2] = GEN_INT (16);
+	
+	emit_insn (gen_rtx_SET (VOIDmode, ops[0],
+				gen_rtx_ASHIFT (SImode, ops[1], ops[2])));
+
+	ops[0] = operands[0];
+	ops[1] = operands[2];
+	ops[2] = GEN_INT (16);
 
-	    ops[0] = operands[0];
-	    ops[1] = operands[2];
-	    ops[2] = GEN_INT (16);
-
-	    emit_insn (gen_rtx_SET (VOIDmode, ops[0],
-				    gen_rtx_LSHIFTRT (SImode, ops[1],
-						      ops[2])));
-	  }
+	emit_insn (gen_rtx_SET (VOIDmode, ops[0],
+				gen_rtx_LSHIFTRT (SImode, ops[1],
+						  ops[2])));
 	DONE; 
       }
   }"
@@ -3247,6 +3231,23 @@
    (set_attr "neg_pool_range" "244")]
 )
 
+(define_insn "*arm_zero_extendhisi2_reg"
+  [(set (match_operand:SI		  0 "s_register_operand" "=r")
+	(zero_extend:SI (subreg:HI
+	    (match_operand:SI 1 "s_register_operand" "r") 0)))]
+  "TARGET_EITHER && arm_arch6j"
+  "uxth%?\\t%0, %1"
+)
+
+(define_insn "*arm_zero_extendhisi2addsi"
+  [(set (match_operand:SI	    0 "s_register_operand" "=r")
+	(plus:SI (zero_extend:SI (subreg:HI
+		  (match_operand:SI 1 "s_register_operand" "r") 0))
+		(match_operand:SI   2 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6j"
+  "uxtah%?\\t%0, %2, %1"
+)
+
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")
 	(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
@@ -3282,6 +3283,8 @@
 	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
   "TARGET_EITHER"
   "
+  if (arm_emit_extendsi (ZERO_EXTEND, operands[0], operands[1]))
+    DONE;
   if (GET_CODE (operands[1]) != MEM)
     {
       if (TARGET_ARM)
@@ -3338,6 +3341,23 @@
    (set_attr "neg_pool_range" "4084")]
 )
 
+(define_insn "*arm_zero_extendqisi2_reg"
+  [(set (match_operand:SI		  0 "s_register_operand" "=r")
+	(zero_extend:SI (subreg:QI
+	    (match_operand:SI 1 "s_register_operand" "r") 0)))]
+  "TARGET_EITHER && arm_arch6j"
+  "uxtb%?\\t%0, %1"
+)
+
+(define_insn "*arm_zero_extendqisi2addsi"
+  [(set (match_operand:SI	    0 "s_register_operand" "=r")
+	(plus:SI (zero_extend:SI (subreg:QI
+		  (match_operand:SI 1 "s_register_operand" "r") 0))
+		(match_operand:SI   2 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6j"
+  "uxtab%?\\t%0, %2, %1"
+)
+
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")
 	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
@@ -3383,6 +3403,8 @@
         emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
         DONE;
       }
+      if (arm_emit_extendsi (SIGN_EXTEND, operands[0], operands[1]))
+	DONE;
     if (!s_register_operand (operands[1], HImode))
       operands[1] = copy_to_mode_reg (HImode, operands[1]);
     operands[1] = gen_lowpart (SImode, operands[1]);
@@ -3517,6 +3539,23 @@
    (set_attr "neg_pool_range" "244")]
 )
 
+(define_insn "*arm_extendhisi2_reg"
+  [(set (match_operand:SI		  0 "s_register_operand" "=r")
+	(sign_extend:SI (subreg:HI
+	    (match_operand:SI 1 "s_register_operand" "r") 0)))]
+  "TARGET_EITHER && arm_arch6j"
+  "sxth%?\\t%0, %1"
+)
+
+(define_insn "*arm_extendhisi2addsi"
+  [(set (match_operand:SI	    0 "s_register_operand" "=r")
+	(plus:SI (sign_extend:SI (subreg:HI
+		  (match_operand:SI 1 "s_register_operand" "r") 0))
+		(match_operand:SI   2 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6j"
+  "sxtah%?\\t%0, %2, %1"
+)
+
 (define_split
   [(set (match_operand:SI                 0 "s_register_operand" "")
 	(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")))
@@ -3641,6 +3680,8 @@
 			        gen_rtx_SIGN_EXTEND (SImode, operands[1])));
         DONE;
       }
+    if (arm_emit_extendsi (SIGN_EXTEND, operands[0], operands[1]))
+      DONE;
     if (!s_register_operand (operands[1], QImode))
       operands[1] = copy_to_mode_reg (QImode, operands[1]);
     operands[1] = gen_lowpart (SImode, operands[1]);
@@ -3686,6 +3727,23 @@
    (set_attr "length" "8")
    (set_attr "pool_range" "256")
    (set_attr "neg_pool_range" "244")]
+)
+
+(define_insn "*arm_extendqisi2_reg"
+  [(set (match_operand:SI		  0 "s_register_operand" "=r")
+	(sign_extend:SI (subreg:QI
+	    (match_operand:SI 1 "s_register_operand" "r") 0)))]
+  "TARGET_EITHER && arm_arch6j"
+  "sxtb%?\\t%0, %1"
+)
+
+(define_insn "*arm_extendqisi2addsi"
+  [(set (match_operand:SI	    0 "s_register_operand" "=r")
+	(plus:SI (sign_extend:SI (subreg:QI
+		  (match_operand:SI 1 "s_register_operand" "r") 0))
+		(match_operand:SI   2 "s_register_operand" "r")))]
+  "TARGET_ARM && arm_arch6j"
+  "sxtab%?\\t%0, %2, %1"
 )
 
 (define_split

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