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] Thumb-2 rotate bugs


The attached patch fixes a couple of bugs in the Thumb-2 rotate instructions.

- The pattern for thumb2_shiftsi3_short was using %I, which doesn't handle 
ROTATE. Changed to use arm_output_shift.
- arm_output_shift wasn't using the correct shift amount after changing ROTATE 
to ROTATERT.

Tested with cross to arm-none-eabi.
Applied to branches/csl/arm-4_1.

Paul

2006-03-30  Paul Brook  <paul@codesourcery.com>

	* gcc/config/arm/arm.c (arm_output_shift): Change set_flags to
	tristate option.  Use modified shift value.
	* gcc/config/arm/arm-protos.h (arm_output_shift): Update prototype.
	* gcc/config/arm/thumb2.md (thumb2_shiftsi3_short): Use
	arm_output_shift.
	* gcc/config/arm/arm.md (arm_shiftsi3, shiftsi3_compare0,
	shiftsi3_compare0_scratch): Adjust arguments to arm_output_shift.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 112511)
+++ gcc/config/arm/arm.c	(working copy)
@@ -16193,26 +16193,29 @@ arm_output_addr_const_extra (FILE *fp, r
   return FALSE;
 }
 
-/* Output assembly for a shift instruction.  SET_FLAGS is TRUE if the
-   instruction modifies the condition codes.  */
+/* Output assembly for a shift instruction.
+   SET_FLAGS determines how the instruction modifies the condition codes.
+   0 - Do not set conditiona codes.
+   1 - Set condition codes.
+   2 - Use smallest instruction.  */
 const char *
-arm_output_shift(rtx * operands, bool set_flags)
+arm_output_shift(rtx * operands, int set_flags)
 {
   char pattern[100];
+  static const char flag_chars[3] = {'.', '?', '!'};
   const char *shift;
   HOST_WIDE_INT val;
   char c;
   
-  if (set_flags)
-    c = '.';
-  else
-    c = '?';
-
+  c = flag_chars[set_flags];
   if (TARGET_UNIFIED_ASM)
     {
       shift = shift_op(operands[3], &val);
       if (shift)
-	sprintf (pattern, "%s%%%c\t%%0, %%1, %%2", shift, c);
+	{
+	  operands[2] = GEN_INT(val);
+	  sprintf (pattern, "%s%%%c\t%%0, %%1, %%2", shift, c);
+	}
       else
 	sprintf (pattern, "mov%%%c\t%%0, %%1", c);
     }
Index: gcc/config/arm/thumb2.md
===================================================================
--- gcc/config/arm/thumb2.md	(revision 112511)
+++ gcc/config/arm/thumb2.md	(working copy)
@@ -1020,7 +1020,7 @@ (define_insn "*thumb2_shiftsi3_short"
 	  (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_THUMB2 && reload_completed"
-  "%I3%!\\t%0, %1, %2"
+  "* return arm_output_shift(operands, 2);"
   [(set_attr "predicable" "yes")
    (set_attr "shift" "1")
    (set_attr "length" "2")
Index: gcc/config/arm/arm-protos.h
===================================================================
--- gcc/config/arm/arm-protos.h	(revision 112511)
+++ gcc/config/arm/arm-protos.h	(working copy)
@@ -125,7 +125,7 @@ extern const char * arm_output_load_gr (
 extern const char *vfp_output_fstmx (rtx *);
 extern void arm_set_return_address (rtx, rtx);
 extern int arm_eliminable_register (rtx);
-extern const char *arm_output_shift(rtx *, bool);
+extern const char *arm_output_shift(rtx *, int);
 
 extern bool arm_output_addr_const_extra (FILE *, rtx);
 
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	(revision 112511)
+++ gcc/config/arm/arm.md	(working copy)
@@ -2903,7 +2903,7 @@ (define_insn "*arm_shiftsi3"
 	 [(match_operand:SI 1 "s_register_operand"  "r")
 	  (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
   "TARGET_32BIT"
-  "* return arm_output_shift(operands, false);"
+  "* return arm_output_shift(operands, 0);"
   [(set_attr "predicable" "yes")
    (set_attr "shift" "1")
    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
@@ -2920,7 +2920,7 @@ (define_insn "*shiftsi3_compare0"
    (set (match_operand:SI 0 "s_register_operand" "=r")
 	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
   "TARGET_32BIT"
-  "* return arm_output_shift(operands, true);"
+  "* return arm_output_shift(operands, 1);"
   [(set_attr "conds" "set")
    (set_attr "shift" "1")
    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
@@ -2936,7 +2936,7 @@ (define_insn "*shiftsi3_compare0_scratch
 			 (const_int 0)))
    (clobber (match_scratch:SI 0 "=r"))]
   "TARGET_32BIT"
-  "* return arm_output_shift(operands, true);"
+  "* return arm_output_shift(operands, 1);"
   [(set_attr "conds" "set")
    (set_attr "shift" "1")]
 )

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