]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/tilegx/sync.md
Add ports for TILE-Gx and TILEPro.
[thirdparty/gcc.git] / gcc / config / tilegx / sync.md
1 ;; GCC machine description for Tilera TILE-Gx synchronization
2 ;; instructions.
3 ;; Copyright (C) 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Walter Lee (walt@tilera.com)
6 ;;
7 ;; This file is part of GCC.
8 ;;
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13 ;;
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 (define_code_iterator fetchop [plus ior and])
24 (define_code_attr fetchop_name [(plus "add") (ior "or") (and "and")])
25
26 (define_insn "mtspr_cmpexch<mode>"
27 [(set (reg:I48MODE TILEGX_CMPEXCH_REG)
28 (unspec_volatile:I48MODE
29 [(match_operand:I48MODE 0 "reg_or_0_operand" "rO")]
30 UNSPEC_SPR_MOVE))]
31 ""
32 "mtspr\tCMPEXCH_VALUE, %r0"
33 [(set_attr "type" "X1")])
34
35
36 (define_expand "atomic_compare_and_swap<mode>"
37 [(match_operand:DI 0 "register_operand" "") ;; bool output
38 (match_operand:I48MODE 1 "register_operand" "") ;; val output
39 (match_operand:I48MODE 2 "nonautoincmem_operand" "") ;; memory
40 (match_operand:I48MODE 3 "reg_or_0_operand" "") ;; expected value
41 (match_operand:I48MODE 4 "reg_or_0_operand" "") ;; desired value
42 (match_operand:SI 5 "const_int_operand" "") ;; is_weak
43 (match_operand:SI 6 "const_int_operand" "") ;; mod_s
44 (match_operand:SI 7 "const_int_operand" "")] ;; mod_f
45 ""
46 {
47 enum memmodel mod_s = (enum memmodel) INTVAL (operands[6]);
48
49 if (operands[3] != const0_rtx)
50 operands[3] = force_reg (<MODE>mode, operands[3]);
51 if (operands[4] != const0_rtx)
52 operands[4] = force_reg (<MODE>mode, operands[4]);
53
54 tilegx_pre_atomic_barrier (mod_s);
55 emit_insn (gen_mtspr_cmpexch<mode> (operands[3]));
56 emit_insn (gen_atomic_compare_and_swap_bare<mode> (operands[1], operands[2],
57 operands[4]));
58 tilegx_post_atomic_barrier (mod_s);
59 emit_insn (gen_insn_cmpeq_<mode>di (operands[0], operands[1], operands[3]));
60 DONE;
61 })
62
63
64 (define_insn "atomic_compare_and_swap_bare<mode>"
65 [(set (match_operand:I48MODE 0 "register_operand" "=r")
66 (match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
67 (set (match_dup 1)
68 (unspec_volatile:I48MODE
69 [(match_dup 1)
70 (reg:I48MODE TILEGX_CMPEXCH_REG)
71 (match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
72 UNSPEC_CMPXCHG))]
73 ""
74 "cmpexch<four_if_si>\t%0, %1, %r2"
75 [(set_attr "type" "X1_L2")])
76
77
78 (define_expand "atomic_exchange<mode>"
79 [(match_operand:I48MODE 0 "register_operand" "") ;; result
80 (match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
81 (match_operand:I48MODE 2 "reg_or_0_operand" "") ;; input
82 (match_operand:SI 3 "const_int_operand" "")] ;; model
83 ""
84 {
85 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
86
87 tilegx_pre_atomic_barrier (model);
88 emit_insn (gen_atomic_exchange_bare<mode> (operands[0], operands[1],
89 operands[2]));
90 tilegx_post_atomic_barrier (model);
91 DONE;
92 })
93
94
95 (define_insn "atomic_exchange_bare<mode>"
96 [(set (match_operand:I48MODE 0 "register_operand" "=r")
97 (match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
98 (set (match_dup 1)
99 (unspec_volatile:I48MODE
100 [(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
101 UNSPEC_XCHG))]
102 ""
103 "exch<four_if_si>\t%0, %1, %r2"
104 [(set_attr "type" "X1_2cycle")])
105
106
107 (define_expand "atomic_fetch_<fetchop_name><mode>"
108 [(match_operand:I48MODE 0 "register_operand" "") ;; result
109 (match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
110 (unspec_volatile:I48MODE
111 [(fetchop:I48MODE
112 (match_dup 1)
113 (match_operand:I48MODE 2 "reg_or_0_operand" ""))] ;; value
114 UNSPEC_ATOMIC)
115 (match_operand:SI 3 "const_int_operand" "")] ;; model
116 ""
117 {
118 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
119
120 tilegx_pre_atomic_barrier (model);
121 emit_insn (gen_atomic_fetch_<fetchop_name>_bare<mode> (operands[0],
122 operands[1],
123 operands[2]));
124 tilegx_pre_atomic_barrier (model);
125 DONE;
126 })
127
128
129 (define_insn "atomic_fetch_<fetchop_name>_bare<mode>"
130 [(set (match_operand:I48MODE 0 "register_operand" "=r")
131 (match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
132 (set (match_dup 1)
133 (unspec_volatile:I48MODE
134 [(fetchop:I48MODE
135 (match_dup 1)
136 (match_operand:I48MODE 2 "reg_or_0_operand" "rO"))]
137 UNSPEC_ATOMIC))]
138 ""
139 "fetch<fetchop_name><four_if_si>\t%0, %1, %r2"
140 [(set_attr "type" "X1_2cycle")])
141
142
143 (define_expand "atomic_fetch_sub<mode>"
144 [(match_operand:I48MODE 0 "register_operand" "") ;; result
145 (match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
146 (unspec_volatile:I48MODE
147 [(minus:I48MODE
148 (match_dup 1)
149 (match_operand:I48MODE 2 "reg_or_0_operand" ""))] ;; value
150 UNSPEC_ATOMIC)
151 (match_operand:SI 3 "const_int_operand" "")] ;; model
152 ""
153 {
154 enum memmodel model = (enum memmodel) INTVAL (operands[3]);
155
156 if (operands[2] != const0_rtx)
157 emit_move_insn (operands[2], gen_rtx_NEG (<MODE>mode, operands[2]));
158
159 tilegx_pre_atomic_barrier (model);
160 emit_insn (gen_atomic_fetch_add_bare<mode> (operands[0],
161 operands[1],
162 operands[2]));
163 tilegx_pre_atomic_barrier (model);
164 DONE;
165 })