Skip to content

Commit ada1ca2

Browse files
Claudiu Zissulescuartemiy-volkov
authored andcommitted
arc64: Add the new ARCv3 ATO instruction support.
Add support for the new atld.<ops>/arldl.<ops> instructions. The following operations are supported by GCC: -ADD -AND -OR -XOR The next builtin macros are defined: __ARC64_ATOMIC_1__ __ARC64_ATOMIC_2__ __ARC64_ATOMIC_3__ The following builtin macro is removed: __ARC64_ATOMIC__ Signed-off-by: Claudiu Zissulescu <[email protected]>
1 parent 4058fc2 commit ada1ca2

File tree

6 files changed

+112
-44
lines changed

6 files changed

+112
-44
lines changed

gcc/config/arc64/arc64-c.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ arc64_cpu_cpp_builtins (cpp_reader * pfile)
5656
builtin_define ("__LITTLE_ENDIAN__");
5757
builtin_define ("__ARCV3__");
5858

59-
if (arc64_atomic_option)
60-
builtin_define_with_int_value ("__ARC64_ATOMIC__", arc64_atomic_option);
61-
6259
if (arc64_cmodel_var == ARC64_CMODEL_SMALL)
6360
builtin_define ("__ARC64_CMODEL_SMALL__");
6461
else if (arc64_cmodel_var == ARC64_CMODEL_MEDIUM)

gcc/config/arc64/arc64-c.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
<http://www.gnu.org/licenses/>.
1818
*/
1919

20-
//ARC_C_DEF ("__ARC_UNALIGNED__", unaligned_access)
20+
ARC64_C_DEF ("__ARC64_ATOMIC_1__", arc64_atomic_option == 1)
21+
ARC64_C_DEF ("__ARC64_ATOMIC_2__", arc64_atomic_option == 2)
22+
ARC64_C_DEF ("__ARC64_ATOMIC_3__", arc64_atomic_option == 3)
2123

2224
/* Local Variables: */
2325
/* mode: c */

gcc/config/arc64/arc64-protos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ extern rtx arc64_eh_return_handler_rtx (void);
2727
extern int arc64_asm_preferred_eh_data_format (int, int);
2828

2929
extern void arc64_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
30+
extern void arc64_pre_atomic_barrier (enum memmodel);
31+
extern void arc64_post_atomic_barrier (enum memmodel);
3032
extern void arc64_expand_compare_and_swap (rtx []);
3133
extern void arc64_split_compare_and_swap (rtx []);
3234
extern bool arc64_allow_direct_access_p (rtx);

gcc/config/arc64/arc64.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,26 +2240,6 @@ emit_unlikely_jump (rtx insn)
22402240
add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
22412241
}
22422242

2243-
/* Emit a (pre) memory barrier around an atomic sequence according to
2244-
MODEL. */
2245-
2246-
static void
2247-
arc64_pre_atomic_barrier (enum memmodel model)
2248-
{
2249-
if (need_atomic_barrier_p (model, true))
2250-
emit_insn (gen_memory_barrier ());
2251-
}
2252-
2253-
/* Emit a (post) memory barrier around an atomic sequence according to
2254-
MODEL. */
2255-
2256-
static void
2257-
arc64_post_atomic_barrier (enum memmodel model)
2258-
{
2259-
if (need_atomic_barrier_p (model, false))
2260-
emit_insn (gen_memory_barrier ());
2261-
}
2262-
22632243
/* Expand code to perform a 8 or 16-bit compare and swap by doing
22642244
32-bit compare and swap on the word containing the byte or
22652245
half-word. The difference between a weak and a strong CAS is that
@@ -2995,6 +2975,26 @@ arc64_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global)
29952975
return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
29962976
}
29972977

2978+
/* Emit a (pre) memory barrier around an atomic sequence according to
2979+
MODEL. */
2980+
2981+
void
2982+
arc64_pre_atomic_barrier (enum memmodel model)
2983+
{
2984+
if (need_atomic_barrier_p (model, true))
2985+
emit_insn (gen_memory_barrier ());
2986+
}
2987+
2988+
/* Emit a (post) memory barrier around an atomic sequence according to
2989+
MODEL. */
2990+
2991+
void
2992+
arc64_post_atomic_barrier (enum memmodel model)
2993+
{
2994+
if (need_atomic_barrier_p (model, false))
2995+
emit_insn (gen_memory_barrier ());
2996+
}
2997+
29982998
/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
29992999
to perform. MEM is the memory on which to operate. VAL is the second
30003000
operand of the binary operator. BEFORE and AFTER are optional locations to

