Import a stripped down version of gcc-4.1.1
[dragonfly.git] / contrib / gcc-4.1 / gcc / config / i386 / sync.md
1 ;; GCC machine description for i386 synchronization instructions.
2 ;; Copyright (C) 2005
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 2, 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 COPYING.  If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
21
22 (define_mode_macro IMODE [QI HI SI (DI "TARGET_64BIT")])
23 (define_mode_attr modesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
24 (define_mode_attr modeconstraint [(QI "q") (HI "r") (SI "r") (DI "r")])
25 (define_mode_attr immconstraint [(QI "i") (HI "i") (SI "i") (DI "e")])
26
27 ;; ??? It would be possible to use cmpxchg8b on pentium for DImode
28 ;; changes.  It's complicated because the insn uses ecx:ebx as the
29 ;; new value; note that the registers are reversed from the order
30 ;; that they'd be in with (reg:DI 2 ecx).  Similarly for TImode 
31 ;; data in 64-bit mode.
32
33 (define_insn "sync_compare_and_swap<mode>"
34   [(set (match_operand:IMODE 0 "register_operand" "=a")
35         (match_operand:IMODE 1 "memory_operand" "+m"))
36    (set (match_dup 1)
37         (unspec_volatile:IMODE
38           [(match_dup 1)
39            (match_operand:IMODE 2 "register_operand" "a")
40            (match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
41           UNSPECV_CMPXCHG_1))
42    (clobber (reg:CC FLAGS_REG))]
43   "TARGET_CMPXCHG"
44   "lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
45
46 (define_expand "sync_compare_and_swap_cc<mode>"
47   [(parallel
48     [(set (match_operand:IMODE 0 "register_operand" "")
49           (match_operand:IMODE 1 "memory_operand" ""))
50      (set (match_dup 1)
51           (unspec_volatile:IMODE
52             [(match_dup 1)
53              (match_operand:IMODE 2 "register_operand" "")
54              (match_operand:IMODE 3 "register_operand" "")]
55             UNSPECV_CMPXCHG_1))
56      (set (match_dup 4)
57           (compare:CCZ
58             (unspec_volatile:IMODE
59               [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
60             (match_dup 2)))])]
61   "TARGET_CMPXCHG"
62 {
63   operands[4] = gen_rtx_REG (CCZmode, FLAGS_REG);
64   ix86_compare_op0 = operands[3];
65   ix86_compare_op1 = NULL;
66   ix86_compare_emitted = operands[4];
67 })
68
69 (define_insn "*sync_compare_and_swap_cc<mode>"
70   [(set (match_operand:IMODE 0 "register_operand" "=a")
71         (match_operand:IMODE 1 "memory_operand" "+m"))
72    (set (match_dup 1)
73         (unspec_volatile:IMODE
74           [(match_dup 1)
75            (match_operand:IMODE 2 "register_operand" "a")
76            (match_operand:IMODE 3 "register_operand" "<modeconstraint>")]
77           UNSPECV_CMPXCHG_1))
78    (set (reg:CCZ FLAGS_REG)
79         (compare:CCZ
80           (unspec_volatile:IMODE
81             [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_CMPXCHG_2)
82           (match_dup 2)))]
83   "TARGET_CMPXCHG"
84   "lock\;cmpxchg{<modesuffix>}\t{%3, %1|%1, %3}")
85
86 (define_insn "sync_old_add<mode>"
87   [(set (match_operand:IMODE 0 "register_operand" "=<modeconstraint>")
88         (unspec_volatile:IMODE
89           [(match_operand:IMODE 1 "memory_operand" "+m")] UNSPECV_XCHG))
90    (set (match_dup 1)
91         (plus:IMODE (match_dup 1)
92                     (match_operand:IMODE 2 "register_operand" "0")))
93    (clobber (reg:CC FLAGS_REG))]
94   "TARGET_XADD"
95   "lock\;xadd{<modesuffix>}\t{%0, %1|%1, %0}")
96
97 ;; Recall that xchg implicitly sets LOCK#, so adding it again wastes space.
98 (define_insn "sync_lock_test_and_set<mode>"
99   [(set (match_operand:IMODE 0 "register_operand" "=<modeconstraint>")
100         (unspec_volatile:IMODE
101           [(match_operand:IMODE 1 "memory_operand" "+m")] UNSPECV_XCHG))
102    (set (match_dup 1)
103         (match_operand:IMODE 2 "register_operand" "0"))]
104   ""
105   "xchg{<modesuffix>}\t{%1, %0|%0, %1}")
106
107 (define_insn "sync_add<mode>"
108   [(set (match_operand:IMODE 0 "memory_operand" "=m")
109         (unspec_volatile:IMODE
110           [(plus:IMODE (match_dup 0)
111              (match_operand:IMODE 1 "nonmemory_operand" "r<immconstraint>"))]
112           UNSPECV_LOCK))
113    (clobber (reg:CC FLAGS_REG))]
114   ""
115   "lock\;add{<modesuffix>}\t{%1, %0|%0, %1}")
116
117 (define_insn "sync_sub<mode>"
118   [(set (match_operand:IMODE 0 "memory_operand" "=m")
119         (unspec_volatile:IMODE
120           [(minus:IMODE (match_dup 0)
121              (match_operand:IMODE 1 "nonmemory_operand" "r<immconstraint>"))]
122           UNSPECV_LOCK))
123    (clobber (reg:CC FLAGS_REG))]
124   ""
125   "lock\;sub{<modesuffix>}\t{%1, %0|%0, %1}")
126
127 (define_insn "sync_ior<mode>"
128   [(set (match_operand:IMODE 0 "memory_operand" "=m")
129         (unspec_volatile:IMODE
130           [(ior:IMODE (match_dup 0)
131              (match_operand:IMODE 1 "nonmemory_operand" "r<immconstraint>"))]
132           UNSPECV_LOCK))
133    (clobber (reg:CC FLAGS_REG))]
134   ""
135   "lock\;or{<modesuffix>}\t{%1, %0|%0, %1}")
136
137 (define_insn "sync_and<mode>"
138   [(set (match_operand:IMODE 0 "memory_operand" "=m")
139         (unspec_volatile:IMODE
140           [(and:IMODE (match_dup 0)
141              (match_operand:IMODE 1 "nonmemory_operand" "r<immconstraint>"))]
142           UNSPECV_LOCK))
143    (clobber (reg:CC FLAGS_REG))]
144   ""
145   "lock\;and{<modesuffix>}\t{%1, %0|%0, %1}")
146
147 (define_insn "sync_xor<mode>"
148   [(set (match_operand:IMODE 0 "memory_operand" "=m")
149         (unspec_volatile:IMODE
150           [(xor:IMODE (match_dup 0)
151              (match_operand:IMODE 1 "nonmemory_operand" "r<immconstraint>"))]
152           UNSPECV_LOCK))
153    (clobber (reg:CC FLAGS_REG))]
154   ""
155   "lock\;xor{<modesuffix>}\t{%1, %0|%0, %1}")