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