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