annotate gcc/config/arm/sync.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 ;; Machine description for ARM processor synchronization primitives.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 ;; Copyright (C) 2010-2018 Free Software Foundation, Inc.
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 ;; Written by Marcus Shawcroft (marcus.shawcroft@arm.com)
111
kono
parents: 68
diff changeset
4 ;; 64bit Atomics by Dave Gilbert (david.gilbert@linaro.org)
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 ;;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 ;; This file is part of GCC.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 ;;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 ;; GCC is free software; you can redistribute it and/or modify it
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 ;; under the terms of the GNU General Public License as published by
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 ;; the Free Software Foundation; either version 3, or (at your option)
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 ;; any later version.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ;;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ;; GCC is distributed in the hope that it will be useful, but
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 ;; General Public License for more details.
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 ;;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 ;; You should have received a copy of the GNU General Public License
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 ;; along with GCC; see the file COPYING3. If not see
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 ;; <http://www.gnu.org/licenses/>. */
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
111
kono
parents: 68
diff changeset
22 (define_mode_attr sync_predtab
kono
parents: 68
diff changeset
23 [(QI "TARGET_HAVE_LDREXBH && TARGET_HAVE_MEMORY_BARRIER")
kono
parents: 68
diff changeset
24 (HI "TARGET_HAVE_LDREXBH && TARGET_HAVE_MEMORY_BARRIER")
kono
parents: 68
diff changeset
25 (SI "TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER")
kono
parents: 68
diff changeset
26 (DI "TARGET_HAVE_LDREXD && ARM_DOUBLEWORD_ALIGN
kono
parents: 68
diff changeset
27 && TARGET_HAVE_MEMORY_BARRIER")])
kono
parents: 68
diff changeset
28
kono
parents: 68
diff changeset
29 (define_code_iterator syncop [plus minus ior xor and])
kono
parents: 68
diff changeset
30
kono
parents: 68
diff changeset
31 (define_code_attr sync_optab
kono
parents: 68
diff changeset
32 [(ior "or") (xor "xor") (and "and") (plus "add") (minus "sub")])
kono
parents: 68
diff changeset
33
kono
parents: 68
diff changeset
34 (define_mode_attr sync_sfx
kono
parents: 68
diff changeset
35 [(QI "b") (HI "h") (SI "") (DI "d")])
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 (define_expand "memory_barrier"
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 [(set (match_dup 0)
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 "TARGET_HAVE_MEMORY_BARRIER"
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 {
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 MEM_VOLATILE_P (operands[0]) = 1;
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 })
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 (define_insn "*memory_barrier"
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 [(set (match_operand:BLK 0 "" "")
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 "TARGET_HAVE_MEMORY_BARRIER"
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 {
111
kono
parents: 68
diff changeset
51 if (TARGET_HAVE_DMB)
kono
parents: 68
diff changeset
52 {
kono
parents: 68
diff changeset
53 return "dmb\\tish";
kono
parents: 68
diff changeset
54 }
kono
parents: 68
diff changeset
55
kono
parents: 68
diff changeset
56 if (TARGET_HAVE_DMB_MCR)
kono
parents: 68
diff changeset
57 return "mcr\\tp15, 0, r0, c7, c10, 5";
kono
parents: 68
diff changeset
58
kono
parents: 68
diff changeset
59 gcc_unreachable ();
68
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 }
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 [(set_attr "length" "4")
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 (set_attr "conds" "unconditional")
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 (set_attr "predicable" "no")])
561a7518be6b update gcc-4.6
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
111
kono
parents: 68
diff changeset
65 (define_insn "atomic_load<mode>"
kono
parents: 68
diff changeset
66 [(set (match_operand:QHSI 0 "register_operand" "=r,r,l")
kono
parents: 68
diff changeset
67 (unspec_volatile:QHSI
kono
parents: 68
diff changeset
68 [(match_operand:QHSI 1 "arm_sync_memory_operand" "Q,Q,Q")
kono
parents: 68
diff changeset
69 (match_operand:SI 2 "const_int_operand" "n,Pf,n")] ;; model
kono
parents: 68
diff changeset
70 VUNSPEC_LDA))]
kono
parents: 68
diff changeset
71 "TARGET_HAVE_LDACQ"
kono
parents: 68
diff changeset
72 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 if (aarch_mm_needs_acquire (operands[2]))
111
kono
parents: 68
diff changeset
74 {
kono
parents: 68
diff changeset
75 if (TARGET_THUMB1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 return "lda<sync_sfx>\t%0, %1";
111
kono
parents: 68
diff changeset
77 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 return "lda<sync_sfx>%?\t%0, %1";
111
kono
parents: 68
diff changeset
79 }
kono
parents: 68
diff changeset
80 else
kono
parents: 68
diff changeset
81 {
kono
parents: 68
diff changeset
82 if (TARGET_THUMB1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 return "ldr<sync_sfx>\t%0, %1";
111
kono
parents: 68
diff changeset
84 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 return "ldr<sync_sfx>%?\t%0, %1";
111
kono
parents: 68
diff changeset
86 }
kono
parents: 68
diff changeset
87 }
kono
parents: 68
diff changeset
88 [(set_attr "arch" "32,v8mb,any")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
90
kono
parents: 68
diff changeset
91 (define_insn "atomic_store<mode>"
kono
parents: 68
diff changeset
92 [(set (match_operand:QHSI 0 "memory_operand" "=Q,Q,Q")
kono
parents: 68
diff changeset
93 (unspec_volatile:QHSI
kono
parents: 68
diff changeset
94 [(match_operand:QHSI 1 "general_operand" "r,r,l")
kono
parents: 68
diff changeset
95 (match_operand:SI 2 "const_int_operand" "n,Pf,n")] ;; model
kono
parents: 68
diff changeset
96 VUNSPEC_STL))]
kono
parents: 68
diff changeset
97 "TARGET_HAVE_LDACQ"
kono
parents: 68
diff changeset
98 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 if (aarch_mm_needs_release (operands[2]))
111
kono
parents: 68
diff changeset
100 {
kono
parents: 68
diff changeset
101 if (TARGET_THUMB1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 return "stl<sync_sfx>\t%1, %0";
111
kono
parents: 68
diff changeset
103 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 return "stl<sync_sfx>%?\t%1, %0";
111
kono
parents: 68
diff changeset
105 }
kono
parents: 68
diff changeset
106 else
kono
parents: 68
diff changeset
107 {
kono
parents: 68
diff changeset
108 if (TARGET_THUMB1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 return "str<sync_sfx>\t%1, %0";
111
kono
parents: 68
diff changeset
110 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 return "str<sync_sfx>%?\t%1, %0";
111
kono
parents: 68
diff changeset
112 }
kono
parents: 68
diff changeset
113 }
kono
parents: 68
diff changeset
114 [(set_attr "arch" "32,v8mb,any")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
116
kono
parents: 68
diff changeset
117 ;; An LDRD instruction usable by the atomic_loaddi expander on LPAE targets
kono
parents: 68
diff changeset
118
kono
parents: 68
diff changeset
119 (define_insn "arm_atomic_loaddi2_ldrd"
kono
parents: 68
diff changeset
120 [(set (match_operand:DI 0 "register_operand" "=r")
kono
parents: 68
diff changeset
121 (unspec_volatile:DI
kono
parents: 68
diff changeset
122 [(match_operand:DI 1 "arm_sync_memory_operand" "Q")]
kono
parents: 68
diff changeset
123 VUNSPEC_LDRD_ATOMIC))]
kono
parents: 68
diff changeset
124 "ARM_DOUBLEWORD_ALIGN && TARGET_HAVE_LPAE"
kono
parents: 68
diff changeset
125 "ldrd%?\t%0, %H0, %C1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 [(set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
127
kono
parents: 68
diff changeset
128 ;; There are three ways to expand this depending on the architecture
kono
parents: 68
diff changeset
129 ;; features available. As for the barriers, a load needs a barrier
kono
parents: 68
diff changeset
130 ;; after it on all non-relaxed memory models except when the load
kono
parents: 68
diff changeset
131 ;; has acquire semantics (for ARMv8-A).
kono
parents: 68
diff changeset
132
kono
parents: 68
diff changeset
133 (define_expand "atomic_loaddi"
kono
parents: 68
diff changeset
134 [(match_operand:DI 0 "s_register_operand") ;; val out
kono
parents: 68
diff changeset
135 (match_operand:DI 1 "mem_noofs_operand") ;; memory
kono
parents: 68
diff changeset
136 (match_operand:SI 2 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
137 "(TARGET_HAVE_LDREXD || TARGET_HAVE_LPAE || TARGET_HAVE_LDACQEXD)
kono
parents: 68
diff changeset
138 && ARM_DOUBLEWORD_ALIGN"
kono
parents: 68
diff changeset
139 {
kono
parents: 68
diff changeset
140 memmodel model = memmodel_from_int (INTVAL (operands[2]));
kono
parents: 68
diff changeset
141
kono
parents: 68
diff changeset
142 /* For ARMv8-A we can use an LDAEXD to atomically load two 32-bit registers
kono
parents: 68
diff changeset
143 when acquire or stronger semantics are needed. When the relaxed model is
kono
parents: 68
diff changeset
144 used this can be relaxed to a normal LDRD. */
kono
parents: 68
diff changeset
145 if (TARGET_HAVE_LDACQEXD)
kono
parents: 68
diff changeset
146 {
kono
parents: 68
diff changeset
147 if (is_mm_relaxed (model))
kono
parents: 68
diff changeset
148 emit_insn (gen_arm_atomic_loaddi2_ldrd (operands[0], operands[1]));
kono
parents: 68
diff changeset
149 else
kono
parents: 68
diff changeset
150 emit_insn (gen_arm_load_acquire_exclusivedi (operands[0], operands[1]));
kono
parents: 68
diff changeset
151
kono
parents: 68
diff changeset
152 DONE;
kono
parents: 68
diff changeset
153 }
kono
parents: 68
diff changeset
154
kono
parents: 68
diff changeset
155 /* On LPAE targets LDRD and STRD accesses to 64-bit aligned
kono
parents: 68
diff changeset
156 locations are 64-bit single-copy atomic. We still need barriers in the
kono
parents: 68
diff changeset
157 appropriate places to implement the ordering constraints. */
kono
parents: 68
diff changeset
158 if (TARGET_HAVE_LPAE)
kono
parents: 68
diff changeset
159 emit_insn (gen_arm_atomic_loaddi2_ldrd (operands[0], operands[1]));
kono
parents: 68
diff changeset
160 else
kono
parents: 68
diff changeset
161 emit_insn (gen_arm_load_exclusivedi (operands[0], operands[1]));
kono
parents: 68
diff changeset
162
kono
parents: 68
diff changeset
163
kono
parents: 68
diff changeset
164 /* All non-relaxed models need a barrier after the load when load-acquire
kono
parents: 68
diff changeset
165 instructions are not available. */
kono
parents: 68
diff changeset
166 if (!is_mm_relaxed (model))
kono
parents: 68
diff changeset
167 expand_mem_thread_fence (model);
kono
parents: 68
diff changeset
168
kono
parents: 68
diff changeset
169 DONE;
kono
parents: 68
diff changeset
170 })
kono
parents: 68
diff changeset
171
kono
parents: 68
diff changeset
172 (define_expand "atomic_compare_and_swap<mode>"
kono
parents: 68
diff changeset
173 [(match_operand:SI 0 "s_register_operand" "") ;; bool out
kono
parents: 68
diff changeset
174 (match_operand:QHSD 1 "s_register_operand" "") ;; val out
kono
parents: 68
diff changeset
175 (match_operand:QHSD 2 "mem_noofs_operand" "") ;; memory
kono
parents: 68
diff changeset
176 (match_operand:QHSD 3 "general_operand" "") ;; expected
kono
parents: 68
diff changeset
177 (match_operand:QHSD 4 "s_register_operand" "") ;; desired
kono
parents: 68
diff changeset
178 (match_operand:SI 5 "const_int_operand") ;; is_weak
kono
parents: 68
diff changeset
179 (match_operand:SI 6 "const_int_operand") ;; mod_s
kono
parents: 68
diff changeset
180 (match_operand:SI 7 "const_int_operand")] ;; mod_f
kono
parents: 68
diff changeset
181 "<sync_predtab>"
kono
parents: 68
diff changeset
182 {
kono
parents: 68
diff changeset
183 arm_expand_compare_and_swap (operands);
kono
parents: 68
diff changeset
184 DONE;
kono
parents: 68
diff changeset
185 })
kono
parents: 68
diff changeset
186
kono
parents: 68
diff changeset
187 ;; Constraints of this pattern must be at least as strict as those of the
kono
parents: 68
diff changeset
188 ;; cbranchsi operations in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
189 (define_insn_and_split "atomic_compare_and_swap<CCSI:arch><NARROW:mode>_1"
kono
parents: 68
diff changeset
190 [(set (match_operand:CCSI 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
kono
parents: 68
diff changeset
191 (unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
kono
parents: 68
diff changeset
192 (set (match_operand:SI 1 "s_register_operand" "=&r,&l,&0,&l*h") ;; val out
kono
parents: 68
diff changeset
193 (zero_extend:SI
kono
parents: 68
diff changeset
194 (match_operand:NARROW 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua"))) ;; memory
kono
parents: 68
diff changeset
195 (set (match_dup 2)
kono
parents: 68
diff changeset
196 (unspec_volatile:NARROW
kono
parents: 68
diff changeset
197 [(match_operand:SI 3 "arm_add_operand" "rIL,lIL*h,J,*r") ;; expected
kono
parents: 68
diff changeset
198 (match_operand:NARROW 4 "s_register_operand" "r,r,r,r") ;; desired
kono
parents: 68
diff changeset
199 (match_operand:SI 5 "const_int_operand") ;; is_weak
kono
parents: 68
diff changeset
200 (match_operand:SI 6 "const_int_operand") ;; mod_s
kono
parents: 68
diff changeset
201 (match_operand:SI 7 "const_int_operand")] ;; mod_f
kono
parents: 68
diff changeset
202 VUNSPEC_ATOMIC_CAS))
kono
parents: 68
diff changeset
203 (clobber (match_scratch:SI 8 "=&r,X,X,X"))]
kono
parents: 68
diff changeset
204 "<sync_predtab>"
kono
parents: 68
diff changeset
205 "#"
kono
parents: 68
diff changeset
206 "&& reload_completed"
kono
parents: 68
diff changeset
207 [(const_int 0)]
kono
parents: 68
diff changeset
208 {
kono
parents: 68
diff changeset
209 arm_split_compare_and_swap (operands);
kono
parents: 68
diff changeset
210 DONE;
kono
parents: 68
diff changeset
211 }
kono
parents: 68
diff changeset
212 [(set_attr "arch" "32,v8mb,v8mb,v8mb")])
kono
parents: 68
diff changeset
213
kono
parents: 68
diff changeset
214 (define_mode_attr cas_cmp_operand
kono
parents: 68
diff changeset
215 [(SI "arm_add_operand") (DI "cmpdi_operand")])
kono
parents: 68
diff changeset
216 (define_mode_attr cas_cmp_str
kono
parents: 68
diff changeset
217 [(SI "rIL") (DI "rDi")])
kono
parents: 68
diff changeset
218
kono
parents: 68
diff changeset
219 ;; Constraints of this pattern must be at least as strict as those of the
kono
parents: 68
diff changeset
220 ;; cbranchsi operations in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
221 (define_insn_and_split "atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1"
kono
parents: 68
diff changeset
222 [(set (match_operand:CCSI 0 "cc_register_operand" "=&c,&l,&l,&l") ;; bool out
kono
parents: 68
diff changeset
223 (unspec_volatile:CCSI [(const_int 0)] VUNSPEC_ATOMIC_CAS))
kono
parents: 68
diff changeset
224 (set (match_operand:SIDI 1 "s_register_operand" "=&r,&l,&0,&l*h") ;; val out
kono
parents: 68
diff changeset
225 (match_operand:SIDI 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua")) ;; memory
kono
parents: 68
diff changeset
226 (set (match_dup 2)
kono
parents: 68
diff changeset
227 (unspec_volatile:SIDI
kono
parents: 68
diff changeset
228 [(match_operand:SIDI 3 "<cas_cmp_operand>" "<cas_cmp_str>,lIL*h,J,*r") ;; expect
kono
parents: 68
diff changeset
229 (match_operand:SIDI 4 "s_register_operand" "r,r,r,r") ;; desired
kono
parents: 68
diff changeset
230 (match_operand:SI 5 "const_int_operand") ;; is_weak
kono
parents: 68
diff changeset
231 (match_operand:SI 6 "const_int_operand") ;; mod_s
kono
parents: 68
diff changeset
232 (match_operand:SI 7 "const_int_operand")] ;; mod_f
kono
parents: 68
diff changeset
233 VUNSPEC_ATOMIC_CAS))
kono
parents: 68
diff changeset
234 (clobber (match_scratch:SI 8 "=&r,X,X,X"))]
kono
parents: 68
diff changeset
235 "<sync_predtab>"
kono
parents: 68
diff changeset
236 "#"
kono
parents: 68
diff changeset
237 "&& reload_completed"
kono
parents: 68
diff changeset
238 [(const_int 0)]
kono
parents: 68
diff changeset
239 {
kono
parents: 68
diff changeset
240 arm_split_compare_and_swap (operands);
kono
parents: 68
diff changeset
241 DONE;
kono
parents: 68
diff changeset
242 }
kono
parents: 68
diff changeset
243 [(set_attr "arch" "32,v8mb,v8mb,v8mb")])
kono
parents: 68
diff changeset
244
kono
parents: 68
diff changeset
245 (define_insn_and_split "atomic_exchange<mode>"
kono
parents: 68
diff changeset
246 [(set (match_operand:QHSD 0 "s_register_operand" "=&r,&r") ;; output
kono
parents: 68
diff changeset
247 (match_operand:QHSD 1 "mem_noofs_operand" "+Ua,Ua")) ;; memory
kono
parents: 68
diff changeset
248 (set (match_dup 1)
kono
parents: 68
diff changeset
249 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
250 [(match_operand:QHSD 2 "s_register_operand" "r,r") ;; input
kono
parents: 68
diff changeset
251 (match_operand:SI 3 "const_int_operand" "")] ;; model
kono
parents: 68
diff changeset
252 VUNSPEC_ATOMIC_XCHG))
kono
parents: 68
diff changeset
253 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
254 (clobber (match_scratch:SI 4 "=&r,&l"))]
kono
parents: 68
diff changeset
255 "<sync_predtab>"
kono
parents: 68
diff changeset
256 "#"
kono
parents: 68
diff changeset
257 "&& reload_completed"
kono
parents: 68
diff changeset
258 [(const_int 0)]
kono
parents: 68
diff changeset
259 {
kono
parents: 68
diff changeset
260 arm_split_atomic_op (SET, operands[0], NULL, operands[1],
kono
parents: 68
diff changeset
261 operands[2], operands[3], operands[4]);
kono
parents: 68
diff changeset
262 DONE;
kono
parents: 68
diff changeset
263 }
kono
parents: 68
diff changeset
264 [(set_attr "arch" "32,v8mb")])
kono
parents: 68
diff changeset
265
kono
parents: 68
diff changeset
266 ;; The following mode and code attribute are defined here because they are
kono
parents: 68
diff changeset
267 ;; specific to atomics and are not needed anywhere else.
kono
parents: 68
diff changeset
268
kono
parents: 68
diff changeset
269 (define_mode_attr atomic_op_operand
kono
parents: 68
diff changeset
270 [(QI "reg_or_int_operand")
kono
parents: 68
diff changeset
271 (HI "reg_or_int_operand")
kono
parents: 68
diff changeset
272 (SI "reg_or_int_operand")
kono
parents: 68
diff changeset
273 (DI "s_register_operand")])
kono
parents: 68
diff changeset
274
kono
parents: 68
diff changeset
275 (define_mode_attr atomic_op_str
kono
parents: 68
diff changeset
276 [(QI "rn") (HI "rn") (SI "rn") (DI "r")])
kono
parents: 68
diff changeset
277
kono
parents: 68
diff changeset
278 (define_code_attr thumb1_atomic_op_str
kono
parents: 68
diff changeset
279 [(ior "l,l") (xor "l,l") (and "l,l") (plus "lIJL,r") (minus "lPd,lPd")])
kono
parents: 68
diff changeset
280
kono
parents: 68
diff changeset
281 (define_code_attr thumb1_atomic_newop_str
kono
parents: 68
diff changeset
282 [(ior "&l,&l") (xor "&l,&l") (and "&l,&l") (plus "&l,&r") (minus "&l,&l")])
kono
parents: 68
diff changeset
283
kono
parents: 68
diff changeset
284 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
285 ;; atomic operations in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
286 (define_insn_and_split "atomic_<sync_optab><mode>"
kono
parents: 68
diff changeset
287 [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua,Ua,Ua")
kono
parents: 68
diff changeset
288 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
289 [(syncop:QHSD (match_dup 0)
kono
parents: 68
diff changeset
290 (match_operand:QHSD 1 "<atomic_op_operand>" "<atomic_op_str>,<thumb1_atomic_op_str>"))
kono
parents: 68
diff changeset
291 (match_operand:SI 2 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
292 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
293 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
294 (clobber (match_scratch:QHSD 3 "=&r,<thumb1_atomic_newop_str>"))
kono
parents: 68
diff changeset
295 (clobber (match_scratch:SI 4 "=&r,&l,&l"))]
kono
parents: 68
diff changeset
296 "<sync_predtab>"
kono
parents: 68
diff changeset
297 "#"
kono
parents: 68
diff changeset
298 "&& reload_completed"
kono
parents: 68
diff changeset
299 [(const_int 0)]
kono
parents: 68
diff changeset
300 {
kono
parents: 68
diff changeset
301 arm_split_atomic_op (<CODE>, NULL, operands[3], operands[0],
kono
parents: 68
diff changeset
302 operands[1], operands[2], operands[4]);
kono
parents: 68
diff changeset
303 DONE;
kono
parents: 68
diff changeset
304 }
kono
parents: 68
diff changeset
305 [(set_attr "arch" "32,v8mb,v8mb")])
kono
parents: 68
diff changeset
306
kono
parents: 68
diff changeset
307 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
308 ;; atomic NANDs in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
309 (define_insn_and_split "atomic_nand<mode>"
kono
parents: 68
diff changeset
310 [(set (match_operand:QHSD 0 "mem_noofs_operand" "+Ua,Ua")
kono
parents: 68
diff changeset
311 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
312 [(not:QHSD
kono
parents: 68
diff changeset
313 (and:QHSD (match_dup 0)
kono
parents: 68
diff changeset
314 (match_operand:QHSD 1 "<atomic_op_operand>" "<atomic_op_str>,l")))
kono
parents: 68
diff changeset
315 (match_operand:SI 2 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
316 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
317 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
318 (clobber (match_scratch:QHSD 3 "=&r,&l"))
kono
parents: 68
diff changeset
319 (clobber (match_scratch:SI 4 "=&r,&l"))]
kono
parents: 68
diff changeset
320 "<sync_predtab>"
kono
parents: 68
diff changeset
321 "#"
kono
parents: 68
diff changeset
322 "&& reload_completed"
kono
parents: 68
diff changeset
323 [(const_int 0)]
kono
parents: 68
diff changeset
324 {
kono
parents: 68
diff changeset
325 arm_split_atomic_op (NOT, NULL, operands[3], operands[0],
kono
parents: 68
diff changeset
326 operands[1], operands[2], operands[4]);
kono
parents: 68
diff changeset
327 DONE;
kono
parents: 68
diff changeset
328 }
kono
parents: 68
diff changeset
329 [(set_attr "arch" "32,v8mb")])
kono
parents: 68
diff changeset
330
kono
parents: 68
diff changeset
331 ;; 3 alternatives are needed to represent constraints after split from
kono
parents: 68
diff changeset
332 ;; thumb1_addsi3: (i) case where operand1 and destination can be in different
kono
parents: 68
diff changeset
333 ;; registers, (ii) case where they are in the same low register and (iii) case
kono
parents: 68
diff changeset
334 ;; when they are in the same register without restriction on the register. We
kono
parents: 68
diff changeset
335 ;; disparage slightly alternatives that require copying the old value into the
kono
parents: 68
diff changeset
336 ;; register for the new value (see bind_old_new in arm_split_atomic_op).
kono
parents: 68
diff changeset
337 (define_code_attr thumb1_atomic_fetch_op_str
kono
parents: 68
diff changeset
338 [(ior "l,l,l") (xor "l,l,l") (and "l,l,l") (plus "lL,?IJ,?r") (minus "lPd,lPd,lPd")])
kono
parents: 68
diff changeset
339
kono
parents: 68
diff changeset
340 (define_code_attr thumb1_atomic_fetch_newop_str
kono
parents: 68
diff changeset
341 [(ior "&l,&l,&l") (xor "&l,&l,&l") (and "&l,&l,&l") (plus "&l,&l,&r") (minus "&l,&l,&l")])
kono
parents: 68
diff changeset
342
kono
parents: 68
diff changeset
343 (define_code_attr thumb1_atomic_fetch_oldop_str
kono
parents: 68
diff changeset
344 [(ior "&r,&r,&r") (xor "&r,&r,&r") (and "&r,&r,&r") (plus "&l,&r,&r") (minus "&l,&l,&l")])
kono
parents: 68
diff changeset
345
kono
parents: 68
diff changeset
346 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
347 ;; atomic operations in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
348 (define_insn_and_split "atomic_fetch_<sync_optab><mode>"
kono
parents: 68
diff changeset
349 [(set (match_operand:QHSD 0 "s_register_operand" "=&r,<thumb1_atomic_fetch_oldop_str>")
kono
parents: 68
diff changeset
350 (match_operand:QHSD 1 "mem_noofs_operand" "+Ua,Ua,Ua,Ua"))
kono
parents: 68
diff changeset
351 (set (match_dup 1)
kono
parents: 68
diff changeset
352 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
353 [(syncop:QHSD (match_dup 1)
kono
parents: 68
diff changeset
354 (match_operand:QHSD 2 "<atomic_op_operand>" "<atomic_op_str>,<thumb1_atomic_fetch_op_str>"))
kono
parents: 68
diff changeset
355 (match_operand:SI 3 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
356 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
357 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
358 (clobber (match_scratch:QHSD 4 "=&r,<thumb1_atomic_fetch_newop_str>"))
kono
parents: 68
diff changeset
359 (clobber (match_scratch:SI 5 "=&r,&l,&l,&l"))]
kono
parents: 68
diff changeset
360 "<sync_predtab>"
kono
parents: 68
diff changeset
361 "#"
kono
parents: 68
diff changeset
362 "&& reload_completed"
kono
parents: 68
diff changeset
363 [(const_int 0)]
kono
parents: 68
diff changeset
364 {
kono
parents: 68
diff changeset
365 arm_split_atomic_op (<CODE>, operands[0], operands[4], operands[1],
kono
parents: 68
diff changeset
366 operands[2], operands[3], operands[5]);
kono
parents: 68
diff changeset
367 DONE;
kono
parents: 68
diff changeset
368 }
kono
parents: 68
diff changeset
369 [(set_attr "arch" "32,v8mb,v8mb,v8mb")])
kono
parents: 68
diff changeset
370
kono
parents: 68
diff changeset
371 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
372 ;; atomic NANDs in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
373 (define_insn_and_split "atomic_fetch_nand<mode>"
kono
parents: 68
diff changeset
374 [(set (match_operand:QHSD 0 "s_register_operand" "=&r,&r")
kono
parents: 68
diff changeset
375 (match_operand:QHSD 1 "mem_noofs_operand" "+Ua,Ua"))
kono
parents: 68
diff changeset
376 (set (match_dup 1)
kono
parents: 68
diff changeset
377 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
378 [(not:QHSD
kono
parents: 68
diff changeset
379 (and:QHSD (match_dup 1)
kono
parents: 68
diff changeset
380 (match_operand:QHSD 2 "<atomic_op_operand>" "<atomic_op_str>,l")))
kono
parents: 68
diff changeset
381 (match_operand:SI 3 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
382 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
383 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
384 (clobber (match_scratch:QHSD 4 "=&r,&l"))
kono
parents: 68
diff changeset
385 (clobber (match_scratch:SI 5 "=&r,&l"))]
kono
parents: 68
diff changeset
386 "<sync_predtab>"
kono
parents: 68
diff changeset
387 "#"
kono
parents: 68
diff changeset
388 "&& reload_completed"
kono
parents: 68
diff changeset
389 [(const_int 0)]
kono
parents: 68
diff changeset
390 {
kono
parents: 68
diff changeset
391 arm_split_atomic_op (NOT, operands[0], operands[4], operands[1],
kono
parents: 68
diff changeset
392 operands[2], operands[3], operands[5]);
kono
parents: 68
diff changeset
393 DONE;
kono
parents: 68
diff changeset
394 }
kono
parents: 68
diff changeset
395 [(set_attr "arch" "32,v8mb")])
kono
parents: 68
diff changeset
396
kono
parents: 68
diff changeset
397 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
398 ;; atomic operations in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
399 (define_insn_and_split "atomic_<sync_optab>_fetch<mode>"
kono
parents: 68
diff changeset
400 [(set (match_operand:QHSD 0 "s_register_operand" "=&r,<thumb1_atomic_newop_str>")
kono
parents: 68
diff changeset
401 (syncop:QHSD
kono
parents: 68
diff changeset
402 (match_operand:QHSD 1 "mem_noofs_operand" "+Ua,Ua,Ua")
kono
parents: 68
diff changeset
403 (match_operand:QHSD 2 "<atomic_op_operand>" "<atomic_op_str>,<thumb1_atomic_op_str>")))
kono
parents: 68
diff changeset
404 (set (match_dup 1)
kono
parents: 68
diff changeset
405 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
406 [(match_dup 1) (match_dup 2)
kono
parents: 68
diff changeset
407 (match_operand:SI 3 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
408 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
409 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
410 (clobber (match_scratch:SI 4 "=&r,&l,&l"))]
kono
parents: 68
diff changeset
411 "<sync_predtab>"
kono
parents: 68
diff changeset
412 "#"
kono
parents: 68
diff changeset
413 "&& reload_completed"
kono
parents: 68
diff changeset
414 [(const_int 0)]
kono
parents: 68
diff changeset
415 {
kono
parents: 68
diff changeset
416 arm_split_atomic_op (<CODE>, NULL, operands[0], operands[1],
kono
parents: 68
diff changeset
417 operands[2], operands[3], operands[4]);
kono
parents: 68
diff changeset
418 DONE;
kono
parents: 68
diff changeset
419 }
kono
parents: 68
diff changeset
420 [(set_attr "arch" "32,v8mb,v8mb")])
kono
parents: 68
diff changeset
421
kono
parents: 68
diff changeset
422 ;; Constraints of this pattern must be at least as strict as those of the non
kono
parents: 68
diff changeset
423 ;; atomic NANDs in thumb1.md and aim to be as permissive.
kono
parents: 68
diff changeset
424 (define_insn_and_split "atomic_nand_fetch<mode>"
kono
parents: 68
diff changeset
425 [(set (match_operand:QHSD 0 "s_register_operand" "=&r,&l")
kono
parents: 68
diff changeset
426 (not:QHSD
kono
parents: 68
diff changeset
427 (and:QHSD
kono
parents: 68
diff changeset
428 (match_operand:QHSD 1 "mem_noofs_operand" "+Ua,Ua")
kono
parents: 68
diff changeset
429 (match_operand:QHSD 2 "<atomic_op_operand>" "<atomic_op_str>,l"))))
kono
parents: 68
diff changeset
430 (set (match_dup 1)
kono
parents: 68
diff changeset
431 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
432 [(match_dup 1) (match_dup 2)
kono
parents: 68
diff changeset
433 (match_operand:SI 3 "const_int_operand")] ;; model
kono
parents: 68
diff changeset
434 VUNSPEC_ATOMIC_OP))
kono
parents: 68
diff changeset
435 (clobber (reg:CC CC_REGNUM))
kono
parents: 68
diff changeset
436 (clobber (match_scratch:SI 4 "=&r,&l"))]
kono
parents: 68
diff changeset
437 "<sync_predtab>"
kono
parents: 68
diff changeset
438 "#"
kono
parents: 68
diff changeset
439 "&& reload_completed"
kono
parents: 68
diff changeset
440 [(const_int 0)]
kono
parents: 68
diff changeset
441 {
kono
parents: 68
diff changeset
442 arm_split_atomic_op (NOT, NULL, operands[0], operands[1],
kono
parents: 68
diff changeset
443 operands[2], operands[3], operands[4]);
kono
parents: 68
diff changeset
444 DONE;
kono
parents: 68
diff changeset
445 }
kono
parents: 68
diff changeset
446 [(set_attr "arch" "32,v8mb")])
kono
parents: 68
diff changeset
447
kono
parents: 68
diff changeset
448 (define_insn "arm_load_exclusive<mode>"
kono
parents: 68
diff changeset
449 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
kono
parents: 68
diff changeset
450 (zero_extend:SI
kono
parents: 68
diff changeset
451 (unspec_volatile:NARROW
kono
parents: 68
diff changeset
452 [(match_operand:NARROW 1 "mem_noofs_operand" "Ua,Ua")]
kono
parents: 68
diff changeset
453 VUNSPEC_LL)))]
kono
parents: 68
diff changeset
454 "TARGET_HAVE_LDREXBH"
kono
parents: 68
diff changeset
455 "@
kono
parents: 68
diff changeset
456 ldrex<sync_sfx>%?\t%0, %C1
kono
parents: 68
diff changeset
457 ldrex<sync_sfx>\t%0, %C1"
kono
parents: 68
diff changeset
458 [(set_attr "arch" "32,v8mb")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
459 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
460
kono
parents: 68
diff changeset
461 (define_insn "arm_load_acquire_exclusive<mode>"
kono
parents: 68
diff changeset
462 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
kono
parents: 68
diff changeset
463 (zero_extend:SI
kono
parents: 68
diff changeset
464 (unspec_volatile:NARROW
kono
parents: 68
diff changeset
465 [(match_operand:NARROW 1 "mem_noofs_operand" "Ua,Ua")]
kono
parents: 68
diff changeset
466 VUNSPEC_LAX)))]
kono
parents: 68
diff changeset
467 "TARGET_HAVE_LDACQ"
kono
parents: 68
diff changeset
468 "@
kono
parents: 68
diff changeset
469 ldaex<sync_sfx>%?\\t%0, %C1
kono
parents: 68
diff changeset
470 ldaex<sync_sfx>\\t%0, %C1"
kono
parents: 68
diff changeset
471 [(set_attr "arch" "32,v8mb")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
473
kono
parents: 68
diff changeset
474 (define_insn "arm_load_exclusivesi"
kono
parents: 68
diff changeset
475 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
kono
parents: 68
diff changeset
476 (unspec_volatile:SI
kono
parents: 68
diff changeset
477 [(match_operand:SI 1 "mem_noofs_operand" "Ua,Ua")]
kono
parents: 68
diff changeset
478 VUNSPEC_LL))]
kono
parents: 68
diff changeset
479 "TARGET_HAVE_LDREX"
kono
parents: 68
diff changeset
480 "@
kono
parents: 68
diff changeset
481 ldrex%?\t%0, %C1
kono
parents: 68
diff changeset
482 ldrex\t%0, %C1"
kono
parents: 68
diff changeset
483 [(set_attr "arch" "32,v8mb")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
484 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
485
kono
parents: 68
diff changeset
486 (define_insn "arm_load_acquire_exclusivesi"
kono
parents: 68
diff changeset
487 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
kono
parents: 68
diff changeset
488 (unspec_volatile:SI
kono
parents: 68
diff changeset
489 [(match_operand:SI 1 "mem_noofs_operand" "Ua,Ua")]
kono
parents: 68
diff changeset
490 VUNSPEC_LAX))]
kono
parents: 68
diff changeset
491 "TARGET_HAVE_LDACQ"
kono
parents: 68
diff changeset
492 "@
kono
parents: 68
diff changeset
493 ldaex%?\t%0, %C1
kono
parents: 68
diff changeset
494 ldaex\t%0, %C1"
kono
parents: 68
diff changeset
495 [(set_attr "arch" "32,v8mb")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
496 (set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
497
kono
parents: 68
diff changeset
498 (define_insn "arm_load_exclusivedi"
kono
parents: 68
diff changeset
499 [(set (match_operand:DI 0 "s_register_operand" "=r")
kono
parents: 68
diff changeset
500 (unspec_volatile:DI
kono
parents: 68
diff changeset
501 [(match_operand:DI 1 "mem_noofs_operand" "Ua")]
kono
parents: 68
diff changeset
502 VUNSPEC_LL))]
kono
parents: 68
diff changeset
503 "TARGET_HAVE_LDREXD"
kono
parents: 68
diff changeset
504 "ldrexd%?\t%0, %H0, %C1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505 [(set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
506
kono
parents: 68
diff changeset
507 (define_insn "arm_load_acquire_exclusivedi"
kono
parents: 68
diff changeset
508 [(set (match_operand:DI 0 "s_register_operand" "=r")
kono
parents: 68
diff changeset
509 (unspec_volatile:DI
kono
parents: 68
diff changeset
510 [(match_operand:DI 1 "mem_noofs_operand" "Ua")]
kono
parents: 68
diff changeset
511 VUNSPEC_LAX))]
kono
parents: 68
diff changeset
512 "TARGET_HAVE_LDACQEXD && ARM_DOUBLEWORD_ALIGN"
kono
parents: 68
diff changeset
513 "ldaexd%?\t%0, %H0, %C1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 [(set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
515
kono
parents: 68
diff changeset
516 (define_insn "arm_store_exclusive<mode>"
kono
parents: 68
diff changeset
517 [(set (match_operand:SI 0 "s_register_operand" "=&r")
kono
parents: 68
diff changeset
518 (unspec_volatile:SI [(const_int 0)] VUNSPEC_SC))
kono
parents: 68
diff changeset
519 (set (match_operand:QHSD 1 "mem_noofs_operand" "=Ua")
kono
parents: 68
diff changeset
520 (unspec_volatile:QHSD
kono
parents: 68
diff changeset
521 [(match_operand:QHSD 2 "s_register_operand" "r")]
kono
parents: 68
diff changeset
522 VUNSPEC_SC))]
kono
parents: 68
diff changeset
523 "<sync_predtab>"
kono
parents: 68
diff changeset
524 {
kono
parents: 68
diff changeset
525 if (<MODE>mode == DImode)
kono
parents: 68
diff changeset
526 {
kono
parents: 68
diff changeset
527 /* The restrictions on target registers in ARM mode are that the two
kono
parents: 68
diff changeset
528 registers are consecutive and the first one is even; Thumb is
kono
parents: 68
diff changeset
529 actually more flexible, but DI should give us this anyway.
kono
parents: 68
diff changeset
530 Note that the 1st register always gets the
kono
parents: 68
diff changeset
531 lowest word in memory. */
kono
parents: 68
diff changeset
532 gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2);
kono
parents: 68
diff changeset
533 return "strexd%?\t%0, %2, %H2, %C1";
kono
parents: 68
diff changeset
534 }
kono
parents: 68
diff changeset
535 if (TARGET_THUMB1)
kono
parents: 68
diff changeset
536 return "strex<sync_sfx>\t%0, %2, %C1";
kono
parents: 68
diff changeset
537 else
kono
parents: 68
diff changeset
538 return "strex<sync_sfx>%?\t%0, %2, %C1";
kono
parents: 68
diff changeset
539 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 [(set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
541
kono
parents: 68
diff changeset
542 (define_insn "arm_store_release_exclusivedi"
kono
parents: 68
diff changeset
543 [(set (match_operand:SI 0 "s_register_operand" "=&r")
kono
parents: 68
diff changeset
544 (unspec_volatile:SI [(const_int 0)] VUNSPEC_SLX))
kono
parents: 68
diff changeset
545 (set (match_operand:DI 1 "mem_noofs_operand" "=Ua")
kono
parents: 68
diff changeset
546 (unspec_volatile:DI
kono
parents: 68
diff changeset
547 [(match_operand:DI 2 "s_register_operand" "r")]
kono
parents: 68
diff changeset
548 VUNSPEC_SLX))]
kono
parents: 68
diff changeset
549 "TARGET_HAVE_LDACQEXD && ARM_DOUBLEWORD_ALIGN"
kono
parents: 68
diff changeset
550 {
kono
parents: 68
diff changeset
551 /* See comment in arm_store_exclusive<mode> above. */
kono
parents: 68
diff changeset
552 gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2);
kono
parents: 68
diff changeset
553 return "stlexd%?\t%0, %2, %H2, %C1";
kono
parents: 68
diff changeset
554 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
555 [(set_attr "predicable" "yes")])
111
kono
parents: 68
diff changeset
556
kono
parents: 68
diff changeset
557 (define_insn "arm_store_release_exclusive<mode>"
kono
parents: 68
diff changeset
558 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
kono
parents: 68
diff changeset
559 (unspec_volatile:SI [(const_int 0)] VUNSPEC_SLX))
kono
parents: 68
diff changeset
560 (set (match_operand:QHSI 1 "mem_noofs_operand" "=Ua,Ua")
kono
parents: 68
diff changeset
561 (unspec_volatile:QHSI
kono
parents: 68
diff changeset
562 [(match_operand:QHSI 2 "s_register_operand" "r,r")]
kono
parents: 68
diff changeset
563 VUNSPEC_SLX))]
kono
parents: 68
diff changeset
564 "TARGET_HAVE_LDACQ"
kono
parents: 68
diff changeset
565 "@
kono
parents: 68
diff changeset
566 stlex<sync_sfx>%?\t%0, %2, %C1
kono
parents: 68
diff changeset
567 stlex<sync_sfx>\t%0, %2, %C1"
kono
parents: 68
diff changeset
568 [(set_attr "arch" "32,v8mb")
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
569 (set_attr "predicable" "yes")])