111
|
1 ;; GCC machine description for ARC atomic instructions.
|
131
|
2 ;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
|
111
|
3 ;;
|
|
4 ;; This file is part of GCC.
|
|
5 ;;
|
|
6 ;; GCC is free software; you can redistribute it and/or modify
|
|
7 ;; it under the terms of the GNU General Public License as published by
|
|
8 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
9 ;; any later version.
|
|
10 ;;
|
|
11 ;; GCC is distributed in the hope that it will be useful,
|
|
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 ;; GNU General Public License for more details.
|
|
15 ;;
|
|
16 ;; You should have received a copy of the GNU General Public License
|
|
17 ;; along with GCC; see the file COPYING3. If not see
|
|
18 ;; <http://www.gnu.org/licenses/>.
|
|
19
|
|
20 (define_mode_iterator QHSI [QI HI SI])
|
|
21 (define_code_iterator atomicop [plus minus ior xor and])
|
|
22 (define_code_attr atomic_optab
|
|
23 [(ior "or") (xor "xor") (and "and") (plus "add") (minus "sub")])
|
|
24
|
|
25 (define_expand "memory_barrier"
|
|
26 [(set (match_dup 0)
|
|
27 (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
|
|
28 ""
|
|
29 {
|
|
30 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
|
|
31 MEM_VOLATILE_P (operands[0]) = 1;
|
|
32 })
|
|
33
|
|
34 ;; A compiler-only memory barrier for ARC700. Generic code, when
|
|
35 ;; checking for the existence of various named patterns, uses
|
|
36 ;; asm("":::"memory") when we don't need an actual instruction. For
|
|
37 ;; ARCHS, we use a hardware data memory barrier that waits for
|
|
38 ;; completion of current data memory operations before initiating
|
|
39 ;; similar data memory operations.
|
|
40 (define_insn "*memory_barrier"
|
|
41 [(set (match_operand:BLK 0 "" "")
|
|
42 (unspec:BLK [(match_dup 0)] UNSPEC_ARC_MEMBAR))]
|
|
43 ""
|
|
44 {
|
|
45 if (TARGET_HS)
|
|
46 {
|
|
47 return "dmb";
|
|
48 }
|
|
49 else
|
|
50 {
|
|
51 return "";
|
|
52 }
|
|
53 }
|
|
54 [(set_attr "type" "multi")
|
|
55 (set_attr "length" "4")])
|
|
56
|
|
57 (define_expand "atomic_compare_and_swap<mode>"
|
|
58 [(match_operand:SI 0 "register_operand" "") ;; bool out
|
|
59 (match_operand:QHSI 1 "register_operand" "") ;; val out
|
|
60 (match_operand:QHSI 2 "mem_noofs_operand" "");; memory
|
|
61 (match_operand:QHSI 3 "register_operand" "") ;; expected
|
|
62 (match_operand:QHSI 4 "register_operand" "") ;; desired
|
|
63 (match_operand:SI 5 "const_int_operand") ;; is_weak
|
|
64 (match_operand:SI 6 "const_int_operand") ;; mod_s
|
|
65 (match_operand:SI 7 "const_int_operand")] ;; mod_f
|
|
66 "TARGET_ATOMIC"
|
|
67 {
|
|
68 arc_expand_compare_and_swap (operands);
|
|
69 DONE;
|
|
70 })
|
|
71
|
|
72 (define_insn_and_split "atomic_compare_and_swapsi_1"
|
|
73 [(set (reg:CC_Z CC_REG) ;; bool out
|
|
74 (unspec_volatile:CC_Z [(const_int 0)] VUNSPEC_ARC_CAS))
|
|
75 (set (match_operand:SI 0 "register_operand" "=&r") ;; val out
|
|
76 (match_operand:SI 1 "mem_noofs_operand" "+ATO")) ;; memory
|
|
77 (set (match_dup 1)
|
|
78 (unspec_volatile:SI
|
|
79 [(match_operand:SI 2 "register_operand" "r") ;; expect
|
|
80 (match_operand:SI 3 "register_operand" "r") ;; desired
|
|
81 (match_operand:SI 4 "const_int_operand") ;; is_weak
|
|
82 (match_operand:SI 5 "const_int_operand") ;; mod_s
|
|
83 (match_operand:SI 6 "const_int_operand")] ;; mod_f
|
|
84 VUNSPEC_ARC_CAS))]
|
|
85 "TARGET_ATOMIC"
|
|
86 "#"
|
|
87 "&& reload_completed"
|
|
88 [(const_int 0)]
|
|
89 {
|
|
90 arc_split_compare_and_swap (operands);
|
|
91 DONE;
|
|
92 })
|
|
93
|
|
94 (define_insn "arc_load_exclusivesi"
|
|
95 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
96 (unspec_volatile:SI
|
|
97 [(match_operand:SI 1 "mem_noofs_operand" "ATO")]
|
|
98 VUNSPEC_ARC_LL))]
|
|
99 "TARGET_ATOMIC"
|
|
100 "llock %0,%1"
|
|
101 [(set_attr "type" "load")
|
|
102 (set_attr "iscompact" "false")
|
|
103 (set_attr "predicable" "no")
|
|
104 (set_attr "length" "*")])
|
|
105
|
|
106 (define_insn "arc_store_exclusivesi"
|
|
107 [(set (match_operand:SI 0 "mem_noofs_operand" "=ATO")
|
|
108 (unspec_volatile:SI[(match_operand:SI 1 "register_operand" "r")]
|
|
109 VUNSPEC_ARC_SC))
|
|
110 (clobber (reg:CC_Z CC_REG))]
|
|
111 "TARGET_ATOMIC"
|
|
112 "scond %1,%0"
|
|
113 [(set_attr "type" "store")
|
|
114 (set_attr "iscompact" "false")
|
|
115 (set_attr "predicable" "no")
|
|
116 (set_attr "length" "*")])
|
|
117
|
|
118 (define_expand "atomic_exchangesi"
|
|
119 [(match_operand:SI 0 "register_operand" "")
|
|
120 (match_operand:SI 1 "mem_noofs_operand" "")
|
|
121 (match_operand:SI 2 "register_operand" "")
|
|
122 (match_operand:SI 3 "const_int_operand" "")]
|
131
|
123 "TARGET_ARC700 || TARGET_V2"
|
111
|
124 {
|
|
125 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
|
|
126
|
|
127 if (model == MEMMODEL_SEQ_CST)
|
|
128 emit_insn (gen_sync (const1_rtx));
|
|
129 emit_insn (gen_exchangesi (operands[0], operands[1], operands[2]));
|
|
130 DONE;
|
|
131 })
|
|
132
|
|
133 (define_insn "exchangesi"
|
|
134 [(set (match_operand:SI 0 "register_operand" "=r")
|
|
135 (unspec_volatile:SI [(match_operand:SI 1 "mem_noofs_operand" "+ATO")]
|
|
136 VUNSPEC_ARC_EX))
|
|
137 (set (match_dup 1)
|
|
138 (match_operand:SI 2 "register_operand" "0"))]
|
|
139 ""
|
|
140 "ex %0,%1"
|
|
141 [(set_attr "type" "load")
|
|
142 (set_attr "iscompact" "false")
|
|
143 (set_attr "predicable" "no")
|
|
144 (set_attr "length" "*")])
|
|
145
|
|
146 (define_expand "atomic_<atomic_optab>si"
|
|
147 [(match_operand:SI 0 "mem_noofs_operand" "") ;; memory
|
|
148 (atomicop:SI (match_dup 0)
|
|
149 (match_operand:SI 1 "register_operand" "")) ;; operand
|
|
150 (match_operand:SI 2 "const_int_operand" "")] ;; model
|
|
151 "TARGET_ATOMIC"
|
|
152 {
|
|
153 arc_expand_atomic_op (<CODE>, operands[0], operands[1],
|
|
154 NULL_RTX, NULL_RTX, operands[2]);
|
|
155 DONE;
|
|
156 })
|
|
157
|
|
158 (define_expand "atomic_nandsi"
|
|
159 [(match_operand:SI 0 "mem_noofs_operand" "") ;; memory
|
|
160 (match_operand:SI 1 "register_operand" "") ;; operand
|
|
161 (match_operand:SI 2 "const_int_operand" "")] ;; model
|
|
162 "TARGET_ATOMIC"
|
|
163 {
|
|
164 arc_expand_atomic_op (NOT, operands[0], operands[1],
|
|
165 NULL_RTX, NULL_RTX, operands[2]);
|
|
166 DONE;
|
|
167 })
|
|
168
|
|
169 (define_expand "atomic_fetch_<atomic_optab>si"
|
|
170 [(match_operand:SI 0 "register_operand" "") ;; output
|
|
171 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
|
|
172 (atomicop:SI (match_dup 1)
|
|
173 (match_operand:SI 2 "register_operand" "")) ;; operand
|
|
174 (match_operand:SI 3 "const_int_operand" "")] ;; model
|
|
175 "TARGET_ATOMIC"
|
|
176 {
|
|
177 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
|
|
178 operands[0], NULL_RTX, operands[3]);
|
|
179 DONE;
|
|
180 })
|
|
181
|
|
182 (define_expand "atomic_fetch_nandsi"
|
|
183 [(match_operand:SI 0 "register_operand" "") ;; output
|
|
184 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
|
|
185 (match_operand:SI 2 "register_operand" "") ;; operand
|
|
186 (match_operand:SI 3 "const_int_operand" "")] ;; model
|
|
187 "TARGET_ATOMIC"
|
|
188 {
|
|
189 arc_expand_atomic_op (NOT, operands[1], operands[2],
|
|
190 operands[0], NULL_RTX, operands[3]);
|
|
191 DONE;
|
|
192 })
|
|
193
|
|
194 (define_expand "atomic_<atomic_optab>_fetchsi"
|
|
195 [(match_operand:SI 0 "register_operand" "") ;; output
|
|
196 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
|
|
197 (atomicop:SI (match_dup 1)
|
|
198 (match_operand:SI 2 "register_operand" "")) ;; operand
|
|
199 (match_operand:SI 3 "const_int_operand" "")] ;; model
|
|
200 "TARGET_ATOMIC"
|
|
201 {
|
|
202 arc_expand_atomic_op (<CODE>, operands[1], operands[2],
|
|
203 NULL_RTX, operands[0], operands[3]);
|
|
204 DONE;
|
|
205 })
|
|
206
|
|
207 (define_expand "atomic_nand_fetchsi"
|
|
208 [(match_operand:SI 0 "register_operand" "") ;; output
|
|
209 (match_operand:SI 1 "mem_noofs_operand" "") ;; memory
|
|
210 (match_operand:SI 2 "register_operand" "") ;; operand
|
|
211 (match_operand:SI 3 "const_int_operand" "")] ;; model
|
|
212 "TARGET_ATOMIC"
|
|
213 {
|
|
214 arc_expand_atomic_op (NOT, operands[1], operands[2],
|
|
215 NULL_RTX, operands[0], operands[3]);
|
|
216 DONE;
|
|
217 })
|
|
218
|