This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch ARM] GCC 4.4 branch . Fix out of range branches for Thumb2.
- From: Ramana Radhakrishnan <ramana dot radhakrishnan at arm dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: rearnsha at arm dot com
- Date: Wed, 24 Feb 2010 11:55:17 +0000
- Subject: [Patch ARM] GCC 4.4 branch . Fix out of range branches for Thumb2.
- Reply-to: ramana dot radhakrishnan at arm dot com
Hi,
This patch is essentially a backport of Mark's patch on trunk that fixes
out of range branches in Thumb2.
http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00636.html
I've added a testcase for this and regression tested by bootstrapping
gcc 4.4 in Thumb2 mode.
Ok to backport to the branch and add the testcase to trunk ?
cheers
Ramana
2010-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Backport from trunk
2009-07-10 Mark Mitchell <mark@codesourcery.com>
* config/arm/thumb2.md (thumb2_cbz): Correct computation of
length attribute.
(thumb2_cbnz): Likewise.
2010-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* gcc.target/arm/thumb2-cbnz.c: New test.
Index: config/arm/thumb2.md
===================================================================
--- config/arm/thumb2.md (revision 157011)
+++ config/arm/thumb2.md (working copy)
@@ -1171,7 +1171,7 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"*
- if (get_attr_length (insn) == 2 && which_alternative == 0)
+ if (get_attr_length (insn) == 2)
return \"cbz\\t%0, %l1\";
else
return \"cmp\\t%0, #0\;beq\\t%l1\";
@@ -1179,7 +1179,8 @@
[(set (attr "length")
(if_then_else
(and (ge (minus (match_dup 1) (pc)) (const_int 2))
- (le (minus (match_dup 1) (pc)) (const_int 128)))
+ (le (minus (match_dup 1) (pc)) (const_int 128))
+ (eq (symbol_ref "which_alternative") (const_int 0)))
(const_int 2)
(const_int 8)))]
)
@@ -1193,7 +1194,7 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB2"
"*
- if (get_attr_length (insn) == 2 && which_alternative == 0)
+ if (get_attr_length (insn) == 2)
return \"cbnz\\t%0, %l1\";
else
return \"cmp\\t%0, #0\;bne\\t%l1\";
@@ -1201,7 +1202,8 @@
[(set (attr "length")
(if_then_else
(and (ge (minus (match_dup 1) (pc)) (const_int 2))
- (le (minus (match_dup 1) (pc)) (const_int 128)))
+ (le (minus (match_dup 1) (pc)) (const_int 128))
+ (eq (symbol_ref "which_alternative")(const_int 0)))
(const_int 2)
(const_int 8)))]
)
--- /dev/null 2010-02-22 14:02:29.065048001 +0000
+++ ./testsuite/gcc.target/arm/thumb2-cbnz.c 2010-02-24 11:51:31.000000000 +0000
@@ -0,0 +1,110 @@
+/* { dg-do assemble } */
+/* { dg-options "-O1 -mthumb -march=armv7-a" } */
+
+typedef short int int16_t;
+typedef unsigned char uint8_t;
+struct component
+{
+ float *Q_table;
+};
+static inline unsigned char descale_and_clamp(int x, int shift)
+{
+ x += (1UL<<(shift-1));
+ if (x<0)
+ x = (x >> shift) | ((~(0UL)) << (32-(shift)));
+ x >>= shift;
+ x += 128;
+ if (x>255)
+ return 255;
+ else if (x<0)
+ return 0;
+ return x;
+}
+void
+tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
+{
+ float tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ float tmp10, tmp11, tmp12, tmp13;
+ float z5, z10, z11, z12, z13;
+ int16_t *inptr;
+ float *quantptr;
+ float *wsptr;
+ uint8_t *outptr;
+ int ctr;
+ float workspace[(8*8)];
+ quantptr = compptr->Q_table;
+ wsptr = workspace;
+ for (ctr = 8; ctr > 0; ctr--) {
+ if (inptr[8*1] == 0 && inptr[8*2] == 0 &&
+ inptr[8*3] == 0 && inptr[8*4] == 0 &&
+ inptr[8*5] == 0 && inptr[8*6] == 0 &&
+ inptr[8*7] == 0) {
+ float dcval = (((float) (inptr[8*0])) * (quantptr[8*0]));
+ wsptr[8*0] = dcval;
+ wsptr[8*1] = dcval;
+ wsptr[8*2] = dcval;
+ wsptr[8*3] = dcval;
+ wsptr[8*4] = dcval;
+ wsptr[8*5] = dcval;
+ wsptr[8*6] = dcval;
+ wsptr[8*7] = dcval;
+ inptr++;
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+ tmp0 = (((float) (inptr[8*0])) * (quantptr[8*0]));
+ tmp1 = (((float) (inptr[8*2])) * (quantptr[8*2]));
+ tmp2 = (((float) (inptr[8*4])) * (quantptr[8*4]));
+ tmp3 = (((float) (inptr[8*6])) * (quantptr[8*6]));
+ tmp10 = tmp0 + tmp2;
+ tmp11 = tmp0 - tmp2;
+ tmp13 = tmp1 + tmp3;
+ tmp12 = (tmp1 - tmp3) * ((float) 1.414213562) - tmp13;
+ tmp0 = tmp10 + tmp13;
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+ tmp4 = (((float) (inptr[8*1])) * (quantptr[8*1]));
+ tmp5 = (((float) (inptr[8*3])) * (quantptr[8*3]));
+ tmp6 = (((float) (inptr[8*5])) * (quantptr[8*5]));
+ tmp7 = (((float) (inptr[8*7])) * (quantptr[8*7]));
+ z13 = tmp6 + tmp5;
+ z10 = tmp6 - tmp5;
+ z11 = tmp4 + tmp7;
+ z12 = tmp4 - tmp7;
+ tmp7 = z11 + z13;
+ tmp11 = (z11 - z13) * ((float) 1.414213562);
+ z5 = (z10 + z12) * ((float) 1.847759065);
+ tmp10 = ((float) 1.082392200) * z12 - z5;
+ tmp12 = ((float) -2.613125930) * z10 + z5;
+ tmp6 = tmp12 - tmp7;
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+ wsptr[8*0] = tmp0 + tmp7;
+ wsptr[8*7] = tmp0 - tmp7;
+ wsptr[8*1] = tmp1 + tmp6;
+ wsptr[8*2] = tmp2 + tmp5;
+ wsptr[8*5] = tmp2 - tmp5;
+ wsptr[8*4] = tmp3 + tmp4;
+ wsptr[8*3] = tmp3 - tmp4;
+ inptr++;
+ quantptr++;
+ wsptr++;
+ }
+ for (ctr = 0; ctr < 8; ctr++) {
+ tmp11 = wsptr[0] - wsptr[4];
+ tmp12 = (wsptr[2] - wsptr[6]) * ((float) 1.414213562) - tmp13;
+ tmp0 = tmp10 + tmp13;
+ tmp1 = tmp11 + tmp12;
+ z10 = wsptr[5] - wsptr[3];
+ tmp12 = ((float) -2.613125930) * z10 + z5;
+ tmp6 = tmp12 - tmp7;
+ outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3);
+ outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3);
+ outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3);
+ outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3);
+ outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3);
+ outptr += stride;
+ }
+}