gcc/config/arc64/arc64.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
ARC64_VUNSPEC_SC
9191
ARC64_VUNSPEC_LL
9292
ARC64_VUNSPEC_SYNC
93+
ARC64_VUNSPEC_ATOOPS
9394

9495
ARC64_UNSPEC_MEMBAR
9596
])
@@ -241,13 +242,14 @@
241242
;; this. For optimizing for size the "length" attribute is used instead.
242243
(define_attr "cost" "" (const_int 0))
243244

244-
(define_attr "type" "abs, adcl, add, addhl, addl, and, andl, asl, asll, asr,
245-
asrl, bic, bl, block, bmsk, branch, branchcc, brk, bset, bsetl, btst, bxor,
246-
bxorl, compare, dbnz, dmb, ex, div, divl, ext, flag, jl, jump, ld, llock,
247-
lsr, lsrl, lr, max, maxl, min, minl, move, movecc, mod, modl, neg, nop,
248-
norm, normh, norml, mpy, mpyl, not, notl, or, orl, return, ror,rol, sbcl,
249-
scond, setcc, sex, sr, st, sub, subl, swape, swapel, sync, trap, udiv,
250-
udivl, umod, umodl, unknown, xbfu, xor, xorl"
245+
(define_attr "type" "abs, adcl, add, addhl, addl, and, andl, asl,
246+
asll, asr, asrl, atldop, atldlop, bic, bl, block, bmsk, branch,
247+
branchcc, brk, bset, bsetl, btst, bxor, bxorl, compare, dbnz, dmb, ex,
248+
div, divl, ext, flag, jl, jump, ld, llock, lsr, lsrl, lr, max, maxl,
249+
min, minl, move, movecc, mod, modl, neg, nop, norm, normh, norml, mpy,
250+
mpyl, not, notl, or, orl, return, ror,rol, sbcl, scond, setcc, sex,
251+
sr, st, sub, subl, swape, swapel, sync, trap, udiv, udivl, umod,
252+
umodl, unknown, xbfu, xor, xorl"
251253
(const_string "unknown"))
252254

253255
(define_attr "iscompact" "yes,no,maybe" (const_string "no"))

gcc/config/arc64/atomic.md

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
;; Operations which can be used with atomic loads and stores.
2121
(define_code_iterator ATOPS [plus minus ior xor and])
2222

23+
;; Operations which are supported by hardware.
24+
(define_code_iterator ATHWOPS [plus ior xor and])
25+
2326
(define_expand "memory_barrier"
2427
[(set (match_dup 0)
2528
(unspec:BLK [(match_dup 0)] ARC64_UNSPEC_MEMBAR))]
@@ -82,7 +85,7 @@
8285
[(match_operand:GPI 1 "mem_noofs_operand" "ATOMC")]
8386
ARC64_VUNSPEC_LL))]
8487
"ARC64_HAS_ATOMIC_1"
85-
"llock<mcctab> %0,%1"
88+
"llock<mcctab>\\t%0,%1"
8689
[(set_attr "type" "llock")
8790
(set_attr "iscompact" "no")
8891
(set_attr "predicable" "no")
@@ -94,7 +97,7 @@
9497
ARC64_VUNSPEC_SC))
9598
(clobber (reg:CC_Z CC_REGNUM))]
9699
"ARC64_HAS_ATOMIC_1"
97-
"scond<mcctab> %1,%0"
100+
"scond<mcctab>\\t%1,%0"
98101
[(set_attr "type" "scond")
99102
(set_attr "iscompact" "no")
100103
(set_attr "predicable" "no")
@@ -122,12 +125,35 @@
122125
(set (match_dup 1)
123126
(match_operand:GPI 2 "register_operand" "0"))]
124127
""
125-
"ex<mcctab> %0,%1"
128+
"ex<mcctab>\\t%0,%1"
126129
[(set_attr "type" "ex")
127130
(set_attr "iscompact" "no")
128131
(set_attr "predicable" "no")
129132
(set_attr "length" "*")])
130133

