aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arm/thumb1.md19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c14
6 files changed, 72 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 76456542..2d22cde 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-06-19 Terry Guo <terry.guo@arm.com>
+
+ * config/arm/thumb1.md (define_split): Split 64bit constant in earlier
+ stage.
+
2014-06-18 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.h (FIXED_REGISTERS): Update comment.
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 379e14c..c044fd5 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -633,6 +633,25 @@
(set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
(set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
+; Split the load of 64-bit constant into two loads for high and low 32-bit parts respectively
+; to see if we can load them in fewer instructions or fewer cycles.
+; For the small 64-bit integer constants that satisfy constraint J, the instruction pattern
+; thumb1_movdi_insn has a better way to handle them.
+(define_split
+ [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
+ (match_operand:ANY64 1 "const_double_operand" ""))]
+ "TARGET_THUMB1 && reload_completed && !satisfies_constraint_J (operands[1])"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (match_dup 3))]
+ "
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
+ operands[1]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ "
+)
+
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "const_int_operand" ""))]
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2d04521..5138e5a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-19 Terry Guo <terry.guo@arm.com>
+
+ * gcc.target/arm/thumb1-load-64bit-constant-1.c: New test.
+ * gcc.target/arm/thumb1-load-64bit-constant-2.c: Ditto.
+ * gcc.target/arm/thumb1-load-64bit-constant-3.c: Ditto.
+
2014-06-19 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/coarray/collectives_2.f90: Extend
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c
new file mode 100644
index 0000000..9537aaf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-1.c
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+/* { dg-skip-if "" { ! { arm_thumb1 } } } */
+
+extern long long madd (long long a, long long b);
+
+long long
+foo ()
+{
+ return madd (0x0000000100000001LL, 0x0000011100000001LL);
+}
+
+/* { dg-final { scan-assembler-not "ldr" } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c
new file mode 100644
index 0000000..836682b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-2.c
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { ! { arm_thumb1 } } } */
+
+extern long long madd (long long a);
+
+long long
+foo ()
+{
+ return madd (0x0000000100000001LL);
+}
+
+/* { dg-final { scan-assembler-not "ldr" } } */
diff --git a/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c
new file mode 100644
index 0000000..cf4d0be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb1-load-64bit-constant-3.c
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+/* { dg-skip-if "" { ! { arm_thumb1 } } } */
+
+long long
+foo (int len)
+{
+ return (long long) (((long long) 1 << len) - 1);
+}
+
+/* { dg-final { scan-assembler-not "ldr" } } */
+/* { dg-final { scan-assembler-times "neg" 1 } } */
+