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