OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [ia64/] [sync.md] - Blame information for rev 713

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;; GCC machine description for IA-64 synchronization instructions.
2
;; Copyright (C) 2005, 2007, 2008, 2009, 2010
3
;; Free Software Foundation, Inc.
4
;;
5
;; This file is part of GCC.
6
;;
7
;; GCC is free software; you can redistribute it and/or modify
8
;; it under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
;;
12
;; GCC is distributed in the hope that it will be useful,
13
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
;; GNU General Public License for more details.
16
;;
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
;; Conversion to C++11 memory model based on
22
;; http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
23
 
24
(define_mode_iterator IMODE [QI HI SI DI])
25
(define_mode_iterator I124MODE [QI HI SI])
26
(define_mode_iterator I48MODE [SI DI])
27
(define_mode_attr modesuffix [(QI "1") (HI "2") (SI "4") (DI "8")])
28
 
29
(define_code_iterator FETCHOP [plus minus ior xor and])
30
(define_code_attr fetchop_name
31
  [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
32
 
33
(define_expand "mem_thread_fence"
34
  [(match_operand:SI 0 "const_int_operand" "")]         ;; model
35
  ""
36
{
37
  if (INTVAL (operands[0]) == MEMMODEL_SEQ_CST)
38
    emit_insn (gen_memory_barrier ());
39
  DONE;
40
})
41
 
42
(define_expand "memory_barrier"
43
  [(set (match_dup 0)
44
        (unspec:BLK [(match_dup 0)] UNSPEC_MF))]
45
  ""
46
{
47
  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
48
  MEM_VOLATILE_P (operands[0]) = 1;
49
})
50
 
51
(define_insn "*memory_barrier"
52
  [(set (match_operand:BLK 0 "" "")
53
        (unspec:BLK [(match_dup 0)] UNSPEC_MF))]
54
  ""
55
  "mf"
56
  [(set_attr "itanium_class" "syst_m")])
57
 
58
(define_expand "atomic_load"
59
  [(match_operand:IMODE 0 "gr_register_operand" "")             ;; output
60
   (match_operand:IMODE 1 "memory_operand" "")                  ;; memory
61
   (match_operand:SI 2 "const_int_operand" "")]                 ;; model
62
  ""
63
{
64
  enum memmodel model = (enum memmodel) INTVAL (operands[2]);
65
 
66
  /* Unless the memory model is relaxed, we want to emit ld.acq, which
67
     will happen automatically for volatile memories.  */
68
  gcc_assert (model == MEMMODEL_RELAXED || MEM_VOLATILE_P (operands[1]));
69
  emit_move_insn (operands[0], operands[1]);
70
  DONE;
71
})
72
 
73
(define_expand "atomic_store"
74
  [(match_operand:IMODE 0 "memory_operand" "")                  ;; memory
75
   (match_operand:IMODE 1 "gr_reg_or_0_operand" "")             ;; input
76
   (match_operand:SI 2 "const_int_operand" "")]                 ;; model
77
  ""
78
{
79
  enum memmodel model = (enum memmodel) INTVAL (operands[2]);
80
 
81
  /* Unless the memory model is relaxed, we want to emit st.rel, which
82
     will happen automatically for volatile memories.  */
83
  gcc_assert (model == MEMMODEL_RELAXED || MEM_VOLATILE_P (operands[0]));
84
  emit_move_insn (operands[0], operands[1]);
85
 
86
  /* Sequentially consistent stores need a subsequent MF.  See
87
     http://www.decadent.org.uk/pipermail/cpp-threads/2008-December/001952.html
88
     for a discussion of why a MF is needed here, but not for atomic_load.  */
89
  if (model == MEMMODEL_SEQ_CST)
90
    emit_insn (gen_memory_barrier ());
91
  DONE;
92
})
93
 
94
(define_expand "atomic_compare_and_swap"
95
  [(match_operand:DI 0 "gr_register_operand" "")                ;; bool out
96
   (match_operand:IMODE 1 "gr_register_operand" "")             ;; val out
97
   (match_operand:IMODE 2 "not_postinc_memory_operand" "")      ;; memory
98
   (match_operand:IMODE 3 "gr_register_operand" "")             ;; expected
99
   (match_operand:IMODE 4 "gr_reg_or_0_operand" "")             ;; desired
100
   (match_operand:SI 5 "const_int_operand" "")                  ;; is_weak
101
   (match_operand:SI 6 "const_int_operand" "")                  ;; succ model
102
   (match_operand:SI 7 "const_int_operand" "")]                 ;; fail model
103
  ""
104
{
105
  enum memmodel model = (enum memmodel) INTVAL (operands[6]);
106
  rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
107
  rtx dval, eval;
108
 
109
  eval = gen_reg_rtx (DImode);
110
  convert_move (eval, operands[3], 1);
111
  emit_move_insn (ccv, eval);
112
 
113
  if (mode == DImode)
114
    dval = operands[1];
115
  else
116
    dval = gen_reg_rtx (DImode);
117
 
118
  switch (model)
119
    {
120
    case MEMMODEL_RELAXED:
121
    case MEMMODEL_ACQUIRE:
122
    case MEMMODEL_CONSUME:
123
      emit_insn (gen_cmpxchg_acq_ (dval, operands[2], ccv, operands[4]));
124
      break;
125
    case MEMMODEL_RELEASE:
126
      emit_insn (gen_cmpxchg_rel_ (dval, operands[2], ccv, operands[4]));
127
      break;
128
    case MEMMODEL_ACQ_REL:
129
    case MEMMODEL_SEQ_CST:
130
      emit_insn (gen_cmpxchg_rel_ (dval, operands[2], ccv, operands[4]));
131
      emit_insn (gen_memory_barrier ());
132
      break;
133
    default:
134
      gcc_unreachable ();
135
    }
136
 
137
  if (mode != DImode)
138
    emit_move_insn (operands[1], gen_lowpart (mode, dval));
139
 
140
  emit_insn (gen_cstoredi4 (operands[0], gen_rtx_EQ (DImode, dval, eval),
141
                            dval, eval));
142
  DONE;
143
})
144
 
145
(define_insn "cmpxchg_acq_"
146
  [(set (match_operand:DI 0 "gr_register_operand" "=r")
147
        (zero_extend:DI
148
          (match_operand:I124MODE 1 "not_postinc_memory_operand" "+S")))
149
   (set (match_dup 1)
150
        (unspec:I124MODE
151
          [(match_dup 1)
152
           (match_operand:DI 2 "ar_ccv_reg_operand" "")
153
           (match_operand:I124MODE 3 "gr_reg_or_0_operand" "rO")]
154
          UNSPEC_CMPXCHG_ACQ))]
155
  ""
156
  "cmpxchg.acq %0 = %1, %r3, %2"
157
  [(set_attr "itanium_class" "sem")])
158
 
159
(define_insn "cmpxchg_rel_"
160
  [(set (match_operand:DI 0 "gr_register_operand" "=r")
161
        (zero_extend:DI
162
          (match_operand:I124MODE 1 "not_postinc_memory_operand" "+S")))
163
   (set (match_dup 1)
164
        (unspec:I124MODE
165
          [(match_dup 1)
166
           (match_operand:DI 2 "ar_ccv_reg_operand" "")
167
           (match_operand:I124MODE 3 "gr_reg_or_0_operand" "rO")]
168
          UNSPEC_CMPXCHG_REL))]
169
  ""
170
  "cmpxchg.rel %0 = %1, %r3, %2"
171
  [(set_attr "itanium_class" "sem")])
172
 
173
(define_insn "cmpxchg_acq_di"
174
  [(set (match_operand:DI 0 "gr_register_operand" "=r")
175
        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
176
   (set (match_dup 1)
177
        (unspec:DI [(match_dup 1)
178
                    (match_operand:DI 2 "ar_ccv_reg_operand" "")
179
                    (match_operand:DI 3 "gr_reg_or_0_operand" "rO")]
180
                   UNSPEC_CMPXCHG_ACQ))]
181
  ""
182
  "cmpxchg8.acq %0 = %1, %r3, %2"
183
  [(set_attr "itanium_class" "sem")])
184
 
185
(define_insn "cmpxchg_rel_di"
186
  [(set (match_operand:DI 0 "gr_register_operand" "=r")
187
        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
188
   (set (match_dup 1)
189
        (unspec:DI [(match_dup 1)
190
                    (match_operand:DI 2 "ar_ccv_reg_operand" "")
191
                    (match_operand:DI 3 "gr_reg_or_0_operand" "rO")]
192
                   UNSPEC_CMPXCHG_REL))]
193
  ""
194
  "cmpxchg8.rel %0 = %1, %r3, %2"
195
  [(set_attr "itanium_class" "sem")])
196
 
197
(define_expand "atomic_exchange"
198
  [(match_operand:IMODE 0 "gr_register_operand" "")             ;; output
199
   (match_operand:IMODE 1 "not_postinc_memory_operand" "")      ;; memory
200
   (match_operand:IMODE 2 "gr_reg_or_0_operand" "")             ;; input
201
   (match_operand:SI 3 "const_int_operand" "")]                 ;; succ model
202
  ""
203
{
204
  enum memmodel model = (enum memmodel) INTVAL (operands[3]);
205
 
206
  switch (model)
207
    {
208
    case MEMMODEL_RELAXED:
209
    case MEMMODEL_ACQUIRE:
210
    case MEMMODEL_CONSUME:
211
      break;
212
    case MEMMODEL_RELEASE:
213
    case MEMMODEL_ACQ_REL:
214
    case MEMMODEL_SEQ_CST:
215
      emit_insn (gen_memory_barrier ());
216
      break;
217
    default:
218
      gcc_unreachable ();
219
    }
220
  emit_insn (gen_xchg_acq_ (operands[0], operands[1], operands[2]));
221
  DONE;
222
})
223
 
224
;; Note that XCHG is always memory model acquire.
225
(define_insn "xchg_acq_"
226
  [(set (match_operand:IMODE 0 "gr_register_operand" "=r")
227
        (match_operand:IMODE 1 "not_postinc_memory_operand" "+S"))
228
   (set (match_dup 1)
229
        (match_operand:IMODE 2 "gr_reg_or_0_operand" "rO"))]
230
  ""
231
  "xchg %0 = %1, %r2"
232
  [(set_attr "itanium_class" "sem")])
233
 
234
(define_expand "atomic_"
235
  [(set (match_operand:IMODE 0 "memory_operand" "")
236
        (FETCHOP:IMODE (match_dup 0)
237
          (match_operand:IMODE 1 "nonmemory_operand" "")))
238
   (use (match_operand:SI 2 "const_int_operand" ""))]
239
  ""
240
{
241
  ia64_expand_atomic_op (, operands[0], operands[1], NULL, NULL,
242
                         (enum memmodel) INTVAL (operands[2]));
243
  DONE;
244
})
245
 
246
(define_expand "atomic_nand"
247
  [(set (match_operand:IMODE 0 "memory_operand" "")
248
        (not:IMODE
249
          (and:IMODE (match_dup 0)
250
                     (match_operand:IMODE 1 "nonmemory_operand" ""))))
251
   (use (match_operand:SI 2 "const_int_operand" ""))]
252
  ""
253
{
254
  ia64_expand_atomic_op (NOT, operands[0], operands[1], NULL, NULL,
255
                         (enum memmodel) INTVAL (operands[2]));
256
  DONE;
257
})
258
 
259
(define_expand "atomic_fetch_"
260
  [(set (match_operand:IMODE 0 "gr_register_operand" "")
261
        (FETCHOP:IMODE
262
          (match_operand:IMODE 1 "memory_operand" "")
263
          (match_operand:IMODE 2 "nonmemory_operand" "")))
264
   (use (match_operand:SI 3 "const_int_operand" ""))]
265
  ""
266
{
267
  ia64_expand_atomic_op (, operands[1], operands[2], operands[0], NULL,
268
                         (enum memmodel) INTVAL (operands[3]));
269
  DONE;
270
})
271
 
272
(define_expand "atomic_fetch_nand"
273
  [(set (match_operand:IMODE 0 "gr_register_operand" "")
274
        (not:IMODE
275
          (and:IMODE (match_operand:IMODE 1 "memory_operand" "")
276
                     (match_operand:IMODE 2 "nonmemory_operand" ""))))
277
   (use (match_operand:SI 3 "const_int_operand" ""))]
278
  ""
279
{
280
  ia64_expand_atomic_op (NOT, operands[1], operands[2], operands[0], NULL,
281
                         (enum memmodel) INTVAL (operands[3]));
282
  DONE;
283
})
284
 
285
(define_expand "atomic__fetch"
286
  [(set (match_operand:IMODE 0 "gr_register_operand" "")
287
        (FETCHOP:IMODE
288
          (match_operand:IMODE 1 "memory_operand" "")
289
          (match_operand:IMODE 2 "nonmemory_operand" "")))
290
   (use (match_operand:SI 3 "const_int_operand" ""))]
291
  ""
292
{
293
  ia64_expand_atomic_op (, operands[1], operands[2], NULL, operands[0],
294
                         (enum memmodel) INTVAL (operands[3]));
295
  DONE;
296
})
297
 
298
(define_expand "atomic_nand_fetch"
299
  [(set (match_operand:IMODE 0 "gr_register_operand" "")
300
        (not:IMODE
301
          (and:IMODE (match_operand:IMODE 1 "memory_operand" "")
302
                     (match_operand:IMODE 2 "nonmemory_operand" ""))))
303
   (use (match_operand:SI 3 "const_int_operand" ""))]
304
  ""
305
{
306
  ia64_expand_atomic_op (NOT, operands[1], operands[2], NULL, operands[0],
307
                         (enum memmodel) INTVAL (operands[3]));
308
  DONE;
309
})
310
 
311
(define_insn "fetchadd_acq_"
312
  [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
313
        (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
314
   (set (match_dup 1)
315
        (unspec:I48MODE [(match_dup 1)
316
                         (match_operand:I48MODE 2 "fetchadd_operand" "n")]
317
                        UNSPEC_FETCHADD_ACQ))]
318
  ""
319
  "fetchadd.acq %0 = %1, %2"
320
  [(set_attr "itanium_class" "sem")])
321
 
322
(define_insn "fetchadd_rel_"
323
  [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
324
        (match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
325
   (set (match_dup 1)
326
        (unspec:I48MODE [(match_dup 1)
327
                         (match_operand:I48MODE 2 "fetchadd_operand" "n")]
328
                        UNSPEC_FETCHADD_REL))]
329
  ""
330
  "fetchadd.rel %0 = %1, %2"
331
  [(set_attr "itanium_class" "sem")])

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.