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