summaryrefslogtreecommitdiffstats
path: root/patches/gcc-4.7.2/0050-Backport-PR-target-55981-from-mainline.patch
blob: 87058aca82a3904d21697b3465ae6f9f94e2916a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
From: Uros Bizjak <ubizjak@gmail.com>
Date: Thu, 17 Jan 2013 22:51:00 +0000
Subject: [PATCH] Backport PR target/55981 from mainline

	Backport from mainline
	2012-01-17  Uros Bizjak  <ubizjak@gmail.com>

	PR target/55981
	* config/i386/sync.md (atomic_store<mode>): Generate SWImode
	store through atomic_store<mode>_1.
	(atomic_store<mode>_1): Macroize insn using SWI mode iterator.

testsuite/ChangeLog:

	Backport from mainline
	2012-01-17  Uros Bizjak  <ubizjak@gmail.com>

	PR target/55981
	* gcc.target/pr55981.c: New test.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
 gcc/ChangeLog                      |   10 +++++++
 gcc/config/i386/sync.md            |   13 +++++++--
 gcc/testsuite/ChangeLog            |    8 ++++++
 gcc/testsuite/gcc.target/pr55981.c |   54 ++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/pr55981.c

diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index ddff1e6..79d3305 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -227,8 +227,9 @@
 	  DONE;
 	}
 
-      /* Otherwise use a normal store.  */
-      emit_move_insn (operands[0], operands[1]);
+      /* Otherwise use a store.  */
+      emit_insn (gen_atomic_store<mode>_1 (operands[0], operands[1],
+					   operands[2]));
     }
   /* ... followed by an MFENCE, if required.  */
   if (model == MEMMODEL_SEQ_CST)
@@ -236,6 +237,14 @@
   DONE;
 })
 
+(define_insn "atomic_store<mode>_1"
+  [(set (match_operand:SWI 0 "memory_operand" "=m")
+	(unspec:SWI [(match_operand:SWI 1 "<nonmemory_operand>" "<r><i>")
+		     (match_operand:SI 2 "const_int_operand")]
+		    UNSPEC_MOVA))]
+  ""
+  "mov{<imodesuffix>}\t{%1, %0|%0, %1}")
+
 (define_insn_and_split "atomic_storedi_fpu"
   [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
 	(unspec:DI [(match_operand:DI 1 "register_operand" "x,m,?r")]
diff --git a/gcc/testsuite/gcc.target/pr55981.c b/gcc/testsuite/gcc.target/pr55981.c
new file mode 100644
index 0000000..36498d6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/pr55981.c
@@ -0,0 +1,54 @@
+/* { dg-do compile  { target { ! { ia32 } } } } */
+/* { dg-options "-O2" } */
+
+volatile int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+
+volatile long long y;
+
+void
+test ()
+{
+  int a_ = a;
+  int b_ = b;
+  int c_ = c;
+  int d_ = d;
+  int e_ = e;
+  int f_ = f;
+  int g_ = g;
+  int h_ = h;
+  int i_ = i;
+  int j_ = j;
+  int k_ = k;
+  int l_ = l;
+  int m_ = m;
+  int n_ = n;
+  int o_ = o;
+  int p_ = p;
+
+  int z;
+
+  for (z = 0; z < 1000; z++)
+    {
+      __atomic_store_n (&y, 0x100000002ll, __ATOMIC_SEQ_CST);
+      __atomic_store_n (&y, 0x300000004ll, __ATOMIC_SEQ_CST);
+    }
+
+  a = a_;
+  b = b_;
+  c = c_;
+  d = d_;
+  e = e_;
+  f = f_;
+  g = g_;
+  h = h_;
+  i = i_;
+  j = j_;
+  k = k_;
+  l = l_;
+  m = m_;
+  n = n_;
+  o = o_;
+  p = p_;
+}
+
+/* { dg-final { scan-assembler-times "movabs" 2 } } */