vax.md revision 1.17 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_expand "extv"
999 [(set (match_operand:SI 0 "general_operand" "")
1000 (sign_extract:SI (match_dup 4)
1001 (match_operand:QI 2 "general_operand" "")
1002 (match_operand:SI 3 "general_operand" ""))
1003 )]
1004 ""
1005 "{
1006 /*
1007 * If the source operand is a memory reference, and the address
1008 * is a symbol, and we're in PIC mode, load the address into a
1009 * register. Don't evaluate the field start or width at this time.
1010 */
1011 operands[4] = operands[1];
1012 if (flag_pic
1013 /* && !reload_completed */
1014 && MEM_P (operands[1])
1015 && !mode_dependent_address_p (XEXP (operands[1], 0),
1016 MEM_ADDR_SPACE (operands[1]))
1017 && SYMBOL_REF_P (XEXP (operands[1], 0))
1018 && !SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))
1019 )
1020 {
1021 rtx address = XEXP (operands[1], 0);
1022 rtx temp = gen_reg_rtx (Pmode);
1023 emit_move_insn (temp, address);
1024 /* copy the original memory reference, replacing the address */
1025 operands[4] = change_address (operands[1], VOIDmode, temp);
1026 set_mem_align (operands[4], MEM_ALIGN (operands[1]));
1027 }
1028 }"
1029 )
1030
1031 (define_insn ""
1032 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1033 (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
1034 (match_operand:QI 2 "general_operand" "g")
1035 (match_operand:SI 3 "general_operand" "nrmT")))]
1036 ""
1037 "*
1038 {
1039 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
1040 || ! CONST_INT_P (operands[3])
1041 || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
1042 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
1043 || side_effects_p (operands[1])
1044 || (MEM_P (operands[1])
1045 && mode_dependent_address_p (XEXP (operands[1], 0),
1046 MEM_ADDR_SPACE (operands[1]))))
1047 return \"extv %3,%2,%1,%0\";
1048 if (INTVAL (operands[2]) == 8)
1049 return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
1050 return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
1051 }")
1052
1053 (define_expand "extzv"
1054 [(set (match_operand:SI 0 "general_operand" "")
1055 (zero_extract:SI (match_operand:SI 1 "general_operand" "")
1056 (match_operand:QI 2 "general_operand" "")
1057 (match_operand:SI 3 "general_operand" "")))]
1058 ""
1059 "")
1060
1061 (define_insn ""
1062 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1063 (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
1064 (match_operand:QI 2 "general_operand" "g")
1065 (match_operand:SI 3 "general_operand" "nrmT")))]
1066 ""
1067 "*
1068 {
1069 if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
1070 || ! CONST_INT_P (operands[3])
1071 || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
1072 || side_effects_p (operands[1])
1073 || (MEM_P (operands[1])
1074 && mode_dependent_address_p (XEXP (operands[1], 0),
1075 MEM_ADDR_SPACE (operands[1]))))
1076 return \"extzv %3,%2,%1,%0\";
1077 if (INTVAL (operands[2]) == 8)
1078 return \"rotl %R3,%1,%0\;movzbl %0,%0\";
1079 if (INTVAL (operands[2]) == 16)
1080 return \"rotl %R3,%1,%0\;movzwl %0,%0\";
1081 if (MEM_P (operands[1])
1082 && GET_CODE (XEXP (operands[1], 0)) == PLUS
1083 && REG_P (XEXP (XEXP (operands[1], 0), 0))
1084 && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
1085 && CONST_INT_P (operands[2])
1086 && CONST_INT_P (operands[3]))
1087 {
1088 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1089 HOST_WIDE_INT l = INTVAL (operands[2]);
1090 HOST_WIDE_INT v = INTVAL (operands[3]);
1091 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1092 {
1093 rtx tmp;
1094 tmp = XEXP (XEXP (operands[1], 0), 0);
1095 if (o & ~3)
1096 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1097 operands[1] = gen_rtx_MEM (QImode, tmp);
1098 operands[3] = GEN_INT (v + (o & 3) * 8);
1099 }
1100 if (optimize_size)
1101 return \"extzv %3,%2,%1,%0\";
1102 }
1103 return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
1104 }")
1105
1106 (define_expand "insv"
1107 [(set (zero_extract:SI (match_dup 4)
1108 (match_operand:QI 1 "general_operand" "")
1109 (match_operand:SI 2 "general_operand" ""))
1110 (match_operand:SI 3 "general_operand" ""))]
1111 ""
1112 "{
1113 /*
1114 * If the destination operand is a memory reference, and the address
1115 * is a symbol, and we're in PIC mode, load the address into a
1116 * register. Don't evaluate the field start or width at this time.
1117 */
1118 operands[4] = operands[0];
1119 if (flag_pic
1120 /* && !reload_completed */
1121 && MEM_P (operands[0])
1122 && !mode_dependent_address_p (XEXP (operands[0], 0),
1123 MEM_ADDR_SPACE (operands[0]))
1124 && SYMBOL_REF_P (XEXP (operands[0], 0))
1125 && !SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0))
1126 )
1127 {
1128 rtx address = XEXP (operands[0], 0);
1129 rtx temp = gen_reg_rtx (Pmode);
1130 emit_move_insn (temp, address);
1131 /* copy the original memory reference, replacing the address */
1132 operands[4] = change_address (operands[0], VOIDmode, temp);
1133 set_mem_align (operands[4], MEM_ALIGN (operands[0]));
1134 }
1135
1136 }")
1137
1138 (define_insn ""
1139 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
1140 (match_operand:QI 1 "general_operand" "g")
1141 (match_operand:SI 2 "general_operand" "nrmT"))
1142 (match_operand:SI 3 "general_operand" "nrmT"))]
1143 ""
1144 "*
1145 {
1146 if (MEM_P (operands[0])
1147 && GET_CODE (XEXP (operands[0], 0)) == PLUS
1148 && REG_P (XEXP (XEXP (operands[0], 0), 0))
1149 && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
1150 && CONST_INT_P (operands[1])
1151 && CONST_INT_P (operands[2]))
1152 {
1153 HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1154 HOST_WIDE_INT v = INTVAL (operands[2]);
1155 HOST_WIDE_INT l = INTVAL (operands[1]);
1156 if ((o & 3) && (o & 3) * 8 + v + l <= 32)
1157 {
1158 rtx tmp;
1159 tmp = XEXP (XEXP (operands[0], 0), 0);
1160 if (o & ~3)
1161 tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
1162 operands[0] = gen_rtx_MEM (QImode, tmp);
1163 operands[2] = GEN_INT (v + (o & 3) * 8);
1164 }
1165 }
1166 return \"insv %3,%2,%1,%0\";
1167 }")
1168
1169 (define_insn ""
1170 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
1171 (match_operand:QI 1 "general_operand" "g")
1172 (match_operand:SI 2 "general_operand" "nrmT"))
1173 (match_operand:SI 3 "general_operand" "nrmT"))]
1174 ""
1175 "insv %3,%2,%1,%0")
1176
1178 ;; Unconditional jump
1179 (define_insn "jump"
1180 [(set (pc)
1181 (label_ref (match_operand 0 "" "")))]
1182 ""
1183 "jbr %l0")
1184
1185 ;; Conditional jumps
1186
1187 (define_expand "cbranch<mode>4"
1188 [(set (cc0)
1189 (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
1190 (match_operand:VAXint 2 "general_operand" "")))
1191 (set (pc)
1192 (if_then_else
1193 (match_operator 0 "ordered_comparison_operator" [(cc0)
1194 (const_int 0)])
1195 (label_ref (match_operand 3 "" ""))
1196 (pc)))]
1197 "")
1198
1199 (define_expand "cbranch<mode>4"
1200 [(set (cc0)
1201 (compare (match_operand:VAXfp 1 "general_operand" "")
1202 (match_operand:VAXfp 2 "general_operand" "")))
1203 (set (pc)
1204 (if_then_else
1205 (match_operator 0 "ordered_comparison_operator" [(cc0)
1206 (const_int 0)])
1207 (label_ref (match_operand 3 "" ""))
1208 (pc)))]
1209 "")
1210
1211 (define_insn "*branch"
1212 [(set (pc)
1213 (if_then_else (match_operator 0 "ordered_comparison_operator"
1214 [(cc0)
1215 (const_int 0)])
1216 (label_ref (match_operand 1 "" ""))
1217 (pc)))]
1218 ""
1219 "j%c0 %l1")
1220
1221 ;; Recognize reversed jumps.
1222 (define_insn "*branch_reversed"
1223 [(set (pc)
1224 (if_then_else (match_operator 0 "ordered_comparison_operator"
1225 [(cc0)
1226 (const_int 0)])
1227 (pc)
1228 (label_ref (match_operand 1 "" ""))))]
1229 ""
1230 "j%C0 %l1") ; %C0 negates condition
1231
1233 ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand
1234 ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is
1235 ;; memory, we use QImode in the insn. So we can't use those instructions
1236 ;; for mode-dependent addresses.
1237
1238 (define_insn ""
1239 [(set (pc)
1240 (if_then_else
1241 (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1242 (const_int 1)
1243 (match_operand:SI 1 "general_operand" "I,nrmT"))
1244 (const_int 0))
1245 (label_ref (match_operand 2 "" ""))
1246 (pc)))]
1247 ""
1248 "@
1249 jlbs %0,%l2
1250 jbs %1,%0,%l2")
1251
1252 (define_insn ""
1253 [(set (pc)
1254 (if_then_else
1255 (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
1256 (const_int 1)
1257 (match_operand:SI 1 "general_operand" "I,nrmT"))
1258 (const_int 0))
1259 (label_ref (match_operand 2 "" ""))
1260 (pc)))]
1261 ""
1262 "@
1263 jlbc %0,%l2
1264 jbc %1,%0,%l2")
1265
1266 (define_insn ""
1267 [(set (pc)
1268 (if_then_else
1269 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1270 (const_int 1)
1271 (match_operand:SI 1 "general_operand" "I,nrmT"))
1272 (const_int 0))
1273 (label_ref (match_operand 2 "" ""))
1274 (pc)))]
1275 ""
1276 "@
1277 jlbs %0,%l2
1278 jbs %1,%0,%l2")
1279
1280 (define_insn ""
1281 [(set (pc)
1282 (if_then_else
1283 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
1284 (const_int 1)
1285 (match_operand:SI 1 "general_operand" "I,nrmT"))
1286 (const_int 0))
1287 (label_ref (match_operand 2 "" ""))
1288 (pc)))]
1289 ""
1290 "@
1291 jlbc %0,%l2
1292 jbc %1,%0,%l2")
1293
1295 ;; Subtract-and-jump and Add-and-jump insns.
1296 ;; These are not used when output is for the Unix assembler
1297 ;; because it does not know how to modify them to reach far.
1298
1299 ;; Normal sob insns.
1300
1301 (define_insn ""
1302 [(set (pc)
1303 (if_then_else
1304 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1305 (const_int -1))
1306 (const_int 0))
1307 (label_ref (match_operand 1 "" ""))
1308 (pc)))
1309 (set (match_dup 0)
1310 (plus:SI (match_dup 0)
1311 (const_int -1)))]
1312 "!TARGET_UNIX_ASM"
1313 "jsobgtr %0,%l1")
1314
1315 (define_insn ""
1316 [(set (pc)
1317 (if_then_else
1318 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1319 (const_int -1))
1320 (const_int 0))
1321 (label_ref (match_operand 1 "" ""))
1322 (pc)))
1323 (set (match_dup 0)
1324 (plus:SI (match_dup 0)
1325 (const_int -1)))]
1326 "!TARGET_UNIX_ASM"
1327 "jsobgeq %0,%l1")
1328
1329 ;; Normal aob insns. Define a version for when operands[1] is a constant.
1330 (define_insn ""
1331 [(set (pc)
1332 (if_then_else
1333 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1334 (const_int 1))
1335 (match_operand:SI 1 "general_operand" "nrmT"))
1336 (label_ref (match_operand 2 "" ""))
1337 (pc)))
1338 (set (match_dup 0)
1339 (plus:SI (match_dup 0)
1340 (const_int 1)))]
1341 "!TARGET_UNIX_ASM"
1342 "jaoblss %1,%0,%l2")
1343
1344 (define_insn ""
1345 [(set (pc)
1346 (if_then_else
1347 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
1348 (match_operand:SI 1 "general_operand" "nrmT"))
1349 (label_ref (match_operand 2 "" ""))
1350 (pc)))
1351 (set (match_dup 0)
1352 (plus:SI (match_dup 0)
1353 (const_int 1)))]
1354 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1355 "jaoblss %P1,%0,%l2")
1356
1357 (define_insn ""
1358 [(set (pc)
1359 (if_then_else
1360 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
1361 (const_int 1))
1362 (match_operand:SI 1 "general_operand" "nrmT"))
1363 (label_ref (match_operand 2 "" ""))
1364 (pc)))
1365 (set (match_dup 0)
1366 (plus:SI (match_dup 0)
1367 (const_int 1)))]
1368 "!TARGET_UNIX_ASM"
1369 "jaobleq %1,%0,%l2")
1370
1371 (define_insn ""
1372 [(set (pc)
1373 (if_then_else
1374 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
1375 (match_operand:SI 1 "general_operand" "nrmT"))
1376 (label_ref (match_operand 2 "" ""))
1377 (pc)))
1378 (set (match_dup 0)
1379 (plus:SI (match_dup 0)
1380 (const_int 1)))]
1381 "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
1382 "jaobleq %P1,%0,%l2")
1383
1384 ;; Something like a sob insn, but compares against -1.
1385 ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
1386
1387 (define_insn ""
1388 [(set (pc)
1389 (if_then_else
1390 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
1391 (const_int 0))
1392 (label_ref (match_operand 1 "" ""))
1393 (pc)))
1394 (set (match_dup 0)
1395 (plus:SI (match_dup 0)
1396 (const_int -1)))]
1397 ""
1398 "decl %0\;jgequ %l1")
1399
1401 (define_expand "call_pop"
1402 [(parallel [(call (match_operand:QI 0 "memory_operand" "")
1403 (match_operand:SI 1 "const_int_operand" ""))
1404 (set (reg:SI VAX_SP_REGNUM)
1405 (plus:SI (reg:SI VAX_SP_REGNUM)
1406 (match_operand:SI 3 "immediate_operand" "")))])]
1407 ""
1408 {
1409 gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0);
1410
1411 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1412 during EH unwinding. We must include the argument count pushed by
1413 the calls instruction. */
1414 operands[1] = GEN_INT (INTVAL (operands[3]) + 4);
1415 })
1416
1417 (define_insn "*call_pop"
1418 [(call (match_operand:QI 0 "memory_operand" "m")
1419 (match_operand:SI 1 "const_int_operand" "n"))
1420 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1421 (match_operand:SI 2 "immediate_operand" "i")))]
1422 ""
1423 {
1424 operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4);
1425 return "calls %1,%0";
1426 })
1427
1428 (define_expand "call_value_pop"
1429 [(parallel [(set (match_operand 0 "" "")
1430 (call (match_operand:QI 1 "memory_operand" "")
1431 (match_operand:SI 2 "const_int_operand" "")))
1432 (set (reg:SI VAX_SP_REGNUM)
1433 (plus:SI (reg:SI VAX_SP_REGNUM)
1434 (match_operand:SI 4 "immediate_operand" "")))])]
1435 ""
1436 {
1437 gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0);
1438
1439 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1440 during EH unwinding. We must include the argument count pushed by
1441 the calls instruction. */
1442 operands[2] = GEN_INT (INTVAL (operands[4]) + 4);
1443 })
1444
1445 (define_insn "*call_value_pop"
1446 [(set (match_operand 0 "" "")
1447 (call (match_operand:QI 1 "memory_operand" "m")
1448 (match_operand:SI 2 "const_int_operand" "n")))
1449 (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
1450 (match_operand:SI 3 "immediate_operand" "i")))]
1451 ""
1452 "*
1453 {
1454 operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4);
1455 return \"calls %2,%1\";
1456 }")
1457
1458 (define_expand "call"
1459 [(call (match_operand:QI 0 "memory_operand" "")
1460 (match_operand:SI 1 "const_int_operand" ""))]
1461 ""
1462 "
1463 {
1464 /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
1465 during EH unwinding. We must include the argument count pushed by
1466 the calls instruction. */
1467 operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
1468 }")
1469
1470 (define_insn "*call"
1471 [(call (match_operand:QI 0 "memory_operand" "m")
1472 (match_operand:SI 1 "const_int_operand" ""))]
1473 ""
1474 "calls $0,%0")
1475
1476 (define_expand "call_value"
1477 [(set (match_operand 0 "" "")
1478 (call (match_operand:QI 1 "memory_operand" "")
1479 (match_operand:SI 2 "const_int_operand" "")))]
1480 ""
1481 "
1482 {
1483 /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
1484 during EH unwinding. We must include the argument count pushed by
1485 the calls instruction. */
1486 operands[2] = GEN_INT (INTVAL (operands[2]) + 4);
1487 }")
1488
1489 (define_insn "*call_value"
1490 [(set (match_operand 0 "" "")
1491 (call (match_operand:QI 1 "memory_operand" "m")
1492 (match_operand:SI 2 "const_int_operand" "")))]
1493 ""
1494 "calls $0,%1")
1495
1496 ;; Call subroutine returning any type.
1497
1498 (define_expand "untyped_call"
1499 [(parallel [(call (match_operand 0 "" "")
1500 (const_int 0))
1501 (match_operand 1 "" "")
1502 (match_operand 2 "" "")])]
1503 ""
1504 "
1505 {
1506 int i;
1507
1508 emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
1509
1510 for (i = 0; i < XVECLEN (operands[2], 0); i++)
1511 {
1512 rtx set = XVECEXP (operands[2], 0, i);
1513 emit_move_insn (SET_DEST (set), SET_SRC (set));
1514 }
1515
1516 /* The optimizer does not know that the call sets the function value
1517 registers we stored in the result block. We avoid problems by
1518 claiming that all hard registers are used and clobbered at this
1519 point. */
1520 emit_insn (gen_blockage ());
1521
1522 DONE;
1523 }")
1524
1525 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1526 ;; all of memory. This blocks insns from being moved across this point.
1527
1528 (define_insn "blockage"
1529 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
1530 ""
1531 "")
1532
1533 (define_insn "procedure_entry_mask"
1534 [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
1535 ""
1536 ".word %x0")
1537
1538 (define_insn "return"
1539 [(return)]
1540 ""
1541 "ret")
1542
1543 (define_expand "prologue"
1544 [(const_int 0)]
1545 ""
1546 {
1547 vax_expand_prologue ();
1548 DONE;
1549 })
1550
1551 (define_expand "epilogue"
1552 [(return)]
1553 ""
1554 "
1555 {
1556 emit_jump_insn (gen_return ());
1557 DONE;
1558 }")
1559
1560 ;; Exception handling
1561 ;; This is used when compiling the stack unwinding routines.
1562 (define_expand "eh_return"
1563 [(use (match_operand 0 "general_operand"))]
1564 ""
1565 {
1566 if (GET_MODE (operands[0]) != word_mode)
1567 operands[0] = convert_to_mode (word_mode, operands[0], 0);
1568 emit_insn (gen_eh_set_retaddr (operands[0]));
1569 DONE;
1570 })
1571
1572 (define_insn_and_split "eh_set_retaddr"
1573 [(unspec [(match_operand:SI 0 "general_operand")] VUNSPEC_EH_RETURN)
1574 (clobber (match_scratch:SI 1 "=&r"))
1575 ]
1576 ""
1577 "#"
1578 "reload_completed"
1579 [(const_int 0)]
1580 {
1581 /* the return address for the current frame is always at 0x10(%fp) */
1582 rtx tmp = plus_constant(Pmode, frame_pointer_rtx, 4 * UNITS_PER_WORD);
1583 tmp = gen_rtx_MEM (word_mode, tmp);
1584 MEM_VOLATILE_P(tmp) = 1;
1585 tmp = gen_rtx_SET(tmp, operands[0]);
1586 emit_insn(tmp);
1587 DONE;
1588 })
1589
1590 (define_insn "nop"
1591 [(const_int 0)]
1592 ""
1593 "nop")
1594
1595 ;; This had a wider constraint once, and it had trouble.
1596 ;; If you are tempted to try `g', please don't--it's not worth
1597 ;; the risk we will reopen the same bug.
1598 (define_insn "indirect_jump"
1599 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
1600 ""
1601 "jmp (%0)")
1602
1603 ;; This is here to accept 5 arguments (as passed by expand_end_case)
1604 ;; and pass the first 4 along to the casesi1 pattern that really does
1605 ;; the actual casesi work. We emit a jump here to the default label
1606 ;; _before_ the casesi so that we can be sure that the casesi never
1607 ;; drops through.
1608 ;; This is suboptimal perhaps, but so is much of the rest of this
1609 ;; machine description. For what it's worth, HPPA uses the same trick.
1610 ;;
1611 ;; operand 0 is index
1612 ;; operand 1 is the minimum bound (a const_int)
1613 ;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
1614 ;; operand 3 is CODE_LABEL for the table;
1615 ;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
1616 ;;
1617 ;; We emit:
1618 ;; i = index - minimum_bound
1619 ;; if (i > (maximum_bound - minimum_bound + 1) goto default;
1620 ;; casesi (i, 0, table);
1621 ;;
1622 (define_expand "casesi"
1623 [(match_operand:SI 0 "general_operand" "")
1624 (match_operand:SI 1 "general_operand" "")
1625 (match_operand:SI 2 "general_operand" "")
1626 (match_operand 3 "" "")
1627 (match_operand 4 "" "")]
1628 ""
1629 {
1630 rtx test;
1631
1632 /* i = index - minimum_bound;
1633 But only if the lower bound is not already zero. */
1634 if (operands[1] != const0_rtx)
1635 {
1636 rtx index = gen_reg_rtx (SImode);
1637 emit_insn (gen_addsi3 (index,
1638 operands[0],
1639 GEN_INT (-INTVAL (operands[1]))));
1640 operands[0] = index;
1641 }
1642
1643 /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */
1644 test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
1645 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
1646
1647 /* casesi (i, 0, table); */
1648 emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
1649 DONE;
1650 })
1651
1652 ;; This insn is a bit of a lier. It actually falls through if no case
1653 ;; matches. But, we prevent that from ever happening by emitting a jump
1654 ;; before this, see the define_expand above.
1655 (define_insn "casesi1"
1656 [(match_operand:SI 1 "const_int_operand" "n")
1657 (set (pc)
1658 (plus:SI (sign_extend:SI
1659 (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
1660 (const_int 2))
1661 (pc))))
1662 (label_ref:SI (match_operand 2 "" ""))))]
1663 ""
1664 "casel %0,$0,%1")
1665
1667 (define_insn "pushextsym"
1668 [(set (match_operand:SI 0 "push_operand" "=g")
1669 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1670 ""
1671 "pushab %a1")
1672
1673 (define_insn "movextsym"
1674 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1675 (match_operand:SI 1 "external_symbolic_operand" "i"))]
1676 ""
1677 "movab %a1,%0")
1678
1679 (define_insn "pushlclsym"
1680 [(set (match_operand:SI 0 "push_operand" "=g")
1681 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1682 ""
1683 "pushab %a1")
1684
1685 (define_insn "movlclsym"
1686 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1687 (match_operand:SI 1 "local_symbolic_operand" "i"))]
1688 ""
1689 "movab %a1,%0")
1690
1692 ;;- load or push effective address
1693 ;; These come after the move and add/sub patterns
1694 ;; because we don't want pushl $1 turned into pushad 1.
1695 ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
1696
1697 ;; It does not work to use constraints to distinguish pushes from moves,
1698 ;; because < matches any autodecrement, not just a push.
1699
1700 (define_insn "pushaddr<mode>"
1701 [(set (match_operand:SI 0 "push_operand" "=g")
1702 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1703 ""
1704 "pusha<VAXintQHSD:isfx> %a1")
1705
1706 (define_insn "movaddr<mode>"
1707 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1708 (match_operand:VAXintQHSD 1 "address_operand" "p"))]
1709 ""
1710 "mova<VAXintQHSD:isfx> %a1,%0")
1711
1712 (define_insn "pushaddr<mode>"
1713 [(set (match_operand:SI 0 "push_operand" "=g")
1714 (match_operand:VAXfp 1 "address_operand" "p"))]
1715 ""
1716 "pusha<VAXfp:fsfx> %a1")
1717
1718 (define_insn "movaddr<mode>"
1719 [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
1720 (match_operand:VAXfp 1 "address_operand" "p"))]
1721 ""
1722 "mova<VAXfp:fsfx> %a1,%0")
1723
1725 ;; These used to be peepholes, but it is more straightforward to do them
1726 ;; as single insns. However, we must force the output to be a register
1727 ;; if it is not an offsettable address so that we know that we can assign
1728 ;; to it twice.
1729
1730 ;; If we had a good way of evaluating the relative costs, these could be
1731 ;; machine-independent.
1732
1733 ;; Optimize extzv ...,z; andl2 ...,z
1734 ;; or ashl ...,z; andl2 ...,z
1735 ;; with other operands constant. This is what the combiner converts the
1736 ;; above sequences to before attempting to recognize the new insn.
1737
1738 (define_insn ""
1739 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1740 (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
1741 (match_operand:QI 2 "const_int_operand" "n"))
1742 (match_operand:SI 3 "const_int_operand" "n")))]
1743 "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
1744 "*
1745 {
1746 unsigned long mask1 = INTVAL (operands[3]);
1747 unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
1748
1749 if ((mask1 & mask2) != mask1)
1750 operands[3] = GEN_INT (mask1 & mask2);
1751
1752 return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
1753 }")
1754
1755 ;; left-shift and mask
1756 ;; The only case where `ashl' is better is if the mask only turns off
1757 ;; bits that the ashl would anyways, in which case it should have been
1758 ;; optimized away.
1759
1760 (define_insn ""
1761 [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
1762 (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
1763 (match_operand:QI 2 "const_int_operand" "n"))
1764 (match_operand:SI 3 "const_int_operand" "n")))]
1765 ""
1766 "*
1767 {
1768 operands[3]
1769 = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
1770 return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
1771 }")
1772
1773 ;; Instruction sequence to sync the VAX instruction stream.
1774 (define_insn "sync_istream"
1775 [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
1776 ""
1777 "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
1778
1779 (define_expand "nonlocal_goto"
1780 [(use (match_operand 0 "general_operand" ""))
1781 (use (match_operand 1 "general_operand" ""))
1782 (use (match_operand 2 "general_operand" ""))
1783 (use (match_operand 3 "general_operand" ""))]
1784 ""
1785 {
1786 rtx lab = operands[1];
1787 rtx stack = operands[2];
1788 rtx fp = operands[3];
1789
1790 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1791 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1792
1793 emit_move_insn (hard_frame_pointer_rtx, fp);
1794 emit_stack_restore (SAVE_NONLOCAL, stack);
1795
1796 emit_use (hard_frame_pointer_rtx);
1797 emit_use (stack_pointer_rtx);
1798
1799 /* We'll convert this to direct jump via a peephole optimization. */
1800 emit_indirect_jump (copy_to_reg (lab));
1801 emit_barrier ();
1802 DONE;
1803 })
1804
1805 (include "builtins.md")
1806
1807 (define_peephole2
1808 [(set (match_operand:SI 0 "push_operand" "")
1809 (const_int 0))
1810 (set (match_dup 0)
1811 (match_operand:SI 1 "const_int_operand" ""))]
1812 "INTVAL (operands[1]) >= 0"
1813 [(set (match_dup 0)
1814 (match_dup 1))]
1815 "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
1816
1817 (define_peephole2
1818 [(set (match_operand:SI 0 "push_operand" "")
1819 (match_operand:SI 1 "general_operand" ""))
1820 (set (match_dup 0)
1821 (match_operand:SI 2 "general_operand" ""))]
1822 "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
1823 [(set (match_dup 0)
1824 (match_dup 2))]
1825 "{
1826 operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1827 operands[2] = REG_P (operands[2])
1828 ? gen_rtx_REG(DImode, REGNO (operands[2]))
1829 : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
1830 }")
1831
1832 ; Leave this commented out until we can determine whether the second move
1833 ; precedes a jump which relies on the CC flags being set correctly.
1834 (define_peephole2
1835 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1836 (match_operand:SI 1 "general_operand" ""))
1837 (set (match_operand:SI 2 "nonimmediate_operand" "")
1838 (match_operand:SI 3 "general_operand" ""))]
1839 "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
1840 && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
1841 [(set (match_dup 0)
1842 (match_dup 1))]
1843 "{
1844 operands[0] = REG_P (operands[0])
1845 ? gen_rtx_REG(DImode, REGNO (operands[0]))
1846 : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
1847 operands[1] = REG_P (operands[1])
1848 ? gen_rtx_REG(DImode, REGNO (operands[1]))
1849 : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
1850 }")
1851