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