Hi there,
Attached patch intends to fix a pattern that is found still non-UAL when do
gcc thumb-1 bootstrap. A test case is reduced and attached. Tested with gcc
regression test on pre-v6 thumb1 and v6 thumb1. No regression. Multilib can
be built for both of them.
Is it OK to trunk?
BR,
Terry
gcc/ChangeLog:
2014-11-14 Terry Guo <terry....@arm.com>
* config/arm/thumb1.md (*addsi3_cbranch_scratch): Updated to UAL
format.
gcc/testsuite/ChangeLog:
2014-11-14 Terry Guo <terry....@arm.com>
* gcc.target/arm/thumb1-ual-1.c: New test.
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 3d6f80b..ddedc39 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -1420,13 +1420,13 @@
if (INTVAL (operands[2]) < 0)
output_asm_insn (\"subs\t%0, %1, %2\", operands);
else
- output_asm_insn (\"add\t%0, %1, %2\", operands);
+ output_asm_insn (\"adds\t%0, %1, %2\", operands);
break;
case 3:
if (INTVAL (operands[2]) < 0)
output_asm_insn (\"subs\t%0, %0, %2\", operands);
else
- output_asm_insn (\"add\t%0, %0, %2\", operands);
+ output_asm_insn (\"adds\t%0, %0, %2\", operands);
break;
}
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-ual-1.c
b/gcc/testsuite/gcc.target/arm/thumb1-ual-1.c
new file mode 100644
index 0000000..a2e439c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb1-ual-1.c
@@ -0,0 +1,87 @@
+/* Test Thumb1 insn pattern addsi3_cbranch_scratch. */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { ! { arm_thumb1 } } } */
+
+struct real_value {
+
+ unsigned int cl : 2;
+ unsigned int decimal : 1;
+ unsigned int sign : 1;
+ unsigned int signalling : 1;
+ unsigned int canonical : 1;
+ unsigned int uexp : (32 - 6);
+ unsigned long sig[((128 + (8 * 4)) / (8 * 4))];
+};
+
+enum real_value_class {
+ rvc_zero,
+ rvc_normal,
+ rvc_inf,
+ rvc_nan
+};
+
+extern void exit(int);
+extern int foo(long long *, int, int);
+
+int
+real_to_integer (const struct real_value *r, int *fail, int precision)
+{
+ long long val[2 * (((64*(8)) + 64) / 64)];
+ int exp;
+ int words, w;
+ int result;
+
+ switch (r->cl)
+ {
+ case rvc_zero:
+ underflow:
+ return 100;
+
+ case rvc_inf:
+ case rvc_nan:
+ overflow:
+ *fail = 1;
+
+ if (r->sign)
+ return 200;
+ else
+ return 300;
+
+ case rvc_normal:
+ if (r->decimal)
+ return 400;
+
+ exp = ((int)((r)->uexp ^ (unsigned int)(1 << ((32 - 6) - 1))) - (1 <<
((32 - 6) - 1)));
+ if (exp <= 0)
+ goto underflow;
+
+
+ if (exp > precision)
+ goto overflow;
+ words = (precision + 64 - 1) / 64;
+ w = words * 64;
+ for (int i = 0; i < words; i++)
+ {
+ int j = ((128 + (8 * 4)) / (8 * 4)) - (words * 2) + (i * 2);
+ if (j < 0)
+ val[i] = 0;
+ else
+ val[i] = r->sig[j];
+ j += 1;
+ if (j >= 0)
+ val[i] |= (unsigned long long) r->sig[j] << (8 * 4);
+ }
+
+
+ result = foo(val, words, w);
+
+ if (r->sign)
+ return -result;
+ else
+ return result;
+
+ default:
+ exit(2);
+ }
+}
+