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