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