vax.md revision 1.1.1.3 1 ;; Machine description for GNU compiler, VAX Version
2 ;; Copyright (C) 1987-2015 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 ;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ...
802 ;; but gcc made it just !MEM_P (operands[0]) || ...
803
804 (define_insn ""
805 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
806 (match_operand:QI 1 "const_int_operand" "n")
807 (match_operand:SI 2 "const_int_operand" "n"))
808 (match_operand:SI 3 "general_operand" "g"))]
809 "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
810 && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
811 && (REG_P (operands[0])
812 || (MEM_P (operands[0])
813 && ! mode_dependent_address_p (XEXP (operands[0], 0),
814 MEM_ADDR_SPACE (operands[0]))))"
815 "*
816 {
817 if (REG_P (operands[0]))
818 {
819 if (INTVAL (operands[2]) != 0)
820 return \"insv %3,%2,%1,%0\";
821 }
822 else
823 operands[0]
824 = adjust_address (operands[0],
825 INTVAL (operands[1]) == 8 ? QImode : HImode,
826 INTVAL (operands[2]) / 8);
827
828 CC_STATUS_INIT;
829 if (INTVAL (operands[1]) == 8)
830 return \"movb %3,%0\";
831 return \"movw %3,%0\";
832 }")
833
834 (define_insn ""
835 [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
836 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
837 (match_operand:QI 2 "const_int_operand" "n")
838 (match_operand:SI 3 "const_int_operand" "n")))]
839 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
840 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
841 && (REG_P (operands[1])
842 || (MEM_P (operands[1])
843 && ! mode_dependent_address_p (XEXP (operands[1], 0),
844 MEM_ADDR_SPACE (operands[1]))))"
845 "*
846 {
847 if (REG_P (operands[1]))
848 {
849 if (INTVAL (operands[3]) != 0)
850 return \"extzv %3,%2,%1,%0\";
851 }
852 else
853 operands[1]
854 = adjust_address (operands[1],
855 INTVAL (operands[2]) == 8 ? QImode : HImode,
856 INTVAL (operands[3]) / 8);
857
858 if (INTVAL (operands[2]) == 8)
859 return \"movzbl %1,%0\";
860 return \"movzwl %1,%0\";
861 }")
862
863 (define_insn ""
864 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
865 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
866 (match_operand:QI 2 "const_int_operand" "n")
867 (match_operand:SI 3 "const_int_operand" "n")))]
868 "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
869 && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
870 && (REG_P (operands[1])
871 || (MEM_P (operands[1])
872 && ! mode_dependent_address_p (XEXP (operands[1], 0),
873 MEM_ADDR_SPACE (operands[1]))))"
874 "*
875 {
876 if (REG_P (operands[1]))
877 {
878 if (INTVAL (operands[3]) != 0)
879 return \"extv %3,%2,%1,%0\";
880 }
881 else
882 operands[1]
883 = adjust_address (operands[1],
884 INTVAL (operands[2]) == 8 ? QImode : HImode,
885 INTVAL (operands[3]) / 8);
886
887 if (INTVAL (operands[2]) == 8)
888 return \"cvtbl %1,%0\";
889 return \"cvtwl %1,%0\";
890 }")
891
893 ;; Register-only SImode cases of bit-field insns.
894
895 (define_insn ""
896 [(set (cc0)
897 (compare
898 (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
899 (match_operand:QI 1 "general_operand" "g")
900 (match_operand:SI 2 "general_operand" "nrmT"))
901 (match_operand:SI 3 "general_operand" "nrmT")))]
902 ""
903 "cmpv %2,%1,%0,%3")
904
905 (define_insn ""
906 [(set (cc0)
907 (compare
908 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
909 (match_operand:QI 1 "general_operand" "g")
910 (match_operand:SI 2 "general_operand" "nrmT"))
911 (match_operand:SI 3 "general_operand" "nrmT")))]
912 ""
913 "cmpzv %2,%1,%0,%3")
914
915 ;; When the field position and size are constant and the destination
916 ;; is a register, extv and extzv are much slower than a rotate followed
917 ;; by a bicl or sign extension. Because we might end up choosing ext[z]v
918 ;; anyway, we can't allow immediate values for the primary source operand.
919
920 (define_insn ""
921 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
922 (sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
923 (match_operand:QI 2 "general_operand" "g")
924 (match_operand:SI 3 "general_operand" "nrmT")))]
925 ""
926 "*
927 {
928 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
929 || ! REG_P (operands[0])
930 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
931 return \"extv %3,%2,%1,%0\";
932 if (INTVAL (operands[2]) == 8)
933 return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
934 return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
935 }")
936
937 (define_insn ""
938 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
939 (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
940 (match_operand:QI 2 "general_operand" "g")
941 (match_operand:SI 3 "general_operand" "nrmT")))]
942 ""
943 "*
944 {
945 if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
946 || ! REG_P (operands[0]))
947 return \"extzv %3,%2,%1,%0\";
948 if (INTVAL (operands[2]) == 8)
949 return \"rotl %R3,%1,%0\;movzbl %0,%0\";
950 if (INTVAL (operands[2]) == 16)
951 return \"rotl %R3,%1,%0\;movzwl %0,%0\";
952 if (INTVAL (operands[3]) & 31)
953 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
954 if (rtx_equal_p (operands[0], operands[1]))
955 return \"bicl2 %M2,%0\";
956 return \"bicl3 %M2,%1,%0\";
957 }")
958
959 ;; Non-register cases.
960 ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
961 ;; don't match these (and therefore match the cases above instead).
962
963 (define_insn ""
964 [(set (cc0)
965 (compare
966 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
967 (match_operand:QI 1 "general_operand" "g")
968 (match_operand:SI 2 "general_operand" "nrmT"))
969 (match_operand:SI 3 "general_operand" "nrmT")))]
970 ""
971 "cmpv %2,%1,%0,%3")
972
973 (define_insn ""
974 [(set (cc0)
975 (compare
976 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
977 (match_operand:QI 1 "general_operand" "g")
978 (match_operand:SI 2 "general_operand" "nrmT"))
979 (match_operand:SI 3 "general_operand" "nrmT")))]
980 ""
981 "cmpzv %2,%1,%0,%3")
982
983 (define_insn "extv"
984 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
985 (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
986 (match_operand:QI 2 "general_operand" "g")
987 (match_operand:SI 3 "general_operand" "nrmT")))]
988 ""
989 "*
990 {
991 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
992 || ! CONST_INT_P (operands[3])
993 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
994 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
995 || side_effects_p (operands[1])
996 || (MEM_P (operands[1])
997 && mode_dependent_address_p (XEXP (operands[1], 0),
998 MEM_ADDR_SPACE (operands[1]))))
999 return \"extv %3,%2,%1,%0\";
1000 if (INTVAL (operands[2]) == 8)
1001 return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
1002 return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
1003 }")
1004
1005 (define_expand "extzv"
1006 [(set (match_operand:SI 0 "general_operand" "")
1007 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
1008 (match_operand:QI 2 "general_operand" "")
1009 (match_operand:SI 3 "general_operand" "")))]
1010 ""
1011 "")
1012
1013 (define_insn ""
1014 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1015 (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
1016 (match_operand:QI 2 "general_operand" "g")
1017 (match_operand:SI 3 "general_operand" "nrmT")))]
1018 ""
1019 "*
1020 {
1021 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
1022 || ! CONST_INT_P (operands[3])
1023 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
1024 || side_effects_p (operands[1])
1025 || (MEM_P (operands[1])
1026 && mode_dependent_address_p (XEXP (operands[1], 0),
1027 MEM_ADDR_SPACE (operands[1]))))
1028 return \"extzv %3,%2,%1,%0\";
1029 if (INTVAL (operands[2]) == 8)
1030 return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1031 if (INTVAL (operands[2]) == 16)
1032 return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1033 if (MEM_P (operands[1])
1034 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1035 && REG_P (XEXP (XEXP (operands[1], 0), 0))
1036 && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
1037 && CONST_INT_P (operands[2])
1038 && CONST_INT_P (operands[3]))
1039 {
1040 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1041 HOST_WIDE_INT l = INTVAL (operands[2]);
1042 HOST_WIDE_INT v = INTVAL (operands[3]);
1043 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1044 {
1045 rtx tmp;
1046 tmp = XEXP (XEXP (operands[1], 0), 0);
1047 if (o & ~3)
1048 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1049 operands[1] = gen_rtx_MEM (QImode, tmp);
1050 operands[3] = GEN_INT (v + (o & 3) * 8);
1051 }
1052 if (optimize_size)
1053 return \"extzv %3,%2,%1,%0\";
1054 }
1055 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1056 }")
1057
1058 (define_expand "insv"
1059 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
1060 (match_operand:QI 1 "general_operand" "")
1061 (match_operand:SI 2 "general_operand" ""))
1062 (match_operand:SI 3 "general_operand" ""))]
1063 ""
1064 "")
1065
1066 (define_insn ""
1067 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
1068 (match_operand:QI 1 "general_operand" "g")
1069 (match_operand:SI 2 "general_operand" "nrmT"))
1070 (match_operand:SI 3 "general_operand" "nrmT"))]
1071 ""
1072 "*
1073 {
1074 if (MEM_P (operands[0])
1075 && GET_CODE (XEXP (operands[0], 0)) == PLUS
1076 && REG_P (XEXP (XEXP (operands[0], 0), 0))
1077 && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
1078 && CONST_INT_P (operands[1])
1079 && CONST_INT_P (operands[2]))
1080 {
1081 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1082 HOST_WIDE_INT v = INTVAL (operands[2]);
1083 HOST_WIDE_INT l = INTVAL (operands[1]);
1084 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1085 {
1086 rtx tmp;
1087 tmp = XEXP (XEXP (operands[0], 0), 0);
1088 if (o & ~3)
1089 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1090 operands[0] = gen_rtx_MEM (QImode, tmp);
1091 operands[2] = GEN_INT (v + (o & 3) * 8);
1092 }
1093 }
1094 return \"insv %3,%2,%1,%0\";
1095 }")
1096
1097 (define_insn ""
1098 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1099 (match_operand:QI 1 "general_operand" "g")
1100 (match_operand:SI 2 "general_operand" "nrmT"))
1101 (match_operand:SI 3 "general_operand" "nrmT"))]
1102 ""
1103 "insv %3,%2,%1,%0")
1104
1106 ;; Unconditional jump
1107 (define_insn "jump"
1108 [(set (pc)
1109 (label_ref (match_operand 0 "" "")))]
1110 ""
1111 "jbr %l0")
1112
1113 ;; Conditional jumps
1114
1115 (define_expand "cbranch<mode>4"
1116 [(set (cc0)
1117 (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
1118 (match_operand:VAXint 2 "general_operand" "")))
1119 (set (pc)
1120 (if_then_else
1121 (match_operator 0 "ordered_comparison_operator" [(cc0)
1122 (const_int 0)])
1123 (label_ref (match_operand 3 "" ""))
1124 (pc)))]
1125 "")
1126
1127 (define_expand "cbranch<mode>4"
1128 [(set (cc0)
1129 (compare (match_operand:VAXfp 1 "general_operand" "")
1130 (match_operand:VAXfp 2 "general_operand" "")))
1131 (set (pc)
1132 (if_then_else
1133 (match_operator 0 "ordered_comparison_operator" [(cc0)
1134 (const_int 0)])
1135 (label_ref (match_operand 3 "" ""))
1136 (pc)))]
1137 "")
1138
1139 (define_insn "*branch"
1140 [(set (pc)
1141 (if_then_else (match_operator 0 "ordered_comparison_operator"
1142 [(cc0)
1143 (const_int 0)])
1144 (label_ref (match_operand 1 "" ""))
1145 (pc)))]
1146 ""
1147 "j%c0 %l1")
1148
1149 ;; Recognize reversed jumps.
1150 (define_insn "*branch_reversed"
1151 [(set (pc)
1152 (if_then_else (match_operator 0 "ordered_comparison_operator"
1153 [(cc0)
1154 (const_int 0)])
1155 (pc)
1156 (label_ref (match_operand 1 "" ""))))]
1157 ""
1158 "j%C0 %l1") ; %C0 negates condition
1159
1161 ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand
1162 ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is
1163 ;; memory, we use QImode in the insn. So we can't use those instructions
1164 ;; for mode-dependent addresses.
1165
1166 (define_insn ""
1167 [(set (pc)
1168 (if_then_else
1169 (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1170 (const_int 1)
1171 (match_operand:SI 1 "general_operand" "I,nrmT"))
1172 (const_int 0))
1173 (label_ref (match_operand 2 "" ""))
1174 (pc)))]
1175 ""
1176 "@
1177 jlbs %0,%l2
1178 jbs %1,%0,%l2")
1179
1180 (define_insn ""
1181 [(set (pc)
1182 (if_then_else
1183 (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1184 (const_int 1)
1185 (match_operand:SI 1 "general_operand" "I,nrmT"))
1186 (const_int 0))
1187 (label_ref (match_operand 2 "" ""))
1188 (pc)))]
1189 ""
1190 "@
1191 jlbc %0,%l2
1192 jbc %1,%0,%l2")
1193
1194 (define_insn ""
1195 [(set (pc)
1196 (if_then_else
1197 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1198 (const_int 1)
1199 (match_operand:SI 1 "general_operand" "I,nrmT"))
1200 (const_int 0))
1201 (label_ref (match_operand 2 "" ""))
1202 (pc)))]
1203 ""
1204 "@
1205 jlbs %0,%l2
1206 jbs %1,%0,%l2")
1207
1208 (define_insn ""
1209 [(set (pc)
1210 (if_then_else
1211 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1212 (const_int 1)
1213 (match_operand:SI 1 "general_operand" "I,nrmT"))
1214 (const_int 0))
1215 (label_ref (match_operand 2 "" ""))
1216 (pc)))]
1217 ""
1218 "@
1219 jlbc %0,%l2
1220 jbc %1,%0,%l2")
1221
1223 ;; Subtract-and-jump and Add-and-jump insns.
1224 ;; These are not used when output is for the Unix assembler
1225 ;; because it does not know how to modify them to reach far.
1226
1227 ;; Normal sob insns.
1228
1229 (define_insn ""
1230 [(set (pc)
1231 (if_then_else
1232 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1233 (const_int -1))
1234 (const_int 0))
1235 (label_ref (match_operand 1 "" ""))
1236 (pc)))
1237 (set (match_dup 0)
1238 (plus:SI (match_dup 0)
1239 (const_int -1)))]
1240 "!TARGET_UNIX_ASM"
1241 "jsobgtr %0,%l1")
1242
1243 (define_insn ""
1244 [(set (pc)
1245 (if_then_else
1246 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1247 (const_int -1))
1248 (const_int 0))
1249 (label_ref (match_operand 1 "" ""))
1250 (pc)))
1251 (set (match_dup 0)
1252 (plus:SI (match_dup 0)
1253 (const_int -1)))]
1254 "!TARGET_UNIX_ASM"
1255 "jsobgeq %0,%l1")
1256
1257 ;; Normal aob insns. Define a version for when operands[1] is a constant.
1258 (define_insn ""
1259 [(set (pc)
1260 (if_then_else
1261 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1262 (const_int 1))
1263 (match_operand:SI 1 "general_operand" "nrmT"))
1264 (label_ref (match_operand 2 "" ""))
1265 (pc)))
1266 (set (match_dup 0)
1267 (plus:SI (match_dup 0)
1268 (const_int 1)))]
1269 "!TARGET_UNIX_ASM"
1270 "jaoblss %1,%0,%l2")
1271
1272 (define_insn ""
1273 [(set (pc)
1274 (if_then_else
1275 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
1276 (match_operand:SI 1 "general_operand" "nrmT"))
1277 (label_ref (match_operand 2 "" ""))
1278 (pc)))
1279 (set (match_dup 0)
1280 (plus:SI (match_dup 0)
1281 (const_int 1)))]
1282 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1283 "jaoblss %P1,%0,%l2")
1284
1285 (define_insn ""
1286 [(set (pc)
1287 (if_then_else
1288 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1289 (const_int 1))
1290 (match_operand:SI 1 "general_operand" "nrmT"))
1291 (label_ref (match_operand 2 "" ""))
1292 (pc)))
1293 (set (match_dup 0)
1294 (plus:SI (match_dup 0)
1295 (const_int 1)))]
1296 "!TARGET_UNIX_ASM"
1297 "jaobleq %1,%0,%l2")
1298
1299 (define_insn ""
1300 [(set (pc)
1301 (if_then_else
1302 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
1303 (match_operand:SI 1 "general_operand" "nrmT"))
1304 (label_ref (match_operand 2 "" ""))
1305 (pc)))
1306 (set (match_dup 0)
1307 (plus:SI (match_dup 0)
1308 (const_int 1)))]
1309 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1310 "jaobleq %P1,%0,%l2")
1311
1312 ;; Something like a sob insn, but compares against -1.
1313 ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1314
1315 (define_insn ""
1316 [(set (pc)
1317 (if_then_else
1318 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
1319 (const_int 0))
1320 (label_ref (match_operand 1 "" ""))
1321 (pc)))
1322 (set (match_dup 0)
1323 (plus:SI (match_dup 0)
1324 (const_int -1)))]
1325 ""
1326 "decl %0\;jgequ %l1")
1327
1329 (define_expand "call_pop"
1330 [(parallel [(call (match_operand:QI 0 "memory_operand" "")
1331 (match_operand:SI 1 "const_int_operand" ""))
1332 (set (reg:SI VAX_SP_REGNUM)
1333 (plus:SI (reg:SI VAX_SP_REGNUM)
1334 (match_operand:SI 3 "immediate_operand" "")))])]
1335 ""
1336 {
1337 gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0);
1338
1339 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1340 during EH unwinding. We must include the argument count pushed by
1341 the calls instruction. */
1342 operands[1] = GEN_INT (INTVAL (operands[3]) + 4);
1343 })
1344
1345 (define_insn "*call_pop"
1346 [(call (match_operand:QI 0 "memory_operand" "m")
1347 (match_operand:SI 1 "const_int_operand" "n"))
1348 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1349 (match_operand:SI 2 "immediate_operand" "i")))]
1350 ""
1351 {
1352 operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4);
1353 return "calls %1,%0";
1354 })
1355
1356 (define_expand "call_value_pop"
1357 [(parallel [(set (match_operand 0 "" "")
1358 (call (match_operand:QI 1 "memory_operand" "")
1359 (match_operand:SI 2 "const_int_operand" "")))
1360 (set (reg:SI VAX_SP_REGNUM)
1361 (plus:SI (reg:SI VAX_SP_REGNUM)
1362 (match_operand:SI 4 "immediate_operand" "")))])]
1363 ""
1364 {
1365 gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0);
1366
1367 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1368 during EH unwinding. We must include the argument count pushed by
1369 the calls instruction. */
1370 operands[2] = GEN_INT (INTVAL (operands[4]) + 4);
1371 })
1372
1373 (define_insn "*call_value_pop"
1374 [(set (match_operand 0 "" "")
1375 (call (match_operand:QI 1 "memory_operand" "m")
1376 (match_operand:SI 2 "const_int_operand" "n")))
1377 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1378 (match_operand:SI 3 "immediate_operand" "i")))]
1379 ""
1380 "*
1381 {
1382 operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4);
1383 return \"calls %2,%1\";
1384 }")
1385
1386 (define_expand "call"
1387 [(call (match_operand:QI 0 "memory_operand" "")
1388 (match_operand:SI 1 "const_int_operand" ""))]
1389 ""
1390 "
1391 {
1392 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1393 during EH unwinding. We must include the argument count pushed by
1394 the calls instruction. */
1395 operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
1396 }")
1397
1398 (define_insn "*call"
1399 [(call (match_operand:QI 0 "memory_operand" "m")
1400 (match_operand:SI 1 "const_int_operand" ""))]
1401 ""
1402 "calls $0,%0")
1403
1404 (define_expand "call_value"
1405 [(set (match_operand 0 "" "")
1406 (call (match_operand:QI 1 "memory_operand" "")
1407 (match_operand:SI 2 "const_int_operand" "")))]
1408 ""
1409 "
1410 {
1411 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1412 during EH unwinding. We must include the argument count pushed by
1413 the calls instruction. */
1414 operands[2] = GEN_INT (INTVAL (operands[2]) + 4);
1415 }")
1416
1417 (define_insn "*call_value"
1418 [(set (match_operand 0 "" "")
1419 (call (match_operand:QI 1 "memory_operand" "m")
1420 (match_operand:SI 2 "const_int_operand" "")))]
1421 ""
1422 "calls $0,%1")
1423
1424 ;; Call subroutine returning any type.
1425
1426 (define_expand "untyped_call"
1427 [(parallel [(call (match_operand 0 "" "")
1428 (const_int 0))
1429 (match_operand 1 "" "")
1430 (match_operand 2 "" "")])]
1431 ""
1432 "
1433 {
1434 int i;
1435
1436 emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1437
1438 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1439 {
1440 rtx set = XVECEXP (operands[2], 0, i);
1441 emit_move_insn (SET_DEST (set), SET_SRC (set));
1442 }
1443
1444 /* The optimizer does not know that the call sets the function value
1445 registers we stored in the result block. We avoid problems by
1446 claiming that all hard registers are used and clobbered at this
1447 point. */
1448 emit_insn (gen_blockage ());
1449
1450 DONE;
1451 }")
1452
1453 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1454 ;; all of memory. This blocks insns from being moved across this point.
1455
1456 (define_insn "blockage"
1457 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
1458 ""
1459 "")
1460
1461 (define_insn "procedure_entry_mask"
1462 [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
1463 ""
1464 ".word %x0")
1465
1466 (define_insn "return"
1467 [(return)]
1468 ""
1469 "ret")
1470
1471 (define_expand "prologue"
1472 [(const_int 0)]
1473 ""
1474 {
1475 vax_expand_prologue ();
1476 DONE;
1477 })
1478
1479 (define_expand "epilogue"
1480 [(return)]
1481 ""
1482 "
1483 {
1484 emit_jump_insn (gen_return ());
1485 DONE;
1486 }")
1487
1488 (define_insn "nop"
1489 [(const_int 0)]
1490 ""
1491 "nop")
1492
1493 ;; This had a wider constraint once, and it had trouble.
1494 ;; If you are tempted to try `g', please don't--it's not worth
1495 ;; the risk we will reopen the same bug.
1496 (define_insn "indirect_jump"
1497 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1498 ""
1499 "jmp (%0)")
1500
1501 ;; This is here to accept 5 arguments (as passed by expand_end_case)
1502 ;; and pass the first 4 along to the casesi1 pattern that really does
1503 ;; the actual casesi work. We emit a jump here to the default label
1504 ;; _before_ the casesi so that we can be sure that the casesi never
1505 ;; drops through.
1506 ;; This is suboptimal perhaps, but so is much of the rest of this
1507 ;; machine description. For what it's worth, HPPA uses the same trick.
1508 ;;
1509 ;; operand 0 is index
1510 ;; operand 1 is the minimum bound (a const_int)
1511 ;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
1512 ;; operand 3 is CODE_LABEL for the table;
1513 ;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
1514 ;;
1515 ;; We emit:
1516 ;; i = index - minimum_bound
1517 ;; if (i > (maximum_bound - minimum_bound + 1) goto default;
1518 ;; casesi (i, 0, table);
1519 ;;
1520 (define_expand "casesi"
1521 [(match_operand:SI 0 "general_operand" "")
1522 (match_operand:SI 1 "general_operand" "")
1523 (match_operand:SI 2 "general_operand" "")
1524 (match_operand 3 "" "")
1525 (match_operand 4 "" "")]
1526 ""
1527 {
1528 rtx test;
1529
1530 /* i = index - minimum_bound;
1531 But only if the lower bound is not already zero. */
1532 if (operands[1] != const0_rtx)
1533 {
1534 rtx index = gen_reg_rtx (SImode);
1535 emit_insn (gen_addsi3 (index,
1536 operands[0],
1537 GEN_INT (-INTVAL (operands[1]))));
1538 operands[0] = index;
1539 }
1540
1541 /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */
1542 test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
1543 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
1544
1545 /* casesi (i, 0, table); */
1546 emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
1547 DONE;
1548 })
1549
1550 ;; This insn is a bit of a lier. It actually falls through if no case
1551 ;; matches. But, we prevent that from ever happening by emitting a jump
1552 ;; before this, see the define_expand above.
1553 (define_insn "casesi1"
1554 [(match_operand:SI 1 "const_int_operand" "n")
1555 (set (pc)
1556 (plus:SI (sign_extend:SI
1557 (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
1558 (const_int 2))
1559 (pc))))
1560 (label_ref:SI (match_operand 2 "" ""))))]
1561 ""
1562 "casel %0,$0,%1")
1563
1565 (define_insn "pushextsym"
1566 [(set (match_operand:SI 0 "push_operand" "=g")
1567 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1568 ""
1569 "pushab %a1")
1570
1571 (define_insn "movextsym"
1572 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1573 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1574 ""
1575 "movab %a1,%0")
1576
1577 (define_insn "pushlclsym"
1578 [(set (match_operand:SI 0 "push_operand" "=g")
1579 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1580 ""
1581 "pushab %a1")
1582
1583 (define_insn "movlclsym"
1584 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1585 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1586 ""
1587 "movab %a1,%0")
1588
1590 ;;- load or push effective address
1591 ;; These come after the move and add/sub patterns
1592 ;; because we don't want pushl $1 turned into pushad 1.
1593 ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1594
1595 ;; It does not work to use constraints to distinguish pushes from moves,
1596 ;; because < matches any autodecrement, not just a push.
1597
1598 (define_insn "pushaddr<mode>"
1599 [(set (match_operand:SI 0 "push_operand" "=g")
1600 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1601 ""
1602 "pusha<VAXintQHSD:isfx> %a1")
1603
1604 (define_insn "movaddr<mode>"
1605 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1606 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1607 ""
1608 "mova<VAXintQHSD:isfx> %a1,%0")
1609
1610 (define_insn "pushaddr<mode>"
1611 [(set (match_operand:SI 0 "push_operand" "=g")
1612 (match_operand:VAXfp 1 "address_operand" "p"))]
1613 ""
1614 "pusha<VAXfp:fsfx> %a1")
1615
1616 (define_insn "movaddr<mode>"
1617 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1618 (match_operand:VAXfp 1 "address_operand" "p"))]
1619 ""
1620 "mova<VAXfp:fsfx> %a1,%0")
1621
1623 ;; These used to be peepholes, but it is more straightforward to do them
1624 ;; as single insns. However, we must force the output to be a register
1625 ;; if it is not an offsettable address so that we know that we can assign
1626 ;; to it twice.
1627
1628 ;; If we had a good way of evaluating the relative costs, these could be
1629 ;; machine-independent.
1630
1631 ;; Optimize extzv ...,z; andl2 ...,z
1632 ;; or ashl ...,z; andl2 ...,z
1633 ;; with other operands constant. This is what the combiner converts the
1634 ;; above sequences to before attempting to recognize the new insn.
1635
1636 (define_insn ""
1637 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1638 (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
1639 (match_operand:QI 2 "const_int_operand" "n"))
1640 (match_operand:SI 3 "const_int_operand" "n")))]
1641 "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
1642 "*
1643 {
1644 unsigned long mask1 = INTVAL (operands[3]);
1645 unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
1646
1647 if ((mask1 & mask2) != mask1)
1648 operands[3] = GEN_INT (mask1 & mask2);
1649
1650 return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
1651 }")
1652
1653 ;; left-shift and mask
1654 ;; The only case where `ashl' is better is if the mask only turns off
1655 ;; bits that the ashl would anyways, in which case it should have been
1656 ;; optimized away.
1657
1658 (define_insn ""
1659 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1660 (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
1661 (match_operand:QI 2 "const_int_operand" "n"))
1662 (match_operand:SI 3 "const_int_operand" "n")))]
1663 ""
1664 "*
1665 {
1666 operands[3]
1667 = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
1668 return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
1669 }")
1670
1671 ;; Instruction sequence to sync the VAX instruction stream.
1672 (define_insn "sync_istream"
1673 [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
1674 ""
1675 "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
1676
1677 (define_expand "nonlocal_goto"
1678 [(use (match_operand 0 "general_operand" ""))
1679 (use (match_operand 1 "general_operand" ""))
1680 (use (match_operand 2 "general_operand" ""))
1681 (use (match_operand 3 "general_operand" ""))]
1682 ""
1683 {
1684 rtx lab = operands[1];
1685 rtx stack = operands[2];
1686 rtx fp = operands[3];
1687
1688 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1689 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1690
1691 emit_move_insn (hard_frame_pointer_rtx, fp);
1692 emit_stack_restore (SAVE_NONLOCAL, stack);
1693
1694 emit_use (hard_frame_pointer_rtx);
1695 emit_use (stack_pointer_rtx);
1696
1697 /* We'll convert this to direct jump via a peephole optimization. */
1698 emit_indirect_jump (copy_to_reg (lab));
1699 emit_barrier ();
1700 DONE;
1701 })
1702
1703 (include "builtins.md")
1704
1705 (define_peephole2
1706 [(set (match_operand:SI 0 "push_operand" "")
1707 (const_int 0))
1708 (set (match_dup 0)
1709 (match_operand:SI 1 "const_int_operand" ""))]
1710 "INTVAL (operands[1]) >= 0"
1711 [(set (match_dup 0)
1712 (match_dup 1))]
1713 "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
1714
1715 (define_peephole2
1716 [(set (match_operand:SI 0 "push_operand" "")
1717 (match_operand:SI 1 "general_operand" ""))
1718 (set (match_dup 0)
1719 (match_operand:SI 2 "general_operand" ""))]
1720 "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
1721 [(set (match_dup 0)
1722 (match_dup 2))]
1723 "{
1724 operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1725 operands[2] = REG_P (operands[2])
1726 ? gen_rtx_REG(DImode, REGNO (operands[2]))
1727 : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
1728 }")
1729
1730 ; Leave this commented out until we can determine whether the second move
1731 ; precedes a jump which relies on the CC flags being set correctly.
1732 (define_peephole2
1733 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1734 (match_operand:SI 1 "general_operand" ""))
1735 (set (match_operand:SI 2 "nonimmediate_operand" "")
1736 (match_operand:SI 3 "general_operand" ""))]
1737 "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
1738 && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
1739 [(set (match_dup 0)
1740 (match_dup 1))]
1741 "{
1742 operands[0] = REG_P (operands[0])
1743 ? gen_rtx_REG(DImode, REGNO (operands[0]))
1744 : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1745 operands[1] = REG_P (operands[1])
1746 ? gen_rtx_REG(DImode, REGNO (operands[1]))
1747 : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
1748 }")
1749