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