vax.md revision 1.1.1.8 1 1.1 mrg ;; Machine description for GNU compiler, VAX Version
2 1.1.1.8 mrg ;; Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg ;; This file is part of GCC.
5 1.1 mrg
6 1.1 mrg ;; GCC is free software; you can redistribute it and/or modify
7 1.1 mrg ;; it under the terms of the GNU General Public License as published by
8 1.1 mrg ;; the Free Software Foundation; either version 3, or (at your option)
9 1.1 mrg ;; any later version.
10 1.1 mrg
11 1.1 mrg ;; GCC is distributed in the hope that it will be useful,
12 1.1 mrg ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 mrg ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 mrg ;; GNU General Public License for more details.
15 1.1 mrg
16 1.1 mrg ;; You should have received a copy of the GNU General Public License
17 1.1 mrg ;; along with GCC; see the file COPYING3. If not see
18 1.1 mrg ;; <http://www.gnu.org/licenses/>.
19 1.1 mrg
20 1.1 mrg
21 1.1 mrg ;;- Instruction patterns. When multiple patterns apply,
22 1.1 mrg ;;- the first one in the file is chosen.
23 1.1 mrg ;;-
24 1.1 mrg ;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
25 1.1 mrg ;;-
26 1.1 mrg ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
27 1.1 mrg ;;- updates for most instructions.
28 1.1 mrg
29 1.1 mrg ;; UNSPEC_VOLATILE usage:
30 1.1 mrg
31 1.1.1.2 mrg (define_c_enum "unspecv" [
32 1.1.1.2 mrg VUNSPEC_BLOCKAGE ; 'blockage' insn to prevent scheduling across an
33 1.1 mrg ; insn in the code.
34 1.1.1.2 mrg VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream
35 1.1.1.2 mrg VUNSPEC_PEM ; 'procedure_entry_mask' insn.
36 1.1.1.2 mrg ])
37 1.1.1.2 mrg
38 1.1.1.2 mrg (define_constants
39 1.1.1.2 mrg [(VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer
40 1.1 mrg (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer
41 1.1 mrg (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer
42 1.1 mrg (VAX_PC_REGNUM 15) ; Register 15 contains the program counter
43 1.1.1.2 mrg (VAX_PSW_REGNUM 16) ; Program Status Word
44 1.1 mrg ]
45 1.1 mrg )
46 1.1 mrg
47 1.1 mrg ;; Integer modes supported on VAX, with a mapping from machine mode
48 1.1 mrg ;; to mnemonic suffix. DImode is always a special case.
49 1.1 mrg (define_mode_iterator VAXint [QI HI SI])
50 1.1 mrg (define_mode_iterator VAXintQH [QI HI])
51 1.1 mrg (define_mode_iterator VAXintQHSD [QI HI SI DI])
52 1.1 mrg (define_mode_attr isfx [(QI "b") (HI "w") (SI "l") (DI "q")])
53 1.1 mrg
54 1.1 mrg ;; Similar for float modes supported on VAX.
55 1.1 mrg (define_mode_iterator VAXfp [SF DF])
56 1.1 mrg (define_mode_attr fsfx [(SF "f") (DF "%#")])
57 1.1 mrg
58 1.1 mrg ;; Some output patterns want integer immediates with a prefix...
59 1.1 mrg (define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")])
60 1.1 mrg
61 1.1 mrg ;;
62 1.1 mrg (include "constraints.md")
63 1.1 mrg (include "predicates.md")
64 1.1 mrg
65 1.1 mrg (define_insn "*cmp<mode>"
66 1.1 mrg [(set (cc0)
67 1.1 mrg (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
68 1.1 mrg (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
69 1.1 mrg ""
70 1.1 mrg "@
71 1.1 mrg tst<VAXint:isfx> %0
72 1.1 mrg cmp<VAXint:isfx> %0,%1")
73 1.1 mrg
74 1.1 mrg (define_insn "*cmp<mode>"
75 1.1 mrg [(set (cc0)
76 1.1 mrg (compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
77 1.1 mrg (match_operand:VAXfp 1 "general_operand" "G,gF")))]
78 1.1 mrg ""
79 1.1 mrg "@
80 1.1 mrg tst<VAXfp:fsfx> %0
81 1.1 mrg cmp<VAXfp:fsfx> %0,%1")
82 1.1 mrg
83 1.1 mrg (define_insn "*bit<mode>"
84 1.1 mrg [(set (cc0)
85 1.1 mrg (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
86 1.1 mrg (match_operand:VAXint 1 "general_operand" "nrmT"))
87 1.1 mrg (const_int 0)))]
88 1.1 mrg ""
89 1.1 mrg "bit<VAXint:isfx> %0,%1")
90 1.1 mrg
91 1.1 mrg ;; The VAX has no sCOND insns. It does have add/subtract with carry
92 1.1 mrg ;; which could be used to implement the sltu and sgeu patterns. However,
93 1.1 mrg ;; to do this properly requires a complete rewrite of the compare insns
94 1.1 mrg ;; to keep them together with the sltu/sgeu insns until after the
95 1.1 mrg ;; reload pass is complete. The previous implementation didn't do this
96 1.1 mrg ;; and has been deleted.
97 1.1 mrg
98 1.1 mrg
100 1.1 mrg (define_insn "mov<mode>"
101 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
102 1.1 mrg (match_operand:VAXfp 1 "general_operand" "G,gF"))]
103 1.1 mrg ""
104 1.1 mrg "@
105 1.1 mrg clr<VAXfp:fsfx> %0
106 1.1 mrg mov<VAXfp:fsfx> %1,%0")
107 1.1 mrg
108 1.1 mrg ;; Some VAXen don't support this instruction.
109 1.1 mrg ;;(define_insn "movti"
110 1.1 mrg ;; [(set (match_operand:TI 0 "general_operand" "=g")
111 1.1 mrg ;; (match_operand:TI 1 "general_operand" "g"))]
112 1.1 mrg ;; ""
113 1.1 mrg ;; "movh %1,%0")
114 1.1 mrg
115 1.1 mrg (define_insn "movdi"
116 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
117 1.1 mrg (match_operand:DI 1 "general_operand" "g"))]
118 1.1 mrg ""
119 1.1 mrg "* return vax_output_int_move (insn, operands, DImode);")
120 1.1 mrg
121 1.1 mrg ;; The VAX move instructions have space-time tradeoffs. On a MicroVAX
122 1.1 mrg ;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl
123 1.1 mrg ;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles
124 1.1 mrg ;; if the constant is smaller than 4 bytes, 3 cycles for a longword
125 1.1 mrg ;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster
126 1.1 mrg ;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt
127 1.1 mrg ;; instructions take 4 cycles. inc takes 3 cycles. The machine description
128 1.1 mrg ;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
129 1.1 mrg ;; instead of movl).
130 1.1 mrg
131 1.1 mrg ;; Cycle counts for other models may vary (on a VAX 750 they are similar,
132 1.1 mrg ;; but on a VAX 9000 most move and add instructions with one constant
133 1.1 mrg ;; operand take 1 cycle).
134 1.1 mrg
135 1.1 mrg ;; Loads of constants between 64 and 128 used to be done with
136 1.1 mrg ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
137 1.1 mrg
138 1.1 mrg (define_expand "movsi"
139 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "")
140 1.1 mrg (match_operand:SI 1 "general_operand" ""))]
141 1.1 mrg ""
142 1.1 mrg "
143 1.1 mrg {
144 1.1 mrg #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
145 1.1 mrg if (flag_pic
146 1.1 mrg && GET_CODE (operands[1]) == CONST
147 1.1 mrg && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
148 1.1 mrg && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (operands[1], 0), 0)))
149 1.1 mrg {
150 1.1 mrg rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0);
151 1.1 mrg rtx const_int = XEXP (XEXP (operands[1], 0), 1);
152 1.1 mrg rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
153 1.1 mrg emit_move_insn (temp, symbol_ref);
154 1.1 mrg emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, const_int));
155 1.1 mrg DONE;
156 1.1 mrg }
157 1.1 mrg #endif
158 1.1 mrg }")
159 1.1 mrg
160 1.1 mrg (define_insn "movsi_2"
161 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
162 1.1 mrg (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
163 1.1 mrg ""
164 1.1 mrg "* return vax_output_int_move (insn, operands, SImode);")
165 1.1 mrg
166 1.1 mrg (define_insn "mov<mode>"
167 1.1 mrg [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
168 1.1 mrg (match_operand:VAXintQH 1 "general_operand" "g"))]
169 1.1 mrg ""
170 1.1 mrg "* return vax_output_int_move (insn, operands, <MODE>mode);")
171 1.1 mrg
172 1.1 mrg (define_insn "movstricthi"
173 1.1 mrg [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
174 1.1 mrg (match_operand:HI 1 "general_operand" "g"))]
175 1.1 mrg ""
176 1.1 mrg "*
177 1.1 mrg {
178 1.1 mrg if (CONST_INT_P (operands[1]))
179 1.1 mrg {
180 1.1 mrg int i = INTVAL (operands[1]);
181 1.1 mrg if (i == 0)
182 1.1 mrg return \"clrw %0\";
183 1.1 mrg else if ((unsigned int)i < 64)
184 1.1 mrg return \"movw %1,%0\";
185 1.1 mrg else if ((unsigned int)~i < 64)
186 1.1 mrg return \"mcomw %H1,%0\";
187 1.1 mrg else if ((unsigned int)i < 256)
188 1.1 mrg return \"movzbw %1,%0\";
189 1.1 mrg }
190 1.1 mrg return \"movw %1,%0\";
191 1.1 mrg }")
192 1.1 mrg
193 1.1 mrg (define_insn "movstrictqi"
194 1.1 mrg [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
195 1.1 mrg (match_operand:QI 1 "general_operand" "g"))]
196 1.1 mrg ""
197 1.1 mrg "*
198 1.1 mrg {
199 1.1 mrg if (CONST_INT_P (operands[1]))
200 1.1 mrg {
201 1.1 mrg int i = INTVAL (operands[1]);
202 1.1 mrg if (i == 0)
203 1.1 mrg return \"clrb %0\";
204 1.1 mrg else if ((unsigned int)~i < 64)
205 1.1 mrg return \"mcomb %B1,%0\";
206 1.1 mrg }
207 1.1 mrg return \"movb %1,%0\";
208 1.1 mrg }")
209 1.1 mrg
210 1.1.1.8 mrg ;; This is here to accept 4 arguments and pass the first 3 along
211 1.1.1.8 mrg ;; to the cpymemhi1 pattern that really does the work.
212 1.1 mrg (define_expand "cpymemhi"
213 1.1 mrg [(set (match_operand:BLK 0 "general_operand" "=g")
214 1.1 mrg (match_operand:BLK 1 "general_operand" "g"))
215 1.1 mrg (use (match_operand:HI 2 "general_operand" "g"))
216 1.1 mrg (match_operand 3 "" "")]
217 1.1 mrg ""
218 1.1 mrg "
219 1.1.1.8 mrg {
220 1.1 mrg #if 0
221 1.1 mrg if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48)
222 1.1.1.8 mrg {
223 1.1 mrg emit_insn (gen_cpymemsi1_2 (operands[0], operands[1], operands[2]));
224 1.1 mrg DONE;
225 1.1.1.8 mrg }
226 1.1.1.8 mrg #endif
227 1.1 mrg emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2]));
228 1.1 mrg DONE;
229 1.1 mrg }")
230 1.1.1.8 mrg
231 1.1.1.8 mrg ;;(define_insn "cpymemsi1_2"
232 1.1.1.8 mrg ;; [(set (match_operand:BLK 0 "memory_operand" "=B")
233 1.1.1.8 mrg ;; (match_operand:BLK 1 "memory_operand" "B"))
234 1.1.1.8 mrg ;; (use (match_operand:SI 2 "const_int_operand" "g"))]
235 1.1.1.8 mrg ;; "INTVAL (operands[2]) <= 48"
236 1.1.1.8 mrg ;; "* return vax_output_cpymemsi (insn, operands);")
237 1.1 mrg
238 1.1 mrg ;; The definition of this insn does not really explain what it does,
239 1.1 mrg ;; but it should suffice
240 1.1 mrg ;; that anything generated as this insn will be recognized as one
241 1.1 mrg ;; and that it won't successfully combine with anything.
242 1.1.1.8 mrg
243 1.1 mrg (define_insn "cpymemhi1"
244 1.1 mrg [(set (match_operand:BLK 0 "memory_operand" "=o")
245 1.1 mrg (match_operand:BLK 1 "memory_operand" "o"))
246 1.1 mrg (use (match_operand:HI 2 "general_operand" "g"))
247 1.1 mrg (clobber (reg:SI 0))
248 1.1 mrg (clobber (reg:SI 1))
249 1.1 mrg (clobber (reg:SI 2))
250 1.1 mrg (clobber (reg:SI 3))
251 1.1 mrg (clobber (reg:SI 4))
252 1.1 mrg (clobber (reg:SI 5))]
253 1.1 mrg ""
254 1.1 mrg "movc3 %2,%1,%0")
255 1.1 mrg
257 1.1 mrg ;; Extension and truncation insns.
258 1.1 mrg
259 1.1 mrg (define_insn "truncsiqi2"
260 1.1 mrg [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
261 1.1 mrg (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
262 1.1 mrg ""
263 1.1 mrg "cvtlb %1,%0")
264 1.1 mrg
265 1.1 mrg (define_insn "truncsihi2"
266 1.1 mrg [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
267 1.1 mrg (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
268 1.1 mrg ""
269 1.1 mrg "cvtlw %1,%0")
270 1.1 mrg
271 1.1 mrg (define_insn "trunchiqi2"
272 1.1 mrg [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
273 1.1 mrg (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
274 1.1 mrg ""
275 1.1 mrg "cvtwb %1,%0")
276 1.1 mrg
277 1.1 mrg (define_insn "extendhisi2"
278 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
279 1.1 mrg (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
280 1.1 mrg ""
281 1.1 mrg "cvtwl %1,%0")
282 1.1 mrg
283 1.1 mrg (define_insn "extendqihi2"
284 1.1 mrg [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
285 1.1 mrg (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
286 1.1 mrg ""
287 1.1 mrg "cvtbw %1,%0")
288 1.1 mrg
289 1.1 mrg (define_insn "extendqisi2"
290 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
291 1.1 mrg (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
292 1.1 mrg ""
293 1.1 mrg "cvtbl %1,%0")
294 1.1 mrg
295 1.1 mrg (define_insn "extendsfdf2"
296 1.1 mrg [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
297 1.1 mrg (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
298 1.1 mrg ""
299 1.1 mrg "cvtf%# %1,%0")
300 1.1 mrg
301 1.1 mrg (define_insn "truncdfsf2"
302 1.1 mrg [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
303 1.1 mrg (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
304 1.1 mrg ""
305 1.1 mrg "cvt%#f %1,%0")
306 1.1 mrg
307 1.1 mrg (define_insn "zero_extendhisi2"
308 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
309 1.1 mrg (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
310 1.1 mrg ""
311 1.1 mrg "movzwl %1,%0")
312 1.1 mrg
313 1.1 mrg (define_insn "zero_extendqihi2"
314 1.1 mrg [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
315 1.1 mrg (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
316 1.1 mrg ""
317 1.1 mrg "movzbw %1,%0")
318 1.1 mrg
319 1.1 mrg (define_insn "zero_extendqisi2"
320 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
321 1.1 mrg (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
322 1.1 mrg ""
323 1.1 mrg "movzbl %1,%0")
324 1.1 mrg
326 1.1 mrg ;; Fix-to-float conversion insns.
327 1.1 mrg
328 1.1 mrg (define_insn "float<VAXint:mode><VAXfp:mode>2"
329 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
330 1.1 mrg (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
331 1.1 mrg ""
332 1.1 mrg "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0")
333 1.1 mrg
334 1.1 mrg ;; Float-to-fix conversion insns.
335 1.1.1.2 mrg
336 1.1 mrg (define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2"
337 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
338 1.1.1.2 mrg (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))]
339 1.1.1.2 mrg ""
340 1.1.1.2 mrg "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0")
341 1.1.1.2 mrg
342 1.1.1.2 mrg (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
343 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
344 1.1 mrg (fix:VAXint (match_operand:VAXfp 1 "general_operand")))]
345 1.1 mrg "")
346 1.1 mrg
348 1.1 mrg ;;- All kinds of add instructions.
349 1.1 mrg
350 1.1 mrg (define_insn "add<mode>3"
351 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
352 1.1 mrg (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
353 1.1 mrg (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
354 1.1 mrg ""
355 1.1 mrg "@
356 1.1 mrg add<VAXfp:fsfx>2 %2,%0
357 1.1 mrg add<VAXfp:fsfx>2 %1,%0
358 1.1 mrg add<VAXfp:fsfx>3 %1,%2,%0")
359 1.1 mrg
360 1.1 mrg (define_insn "pushlclsymreg"
361 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
362 1.1 mrg (plus:SI (match_operand:SI 1 "register_operand" "%r")
363 1.1 mrg (match_operand:SI 2 "local_symbolic_operand" "i")))]
364 1.1 mrg "flag_pic"
365 1.1 mrg "pushab %a2[%1]")
366 1.1 mrg
367 1.1 mrg (define_insn "pushextsymreg"
368 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
369 1.1 mrg (plus:SI (match_operand:SI 1 "register_operand" "%r")
370 1.1 mrg (match_operand:SI 2 "external_symbolic_operand" "i")))]
371 1.1 mrg "flag_pic"
372 1.1 mrg "pushab %a2[%1]")
373 1.1 mrg
374 1.1 mrg (define_insn "movlclsymreg"
375 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
376 1.1 mrg (plus:SI (match_operand:SI 1 "register_operand" "%r")
377 1.1 mrg (match_operand:SI 2 "local_symbolic_operand" "i")))]
378 1.1 mrg "flag_pic"
379 1.1 mrg "movab %a2[%1],%0")
380 1.1 mrg
381 1.1 mrg (define_insn "movextsymreg"
382 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
383 1.1 mrg (plus:SI (match_operand:SI 1 "register_operand" "%r")
384 1.1 mrg (match_operand:SI 2 "external_symbolic_operand" "i")))]
385 1.1 mrg "flag_pic"
386 1.1 mrg "movab %a2[%1],%0")
387 1.1.1.2 mrg
388 1.1 mrg (define_insn "add<mode>3"
389 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
390 1.1 mrg (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
391 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT")))]
392 1.1 mrg ""
393 1.1 mrg "* return vax_output_int_add (insn, operands, <MODE>mode);")
394 1.1 mrg
395 1.1 mrg (define_expand "adddi3"
396 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
397 1.1 mrg (plus:DI (match_operand:DI 1 "general_operand" "g")
398 1.1 mrg (match_operand:DI 2 "general_operand" "g")))]
399 1.1 mrg "!reload_in_progress"
400 1.1 mrg "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
401 1.1 mrg
402 1.1 mrg (define_insn "adcdi3"
403 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
404 1.1 mrg (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
405 1.1 mrg (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
406 1.1 mrg "TARGET_QMATH"
407 1.1 mrg "* return vax_output_int_add (insn, operands, DImode);")
408 1.1 mrg
409 1.1 mrg ;; The add-with-carry (adwc) instruction only accepts two operands.
410 1.1 mrg (define_insn "adddi3_old"
411 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
412 1.1 mrg (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
413 1.1 mrg (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
414 1.1 mrg "!TARGET_QMATH"
415 1.1 mrg "* return vax_output_int_add (insn, operands, DImode);")
416 1.1 mrg
418 1.1 mrg ;;- All kinds of subtract instructions.
419 1.1 mrg
420 1.1 mrg (define_insn "sub<mode>3"
421 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
422 1.1 mrg (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
423 1.1 mrg (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
424 1.1 mrg ""
425 1.1 mrg "@
426 1.1 mrg sub<VAXfp:fsfx>2 %2,%0
427 1.1.1.2 mrg sub<VAXfp:fsfx>3 %2,%1,%0")
428 1.1 mrg
429 1.1 mrg (define_insn "sub<mode>3"
430 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
431 1.1 mrg (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
432 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
433 1.1 mrg ""
434 1.1 mrg "@
435 1.1 mrg sub<VAXint:isfx>2 %2,%0
436 1.1 mrg sub<VAXint:isfx>3 %2,%1,%0")
437 1.1 mrg
438 1.1 mrg (define_expand "subdi3"
439 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
440 1.1 mrg (minus:DI (match_operand:DI 1 "general_operand" "g")
441 1.1.1.3 mrg (match_operand:DI 2 "general_operand" "g")))]
442 1.1 mrg "!reload_in_progress"
443 1.1 mrg "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
444 1.1 mrg
445 1.1 mrg (define_insn "sbcdi3"
446 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
447 1.1 mrg (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
448 1.1 mrg (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
449 1.1 mrg "TARGET_QMATH"
450 1.1 mrg "* return vax_output_int_subtract (insn, operands, DImode);")
451 1.1 mrg
452 1.1 mrg ;; The subtract-with-carry (sbwc) instruction only takes two operands.
453 1.1 mrg (define_insn "subdi3_old"
454 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
455 1.1 mrg (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
456 1.1 mrg (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
457 1.1 mrg "!TARGET_QMATH"
458 1.1 mrg "* return vax_output_int_subtract (insn, operands, DImode);")
459 1.1 mrg
461 1.1 mrg ;;- Multiply instructions.
462 1.1 mrg
463 1.1 mrg (define_insn "mul<mode>3"
464 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
465 1.1 mrg (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
466 1.1 mrg (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
467 1.1 mrg ""
468 1.1 mrg "@
469 1.1 mrg mul<VAXfp:fsfx>2 %2,%0
470 1.1.1.2 mrg mul<VAXfp:fsfx>2 %1,%0
471 1.1 mrg mul<VAXfp:fsfx>3 %1,%2,%0")
472 1.1 mrg
473 1.1 mrg (define_insn "mul<mode>3"
474 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
475 1.1 mrg (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
476 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
477 1.1 mrg ""
478 1.1 mrg "@
479 1.1 mrg mul<VAXint:isfx>2 %2,%0
480 1.1 mrg mul<VAXint:isfx>2 %1,%0
481 1.1 mrg mul<VAXint:isfx>3 %1,%2,%0")
482 1.1 mrg
483 1.1 mrg (define_insn "mulsidi3"
484 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
485 1.1 mrg (mult:DI (sign_extend:DI
486 1.1 mrg (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
487 1.1 mrg (sign_extend:DI
488 1.1 mrg (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))]
489 1.1 mrg ""
490 1.1 mrg "emul %1,%2,$0,%0")
491 1.1 mrg
492 1.1 mrg (define_insn ""
493 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
494 1.1 mrg (plus:DI
495 1.1 mrg (mult:DI (sign_extend:DI
496 1.1 mrg (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
497 1.1 mrg (sign_extend:DI
498 1.1 mrg (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
499 1.1 mrg (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
500 1.1 mrg ""
501 1.1 mrg "emul %1,%2,%3,%0")
502 1.1 mrg
503 1.1 mrg ;; 'F' constraint means type CONST_DOUBLE
504 1.1 mrg (define_insn ""
505 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
506 1.1 mrg (plus:DI
507 1.1 mrg (mult:DI (sign_extend:DI
508 1.1 mrg (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
509 1.1 mrg (sign_extend:DI
510 1.1 mrg (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
511 1.1 mrg (match_operand:DI 3 "immediate_operand" "F")))]
512 1.1 mrg "GET_CODE (operands[3]) == CONST_DOUBLE
513 1.1 mrg && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
514 1.1 mrg "*
515 1.1 mrg {
516 1.1 mrg if (CONST_DOUBLE_HIGH (operands[3]))
517 1.1 mrg operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3]));
518 1.1 mrg return \"emul %1,%2,%3,%0\";
519 1.1 mrg }")
520 1.1 mrg
522 1.1 mrg ;;- Divide instructions.
523 1.1 mrg
524 1.1 mrg (define_insn "div<mode>3"
525 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
526 1.1 mrg (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
527 1.1 mrg (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
528 1.1 mrg ""
529 1.1.1.2 mrg "@
530 1.1 mrg div<VAXfp:fsfx>2 %2,%0
531 1.1 mrg div<VAXfp:fsfx>3 %2,%1,%0")
532 1.1 mrg
533 1.1 mrg (define_insn "div<mode>3"
534 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
535 1.1 mrg (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
536 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
537 1.1 mrg ""
538 1.1 mrg "@
539 1.1 mrg div<VAXint:isfx>2 %2,%0
540 1.1 mrg div<VAXint:isfx>3 %2,%1,%0")
541 1.1 mrg
542 1.1 mrg ;This is left out because it is very slow;
543 1.1 mrg ;we are better off programming around the "lack" of this insn.
544 1.1 mrg ;(define_insn "divmoddisi4"
545 1.1 mrg ; [(set (match_operand:SI 0 "general_operand" "=g")
546 1.1 mrg ; (div:SI (match_operand:DI 1 "general_operand" "g")
547 1.1 mrg ; (match_operand:SI 2 "general_operand" "g")))
548 1.1 mrg ; (set (match_operand:SI 3 "general_operand" "=g")
549 1.1 mrg ; (mod:SI (match_operand:DI 1 "general_operand" "g")
550 1.1 mrg ; (match_operand:SI 2 "general_operand" "g")))]
551 1.1.1.2 mrg ; ""
552 1.1 mrg ; "ediv %2,%1,%0,%3")
553 1.1 mrg
555 1.1 mrg ;; Bit-and on the VAX is done with a clear-bits insn.
556 1.1 mrg (define_expand "and<mode>3"
557 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
558 1.1 mrg (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" ""))
559 1.1 mrg (match_operand:VAXint 2 "general_operand" "")))]
560 1.1 mrg ""
561 1.1 mrg "
562 1.1 mrg {
563 1.1 mrg rtx op1 = operands[1];
564 1.1 mrg
565 1.1 mrg /* If there is a constant argument, complement that one. */
566 1.1 mrg if (CONST_INT_P (operands[2]) && ! CONST_INT_P (op1))
567 1.1 mrg {
568 1.1 mrg operands[1] = operands[2];
569 1.1 mrg operands[2] = op1;
570 1.1 mrg op1 = operands[1];
571 1.1 mrg }
572 1.1 mrg
573 1.1 mrg if (CONST_INT_P (op1))
574 1.1 mrg operands[1] = GEN_INT (~INTVAL (op1));
575 1.1 mrg else
576 1.1 mrg operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
577 1.1 mrg }")
578 1.1 mrg
579 1.1 mrg (define_insn "*and<mode>"
580 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
581 1.1 mrg (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
582 1.1 mrg (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
583 1.1 mrg ""
584 1.1 mrg "@
585 1.1 mrg bic<VAXint:isfx>2 %1,%0
586 1.1 mrg bic<VAXint:isfx>3 %1,%2,%0")
587 1.1 mrg
588 1.1.1.2 mrg ;; The following used to be needed because constant propagation can
589 1.1 mrg ;; create them starting from the bic insn patterns above. This is no
590 1.1 mrg ;; longer a problem. However, having these patterns allows optimization
591 1.1 mrg ;; opportunities in combine.c.
592 1.1 mrg
593 1.1 mrg (define_insn "*and<mode>_const_int"
594 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
595 1.1 mrg (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
596 1.1 mrg (match_operand:VAXint 2 "const_int_operand" "n,n")))]
597 1.1 mrg ""
598 1.1 mrg "@
599 1.1 mrg bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0
600 1.1.1.2 mrg bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0")
601 1.1 mrg
602 1.1 mrg
604 1.1 mrg ;;- Bit set instructions.
605 1.1 mrg
606 1.1 mrg (define_insn "ior<mode>3"
607 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
608 1.1 mrg (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
609 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
610 1.1 mrg ""
611 1.1 mrg "@
612 1.1.1.2 mrg bis<VAXint:isfx>2 %2,%0
613 1.1 mrg bis<VAXint:isfx>2 %1,%0
614 1.1 mrg bis<VAXint:isfx>3 %2,%1,%0")
615 1.1 mrg
616 1.1 mrg ;;- xor instructions.
617 1.1 mrg
618 1.1 mrg (define_insn "xor<mode>3"
619 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
620 1.1 mrg (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
621 1.1 mrg (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
622 1.1 mrg ""
623 1.1 mrg "@
624 1.1 mrg xor<VAXint:isfx>2 %2,%0
625 1.1 mrg xor<VAXint:isfx>2 %1,%0
626 1.1 mrg xor<VAXint:isfx>3 %2,%1,%0")
627 1.1 mrg
628 1.1 mrg
630 1.1 mrg (define_insn "neg<mode>2"
631 1.1 mrg [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
632 1.1 mrg (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
633 1.1 mrg ""
634 1.1 mrg "mneg<VAXfp:fsfx> %1,%0")
635 1.1 mrg
636 1.1 mrg (define_insn "neg<mode>2"
637 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
638 1.1 mrg (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
639 1.1 mrg ""
640 1.1 mrg "mneg<VAXint:isfx> %1,%0")
641 1.1 mrg
642 1.1 mrg (define_insn "one_cmpl<mode>2"
643 1.1 mrg [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
644 1.1 mrg (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
645 1.1 mrg ""
646 1.1 mrg "mcom<VAXint:isfx> %1,%0")
647 1.1.1.2 mrg
648 1.1 mrg
650 1.1 mrg ;; Arithmetic right shift on the VAX works by negating the shift count,
651 1.1 mrg ;; then emitting a right shift with the shift count negated. This means
652 1.1 mrg ;; that all actual shift counts in the RTL will be positive. This
653 1.1 mrg ;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
654 1.1 mrg ;; which isn't valid.
655 1.1 mrg (define_expand "ashrsi3"
656 1.1 mrg [(set (match_operand:SI 0 "general_operand" "=g")
657 1.1 mrg (ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
658 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
659 1.1 mrg ""
660 1.1 mrg "
661 1.1 mrg {
662 1.1 mrg if (! CONST_INT_P (operands[2]))
663 1.1 mrg operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
664 1.1 mrg }")
665 1.1 mrg
666 1.1 mrg (define_insn ""
667 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
668 1.1 mrg (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
669 1.1 mrg (match_operand:QI 2 "const_int_operand" "n")))]
670 1.1 mrg ""
671 1.1 mrg "ashl $%n2,%1,%0")
672 1.1 mrg
673 1.1 mrg (define_insn ""
674 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
675 1.1 mrg (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
676 1.1 mrg (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
677 1.1 mrg ""
678 1.1 mrg "ashl %2,%1,%0")
679 1.1 mrg
680 1.1 mrg (define_insn "ashlsi3"
681 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
682 1.1 mrg (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
683 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
684 1.1 mrg ""
685 1.1 mrg "*
686 1.1 mrg {
687 1.1 mrg if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
688 1.1 mrg return \"addl2 %0,%0\";
689 1.1 mrg if (REG_P (operands[1]) && CONST_INT_P (operands[2]))
690 1.1 mrg {
691 1.1 mrg int i = INTVAL (operands[2]);
692 1.1 mrg if (i == 1)
693 1.1 mrg return \"addl3 %1,%1,%0\";
694 1.1 mrg if (i == 2 && !optimize_size)
695 1.1 mrg {
696 1.1 mrg if (push_operand (operands[0], SImode))
697 1.1 mrg return \"pushal 0[%1]\";
698 1.1 mrg return \"moval 0[%1],%0\";
699 1.1 mrg }
700 1.1 mrg if (i == 3 && !optimize_size)
701 1.1 mrg {
702 1.1 mrg if (push_operand (operands[0], SImode))
703 1.1 mrg return \"pushaq 0[%1]\";
704 1.1 mrg return \"movaq 0[%1],%0\";
705 1.1 mrg }
706 1.1 mrg }
707 1.1 mrg return \"ashl %2,%1,%0\";
708 1.1 mrg }")
709 1.1 mrg
710 1.1 mrg ;; Arithmetic right shift on the VAX works by negating the shift count.
711 1.1 mrg (define_expand "ashrdi3"
712 1.1 mrg [(set (match_operand:DI 0 "general_operand" "=g")
713 1.1 mrg (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
714 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
715 1.1 mrg ""
716 1.1 mrg "
717 1.1 mrg {
718 1.1 mrg operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
719 1.1 mrg }")
720 1.1 mrg
721 1.1 mrg (define_insn "ashldi3"
722 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
723 1.1 mrg (ashift:DI (match_operand:DI 1 "general_operand" "g")
724 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
725 1.1 mrg ""
726 1.1 mrg "ashq %2,%D1,%0")
727 1.1 mrg
728 1.1 mrg (define_insn ""
729 1.1 mrg [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
730 1.1 mrg (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
731 1.1 mrg (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
732 1.1 mrg ""
733 1.1 mrg "ashq %2,%D1,%0")
734 1.1 mrg
735 1.1 mrg ;; We used to have expand_shift handle logical right shifts by using extzv,
736 1.1 mrg ;; but this make it very difficult to do lshrdi3. Since the VAX is the
737 1.1 mrg ;; only machine with this kludge, it's better to just do this with a
738 1.1 mrg ;; define_expand and remove that case from expand_shift.
739 1.1 mrg
740 1.1 mrg (define_expand "lshrsi3"
741 1.1 mrg [(set (match_dup 3)
742 1.1 mrg (minus:QI (const_int 32)
743 1.1 mrg (match_dup 4)))
744 1.1 mrg (set (match_operand:SI 0 "nonimmediate_operand" "=g")
745 1.1 mrg (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
746 1.1 mrg (match_dup 3)
747 1.1 mrg (match_operand:SI 2 "register_operand" "g")))]
748 1.1 mrg ""
749 1.1 mrg "
750 1.1 mrg {
751 1.1 mrg operands[3] = gen_reg_rtx (QImode);
752 1.1 mrg operands[4] = gen_lowpart (QImode, operands[2]);
753 1.1 mrg }")
754 1.1 mrg
755 1.1 mrg ;; Rotate right on the VAX works by negating the shift count.
756 1.1 mrg (define_expand "rotrsi3"
757 1.1 mrg [(set (match_operand:SI 0 "general_operand" "=g")
758 1.1 mrg (rotatert:SI (match_operand:SI 1 "general_operand" "g")
759 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
760 1.1 mrg ""
761 1.1 mrg "
762 1.1 mrg {
763 1.1 mrg if (! CONST_INT_P (operands[2]))
764 1.1 mrg operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
765 1.1 mrg }")
766 1.1 mrg
767 1.1 mrg (define_insn "rotlsi3"
768 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
769 1.1 mrg (rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
770 1.1 mrg (match_operand:QI 2 "general_operand" "g")))]
771 1.1 mrg ""
772 1.1 mrg "rotl %2,%1,%0")
773 1.1 mrg
774 1.1 mrg (define_insn ""
775 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
776 1.1 mrg (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
777 1.1 mrg (match_operand:QI 2 "const_int_operand" "n")))]
778 1.1 mrg ""
779 1.1 mrg "rotl %R2,%1,%0")
780 1.1 mrg
781 1.1 mrg (define_insn ""
782 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
783 1.1 mrg (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
784 1.1 mrg (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
785 1.1 mrg ""
786 1.1 mrg "rotl %2,%1,%0")
787 1.1 mrg
788 1.1 mrg ;This insn is probably slower than a multiply and an add.
789 1.1 mrg ;(define_insn ""
790 1.1 mrg ; [(set (match_operand:SI 0 "general_operand" "=g")
791 1.1.1.3 mrg ; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
792 1.1.1.3 mrg ; (match_operand:SI 2 "general_operand" "g"))
793 1.1.1.3 mrg ; (match_operand:SI 3 "general_operand" "g")))]
794 1.1 mrg ; ""
795 1.1 mrg ; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
796 1.1 mrg
798 1.1 mrg ;; Special cases of bit-field insns which we should
799 1.1 mrg ;; recognize in preference to the general case.
800 1.1 mrg ;; These handle aligned 8-bit and 16-bit fields,
801 1.1 mrg ;; which can usually be done with move instructions.
802 1.1.1.2 mrg
803 1.1.1.2 mrg ;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ...
804 1.1.1.2 mrg ;; but gcc made it just !MEM_P (operands[0]) || ...
805 1.1 mrg
806 1.1 mrg (define_insn ""
807 1.1 mrg [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
808 1.1 mrg (match_operand:QI 1 "const_int_operand" "n")
809 1.1 mrg (match_operand:SI 2 "const_int_operand" "n"))
810 1.1 mrg (match_operand:SI 3 "general_operand" "g"))]
811 1.1 mrg "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
812 1.1 mrg && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
813 1.1 mrg && (REG_P (operands[0])
814 1.1 mrg || (MEM_P (operands[0])
815 1.1 mrg && ! mode_dependent_address_p (XEXP (operands[0], 0),
816 1.1 mrg MEM_ADDR_SPACE (operands[0]))))"
817 1.1 mrg "*
818 1.1 mrg {
819 1.1 mrg if (REG_P (operands[0]))
820 1.1 mrg {
821 1.1 mrg if (INTVAL (operands[2]) != 0)
822 1.1 mrg return \"insv %3,%2,%1,%0\";
823 1.1 mrg }
824 1.1 mrg else
825 1.1 mrg operands[0]
826 1.1 mrg = adjust_address (operands[0],
827 1.1 mrg INTVAL (operands[1]) == 8 ? QImode : HImode,
828 1.1 mrg INTVAL (operands[2]) / 8);
829 1.1 mrg
830 1.1 mrg CC_STATUS_INIT;
831 1.1 mrg if (INTVAL (operands[1]) == 8)
832 1.1.1.2 mrg return \"movb %3,%0\";
833 1.1.1.2 mrg return \"movw %3,%0\";
834 1.1.1.2 mrg }")
835 1.1 mrg
836 1.1 mrg (define_insn ""
837 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
838 1.1 mrg (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
839 1.1 mrg (match_operand:QI 2 "const_int_operand" "n")
840 1.1 mrg (match_operand:SI 3 "const_int_operand" "n")))]
841 1.1 mrg "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
842 1.1 mrg && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
843 1.1 mrg && (REG_P (operands[1])
844 1.1 mrg || (MEM_P (operands[1])
845 1.1 mrg && ! mode_dependent_address_p (XEXP (operands[1], 0),
846 1.1 mrg MEM_ADDR_SPACE (operands[1]))))"
847 1.1 mrg "*
848 1.1 mrg {
849 1.1 mrg if (REG_P (operands[1]))
850 1.1 mrg {
851 1.1 mrg if (INTVAL (operands[3]) != 0)
852 1.1 mrg return \"extzv %3,%2,%1,%0\";
853 1.1 mrg }
854 1.1 mrg else
855 1.1 mrg operands[1]
856 1.1 mrg = adjust_address (operands[1],
857 1.1 mrg INTVAL (operands[2]) == 8 ? QImode : HImode,
858 1.1 mrg INTVAL (operands[3]) / 8);
859 1.1 mrg
860 1.1 mrg if (INTVAL (operands[2]) == 8)
861 1.1.1.2 mrg return \"movzbl %1,%0\";
862 1.1.1.2 mrg return \"movzwl %1,%0\";
863 1.1.1.2 mrg }")
864 1.1 mrg
865 1.1 mrg (define_insn ""
866 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
867 1.1 mrg (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
868 1.1 mrg (match_operand:QI 2 "const_int_operand" "n")
869 1.1 mrg (match_operand:SI 3 "const_int_operand" "n")))]
870 1.1 mrg "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
871 1.1 mrg && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
872 1.1 mrg && (REG_P (operands[1])
873 1.1 mrg || (MEM_P (operands[1])
874 1.1 mrg && ! mode_dependent_address_p (XEXP (operands[1], 0),
875 1.1 mrg MEM_ADDR_SPACE (operands[1]))))"
876 1.1 mrg "*
877 1.1 mrg {
878 1.1 mrg if (REG_P (operands[1]))
879 1.1 mrg {
880 1.1 mrg if (INTVAL (operands[3]) != 0)
881 1.1 mrg return \"extv %3,%2,%1,%0\";
882 1.1 mrg }
883 1.1 mrg else
884 1.1 mrg operands[1]
885 1.1 mrg = adjust_address (operands[1],
886 1.1 mrg INTVAL (operands[2]) == 8 ? QImode : HImode,
887 1.1 mrg INTVAL (operands[3]) / 8);
888 1.1 mrg
889 1.1 mrg if (INTVAL (operands[2]) == 8)
890 1.1 mrg return \"cvtbl %1,%0\";
891 1.1 mrg return \"cvtwl %1,%0\";
892 1.1 mrg }")
893 1.1 mrg
895 1.1 mrg ;; Register-only SImode cases of bit-field insns.
896 1.1 mrg
897 1.1 mrg (define_insn ""
898 1.1 mrg [(set (cc0)
899 1.1 mrg (compare
900 1.1 mrg (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
901 1.1 mrg (match_operand:QI 1 "general_operand" "g")
902 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
903 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
904 1.1 mrg ""
905 1.1 mrg "cmpv %2,%1,%0,%3")
906 1.1 mrg
907 1.1 mrg (define_insn ""
908 1.1 mrg [(set (cc0)
909 1.1 mrg (compare
910 1.1 mrg (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
911 1.1 mrg (match_operand:QI 1 "general_operand" "g")
912 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
913 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
914 1.1 mrg ""
915 1.1 mrg "cmpzv %2,%1,%0,%3")
916 1.1 mrg
917 1.1 mrg ;; When the field position and size are constant and the destination
918 1.1 mrg ;; is a register, extv and extzv are much slower than a rotate followed
919 1.1 mrg ;; by a bicl or sign extension. Because we might end up choosing ext[z]v
920 1.1 mrg ;; anyway, we can't allow immediate values for the primary source operand.
921 1.1 mrg
922 1.1 mrg (define_insn ""
923 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
924 1.1 mrg (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
925 1.1 mrg (match_operand:QI 2 "general_operand" "g")
926 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
927 1.1 mrg ""
928 1.1 mrg "*
929 1.1 mrg {
930 1.1 mrg if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
931 1.1 mrg || ! REG_P (operands[0])
932 1.1 mrg || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
933 1.1 mrg return \"extv %3,%2,%1,%0\";
934 1.1 mrg if (INTVAL (operands[2]) == 8)
935 1.1 mrg return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
936 1.1 mrg return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
937 1.1 mrg }")
938 1.1 mrg
939 1.1 mrg (define_insn ""
940 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
941 1.1 mrg (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
942 1.1 mrg (match_operand:QI 2 "general_operand" "g")
943 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
944 1.1 mrg ""
945 1.1 mrg "*
946 1.1 mrg {
947 1.1 mrg if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
948 1.1 mrg || ! REG_P (operands[0]))
949 1.1 mrg return \"extzv %3,%2,%1,%0\";
950 1.1 mrg if (INTVAL (operands[2]) == 8)
951 1.1 mrg return \"rotl %R3,%1,%0\;movzbl %0,%0\";
952 1.1 mrg if (INTVAL (operands[2]) == 16)
953 1.1 mrg return \"rotl %R3,%1,%0\;movzwl %0,%0\";
954 1.1 mrg if (INTVAL (operands[3]) & 31)
955 1.1 mrg return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
956 1.1 mrg if (rtx_equal_p (operands[0], operands[1]))
957 1.1 mrg return \"bicl2 %M2,%0\";
958 1.1 mrg return \"bicl3 %M2,%1,%0\";
959 1.1 mrg }")
960 1.1 mrg
961 1.1 mrg ;; Non-register cases.
962 1.1 mrg ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
963 1.1 mrg ;; don't match these (and therefore match the cases above instead).
964 1.1 mrg
965 1.1 mrg (define_insn ""
966 1.1 mrg [(set (cc0)
967 1.1 mrg (compare
968 1.1 mrg (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
969 1.1 mrg (match_operand:QI 1 "general_operand" "g")
970 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
971 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
972 1.1 mrg ""
973 1.1 mrg "cmpv %2,%1,%0,%3")
974 1.1 mrg
975 1.1 mrg (define_insn ""
976 1.1 mrg [(set (cc0)
977 1.1 mrg (compare
978 1.1 mrg (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
979 1.1 mrg (match_operand:QI 1 "general_operand" "g")
980 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
981 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
982 1.1 mrg ""
983 1.1 mrg "cmpzv %2,%1,%0,%3")
984 1.1 mrg
985 1.1 mrg (define_insn "extv"
986 1.1.1.2 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
987 1.1.1.2 mrg (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
988 1.1 mrg (match_operand:QI 2 "general_operand" "g")
989 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
990 1.1 mrg ""
991 1.1 mrg "*
992 1.1 mrg {
993 1.1 mrg if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
994 1.1 mrg || ! CONST_INT_P (operands[3])
995 1.1 mrg || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
996 1.1 mrg || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
997 1.1 mrg || side_effects_p (operands[1])
998 1.1 mrg || (MEM_P (operands[1])
999 1.1 mrg && mode_dependent_address_p (XEXP (operands[1], 0),
1000 1.1 mrg MEM_ADDR_SPACE (operands[1]))))
1001 1.1 mrg return \"extv %3,%2,%1,%0\";
1002 1.1 mrg if (INTVAL (operands[2]) == 8)
1003 1.1 mrg return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
1004 1.1 mrg return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
1005 1.1 mrg }")
1006 1.1 mrg
1007 1.1 mrg (define_expand "extzv"
1008 1.1 mrg [(set (match_operand:SI 0 "general_operand" "")
1009 1.1 mrg (zero_extract:SI (match_operand:SI 1 "general_operand" "")
1010 1.1 mrg (match_operand:QI 2 "general_operand" "")
1011 1.1 mrg (match_operand:SI 3 "general_operand" "")))]
1012 1.1 mrg ""
1013 1.1 mrg "")
1014 1.1 mrg
1015 1.1.1.2 mrg (define_insn ""
1016 1.1.1.2 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1017 1.1 mrg (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
1018 1.1 mrg (match_operand:QI 2 "general_operand" "g")
1019 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT")))]
1020 1.1 mrg ""
1021 1.1 mrg "*
1022 1.1 mrg {
1023 1.1 mrg if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
1024 1.1 mrg || ! CONST_INT_P (operands[3])
1025 1.1 mrg || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
1026 1.1 mrg || side_effects_p (operands[1])
1027 1.1 mrg || (MEM_P (operands[1])
1028 1.1 mrg && mode_dependent_address_p (XEXP (operands[1], 0),
1029 1.1 mrg MEM_ADDR_SPACE (operands[1]))))
1030 1.1 mrg return \"extzv %3,%2,%1,%0\";
1031 1.1 mrg if (INTVAL (operands[2]) == 8)
1032 1.1 mrg return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1033 1.1 mrg if (INTVAL (operands[2]) == 16)
1034 1.1 mrg return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1035 1.1 mrg if (MEM_P (operands[1])
1036 1.1 mrg && GET_CODE (XEXP (operands[1], 0)) == PLUS
1037 1.1 mrg && REG_P (XEXP (XEXP (operands[1], 0), 0))
1038 1.1 mrg && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
1039 1.1 mrg && CONST_INT_P (operands[2])
1040 1.1 mrg && CONST_INT_P (operands[3]))
1041 1.1 mrg {
1042 1.1 mrg HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1043 1.1 mrg HOST_WIDE_INT l = INTVAL (operands[2]);
1044 1.1 mrg HOST_WIDE_INT v = INTVAL (operands[3]);
1045 1.1 mrg if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1046 1.1 mrg {
1047 1.1 mrg rtx tmp;
1048 1.1 mrg tmp = XEXP (XEXP (operands[1], 0), 0);
1049 1.1 mrg if (o & ~3)
1050 1.1 mrg tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1051 1.1 mrg operands[1] = gen_rtx_MEM (QImode, tmp);
1052 1.1 mrg operands[3] = GEN_INT (v + (o & 3) * 8);
1053 1.1 mrg }
1054 1.1 mrg if (optimize_size)
1055 1.1 mrg return \"extzv %3,%2,%1,%0\";
1056 1.1 mrg }
1057 1.1 mrg return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1058 1.1 mrg }")
1059 1.1 mrg
1060 1.1 mrg (define_expand "insv"
1061 1.1 mrg [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
1062 1.1 mrg (match_operand:QI 1 "general_operand" "")
1063 1.1 mrg (match_operand:SI 2 "general_operand" ""))
1064 1.1 mrg (match_operand:SI 3 "general_operand" ""))]
1065 1.1 mrg ""
1066 1.1 mrg "")
1067 1.1 mrg
1068 1.1 mrg (define_insn ""
1069 1.1 mrg [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
1070 1.1 mrg (match_operand:QI 1 "general_operand" "g")
1071 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
1072 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT"))]
1073 1.1 mrg ""
1074 1.1 mrg "*
1075 1.1 mrg {
1076 1.1 mrg if (MEM_P (operands[0])
1077 1.1 mrg && GET_CODE (XEXP (operands[0], 0)) == PLUS
1078 1.1 mrg && REG_P (XEXP (XEXP (operands[0], 0), 0))
1079 1.1 mrg && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
1080 1.1 mrg && CONST_INT_P (operands[1])
1081 1.1 mrg && CONST_INT_P (operands[2]))
1082 1.1 mrg {
1083 1.1 mrg HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1084 1.1 mrg HOST_WIDE_INT v = INTVAL (operands[2]);
1085 1.1 mrg HOST_WIDE_INT l = INTVAL (operands[1]);
1086 1.1 mrg if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1087 1.1 mrg {
1088 1.1 mrg rtx tmp;
1089 1.1 mrg tmp = XEXP (XEXP (operands[0], 0), 0);
1090 1.1 mrg if (o & ~3)
1091 1.1 mrg tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1092 1.1 mrg operands[0] = gen_rtx_MEM (QImode, tmp);
1093 1.1 mrg operands[2] = GEN_INT (v + (o & 3) * 8);
1094 1.1 mrg }
1095 1.1 mrg }
1096 1.1 mrg return \"insv %3,%2,%1,%0\";
1097 1.1 mrg }")
1098 1.1 mrg
1099 1.1 mrg (define_insn ""
1100 1.1 mrg [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1101 1.1 mrg (match_operand:QI 1 "general_operand" "g")
1102 1.1 mrg (match_operand:SI 2 "general_operand" "nrmT"))
1103 1.1 mrg (match_operand:SI 3 "general_operand" "nrmT"))]
1104 1.1 mrg ""
1105 1.1 mrg "insv %3,%2,%1,%0")
1106 1.1 mrg
1108 1.1 mrg ;; Unconditional jump
1109 1.1 mrg (define_insn "jump"
1110 1.1 mrg [(set (pc)
1111 1.1 mrg (label_ref (match_operand 0 "" "")))]
1112 1.1 mrg ""
1113 1.1 mrg "jbr %l0")
1114 1.1 mrg
1115 1.1 mrg ;; Conditional jumps
1116 1.1 mrg
1117 1.1 mrg (define_expand "cbranch<mode>4"
1118 1.1 mrg [(set (cc0)
1119 1.1 mrg (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
1120 1.1 mrg (match_operand:VAXint 2 "general_operand" "")))
1121 1.1 mrg (set (pc)
1122 1.1 mrg (if_then_else
1123 1.1 mrg (match_operator 0 "ordered_comparison_operator" [(cc0)
1124 1.1 mrg (const_int 0)])
1125 1.1 mrg (label_ref (match_operand 3 "" ""))
1126 1.1 mrg (pc)))]
1127 1.1 mrg "")
1128 1.1 mrg
1129 1.1 mrg (define_expand "cbranch<mode>4"
1130 1.1 mrg [(set (cc0)
1131 1.1 mrg (compare (match_operand:VAXfp 1 "general_operand" "")
1132 1.1 mrg (match_operand:VAXfp 2 "general_operand" "")))
1133 1.1 mrg (set (pc)
1134 1.1 mrg (if_then_else
1135 1.1 mrg (match_operator 0 "ordered_comparison_operator" [(cc0)
1136 1.1 mrg (const_int 0)])
1137 1.1 mrg (label_ref (match_operand 3 "" ""))
1138 1.1 mrg (pc)))]
1139 1.1 mrg "")
1140 1.1 mrg
1141 1.1 mrg (define_insn "*branch"
1142 1.1 mrg [(set (pc)
1143 1.1 mrg (if_then_else (match_operator 0 "ordered_comparison_operator"
1144 1.1 mrg [(cc0)
1145 1.1 mrg (const_int 0)])
1146 1.1 mrg (label_ref (match_operand 1 "" ""))
1147 1.1 mrg (pc)))]
1148 1.1 mrg ""
1149 1.1 mrg "j%c0 %l1")
1150 1.1 mrg
1151 1.1 mrg ;; Recognize reversed jumps.
1152 1.1 mrg (define_insn "*branch_reversed"
1153 1.1 mrg [(set (pc)
1154 1.1 mrg (if_then_else (match_operator 0 "ordered_comparison_operator"
1155 1.1 mrg [(cc0)
1156 1.1 mrg (const_int 0)])
1157 1.1 mrg (pc)
1158 1.1 mrg (label_ref (match_operand 1 "" ""))))]
1159 1.1 mrg ""
1160 1.1 mrg "j%C0 %l1") ; %C0 negates condition
1161 1.1 mrg
1163 1.1 mrg ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand
1164 1.1 mrg ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is
1165 1.1 mrg ;; memory, we use QImode in the insn. So we can't use those instructions
1166 1.1 mrg ;; for mode-dependent addresses.
1167 1.1 mrg
1168 1.1 mrg (define_insn ""
1169 1.1 mrg [(set (pc)
1170 1.1 mrg (if_then_else
1171 1.1 mrg (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1172 1.1 mrg (const_int 1)
1173 1.1 mrg (match_operand:SI 1 "general_operand" "I,nrmT"))
1174 1.1 mrg (const_int 0))
1175 1.1 mrg (label_ref (match_operand 2 "" ""))
1176 1.1 mrg (pc)))]
1177 1.1 mrg ""
1178 1.1 mrg "@
1179 1.1 mrg jlbs %0,%l2
1180 1.1 mrg jbs %1,%0,%l2")
1181 1.1 mrg
1182 1.1 mrg (define_insn ""
1183 1.1 mrg [(set (pc)
1184 1.1 mrg (if_then_else
1185 1.1 mrg (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1186 1.1 mrg (const_int 1)
1187 1.1 mrg (match_operand:SI 1 "general_operand" "I,nrmT"))
1188 1.1 mrg (const_int 0))
1189 1.1 mrg (label_ref (match_operand 2 "" ""))
1190 1.1 mrg (pc)))]
1191 1.1 mrg ""
1192 1.1 mrg "@
1193 1.1 mrg jlbc %0,%l2
1194 1.1 mrg jbc %1,%0,%l2")
1195 1.1 mrg
1196 1.1 mrg (define_insn ""
1197 1.1 mrg [(set (pc)
1198 1.1 mrg (if_then_else
1199 1.1 mrg (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1200 1.1 mrg (const_int 1)
1201 1.1 mrg (match_operand:SI 1 "general_operand" "I,nrmT"))
1202 1.1 mrg (const_int 0))
1203 1.1 mrg (label_ref (match_operand 2 "" ""))
1204 1.1 mrg (pc)))]
1205 1.1 mrg ""
1206 1.1 mrg "@
1207 1.1 mrg jlbs %0,%l2
1208 1.1 mrg jbs %1,%0,%l2")
1209 1.1 mrg
1210 1.1 mrg (define_insn ""
1211 1.1 mrg [(set (pc)
1212 1.1 mrg (if_then_else
1213 1.1 mrg (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1214 1.1 mrg (const_int 1)
1215 1.1 mrg (match_operand:SI 1 "general_operand" "I,nrmT"))
1216 1.1 mrg (const_int 0))
1217 1.1 mrg (label_ref (match_operand 2 "" ""))
1218 1.1 mrg (pc)))]
1219 1.1 mrg ""
1220 1.1 mrg "@
1221 1.1 mrg jlbc %0,%l2
1222 1.1 mrg jbc %1,%0,%l2")
1223 1.1 mrg
1225 1.1 mrg ;; Subtract-and-jump and Add-and-jump insns.
1226 1.1 mrg ;; These are not used when output is for the Unix assembler
1227 1.1 mrg ;; because it does not know how to modify them to reach far.
1228 1.1 mrg
1229 1.1 mrg ;; Normal sob insns.
1230 1.1 mrg
1231 1.1 mrg (define_insn ""
1232 1.1 mrg [(set (pc)
1233 1.1 mrg (if_then_else
1234 1.1 mrg (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1235 1.1 mrg (const_int -1))
1236 1.1 mrg (const_int 0))
1237 1.1 mrg (label_ref (match_operand 1 "" ""))
1238 1.1 mrg (pc)))
1239 1.1 mrg (set (match_dup 0)
1240 1.1 mrg (plus:SI (match_dup 0)
1241 1.1 mrg (const_int -1)))]
1242 1.1 mrg "!TARGET_UNIX_ASM"
1243 1.1 mrg "jsobgtr %0,%l1")
1244 1.1 mrg
1245 1.1 mrg (define_insn ""
1246 1.1 mrg [(set (pc)
1247 1.1 mrg (if_then_else
1248 1.1 mrg (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1249 1.1 mrg (const_int -1))
1250 1.1 mrg (const_int 0))
1251 1.1 mrg (label_ref (match_operand 1 "" ""))
1252 1.1 mrg (pc)))
1253 1.1 mrg (set (match_dup 0)
1254 1.1 mrg (plus:SI (match_dup 0)
1255 1.1 mrg (const_int -1)))]
1256 1.1 mrg "!TARGET_UNIX_ASM"
1257 1.1 mrg "jsobgeq %0,%l1")
1258 1.1 mrg
1259 1.1 mrg ;; Normal aob insns. Define a version for when operands[1] is a constant.
1260 1.1 mrg (define_insn ""
1261 1.1 mrg [(set (pc)
1262 1.1 mrg (if_then_else
1263 1.1 mrg (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1264 1.1 mrg (const_int 1))
1265 1.1 mrg (match_operand:SI 1 "general_operand" "nrmT"))
1266 1.1 mrg (label_ref (match_operand 2 "" ""))
1267 1.1 mrg (pc)))
1268 1.1 mrg (set (match_dup 0)
1269 1.1 mrg (plus:SI (match_dup 0)
1270 1.1 mrg (const_int 1)))]
1271 1.1 mrg "!TARGET_UNIX_ASM"
1272 1.1 mrg "jaoblss %1,%0,%l2")
1273 1.1 mrg
1274 1.1 mrg (define_insn ""
1275 1.1 mrg [(set (pc)
1276 1.1 mrg (if_then_else
1277 1.1 mrg (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
1278 1.1 mrg (match_operand:SI 1 "general_operand" "nrmT"))
1279 1.1 mrg (label_ref (match_operand 2 "" ""))
1280 1.1 mrg (pc)))
1281 1.1 mrg (set (match_dup 0)
1282 1.1 mrg (plus:SI (match_dup 0)
1283 1.1 mrg (const_int 1)))]
1284 1.1 mrg "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1285 1.1 mrg "jaoblss %P1,%0,%l2")
1286 1.1 mrg
1287 1.1 mrg (define_insn ""
1288 1.1 mrg [(set (pc)
1289 1.1 mrg (if_then_else
1290 1.1 mrg (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1291 1.1 mrg (const_int 1))
1292 1.1 mrg (match_operand:SI 1 "general_operand" "nrmT"))
1293 1.1 mrg (label_ref (match_operand 2 "" ""))
1294 1.1 mrg (pc)))
1295 1.1 mrg (set (match_dup 0)
1296 1.1 mrg (plus:SI (match_dup 0)
1297 1.1 mrg (const_int 1)))]
1298 1.1 mrg "!TARGET_UNIX_ASM"
1299 1.1 mrg "jaobleq %1,%0,%l2")
1300 1.1 mrg
1301 1.1 mrg (define_insn ""
1302 1.1 mrg [(set (pc)
1303 1.1 mrg (if_then_else
1304 1.1 mrg (le (match_operand:SI 0 "nonimmediate_operand" "+g")
1305 1.1 mrg (match_operand:SI 1 "general_operand" "nrmT"))
1306 1.1 mrg (label_ref (match_operand 2 "" ""))
1307 1.1 mrg (pc)))
1308 1.1 mrg (set (match_dup 0)
1309 1.1 mrg (plus:SI (match_dup 0)
1310 1.1 mrg (const_int 1)))]
1311 1.1 mrg "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1312 1.1 mrg "jaobleq %P1,%0,%l2")
1313 1.1 mrg
1314 1.1 mrg ;; Something like a sob insn, but compares against -1.
1315 1.1 mrg ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1316 1.1 mrg
1317 1.1 mrg (define_insn ""
1318 1.1 mrg [(set (pc)
1319 1.1 mrg (if_then_else
1320 1.1 mrg (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
1321 1.1 mrg (const_int 0))
1322 1.1 mrg (label_ref (match_operand 1 "" ""))
1323 1.1 mrg (pc)))
1324 1.1 mrg (set (match_dup 0)
1325 1.1 mrg (plus:SI (match_dup 0)
1326 1.1 mrg (const_int -1)))]
1327 1.1 mrg ""
1328 1.1 mrg "decl %0\;jgequ %l1")
1329 1.1 mrg
1331 1.1 mrg (define_expand "call_pop"
1332 1.1 mrg [(parallel [(call (match_operand:QI 0 "memory_operand" "")
1333 1.1 mrg (match_operand:SI 1 "const_int_operand" ""))
1334 1.1 mrg (set (reg:SI VAX_SP_REGNUM)
1335 1.1 mrg (plus:SI (reg:SI VAX_SP_REGNUM)
1336 1.1 mrg (match_operand:SI 3 "immediate_operand" "")))])]
1337 1.1 mrg ""
1338 1.1 mrg {
1339 1.1 mrg gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0);
1340 1.1 mrg
1341 1.1 mrg /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1342 1.1 mrg during EH unwinding. We must include the argument count pushed by
1343 1.1 mrg the calls instruction. */
1344 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[3]) + 4);
1345 1.1 mrg })
1346 1.1 mrg
1347 1.1 mrg (define_insn "*call_pop"
1348 1.1 mrg [(call (match_operand:QI 0 "memory_operand" "m")
1349 1.1 mrg (match_operand:SI 1 "const_int_operand" "n"))
1350 1.1 mrg (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1351 1.1 mrg (match_operand:SI 2 "immediate_operand" "i")))]
1352 1.1 mrg ""
1353 1.1 mrg {
1354 1.1 mrg operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4);
1355 1.1 mrg return "calls %1,%0";
1356 1.1 mrg })
1357 1.1 mrg
1358 1.1 mrg (define_expand "call_value_pop"
1359 1.1 mrg [(parallel [(set (match_operand 0 "" "")
1360 1.1 mrg (call (match_operand:QI 1 "memory_operand" "")
1361 1.1 mrg (match_operand:SI 2 "const_int_operand" "")))
1362 1.1 mrg (set (reg:SI VAX_SP_REGNUM)
1363 1.1 mrg (plus:SI (reg:SI VAX_SP_REGNUM)
1364 1.1 mrg (match_operand:SI 4 "immediate_operand" "")))])]
1365 1.1 mrg ""
1366 1.1 mrg {
1367 1.1 mrg gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0);
1368 1.1 mrg
1369 1.1 mrg /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1370 1.1 mrg during EH unwinding. We must include the argument count pushed by
1371 1.1 mrg the calls instruction. */
1372 1.1 mrg operands[2] = GEN_INT (INTVAL (operands[4]) + 4);
1373 1.1 mrg })
1374 1.1 mrg
1375 1.1 mrg (define_insn "*call_value_pop"
1376 1.1 mrg [(set (match_operand 0 "" "")
1377 1.1 mrg (call (match_operand:QI 1 "memory_operand" "m")
1378 1.1 mrg (match_operand:SI 2 "const_int_operand" "n")))
1379 1.1 mrg (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1380 1.1 mrg (match_operand:SI 3 "immediate_operand" "i")))]
1381 1.1 mrg ""
1382 1.1 mrg "*
1383 1.1 mrg {
1384 1.1 mrg operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4);
1385 1.1.1.2 mrg return \"calls %2,%1\";
1386 1.1 mrg }")
1387 1.1 mrg
1388 1.1 mrg (define_expand "call"
1389 1.1 mrg [(call (match_operand:QI 0 "memory_operand" "")
1390 1.1 mrg (match_operand:SI 1 "const_int_operand" ""))]
1391 1.1 mrg ""
1392 1.1 mrg "
1393 1.1 mrg {
1394 1.1 mrg /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1395 1.1 mrg during EH unwinding. We must include the argument count pushed by
1396 1.1 mrg the calls instruction. */
1397 1.1 mrg operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
1398 1.1 mrg }")
1399 1.1 mrg
1400 1.1 mrg (define_insn "*call"
1401 1.1 mrg [(call (match_operand:QI 0 "memory_operand" "m")
1402 1.1 mrg (match_operand:SI 1 "const_int_operand" ""))]
1403 1.1 mrg ""
1404 1.1 mrg "calls $0,%0")
1405 1.1 mrg
1406 1.1 mrg (define_expand "call_value"
1407 1.1 mrg [(set (match_operand 0 "" "")
1408 1.1 mrg (call (match_operand:QI 1 "memory_operand" "")
1409 1.1 mrg (match_operand:SI 2 "const_int_operand" "")))]
1410 1.1 mrg ""
1411 1.1 mrg "
1412 1.1 mrg {
1413 1.1 mrg /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1414 1.1 mrg during EH unwinding. We must include the argument count pushed by
1415 1.1 mrg the calls instruction. */
1416 1.1 mrg operands[2] = GEN_INT (INTVAL (operands[2]) + 4);
1417 1.1 mrg }")
1418 1.1 mrg
1419 1.1 mrg (define_insn "*call_value"
1420 1.1 mrg [(set (match_operand 0 "" "")
1421 1.1 mrg (call (match_operand:QI 1 "memory_operand" "m")
1422 1.1 mrg (match_operand:SI 2 "const_int_operand" "")))]
1423 1.1 mrg ""
1424 1.1 mrg "calls $0,%1")
1425 1.1 mrg
1426 1.1 mrg ;; Call subroutine returning any type.
1427 1.1 mrg
1428 1.1 mrg (define_expand "untyped_call"
1429 1.1 mrg [(parallel [(call (match_operand 0 "" "")
1430 1.1 mrg (const_int 0))
1431 1.1 mrg (match_operand 1 "" "")
1432 1.1 mrg (match_operand 2 "" "")])]
1433 1.1 mrg ""
1434 1.1 mrg "
1435 1.1 mrg {
1436 1.1 mrg int i;
1437 1.1 mrg
1438 1.1 mrg emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1439 1.1 mrg
1440 1.1 mrg for (i = 0; i < XVECLEN (operands[2], 0); i++)
1441 1.1 mrg {
1442 1.1 mrg rtx set = XVECEXP (operands[2], 0, i);
1443 1.1 mrg emit_move_insn (SET_DEST (set), SET_SRC (set));
1444 1.1 mrg }
1445 1.1 mrg
1446 1.1.1.2 mrg /* The optimizer does not know that the call sets the function value
1447 1.1.1.2 mrg registers we stored in the result block. We avoid problems by
1448 1.1.1.2 mrg claiming that all hard registers are used and clobbered at this
1449 1.1.1.2 mrg point. */
1450 1.1.1.2 mrg emit_insn (gen_blockage ());
1451 1.1 mrg
1452 1.1 mrg DONE;
1453 1.1 mrg }")
1454 1.1 mrg
1455 1.1 mrg ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1456 1.1.1.2 mrg ;; all of memory. This blocks insns from being moved across this point.
1457 1.1.1.2 mrg
1458 1.1.1.2 mrg (define_insn "blockage"
1459 1.1.1.2 mrg [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
1460 1.1.1.2 mrg ""
1461 1.1.1.2 mrg "")
1462 1.1.1.2 mrg
1463 1.1.1.2 mrg (define_insn "procedure_entry_mask"
1464 1.1 mrg [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
1465 1.1 mrg ""
1466 1.1 mrg ".word %x0")
1467 1.1 mrg
1468 1.1 mrg (define_insn "return"
1469 1.1 mrg [(return)]
1470 1.1 mrg ""
1471 1.1 mrg "ret")
1472 1.1 mrg
1473 1.1 mrg (define_expand "prologue"
1474 1.1 mrg [(const_int 0)]
1475 1.1 mrg ""
1476 1.1 mrg {
1477 1.1 mrg vax_expand_prologue ();
1478 1.1 mrg DONE;
1479 1.1 mrg })
1480 1.1 mrg
1481 1.1 mrg (define_expand "epilogue"
1482 1.1 mrg [(return)]
1483 1.1 mrg ""
1484 1.1 mrg "
1485 1.1 mrg {
1486 1.1 mrg emit_jump_insn (gen_return ());
1487 1.1 mrg DONE;
1488 1.1 mrg }")
1489 1.1 mrg
1490 1.1 mrg (define_insn "nop"
1491 1.1 mrg [(const_int 0)]
1492 1.1 mrg ""
1493 1.1 mrg "nop")
1494 1.1 mrg
1495 1.1 mrg ;; This had a wider constraint once, and it had trouble.
1496 1.1 mrg ;; If you are tempted to try `g', please don't--it's not worth
1497 1.1 mrg ;; the risk we will reopen the same bug.
1498 1.1 mrg (define_insn "indirect_jump"
1499 1.1 mrg [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1500 1.1 mrg ""
1501 1.1 mrg "jmp (%0)")
1502 1.1 mrg
1503 1.1 mrg ;; This is here to accept 5 arguments (as passed by expand_end_case)
1504 1.1 mrg ;; and pass the first 4 along to the casesi1 pattern that really does
1505 1.1 mrg ;; the actual casesi work. We emit a jump here to the default label
1506 1.1 mrg ;; _before_ the casesi so that we can be sure that the casesi never
1507 1.1 mrg ;; drops through.
1508 1.1 mrg ;; This is suboptimal perhaps, but so is much of the rest of this
1509 1.1 mrg ;; machine description. For what it's worth, HPPA uses the same trick.
1510 1.1 mrg ;;
1511 1.1 mrg ;; operand 0 is index
1512 1.1 mrg ;; operand 1 is the minimum bound (a const_int)
1513 1.1 mrg ;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
1514 1.1 mrg ;; operand 3 is CODE_LABEL for the table;
1515 1.1 mrg ;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
1516 1.1 mrg ;;
1517 1.1 mrg ;; We emit:
1518 1.1 mrg ;; i = index - minimum_bound
1519 1.1 mrg ;; if (i > (maximum_bound - minimum_bound + 1) goto default;
1520 1.1 mrg ;; casesi (i, 0, table);
1521 1.1 mrg ;;
1522 1.1 mrg (define_expand "casesi"
1523 1.1 mrg [(match_operand:SI 0 "general_operand" "")
1524 1.1 mrg (match_operand:SI 1 "general_operand" "")
1525 1.1 mrg (match_operand:SI 2 "general_operand" "")
1526 1.1 mrg (match_operand 3 "" "")
1527 1.1 mrg (match_operand 4 "" "")]
1528 1.1 mrg ""
1529 1.1 mrg {
1530 1.1 mrg rtx test;
1531 1.1 mrg
1532 1.1 mrg /* i = index - minimum_bound;
1533 1.1 mrg But only if the lower bound is not already zero. */
1534 1.1 mrg if (operands[1] != const0_rtx)
1535 1.1 mrg {
1536 1.1 mrg rtx index = gen_reg_rtx (SImode);
1537 1.1 mrg emit_insn (gen_addsi3 (index,
1538 1.1 mrg operands[0],
1539 1.1 mrg GEN_INT (-INTVAL (operands[1]))));
1540 1.1 mrg operands[0] = index;
1541 1.1 mrg }
1542 1.1 mrg
1543 1.1 mrg /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */
1544 1.1 mrg test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
1545 1.1 mrg emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
1546 1.1 mrg
1547 1.1 mrg /* casesi (i, 0, table); */
1548 1.1 mrg emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
1549 1.1 mrg DONE;
1550 1.1 mrg })
1551 1.1 mrg
1552 1.1 mrg ;; This insn is a bit of a lier. It actually falls through if no case
1553 1.1 mrg ;; matches. But, we prevent that from ever happening by emitting a jump
1554 1.1 mrg ;; before this, see the define_expand above.
1555 1.1 mrg (define_insn "casesi1"
1556 1.1 mrg [(match_operand:SI 1 "const_int_operand" "n")
1557 1.1 mrg (set (pc)
1558 1.1 mrg (plus:SI (sign_extend:SI
1559 1.1 mrg (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
1560 1.1 mrg (const_int 2))
1561 1.1 mrg (pc))))
1562 1.1 mrg (label_ref:SI (match_operand 2 "" ""))))]
1563 1.1 mrg ""
1564 1.1 mrg "casel %0,$0,%1")
1565 1.1 mrg
1567 1.1 mrg (define_insn "pushextsym"
1568 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
1569 1.1 mrg (match_operand:SI 1 "external_symbolic_operand" "i"))]
1570 1.1 mrg ""
1571 1.1 mrg "pushab %a1")
1572 1.1 mrg
1573 1.1 mrg (define_insn "movextsym"
1574 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1575 1.1 mrg (match_operand:SI 1 "external_symbolic_operand" "i"))]
1576 1.1 mrg ""
1577 1.1 mrg "movab %a1,%0")
1578 1.1 mrg
1579 1.1 mrg (define_insn "pushlclsym"
1580 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
1581 1.1 mrg (match_operand:SI 1 "local_symbolic_operand" "i"))]
1582 1.1 mrg ""
1583 1.1 mrg "pushab %a1")
1584 1.1 mrg
1585 1.1 mrg (define_insn "movlclsym"
1586 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1587 1.1 mrg (match_operand:SI 1 "local_symbolic_operand" "i"))]
1588 1.1 mrg ""
1589 1.1 mrg "movab %a1,%0")
1590 1.1 mrg
1592 1.1 mrg ;;- load or push effective address
1593 1.1 mrg ;; These come after the move and add/sub patterns
1594 1.1 mrg ;; because we don't want pushl $1 turned into pushad 1.
1595 1.1 mrg ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1596 1.1 mrg
1597 1.1 mrg ;; It does not work to use constraints to distinguish pushes from moves,
1598 1.1 mrg ;; because < matches any autodecrement, not just a push.
1599 1.1 mrg
1600 1.1 mrg (define_insn "pushaddr<mode>"
1601 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
1602 1.1 mrg (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1603 1.1 mrg ""
1604 1.1 mrg "pusha<VAXintQHSD:isfx> %a1")
1605 1.1 mrg
1606 1.1 mrg (define_insn "movaddr<mode>"
1607 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1608 1.1 mrg (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1609 1.1 mrg ""
1610 1.1 mrg "mova<VAXintQHSD:isfx> %a1,%0")
1611 1.1 mrg
1612 1.1 mrg (define_insn "pushaddr<mode>"
1613 1.1 mrg [(set (match_operand:SI 0 "push_operand" "=g")
1614 1.1 mrg (match_operand:VAXfp 1 "address_operand" "p"))]
1615 1.1 mrg ""
1616 1.1 mrg "pusha<VAXfp:fsfx> %a1")
1617 1.1 mrg
1618 1.1 mrg (define_insn "movaddr<mode>"
1619 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1620 1.1 mrg (match_operand:VAXfp 1 "address_operand" "p"))]
1621 1.1 mrg ""
1622 1.1 mrg "mova<VAXfp:fsfx> %a1,%0")
1623 1.1 mrg
1625 1.1 mrg ;; These used to be peepholes, but it is more straightforward to do them
1626 1.1 mrg ;; as single insns. However, we must force the output to be a register
1627 1.1 mrg ;; if it is not an offsettable address so that we know that we can assign
1628 1.1 mrg ;; to it twice.
1629 1.1 mrg
1630 1.1 mrg ;; If we had a good way of evaluating the relative costs, these could be
1631 1.1 mrg ;; machine-independent.
1632 1.1 mrg
1633 1.1 mrg ;; Optimize extzv ...,z; andl2 ...,z
1634 1.1 mrg ;; or ashl ...,z; andl2 ...,z
1635 1.1 mrg ;; with other operands constant. This is what the combiner converts the
1636 1.1 mrg ;; above sequences to before attempting to recognize the new insn.
1637 1.1 mrg
1638 1.1 mrg (define_insn ""
1639 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1640 1.1 mrg (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
1641 1.1 mrg (match_operand:QI 2 "const_int_operand" "n"))
1642 1.1 mrg (match_operand:SI 3 "const_int_operand" "n")))]
1643 1.1 mrg "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
1644 1.1 mrg "*
1645 1.1 mrg {
1646 1.1 mrg unsigned long mask1 = INTVAL (operands[3]);
1647 1.1 mrg unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
1648 1.1 mrg
1649 1.1 mrg if ((mask1 & mask2) != mask1)
1650 1.1 mrg operands[3] = GEN_INT (mask1 & mask2);
1651 1.1 mrg
1652 1.1 mrg return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
1653 1.1 mrg }")
1654 1.1 mrg
1655 1.1 mrg ;; left-shift and mask
1656 1.1 mrg ;; The only case where `ashl' is better is if the mask only turns off
1657 1.1 mrg ;; bits that the ashl would anyways, in which case it should have been
1658 1.1 mrg ;; optimized away.
1659 1.1 mrg
1660 1.1 mrg (define_insn ""
1661 1.1 mrg [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1662 1.1 mrg (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
1663 1.1 mrg (match_operand:QI 2 "const_int_operand" "n"))
1664 1.1 mrg (match_operand:SI 3 "const_int_operand" "n")))]
1665 1.1 mrg ""
1666 1.1 mrg "*
1667 1.1 mrg {
1668 1.1 mrg operands[3]
1669 1.1 mrg = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
1670 1.1 mrg return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
1671 1.1 mrg }")
1672 1.1 mrg
1673 1.1 mrg ;; Instruction sequence to sync the VAX instruction stream.
1674 1.1.1.2 mrg (define_insn "sync_istream"
1675 1.1 mrg [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
1676 1.1 mrg ""
1677 1.1 mrg "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
1678 1.1 mrg
1679 1.1 mrg (define_expand "nonlocal_goto"
1680 1.1 mrg [(use (match_operand 0 "general_operand" ""))
1681 1.1 mrg (use (match_operand 1 "general_operand" ""))
1682 1.1 mrg (use (match_operand 2 "general_operand" ""))
1683 1.1 mrg (use (match_operand 3 "general_operand" ""))]
1684 1.1 mrg ""
1685 1.1 mrg {
1686 1.1.1.2 mrg rtx lab = operands[1];
1687 1.1.1.2 mrg rtx stack = operands[2];
1688 1.1.1.2 mrg rtx fp = operands[3];
1689 1.1.1.2 mrg
1690 1.1.1.2 mrg emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1691 1.1.1.2 mrg emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1692 1.1.1.2 mrg
1693 1.1.1.2 mrg emit_move_insn (hard_frame_pointer_rtx, fp);
1694 1.1.1.2 mrg emit_stack_restore (SAVE_NONLOCAL, stack);
1695 1.1.1.2 mrg
1696 1.1.1.2 mrg emit_use (hard_frame_pointer_rtx);
1697 1.1.1.2 mrg emit_use (stack_pointer_rtx);
1698 1.1.1.2 mrg
1699 1.1.1.2 mrg /* We'll convert this to direct jump via a peephole optimization. */
1700 1.1.1.2 mrg emit_indirect_jump (copy_to_reg (lab));
1701 1.1.1.2 mrg emit_barrier ();
1702 1.1.1.2 mrg DONE;
1703 1.1.1.2 mrg })
1704 1.1.1.2 mrg
1705 1.1.1.2 mrg (include "builtins.md")
1706 1.1.1.2 mrg
1707 1.1.1.2 mrg (define_peephole2
1708 1.1.1.2 mrg [(set (match_operand:SI 0 "push_operand" "")
1709 1.1.1.2 mrg (const_int 0))
1710 1.1.1.2 mrg (set (match_dup 0)
1711 1.1.1.2 mrg (match_operand:SI 1 "const_int_operand" ""))]
1712 1.1.1.2 mrg "INTVAL (operands[1]) >= 0"
1713 1.1.1.2 mrg [(set (match_dup 0)
1714 1.1.1.2 mrg (match_dup 1))]
1715 1.1.1.2 mrg "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
1716 1.1.1.2 mrg
1717 1.1.1.2 mrg (define_peephole2
1718 1.1.1.2 mrg [(set (match_operand:SI 0 "push_operand" "")
1719 1.1.1.2 mrg (match_operand:SI 1 "general_operand" ""))
1720 1.1.1.2 mrg (set (match_dup 0)
1721 1.1.1.2 mrg (match_operand:SI 2 "general_operand" ""))]
1722 1.1.1.2 mrg "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
1723 1.1.1.2 mrg [(set (match_dup 0)
1724 1.1.1.2 mrg (match_dup 2))]
1725 1.1.1.2 mrg "{
1726 1.1.1.2 mrg operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1727 1.1.1.2 mrg operands[2] = REG_P (operands[2])
1728 1.1.1.2 mrg ? gen_rtx_REG(DImode, REGNO (operands[2]))
1729 1.1.1.2 mrg : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
1730 1.1.1.2 mrg }")
1731
1732 ; Leave this commented out until we can determine whether the second move
1733 ; precedes a jump which relies on the CC flags being set correctly.
1734 (define_peephole2
1735 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1736 (match_operand:SI 1 "general_operand" ""))
1737 (set (match_operand:SI 2 "nonimmediate_operand" "")
1738 (match_operand:SI 3 "general_operand" ""))]
1739 "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
1740 && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
1741 [(set (match_dup 0)
1742 (match_dup 1))]
1743 "{
1744 operands[0] = REG_P (operands[0])
1745 ? gen_rtx_REG(DImode, REGNO (operands[0]))
1746 : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1747 operands[1] = REG_P (operands[1])
1748 ? gen_rtx_REG(DImode, REGNO (operands[1]))
1749 : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
1750 }")
1751