|
20 | 20 | ;; Operations which can be used with atomic loads and stores.
|
21 | 21 | (define_code_iterator ATOPS [plus minus ior xor and])
|
22 | 22 |
|
| 23 | +;; Operations which are supported by hardware. |
| 24 | +(define_code_iterator ATHWOPS [plus ior xor and]) |
| 25 | + |
23 | 26 | (define_expand "memory_barrier"
|
24 | 27 | [(set (match_dup 0)
|
25 | 28 | (unspec:BLK [(match_dup 0)] ARC64_UNSPEC_MEMBAR))]
|
|
82 | 85 | [(match_operand:GPI 1 "mem_noofs_operand" "ATOMC")]
|
83 | 86 | ARC64_VUNSPEC_LL))]
|
84 | 87 | "ARC64_HAS_ATOMIC_1"
|
85 |
| - "llock<mcctab> %0,%1" |
| 88 | + "llock<mcctab>\\t%0,%1" |
86 | 89 | [(set_attr "type" "llock")
|
87 | 90 | (set_attr "iscompact" "no")
|
88 | 91 | (set_attr "predicable" "no")
|
|
94 | 97 | ARC64_VUNSPEC_SC))
|
95 | 98 | (clobber (reg:CC_Z CC_REGNUM))]
|
96 | 99 | "ARC64_HAS_ATOMIC_1"
|
97 |
| - "scond<mcctab> %1,%0" |
| 100 | + "scond<mcctab>\\t%1,%0" |
98 | 101 | [(set_attr "type" "scond")
|
99 | 102 | (set_attr "iscompact" "no")
|
100 | 103 | (set_attr "predicable" "no")
|
|
122 | 125 | (set (match_dup 1)
|
123 | 126 | (match_operand:GPI 2 "register_operand" "0"))]
|
124 | 127 | ""
|
125 |
| - "ex<mcctab> %0,%1" |
| 128 | + "ex<mcctab>\\t%0,%1" |
126 | 129 | [(set_attr "type" "ex")
|
127 | 130 | (set_attr "iscompact" "no")
|
128 | 131 | (set_attr "predicable" "no")
|
129 | 132 | (set_attr "length" "*")])
|
130 | 133 |
|
| 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 | + |
131 | 157 | (define_expand "atomic_<optab><mode>"
|
132 | 158 | [(match_operand:GPI 0 "mem_noofs_operand" "") ;; memory
|
133 | 159 | (ATOPS:GPI (match_dup 0)
|
|
152 | 178 | })
|
153 | 179 |
|
154 | 180 | (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))] |
160 | 189 | "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 | + }) |
166 | 221 |
|
167 | 222 | (define_expand "atomic_fetch_nand<mode>"
|
168 | 223 | [(match_operand:GPI 0 "register_operand" "") ;; output
|
|
201 | 256 | DONE;
|
202 | 257 | })
|
203 | 258 |
|
| 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