134+
;; New Atomic options enabled by option 2
135+
(define_insn_and_split "atld_<optab><mode>"
136+
[(set (match_operand:GPI 0 "register_operand" "=&r,r")
137+
(match_operand:GPI 1 "mem_noofs_operand" "+ATOMC,ATOMC"))
138+
(set (match_dup 1)
139+
(unspec_volatile:GPI
140+
[(ATHWOPS:GPI (match_dup 0)
141+
(match_operand:GPI 2 "register_operand" "0,r"))
142+
(match_operand:SI 3 "const_int_operand")]
143+
ARC64_VUNSPEC_ATOOPS))]
144+
"ARC64_HAS_ATOMIC_2"
145+
"@
146+
atld<sfxtab>.<optab>\\t%0,%1
147+
#"
148+
"&& reload_completed && !operands_match_p (operands[0], operands[2])"
149+
[(const_int 0)]
150+
{
151+
emit_insn (gen_rtx_SET (operands[0], operands[2]));
152+
emit_insn (gen_atld_<optab><mode> (operands[0], operands[1], operands[0], operands[3]));
153+
DONE;
154+
}
155+
[(set_attr "type" "atld<sfxtab>op")])
156+
131157
(define_expand "atomic_<optab><mode>"
132158
[(match_operand:GPI 0 "mem_noofs_operand" "") ;; memory
133159
(ATOPS:GPI (match_dup 0)
@@ -152,17 +178,46 @@
152178
})
153179

154180
(define_expand "atomic_fetch_<optab><mode>"
155-
[(match_operand:GPI 0 "register_operand" "") ;; output
156-
(match_operand:GPI 1 "mem_noofs_operand" "") ;; memory
157-
(ATOPS:GPI (match_dup 1)
158-
(match_operand:GPI 2 "register_operand" "")) ;; operand
159-
(match_operand:SI 3 "const_int_operand" "")] ;; model
181+
[(set (match_operand:GPI 0 "register_operand") ;; output
182+
(match_operand:GPI 1 "mem_noofs_operand")) ;; memory
183+
(set (match_dup 1)
184+
(unspec_volatile:GPI
185+
[(ATHWOPS:GPI (match_dup 1)
186+
(match_operand:GPI 2 "register_operand")) ;; operand
187+
(match_operand:SI 3 "const_int_operand")] ;; model
188+
ARC64_VUNSPEC_ATOOPS))]
160189
"ARC64_HAS_ATOMIC_1"
161-
{
162-
arc64_expand_atomic_op (<CODE>, operands[1], operands[2],
163-
operands[0], NULL_RTX, operands[3]);
164-
DONE;
165-
})
190+
{
191+
if (!ARC64_HAS_ATOMIC_2)
192+
{
193+
arc64_expand_atomic_op (<CODE>, operands[1], operands[2],
194+
operands[0], NULL_RTX, operands[3]);
195+
DONE;
196+
}
197+
if (!ARC64_HAS_ATOMIC_3)
198+
arc64_pre_atomic_barrier ((enum memmodel) INTVAL (operands[3]));
199+
emit_insn (gen_atld_<optab><mode> (operands[0], operands[1], operands[2], operands[3]));
200+
if (!ARC64_HAS_ATOMIC_3)
201+
arc64_post_atomic_barrier ((enum memmodel) INTVAL (operands[3]));
202+
DONE;
203+
})
204+
205+
;; ARCv3 doesn't have a MINUS atomic memory operation.
206+
(define_expand "atomic_fetch_sub<mode>"
207+
[(set (match_operand:GPI 0 "register_operand") ;; output
208+
(match_operand:GPI 1 "mem_noofs_operand")) ;; memory
209+
(set (match_dup 1)
210+
(unspec_volatile:GPI
211+
[(minus:GPI (match_dup 1)
212+
(match_operand:GPI 2 "register_operand")) ;; operand
213+
(match_operand:SI 3 "const_int_operand")] ;; model
214+
ARC64_VUNSPEC_ATOOPS))]
215+
"ARC64_HAS_ATOMIC_1"
216+
{
217+
arc64_expand_atomic_op (MINUS, operands[1], operands[2],
218+
operands[0], NULL_RTX, operands[3]);
219+
DONE;
220+
})
166221

167222
(define_expand "atomic_fetch_nand<mode>"
168223
[(match_operand:GPI 0 "register_operand" "") ;; output
@@ -201,3 +256,13 @@
201256
DONE;
202257
})
203258

259+
260+
;; mode:emacs-lisp
261+
;; comment-start: ";; "
262+
;; eval: (set-syntax-table (caopy-sequence (syntax-table)))
263+
;; eval: (modify-syntax-entry ?[ "(]")
264+
;; eval: (modify-syntax-entry ?] ")[")
265+
;; eval: (modify-syntax-entry ?{ "(}")
266+
;; eval: (modify-syntax-entry ?} "){")
267+
;; eval: (setq indent-tabs-mode t)
268+
;; End:

0 commit comments

Comments
 (0)