]>
Commit | Line | Data |
---|---|---|
c4e75102 | 1 | ;; builtin definitions for DEC VAX. |
83ffe9cd | 2 | ;; Copyright (C) 2007-2023 Free Software Foundation, Inc. |
c4e75102 MT |
3 | ;; |
4 | ;; This file is part of GCC. | |
5 | ;; | |
6 | ;; GCC is free software; you can redistribute it and/or modify it under | |
7 | ;; the terms of the GNU General Public License as published by the Free | |
8 | ;; Software Foundation; either version 3, or (at your option) any later | |
9 | ;; version. | |
10 | ;; | |
11 | ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 | ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | ;; for more details. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
17 | ;; along with GCC; see the file COPYING3. If not see | |
18 | ;; <http://www.gnu.org/licenses/>. | |
19 | ||
20 | (define_constants | |
21 | [ | |
fbe57595 | 22 | (VUNSPEC_LOCK 100) ; sync lock operations |
c4e75102 MT |
23 | ] |
24 | ) | |
25 | ||
273ffa3a | 26 | (define_mode_attr width [(QI "8") (HI "16") (SI "32")]) |
47d524a6 MR |
27 | (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")]) |
28 | ||
2500add2 MR |
29 | (define_int_iterator bit [0 1]) |
30 | (define_int_attr ccss [(0 "cc") (1 "ss")]) | |
31 | ||
b9240a4a MR |
32 | (define_code_iterator any_extend [sign_extend zero_extend]) |
33 | ||
273ffa3a | 34 | (define_expand "ffs<mode>2" |
c4e75102 | 35 | [(set (match_operand:SI 0 "nonimmediate_operand" "") |
273ffa3a | 36 | (ffs:SI (match_operand:VAXint 1 "general_operand" "")))] |
c4e75102 MT |
37 | "" |
38 | " | |
39 | { | |
40 | rtx label = gen_label_rtx (); | |
8c18e22a | 41 | rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label); |
e552abe2 | 42 | rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx); |
8c18e22a MR |
43 | rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); |
44 | ||
e552abe2 | 45 | emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1])); |
8c18e22a | 46 | emit_jump_insn (gen_rtx_SET (pc_rtx, target)); |
273ffa3a | 47 | emit_insn (gen_neg<mode>2 (operands[0], const1_rtx)); |
c4e75102 | 48 | emit_label (label); |
273ffa3a | 49 | emit_insn (gen_add<mode>3 (operands[0], operands[0], const1_rtx)); |
c4e75102 MT |
50 | DONE; |
51 | }") | |
52 | ||
e552abe2 MR |
53 | (define_insn_and_split "ctz<mode>2" |
54 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") | |
55 | (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] | |
56 | "" | |
57 | "#" | |
58 | "reload_completed" | |
59 | [(parallel | |
60 | [(set (match_dup 0) | |
61 | (ctz:SI (match_dup 1))) | |
62 | (clobber (reg:CC VAX_PSL_REGNUM))])] | |
63 | "") | |
64 | ||
65 | (define_insn "*ctz<mode>2" | |
c4e75102 | 66 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") |
273ffa3a | 67 | (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT"))) |
e552abe2 MR |
68 | (clobber (reg:CC VAX_PSL_REGNUM))] |
69 | "reload_completed" | |
70 | "ffs $0,$<width>,%1,%0") | |
71 | ||
72 | (define_insn_and_split "ctz<mode>2_ccz" | |
73 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") | |
74 | (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] | |
c4e75102 | 75 | "" |
e552abe2 MR |
76 | "#" |
77 | "reload_completed" | |
78 | [(parallel | |
79 | [(set (reg:CCZ VAX_PSL_REGNUM) | |
80 | (compare:CCZ (match_dup 1) | |
81 | (const_int 0))) | |
82 | (set (match_dup 0) | |
83 | (ctz:SI (match_dup 1)))])] | |
84 | "") | |
85 | ||
86 | (define_insn "*ctz<mode>2_ccz" | |
87 | [(set (reg:CCZ VAX_PSL_REGNUM) | |
88 | (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT") | |
89 | (const_int 0))) | |
90 | (set (match_operand:SI 0 "nonimmediate_operand" "=rQ") | |
91 | (ctz:SI (match_dup 1)))] | |
92 | "reload_completed" | |
273ffa3a | 93 | "ffs $0,$<width>,%1,%0") |
c4e75102 | 94 | |
b9240a4a MR |
95 | ;; Our FFS hardware instruction supports any field width, |
96 | ;; so handle narrower inputs directly as well. | |
97 | (define_peephole2 | |
e552abe2 MR |
98 | [(parallel |
99 | [(set (match_operand:SI 0 "register_operand") | |
100 | (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) | |
101 | (clobber (reg:CC VAX_PSL_REGNUM))]) | |
b9240a4a MR |
102 | (parallel |
103 | [(set (match_operand:SI 2 "nonimmediate_operand") | |
104 | (ctz:SI (match_dup 0))) | |
e552abe2 | 105 | (clobber (reg:CC VAX_PSL_REGNUM))])] |
b9240a4a MR |
106 | "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])" |
107 | [(parallel | |
108 | [(set (match_dup 2) | |
109 | (ctz:SI (match_dup 1))) | |
e552abe2 MR |
110 | (clobber (reg:CC VAX_PSL_REGNUM))])] |
111 | "") | |
112 | ||
113 | ;; The FFS hardware instruction sets the Z condition code based on | |
114 | ;; the input field rather than the output operand, so the compare | |
115 | ;; elimination pass cannot handle it. Try to get rid of the extra | |
116 | ;; operation by hand. | |
117 | ;; | |
118 | ;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to | |
119 | ;; have a mode dependent address, so all we need to verify is that | |
120 | ;; the two operands are not the same, in which case it's the FFS | |
121 | ;; output rather than input that condition codes are checked for. | |
122 | (define_peephole2 | |
123 | [(parallel | |
124 | [(set (match_operand:SI 0 "nonimmediate_operand") | |
125 | (ctz:SI (match_operand:VAXint 1 "general_operand"))) | |
126 | (clobber (reg:CC VAX_PSL_REGNUM))]) | |
127 | (set (reg:CCZ VAX_PSL_REGNUM) | |
128 | (compare:CCZ (match_dup 1) | |
129 | (const_int 0)))] | |
130 | "!rtx_equal_p (operands[0], operands[1])" | |
131 | [(parallel | |
132 | [(set (reg:CCZ VAX_PSL_REGNUM) | |
133 | (compare:CCZ (match_dup 1) | |
134 | (const_int 0))) | |
135 | (set (match_dup 0) | |
136 | (ctz:SI (match_dup 1)))])] | |
137 | "") | |
138 | ||
139 | ;; This effectively combines the two peepholes above, | |
140 | ;; matching the sequence produced by `ffs<mode>2'. | |
141 | (define_peephole2 | |
142 | [(parallel | |
143 | [(set (match_operand:SI 0 "register_operand") | |
144 | (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) | |
145 | (clobber (reg:CC VAX_PSL_REGNUM))]) | |
146 | (parallel | |
147 | [(set (match_operand:SI 2 "nonimmediate_operand") | |
148 | (ctz:SI (match_dup 0))) | |
149 | (clobber (reg:CC VAX_PSL_REGNUM))]) | |
150 | (set (reg:CCZ VAX_PSL_REGNUM) | |
151 | (compare:CCZ (match_dup 0) | |
152 | (const_int 0)))] | |
153 | "!rtx_equal_p (operands[0], operands[2]) | |
154 | && peep2_reg_dead_p (3, operands[0])" | |
155 | [(parallel | |
156 | [(set (reg:CCZ VAX_PSL_REGNUM) | |
157 | (compare:CCZ (match_dup 1) | |
158 | (const_int 0))) | |
159 | (set (match_dup 2) | |
160 | (ctz:SI (match_dup 1)))])] | |
b9240a4a MR |
161 | "") |
162 | ||
c4e75102 | 163 | (define_expand "sync_lock_test_and_set<mode>" |
fbe57595 MR |
164 | [(match_operand:VAXint 0 "nonimmediate_operand" "=&g") |
165 | (match_operand:VAXint 1 "memory_operand" "+m") | |
166 | (match_operand:VAXint 2 "const_int_operand" "n")] | |
c4e75102 MT |
167 | "" |
168 | " | |
169 | { | |
170 | rtx label; | |
171 | ||
172 | if (operands[2] != const1_rtx) | |
173 | FAIL; | |
174 | ||
175 | label = gen_label_rtx (); | |
176 | emit_move_insn (operands[0], const1_rtx); | |
f3bfed33 | 177 | emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label)); |
c4e75102 MT |
178 | emit_move_insn (operands[0], const0_rtx); |
179 | emit_label (label); | |
180 | DONE; | |
181 | }") | |
182 | ||
c4e75102 | 183 | (define_expand "sync_lock_release<mode>" |
fbe57595 MR |
184 | [(match_operand:VAXint 0 "memory_operand" "+m") |
185 | (match_operand:VAXint 1 "const_int_operand" "n")] | |
c4e75102 MT |
186 | "" |
187 | " | |
188 | { | |
189 | rtx label; | |
fbe57595 | 190 | |
c4e75102 MT |
191 | if (operands[1] != const0_rtx) |
192 | FAIL; | |
fbe57595 | 193 | |
c4e75102 | 194 | label = gen_label_rtx (); |
f3bfed33 | 195 | emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label)); |
c4e75102 | 196 | emit_label (label); |
c4e75102 MT |
197 | DONE; |
198 | }") | |
199 | ||
2500add2 | 200 | (define_insn "jbb<ccss>i<mode>" |
fbe57595 | 201 | [(unspec_volatile |
c4e75102 MT |
202 | [(set (pc) |
203 | (if_then_else | |
47d524a6 | 204 | (eq (zero_extract:SI |
f3bfed33 | 205 | (match_operand:VAXint 0 "any_memory_operand" "+<bb_mem>") |
47d524a6 MR |
206 | (const_int 1) |
207 | (match_operand:SI 1 "general_operand" "nrmT")) | |
2500add2 | 208 | (const_int bit)) |
c4e75102 MT |
209 | (label_ref (match_operand 2 "" "")) |
210 | (pc))) | |
f3bfed33 | 211 | (set (zero_extract:SI (match_dup 0) |
c4e75102 MT |
212 | (const_int 1) |
213 | (match_dup 1)) | |
fbe57595 MR |
214 | (const_int bit))] |
215 | VUNSPEC_LOCK)] | |
c4e75102 | 216 | "" |
2500add2 | 217 | "jb<ccss>i %1,%0,%l2") |