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