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