xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/ia64/sync.md (revision f14316bcbc544b96a93e884bc5c2b15fd60e22ae)
1;; 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;; <http://www.gnu.org/licenses/>.
20
21(define_mode_iterator IMODE [QI HI SI DI])
22(define_mode_iterator I124MODE [QI HI SI])
23(define_mode_iterator I48MODE [SI DI])
24(define_mode_attr modesuffix [(QI "1") (HI "2") (SI "4") (DI "8")])
25
26(define_code_iterator FETCHOP [plus minus ior xor and])
27(define_code_attr fetchop_name
28  [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
29
30(define_expand "memory_barrier"
31  [(set (match_dup 0)
32	(unspec:BLK [(match_dup 0)] UNSPEC_MF))]
33  ""
34{
35  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
36  MEM_VOLATILE_P (operands[0]) = 1;
37})
38
39(define_insn "*memory_barrier"
40  [(set (match_operand:BLK 0 "" "")
41	(unspec:BLK [(match_dup 0)] UNSPEC_MF))]
42  ""
43  "mf"
44  [(set_attr "itanium_class" "syst_m")])
45
46(define_insn "fetchadd_acq_<mode>"
47  [(set (match_operand:I48MODE 0 "gr_register_operand" "=r")
48	(match_operand:I48MODE 1 "not_postinc_memory_operand" "+S"))
49   (set (match_dup 1)
50	(unspec:I48MODE [(match_dup 1)
51			 (match_operand:I48MODE 2 "fetchadd_operand" "n")]
52		        UNSPEC_FETCHADD_ACQ))]
53  ""
54  "fetchadd<modesuffix>.acq %0 = %1, %2"
55  [(set_attr "itanium_class" "sem")])
56
57(define_expand "sync_<fetchop_name><mode>"
58  [(set (match_operand:IMODE 0 "memory_operand" "")
59	(FETCHOP:IMODE (match_dup 0)
60	  (match_operand:IMODE 1 "general_operand" "")))]
61  ""
62{
63  ia64_expand_atomic_op (<CODE>, operands[0], operands[1], NULL, NULL);
64  DONE;
65})
66
67(define_expand "sync_nand<mode>"
68  [(set (match_operand:IMODE 0 "memory_operand" "")
69	(not:IMODE
70	  (and:IMODE (match_dup 0)
71		     (match_operand:IMODE 1 "general_operand" ""))))]
72  ""
73{
74  ia64_expand_atomic_op (NOT, operands[0], operands[1], NULL, NULL);
75  DONE;
76})
77
78(define_expand "sync_old_<fetchop_name><mode>"
79  [(set (match_operand:IMODE 0 "gr_register_operand" "")
80	(FETCHOP:IMODE
81	  (match_operand:IMODE 1 "memory_operand" "")
82	  (match_operand:IMODE 2 "general_operand" "")))]
83  ""
84{
85  ia64_expand_atomic_op (<CODE>, operands[1], operands[2], operands[0], NULL);
86  DONE;
87})
88
89(define_expand "sync_old_nand<mode>"
90  [(set (match_operand:IMODE 0 "gr_register_operand" "")
91	(not:IMODE
92	  (and:IMODE (match_operand:IMODE 1 "memory_operand" "")
93		     (match_operand:IMODE 2 "general_operand" ""))))]
94  ""
95{
96  ia64_expand_atomic_op (NOT, operands[1], operands[2], operands[0], NULL);
97  DONE;
98})
99
100(define_expand "sync_new_<fetchop_name><mode>"
101  [(set (match_operand:IMODE 0 "gr_register_operand" "")
102	(FETCHOP:IMODE
103	  (match_operand:IMODE 1 "memory_operand" "")
104	  (match_operand:IMODE 2 "general_operand" "")))]
105  ""
106{
107  ia64_expand_atomic_op (<CODE>, operands[1], operands[2], NULL, operands[0]);
108  DONE;
109})
110
111(define_expand "sync_new_nand<mode>"
112  [(set (match_operand:IMODE 0 "gr_register_operand" "")
113	(not:IMODE
114	  (and:IMODE (match_operand:IMODE 1 "memory_operand" "")
115		     (match_operand:IMODE 2 "general_operand" ""))))]
116  ""
117{
118  ia64_expand_atomic_op (NOT, operands[1], operands[2], NULL, operands[0]);
119  DONE;
120})
121
122(define_expand "sync_compare_and_swap<mode>"
123  [(match_operand:IMODE 0 "gr_register_operand" "")
124   (match_operand:IMODE 1 "memory_operand" "")
125   (match_operand:IMODE 2 "gr_register_operand" "")
126   (match_operand:IMODE 3 "gr_register_operand" "")]
127  ""
128{
129  rtx ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
130  rtx dst;
131
132  convert_move (ccv, operands[2], 1);
133
134  dst = operands[0];
135  if (GET_MODE (dst) != DImode)
136    dst = gen_reg_rtx (DImode);
137
138  emit_insn (gen_cmpxchg_rel_<mode> (dst, operands[1], ccv, operands[3]));
139  emit_insn (gen_memory_barrier ());
140
141  if (dst != operands[0])
142    emit_move_insn (operands[0], gen_lowpart (<MODE>mode, dst));
143  DONE;
144})
145
146(define_insn "cmpxchg_rel_<mode>"
147  [(set (match_operand:DI 0 "gr_register_operand" "=r")
148	(zero_extend:DI
149	  (match_operand:I124MODE 1 "not_postinc_memory_operand" "+S")))
150   (set (match_dup 1)
151        (unspec:I124MODE
152	  [(match_dup 1)
153	   (match_operand:DI 2 "ar_ccv_reg_operand" "")
154	   (match_operand:I124MODE 3 "gr_reg_or_0_operand" "rO")]
155	  UNSPEC_CMPXCHG_ACQ))]
156  ""
157  "cmpxchg<modesuffix>.rel %0 = %1, %r3, %2"
158  [(set_attr "itanium_class" "sem")])
159
160(define_insn "cmpxchg_rel_di"
161  [(set (match_operand:DI 0 "gr_register_operand" "=r")
162	(match_operand:DI 1 "not_postinc_memory_operand" "+S"))
163   (set (match_dup 1)
164        (unspec:DI [(match_dup 1)
165		    (match_operand:DI 2 "ar_ccv_reg_operand" "")
166		    (match_operand:DI 3 "gr_reg_or_0_operand" "rO")]
167		   UNSPEC_CMPXCHG_ACQ))]
168  ""
169  "cmpxchg8.rel %0 = %1, %r3, %2"
170  [(set_attr "itanium_class" "sem")])
171
172(define_insn "sync_lock_test_and_set<mode>"
173  [(set (match_operand:IMODE 0 "gr_register_operand" "=r")
174        (match_operand:IMODE 1 "not_postinc_memory_operand" "+S"))
175   (set (match_dup 1)
176        (match_operand:IMODE 2 "gr_reg_or_0_operand" "rO"))]
177  ""
178  "xchg<modesuffix> %0 = %1, %r2"
179  [(set_attr "itanium_class" "sem")])
180
181(define_expand "sync_lock_release<mode>"
182  [(set (match_operand:IMODE 0 "memory_operand" "")
183	(match_operand:IMODE 1 "gr_reg_or_0_operand" ""))]
184  ""
185{
186  gcc_assert (MEM_VOLATILE_P (operands[0]));
187})
188