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