]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/vax/builtins.md
PR target/95294: VAX: Convert backend to MODE_CC representation
[thirdparty/gcc.git] / gcc / config / vax / builtins.md
1 ;; builtin definitions for DEC VAX.
2 ;; Copyright (C) 2007-2020 Free Software Foundation, Inc.
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 [
22 (VUNSPEC_LOCK 100) ; sync lock operations
23 ]
24 )
25
26 (define_mode_attr width [(QI "8") (HI "16") (SI "32")])
27 (define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")])
28
29 (define_int_iterator bit [0 1])
30 (define_int_attr ccss [(0 "cc") (1 "ss")])
31
32 (define_code_iterator any_extend [sign_extend zero_extend])
33
34 (define_expand "ffs<mode>2"
35 [(set (match_operand:SI 0 "nonimmediate_operand" "")
36 (ffs:SI (match_operand:VAXint 1 "general_operand" "")))]
37 ""
38 "
39 {
40 rtx label = gen_label_rtx ();
41 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
42 rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx);
43 rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
44
45 emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1]));
46 emit_jump_insn (gen_rtx_SET (pc_rtx, target));
47 emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
48 emit_label (label);
49 emit_insn (gen_add<mode>3 (operands[0], operands[0], const1_rtx));
50 DONE;
51 }")
52
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"
66 [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
67 (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
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")))]
75 ""
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"
93 "ffs $0,$<width>,%1,%0")
94
95 ;; Our FFS hardware instruction supports any field width,
96 ;; so handle narrower inputs directly as well.
97 (define_peephole2
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))])
102 (parallel
103 [(set (match_operand:SI 2 "nonimmediate_operand")
104 (ctz:SI (match_dup 0)))
105 (clobber (reg:CC VAX_PSL_REGNUM))])]
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)))
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)))])]
161 "")
162
163 (define_expand "sync_lock_test_and_set<mode>"
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")]
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);
177 emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label,
178 operands[1]));
179 emit_move_insn (operands[0], const0_rtx);
180 emit_label (label);
181 DONE;
182 }")
183
184 (define_expand "sync_lock_release<mode>"
185 [(match_operand:VAXint 0 "memory_operand" "+m")
186 (match_operand:VAXint 1 "const_int_operand" "n")]
187 ""
188 "
189 {
190 rtx label;
191
192 if (operands[1] != const0_rtx)
193 FAIL;
194
195 label = gen_label_rtx ();
196 emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label,
197 operands[0]));
198 emit_label (label);
199 DONE;
200 }")
201
202 (define_insn "jbb<ccss>i<mode>"
203 [(unspec_volatile
204 [(set (pc)
205 (if_then_else
206 (eq (zero_extract:SI
207 (match_operand:VAXint 0 "any_memory_operand" "<bb_mem>")
208 (const_int 1)
209 (match_operand:SI 1 "general_operand" "nrmT"))
210 (const_int bit))
211 (label_ref (match_operand 2 "" ""))
212 (pc)))
213 (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0")
214 (const_int 1)
215 (match_dup 1))
216 (const_int bit))]
217 VUNSPEC_LOCK)]
218 ""
219 "jb<ccss>i %1,%0,%l2")