36efb84806a4d1a3f0f3b2867faf137a2ca687c6
[gcc.git] / gcc / config / pa / pa.md
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;; Copyright (C) 1992-2015 Free Software Foundation, Inc.
3 ;; Contributed by the Center for Software Science at the University
4 ;; of Utah.
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;; This machine description is inspired by sparc.md and to a lesser
23 ;; extent mips.md.
24
25 ;; Possible improvements:
26 ;;
27 ;; * With PA1.1, most computational instructions can conditionally nullify
28 ;; the execution of the following instruction. A nullified instruction
29 ;; does not cause the instruction pipeline to stall, making it a very
30 ;; efficient alternative to e.g. branching or conditional moves.
31 ;;
32 ;; Nullification is performed conditionally based on the outcome of a
33 ;; test specified in the opcode. The test result is stored in PSW[N]
34 ;; and can only be used to nullify the instruction following immediately
35 ;; after the test. For example:
36 ;;
37 ;; ldi 10,%r26
38 ;; ldi 5,%r25
39 ;; sub,< %r26,%r25,%r28
40 ;; sub %r28,%r25,%r28 ; %r28 == 0
41 ;; sub,> %r26,%r25,%r29
42 ;; sub %r29,%r25,%r29 ; %r29 == 5
43 ;;
44 ;; This could be tricky to implement because the result of the test has
45 ;; to be propagated one instruction forward, which, in the worst case,
46 ;; would involve (1) adding a fake register for PSW[N]; (2) adding the
47 ;; variants of the computational instructions that set or consume this
48 ;; fake register. The cond_exec infrastructure is probably not helpful
49 ;; for this.
50 ;;
51 ;; * PA-RISC includes a set of conventions for branch instruction usage
52 ;; to indicate whether a particular branch is more likely to be taken
53 ;; or not taken. For example, the prediction for CMPB instructions
54 ;; (CMPB,cond,n r1,r2,target) depends on the direction of the branch
55 ;; (forward or backward) and on the order of the operands:
56 ;;
57 ;; | branch | operand | branch |
58 ;; | direction | compare | prediction |
59 ;; +-----------+----------+------------+
60 ;; | backward | r1 < r2 | taken |
61 ;; | backward | r1 >= r2 | not taken |
62 ;; | forward | r1 < r2 | not taken |
63 ;; | forward | r1 >= r2 | taken |
64 ;;
65 ;; By choosing instructions and operand order carefully, the compiler
66 ;; could give the CPU branch predictor some help.
67 ;;
68
69 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
70
71 ;; Uses of UNSPEC in this file:
72
73 (define_c_enum "unspec"
74 [UNSPEC_CFFC ; canonicalize_funcptr_for_compare
75 UNSPEC_GOTO ; indirect_goto
76 UNSPEC_DLTIND14R
77 UNSPEC_TP
78 UNSPEC_TLSGD
79 UNSPEC_TLSLDM
80 UNSPEC_TLSLDO
81 UNSPEC_TLSLDBASE
82 UNSPEC_TLSIE
83 UNSPEC_TLSLE
84 UNSPEC_TLSGD_PIC
85 UNSPEC_TLSLDM_PIC
86 UNSPEC_TLSIE_PIC
87 ])
88
89 ;; UNSPEC_VOLATILE:
90
91 (define_c_enum "unspecv"
92 [UNSPECV_BLOCKAGE ; blockage
93 UNSPECV_DCACHE ; dcacheflush
94 UNSPECV_ICACHE ; icacheflush
95 UNSPECV_OPC ; outline_prologue_call
96 UNSPECV_OEC ; outline_epilogue_call
97 UNSPECV_LONGJMP ; builtin_longjmp
98 ])
99
100 ;; Maximum pc-relative branch offsets.
101
102 ;; These numbers are a bit smaller than the maximum allowable offsets
103 ;; so that a few instructions may be inserted before the actual branch.
104
105 (define_constants
106 [(MAX_12BIT_OFFSET 8184) ; 12-bit branch
107 (MAX_17BIT_OFFSET 262100) ; 17-bit branch
108 ])
109
110 ;; Mode and code iterators
111
112 ;; This mode iterator allows :P to be used for patterns that operate on
113 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
114 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
115
116 ;; This attribute defines the condition prefix for word and double word
117 ;; add, compare, subtract and logical instructions.
118 (define_mode_attr dwc [(SI "") (DI "*")])
119
120 ;; Insn type. Used to default other attribute values.
121
122 ;; type "unary" insns have one input operand (1) and one output operand (0)
123 ;; type "binary" insns have two input operands (1,2) and one output (0)
124
125 (define_attr "type"
126 "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload,trap"
127 (const_string "binary"))
128
129 (define_attr "pa_combine_type"
130 "fmpy,faddsub,uncond_branch,addmove,none"
131 (const_string "none"))
132
133 ;; Processor type (for scheduling, not code generation) -- this attribute
134 ;; must exactly match the processor_type enumeration in pa.h.
135 ;;
136 ;; FIXME: Add 800 scheduling for completeness?
137
138 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
139
140 ;; Length (in # of bytes).
141 (define_attr "length" ""
142 (cond [(eq_attr "type" "load,fpload")
143 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
144 (const_int 8) (const_int 4))
145
146 (eq_attr "type" "store,fpstore")
147 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
148 (const_int 8) (const_int 4))
149
150 (eq_attr "type" "binary,shift,nullshift")
151 (if_then_else (match_operand 2 "arith14_operand" "")
152 (const_int 4) (const_int 12))
153
154 (eq_attr "type" "move,unary,shift,nullshift")
155 (if_then_else (match_operand 1 "arith14_operand" "")
156 (const_int 4) (const_int 8))]
157
158 (const_int 4)))
159
160 (define_asm_attributes
161 [(set_attr "length" "4")
162 (set_attr "type" "multi")])
163
164 ;; Attributes for instruction and branch scheduling
165
166 ;; For conditional branches. Frame related instructions are not allowed
167 ;; because they confuse the unwind support.
168 (define_attr "in_branch_delay" "false,true"
169 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
170 (eq_attr "length" "4")
171 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
172 (const_string "true")
173 (const_string "false")))
174
175 ;; Disallow instructions which use the FPU since they will tie up the FPU
176 ;; even if the instruction is nullified.
177 (define_attr "in_nullified_branch_delay" "false,true"
178 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch,trap")
179 (eq_attr "length" "4")
180 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
181 (const_string "true")
182 (const_string "false")))
183
184 ;; For calls and millicode calls.
185 (define_attr "in_call_delay" "false,true"
186 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
187 (eq_attr "length" "4")
188 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
189 (const_string "true")
190 (const_string "false")))
191
192 ;; Call delay slot description.
193 (define_delay (eq_attr "type" "call")
194 [(eq_attr "in_call_delay" "true") (nil) (nil)])
195
196 ;; Sibcall delay slot description.
197 (define_delay (eq_attr "type" "sibcall")
198 [(eq_attr "in_call_delay" "true") (nil) (nil)])
199
200 ;; Millicode call delay slot description.
201 (define_delay (eq_attr "type" "milli")
202 [(eq_attr "in_call_delay" "true") (nil) (nil)])
203
204 ;; Return and other similar instructions.
205 (define_delay (eq_attr "type" "branch,parallel_branch")
206 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
207
208 ;; Floating point conditional branch delay slot description.
209 (define_delay (eq_attr "type" "fbranch")
210 [(eq_attr "in_branch_delay" "true")
211 (eq_attr "in_nullified_branch_delay" "true")
212 (nil)])
213
214 ;; Integer conditional branch delay slot description.
215 ;; Nullification of conditional branches on the PA is dependent on the
216 ;; direction of the branch. Forward branches nullify true and
217 ;; backward branches nullify false. If the direction is unknown
218 ;; then nullification is not allowed.
219 (define_delay (eq_attr "type" "cbranch")
220 [(eq_attr "in_branch_delay" "true")
221 (and (eq_attr "in_nullified_branch_delay" "true")
222 (attr_flag "forward"))
223 (and (eq_attr "in_nullified_branch_delay" "true")
224 (attr_flag "backward"))])
225
226 (define_delay (eq_attr "type" "uncond_branch")
227 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
228
229 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
230 ;; load: 2, fpload: 3
231 ;; store, fpstore: 3, no D-cache operations should be scheduled.
232
233 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
234 ;; Timings:
235 ;; Instruction Time Unit Minimum Distance (unit contention)
236 ;; fcpy 3 ALU 2
237 ;; fabs 3 ALU 2
238 ;; fadd 3 ALU 2
239 ;; fsub 3 ALU 2
240 ;; fcmp 3 ALU 2
241 ;; fcnv 3 ALU 2
242 ;; fmpyadd 3 ALU,MPY 2
243 ;; fmpysub 3 ALU,MPY 2
244 ;; fmpycfxt 3 ALU,MPY 2
245 ;; fmpy 3 MPY 2
246 ;; fmpyi 3 MPY 2
247 ;; fdiv,sgl 10 MPY 10
248 ;; fdiv,dbl 12 MPY 12
249 ;; fsqrt,sgl 14 MPY 14
250 ;; fsqrt,dbl 18 MPY 18
251 ;;
252 ;; We don't model fmpyadd/fmpysub properly as those instructions
253 ;; keep both the FP ALU and MPY units busy. Given that these
254 ;; processors are obsolete, I'm not going to spend the time to
255 ;; model those instructions correctly.
256
257 (define_automaton "pa700")
258 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
259
260 (define_insn_reservation "W0" 4
261 (and (eq_attr "type" "fpcc")
262 (eq_attr "cpu" "700"))
263 "fpalu_700*2")
264
265 (define_insn_reservation "W1" 3
266 (and (eq_attr "type" "fpalu")
267 (eq_attr "cpu" "700"))
268 "fpalu_700*2")
269
270 (define_insn_reservation "W2" 3
271 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
272 (eq_attr "cpu" "700"))
273 "fpmpy_700*2")
274
275 (define_insn_reservation "W3" 10
276 (and (eq_attr "type" "fpdivsgl")
277 (eq_attr "cpu" "700"))
278 "fpmpy_700*10")
279
280 (define_insn_reservation "W4" 12
281 (and (eq_attr "type" "fpdivdbl")
282 (eq_attr "cpu" "700"))
283 "fpmpy_700*12")
284
285 (define_insn_reservation "W5" 14
286 (and (eq_attr "type" "fpsqrtsgl")
287 (eq_attr "cpu" "700"))
288 "fpmpy_700*14")
289
290 (define_insn_reservation "W6" 18
291 (and (eq_attr "type" "fpsqrtdbl")
292 (eq_attr "cpu" "700"))
293 "fpmpy_700*18")
294
295 (define_insn_reservation "W7" 2
296 (and (eq_attr "type" "load")
297 (eq_attr "cpu" "700"))
298 "mem_700")
299
300 (define_insn_reservation "W8" 2
301 (and (eq_attr "type" "fpload")
302 (eq_attr "cpu" "700"))
303 "mem_700")
304
305 (define_insn_reservation "W9" 3
306 (and (eq_attr "type" "store")
307 (eq_attr "cpu" "700"))
308 "mem_700*3")
309
310 (define_insn_reservation "W10" 3
311 (and (eq_attr "type" "fpstore")
312 (eq_attr "cpu" "700"))
313 "mem_700*3")
314
315 (define_insn_reservation "W11" 5
316 (and (eq_attr "type" "fpstore_load")
317 (eq_attr "cpu" "700"))
318 "mem_700*5")
319
320 (define_insn_reservation "W12" 6
321 (and (eq_attr "type" "store_fpload")
322 (eq_attr "cpu" "700"))
323 "mem_700*6")
324
325 (define_insn_reservation "W13" 1
326 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
327 (eq_attr "cpu" "700"))
328 "dummy_700")
329
330 ;; We have a bypass for all computations in the FP unit which feed an
331 ;; FP store as long as the sizes are the same.
332 (define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
333 (define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
334 (define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
335 (define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
336 (define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
337
338 ;; We have an "anti-bypass" for FP loads which feed an FP store.
339 (define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
340
341 ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
342 ;; floating point computations with non-floating point computations (fp loads
343 ;; and stores are not fp computations).
344 ;;
345 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
346 ;; take two cycles, during which no Dcache operations should be scheduled.
347 ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
348 ;; all have the same memory characteristics if one disregards cache misses.
349 ;;
350 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
351 ;; There's no value in modeling the ALU and MUL separately though
352 ;; since there can never be a functional unit conflict given the
353 ;; latency and issue rates for those units.
354 ;;
355 ;; Timings:
356 ;; Instruction Time Unit Minimum Distance (unit contention)
357 ;; fcpy 2 ALU 1
358 ;; fabs 2 ALU 1
359 ;; fadd 2 ALU 1
360 ;; fsub 2 ALU 1
361 ;; fcmp 2 ALU 1
362 ;; fcnv 2 ALU 1
363 ;; fmpyadd 2 ALU,MPY 1
364 ;; fmpysub 2 ALU,MPY 1
365 ;; fmpycfxt 2 ALU,MPY 1
366 ;; fmpy 2 MPY 1
367 ;; fmpyi 2 MPY 1
368 ;; fdiv,sgl 8 DIV 8
369 ;; fdiv,dbl 15 DIV 15
370 ;; fsqrt,sgl 8 DIV 8
371 ;; fsqrt,dbl 15 DIV 15
372
373 (define_automaton "pa7100")
374 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
375
376 (define_insn_reservation "X0" 2
377 (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
378 (eq_attr "cpu" "7100"))
379 "f_7100,fpmac_7100")
380
381 (define_insn_reservation "X1" 8
382 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
383 (eq_attr "cpu" "7100"))
384 "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
385
386 (define_insn_reservation "X2" 15
387 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
388 (eq_attr "cpu" "7100"))
389 "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
390
391 (define_insn_reservation "X3" 2
392 (and (eq_attr "type" "load")
393 (eq_attr "cpu" "7100"))
394 "i_7100+mem_7100")
395
396 (define_insn_reservation "X4" 2
397 (and (eq_attr "type" "fpload")
398 (eq_attr "cpu" "7100"))
399 "i_7100+mem_7100")
400
401 (define_insn_reservation "X5" 2
402 (and (eq_attr "type" "store")
403 (eq_attr "cpu" "7100"))
404 "i_7100+mem_7100,mem_7100")
405
406 (define_insn_reservation "X6" 2
407 (and (eq_attr "type" "fpstore")
408 (eq_attr "cpu" "7100"))
409 "i_7100+mem_7100,mem_7100")
410
411 (define_insn_reservation "X7" 4
412 (and (eq_attr "type" "fpstore_load")
413 (eq_attr "cpu" "7100"))
414 "i_7100+mem_7100,mem_7100*3")
415
416 (define_insn_reservation "X8" 4
417 (and (eq_attr "type" "store_fpload")
418 (eq_attr "cpu" "7100"))
419 "i_7100+mem_7100,mem_7100*3")
420
421 (define_insn_reservation "X9" 1
422 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
423 (eq_attr "cpu" "7100"))
424 "i_7100")
425
426 ;; We have a bypass for all computations in the FP unit which feed an
427 ;; FP store as long as the sizes are the same.
428 (define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
429 (define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
430 (define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
431
432 ;; We have an "anti-bypass" for FP loads which feed an FP store.
433 (define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
434
435 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
436 ;; There's no value in modeling the ALU and MUL separately though
437 ;; since there can never be a functional unit conflict that
438 ;; can be avoided given the latency, issue rates and mandatory
439 ;; one cycle cpu-wide lock for a double precision fp multiply.
440 ;;
441 ;; Timings:
442 ;; Instruction Time Unit Minimum Distance (unit contention)
443 ;; fcpy 2 ALU 1
444 ;; fabs 2 ALU 1
445 ;; fadd 2 ALU 1
446 ;; fsub 2 ALU 1
447 ;; fcmp 2 ALU 1
448 ;; fcnv 2 ALU 1
449 ;; fmpyadd,sgl 2 ALU,MPY 1
450 ;; fmpyadd,dbl 3 ALU,MPY 2
451 ;; fmpysub,sgl 2 ALU,MPY 1
452 ;; fmpysub,dbl 3 ALU,MPY 2
453 ;; fmpycfxt,sgl 2 ALU,MPY 1
454 ;; fmpycfxt,dbl 3 ALU,MPY 2
455 ;; fmpy,sgl 2 MPY 1
456 ;; fmpy,dbl 3 MPY 2
457 ;; fmpyi 3 MPY 2
458 ;; fdiv,sgl 8 DIV 8
459 ;; fdiv,dbl 15 DIV 15
460 ;; fsqrt,sgl 8 DIV 8
461 ;; fsqrt,dbl 15 DIV 15
462 ;;
463 ;; The PA7200 is just like the PA7100LC except that there is
464 ;; no store-store penalty.
465 ;;
466 ;; The PA7300 is just like the PA7200 except that there is
467 ;; no store-load penalty.
468 ;;
469 ;; Note there are some aspects of the 7100LC we are not modeling
470 ;; at the moment. I'll be reviewing the 7100LC scheduling info
471 ;; shortly and updating this description.
472 ;;
473 ;; load-load pairs
474 ;; store-store pairs
475 ;; other issue modeling
476
477 (define_automaton "pa7100lc")
478 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
479 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
480 (define_cpu_unit "mem_7100lc" "pa7100lc")
481
482 ;; Double precision multiplies lock the entire CPU for one
483 ;; cycle. There is no way to avoid this lock and trying to
484 ;; schedule around the lock is pointless and thus there is no
485 ;; value in trying to model this lock.
486 ;;
487 ;; Not modeling the lock allows us to treat fp multiplies just
488 ;; like any other FP alu instruction. It allows for a smaller
489 ;; DFA and may reduce register pressure.
490 (define_insn_reservation "Y0" 2
491 (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
492 (eq_attr "cpu" "7100LC,7200,7300"))
493 "f_7100lc,fpmac_7100lc")
494
495 ;; fp division and sqrt instructions lock the entire CPU for
496 ;; 7 cycles (single precision) or 14 cycles (double precision).
497 ;; There is no way to avoid this lock and trying to schedule
498 ;; around the lock is pointless and thus there is no value in
499 ;; trying to model this lock. Not modeling the lock allows
500 ;; for a smaller DFA and may reduce register pressure.
501 (define_insn_reservation "Y1" 1
502 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
503 (eq_attr "cpu" "7100LC,7200,7300"))
504 "f_7100lc")
505
506 (define_insn_reservation "Y2" 2
507 (and (eq_attr "type" "load")
508 (eq_attr "cpu" "7100LC,7200,7300"))
509 "i1_7100lc+mem_7100lc")
510
511 (define_insn_reservation "Y3" 2
512 (and (eq_attr "type" "fpload")
513 (eq_attr "cpu" "7100LC,7200,7300"))
514 "i1_7100lc+mem_7100lc")
515
516 (define_insn_reservation "Y4" 2
517 (and (eq_attr "type" "store")
518 (eq_attr "cpu" "7100LC"))
519 "i1_7100lc+mem_7100lc,mem_7100lc")
520
521 (define_insn_reservation "Y5" 2
522 (and (eq_attr "type" "fpstore")
523 (eq_attr "cpu" "7100LC"))
524 "i1_7100lc+mem_7100lc,mem_7100lc")
525
526 (define_insn_reservation "Y6" 4
527 (and (eq_attr "type" "fpstore_load")
528 (eq_attr "cpu" "7100LC"))
529 "i1_7100lc+mem_7100lc,mem_7100lc*3")
530
531 (define_insn_reservation "Y7" 4
532 (and (eq_attr "type" "store_fpload")
533 (eq_attr "cpu" "7100LC"))
534 "i1_7100lc+mem_7100lc,mem_7100lc*3")
535
536 (define_insn_reservation "Y8" 1
537 (and (eq_attr "type" "shift,nullshift")
538 (eq_attr "cpu" "7100LC,7200,7300"))
539 "i1_7100lc")
540
541 (define_insn_reservation "Y9" 1
542 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
543 (eq_attr "cpu" "7100LC,7200,7300"))
544 "(i0_7100lc|i1_7100lc)")
545
546 ;; The 7200 has a store-load penalty
547 (define_insn_reservation "Y10" 2
548 (and (eq_attr "type" "store")
549 (eq_attr "cpu" "7200"))
550 "i1_7100lc,mem_7100lc")
551
552 (define_insn_reservation "Y11" 2
553 (and (eq_attr "type" "fpstore")
554 (eq_attr "cpu" "7200"))
555 "i1_7100lc,mem_7100lc")
556
557 (define_insn_reservation "Y12" 4
558 (and (eq_attr "type" "fpstore_load")
559 (eq_attr "cpu" "7200"))
560 "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
561
562 (define_insn_reservation "Y13" 4
563 (and (eq_attr "type" "store_fpload")
564 (eq_attr "cpu" "7200"))
565 "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
566
567 ;; The 7300 has no penalty for store-store or store-load
568 (define_insn_reservation "Y14" 2
569 (and (eq_attr "type" "store")
570 (eq_attr "cpu" "7300"))
571 "i1_7100lc")
572
573 (define_insn_reservation "Y15" 2
574 (and (eq_attr "type" "fpstore")
575 (eq_attr "cpu" "7300"))
576 "i1_7100lc")
577
578 (define_insn_reservation "Y16" 4
579 (and (eq_attr "type" "fpstore_load")
580 (eq_attr "cpu" "7300"))
581 "i1_7100lc,i1_7100lc+mem_7100lc")
582
583 (define_insn_reservation "Y17" 4
584 (and (eq_attr "type" "store_fpload")
585 (eq_attr "cpu" "7300"))
586 "i1_7100lc,i1_7100lc+mem_7100lc")
587
588 ;; We have an "anti-bypass" for FP loads which feed an FP store.
589 (define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
590
591 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
592 ;; traditional architecture.
593 ;;
594 ;; The PA8000 has a large (56) entry reorder buffer that is split between
595 ;; memory and non-memory operations.
596 ;;
597 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
598 ;; the function units, with the exception of branches and multi-output
599 ;; instructions. The PA8000 can retire two non-memory operations per cycle
600 ;; and two memory operations per cycle, only one of which may be a store.
601 ;;
602 ;; Given the large reorder buffer, the processor can hide most latencies.
603 ;; According to HP, they've got the best results by scheduling for retirement
604 ;; bandwidth with limited latency scheduling for floating point operations.
605 ;; Latency for integer operations and memory references is ignored.
606 ;;
607 ;;
608 ;; We claim floating point operations have a 2 cycle latency and are
609 ;; fully pipelined, except for div and sqrt which are not pipelined and
610 ;; take from 17 to 31 cycles to complete.
611 ;;
612 ;; It's worth noting that there is no way to saturate all the functional
613 ;; units on the PA8000 as there is not enough issue bandwidth.
614
615 (define_automaton "pa8000")
616 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
617 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
618 (define_cpu_unit "store_8000" "pa8000")
619 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
620 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
621 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
622 (define_reservation "im_8000" "im0_8000 | im1_8000")
623 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
624 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
625 (define_reservation "f_8000" "f0_8000 | f1_8000")
626 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
627
628 ;; We can issue any two memops per cycle, but we can only retire
629 ;; one memory store per cycle. We assume that the reorder buffer
630 ;; will hide any memory latencies per HP's recommendation.
631 (define_insn_reservation "Z0" 0
632 (and
633 (eq_attr "type" "load,fpload")
634 (eq_attr "cpu" "8000"))
635 "im_8000,rm_8000")
636
637 (define_insn_reservation "Z1" 0
638 (and
639 (eq_attr "type" "store,fpstore")
640 (eq_attr "cpu" "8000"))
641 "im_8000,rm_8000+store_8000")
642
643 (define_insn_reservation "Z2" 0
644 (and (eq_attr "type" "fpstore_load,store_fpload")
645 (eq_attr "cpu" "8000"))
646 "im_8000,rm_8000+store_8000,im_8000,rm_8000")
647
648 ;; We can issue and retire two non-memory operations per cycle with
649 ;; a few exceptions (branches). This group catches those we want
650 ;; to assume have zero latency.
651 (define_insn_reservation "Z3" 0
652 (and
653 (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload")
654 (eq_attr "cpu" "8000"))
655 "inm_8000,rnm_8000")
656
657 ;; Branches use both slots in the non-memory issue and
658 ;; retirement unit.
659 (define_insn_reservation "Z4" 0
660 (and
661 (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
662 (eq_attr "cpu" "8000"))
663 "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
664
665 ;; We partial latency schedule the floating point units.
666 ;; They can issue/retire two at a time in the non-memory
667 ;; units. We fix their latency at 2 cycles and they
668 ;; are fully pipelined.
669 (define_insn_reservation "Z5" 1
670 (and
671 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
672 (eq_attr "cpu" "8000"))
673 "inm_8000,f_8000,rnm_8000")
674
675 ;; The fdivsqrt units are not pipelined and have a very long latency.
676 ;; To keep the DFA from exploding, we do not show all the
677 ;; reservations for the divsqrt unit.
678 (define_insn_reservation "Z6" 17
679 (and
680 (eq_attr "type" "fpdivsgl,fpsqrtsgl")
681 (eq_attr "cpu" "8000"))
682 "inm_8000,fdivsqrt_8000*6,rnm_8000")
683
684 (define_insn_reservation "Z7" 31
685 (and
686 (eq_attr "type" "fpdivdbl,fpsqrtdbl")
687 (eq_attr "cpu" "8000"))
688 "inm_8000,fdivsqrt_8000*6,rnm_8000")
689
690 ;; Operand and operator predicates and constraints
691
692 (include "predicates.md")
693 (include "constraints.md")
694 \f
695 ;; Atomic instructions
696
697 ;; All memory loads and stores access storage atomically except
698 ;; for one exception. The STORE BYTES, STORE DOUBLE BYTES, and
699 ;; doubleword loads and stores are not guaranteed to be atomic
700 ;; when referencing the I/O address space.
701
702 ;; The kernel cmpxchg operation on linux is not atomic with respect to
703 ;; memory stores on SMP machines, so we must do stores using a cmpxchg
704 ;; operation.
705
706 ;; Implement atomic QImode store using exchange.
707
708 (define_expand "atomic_storeqi"
709 [(match_operand:QI 0 "memory_operand") ;; memory
710 (match_operand:QI 1 "register_operand") ;; val out
711 (match_operand:SI 2 "const_int_operand")] ;; model
712 ""
713 {
714 if (TARGET_SYNC_LIBCALL)
715 {
716 rtx mem = operands[0];
717 rtx val = operands[1];
718 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
719 DONE;
720 }
721 FAIL;
722 })
723
724 ;; Implement atomic HImode stores using exchange.
725
726 (define_expand "atomic_storehi"
727 [(match_operand:HI 0 "memory_operand") ;; memory
728 (match_operand:HI 1 "register_operand") ;; val out
729 (match_operand:SI 2 "const_int_operand")] ;; model
730 ""
731 {
732 if (TARGET_SYNC_LIBCALL)
733 {
734 rtx mem = operands[0];
735 rtx val = operands[1];
736 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
737 DONE;
738 }
739 FAIL;
740 })
741
742 ;; Implement atomic SImode store using exchange.
743
744 (define_expand "atomic_storesi"
745 [(match_operand:SI 0 "memory_operand") ;; memory
746 (match_operand:SI 1 "register_operand") ;; val out
747 (match_operand:SI 2 "const_int_operand")] ;; model
748 ""
749 {
750 if (TARGET_SYNC_LIBCALL)
751 {
752 rtx mem = operands[0];
753 rtx val = operands[1];
754 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
755 DONE;
756 }
757 FAIL;
758 })
759
760 ;; Implement atomic SFmode store using exchange.
761
762 (define_expand "atomic_storesf"
763 [(match_operand:SF 0 "memory_operand") ;; memory
764 (match_operand:SF 1 "register_operand") ;; val out
765 (match_operand:SI 2 "const_int_operand")] ;; model
766 ""
767 {
768 if (TARGET_SYNC_LIBCALL)
769 {
770 rtx mem = operands[0];
771 rtx val = operands[1];
772 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
773 DONE;
774 }
775 FAIL;
776 })
777
778 ;; Implement atomic DImode load using 64-bit floating point load.
779
780 (define_expand "atomic_loaddi"
781 [(match_operand:DI 0 "register_operand") ;; val out
782 (match_operand:DI 1 "memory_operand") ;; memory
783 (match_operand:SI 2 "const_int_operand")] ;; model
784 ""
785 {
786 enum memmodel model;
787
788 if (TARGET_64BIT || TARGET_SOFT_FLOAT)
789 FAIL;
790
791 model = memmodel_from_int (INTVAL (operands[2]));
792 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
793 expand_mem_thread_fence (model);
794 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
795 if (is_mm_seq_cst (model))
796 expand_mem_thread_fence (model);
797 DONE;
798 })
799
800 (define_insn "atomic_loaddi_1"
801 [(set (match_operand:DI 0 "register_operand" "=f,r")
802 (mem:DI (match_operand:SI 1 "register_operand" "r,r")))
803 (clobber (match_scratch:DI 2 "=X,f"))]
804 "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
805 "@
806 {fldds|fldd} 0(%1),%0
807 {fldds|fldd} 0(%1),%2\n\t{fstds|fstd} %2,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0\n\t{ldws|ldw} -12(%%sp),%R0"
808 [(set_attr "type" "move,move")
809 (set_attr "length" "4,16")])
810
811 ;; Implement atomic DImode store.
812
813 (define_expand "atomic_storedi"
814 [(match_operand:DI 0 "memory_operand") ;; memory
815 (match_operand:DI 1 "register_operand") ;; val out
816 (match_operand:SI 2 "const_int_operand")] ;; model
817 ""
818 {
819 enum memmodel model;
820
821 if (TARGET_SYNC_LIBCALL)
822 {
823 rtx mem = operands[0];
824 rtx val = operands[1];
825 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
826 DONE;
827 }
828
829 if (TARGET_64BIT || TARGET_SOFT_FLOAT)
830 FAIL;
831
832 model = memmodel_from_int (INTVAL (operands[2]));
833 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
834 expand_mem_thread_fence (model);
835 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
836 if (is_mm_seq_cst (model))
837 expand_mem_thread_fence (model);
838 DONE;
839 })
840
841 (define_insn "atomic_storedi_1"
842 [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
843 (match_operand:DI 1 "register_operand" "f,r"))
844 (clobber (match_scratch:DI 2 "=X,f"))]
845 "!TARGET_64BIT && !TARGET_SOFT_FLOAT && !TARGET_SYNC_LIBCALL"
846 "@
847 {fstds|fstd} %1,0(%0)
848 {stws|stw} %1,-16(%%sp)\n\t{stws|stw} %R1,-12(%%sp)\n\t{fldds|fldd} -16(%%sp),%2\n\t{fstds|fstd} %2,0(%0)"
849 [(set_attr "type" "move,move")
850 (set_attr "length" "4,16")])
851
852 ;; Implement atomic DFmode load using 64-bit floating point load.
853
854 (define_expand "atomic_loaddf"
855 [(match_operand:DF 0 "register_operand") ;; val out
856 (match_operand:DF 1 "memory_operand") ;; memory
857 (match_operand:SI 2 "const_int_operand")] ;; model
858 ""
859 {
860 enum memmodel model;
861
862 if (TARGET_64BIT || TARGET_SOFT_FLOAT)
863 FAIL;
864
865 model = memmodel_from_int (INTVAL (operands[2]));
866 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
867 expand_mem_thread_fence (model);
868 emit_insn (gen_atomic_loaddf_1 (operands[0], operands[1]));
869 if (is_mm_seq_cst (model))
870 expand_mem_thread_fence (model);
871 DONE;
872 })
873
874 (define_insn "atomic_loaddf_1"
875 [(set (match_operand:DF 0 "register_operand" "=f,r")
876 (mem:DF (match_operand:SI 1 "register_operand" "r,r")))
877 (clobber (match_scratch:DF 2 "=X,f"))]
878 "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
879 "@
880 {fldds|fldd} 0(%1),%0
881 {fldds|fldd} 0(%1),%2\n\t{fstds|fstd} %2,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0\n\t{ldws|ldw} -12(%%sp),%R0"
882 [(set_attr "type" "move,move")
883 (set_attr "length" "4,16")])
884
885 ;; Implement atomic DFmode store using 64-bit floating point store.
886
887 (define_expand "atomic_storedf"
888 [(match_operand:DF 0 "memory_operand") ;; memory
889 (match_operand:DF 1 "register_operand") ;; val out
890 (match_operand:SI 2 "const_int_operand")] ;; model
891 ""
892 {
893 enum memmodel model;
894
895 if (TARGET_SYNC_LIBCALL)
896 {
897 rtx mem = operands[0];
898 rtx val = operands[1];
899 if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
900 DONE;
901 }
902
903 if (TARGET_64BIT || TARGET_SOFT_FLOAT)
904 FAIL;
905
906 model = memmodel_from_int (INTVAL (operands[2]));
907 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
908 expand_mem_thread_fence (model);
909 emit_insn (gen_atomic_storedf_1 (operands[0], operands[1]));
910 if (is_mm_seq_cst (model))
911 expand_mem_thread_fence (model);
912 DONE;
913 })
914
915 (define_insn "atomic_storedf_1"
916 [(set (mem:DF (match_operand:SI 0 "register_operand" "r,r"))
917 (match_operand:DF 1 "register_operand" "f,r"))
918 (clobber (match_scratch:DF 2 "=X,f"))]
919 "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
920 "@
921 {fstds|fstd} %1,0(%0)
922 {stws|stw} %1,-16(%%sp)\n\t{stws|stw} %R1,-12(%%sp)\n\t{fldds|fldd} -16(%%sp),%2\n\t{fstds|fstd} %2,0(%0)"
923 [(set_attr "type" "move,move")
924 (set_attr "length" "4,16")])
925
926 ;; Compare instructions.
927 ;; This controls RTL generation and register allocation.
928
929 (define_insn ""
930 [(set (reg:CCFP 0)
931 (match_operator:CCFP 2 "comparison_operator"
932 [(match_operand:SF 0 "reg_or_0_operand" "fG")
933 (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
934 "! TARGET_SOFT_FLOAT"
935 "fcmp,sgl,%Y2 %f0,%f1"
936 [(set_attr "length" "4")
937 (set_attr "type" "fpcc")])
938
939 (define_insn ""
940 [(set (reg:CCFP 0)
941 (match_operator:CCFP 2 "comparison_operator"
942 [(match_operand:DF 0 "reg_or_0_operand" "fG")
943 (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
944 "! TARGET_SOFT_FLOAT"
945 "fcmp,dbl,%Y2 %f0,%f1"
946 [(set_attr "length" "4")
947 (set_attr "type" "fpcc")])
948
949 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
950 ;; placeholders. This is necessary in rare situations when a
951 ;; placeholder is re-emitted (see PR 8705).
952
953 (define_expand "movccfp"
954 [(set (reg:CCFP 0)
955 (match_operand 0 "const_int_operand" ""))]
956 "! TARGET_SOFT_FLOAT"
957 "
958 {
959 if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
960 FAIL;
961 }")
962
963 ;; The following patterns are optimization placeholders. In almost
964 ;; all cases, the user of the condition code will be simplified and the
965 ;; original condition code setting insn should be eliminated.
966
967 (define_insn "*movccfp0"
968 [(set (reg:CCFP 0)
969 (const_int 0))]
970 "! TARGET_SOFT_FLOAT"
971 "fcmp,dbl,= %%fr0,%%fr0"
972 [(set_attr "length" "4")
973 (set_attr "type" "fpcc")])
974
975 (define_insn "*movccfp1"
976 [(set (reg:CCFP 0)
977 (const_int 1))]
978 "! TARGET_SOFT_FLOAT"
979 "fcmp,dbl,!= %%fr0,%%fr0"
980 [(set_attr "length" "4")
981 (set_attr "type" "fpcc")])
982
983 ;; scc insns.
984
985 (define_expand "cstoresi4"
986 [(set (match_operand:SI 0 "register_operand")
987 (match_operator:SI 1 "ordered_comparison_operator"
988 [(match_operand:SI 2 "reg_or_0_operand" "")
989 (match_operand:SI 3 "arith5_operand" "")]))]
990 "!TARGET_64BIT"
991 "")
992
993 ;; Instruction canonicalization puts immediate operands second, which
994 ;; is the reverse of what we want.
995
996 (define_insn "scc"
997 [(set (match_operand:SI 0 "register_operand" "=r")
998 (match_operator:SI 3 "comparison_operator"
999 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1000 (match_operand:SI 2 "arith11_operand" "rI")]))]
1001 ""
1002 "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
1003 [(set_attr "type" "binary")
1004 (set_attr "length" "8")])
1005
1006 (define_insn ""
1007 [(set (match_operand:DI 0 "register_operand" "=r")
1008 (match_operator:DI 3 "comparison_operator"
1009 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1010 (match_operand:DI 2 "arith11_operand" "rI")]))]
1011 "TARGET_64BIT"
1012 "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
1013 [(set_attr "type" "binary")
1014 (set_attr "length" "8")])
1015
1016 (define_insn "iorscc"
1017 [(set (match_operand:SI 0 "register_operand" "=r")
1018 (ior:SI (match_operator:SI 3 "comparison_operator"
1019 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1020 (match_operand:SI 2 "arith11_operand" "rI")])
1021 (match_operator:SI 6 "comparison_operator"
1022 [(match_operand:SI 4 "reg_or_0_operand" "rM")
1023 (match_operand:SI 5 "arith11_operand" "rI")])))]
1024 ""
1025 "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
1026 [(set_attr "type" "binary")
1027 (set_attr "length" "12")])
1028
1029 (define_insn ""
1030 [(set (match_operand:DI 0 "register_operand" "=r")
1031 (ior:DI (match_operator:DI 3 "comparison_operator"
1032 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1033 (match_operand:DI 2 "arith11_operand" "rI")])
1034 (match_operator:DI 6 "comparison_operator"
1035 [(match_operand:DI 4 "reg_or_0_operand" "rM")
1036 (match_operand:DI 5 "arith11_operand" "rI")])))]
1037 "TARGET_64BIT"
1038 "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
1039 [(set_attr "type" "binary")
1040 (set_attr "length" "12")])
1041
1042 ;; Combiner patterns for common operations performed with the output
1043 ;; from an scc insn (negscc and incscc).
1044 (define_insn "negscc"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (neg:SI (match_operator:SI 3 "comparison_operator"
1047 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1048 (match_operand:SI 2 "arith11_operand" "rI")])))]
1049 ""
1050 "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
1051 [(set_attr "type" "binary")
1052 (set_attr "length" "8")])
1053
1054 (define_insn ""
1055 [(set (match_operand:DI 0 "register_operand" "=r")
1056 (neg:DI (match_operator:DI 3 "comparison_operator"
1057 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1058 (match_operand:DI 2 "arith11_operand" "rI")])))]
1059 "TARGET_64BIT"
1060 "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
1061 [(set_attr "type" "binary")
1062 (set_attr "length" "8")])
1063
1064 ;; Patterns for adding/subtracting the result of a boolean expression from
1065 ;; a register. First we have special patterns that make use of the carry
1066 ;; bit, and output only two instructions. For the cases we can't in
1067 ;; general do in two instructions, the incscc pattern at the end outputs
1068 ;; two or three instructions.
1069
1070 (define_insn ""
1071 [(set (match_operand:SI 0 "register_operand" "=r")
1072 (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
1073 (match_operand:SI 3 "arith11_operand" "rI"))
1074 (match_operand:SI 1 "register_operand" "r")))]
1075 ""
1076 "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
1077 [(set_attr "type" "binary")
1078 (set_attr "length" "8")])
1079
1080 (define_insn ""
1081 [(set (match_operand:DI 0 "register_operand" "=r")
1082 (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
1083 (match_operand:DI 3 "arith11_operand" "rI"))
1084 (match_operand:DI 1 "register_operand" "r")))]
1085 "TARGET_64BIT"
1086 "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
1087 [(set_attr "type" "binary")
1088 (set_attr "length" "8")])
1089
1090 ; This need only accept registers for op3, since canonicalization
1091 ; replaces geu with gtu when op3 is an integer.
1092 (define_insn ""
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
1095 (match_operand:SI 3 "register_operand" "r"))
1096 (match_operand:SI 1 "register_operand" "r")))]
1097 ""
1098 "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
1099 [(set_attr "type" "binary")
1100 (set_attr "length" "8")])
1101
1102 (define_insn ""
1103 [(set (match_operand:DI 0 "register_operand" "=r")
1104 (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
1105 (match_operand:DI 3 "register_operand" "r"))
1106 (match_operand:DI 1 "register_operand" "r")))]
1107 "TARGET_64BIT"
1108 "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
1109 [(set_attr "type" "binary")
1110 (set_attr "length" "8")])
1111
1112 ; Match only integers for op3 here. This is used as canonical form of the
1113 ; geu pattern when op3 is an integer. Don't match registers since we can't
1114 ; make better code than the general incscc pattern.
1115 (define_insn ""
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
1118 (match_operand:SI 3 "int11_operand" "I"))
1119 (match_operand:SI 1 "register_operand" "r")))]
1120 ""
1121 "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
1122 [(set_attr "type" "binary")
1123 (set_attr "length" "8")])
1124
1125 (define_insn ""
1126 [(set (match_operand:DI 0 "register_operand" "=r")
1127 (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
1128 (match_operand:DI 3 "int11_operand" "I"))
1129 (match_operand:DI 1 "register_operand" "r")))]
1130 "TARGET_64BIT"
1131 "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
1132 [(set_attr "type" "binary")
1133 (set_attr "length" "8")])
1134
1135 (define_insn "incscc"
1136 [(set (match_operand:SI 0 "register_operand" "=r,r")
1137 (plus:SI (match_operator:SI 4 "comparison_operator"
1138 [(match_operand:SI 2 "register_operand" "r,r")
1139 (match_operand:SI 3 "arith11_operand" "rI,rI")])
1140 (match_operand:SI 1 "register_operand" "0,?r")))]
1141 ""
1142 "@
1143 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
1144 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
1145 [(set_attr "type" "binary,binary")
1146 (set_attr "length" "8,12")])
1147
1148 (define_insn ""
1149 [(set (match_operand:DI 0 "register_operand" "=r,r")
1150 (plus:DI (match_operator:DI 4 "comparison_operator"
1151 [(match_operand:DI 2 "register_operand" "r,r")
1152 (match_operand:DI 3 "arith11_operand" "rI,rI")])
1153 (match_operand:DI 1 "register_operand" "0,?r")))]
1154 "TARGET_64BIT"
1155 "@
1156 cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
1157 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
1158 [(set_attr "type" "binary,binary")
1159 (set_attr "length" "8,12")])
1160
1161 (define_insn ""
1162 [(set (match_operand:SI 0 "register_operand" "=r")
1163 (minus:SI (match_operand:SI 1 "register_operand" "r")
1164 (gtu:SI (match_operand:SI 2 "register_operand" "r")
1165 (match_operand:SI 3 "arith11_operand" "rI"))))]
1166 ""
1167 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1168 [(set_attr "type" "binary")
1169 (set_attr "length" "8")])
1170
1171 (define_insn ""
1172 [(set (match_operand:DI 0 "register_operand" "=r")
1173 (minus:DI (match_operand:DI 1 "register_operand" "r")
1174 (gtu:DI (match_operand:DI 2 "register_operand" "r")
1175 (match_operand:DI 3 "arith11_operand" "rI"))))]
1176 "TARGET_64BIT"
1177 "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
1178 [(set_attr "type" "binary")
1179 (set_attr "length" "8")])
1180
1181 (define_insn ""
1182 [(set (match_operand:SI 0 "register_operand" "=r")
1183 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1184 (gtu:SI (match_operand:SI 2 "register_operand" "r")
1185 (match_operand:SI 3 "arith11_operand" "rI")))
1186 (match_operand:SI 4 "register_operand" "r")))]
1187 ""
1188 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1189 [(set_attr "type" "binary")
1190 (set_attr "length" "8")])
1191
1192 (define_insn ""
1193 [(set (match_operand:DI 0 "register_operand" "=r")
1194 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1195 (gtu:DI (match_operand:DI 2 "register_operand" "r")
1196 (match_operand:DI 3 "arith11_operand" "rI")))
1197 (match_operand:DI 4 "register_operand" "r")))]
1198 "TARGET_64BIT"
1199 "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
1200 [(set_attr "type" "binary")
1201 (set_attr "length" "8")])
1202
1203 ; This need only accept registers for op3, since canonicalization
1204 ; replaces ltu with leu when op3 is an integer.
1205 (define_insn ""
1206 [(set (match_operand:SI 0 "register_operand" "=r")
1207 (minus:SI (match_operand:SI 1 "register_operand" "r")
1208 (ltu:SI (match_operand:SI 2 "register_operand" "r")
1209 (match_operand:SI 3 "register_operand" "r"))))]
1210 ""
1211 "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
1212 [(set_attr "type" "binary")
1213 (set_attr "length" "8")])
1214
1215 (define_insn ""
1216 [(set (match_operand:DI 0 "register_operand" "=r")
1217 (minus:DI (match_operand:DI 1 "register_operand" "r")
1218 (ltu:DI (match_operand:DI 2 "register_operand" "r")
1219 (match_operand:DI 3 "register_operand" "r"))))]
1220 "TARGET_64BIT"
1221 "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
1222 [(set_attr "type" "binary")
1223 (set_attr "length" "8")])
1224
1225 (define_insn ""
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1228 (ltu:SI (match_operand:SI 2 "register_operand" "r")
1229 (match_operand:SI 3 "register_operand" "r")))
1230 (match_operand:SI 4 "register_operand" "r")))]
1231 ""
1232 "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1233 [(set_attr "type" "binary")
1234 (set_attr "length" "8")])
1235
1236 (define_insn ""
1237 [(set (match_operand:DI 0 "register_operand" "=r")
1238 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1239 (ltu:DI (match_operand:DI 2 "register_operand" "r")
1240 (match_operand:DI 3 "register_operand" "r")))
1241 (match_operand:DI 4 "register_operand" "r")))]
1242 "TARGET_64BIT"
1243 "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1244 [(set_attr "type" "binary")
1245 (set_attr "length" "8")])
1246
1247 ; Match only integers for op3 here. This is used as canonical form of the
1248 ; ltu pattern when op3 is an integer. Don't match registers since we can't
1249 ; make better code than the general incscc pattern.
1250 (define_insn ""
1251 [(set (match_operand:SI 0 "register_operand" "=r")
1252 (minus:SI (match_operand:SI 1 "register_operand" "r")
1253 (leu:SI (match_operand:SI 2 "register_operand" "r")
1254 (match_operand:SI 3 "int11_operand" "I"))))]
1255 ""
1256 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1257 [(set_attr "type" "binary")
1258 (set_attr "length" "8")])
1259
1260 (define_insn ""
1261 [(set (match_operand:DI 0 "register_operand" "=r")
1262 (minus:DI (match_operand:DI 1 "register_operand" "r")
1263 (leu:DI (match_operand:DI 2 "register_operand" "r")
1264 (match_operand:DI 3 "int11_operand" "I"))))]
1265 "TARGET_64BIT"
1266 "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1267 [(set_attr "type" "binary")
1268 (set_attr "length" "8")])
1269
1270 (define_insn ""
1271 [(set (match_operand:SI 0 "register_operand" "=r")
1272 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1273 (leu:SI (match_operand:SI 2 "register_operand" "r")
1274 (match_operand:SI 3 "int11_operand" "I")))
1275 (match_operand:SI 4 "register_operand" "r")))]
1276 ""
1277 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1278 [(set_attr "type" "binary")
1279 (set_attr "length" "8")])
1280
1281 (define_insn ""
1282 [(set (match_operand:DI 0 "register_operand" "=r")
1283 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1284 (leu:DI (match_operand:DI 2 "register_operand" "r")
1285 (match_operand:DI 3 "int11_operand" "I")))
1286 (match_operand:DI 4 "register_operand" "r")))]
1287 "TARGET_64BIT"
1288 "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1289 [(set_attr "type" "binary")
1290 (set_attr "length" "8")])
1291
1292 (define_insn "decscc"
1293 [(set (match_operand:SI 0 "register_operand" "=r,r")
1294 (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1295 (match_operator:SI 4 "comparison_operator"
1296 [(match_operand:SI 2 "register_operand" "r,r")
1297 (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1298 ""
1299 "@
1300 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1301 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1302 [(set_attr "type" "binary,binary")
1303 (set_attr "length" "8,12")])
1304
1305 (define_insn ""
1306 [(set (match_operand:DI 0 "register_operand" "=r,r")
1307 (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1308 (match_operator:DI 4 "comparison_operator"
1309 [(match_operand:DI 2 "register_operand" "r,r")
1310 (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1311 "TARGET_64BIT"
1312 "@
1313 cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1314 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1315 [(set_attr "type" "binary,binary")
1316 (set_attr "length" "8,12")])
1317
1318 ; Patterns for max and min. (There is no need for an earlyclobber in the
1319 ; last alternative since the middle alternative will match if op0 == op1.)
1320
1321 (define_insn "sminsi3"
1322 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1323 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1324 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1325 ""
1326 "@
1327 {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1328 {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1329 {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1330 [(set_attr "type" "multi,multi,multi")
1331 (set_attr "length" "8,8,8")])
1332
1333 (define_insn "smindi3"
1334 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1335 (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1336 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1337 "TARGET_64BIT"
1338 "@
1339 cmpclr,*> %2,%0,%%r0\;copy %2,%0
1340 cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1341 cmpclr,*> %1,%r2,%0\;copy %1,%0"
1342 [(set_attr "type" "multi,multi,multi")
1343 (set_attr "length" "8,8,8")])
1344
1345 (define_insn "uminsi3"
1346 [(set (match_operand:SI 0 "register_operand" "=r,r")
1347 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1348 (match_operand:SI 2 "arith11_operand" "r,I")))]
1349 ""
1350 "@
1351 {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1352 {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1353 [(set_attr "type" "multi,multi")
1354 (set_attr "length" "8,8")])
1355
1356 (define_insn "umindi3"
1357 [(set (match_operand:DI 0 "register_operand" "=r,r")
1358 (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1359 (match_operand:DI 2 "arith11_operand" "r,I")))]
1360 "TARGET_64BIT"
1361 "@
1362 cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1363 cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1364 [(set_attr "type" "multi,multi")
1365 (set_attr "length" "8,8")])
1366
1367 (define_insn "smaxsi3"
1368 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1369 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1370 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1371 ""
1372 "@
1373 {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1374 {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1375 {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1376 [(set_attr "type" "multi,multi,multi")
1377 (set_attr "length" "8,8,8")])
1378
1379 (define_insn "smaxdi3"
1380 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1381 (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1382 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1383 "TARGET_64BIT"
1384 "@
1385 cmpclr,*< %2,%0,%%r0\;copy %2,%0
1386 cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1387 cmpclr,*< %1,%r2,%0\;copy %1,%0"
1388 [(set_attr "type" "multi,multi,multi")
1389 (set_attr "length" "8,8,8")])
1390
1391 (define_insn "umaxsi3"
1392 [(set (match_operand:SI 0 "register_operand" "=r,r")
1393 (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1394 (match_operand:SI 2 "arith11_operand" "r,I")))]
1395 ""
1396 "@
1397 {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1398 {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1399 [(set_attr "type" "multi,multi")
1400 (set_attr "length" "8,8")])
1401
1402 (define_insn "umaxdi3"
1403 [(set (match_operand:DI 0 "register_operand" "=r,r")
1404 (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1405 (match_operand:DI 2 "arith11_operand" "r,I")))]
1406 "TARGET_64BIT"
1407 "@
1408 cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1409 cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1410 [(set_attr "type" "multi,multi")
1411 (set_attr "length" "8,8")])
1412
1413 (define_insn "abssi2"
1414 [(set (match_operand:SI 0 "register_operand" "=r")
1415 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1416 ""
1417 "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1418 [(set_attr "type" "multi")
1419 (set_attr "length" "8")])
1420
1421 (define_insn "absdi2"
1422 [(set (match_operand:DI 0 "register_operand" "=r")
1423 (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1424 "TARGET_64BIT"
1425 "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1426 [(set_attr "type" "multi")
1427 (set_attr "length" "8")])
1428
1429 ;;; Experimental conditional move patterns
1430
1431 (define_expand "movsicc"
1432 [(set (match_operand:SI 0 "register_operand" "")
1433 (if_then_else:SI
1434 (match_operand 1 "comparison_operator" "")
1435 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1436 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1437 ""
1438 "
1439 {
1440 if (GET_MODE (XEXP (operands[1], 0)) != SImode
1441 || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1442 FAIL;
1443 }")
1444
1445 ;; We used to accept any register for op1.
1446 ;;
1447 ;; However, it loses sometimes because the compiler will end up using
1448 ;; different registers for op0 and op1 in some critical cases. local-alloc
1449 ;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
1450 ;;
1451 ;; If/when global register allocation supports tying we should allow any
1452 ;; register for op1 again.
1453 (define_insn ""
1454 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1455 (if_then_else:SI
1456 (match_operator 2 "comparison_operator"
1457 [(match_operand:SI 3 "register_operand" "r,r,r,r")
1458 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1459 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1460 (const_int 0)))]
1461 ""
1462 "@
1463 {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1464 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1465 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1466 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1467 [(set_attr "type" "multi,multi,multi,nullshift")
1468 (set_attr "length" "8,8,8,8")])
1469
1470 (define_insn ""
1471 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1472 (if_then_else:SI
1473 (match_operator 5 "comparison_operator"
1474 [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1475 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1476 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1477 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1478 ""
1479 "@
1480 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1481 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1482 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1483 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1484 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1485 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1486 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1487 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1488 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1489 (set_attr "length" "8,8,8,8,8,8,8,8")])
1490
1491 (define_expand "movdicc"
1492 [(set (match_operand:DI 0 "register_operand" "")
1493 (if_then_else:DI
1494 (match_operand 1 "comparison_operator" "")
1495 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1496 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1497 "TARGET_64BIT"
1498 "
1499 {
1500 if (GET_MODE (XEXP (operands[1], 0)) != DImode
1501 || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1502 FAIL;
1503 }")
1504
1505 ; We need the first constraint alternative in order to avoid
1506 ; earlyclobbers on all other alternatives.
1507 (define_insn ""
1508 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1509 (if_then_else:DI
1510 (match_operator 2 "comparison_operator"
1511 [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1512 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1513 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1514 (const_int 0)))]
1515 "TARGET_64BIT"
1516 "@
1517 cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1518 cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1519 cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1520 cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1521 cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1522 [(set_attr "type" "multi,multi,multi,multi,nullshift")
1523 (set_attr "length" "8,8,8,8,8")])
1524
1525 (define_insn ""
1526 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1527 (if_then_else:DI
1528 (match_operator 5 "comparison_operator"
1529 [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1530 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1531 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1532 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1533 "TARGET_64BIT"
1534 "@
1535 cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1536 cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1537 cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1538 cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1539 cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1540 cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1541 cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1542 cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1543 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1544 (set_attr "length" "8,8,8,8,8,8,8,8")])
1545
1546 ;; Conditional Branches
1547
1548 (define_expand "cbranchdi4"
1549 [(set (pc)
1550 (if_then_else (match_operator 0 "ordered_comparison_operator"
1551 [(match_operand:DI 1 "reg_or_0_operand" "")
1552 (match_operand:DI 2 "register_operand" "")])
1553 (label_ref (match_operand 3 "" ""))
1554 (pc)))]
1555 "TARGET_64BIT"
1556 "")
1557
1558 (define_expand "cbranchsi4"
1559 [(set (pc)
1560 (if_then_else (match_operator 0 "ordered_comparison_operator"
1561 [(match_operand:SI 1 "reg_or_0_operand" "")
1562 (match_operand:SI 2 "arith5_operand" "")])
1563 (label_ref (match_operand 3 "" ""))
1564 (pc)))]
1565 ""
1566 "")
1567
1568 (define_expand "cbranchsf4"
1569 [(set (pc)
1570 (if_then_else (match_operator 0 "comparison_operator"
1571 [(match_operand:SF 1 "reg_or_0_operand" "")
1572 (match_operand:SF 2 "reg_or_0_operand" "")])
1573 (label_ref (match_operand 3 "" ""))
1574 (pc)))]
1575 ""
1576 "
1577 {
1578 pa_emit_bcond_fp (operands);
1579 DONE;
1580 }")
1581
1582
1583 (define_expand "cbranchdf4"
1584 [(set (pc)
1585 (if_then_else (match_operator 0 "comparison_operator"
1586 [(match_operand:DF 1 "reg_or_0_operand" "")
1587 (match_operand:DF 2 "reg_or_0_operand" "")])
1588 (label_ref (match_operand 3 "" ""))
1589 (pc)))]
1590 ""
1591 "
1592 {
1593 pa_emit_bcond_fp (operands);
1594 DONE;
1595 }")
1596
1597 ;; Match the branch patterns.
1598
1599
1600 ;; Note a long backward conditional branch with an annulled delay slot
1601 ;; has a length of 12.
1602 (define_insn ""
1603 [(set (pc)
1604 (if_then_else
1605 (match_operator 3 "comparison_operator"
1606 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1607 (match_operand:SI 2 "arith5_operand" "rL")])
1608 (label_ref (match_operand 0 "" ""))
1609 (pc)))]
1610 ""
1611 "*
1612 {
1613 return pa_output_cbranch (operands, 0, insn);
1614 }"
1615 [(set_attr "type" "cbranch")
1616 (set (attr "length")
1617 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1618 (const_int MAX_12BIT_OFFSET))
1619 (const_int 4)
1620 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1621 (const_int MAX_17BIT_OFFSET))
1622 (const_int 8)
1623 (match_test "TARGET_PORTABLE_RUNTIME")
1624 (const_int 24)
1625 (not (match_test "flag_pic"))
1626 (const_int 20)]
1627 (const_int 28)))])
1628
1629 ;; Match the negated branch.
1630
1631 (define_insn ""
1632 [(set (pc)
1633 (if_then_else
1634 (match_operator 3 "comparison_operator"
1635 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1636 (match_operand:SI 2 "arith5_operand" "rL")])
1637 (pc)
1638 (label_ref (match_operand 0 "" ""))))]
1639 ""
1640 "*
1641 {
1642 return pa_output_cbranch (operands, 1, insn);
1643 }"
1644 [(set_attr "type" "cbranch")
1645 (set (attr "length")
1646 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1647 (const_int MAX_12BIT_OFFSET))
1648 (const_int 4)
1649 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1650 (const_int MAX_17BIT_OFFSET))
1651 (const_int 8)
1652 (match_test "TARGET_PORTABLE_RUNTIME")
1653 (const_int 24)
1654 (not (match_test "flag_pic"))
1655 (const_int 20)]
1656 (const_int 28)))])
1657
1658 (define_insn ""
1659 [(set (pc)
1660 (if_then_else
1661 (match_operator 3 "comparison_operator"
1662 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1663 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1664 (label_ref (match_operand 0 "" ""))
1665 (pc)))]
1666 "TARGET_64BIT"
1667 "*
1668 {
1669 return pa_output_cbranch (operands, 0, insn);
1670 }"
1671 [(set_attr "type" "cbranch")
1672 (set (attr "length")
1673 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1674 (const_int MAX_12BIT_OFFSET))
1675 (const_int 4)
1676 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1677 (const_int MAX_17BIT_OFFSET))
1678 (const_int 8)
1679 (match_test "TARGET_PORTABLE_RUNTIME")
1680 (const_int 24)
1681 (not (match_test "flag_pic"))
1682 (const_int 20)]
1683 (const_int 28)))])
1684
1685 ;; Match the negated branch.
1686
1687 (define_insn ""
1688 [(set (pc)
1689 (if_then_else
1690 (match_operator 3 "comparison_operator"
1691 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1692 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1693 (pc)
1694 (label_ref (match_operand 0 "" ""))))]
1695 "TARGET_64BIT"
1696 "*
1697 {
1698 return pa_output_cbranch (operands, 1, insn);
1699 }"
1700 [(set_attr "type" "cbranch")
1701 (set (attr "length")
1702 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1703 (const_int MAX_12BIT_OFFSET))
1704 (const_int 4)
1705 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1706 (const_int MAX_17BIT_OFFSET))
1707 (const_int 8)
1708 (match_test "TARGET_PORTABLE_RUNTIME")
1709 (const_int 24)
1710 (not (match_test "flag_pic"))
1711 (const_int 20)]
1712 (const_int 28)))])
1713 (define_insn ""
1714 [(set (pc)
1715 (if_then_else
1716 (match_operator 3 "cmpib_comparison_operator"
1717 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1718 (match_operand:DI 2 "arith5_operand" "rL")])
1719 (label_ref (match_operand 0 "" ""))
1720 (pc)))]
1721 "TARGET_64BIT"
1722 "*
1723 {
1724 return pa_output_cbranch (operands, 0, insn);
1725 }"
1726 [(set_attr "type" "cbranch")
1727 (set (attr "length")
1728 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1729 (const_int MAX_12BIT_OFFSET))
1730 (const_int 4)
1731 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1732 (const_int MAX_17BIT_OFFSET))
1733 (const_int 8)
1734 (match_test "TARGET_PORTABLE_RUNTIME")
1735 (const_int 24)
1736 (not (match_test "flag_pic"))
1737 (const_int 20)]
1738 (const_int 28)))])
1739
1740 ;; Match the negated branch.
1741
1742 (define_insn ""
1743 [(set (pc)
1744 (if_then_else
1745 (match_operator 3 "cmpib_comparison_operator"
1746 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1747 (match_operand:DI 2 "arith5_operand" "rL")])
1748 (pc)
1749 (label_ref (match_operand 0 "" ""))))]
1750 "TARGET_64BIT"
1751 "*
1752 {
1753 return pa_output_cbranch (operands, 1, insn);
1754 }"
1755 [(set_attr "type" "cbranch")
1756 (set (attr "length")
1757 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1758 (const_int MAX_12BIT_OFFSET))
1759 (const_int 4)
1760 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1761 (const_int MAX_17BIT_OFFSET))
1762 (const_int 8)
1763 (match_test "TARGET_PORTABLE_RUNTIME")
1764 (const_int 24)
1765 (not (match_test "flag_pic"))
1766 (const_int 20)]
1767 (const_int 28)))])
1768
1769 ;; Branch on Bit patterns.
1770 (define_insn ""
1771 [(set (pc)
1772 (if_then_else
1773 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1774 (const_int 1)
1775 (match_operand:SI 1 "uint5_operand" ""))
1776 (const_int 0))
1777 (label_ref (match_operand 2 "" ""))
1778 (pc)))]
1779 ""
1780 "*
1781 {
1782 return pa_output_bb (operands, 0, insn, 0);
1783 }"
1784 [(set_attr "type" "cbranch")
1785 (set (attr "length")
1786 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1787 (const_int MAX_12BIT_OFFSET))
1788 (const_int 4)
1789 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1790 (const_int MAX_17BIT_OFFSET))
1791 (const_int 8)
1792 (match_test "TARGET_PORTABLE_RUNTIME")
1793 (const_int 24)
1794 (not (match_test "flag_pic"))
1795 (const_int 20)]
1796 (const_int 28)))])
1797
1798 (define_insn ""
1799 [(set (pc)
1800 (if_then_else
1801 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1802 (const_int 1)
1803 (match_operand:DI 1 "uint32_operand" ""))
1804 (const_int 0))
1805 (label_ref (match_operand 2 "" ""))
1806 (pc)))]
1807 "TARGET_64BIT"
1808 "*
1809 {
1810 return pa_output_bb (operands, 0, insn, 0);
1811 }"
1812 [(set_attr "type" "cbranch")
1813 (set (attr "length")
1814 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1815 (const_int MAX_12BIT_OFFSET))
1816 (const_int 4)
1817 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1818 (const_int MAX_17BIT_OFFSET))
1819 (const_int 8)
1820 (match_test "TARGET_PORTABLE_RUNTIME")
1821 (const_int 24)
1822 (not (match_test "flag_pic"))
1823 (const_int 20)]
1824 (const_int 28)))])
1825
1826 (define_insn ""
1827 [(set (pc)
1828 (if_then_else
1829 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1830 (const_int 1)
1831 (match_operand:SI 1 "uint5_operand" ""))
1832 (const_int 0))
1833 (pc)
1834 (label_ref (match_operand 2 "" ""))))]
1835 ""
1836 "*
1837 {
1838 return pa_output_bb (operands, 1, insn, 0);
1839 }"
1840 [(set_attr "type" "cbranch")
1841 (set (attr "length")
1842 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1843 (const_int MAX_12BIT_OFFSET))
1844 (const_int 4)
1845 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1846 (const_int MAX_17BIT_OFFSET))
1847 (const_int 8)
1848 (match_test "TARGET_PORTABLE_RUNTIME")
1849 (const_int 24)
1850 (not (match_test "flag_pic"))
1851 (const_int 20)]
1852 (const_int 28)))])
1853
1854 (define_insn ""
1855 [(set (pc)
1856 (if_then_else
1857 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1858 (const_int 1)
1859 (match_operand:DI 1 "uint32_operand" ""))
1860 (const_int 0))
1861 (pc)
1862 (label_ref (match_operand 2 "" ""))))]
1863 "TARGET_64BIT"
1864 "*
1865 {
1866 return pa_output_bb (operands, 1, insn, 0);
1867 }"
1868 [(set_attr "type" "cbranch")
1869 (set (attr "length")
1870 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1871 (const_int MAX_12BIT_OFFSET))
1872 (const_int 4)
1873 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1874 (const_int MAX_17BIT_OFFSET))
1875 (const_int 8)
1876 (match_test "TARGET_PORTABLE_RUNTIME")
1877 (const_int 24)
1878 (not (match_test "flag_pic"))
1879 (const_int 20)]
1880 (const_int 28)))])
1881
1882 (define_insn ""
1883 [(set (pc)
1884 (if_then_else
1885 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1886 (const_int 1)
1887 (match_operand:SI 1 "uint5_operand" ""))
1888 (const_int 0))
1889 (label_ref (match_operand 2 "" ""))
1890 (pc)))]
1891 ""
1892 "*
1893 {
1894 return pa_output_bb (operands, 0, insn, 1);
1895 }"
1896 [(set_attr "type" "cbranch")
1897 (set (attr "length")
1898 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1899 (const_int MAX_12BIT_OFFSET))
1900 (const_int 4)
1901 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1902 (const_int MAX_17BIT_OFFSET))
1903 (const_int 8)
1904 (match_test "TARGET_PORTABLE_RUNTIME")
1905 (const_int 24)
1906 (not (match_test "flag_pic"))
1907 (const_int 20)]
1908 (const_int 28)))])
1909
1910 (define_insn ""
1911 [(set (pc)
1912 (if_then_else
1913 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1914 (const_int 1)
1915 (match_operand:DI 1 "uint32_operand" ""))
1916 (const_int 0))
1917 (label_ref (match_operand 2 "" ""))
1918 (pc)))]
1919 "TARGET_64BIT"
1920 "*
1921 {
1922 return pa_output_bb (operands, 0, insn, 1);
1923 }"
1924 [(set_attr "type" "cbranch")
1925 (set (attr "length")
1926 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1927 (const_int MAX_12BIT_OFFSET))
1928 (const_int 4)
1929 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1930 (const_int MAX_17BIT_OFFSET))
1931 (const_int 8)
1932 (match_test "TARGET_PORTABLE_RUNTIME")
1933 (const_int 24)
1934 (not (match_test "flag_pic"))
1935 (const_int 20)]
1936 (const_int 28)))])
1937
1938 (define_insn ""
1939 [(set (pc)
1940 (if_then_else
1941 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1942 (const_int 1)
1943 (match_operand:SI 1 "uint5_operand" ""))
1944 (const_int 0))
1945 (pc)
1946 (label_ref (match_operand 2 "" ""))))]
1947 ""
1948 "*
1949 {
1950 return pa_output_bb (operands, 1, insn, 1);
1951 }"
1952 [(set_attr "type" "cbranch")
1953 (set (attr "length")
1954 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1955 (const_int MAX_12BIT_OFFSET))
1956 (const_int 4)
1957 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1958 (const_int MAX_17BIT_OFFSET))
1959 (const_int 8)
1960 (match_test "TARGET_PORTABLE_RUNTIME")
1961 (const_int 24)
1962 (not (match_test "flag_pic"))
1963 (const_int 20)]
1964 (const_int 28)))])
1965
1966 (define_insn ""
1967 [(set (pc)
1968 (if_then_else
1969 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1970 (const_int 1)
1971 (match_operand:DI 1 "uint32_operand" ""))
1972 (const_int 0))
1973 (pc)
1974 (label_ref (match_operand 2 "" ""))))]
1975 "TARGET_64BIT"
1976 "*
1977 {
1978 return pa_output_bb (operands, 1, insn, 1);
1979 }"
1980 [(set_attr "type" "cbranch")
1981 (set (attr "length")
1982 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1983 (const_int MAX_12BIT_OFFSET))
1984 (const_int 4)
1985 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1986 (const_int MAX_17BIT_OFFSET))
1987 (const_int 8)
1988 (match_test "TARGET_PORTABLE_RUNTIME")
1989 (const_int 24)
1990 (not (match_test "flag_pic"))
1991 (const_int 20)]
1992 (const_int 28)))])
1993
1994 ;; Branch on Variable Bit patterns.
1995 (define_insn ""
1996 [(set (pc)
1997 (if_then_else
1998 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1999 (const_int 1)
2000 (match_operand:SI 1 "register_operand" "q"))
2001 (const_int 0))
2002 (label_ref (match_operand 2 "" ""))
2003 (pc)))]
2004 ""
2005 "*
2006 {
2007 return pa_output_bvb (operands, 0, insn, 0);
2008 }"
2009 [(set_attr "type" "cbranch")
2010 (set (attr "length")
2011 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2012 (const_int MAX_12BIT_OFFSET))
2013 (const_int 4)
2014 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2015 (const_int MAX_17BIT_OFFSET))
2016 (const_int 8)
2017 (match_test "TARGET_PORTABLE_RUNTIME")
2018 (const_int 24)
2019 (not (match_test "flag_pic"))
2020 (const_int 20)]
2021 (const_int 28)))])
2022
2023 (define_insn ""
2024 [(set (pc)
2025 (if_then_else
2026 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2027 (const_int 1)
2028 (match_operand:DI 1 "register_operand" "q"))
2029 (const_int 0))
2030 (label_ref (match_operand 2 "" ""))
2031 (pc)))]
2032 "TARGET_64BIT"
2033 "*
2034 {
2035 return pa_output_bvb (operands, 0, insn, 0);
2036 }"
2037 [(set_attr "type" "cbranch")
2038 (set (attr "length")
2039 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2040 (const_int MAX_12BIT_OFFSET))
2041 (const_int 4)
2042 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2043 (const_int MAX_17BIT_OFFSET))
2044 (const_int 8)
2045 (match_test "TARGET_PORTABLE_RUNTIME")
2046 (const_int 24)
2047 (not (match_test "flag_pic"))
2048 (const_int 20)]
2049 (const_int 28)))])
2050
2051 (define_insn ""
2052 [(set (pc)
2053 (if_then_else
2054 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2055 (const_int 1)
2056 (match_operand:SI 1 "register_operand" "q"))
2057 (const_int 0))
2058 (pc)
2059 (label_ref (match_operand 2 "" ""))))]
2060 ""
2061 "*
2062 {
2063 return pa_output_bvb (operands, 1, insn, 0);
2064 }"
2065 [(set_attr "type" "cbranch")
2066 (set (attr "length")
2067 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2068 (const_int MAX_12BIT_OFFSET))
2069 (const_int 4)
2070 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2071 (const_int MAX_17BIT_OFFSET))
2072 (const_int 8)
2073 (match_test "TARGET_PORTABLE_RUNTIME")
2074 (const_int 24)
2075 (not (match_test "flag_pic"))
2076 (const_int 20)]
2077 (const_int 28)))])
2078
2079 (define_insn ""
2080 [(set (pc)
2081 (if_then_else
2082 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2083 (const_int 1)
2084 (match_operand:DI 1 "register_operand" "q"))
2085 (const_int 0))
2086 (pc)
2087 (label_ref (match_operand 2 "" ""))))]
2088 "TARGET_64BIT"
2089 "*
2090 {
2091 return pa_output_bvb (operands, 1, insn, 0);
2092 }"
2093 [(set_attr "type" "cbranch")
2094 (set (attr "length")
2095 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2096 (const_int MAX_12BIT_OFFSET))
2097 (const_int 4)
2098 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2099 (const_int MAX_17BIT_OFFSET))
2100 (const_int 8)
2101 (match_test "TARGET_PORTABLE_RUNTIME")
2102 (const_int 24)
2103 (not (match_test "flag_pic"))
2104 (const_int 20)]
2105 (const_int 28)))])
2106
2107 (define_insn ""
2108 [(set (pc)
2109 (if_then_else
2110 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2111 (const_int 1)
2112 (match_operand:SI 1 "register_operand" "q"))
2113 (const_int 0))
2114 (label_ref (match_operand 2 "" ""))
2115 (pc)))]
2116 ""
2117 "*
2118 {
2119 return pa_output_bvb (operands, 0, insn, 1);
2120 }"
2121 [(set_attr "type" "cbranch")
2122 (set (attr "length")
2123 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2124 (const_int MAX_12BIT_OFFSET))
2125 (const_int 4)
2126 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2127 (const_int MAX_17BIT_OFFSET))
2128 (const_int 8)
2129 (match_test "TARGET_PORTABLE_RUNTIME")
2130 (const_int 24)
2131 (not (match_test "flag_pic"))
2132 (const_int 20)]
2133 (const_int 28)))])
2134
2135 (define_insn ""
2136 [(set (pc)
2137 (if_then_else
2138 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2139 (const_int 1)
2140 (match_operand:DI 1 "register_operand" "q"))
2141 (const_int 0))
2142 (label_ref (match_operand 2 "" ""))
2143 (pc)))]
2144 "TARGET_64BIT"
2145 "*
2146 {
2147 return pa_output_bvb (operands, 0, insn, 1);
2148 }"
2149 [(set_attr "type" "cbranch")
2150 (set (attr "length")
2151 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2152 (const_int MAX_12BIT_OFFSET))
2153 (const_int 4)
2154 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2155 (const_int MAX_17BIT_OFFSET))
2156 (const_int 8)
2157 (match_test "TARGET_PORTABLE_RUNTIME")
2158 (const_int 24)
2159 (not (match_test "flag_pic"))
2160 (const_int 20)]
2161 (const_int 28)))])
2162
2163 (define_insn ""
2164 [(set (pc)
2165 (if_then_else
2166 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2167 (const_int 1)
2168 (match_operand:SI 1 "register_operand" "q"))
2169 (const_int 0))
2170 (pc)
2171 (label_ref (match_operand 2 "" ""))))]
2172 ""
2173 "*
2174 {
2175 return pa_output_bvb (operands, 1, insn, 1);
2176 }"
2177 [(set_attr "type" "cbranch")
2178 (set (attr "length")
2179 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2180 (const_int MAX_12BIT_OFFSET))
2181 (const_int 4)
2182 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2183 (const_int MAX_17BIT_OFFSET))
2184 (const_int 8)
2185 (match_test "TARGET_PORTABLE_RUNTIME")
2186 (const_int 24)
2187 (not (match_test "flag_pic"))
2188 (const_int 20)]
2189 (const_int 28)))])
2190
2191 (define_insn ""
2192 [(set (pc)
2193 (if_then_else
2194 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2195 (const_int 1)
2196 (match_operand:DI 1 "register_operand" "q"))
2197 (const_int 0))
2198 (pc)
2199 (label_ref (match_operand 2 "" ""))))]
2200 "TARGET_64BIT"
2201 "*
2202 {
2203 return pa_output_bvb (operands, 1, insn, 1);
2204 }"
2205 [(set_attr "type" "cbranch")
2206 (set (attr "length")
2207 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2208 (const_int MAX_12BIT_OFFSET))
2209 (const_int 4)
2210 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2211 (const_int MAX_17BIT_OFFSET))
2212 (const_int 8)
2213 (match_test "TARGET_PORTABLE_RUNTIME")
2214 (const_int 24)
2215 (not (match_test "flag_pic"))
2216 (const_int 20)]
2217 (const_int 28)))])
2218
2219 ;; Floating point branches
2220
2221 ;; ??? Nullification is handled differently from other branches.
2222 ;; If nullification is specified, the delay slot is nullified on any
2223 ;; taken branch regardless of branch direction.
2224 (define_insn ""
2225 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2226 (label_ref (match_operand 0 "" ""))
2227 (pc)))]
2228 "!TARGET_SOFT_FLOAT"
2229 "*
2230 {
2231 int length = get_attr_length (insn);
2232 rtx xoperands[1];
2233 int nullify, xdelay;
2234
2235 if (length < 16)
2236 return \"ftest\;b%* %l0\";
2237
2238 if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2239 {
2240 nullify = 1;
2241 xdelay = 0;
2242 xoperands[0] = GEN_INT (length - 8);
2243 }
2244 else
2245 {
2246 nullify = 0;
2247 xdelay = 1;
2248 xoperands[0] = GEN_INT (length - 4);
2249 }
2250
2251 if (nullify)
2252 output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2253 else
2254 output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2255 return pa_output_lbranch (operands[0], insn, xdelay);
2256 }"
2257 [(set_attr "type" "fbranch")
2258 (set (attr "length")
2259 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2260 (const_int MAX_17BIT_OFFSET))
2261 (const_int 8)
2262 (match_test "TARGET_PORTABLE_RUNTIME")
2263 (const_int 32)
2264 (not (match_test "flag_pic"))
2265 (const_int 28)]
2266 (const_int 36)))])
2267
2268 (define_insn ""
2269 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2270 (pc)
2271 (label_ref (match_operand 0 "" ""))))]
2272 "!TARGET_SOFT_FLOAT"
2273 "*
2274 {
2275 int length = get_attr_length (insn);
2276 rtx xoperands[1];
2277 int nullify, xdelay;
2278
2279 if (length < 16)
2280 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2281
2282 if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2283 {
2284 nullify = 1;
2285 xdelay = 0;
2286 xoperands[0] = GEN_INT (length - 4);
2287 }
2288 else
2289 {
2290 nullify = 0;
2291 xdelay = 1;
2292 xoperands[0] = GEN_INT (length);
2293 }
2294
2295 if (nullify)
2296 output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2297 else
2298 output_asm_insn (\"ftest\;b .+%0\", xoperands);
2299 return pa_output_lbranch (operands[0], insn, xdelay);
2300 }"
2301 [(set_attr "type" "fbranch")
2302 (set (attr "length")
2303 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2304 (const_int MAX_17BIT_OFFSET))
2305 (const_int 12)
2306 (match_test "TARGET_PORTABLE_RUNTIME")
2307 (const_int 28)
2308 (not (match_test "flag_pic"))
2309 (const_int 24)]
2310 (const_int 32)))])
2311
2312 ;; Move instructions
2313
2314 (define_expand "movsi"
2315 [(set (match_operand:SI 0 "general_operand" "")
2316 (match_operand:SI 1 "general_operand" ""))]
2317 ""
2318 "
2319 {
2320 if (pa_emit_move_sequence (operands, SImode, 0))
2321 DONE;
2322 }")
2323
2324 ;; Handle SImode input reloads requiring %r1 as a scratch register.
2325 (define_expand "reload_insi_r1"
2326 [(set (match_operand:SI 0 "register_operand" "=Z")
2327 (match_operand:SI 1 "non_hard_reg_operand" ""))
2328 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2329 ""
2330 "
2331 {
2332 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2333 DONE;
2334
2335 /* We don't want the clobber emitted, so handle this ourselves. */
2336 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2337 DONE;
2338 }")
2339
2340 ;; Handle SImode input reloads requiring a general register as a
2341 ;; scratch register.
2342 (define_expand "reload_insi"
2343 [(set (match_operand:SI 0 "register_operand" "=Z")
2344 (match_operand:SI 1 "non_hard_reg_operand" ""))
2345 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2346 ""
2347 "
2348 {
2349 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2350 DONE;
2351
2352 /* We don't want the clobber emitted, so handle this ourselves. */
2353 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2354 DONE;
2355 }")
2356
2357 ;; Handle SImode output reloads requiring a general register as a
2358 ;; scratch register.
2359 (define_expand "reload_outsi"
2360 [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2361 (match_operand:SI 1 "register_operand" "Z"))
2362 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2363 ""
2364 "
2365 {
2366 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2367 DONE;
2368
2369 /* We don't want the clobber emitted, so handle this ourselves. */
2370 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2371 DONE;
2372 }")
2373
2374 (define_insn ""
2375 [(set (match_operand:SI 0 "move_dest_operand"
2376 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2377 (match_operand:SI 1 "move_src_operand"
2378 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2379 "(register_operand (operands[0], SImode)
2380 || reg_or_0_operand (operands[1], SImode))
2381 && !TARGET_SOFT_FLOAT
2382 && !TARGET_64BIT"
2383 "@
2384 ldw RT'%A1,%0
2385 copy %1,%0
2386 ldi %1,%0
2387 ldil L'%1,%0
2388 {zdepi|depwi,z} %Z1,%0
2389 ldw%M1 %1,%0
2390 stw%M0 %r1,%0
2391 mtsar %r1
2392 {mfctl|mfctl,w} %%sar,%0
2393 fcpy,sgl %f1,%0
2394 fldw%F1 %1,%0
2395 fstw%F0 %1,%0
2396 {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2397 {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2398 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2399 (set_attr "pa_combine_type" "addmove")
2400 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2401
2402 (define_insn ""
2403 [(set (match_operand:SI 0 "move_dest_operand"
2404 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2405 (match_operand:SI 1 "move_src_operand"
2406 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2407 "(register_operand (operands[0], SImode)
2408 || reg_or_0_operand (operands[1], SImode))
2409 && !TARGET_SOFT_FLOAT
2410 && TARGET_64BIT"
2411 "@
2412 ldw RT'%A1,%0
2413 copy %1,%0
2414 ldi %1,%0
2415 ldil L'%1,%0
2416 {zdepi|depwi,z} %Z1,%0
2417 ldw%M1 %1,%0
2418 stw%M0 %r1,%0
2419 mtsar %r1
2420 {mfctl|mfctl,w} %%sar,%0
2421 fcpy,sgl %f1,%0
2422 fldw%F1 %1,%0
2423 fstw%F0 %1,%0"
2424 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2425 (set_attr "pa_combine_type" "addmove")
2426 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2427
2428 (define_insn ""
2429 [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2430 (match_operand:SI 1 "register_operand" "f"))]
2431 "!TARGET_SOFT_FLOAT
2432 && !TARGET_DISABLE_INDEXING
2433 && reload_completed"
2434 "fstw%F0 %1,%0"
2435 [(set_attr "type" "fpstore")
2436 (set_attr "pa_combine_type" "addmove")
2437 (set_attr "length" "4")])
2438
2439 ; Rewrite RTL using an indexed store. This will allow the insn that
2440 ; computes the address to be deleted if the register it sets is dead.
2441 (define_peephole2
2442 [(set (match_operand:SI 0 "register_operand" "")
2443 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2444 (const_int 2))
2445 (match_operand:SI 2 "register_operand" "")))
2446 (set (mem:SI (match_dup 0))
2447 (match_operand:SI 3 "register_operand" ""))]
2448 "!TARGET_SOFT_FLOAT
2449 && !TARGET_DISABLE_INDEXING
2450 && REG_OK_FOR_BASE_P (operands[2])
2451 && FP_REGNO_P (REGNO (operands[3]))"
2452 [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2453 (match_dup 3))
2454 (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2455 (match_dup 2)))]
2456 "")
2457
2458 (define_peephole2
2459 [(set (match_operand:DI 0 "register_operand" "")
2460 (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2461 (const_int 2))
2462 (match_operand:DI 2 "register_operand" "")))
2463 (set (mem:SI (match_dup 0))
2464 (match_operand:SI 3 "register_operand" ""))]
2465 "!TARGET_SOFT_FLOAT
2466 && !TARGET_DISABLE_INDEXING
2467 && TARGET_64BIT
2468 && REG_OK_FOR_BASE_P (operands[2])
2469 && FP_REGNO_P (REGNO (operands[3]))"
2470 [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2471 (match_dup 3))
2472 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2473 (match_dup 2)))]
2474 "")
2475
2476 (define_peephole2
2477 [(set (match_operand:SI 0 "register_operand" "")
2478 (plus:SI (match_operand:SI 1 "register_operand" "")
2479 (match_operand:SI 2 "register_operand" "")))
2480 (set (mem:SI (match_dup 0))
2481 (match_operand:SI 3 "register_operand" ""))]
2482 "!TARGET_SOFT_FLOAT
2483 && !TARGET_DISABLE_INDEXING
2484 && TARGET_NO_SPACE_REGS
2485 && REG_OK_FOR_INDEX_P (operands[1])
2486 && REG_OK_FOR_BASE_P (operands[2])
2487 && FP_REGNO_P (REGNO (operands[3]))"
2488 [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2489 (match_dup 3))
2490 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2491 "")
2492
2493 (define_peephole2
2494 [(set (match_operand:SI 0 "register_operand" "")
2495 (plus:SI (match_operand:SI 1 "register_operand" "")
2496 (match_operand:SI 2 "register_operand" "")))
2497 (set (mem:SI (match_dup 0))
2498 (match_operand:SI 3 "register_operand" ""))]
2499 "!TARGET_SOFT_FLOAT
2500 && !TARGET_DISABLE_INDEXING
2501 && TARGET_NO_SPACE_REGS
2502 && REG_OK_FOR_BASE_P (operands[1])
2503 && REG_OK_FOR_INDEX_P (operands[2])
2504 && FP_REGNO_P (REGNO (operands[3]))"
2505 [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2506 (match_dup 3))
2507 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2508 "")
2509
2510 (define_peephole2
2511 [(set (match_operand:DI 0 "register_operand" "")
2512 (plus:DI (match_operand:DI 1 "register_operand" "")
2513 (match_operand:DI 2 "register_operand" "")))
2514 (set (mem:SI (match_dup 0))
2515 (match_operand:SI 3 "register_operand" ""))]
2516 "!TARGET_SOFT_FLOAT
2517 && !TARGET_DISABLE_INDEXING
2518 && TARGET_64BIT
2519 && TARGET_NO_SPACE_REGS
2520 && REG_OK_FOR_INDEX_P (operands[1])
2521 && REG_OK_FOR_BASE_P (operands[2])
2522 && FP_REGNO_P (REGNO (operands[3]))"
2523 [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2524 (match_dup 3))
2525 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2526 "")
2527
2528 (define_peephole2
2529 [(set (match_operand:DI 0 "register_operand" "")
2530 (plus:DI (match_operand:DI 1 "register_operand" "")
2531 (match_operand:DI 2 "register_operand" "")))
2532 (set (mem:SI (match_dup 0))
2533 (match_operand:SI 3 "register_operand" ""))]
2534 "!TARGET_SOFT_FLOAT
2535 && !TARGET_DISABLE_INDEXING
2536 && TARGET_64BIT
2537 && TARGET_NO_SPACE_REGS
2538 && REG_OK_FOR_BASE_P (operands[1])
2539 && REG_OK_FOR_INDEX_P (operands[2])
2540 && FP_REGNO_P (REGNO (operands[3]))"
2541 [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2542 (match_dup 3))
2543 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2544 "")
2545
2546 (define_insn ""
2547 [(set (match_operand:SI 0 "move_dest_operand"
2548 "=r,r,r,r,r,r,Q,!*q,!r")
2549 (match_operand:SI 1 "move_src_operand"
2550 "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2551 "(register_operand (operands[0], SImode)
2552 || reg_or_0_operand (operands[1], SImode))
2553 && TARGET_SOFT_FLOAT"
2554 "@
2555 ldw RT'%A1,%0
2556 copy %1,%0
2557 ldi %1,%0
2558 ldil L'%1,%0
2559 {zdepi|depwi,z} %Z1,%0
2560 ldw%M1 %1,%0
2561 stw%M0 %r1,%0
2562 mtsar %r1
2563 {mfctl|mfctl,w} %%sar,%0"
2564 [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2565 (set_attr "pa_combine_type" "addmove")
2566 (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2567
2568 ;; Load or store with base-register modification.
2569 (define_insn ""
2570 [(set (match_operand:SI 0 "register_operand" "=r")
2571 (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2572 (match_operand:DI 2 "int5_operand" "L"))))
2573 (set (match_dup 1)
2574 (plus:DI (match_dup 1) (match_dup 2)))]
2575 "TARGET_64BIT"
2576 "ldw,mb %2(%1),%0"
2577 [(set_attr "type" "load")
2578 (set_attr "length" "4")])
2579
2580 ; And a zero extended variant.
2581 (define_insn ""
2582 [(set (match_operand:DI 0 "register_operand" "=r")
2583 (zero_extend:DI (mem:SI
2584 (plus:DI
2585 (match_operand:DI 1 "register_operand" "+r")
2586 (match_operand:DI 2 "int5_operand" "L")))))
2587 (set (match_dup 1)
2588 (plus:DI (match_dup 1) (match_dup 2)))]
2589 "TARGET_64BIT"
2590 "ldw,mb %2(%1),%0"
2591 [(set_attr "type" "load")
2592 (set_attr "length" "4")])
2593
2594 (define_expand "pre_load"
2595 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2596 (mem (plus (match_operand 1 "register_operand" "")
2597 (match_operand 2 "pre_cint_operand" ""))))
2598 (set (match_dup 1)
2599 (plus (match_dup 1) (match_dup 2)))])]
2600 ""
2601 "
2602 {
2603 if (TARGET_64BIT)
2604 {
2605 emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2606 DONE;
2607 }
2608 emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2609 DONE;
2610 }")
2611
2612 (define_insn "pre_ldw"
2613 [(set (match_operand:SI 0 "register_operand" "=r")
2614 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2615 (match_operand:SI 2 "pre_cint_operand" ""))))
2616 (set (match_dup 1)
2617 (plus:SI (match_dup 1) (match_dup 2)))]
2618 ""
2619 "*
2620 {
2621 if (INTVAL (operands[2]) < 0)
2622 return \"{ldwm|ldw,mb} %2(%1),%0\";
2623 return \"{ldws|ldw},mb %2(%1),%0\";
2624 }"
2625 [(set_attr "type" "load")
2626 (set_attr "length" "4")])
2627
2628 (define_insn "pre_ldd"
2629 [(set (match_operand:DI 0 "register_operand" "=r")
2630 (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2631 (match_operand:DI 2 "pre_cint_operand" ""))))
2632 (set (match_dup 1)
2633 (plus:DI (match_dup 1) (match_dup 2)))]
2634 "TARGET_64BIT"
2635 "ldd,mb %2(%1),%0"
2636 [(set_attr "type" "load")
2637 (set_attr "length" "4")])
2638
2639 (define_insn ""
2640 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2641 (match_operand:SI 1 "pre_cint_operand" "")))
2642 (match_operand:SI 2 "reg_or_0_operand" "rM"))
2643 (set (match_dup 0)
2644 (plus:SI (match_dup 0) (match_dup 1)))]
2645 ""
2646 "*
2647 {
2648 if (INTVAL (operands[1]) < 0)
2649 return \"{stwm|stw,mb} %r2,%1(%0)\";
2650 return \"{stws|stw},mb %r2,%1(%0)\";
2651 }"
2652 [(set_attr "type" "store")
2653 (set_attr "length" "4")])
2654
2655 (define_insn ""
2656 [(set (match_operand:SI 0 "register_operand" "=r")
2657 (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2658 (set (match_dup 1)
2659 (plus:SI (match_dup 1)
2660 (match_operand:SI 2 "post_cint_operand" "")))]
2661 ""
2662 "*
2663 {
2664 if (INTVAL (operands[2]) > 0)
2665 return \"{ldwm|ldw,ma} %2(%1),%0\";
2666 return \"{ldws|ldw},ma %2(%1),%0\";
2667 }"
2668 [(set_attr "type" "load")
2669 (set_attr "length" "4")])
2670
2671 (define_expand "post_store"
2672 [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2673 (match_operand 1 "reg_or_0_operand" ""))
2674 (set (match_dup 0)
2675 (plus (match_dup 0)
2676 (match_operand 2 "post_cint_operand" "")))])]
2677 ""
2678 "
2679 {
2680 if (TARGET_64BIT)
2681 {
2682 emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2683 DONE;
2684 }
2685 emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2686 DONE;
2687 }")
2688
2689 (define_insn "post_stw"
2690 [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2691 (match_operand:SI 1 "reg_or_0_operand" "rM"))
2692 (set (match_dup 0)
2693 (plus:SI (match_dup 0)
2694 (match_operand:SI 2 "post_cint_operand" "")))]
2695 ""
2696 "*
2697 {
2698 if (INTVAL (operands[2]) > 0)
2699 return \"{stwm|stw,ma} %r1,%2(%0)\";
2700 return \"{stws|stw},ma %r1,%2(%0)\";
2701 }"
2702 [(set_attr "type" "store")
2703 (set_attr "length" "4")])
2704
2705 (define_insn "post_std"
2706 [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2707 (match_operand:DI 1 "reg_or_0_operand" "rM"))
2708 (set (match_dup 0)
2709 (plus:DI (match_dup 0)
2710 (match_operand:DI 2 "post_cint_operand" "")))]
2711 "TARGET_64BIT"
2712 "std,ma %r1,%2(%0)"
2713 [(set_attr "type" "store")
2714 (set_attr "length" "4")])
2715
2716 ;; For loading the address of a label while generating PIC code.
2717 ;; Note since this pattern can be created at reload time (via movsi), all
2718 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
2719 (define_insn ""
2720 [(set (match_operand 0 "pmode_register_operand" "=a")
2721 (match_operand 1 "pic_label_operand" ""))]
2722 "TARGET_PA_20"
2723 "*
2724 {
2725 rtx xoperands[3];
2726
2727 xoperands[0] = operands[0];
2728 xoperands[1] = operands[1];
2729 xoperands[2] = gen_label_rtx ();
2730
2731 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2732 CODE_LABEL_NUMBER (xoperands[2]));
2733 output_asm_insn (\"mfia %0\", xoperands);
2734
2735 /* If we're trying to load the address of a label that happens to be
2736 close, then we can use a shorter sequence. */
2737 if (GET_CODE (operands[1]) == LABEL_REF
2738 && !LABEL_REF_NONLOCAL_P (operands[1])
2739 && INSN_ADDRESSES_SET_P ()
2740 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2741 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2742 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2743 else
2744 {
2745 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2746 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2747 }
2748 return \"\";
2749 }"
2750 [(set_attr "type" "multi")
2751 (set_attr "length" "12")]) ; 8 or 12
2752
2753 (define_insn ""
2754 [(set (match_operand 0 "pmode_register_operand" "=a")
2755 (match_operand 1 "pic_label_operand" ""))]
2756 "!TARGET_PA_20"
2757 "*
2758 {
2759 rtx xoperands[3];
2760
2761 xoperands[0] = operands[0];
2762 xoperands[1] = operands[1];
2763 xoperands[2] = gen_label_rtx ();
2764
2765 output_asm_insn (\"bl .+8,%0\", xoperands);
2766 output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2767 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2768 CODE_LABEL_NUMBER (xoperands[2]));
2769
2770 /* If we're trying to load the address of a label that happens to be
2771 close, then we can use a shorter sequence. */
2772 if (GET_CODE (operands[1]) == LABEL_REF
2773 && !LABEL_REF_NONLOCAL_P (operands[1])
2774 && INSN_ADDRESSES_SET_P ()
2775 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2776 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2777 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2778 else
2779 {
2780 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2781 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2782 }
2783 return \"\";
2784 }"
2785 [(set_attr "type" "multi")
2786 (set_attr "length" "16")]) ; 12 or 16
2787
2788 (define_insn ""
2789 [(set (match_operand:SI 0 "register_operand" "=a")
2790 (plus:SI (match_operand:SI 1 "register_operand" "r")
2791 (high:SI (match_operand 2 "" ""))))]
2792 "symbolic_operand (operands[2], Pmode)
2793 && ! function_label_operand (operands[2], Pmode)
2794 && flag_pic"
2795 "addil LT'%G2,%1"
2796 [(set_attr "type" "binary")
2797 (set_attr "length" "4")])
2798
2799 (define_insn ""
2800 [(set (match_operand:DI 0 "register_operand" "=a")
2801 (plus:DI (match_operand:DI 1 "register_operand" "r")
2802 (high:DI (match_operand 2 "" ""))))]
2803 "symbolic_operand (operands[2], Pmode)
2804 && ! function_label_operand (operands[2], Pmode)
2805 && TARGET_64BIT
2806 && flag_pic"
2807 "addil LT'%G2,%1"
2808 [(set_attr "type" "binary")
2809 (set_attr "length" "4")])
2810
2811 (define_insn ""
2812 [(set (match_operand:SI 0 "register_operand" "=r")
2813 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2814 (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2815 "symbolic_operand (operands[2], Pmode)
2816 && ! function_label_operand (operands[2], Pmode)
2817 && flag_pic"
2818 "ldo RT'%G2(%1),%0"
2819 [(set_attr "type" "binary")
2820 (set_attr "length" "4")])
2821
2822 (define_insn ""
2823 [(set (match_operand:DI 0 "register_operand" "=r")
2824 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2825 (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2826 "symbolic_operand (operands[2], Pmode)
2827 && ! function_label_operand (operands[2], Pmode)
2828 && TARGET_64BIT
2829 && flag_pic"
2830 "ldo RT'%G2(%1),%0"
2831 [(set_attr "type" "binary")
2832 (set_attr "length" "4")])
2833
2834 ;; Always use addil rather than ldil;add sequences. This allows the
2835 ;; HP linker to eliminate the dp relocation if the symbolic operand
2836 ;; lives in the TEXT space.
2837 (define_insn ""
2838 [(set (match_operand:SI 0 "register_operand" "=a")
2839 (high:SI (match_operand 1 "" "")))]
2840 "symbolic_operand (operands[1], Pmode)
2841 && ! function_label_operand (operands[1], Pmode)
2842 && ! read_only_operand (operands[1], Pmode)
2843 && ! flag_pic"
2844 "*
2845 {
2846 if (TARGET_LONG_LOAD_STORE)
2847 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2848 else
2849 return \"addil LR'%H1,%%r27\";
2850 }"
2851 [(set_attr "type" "binary")
2852 (set (attr "length")
2853 (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2854 (const_int 4)
2855 (const_int 8)))])
2856
2857
2858 ;; This is for use in the prologue/epilogue code. We need it
2859 ;; to add large constants to a stack pointer or frame pointer.
2860 ;; Because of the additional %r1 pressure, we probably do not
2861 ;; want to use this in general code, so make it available
2862 ;; only after reload.
2863 (define_insn ""
2864 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2865 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2866 (high:SI (match_operand 2 "const_int_operand" ""))))]
2867 "reload_completed"
2868 "@
2869 addil L'%G2,%1
2870 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2871 [(set_attr "type" "binary,binary")
2872 (set_attr "length" "4,8")])
2873
2874 (define_insn ""
2875 [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2876 (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2877 (high:DI (match_operand 2 "const_int_operand" ""))))]
2878 "reload_completed && TARGET_64BIT"
2879 "@
2880 addil L'%G2,%1
2881 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2882 [(set_attr "type" "binary,binary")
2883 (set_attr "length" "4,8")])
2884
2885 (define_insn ""
2886 [(set (match_operand:SI 0 "register_operand" "=r")
2887 (high:SI (match_operand 1 "" "")))]
2888 "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2889 && !pa_is_function_label_plus_const (operands[1])"
2890 "*
2891 {
2892 if (symbolic_operand (operands[1], Pmode))
2893 return \"ldil LR'%H1,%0\";
2894 else
2895 return \"ldil L'%G1,%0\";
2896 }"
2897 [(set_attr "type" "move")
2898 (set_attr "length" "4")])
2899
2900 (define_insn ""
2901 [(set (match_operand:DI 0 "register_operand" "=r")
2902 (high:DI (match_operand 1 "const_int_operand" "")))]
2903 "TARGET_64BIT"
2904 "ldil L'%G1,%0";
2905 [(set_attr "type" "move")
2906 (set_attr "length" "4")])
2907
2908 (define_insn ""
2909 [(set (match_operand:DI 0 "register_operand" "=r")
2910 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2911 (match_operand:DI 2 "const_int_operand" "i")))]
2912 "TARGET_64BIT"
2913 "ldo R'%G2(%1),%0";
2914 [(set_attr "type" "move")
2915 (set_attr "length" "4")])
2916
2917 (define_insn ""
2918 [(set (match_operand:SI 0 "register_operand" "=r")
2919 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2920 (match_operand:SI 2 "immediate_operand" "i")))]
2921 "!pa_is_function_label_plus_const (operands[2])"
2922 "*
2923 {
2924 gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2925
2926 if (symbolic_operand (operands[2], Pmode))
2927 return \"ldo RR'%G2(%1),%0\";
2928 else
2929 return \"ldo R'%G2(%1),%0\";
2930 }"
2931 [(set_attr "type" "move")
2932 (set_attr "length" "4")])
2933
2934 ;; Now that a symbolic_address plus a constant is broken up early
2935 ;; in the compilation phase (for better CSE) we need a special
2936 ;; combiner pattern to load the symbolic address plus the constant
2937 ;; in only 2 instructions. (For cases where the symbolic address
2938 ;; was not a common subexpression.)
2939 (define_split
2940 [(set (match_operand:SI 0 "register_operand" "")
2941 (match_operand:SI 1 "symbolic_operand" ""))
2942 (clobber (match_operand:SI 2 "register_operand" ""))]
2943 "! (flag_pic && pic_label_operand (operands[1], SImode))"
2944 [(set (match_dup 2) (high:SI (match_dup 1)))
2945 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2946 "")
2947
2948 ;; hppa_legitimize_address goes to a great deal of trouble to
2949 ;; create addresses which use indexing. In some cases, this
2950 ;; is a lose because there isn't any store instructions which
2951 ;; allow indexed addresses (with integer register source).
2952 ;;
2953 ;; These define_splits try to turn a 3 insn store into
2954 ;; a 2 insn store with some creative RTL rewriting.
2955 (define_split
2956 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2957 (match_operand:SI 1 "mem_shadd_operand" ""))
2958 (plus:SI (match_operand:SI 2 "register_operand" "")
2959 (match_operand:SI 3 "const_int_operand" ""))))
2960 (match_operand:SI 4 "register_operand" ""))
2961 (clobber (match_operand:SI 5 "register_operand" ""))]
2962 ""
2963 [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2964 (match_dup 2)))
2965 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2966 "
2967 {
2968 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2969
2970 }")
2971
2972 (define_split
2973 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2974 (match_operand:SI 1 "mem_shadd_operand" ""))
2975 (plus:SI (match_operand:SI 2 "register_operand" "")
2976 (match_operand:SI 3 "const_int_operand" ""))))
2977 (match_operand:HI 4 "register_operand" ""))
2978 (clobber (match_operand:SI 5 "register_operand" ""))]
2979 ""
2980 [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2981 (match_dup 2)))
2982 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2983 "
2984 {
2985 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2986
2987 }")
2988
2989 (define_split
2990 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2991 (match_operand:SI 1 "mem_shadd_operand" ""))
2992 (plus:SI (match_operand:SI 2 "register_operand" "")
2993 (match_operand:SI 3 "const_int_operand" ""))))
2994 (match_operand:QI 4 "register_operand" ""))
2995 (clobber (match_operand:SI 5 "register_operand" ""))]
2996 ""
2997 [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2998 (match_dup 2)))
2999 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
3000 "
3001 {
3002 operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
3003
3004 }")
3005
3006 (define_expand "movhi"
3007 [(set (match_operand:HI 0 "general_operand" "")
3008 (match_operand:HI 1 "general_operand" ""))]
3009 ""
3010 "
3011 {
3012 if (pa_emit_move_sequence (operands, HImode, 0))
3013 DONE;
3014 }")
3015
3016 ;; Handle HImode input reloads requiring a general register as a
3017 ;; scratch register.
3018 (define_expand "reload_inhi"
3019 [(set (match_operand:HI 0 "register_operand" "=Z")
3020 (match_operand:HI 1 "non_hard_reg_operand" ""))
3021 (clobber (match_operand:HI 2 "register_operand" "=&r"))]
3022 ""
3023 "
3024 {
3025 if (pa_emit_move_sequence (operands, HImode, operands[2]))
3026 DONE;
3027
3028 /* We don't want the clobber emitted, so handle this ourselves. */
3029 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3030 DONE;
3031 }")
3032
3033 ;; Handle HImode output reloads requiring a general register as a
3034 ;; scratch register.
3035 (define_expand "reload_outhi"
3036 [(set (match_operand:HI 0 "non_hard_reg_operand" "")
3037 (match_operand:HI 1 "register_operand" "Z"))
3038 (clobber (match_operand:HI 2 "register_operand" "=&r"))]
3039 ""
3040 "
3041 {
3042 if (pa_emit_move_sequence (operands, HImode, operands[2]))
3043 DONE;
3044
3045 /* We don't want the clobber emitted, so handle this ourselves. */
3046 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3047 DONE;
3048 }")
3049
3050 (define_insn ""
3051 [(set (match_operand:HI 0 "move_dest_operand"
3052 "=r,r,r,r,r,Q,!*q,!r")
3053 (match_operand:HI 1 "move_src_operand"
3054 "r,J,N,K,RQ,rM,!rM,!*q"))]
3055 "(register_operand (operands[0], HImode)
3056 || reg_or_0_operand (operands[1], HImode))"
3057 "@
3058 copy %1,%0
3059 ldi %1,%0
3060 ldil L'%1,%0
3061 {zdepi|depwi,z} %Z1,%0
3062 ldh%M1 %1,%0
3063 sth%M0 %r1,%0
3064 mtsar %r1
3065 {mfctl|mfctl,w} %sar,%0"
3066 [(set_attr "type" "move,move,move,shift,load,store,move,move")
3067 (set_attr "pa_combine_type" "addmove")
3068 (set_attr "length" "4,4,4,4,4,4,4,4")])
3069
3070 (define_insn ""
3071 [(set (match_operand:HI 0 "register_operand" "=r")
3072 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3073 (match_operand:SI 2 "int5_operand" "L"))))
3074 (set (match_dup 1)
3075 (plus:SI (match_dup 1) (match_dup 2)))]
3076 ""
3077 "{ldhs|ldh},mb %2(%1),%0"
3078 [(set_attr "type" "load")
3079 (set_attr "length" "4")])
3080
3081 (define_insn ""
3082 [(set (match_operand:HI 0 "register_operand" "=r")
3083 (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3084 (match_operand:DI 2 "int5_operand" "L"))))
3085 (set (match_dup 1)
3086 (plus:DI (match_dup 1) (match_dup 2)))]
3087 "TARGET_64BIT"
3088 "ldh,mb %2(%1),%0"
3089 [(set_attr "type" "load")
3090 (set_attr "length" "4")])
3091
3092 ; And a zero extended variant.
3093 (define_insn ""
3094 [(set (match_operand:DI 0 "register_operand" "=r")
3095 (zero_extend:DI (mem:HI
3096 (plus:DI
3097 (match_operand:DI 1 "register_operand" "+r")
3098 (match_operand:DI 2 "int5_operand" "L")))))
3099 (set (match_dup 1)
3100 (plus:DI (match_dup 1) (match_dup 2)))]
3101 "TARGET_64BIT"
3102 "ldh,mb %2(%1),%0"
3103 [(set_attr "type" "load")
3104 (set_attr "length" "4")])
3105
3106 (define_insn ""
3107 [(set (match_operand:SI 0 "register_operand" "=r")
3108 (zero_extend:SI (mem:HI
3109 (plus:SI
3110 (match_operand:SI 1 "register_operand" "+r")
3111 (match_operand:SI 2 "int5_operand" "L")))))
3112 (set (match_dup 1)
3113 (plus:SI (match_dup 1) (match_dup 2)))]
3114 ""
3115 "{ldhs|ldh},mb %2(%1),%0"
3116 [(set_attr "type" "load")
3117 (set_attr "length" "4")])
3118
3119 (define_insn ""
3120 [(set (match_operand:SI 0 "register_operand" "=r")
3121 (zero_extend:SI (mem:HI
3122 (plus:DI
3123 (match_operand:DI 1 "register_operand" "+r")
3124 (match_operand:DI 2 "int5_operand" "L")))))
3125 (set (match_dup 1)
3126 (plus:DI (match_dup 1) (match_dup 2)))]
3127 "TARGET_64BIT"
3128 "ldh,mb %2(%1),%0"
3129 [(set_attr "type" "load")
3130 (set_attr "length" "4")])
3131
3132 (define_insn ""
3133 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3134 (match_operand:SI 1 "int5_operand" "L")))
3135 (match_operand:HI 2 "reg_or_0_operand" "rM"))
3136 (set (match_dup 0)
3137 (plus:SI (match_dup 0) (match_dup 1)))]
3138 ""
3139 "{sths|sth},mb %r2,%1(%0)"
3140 [(set_attr "type" "store")
3141 (set_attr "length" "4")])
3142
3143 (define_insn ""
3144 [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3145 (match_operand:DI 1 "int5_operand" "L")))
3146 (match_operand:HI 2 "reg_or_0_operand" "rM"))
3147 (set (match_dup 0)
3148 (plus:DI (match_dup 0) (match_dup 1)))]
3149 "TARGET_64BIT"
3150 "sth,mb %r2,%1(%0)"
3151 [(set_attr "type" "store")
3152 (set_attr "length" "4")])
3153
3154 (define_insn "addhi3"
3155 [(set (match_operand:HI 0 "register_operand" "=r,r")
3156 (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3157 (match_operand:HI 2 "arith14_operand" "r,J")))]
3158 ""
3159 "@
3160 {addl|add,l} %1,%2,%0
3161 ldo %2(%1),%0"
3162 [(set_attr "type" "binary,binary")
3163 (set_attr "pa_combine_type" "addmove")
3164 (set_attr "length" "4,4")])
3165
3166 (define_expand "movqi"
3167 [(set (match_operand:QI 0 "general_operand" "")
3168 (match_operand:QI 1 "general_operand" ""))]
3169 ""
3170 "
3171 {
3172 if (pa_emit_move_sequence (operands, QImode, 0))
3173 DONE;
3174 }")
3175
3176 ;; Handle QImode input reloads requiring a general register as a
3177 ;; scratch register.
3178 (define_expand "reload_inqi"
3179 [(set (match_operand:QI 0 "register_operand" "=Z")
3180 (match_operand:QI 1 "non_hard_reg_operand" ""))
3181 (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3182 ""
3183 "
3184 {
3185 if (pa_emit_move_sequence (operands, QImode, operands[2]))
3186 DONE;
3187
3188 /* We don't want the clobber emitted, so handle this ourselves. */
3189 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3190 DONE;
3191 }")
3192
3193 ;; Handle QImode output reloads requiring a general register as a
3194 ;; scratch register.
3195 (define_expand "reload_outqi"
3196 [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3197 (match_operand:QI 1 "register_operand" "Z"))
3198 (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3199 ""
3200 "
3201 {
3202 if (pa_emit_move_sequence (operands, QImode, operands[2]))
3203 DONE;
3204
3205 /* We don't want the clobber emitted, so handle this ourselves. */
3206 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3207 DONE;
3208 }")
3209
3210 (define_insn ""
3211 [(set (match_operand:QI 0 "move_dest_operand"
3212 "=r,r,r,r,r,Q,!*q,!r")
3213 (match_operand:QI 1 "move_src_operand"
3214 "r,J,N,K,RQ,rM,!rM,!*q"))]
3215 "(register_operand (operands[0], QImode)
3216 || reg_or_0_operand (operands[1], QImode))"
3217 "@
3218 copy %1,%0
3219 ldi %1,%0
3220 ldil L'%1,%0
3221 {zdepi|depwi,z} %Z1,%0
3222 ldb%M1 %1,%0
3223 stb%M0 %r1,%0
3224 mtsar %r1
3225 {mfctl|mfctl,w} %%sar,%0"
3226 [(set_attr "type" "move,move,move,shift,load,store,move,move")
3227 (set_attr "pa_combine_type" "addmove")
3228 (set_attr "length" "4,4,4,4,4,4,4,4")])
3229
3230 (define_insn ""
3231 [(set (match_operand:QI 0 "register_operand" "=r")
3232 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3233 (match_operand:SI 2 "int5_operand" "L"))))
3234 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3235 ""
3236 "{ldbs|ldb},mb %2(%1),%0"
3237 [(set_attr "type" "load")
3238 (set_attr "length" "4")])
3239
3240 (define_insn ""
3241 [(set (match_operand:QI 0 "register_operand" "=r")
3242 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3243 (match_operand:DI 2 "int5_operand" "L"))))
3244 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3245 "TARGET_64BIT"
3246 "ldb,mb %2(%1),%0"
3247 [(set_attr "type" "load")
3248 (set_attr "length" "4")])
3249
3250 ; Now the same thing with zero extensions.
3251 (define_insn ""
3252 [(set (match_operand:DI 0 "register_operand" "=r")
3253 (zero_extend:DI (mem:QI (plus:DI
3254 (match_operand:DI 1 "register_operand" "+r")
3255 (match_operand:DI 2 "int5_operand" "L")))))
3256 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3257 "TARGET_64BIT"
3258 "ldb,mb %2(%1),%0"
3259 [(set_attr "type" "load")
3260 (set_attr "length" "4")])
3261
3262 (define_insn ""
3263 [(set (match_operand:SI 0 "register_operand" "=r")
3264 (zero_extend:SI (mem:QI (plus:SI
3265 (match_operand:SI 1 "register_operand" "+r")
3266 (match_operand:SI 2 "int5_operand" "L")))))
3267 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3268 ""
3269 "{ldbs|ldb},mb %2(%1),%0"
3270 [(set_attr "type" "load")
3271 (set_attr "length" "4")])
3272
3273 (define_insn ""
3274 [(set (match_operand:SI 0 "register_operand" "=r")
3275 (zero_extend:SI (mem:QI (plus:DI
3276 (match_operand:DI 1 "register_operand" "+r")
3277 (match_operand:DI 2 "int5_operand" "L")))))
3278 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3279 "TARGET_64BIT"
3280 "ldb,mb %2(%1),%0"
3281 [(set_attr "type" "load")
3282 (set_attr "length" "4")])
3283
3284 (define_insn ""
3285 [(set (match_operand:HI 0 "register_operand" "=r")
3286 (zero_extend:HI (mem:QI (plus:SI
3287 (match_operand:SI 1 "register_operand" "+r")
3288 (match_operand:SI 2 "int5_operand" "L")))))
3289 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3290 ""
3291 "{ldbs|ldb},mb %2(%1),%0"
3292 [(set_attr "type" "load")
3293 (set_attr "length" "4")])
3294
3295 (define_insn ""
3296 [(set (match_operand:HI 0 "register_operand" "=r")
3297 (zero_extend:HI (mem:QI (plus:DI
3298 (match_operand:DI 1 "register_operand" "+r")
3299 (match_operand:DI 2 "int5_operand" "L")))))
3300 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3301 "TARGET_64BIT"
3302 "ldb,mb %2(%1),%0"
3303 [(set_attr "type" "load")
3304 (set_attr "length" "4")])
3305
3306 (define_insn ""
3307 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3308 (match_operand:SI 1 "int5_operand" "L")))
3309 (match_operand:QI 2 "reg_or_0_operand" "rM"))
3310 (set (match_dup 0)
3311 (plus:SI (match_dup 0) (match_dup 1)))]
3312 ""
3313 "{stbs|stb},mb %r2,%1(%0)"
3314 [(set_attr "type" "store")
3315 (set_attr "length" "4")])
3316
3317 (define_insn ""
3318 [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3319 (match_operand:DI 1 "int5_operand" "L")))
3320 (match_operand:QI 2 "reg_or_0_operand" "rM"))
3321 (set (match_dup 0)
3322 (plus:DI (match_dup 0) (match_dup 1)))]
3323 "TARGET_64BIT"
3324 "stb,mb %r2,%1(%0)"
3325 [(set_attr "type" "store")
3326 (set_attr "length" "4")])
3327
3328 ;; The definition of this insn does not really explain what it does,
3329 ;; but it should suffice that anything generated as this insn will be
3330 ;; recognized as a movmemsi operation, and that it will not successfully
3331 ;; combine with anything.
3332 (define_expand "movmemsi"
3333 [(parallel [(set (match_operand:BLK 0 "" "")
3334 (match_operand:BLK 1 "" ""))
3335 (clobber (match_dup 4))
3336 (clobber (match_dup 5))
3337 (clobber (match_dup 6))
3338 (clobber (match_dup 7))
3339 (clobber (match_dup 8))
3340 (use (match_operand:SI 2 "arith14_operand" ""))
3341 (use (match_operand:SI 3 "const_int_operand" ""))])]
3342 "!TARGET_64BIT && optimize > 0"
3343 "
3344 {
3345 int size, align;
3346
3347 /* HP provides very fast block move library routine for the PA;
3348 this routine includes:
3349
3350 4x4 byte at a time block moves,
3351 1x4 byte at a time with alignment checked at runtime with
3352 attempts to align the source and destination as needed
3353 1x1 byte loop
3354
3355 With that in mind, here's the heuristics to try and guess when
3356 the inlined block move will be better than the library block
3357 move:
3358
3359 If the size isn't constant, then always use the library routines.
3360
3361 If the size is large in respect to the known alignment, then use
3362 the library routines.
3363
3364 If the size is small in respect to the known alignment, then open
3365 code the copy (since that will lead to better scheduling).
3366
3367 Else use the block move pattern. */
3368
3369 /* Undetermined size, use the library routine. */
3370 if (GET_CODE (operands[2]) != CONST_INT)
3371 FAIL;
3372
3373 size = INTVAL (operands[2]);
3374 align = INTVAL (operands[3]);
3375 align = align > 4 ? 4 : (align ? align : 1);
3376
3377 /* If size/alignment is large, then use the library routines. */
3378 if (size / align > 16)
3379 FAIL;
3380
3381 /* This does happen, but not often enough to worry much about. */
3382 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3383 FAIL;
3384
3385 /* Fall through means we're going to use our block move pattern. */
3386 operands[0]
3387 = replace_equiv_address (operands[0],
3388 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3389 operands[1]
3390 = replace_equiv_address (operands[1],
3391 copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3392 operands[4] = gen_reg_rtx (SImode);
3393 operands[5] = gen_reg_rtx (SImode);
3394 operands[6] = gen_reg_rtx (SImode);
3395 operands[7] = gen_reg_rtx (SImode);
3396 operands[8] = gen_reg_rtx (SImode);
3397 }")
3398
3399 ;; The operand constraints are written like this to support both compile-time
3400 ;; and run-time determined byte counts. The expander and pa_output_block_move
3401 ;; only support compile-time determined counts at this time.
3402 ;;
3403 ;; If the count is run-time determined, the register with the byte count
3404 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3405 ;;
3406 ;; We used to clobber operands 0 and 1. However, a change to regrename.c
3407 ;; broke this semantic for pseudo registers. We can't use match_scratch
3408 ;; as this requires two registers in the class R1_REGS when the MEMs for
3409 ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
3410 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3411 ;; respectively. We then split or peephole optimize after reload.
3412 (define_insn "movmemsi_prereload"
3413 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3414 (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3415 (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3416 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
3417 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
3418 (clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3
3419 (clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4
3420 (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count
3421 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3422 "!TARGET_64BIT"
3423 "#"
3424 [(set_attr "type" "multi,multi")])
3425
3426 (define_split
3427 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3428 (match_operand:BLK 1 "memory_operand" ""))
3429 (clobber (match_operand:SI 2 "register_operand" ""))
3430 (clobber (match_operand:SI 3 "register_operand" ""))
3431 (clobber (match_operand:SI 6 "register_operand" ""))
3432 (clobber (match_operand:SI 7 "register_operand" ""))
3433 (clobber (match_operand:SI 8 "register_operand" ""))
3434 (use (match_operand:SI 4 "arith14_operand" ""))
3435 (use (match_operand:SI 5 "const_int_operand" ""))])]
3436 "!TARGET_64BIT && reload_completed && !flag_peephole2
3437 && GET_CODE (operands[0]) == MEM
3438 && register_operand (XEXP (operands[0], 0), SImode)
3439 && GET_CODE (operands[1]) == MEM
3440 && register_operand (XEXP (operands[1], 0), SImode)"
3441 [(set (match_dup 7) (match_dup 9))
3442 (set (match_dup 8) (match_dup 10))
3443 (parallel [(set (match_dup 0) (match_dup 1))
3444 (clobber (match_dup 2))
3445 (clobber (match_dup 3))
3446 (clobber (match_dup 6))
3447 (clobber (match_dup 7))
3448 (clobber (match_dup 8))
3449 (use (match_dup 4))
3450 (use (match_dup 5))
3451 (const_int 0)])]
3452 "
3453 {
3454 operands[9] = XEXP (operands[0], 0);
3455 operands[10] = XEXP (operands[1], 0);
3456 operands[0] = replace_equiv_address (operands[0], operands[7]);
3457 operands[1] = replace_equiv_address (operands[1], operands[8]);
3458 }")
3459
3460 (define_peephole2
3461 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3462 (match_operand:BLK 1 "memory_operand" ""))
3463 (clobber (match_operand:SI 2 "register_operand" ""))
3464 (clobber (match_operand:SI 3 "register_operand" ""))
3465 (clobber (match_operand:SI 6 "register_operand" ""))
3466 (clobber (match_operand:SI 7 "register_operand" ""))
3467 (clobber (match_operand:SI 8 "register_operand" ""))
3468 (use (match_operand:SI 4 "arith14_operand" ""))
3469 (use (match_operand:SI 5 "const_int_operand" ""))])]
3470 "!TARGET_64BIT
3471 && GET_CODE (operands[0]) == MEM
3472 && register_operand (XEXP (operands[0], 0), SImode)
3473 && GET_CODE (operands[1]) == MEM
3474 && register_operand (XEXP (operands[1], 0), SImode)"
3475 [(parallel [(set (match_dup 0) (match_dup 1))
3476 (clobber (match_dup 2))
3477 (clobber (match_dup 3))
3478 (clobber (match_dup 6))
3479 (clobber (match_dup 7))
3480 (clobber (match_dup 8))
3481 (use (match_dup 4))
3482 (use (match_dup 5))
3483 (const_int 0)])]
3484 "
3485 {
3486 rtx addr = XEXP (operands[0], 0);
3487 if (dead_or_set_p (curr_insn, addr))
3488 operands[7] = addr;
3489 else
3490 {
3491 emit_insn (gen_rtx_SET (operands[7], addr));
3492 operands[0] = replace_equiv_address (operands[0], operands[7]);
3493 }
3494
3495 addr = XEXP (operands[1], 0);
3496 if (dead_or_set_p (curr_insn, addr))
3497 operands[8] = addr;
3498 else
3499 {
3500 emit_insn (gen_rtx_SET (operands[8], addr));
3501 operands[1] = replace_equiv_address (operands[1], operands[8]);
3502 }
3503 }")
3504
3505 (define_insn "movmemsi_postreload"
3506 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3507 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3508 (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3509 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
3510 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
3511 (clobber (match_dup 0))
3512 (clobber (match_dup 1))
3513 (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count
3514 (use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment
3515 (const_int 0)]
3516 "!TARGET_64BIT && reload_completed"
3517 "* return pa_output_block_move (operands, !which_alternative);"
3518 [(set_attr "type" "multi,multi")])
3519
3520 (define_expand "movmemdi"
3521 [(parallel [(set (match_operand:BLK 0 "" "")
3522 (match_operand:BLK 1 "" ""))
3523 (clobber (match_dup 4))
3524 (clobber (match_dup 5))
3525 (clobber (match_dup 6))
3526 (clobber (match_dup 7))
3527 (clobber (match_dup 8))
3528 (use (match_operand:DI 2 "arith14_operand" ""))
3529 (use (match_operand:DI 3 "const_int_operand" ""))])]
3530 "TARGET_64BIT && optimize > 0"
3531 "
3532 {
3533 int size, align;
3534
3535 /* HP provides very fast block move library routine for the PA;
3536 this routine includes:
3537
3538 4x4 byte at a time block moves,
3539 1x4 byte at a time with alignment checked at runtime with
3540 attempts to align the source and destination as needed
3541 1x1 byte loop
3542
3543 With that in mind, here's the heuristics to try and guess when
3544 the inlined block move will be better than the library block
3545 move:
3546
3547 If the size isn't constant, then always use the library routines.
3548
3549 If the size is large in respect to the known alignment, then use
3550 the library routines.
3551
3552 If the size is small in respect to the known alignment, then open
3553 code the copy (since that will lead to better scheduling).
3554
3555 Else use the block move pattern. */
3556
3557 /* Undetermined size, use the library routine. */
3558 if (GET_CODE (operands[2]) != CONST_INT)
3559 FAIL;
3560
3561 size = INTVAL (operands[2]);
3562 align = INTVAL (operands[3]);
3563 align = align > 8 ? 8 : (align ? align : 1);
3564
3565 /* If size/alignment is large, then use the library routines. */
3566 if (size / align > 16)
3567 FAIL;
3568
3569 /* This does happen, but not often enough to worry much about. */
3570 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3571 FAIL;
3572
3573 /* Fall through means we're going to use our block move pattern. */
3574 operands[0]
3575 = replace_equiv_address (operands[0],
3576 copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3577 operands[1]
3578 = replace_equiv_address (operands[1],
3579 copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3580 operands[4] = gen_reg_rtx (DImode);
3581 operands[5] = gen_reg_rtx (DImode);
3582 operands[6] = gen_reg_rtx (DImode);
3583 operands[7] = gen_reg_rtx (DImode);
3584 operands[8] = gen_reg_rtx (DImode);
3585 }")
3586
3587 ;; The operand constraints are written like this to support both compile-time
3588 ;; and run-time determined byte counts. The expander and pa_output_block_move
3589 ;; only support compile-time determined counts at this time.
3590 ;;
3591 ;; If the count is run-time determined, the register with the byte count
3592 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3593 ;;
3594 ;; We used to clobber operands 0 and 1. However, a change to regrename.c
3595 ;; broke this semantic for pseudo registers. We can't use match_scratch
3596 ;; as this requires two registers in the class R1_REGS when the MEMs for
3597 ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
3598 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3599 ;; respectively. We then split or peephole optimize after reload.
3600 (define_insn "movmemdi_prereload"
3601 [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3602 (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3603 (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3604 (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
3605 (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
3606 (clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3
3607 (clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4
3608 (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count
3609 (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3610 "TARGET_64BIT"
3611 "#"
3612 [(set_attr "type" "multi,multi")])
3613
3614 (define_split
3615 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3616 (match_operand:BLK 1 "memory_operand" ""))
3617 (clobber (match_operand:DI 2 "register_operand" ""))
3618 (clobber (match_operand:DI 3 "register_operand" ""))
3619 (clobber (match_operand:DI 6 "register_operand" ""))
3620 (clobber (match_operand:DI 7 "register_operand" ""))
3621 (clobber (match_operand:DI 8 "register_operand" ""))
3622 (use (match_operand:DI 4 "arith14_operand" ""))
3623 (use (match_operand:DI 5 "const_int_operand" ""))])]
3624 "TARGET_64BIT && reload_completed && !flag_peephole2
3625 && GET_CODE (operands[0]) == MEM
3626 && register_operand (XEXP (operands[0], 0), DImode)
3627 && GET_CODE (operands[1]) == MEM
3628 && register_operand (XEXP (operands[1], 0), DImode)"
3629 [(set (match_dup 7) (match_dup 9))
3630 (set (match_dup 8) (match_dup 10))
3631 (parallel [(set (match_dup 0) (match_dup 1))
3632 (clobber (match_dup 2))
3633 (clobber (match_dup 3))
3634 (clobber (match_dup 6))
3635 (clobber (match_dup 7))
3636 (clobber (match_dup 8))
3637 (use (match_dup 4))
3638 (use (match_dup 5))
3639 (const_int 0)])]
3640 "
3641 {
3642 operands[9] = XEXP (operands[0], 0);
3643 operands[10] = XEXP (operands[1], 0);
3644 operands[0] = replace_equiv_address (operands[0], operands[7]);
3645 operands[1] = replace_equiv_address (operands[1], operands[8]);
3646 }")
3647
3648 (define_peephole2
3649 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3650 (match_operand:BLK 1 "memory_operand" ""))
3651 (clobber (match_operand:DI 2 "register_operand" ""))
3652 (clobber (match_operand:DI 3 "register_operand" ""))
3653 (clobber (match_operand:DI 6 "register_operand" ""))
3654 (clobber (match_operand:DI 7 "register_operand" ""))
3655 (clobber (match_operand:DI 8 "register_operand" ""))
3656 (use (match_operand:DI 4 "arith14_operand" ""))
3657 (use (match_operand:DI 5 "const_int_operand" ""))])]
3658 "TARGET_64BIT
3659 && GET_CODE (operands[0]) == MEM
3660 && register_operand (XEXP (operands[0], 0), DImode)
3661 && GET_CODE (operands[1]) == MEM
3662 && register_operand (XEXP (operands[1], 0), DImode)"
3663 [(parallel [(set (match_dup 0) (match_dup 1))
3664 (clobber (match_dup 2))
3665 (clobber (match_dup 3))
3666 (clobber (match_dup 6))
3667 (clobber (match_dup 7))
3668 (clobber (match_dup 8))
3669 (use (match_dup 4))
3670 (use (match_dup 5))
3671 (const_int 0)])]
3672 "
3673 {
3674 rtx addr = XEXP (operands[0], 0);
3675 if (dead_or_set_p (curr_insn, addr))
3676 operands[7] = addr;
3677 else
3678 {
3679 emit_insn (gen_rtx_SET (operands[7], addr));
3680 operands[0] = replace_equiv_address (operands[0], operands[7]);
3681 }
3682
3683 addr = XEXP (operands[1], 0);
3684 if (dead_or_set_p (curr_insn, addr))
3685 operands[8] = addr;
3686 else
3687 {
3688 emit_insn (gen_rtx_SET (operands[8], addr));
3689 operands[1] = replace_equiv_address (operands[1], operands[8]);
3690 }
3691 }")
3692
3693 (define_insn "movmemdi_postreload"
3694 [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3695 (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3696 (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3697 (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
3698 (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
3699 (clobber (match_dup 0))
3700 (clobber (match_dup 1))
3701 (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count
3702 (use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment
3703 (const_int 0)]
3704 "TARGET_64BIT && reload_completed"
3705 "* return pa_output_block_move (operands, !which_alternative);"
3706 [(set_attr "type" "multi,multi")])
3707
3708 (define_expand "setmemsi"
3709 [(parallel [(set (match_operand:BLK 0 "" "")
3710 (match_operand 2 "const_int_operand" ""))
3711 (clobber (match_dup 4))
3712 (clobber (match_dup 5))
3713 (use (match_operand:SI 1 "arith14_operand" ""))
3714 (use (match_operand:SI 3 "const_int_operand" ""))])]
3715 "!TARGET_64BIT && optimize > 0"
3716 "
3717 {
3718 int size, align;
3719
3720 /* If value to set is not zero, use the library routine. */
3721 if (operands[2] != const0_rtx)
3722 FAIL;
3723
3724 /* Undetermined size, use the library routine. */
3725 if (GET_CODE (operands[1]) != CONST_INT)
3726 FAIL;
3727
3728 size = INTVAL (operands[1]);
3729 align = INTVAL (operands[3]);
3730 align = align > 4 ? 4 : align;
3731
3732 /* If size/alignment is large, then use the library routines. */
3733 if (size / align > 16)
3734 FAIL;
3735
3736 /* This does happen, but not often enough to worry much about. */
3737 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3738 FAIL;
3739
3740 /* Fall through means we're going to use our block clear pattern. */
3741 operands[0]
3742 = replace_equiv_address (operands[0],
3743 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3744 operands[4] = gen_reg_rtx (SImode);
3745 operands[5] = gen_reg_rtx (SImode);
3746 }")
3747
3748 (define_insn "clrmemsi_prereload"
3749 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3750 (const_int 0))
3751 (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3752 (clobber (match_operand:SI 4 "register_operand" "=&r,&r")) ;tmp1
3753 (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count
3754 (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3755 "!TARGET_64BIT"
3756 "#"
3757 [(set_attr "type" "multi,multi")])
3758
3759 (define_split
3760 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3761 (const_int 0))
3762 (clobber (match_operand:SI 1 "register_operand" ""))
3763 (clobber (match_operand:SI 4 "register_operand" ""))
3764 (use (match_operand:SI 2 "arith14_operand" ""))
3765 (use (match_operand:SI 3 "const_int_operand" ""))])]
3766 "!TARGET_64BIT && reload_completed && !flag_peephole2
3767 && GET_CODE (operands[0]) == MEM
3768 && register_operand (XEXP (operands[0], 0), SImode)"
3769 [(set (match_dup 4) (match_dup 5))
3770 (parallel [(set (match_dup 0) (const_int 0))
3771 (clobber (match_dup 1))
3772 (clobber (match_dup 4))
3773 (use (match_dup 2))
3774 (use (match_dup 3))
3775 (const_int 0)])]
3776 "
3777 {
3778 operands[5] = XEXP (operands[0], 0);
3779 operands[0] = replace_equiv_address (operands[0], operands[4]);
3780 }")
3781
3782 (define_peephole2
3783 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3784 (const_int 0))
3785 (clobber (match_operand:SI 1 "register_operand" ""))
3786 (clobber (match_operand:SI 4 "register_operand" ""))
3787 (use (match_operand:SI 2 "arith14_operand" ""))
3788 (use (match_operand:SI 3 "const_int_operand" ""))])]
3789 "!TARGET_64BIT
3790 && GET_CODE (operands[0]) == MEM
3791 && register_operand (XEXP (operands[0], 0), SImode)"
3792 [(parallel [(set (match_dup 0) (const_int 0))
3793 (clobber (match_dup 1))
3794 (clobber (match_dup 4))
3795 (use (match_dup 2))
3796 (use (match_dup 3))
3797 (const_int 0)])]
3798 "
3799 {
3800 rtx addr = XEXP (operands[0], 0);
3801 if (dead_or_set_p (curr_insn, addr))
3802 operands[4] = addr;
3803 else
3804 {
3805 emit_insn (gen_rtx_SET (operands[4], addr));
3806 operands[0] = replace_equiv_address (operands[0], operands[4]);
3807 }
3808 }")
3809
3810 (define_insn "clrmemsi_postreload"
3811 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3812 (const_int 0))
3813 (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3814 (clobber (match_dup 0))
3815 (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count
3816 (use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment
3817 (const_int 0)]
3818 "!TARGET_64BIT && reload_completed"
3819 "* return pa_output_block_clear (operands, !which_alternative);"
3820 [(set_attr "type" "multi,multi")])
3821
3822 (define_expand "setmemdi"
3823 [(parallel [(set (match_operand:BLK 0 "" "")
3824 (match_operand 2 "const_int_operand" ""))
3825 (clobber (match_dup 4))
3826 (clobber (match_dup 5))
3827 (use (match_operand:DI 1 "arith14_operand" ""))
3828 (use (match_operand:DI 3 "const_int_operand" ""))])]
3829 "TARGET_64BIT && optimize > 0"
3830 "
3831 {
3832 int size, align;
3833
3834 /* If value to set is not zero, use the library routine. */
3835 if (operands[2] != const0_rtx)
3836 FAIL;
3837
3838 /* Undetermined size, use the library routine. */
3839 if (GET_CODE (operands[1]) != CONST_INT)
3840 FAIL;
3841
3842 size = INTVAL (operands[1]);
3843 align = INTVAL (operands[3]);
3844 align = align > 8 ? 8 : align;
3845
3846 /* If size/alignment is large, then use the library routines. */
3847 if (size / align > 16)
3848 FAIL;
3849
3850 /* This does happen, but not often enough to worry much about. */
3851 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3852 FAIL;
3853
3854 /* Fall through means we're going to use our block clear pattern. */
3855 operands[0]
3856 = replace_equiv_address (operands[0],
3857 copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3858 operands[4] = gen_reg_rtx (DImode);
3859 operands[5] = gen_reg_rtx (DImode);
3860 }")
3861
3862 (define_insn "clrmemdi_prereload"
3863 [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3864 (const_int 0))
3865 (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3866 (clobber (match_operand:DI 4 "register_operand" "=&r,&r")) ;item tmp1
3867 (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count
3868 (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3869 "TARGET_64BIT"
3870 "#"
3871 [(set_attr "type" "multi,multi")])
3872
3873 (define_split
3874 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3875 (const_int 0))
3876 (clobber (match_operand:DI 1 "register_operand" ""))
3877 (clobber (match_operand:DI 4 "register_operand" ""))
3878 (use (match_operand:DI 2 "arith14_operand" ""))
3879 (use (match_operand:DI 3 "const_int_operand" ""))])]
3880 "TARGET_64BIT && reload_completed && !flag_peephole2
3881 && GET_CODE (operands[0]) == MEM
3882 && register_operand (XEXP (operands[0], 0), DImode)"
3883 [(set (match_dup 4) (match_dup 5))
3884 (parallel [(set (match_dup 0) (const_int 0))
3885 (clobber (match_dup 1))
3886 (clobber (match_dup 4))
3887 (use (match_dup 2))
3888 (use (match_dup 3))
3889 (const_int 0)])]
3890 "
3891 {
3892 operands[5] = XEXP (operands[0], 0);
3893 operands[0] = replace_equiv_address (operands[0], operands[4]);
3894 }")
3895
3896 (define_peephole2
3897 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3898 (const_int 0))
3899 (clobber (match_operand:DI 1 "register_operand" ""))
3900 (clobber (match_operand:DI 4 "register_operand" ""))
3901 (use (match_operand:DI 2 "arith14_operand" ""))
3902 (use (match_operand:DI 3 "const_int_operand" ""))])]
3903 "TARGET_64BIT
3904 && GET_CODE (operands[0]) == MEM
3905 && register_operand (XEXP (operands[0], 0), DImode)"
3906 [(parallel [(set (match_dup 0) (const_int 0))
3907 (clobber (match_dup 1))
3908 (clobber (match_dup 4))
3909 (use (match_dup 2))
3910 (use (match_dup 3))
3911 (const_int 0)])]
3912 "
3913 {
3914 rtx addr = XEXP (operands[0], 0);
3915 if (dead_or_set_p (curr_insn, addr))
3916 operands[4] = addr;
3917 else
3918 {
3919 emit_insn (gen_rtx_SET (operands[4], addr));
3920 operands[0] = replace_equiv_address (operands[0], operands[4]);
3921 }
3922 }")
3923
3924 (define_insn "clrmemdi_postreload"
3925 [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3926 (const_int 0))
3927 (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3928 (clobber (match_dup 0))
3929 (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count
3930 (use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment
3931 (const_int 0)]
3932 "TARGET_64BIT && reload_completed"
3933 "* return pa_output_block_clear (operands, !which_alternative);"
3934 [(set_attr "type" "multi,multi")])
3935 \f
3936 ;; Floating point move insns
3937
3938 (define_expand "movdf"
3939 [(set (match_operand:DF 0 "general_operand" "")
3940 (match_operand:DF 1 "general_operand" ""))]
3941 ""
3942 "
3943 {
3944 if (pa_emit_move_sequence (operands, DFmode, 0))
3945 DONE;
3946 }")
3947
3948 ;; Handle DFmode input reloads requiring %r1 as a scratch register.
3949 (define_expand "reload_indf_r1"
3950 [(set (match_operand:DF 0 "register_operand" "=Z")
3951 (match_operand:DF 1 "non_hard_reg_operand" ""))
3952 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3953 ""
3954 "
3955 {
3956 if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3957 DONE;
3958
3959 /* We don't want the clobber emitted, so handle this ourselves. */
3960 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3961 DONE;
3962 }")
3963
3964 ;; Handle DFmode input reloads requiring a general register as a
3965 ;; scratch register.
3966 (define_expand "reload_indf"
3967 [(set (match_operand:DF 0 "register_operand" "=Z")
3968 (match_operand:DF 1 "non_hard_reg_operand" ""))
3969 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3970 ""
3971 "
3972 {
3973 if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3974 DONE;
3975
3976 /* We don't want the clobber emitted, so handle this ourselves. */
3977 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3978 DONE;
3979 }")
3980
3981 ;; Handle DFmode output reloads requiring a general register as a
3982 ;; scratch register.
3983 (define_expand "reload_outdf"
3984 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3985 (match_operand:DF 1 "register_operand" "Z"))
3986 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3987 ""
3988 "
3989 {
3990 if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3991 DONE;
3992
3993 /* We don't want the clobber emitted, so handle this ourselves. */
3994 emit_insn (gen_rtx_SET (operands[0], operands[1]));
3995 DONE;
3996 }")
3997
3998 (define_insn ""
3999 [(set (match_operand:DF 0 "move_dest_operand"
4000 "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
4001 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4002 "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
4003 "(register_operand (operands[0], DFmode)
4004 || reg_or_0_operand (operands[1], DFmode))
4005 && !(GET_CODE (operands[1]) == CONST_DOUBLE
4006 && GET_CODE (operands[0]) == MEM)
4007 && !TARGET_64BIT
4008 && !TARGET_SOFT_FLOAT"
4009 "*
4010 {
4011 if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4012 || operands[1] == CONST0_RTX (DFmode))
4013 && !(REG_P (operands[0]) && REG_P (operands[1])
4014 && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4015 return pa_output_fp_move_double (operands);
4016 return pa_output_move_double (operands);
4017 }"
4018 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
4019 (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
4020
4021 (define_insn ""
4022 [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
4023 (match_operand:DF 1 "reg_or_0_operand" "f"))]
4024 "!TARGET_SOFT_FLOAT
4025 && !TARGET_DISABLE_INDEXING
4026 && reload_completed"
4027 "fstd%F0 %1,%0"
4028 [(set_attr "type" "fpstore")
4029 (set_attr "pa_combine_type" "addmove")
4030 (set_attr "length" "4")])
4031
4032 (define_peephole2
4033 [(set (match_operand:SI 0 "register_operand" "")
4034 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4035 (const_int 3))
4036 (match_operand:SI 2 "register_operand" "")))
4037 (set (mem:DF (match_dup 0))
4038 (match_operand:DF 3 "register_operand" ""))]
4039 "!TARGET_SOFT_FLOAT
4040 && !TARGET_DISABLE_INDEXING
4041 && REG_OK_FOR_BASE_P (operands[2])
4042 && FP_REGNO_P (REGNO (operands[3]))"
4043 [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
4044 (match_dup 3))
4045 (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
4046 (match_dup 2)))]
4047 "")
4048
4049 (define_peephole2
4050 [(set (match_operand:SI 0 "register_operand" "")
4051 (plus:SI (match_operand:SI 2 "register_operand" "")
4052 (ashift:SI (match_operand:SI 1 "register_operand" "")
4053 (const_int 3))))
4054 (set (mem:DF (match_dup 0))
4055 (match_operand:DF 3 "register_operand" ""))]
4056 "!TARGET_SOFT_FLOAT
4057 && !TARGET_DISABLE_INDEXING
4058 && REG_OK_FOR_BASE_P (operands[2])
4059 && FP_REGNO_P (REGNO (operands[3]))"
4060 [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
4061 (match_dup 3))
4062 (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
4063 (match_dup 2)))]
4064 "")
4065
4066 (define_peephole2
4067 [(set (match_operand:DI 0 "register_operand" "")
4068 (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4069 (const_int 3))
4070 (match_operand:DI 2 "register_operand" "")))
4071 (set (mem:DF (match_dup 0))
4072 (match_operand:DF 3 "register_operand" ""))]
4073 "!TARGET_SOFT_FLOAT
4074 && !TARGET_DISABLE_INDEXING
4075 && TARGET_64BIT
4076 && REG_OK_FOR_BASE_P (operands[2])
4077 && FP_REGNO_P (REGNO (operands[3]))"
4078 [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4079 (match_dup 3))
4080 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4081 (match_dup 2)))]
4082 "")
4083
4084 (define_peephole2
4085 [(set (match_operand:DI 0 "register_operand" "")
4086 (plus:DI (match_operand:DI 2 "register_operand" "")
4087 (ashift:DI (match_operand:DI 1 "register_operand" "")
4088 (const_int 3))))
4089 (set (mem:DF (match_dup 0))
4090 (match_operand:DF 3 "register_operand" ""))]
4091 "!TARGET_SOFT_FLOAT
4092 && !TARGET_DISABLE_INDEXING
4093 && TARGET_64BIT
4094 && REG_OK_FOR_BASE_P (operands[2])
4095 && FP_REGNO_P (REGNO (operands[3]))"
4096 [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4097 (match_dup 3))
4098 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4099 (match_dup 2)))]
4100 "")
4101
4102 (define_peephole2
4103 [(set (match_operand:SI 0 "register_operand" "")
4104 (plus:SI (match_operand:SI 1 "register_operand" "")
4105 (match_operand:SI 2 "register_operand" "")))
4106 (set (mem:DF (match_dup 0))
4107 (match_operand:DF 3 "register_operand" ""))]
4108 "!TARGET_SOFT_FLOAT
4109 && !TARGET_DISABLE_INDEXING
4110 && TARGET_NO_SPACE_REGS
4111 && REG_OK_FOR_INDEX_P (operands[1])
4112 && REG_OK_FOR_BASE_P (operands[2])
4113 && FP_REGNO_P (REGNO (operands[3]))"
4114 [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
4115 (match_dup 3))
4116 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4117 "")
4118
4119 (define_peephole2
4120 [(set (match_operand:SI 0 "register_operand" "")
4121 (plus:SI (match_operand:SI 1 "register_operand" "")
4122 (match_operand:SI 2 "register_operand" "")))
4123 (set (mem:DF (match_dup 0))
4124 (match_operand:DF 3 "register_operand" ""))]
4125 "!TARGET_SOFT_FLOAT
4126 && !TARGET_DISABLE_INDEXING
4127 && TARGET_NO_SPACE_REGS
4128 && REG_OK_FOR_BASE_P (operands[1])
4129 && REG_OK_FOR_INDEX_P (operands[2])
4130 && FP_REGNO_P (REGNO (operands[3]))"
4131 [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
4132 (match_dup 3))
4133 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4134 "")
4135
4136 (define_peephole2
4137 [(set (match_operand:DI 0 "register_operand" "")
4138 (plus:DI (match_operand:DI 1 "register_operand" "")
4139 (match_operand:DI 2 "register_operand" "")))
4140 (set (mem:DF (match_dup 0))
4141 (match_operand:DF 3 "register_operand" ""))]
4142 "!TARGET_SOFT_FLOAT
4143 && !TARGET_DISABLE_INDEXING
4144 && TARGET_64BIT
4145 && TARGET_NO_SPACE_REGS
4146 && REG_OK_FOR_INDEX_P (operands[1])
4147 && REG_OK_FOR_BASE_P (operands[2])
4148 && FP_REGNO_P (REGNO (operands[3]))"
4149 [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4150 (match_dup 3))
4151 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4152 "")
4153
4154 (define_peephole2
4155 [(set (match_operand:DI 0 "register_operand" "")
4156 (plus:DI (match_operand:DI 1 "register_operand" "")
4157 (match_operand:DI 2 "register_operand" "")))
4158 (set (mem:DF (match_dup 0))
4159 (match_operand:DF 3 "register_operand" ""))]
4160 "!TARGET_SOFT_FLOAT
4161 && !TARGET_DISABLE_INDEXING
4162 && TARGET_64BIT
4163 && TARGET_NO_SPACE_REGS
4164 && REG_OK_FOR_BASE_P (operands[1])
4165 && REG_OK_FOR_INDEX_P (operands[2])
4166 && FP_REGNO_P (REGNO (operands[3]))"
4167 [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4168 (match_dup 3))
4169 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4170 "")
4171
4172 (define_insn ""
4173 [(set (match_operand:DF 0 "move_dest_operand"
4174 "=r,?o,?Q,r,r")
4175 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4176 "rG,r,r,o,RQ"))]
4177 "(register_operand (operands[0], DFmode)
4178 || reg_or_0_operand (operands[1], DFmode))
4179 && !TARGET_64BIT
4180 && TARGET_SOFT_FLOAT"
4181 "*
4182 {
4183 return pa_output_move_double (operands);
4184 }"
4185 [(set_attr "type" "move,store,store,load,load")
4186 (set_attr "length" "8,8,16,8,16")])
4187
4188 (define_insn ""
4189 [(set (match_operand:DF 0 "move_dest_operand"
4190 "=!*r,*r,*r,*r,*r,Q,f,f,T")
4191 (match_operand:DF 1 "move_src_operand"
4192 "!*r,J,N,K,RQ,*rG,fG,RT,f"))]
4193 "(register_operand (operands[0], DFmode)
4194 || reg_or_0_operand (operands[1], DFmode))
4195 && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4196 "@
4197 copy %1,%0
4198 ldi %1,%0
4199 ldil L'%1,%0
4200 depdi,z %z1,%0
4201 ldd%M1 %1,%0
4202 std%M0 %r1,%0
4203 fcpy,dbl %f1,%0
4204 fldd%F1 %1,%0
4205 fstd%F0 %1,%0"
4206 [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4207 (set_attr "pa_combine_type" "addmove")
4208 (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4209
4210 \f
4211 (define_expand "movdi"
4212 [(set (match_operand:DI 0 "general_operand" "")
4213 (match_operand:DI 1 "general_operand" ""))]
4214 ""
4215 "
4216 {
4217 if (pa_emit_move_sequence (operands, DImode, 0))
4218 DONE;
4219 }")
4220
4221 ;; Handle DImode input reloads requiring %r1 as a scratch register.
4222 (define_expand "reload_indi_r1"
4223 [(set (match_operand:DI 0 "register_operand" "=Z")
4224 (match_operand:DI 1 "non_hard_reg_operand" ""))
4225 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4226 ""
4227 "
4228 {
4229 if (pa_emit_move_sequence (operands, DImode, operands[2]))
4230 DONE;
4231
4232 /* We don't want the clobber emitted, so handle this ourselves. */
4233 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4234 DONE;
4235 }")
4236
4237 ;; Handle DImode input reloads requiring a general register as a
4238 ;; scratch register.
4239 (define_expand "reload_indi"
4240 [(set (match_operand:DI 0 "register_operand" "=Z")
4241 (match_operand:DI 1 "non_hard_reg_operand" ""))
4242 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4243 ""
4244 "
4245 {
4246 if (pa_emit_move_sequence (operands, DImode, operands[2]))
4247 DONE;
4248
4249 /* We don't want the clobber emitted, so handle this ourselves. */
4250 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4251 DONE;
4252 }")
4253
4254 ;; Handle DImode output reloads requiring a general register as a
4255 ;; scratch register.
4256 (define_expand "reload_outdi"
4257 [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4258 (match_operand:DI 1 "register_operand" "Z"))
4259 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4260 ""
4261 "
4262 {
4263 if (pa_emit_move_sequence (operands, DImode, operands[2]))
4264 DONE;
4265
4266 /* We don't want the clobber emitted, so handle this ourselves. */
4267 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4268 DONE;
4269 }")
4270
4271 (define_insn ""
4272 [(set (match_operand:DI 0 "register_operand" "=r")
4273 (high:DI (match_operand 1 "" "")))]
4274 "!TARGET_64BIT"
4275 "*
4276 {
4277 rtx op0 = operands[0];
4278 rtx op1 = operands[1];
4279
4280 switch (GET_CODE (op1))
4281 {
4282 case CONST_INT:
4283 #if HOST_BITS_PER_WIDE_INT <= 32
4284 operands[0] = operand_subword (op0, 1, 0, DImode);
4285 output_asm_insn (\"ldil L'%1,%0\", operands);
4286
4287 operands[0] = operand_subword (op0, 0, 0, DImode);
4288 if (INTVAL (op1) < 0)
4289 output_asm_insn (\"ldi -1,%0\", operands);
4290 else
4291 output_asm_insn (\"ldi 0,%0\", operands);
4292 #else
4293 operands[0] = operand_subword (op0, 1, 0, DImode);
4294 operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4295 output_asm_insn (\"ldil L'%1,%0\", operands);
4296
4297 operands[0] = operand_subword (op0, 0, 0, DImode);
4298 operands[1] = GEN_INT (INTVAL (op1) >> 32);
4299 output_asm_insn (pa_singlemove_string (operands), operands);
4300 #endif
4301 break;
4302
4303 case CONST_DOUBLE:
4304 operands[0] = operand_subword (op0, 1, 0, DImode);
4305 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4306 output_asm_insn (\"ldil L'%1,%0\", operands);
4307
4308 operands[0] = operand_subword (op0, 0, 0, DImode);
4309 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4310 output_asm_insn (pa_singlemove_string (operands), operands);
4311 break;
4312
4313 default:
4314 gcc_unreachable ();
4315 }
4316 return \"\";
4317 }"
4318 [(set_attr "type" "move")
4319 (set_attr "length" "12")])
4320
4321 (define_insn ""
4322 [(set (match_operand:DI 0 "move_dest_operand"
4323 "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4324 (match_operand:DI 1 "move_src_operand"
4325 "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4326 "(register_operand (operands[0], DImode)
4327 || reg_or_0_operand (operands[1], DImode))
4328 && !TARGET_64BIT
4329 && !TARGET_SOFT_FLOAT"
4330 "*
4331 {
4332 if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4333 || operands[1] == CONST0_RTX (DFmode))
4334 && !(REG_P (operands[0]) && REG_P (operands[1])
4335 && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4336 return pa_output_fp_move_double (operands);
4337 return pa_output_move_double (operands);
4338 }"
4339 [(set_attr "type"
4340 "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4341 (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4342
4343 (define_insn ""
4344 [(set (match_operand:DI 0 "move_dest_operand"
4345 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4346 (match_operand:DI 1 "move_src_operand"
4347 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4348 "(register_operand (operands[0], DImode)
4349 || reg_or_0_operand (operands[1], DImode))
4350 && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4351 "@
4352 ldd RT'%A1,%0
4353 copy %1,%0
4354 ldi %1,%0
4355 ldil L'%1,%0
4356 depdi,z %z1,%0
4357 ldd%M1 %1,%0
4358 std%M0 %r1,%0
4359 mtsar %r1
4360 {mfctl|mfctl,w} %%sar,%0
4361 fcpy,dbl %f1,%0
4362 fldd%F1 %1,%0
4363 fstd%F0 %1,%0"
4364 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4365 (set_attr "pa_combine_type" "addmove")
4366 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4367
4368 (define_insn ""
4369 [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4370 (match_operand:DI 1 "register_operand" "f"))]
4371 "!TARGET_SOFT_FLOAT
4372 && TARGET_64BIT
4373 && !TARGET_DISABLE_INDEXING
4374 && reload_completed"
4375 "fstd%F0 %1,%0"
4376 [(set_attr "type" "fpstore")
4377 (set_attr "pa_combine_type" "addmove")
4378 (set_attr "length" "4")])
4379
4380 (define_peephole2
4381 [(set (match_operand:DI 0 "register_operand" "")
4382 (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4383 (const_int 3))
4384 (match_operand:DI 2 "register_operand" "")))
4385 (set (mem:DI (match_dup 0))
4386 (match_operand:DI 3 "register_operand" ""))]
4387 "!TARGET_SOFT_FLOAT
4388 && !TARGET_DISABLE_INDEXING
4389 && TARGET_64BIT
4390 && REG_OK_FOR_BASE_P (operands[2])
4391 && FP_REGNO_P (REGNO (operands[3]))"
4392 [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4393 (match_dup 3))
4394 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4395 (match_dup 2)))]
4396 "")
4397
4398 (define_peephole2
4399 [(set (match_operand:DI 0 "register_operand" "")
4400 (plus:DI (match_operand:DI 1 "register_operand" "")
4401 (match_operand:DI 2 "register_operand" "")))
4402 (set (mem:DI (match_dup 0))
4403 (match_operand:DI 3 "register_operand" ""))]
4404 "!TARGET_SOFT_FLOAT
4405 && !TARGET_DISABLE_INDEXING
4406 && TARGET_64BIT
4407 && TARGET_NO_SPACE_REGS
4408 && REG_OK_FOR_INDEX_P (operands[1])
4409 && REG_OK_FOR_BASE_P (operands[2])
4410 && FP_REGNO_P (REGNO (operands[3]))"
4411 [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4412 (match_dup 3))
4413 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4414 "")
4415
4416 (define_peephole2
4417 [(set (match_operand:DI 0 "register_operand" "")
4418 (plus:DI (match_operand:DI 1 "register_operand" "")
4419 (match_operand:DI 2 "register_operand" "")))
4420 (set (mem:DI (match_dup 0))
4421 (match_operand:DI 3 "register_operand" ""))]
4422 "!TARGET_SOFT_FLOAT
4423 && !TARGET_DISABLE_INDEXING
4424 && TARGET_64BIT
4425 && TARGET_NO_SPACE_REGS
4426 && REG_OK_FOR_BASE_P (operands[1])
4427 && REG_OK_FOR_INDEX_P (operands[2])
4428 && FP_REGNO_P (REGNO (operands[3]))"
4429 [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4430 (match_dup 3))
4431 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4432 "")
4433
4434 (define_insn ""
4435 [(set (match_operand:DI 0 "move_dest_operand"
4436 "=r,o,Q,r,r,r")
4437 (match_operand:DI 1 "general_operand"
4438 "rM,r,r,o,Q,i"))]
4439 "(register_operand (operands[0], DImode)
4440 || reg_or_0_operand (operands[1], DImode))
4441 && !TARGET_64BIT
4442 && TARGET_SOFT_FLOAT"
4443 "*
4444 {
4445 return pa_output_move_double (operands);
4446 }"
4447 [(set_attr "type" "move,store,store,load,load,multi")
4448 (set_attr "length" "8,8,16,8,16,16")])
4449
4450 (define_insn ""
4451 [(set (match_operand:DI 0 "register_operand" "=r,&r")
4452 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4453 (match_operand:DI 2 "immediate_operand" "i,i")))]
4454 "!TARGET_64BIT"
4455 "*
4456 {
4457 /* Don't output a 64-bit constant, since we can't trust the assembler to
4458 handle it correctly. */
4459 if (GET_CODE (operands[2]) == CONST_DOUBLE)
4460 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4461 else if (HOST_BITS_PER_WIDE_INT > 32
4462 && GET_CODE (operands[2]) == CONST_INT)
4463 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4464 if (which_alternative == 1)
4465 output_asm_insn (\"copy %1,%0\", operands);
4466 return \"ldo R'%G2(%R1),%R0\";
4467 }"
4468 [(set_attr "type" "move,move")
4469 (set_attr "length" "4,8")])
4470
4471 (define_expand "movsf"
4472 [(set (match_operand:SF 0 "general_operand" "")
4473 (match_operand:SF 1 "general_operand" ""))]
4474 ""
4475 "
4476 {
4477 if (pa_emit_move_sequence (operands, SFmode, 0))
4478 DONE;
4479 }")
4480
4481 ;; Handle SFmode input reloads requiring %r1 as a scratch register.
4482 (define_expand "reload_insf_r1"
4483 [(set (match_operand:SF 0 "register_operand" "=Z")
4484 (match_operand:SF 1 "non_hard_reg_operand" ""))
4485 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4486 ""
4487 "
4488 {
4489 if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4490 DONE;
4491
4492 /* We don't want the clobber emitted, so handle this ourselves. */
4493 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4494 DONE;
4495 }")
4496
4497 ;; Handle SFmode input reloads requiring a general register as a
4498 ;; scratch register.
4499 (define_expand "reload_insf"
4500 [(set (match_operand:SF 0 "register_operand" "=Z")
4501 (match_operand:SF 1 "non_hard_reg_operand" ""))
4502 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4503 ""
4504 "
4505 {
4506 if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4507 DONE;
4508
4509 /* We don't want the clobber emitted, so handle this ourselves. */
4510 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4511 DONE;
4512 }")
4513
4514 ;; Handle SFmode output reloads requiring a general register as a
4515 ;; scratch register.
4516 (define_expand "reload_outsf"
4517 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4518 (match_operand:SF 1 "register_operand" "Z"))
4519 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4520 ""
4521 "
4522 {
4523 if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4524 DONE;
4525
4526 /* We don't want the clobber emitted, so handle this ourselves. */
4527 emit_insn (gen_rtx_SET (operands[0], operands[1]));
4528 DONE;
4529 }")
4530
4531 (define_insn ""
4532 [(set (match_operand:SF 0 "move_dest_operand"
4533 "=f,!*r,f,*r,T,Q,?*r,?f")
4534 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4535 "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4536 "(register_operand (operands[0], SFmode)
4537 || reg_or_0_operand (operands[1], SFmode))
4538 && !TARGET_SOFT_FLOAT
4539 && !TARGET_64BIT"
4540 "@
4541 fcpy,sgl %f1,%0
4542 copy %r1,%0
4543 fldw%F1 %1,%0
4544 ldw%M1 %1,%0
4545 fstw%F0 %1,%0
4546 stw%M0 %r1,%0
4547 {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4548 {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4549 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4550 (set_attr "pa_combine_type" "addmove")
4551 (set_attr "length" "4,4,4,4,4,4,8,8")])
4552
4553 (define_insn ""
4554 [(set (match_operand:SF 0 "move_dest_operand"
4555 "=f,!*r,f,*r,T,Q")
4556 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4557 "fG,!*rG,RT,RQ,f,*rG"))]
4558 "(register_operand (operands[0], SFmode)
4559 || reg_or_0_operand (operands[1], SFmode))
4560 && !TARGET_SOFT_FLOAT
4561 && TARGET_64BIT"
4562 "@
4563 fcpy,sgl %f1,%0
4564 copy %r1,%0
4565 fldw%F1 %1,%0
4566 ldw%M1 %1,%0
4567 fstw%F0 %1,%0
4568 stw%M0 %r1,%0"
4569 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4570 (set_attr "pa_combine_type" "addmove")
4571 (set_attr "length" "4,4,4,4,4,4")])
4572
4573 (define_insn ""
4574 [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4575 (match_operand:SF 1 "register_operand" "f"))]
4576 "!TARGET_SOFT_FLOAT
4577 && !TARGET_DISABLE_INDEXING
4578 && reload_completed"
4579 "fstw%F0 %1,%0"
4580 [(set_attr "type" "fpstore")
4581 (set_attr "pa_combine_type" "addmove")
4582 (set_attr "length" "4")])
4583
4584 (define_peephole2
4585 [(set (match_operand:SI 0 "register_operand" "")
4586 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4587 (const_int 2))
4588 (match_operand:SI 2 "register_operand" "")))
4589 (set (mem:SF (match_dup 0))
4590 (match_operand:SF 3 "register_operand" ""))]
4591 "!TARGET_SOFT_FLOAT
4592 && !TARGET_DISABLE_INDEXING
4593 && REG_OK_FOR_BASE_P (operands[2])
4594 && FP_REGNO_P (REGNO (operands[3]))"
4595 [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4596 (match_dup 3))
4597 (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4598 (match_dup 2)))]
4599 "")
4600
4601 (define_peephole2
4602 [(set (match_operand:DI 0 "register_operand" "")
4603 (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4604 (const_int 2))
4605 (match_operand:DI 2 "register_operand" "")))
4606 (set (mem:SF (match_dup 0))
4607 (match_operand:SF 3 "register_operand" ""))]
4608 "!TARGET_SOFT_FLOAT
4609 && !TARGET_DISABLE_INDEXING
4610 && TARGET_64BIT
4611 && REG_OK_FOR_BASE_P (operands[2])
4612 && FP_REGNO_P (REGNO (operands[3]))"
4613 [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4614 (match_dup 3))
4615 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4616 (match_dup 2)))]
4617 "")
4618
4619 (define_peephole2
4620 [(set (match_operand:SI 0 "register_operand" "")
4621 (plus:SI (match_operand:SI 1 "register_operand" "")
4622 (match_operand:SI 2 "register_operand" "")))
4623 (set (mem:SF (match_dup 0))
4624 (match_operand:SF 3 "register_operand" ""))]
4625 "!TARGET_SOFT_FLOAT
4626 && !TARGET_DISABLE_INDEXING
4627 && TARGET_NO_SPACE_REGS
4628 && REG_OK_FOR_INDEX_P (operands[1])
4629 && REG_OK_FOR_BASE_P (operands[2])
4630 && FP_REGNO_P (REGNO (operands[3]))"
4631 [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4632 (match_dup 3))
4633 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4634 "")
4635
4636 (define_peephole2
4637 [(set (match_operand:SI 0 "register_operand" "")
4638 (plus:SI (match_operand:SI 1 "register_operand" "")
4639 (match_operand:SI 2 "register_operand" "")))
4640 (set (mem:SF (match_dup 0))
4641 (match_operand:SF 3 "register_operand" ""))]
4642 "!TARGET_SOFT_FLOAT
4643 && !TARGET_DISABLE_INDEXING
4644 && TARGET_NO_SPACE_REGS
4645 && REG_OK_FOR_BASE_P (operands[1])
4646 && REG_OK_FOR_INDEX_P (operands[2])
4647 && FP_REGNO_P (REGNO (operands[3]))"
4648 [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4649 (match_dup 3))
4650 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4651 "")
4652
4653 (define_peephole2
4654 [(set (match_operand:DI 0 "register_operand" "")
4655 (plus:DI (match_operand:DI 1 "register_operand" "")
4656 (match_operand:DI 2 "register_operand" "")))
4657 (set (mem:SF (match_dup 0))
4658 (match_operand:SF 3 "register_operand" ""))]
4659 "!TARGET_SOFT_FLOAT
4660 && !TARGET_DISABLE_INDEXING
4661 && TARGET_64BIT
4662 && TARGET_NO_SPACE_REGS
4663 && REG_OK_FOR_INDEX_P (operands[1])
4664 && REG_OK_FOR_BASE_P (operands[2])
4665 && FP_REGNO_P (REGNO (operands[3]))"
4666 [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4667 (match_dup 3))
4668 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4669 "")
4670
4671 (define_peephole2
4672 [(set (match_operand:DI 0 "register_operand" "")
4673 (plus:DI (match_operand:DI 1 "register_operand" "")
4674 (match_operand:DI 2 "register_operand" "")))
4675 (set (mem:SF (match_dup 0))
4676 (match_operand:SF 3 "register_operand" ""))]
4677 "!TARGET_SOFT_FLOAT
4678 && !TARGET_DISABLE_INDEXING
4679 && TARGET_64BIT
4680 && TARGET_NO_SPACE_REGS
4681 && REG_OK_FOR_BASE_P (operands[1])
4682 && REG_OK_FOR_INDEX_P (operands[2])
4683 && FP_REGNO_P (REGNO (operands[3]))"
4684 [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4685 (match_dup 3))
4686 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4687 "")
4688
4689 (define_insn ""
4690 [(set (match_operand:SF 0 "move_dest_operand"
4691 "=r,r,Q")
4692 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4693 "rG,RQ,rG"))]
4694 "(register_operand (operands[0], SFmode)
4695 || reg_or_0_operand (operands[1], SFmode))
4696 && TARGET_SOFT_FLOAT"
4697 "@
4698 copy %r1,%0
4699 ldw%M1 %1,%0
4700 stw%M0 %r1,%0"
4701 [(set_attr "type" "move,load,store")
4702 (set_attr "pa_combine_type" "addmove")
4703 (set_attr "length" "4,4,4")])
4704
4705 \f
4706
4707 ;;- zero extension instructions
4708 ;; We have define_expand for zero extension patterns to make sure the
4709 ;; operands get loaded into registers. The define_insns accept
4710 ;; memory operands. This gives us better overall code than just
4711 ;; having a pattern that does or does not accept memory operands.
4712
4713 (define_expand "zero_extendqihi2"
4714 [(set (match_operand:HI 0 "register_operand" "")
4715 (zero_extend:HI
4716 (match_operand:QI 1 "register_operand" "")))]
4717 ""
4718 "")
4719
4720 (define_insn ""
4721 [(set (match_operand:HI 0 "register_operand" "=r,r")
4722 (zero_extend:HI
4723 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4724 "GET_CODE (operands[1]) != CONST_INT"
4725 "@
4726 {extru|extrw,u} %1,31,8,%0
4727 ldb%M1 %1,%0"
4728 [(set_attr "type" "shift,load")
4729 (set_attr "length" "4,4")])
4730
4731 (define_expand "zero_extendqisi2"
4732 [(set (match_operand:SI 0 "register_operand" "")
4733 (zero_extend:SI
4734 (match_operand:QI 1 "register_operand" "")))]
4735 ""
4736 "")
4737
4738 (define_insn ""
4739 [(set (match_operand:SI 0 "register_operand" "=r,r")
4740 (zero_extend:SI
4741 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4742 "GET_CODE (operands[1]) != CONST_INT"
4743 "@
4744 {extru|extrw,u} %1,31,8,%0
4745 ldb%M1 %1,%0"
4746 [(set_attr "type" "shift,load")
4747 (set_attr "length" "4,4")])
4748
4749 (define_expand "zero_extendhisi2"
4750 [(set (match_operand:SI 0 "register_operand" "")
4751 (zero_extend:SI
4752 (match_operand:HI 1 "register_operand" "")))]
4753 ""
4754 "")
4755
4756 (define_insn ""
4757 [(set (match_operand:SI 0 "register_operand" "=r,r")
4758 (zero_extend:SI
4759 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4760 "GET_CODE (operands[1]) != CONST_INT"
4761 "@
4762 {extru|extrw,u} %1,31,16,%0
4763 ldh%M1 %1,%0"
4764 [(set_attr "type" "shift,load")
4765 (set_attr "length" "4,4")])
4766
4767 (define_expand "zero_extendqidi2"
4768 [(set (match_operand:DI 0 "register_operand" "")
4769 (zero_extend:DI
4770 (match_operand:QI 1 "register_operand" "")))]
4771 "TARGET_64BIT"
4772 "")
4773
4774 (define_insn ""
4775 [(set (match_operand:DI 0 "register_operand" "=r,r")
4776 (zero_extend:DI
4777 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4778 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4779 "@
4780 extrd,u %1,63,8,%0
4781 ldb%M1 %1,%0"
4782 [(set_attr "type" "shift,load")
4783 (set_attr "length" "4,4")])
4784
4785 (define_expand "zero_extendhidi2"
4786 [(set (match_operand:DI 0 "register_operand" "")
4787 (zero_extend:DI
4788 (match_operand:HI 1 "register_operand" "")))]
4789 "TARGET_64BIT"
4790 "")
4791
4792 (define_insn ""
4793 [(set (match_operand:DI 0 "register_operand" "=r,r")
4794 (zero_extend:DI
4795 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4796 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4797 "@
4798 extrd,u %1,63,16,%0
4799 ldh%M1 %1,%0"
4800 [(set_attr "type" "shift,load")
4801 (set_attr "length" "4,4")])
4802
4803 (define_expand "zero_extendsidi2"
4804 [(set (match_operand:DI 0 "register_operand" "")
4805 (zero_extend:DI
4806 (match_operand:SI 1 "register_operand" "")))]
4807 "TARGET_64BIT"
4808 "")
4809
4810 (define_insn ""
4811 [(set (match_operand:DI 0 "register_operand" "=r,r")
4812 (zero_extend:DI
4813 (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4814 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4815 "@
4816 extrd,u %1,63,32,%0
4817 ldw%M1 %1,%0"
4818 [(set_attr "type" "shift,load")
4819 (set_attr "length" "4,4")])
4820
4821 ;;- sign extension instructions
4822
4823 (define_insn "extendhisi2"
4824 [(set (match_operand:SI 0 "register_operand" "=r")
4825 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4826 ""
4827 "{extrs|extrw,s} %1,31,16,%0"
4828 [(set_attr "type" "shift")
4829 (set_attr "length" "4")])
4830
4831 (define_insn "extendqihi2"
4832 [(set (match_operand:HI 0 "register_operand" "=r")
4833 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4834 ""
4835 "{extrs|extrw,s} %1,31,8,%0"
4836 [(set_attr "type" "shift")
4837 (set_attr "length" "4")])
4838
4839 (define_insn "extendqisi2"
4840 [(set (match_operand:SI 0 "register_operand" "=r")
4841 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4842 ""
4843 "{extrs|extrw,s} %1,31,8,%0"
4844 [(set_attr "type" "shift")
4845 (set_attr "length" "4")])
4846
4847 (define_insn "extendqidi2"
4848 [(set (match_operand:DI 0 "register_operand" "=r")
4849 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4850 "TARGET_64BIT"
4851 "extrd,s %1,63,8,%0"
4852 [(set_attr "type" "shift")
4853 (set_attr "length" "4")])
4854
4855 (define_insn "extendhidi2"
4856 [(set (match_operand:DI 0 "register_operand" "=r")
4857 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4858 "TARGET_64BIT"
4859 "extrd,s %1,63,16,%0"
4860 [(set_attr "type" "shift")
4861 (set_attr "length" "4")])
4862
4863 (define_insn "extendsidi2"
4864 [(set (match_operand:DI 0 "register_operand" "=r")
4865 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4866 "TARGET_64BIT"
4867 "extrd,s %1,63,32,%0"
4868 [(set_attr "type" "shift")
4869 (set_attr "length" "4")])
4870
4871 \f
4872 ;; Conversions between float and double.
4873
4874 (define_insn "extendsfdf2"
4875 [(set (match_operand:DF 0 "register_operand" "=f")
4876 (float_extend:DF
4877 (match_operand:SF 1 "register_operand" "f")))]
4878 "! TARGET_SOFT_FLOAT"
4879 "{fcnvff|fcnv},sgl,dbl %1,%0"
4880 [(set_attr "type" "fpalu")
4881 (set_attr "length" "4")])
4882
4883 (define_insn "truncdfsf2"
4884 [(set (match_operand:SF 0 "register_operand" "=f")
4885 (float_truncate:SF
4886 (match_operand:DF 1 "register_operand" "f")))]
4887 "! TARGET_SOFT_FLOAT"
4888 "{fcnvff|fcnv},dbl,sgl %1,%0"
4889 [(set_attr "type" "fpalu")
4890 (set_attr "length" "4")])
4891
4892 ;; Conversion between fixed point and floating point.
4893 ;; Note that among the fix-to-float insns
4894 ;; the ones that start with SImode come first.
4895 ;; That is so that an operand that is a CONST_INT
4896 ;; (and therefore lacks a specific machine mode).
4897 ;; will be recognized as SImode (which is always valid)
4898 ;; rather than as QImode or HImode.
4899
4900 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4901 ;; to be reloaded by putting the constant into memory.
4902 ;; It must come before the more general floatsisf2 pattern.
4903 (define_insn ""
4904 [(set (match_operand:SF 0 "register_operand" "=f")
4905 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4906 "! TARGET_SOFT_FLOAT"
4907 "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4908 [(set_attr "type" "fpalu")
4909 (set_attr "length" "8")])
4910
4911 (define_insn "floatsisf2"
4912 [(set (match_operand:SF 0 "register_operand" "=f")
4913 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4914 "! TARGET_SOFT_FLOAT"
4915 "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4916 [(set_attr "type" "fpalu")
4917 (set_attr "length" "4")])
4918
4919 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4920 ;; to be reloaded by putting the constant into memory.
4921 ;; It must come before the more general floatsidf2 pattern.
4922 (define_insn ""
4923 [(set (match_operand:DF 0 "register_operand" "=f")
4924 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4925 "! TARGET_SOFT_FLOAT"
4926 "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4927 [(set_attr "type" "fpalu")
4928 (set_attr "length" "8")])
4929
4930 (define_insn "floatsidf2"
4931 [(set (match_operand:DF 0 "register_operand" "=f")
4932 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4933 "! TARGET_SOFT_FLOAT"
4934 "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4935 [(set_attr "type" "fpalu")
4936 (set_attr "length" "4")])
4937
4938 (define_expand "floatunssisf2"
4939 [(set (subreg:SI (match_dup 2) 4)
4940 (match_operand:SI 1 "register_operand" ""))
4941 (set (subreg:SI (match_dup 2) 0)
4942 (const_int 0))
4943 (set (match_operand:SF 0 "register_operand" "")
4944 (float:SF (match_dup 2)))]
4945 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4946 "
4947 {
4948 if (TARGET_PA_20)
4949 {
4950 emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4951 DONE;
4952 }
4953 operands[2] = gen_reg_rtx (DImode);
4954 }")
4955
4956 (define_expand "floatunssidf2"
4957 [(set (subreg:SI (match_dup 2) 4)
4958 (match_operand:SI 1 "register_operand" ""))
4959 (set (subreg:SI (match_dup 2) 0)
4960 (const_int 0))
4961 (set (match_operand:DF 0 "register_operand" "")
4962 (float:DF (match_dup 2)))]
4963 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4964 "
4965 {
4966 if (TARGET_PA_20)
4967 {
4968 emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4969 DONE;
4970 }
4971 operands[2] = gen_reg_rtx (DImode);
4972 }")
4973
4974 (define_insn "floatdisf2"
4975 [(set (match_operand:SF 0 "register_operand" "=f")
4976 (float:SF (match_operand:DI 1 "register_operand" "f")))]
4977 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4978 "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4979 [(set_attr "type" "fpalu")
4980 (set_attr "length" "4")])
4981
4982 (define_insn "floatdidf2"
4983 [(set (match_operand:DF 0 "register_operand" "=f")
4984 (float:DF (match_operand:DI 1 "register_operand" "f")))]
4985 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4986 "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4987 [(set_attr "type" "fpalu")
4988 (set_attr "length" "4")])
4989
4990 ;; Convert a float to an actual integer.
4991 ;; Truncation is performed as part of the conversion.
4992
4993 (define_insn "fix_truncsfsi2"
4994 [(set (match_operand:SI 0 "register_operand" "=f")
4995 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4996 "! TARGET_SOFT_FLOAT"
4997 "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4998 [(set_attr "type" "fpalu")
4999 (set_attr "length" "4")])
5000
5001 (define_insn "fix_truncdfsi2"
5002 [(set (match_operand:SI 0 "register_operand" "=f")
5003 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5004 "! TARGET_SOFT_FLOAT"
5005 "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
5006 [(set_attr "type" "fpalu")
5007 (set_attr "length" "4")])
5008
5009 (define_insn "fix_truncsfdi2"
5010 [(set (match_operand:DI 0 "register_operand" "=f")
5011 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5012 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
5013 "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
5014 [(set_attr "type" "fpalu")
5015 (set_attr "length" "4")])
5016
5017 (define_insn "fix_truncdfdi2"
5018 [(set (match_operand:DI 0 "register_operand" "=f")
5019 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5020 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
5021 "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
5022 [(set_attr "type" "fpalu")
5023 (set_attr "length" "4")])
5024
5025 (define_insn "floatunssidf2_pa20"
5026 [(set (match_operand:DF 0 "register_operand" "=f")
5027 (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
5028 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5029 "fcnv,uw,dbl %1,%0"
5030 [(set_attr "type" "fpalu")
5031 (set_attr "length" "4")])
5032
5033 (define_insn "floatunssisf2_pa20"
5034 [(set (match_operand:SF 0 "register_operand" "=f")
5035 (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
5036 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5037 "fcnv,uw,sgl %1,%0"
5038 [(set_attr "type" "fpalu")
5039 (set_attr "length" "4")])
5040
5041 (define_insn "floatunsdisf2"
5042 [(set (match_operand:SF 0 "register_operand" "=f")
5043 (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
5044 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5045 "fcnv,udw,sgl %1,%0"
5046 [(set_attr "type" "fpalu")
5047 (set_attr "length" "4")])
5048
5049 (define_insn "floatunsdidf2"
5050 [(set (match_operand:DF 0 "register_operand" "=f")
5051 (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
5052 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5053 "fcnv,udw,dbl %1,%0"
5054 [(set_attr "type" "fpalu")
5055 (set_attr "length" "4")])
5056
5057 (define_insn "fixuns_truncsfsi2"
5058 [(set (match_operand:SI 0 "register_operand" "=f")
5059 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5060 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5061 "fcnv,t,sgl,uw %1,%0"
5062 [(set_attr "type" "fpalu")
5063 (set_attr "length" "4")])
5064
5065 (define_insn "fixuns_truncdfsi2"
5066 [(set (match_operand:SI 0 "register_operand" "=f")
5067 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5068 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5069 "fcnv,t,dbl,uw %1,%0"
5070 [(set_attr "type" "fpalu")
5071 (set_attr "length" "4")])
5072
5073 (define_insn "fixuns_truncsfdi2"
5074 [(set (match_operand:DI 0 "register_operand" "=f")
5075 (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5076 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5077 "fcnv,t,sgl,udw %1,%0"
5078 [(set_attr "type" "fpalu")
5079 (set_attr "length" "4")])
5080
5081 (define_insn "fixuns_truncdfdi2"
5082 [(set (match_operand:DI 0 "register_operand" "=f")
5083 (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5084 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5085 "fcnv,t,dbl,udw %1,%0"
5086 [(set_attr "type" "fpalu")
5087 (set_attr "length" "4")])
5088 \f
5089 ;;- arithmetic instructions
5090
5091 (define_expand "adddi3"
5092 [(set (match_operand:DI 0 "register_operand" "")
5093 (plus:DI (match_operand:DI 1 "register_operand" "")
5094 (match_operand:DI 2 "adddi3_operand" "")))]
5095 ""
5096 "")
5097
5098 (define_insn ""
5099 [(set (match_operand:DI 0 "register_operand" "=r")
5100 (plus:DI (match_operand:DI 1 "register_operand" "%r")
5101 (match_operand:DI 2 "arith11_operand" "rI")))]
5102 "!TARGET_64BIT"
5103 "*
5104 {
5105 if (GET_CODE (operands[2]) == CONST_INT)
5106 {
5107 if (INTVAL (operands[2]) >= 0)
5108 return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5109 else
5110 return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5111 }
5112 else
5113 return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5114 }"
5115 [(set_attr "type" "binary")
5116 (set_attr "length" "8")])
5117
5118 (define_insn ""
5119 [(set (match_operand:DI 0 "register_operand" "=r,r")
5120 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5121 (match_operand:DI 2 "arith14_operand" "r,J")))]
5122 "TARGET_64BIT"
5123 "@
5124 add,l %1,%2,%0
5125 ldo %2(%1),%0"
5126 [(set_attr "type" "binary,binary")
5127 (set_attr "pa_combine_type" "addmove")
5128 (set_attr "length" "4,4")])
5129
5130 (define_insn ""
5131 [(set (match_operand:DI 0 "register_operand" "=r")
5132 (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5133 (match_operand:DI 2 "register_operand" "r")))]
5134 "TARGET_64BIT"
5135 "uaddcm %2,%1,%0"
5136 [(set_attr "type" "binary")
5137 (set_attr "length" "4")])
5138
5139 (define_insn ""
5140 [(set (match_operand:SI 0 "register_operand" "=r")
5141 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5142 (match_operand:SI 2 "register_operand" "r")))]
5143 ""
5144 "uaddcm %2,%1,%0"
5145 [(set_attr "type" "binary")
5146 (set_attr "length" "4")])
5147
5148 (define_expand "addvdi3"
5149 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5150 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5151 (match_operand:DI 2 "arith11_operand" "")))
5152 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5153 (sign_extend:TI (match_dup 2)))
5154 (sign_extend:TI (plus:DI (match_dup 1)
5155 (match_dup 2))))
5156 (const_int 0))])]
5157 ""
5158 "")
5159
5160 (define_insn ""
5161 [(set (match_operand:DI 0 "register_operand" "=r,r")
5162 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
5163 (match_operand:DI 2 "arith11_operand" "r,I")))
5164 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5165 (sign_extend:TI (match_dup 2)))
5166 (sign_extend:TI (plus:DI (match_dup 1)
5167 (match_dup 2))))
5168 (const_int 0))]
5169 "TARGET_64BIT"
5170 "@
5171 add,tsv,* %2,%1,%0
5172 addi,tsv,* %2,%1,%0"
5173 [(set_attr "type" "binary,binary")
5174 (set_attr "length" "4,4")])
5175
5176 (define_insn ""
5177 [(set (match_operand:DI 0 "register_operand" "=r")
5178 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5179 (match_operand:DI 2 "arith11_operand" "rI")))
5180 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5181 (sign_extend:TI (match_dup 2)))
5182 (sign_extend:TI (plus:DI (match_dup 1)
5183 (match_dup 2))))
5184 (const_int 0))]
5185 "!TARGET_64BIT"
5186 "*
5187 {
5188 if (GET_CODE (operands[2]) == CONST_INT)
5189 {
5190 if (INTVAL (operands[2]) >= 0)
5191 return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5192 else
5193 return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5194 }
5195 else
5196 return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5197 }"
5198 [(set_attr "type" "binary")
5199 (set_attr "length" "8")])
5200
5201 ;; define_splits to optimize cases of adding a constant integer
5202 ;; to a register when the constant does not fit in 14 bits. */
5203 (define_split
5204 [(set (match_operand:SI 0 "register_operand" "")
5205 (plus:SI (match_operand:SI 1 "register_operand" "")
5206 (match_operand:SI 2 "const_int_operand" "")))
5207 (clobber (match_operand:SI 4 "register_operand" ""))]
5208 "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5209 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5210 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5211 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5212 "
5213 {
5214 int val = INTVAL (operands[2]);
5215 int low = (val < 0) ? -0x2000 : 0x1fff;
5216 int rest = val - low;
5217
5218 operands[2] = GEN_INT (rest);
5219 operands[3] = GEN_INT (low);
5220 }")
5221
5222 (define_split
5223 [(set (match_operand:SI 0 "register_operand" "")
5224 (plus:SI (match_operand:SI 1 "register_operand" "")
5225 (match_operand:SI 2 "const_int_operand" "")))
5226 (clobber (match_operand:SI 4 "register_operand" ""))]
5227 "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5228 [(set (match_dup 4) (match_dup 2))
5229 (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5230 (match_dup 1)))]
5231 "
5232 {
5233 unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5234
5235 /* Try dividing the constant by 2, then 4, and finally 8 to see
5236 if we can get a constant which can be loaded into a register
5237 in a single instruction (pa_cint_ok_for_move).
5238
5239 If that fails, try to negate the constant and subtract it
5240 from our input operand. */
5241 if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5242 {
5243 operands[2] = GEN_INT (intval / 2);
5244 operands[3] = const1_rtx;
5245 }
5246 else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5247 {
5248 operands[2] = GEN_INT (intval / 4);
5249 operands[3] = const2_rtx;
5250 }
5251 else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5252 {
5253 operands[2] = GEN_INT (intval / 8);
5254 operands[3] = GEN_INT (3);
5255 }
5256 else if (pa_cint_ok_for_move (-intval))
5257 {
5258 emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5259 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5260 DONE;
5261 }
5262 else
5263 FAIL;
5264 }")
5265
5266 (define_insn "addsi3"
5267 [(set (match_operand:SI 0 "register_operand" "=r,r")
5268 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5269 (match_operand:SI 2 "arith14_operand" "r,J")))]
5270 ""
5271 "@
5272 {addl|add,l} %1,%2,%0
5273 ldo %2(%1),%0"
5274 [(set_attr "type" "binary,binary")
5275 (set_attr "pa_combine_type" "addmove")
5276 (set_attr "length" "4,4")])
5277
5278 (define_insn "addvsi3"
5279 [(set (match_operand:SI 0 "register_operand" "=r,r")
5280 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5281 (match_operand:SI 2 "arith11_operand" "r,I")))
5282 (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5283 (sign_extend:DI (match_dup 2)))
5284 (sign_extend:DI (plus:SI (match_dup 1)
5285 (match_dup 2))))
5286 (const_int 0))]
5287 ""
5288 "@
5289 {addo|add,tsv} %2,%1,%0
5290 {addio|addi,tsv} %2,%1,%0"
5291 [(set_attr "type" "binary,binary")
5292 (set_attr "length" "4,4")])
5293
5294 (define_expand "subdi3"
5295 [(set (match_operand:DI 0 "register_operand" "")
5296 (minus:DI (match_operand:DI 1 "arith11_operand" "")
5297 (match_operand:DI 2 "reg_or_0_operand" "")))]
5298 ""
5299 "")
5300
5301 (define_insn ""
5302 [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5303 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5304 (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5305 "TARGET_64BIT"
5306 "@
5307 sub %1,%2,%0
5308 subi %1,%2,%0
5309 mtsarcm %2"
5310 [(set_attr "type" "binary,binary,move")
5311 (set_attr "length" "4,4,4")])
5312
5313 (define_insn ""
5314 [(set (match_operand:DI 0 "register_operand" "=r,&r")
5315 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5316 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5317 "!TARGET_64BIT"
5318 "*
5319 {
5320 if (GET_CODE (operands[1]) == CONST_INT)
5321 {
5322 if (INTVAL (operands[1]) >= 0)
5323 return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5324 else
5325 return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5326 }
5327 else
5328 return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5329 }"
5330 [(set_attr "type" "binary")
5331 (set (attr "length")
5332 (if_then_else (eq_attr "alternative" "0")
5333 (const_int 8)
5334 (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5335 (const_int 0))
5336 (const_int 8)
5337 (const_int 12))))])
5338
5339 (define_expand "subvdi3"
5340 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5341 (minus:DI (match_operand:DI 1 "arith11_operand" "")
5342 (match_operand:DI 2 "reg_or_0_operand" "")))
5343 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5344 (sign_extend:TI (match_dup 2)))
5345 (sign_extend:TI (minus:DI (match_dup 1)
5346 (match_dup 2))))
5347 (const_int 0))])]
5348 ""
5349 "")
5350
5351 (define_insn ""
5352 [(set (match_operand:DI 0 "register_operand" "=r,r")
5353 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5354 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5355 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5356 (sign_extend:TI (match_dup 2)))
5357 (sign_extend:TI (minus:DI (match_dup 1)
5358 (match_dup 2))))
5359 (const_int 0))]
5360 "TARGET_64BIT"
5361 "@
5362 {subo|sub,tsv} %1,%2,%0
5363 {subio|subi,tsv} %1,%2,%0"
5364 [(set_attr "type" "binary,binary")
5365 (set_attr "length" "4,4")])
5366
5367 (define_insn ""
5368 [(set (match_operand:DI 0 "register_operand" "=r,&r")
5369 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5370 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5371 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5372 (sign_extend:TI (match_dup 2)))
5373 (sign_extend:TI (minus:DI (match_dup 1)
5374 (match_dup 2))))
5375 (const_int 0))]
5376 "!TARGET_64BIT"
5377 "*
5378 {
5379 if (GET_CODE (operands[1]) == CONST_INT)
5380 {
5381 if (INTVAL (operands[1]) >= 0)
5382 return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5383 else
5384 return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5385 }
5386 else
5387 return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5388 }"
5389 [(set_attr "type" "binary,binary")
5390 (set (attr "length")
5391 (if_then_else (eq_attr "alternative" "0")
5392 (const_int 8)
5393 (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5394 (const_int 0))
5395 (const_int 8)
5396 (const_int 12))))])
5397
5398 (define_expand "subsi3"
5399 [(set (match_operand:SI 0 "register_operand" "")
5400 (minus:SI (match_operand:SI 1 "arith11_operand" "")
5401 (match_operand:SI 2 "register_operand" "")))]
5402 ""
5403 "")
5404
5405 (define_insn ""
5406 [(set (match_operand:SI 0 "register_operand" "=r,r")
5407 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5408 (match_operand:SI 2 "register_operand" "r,r")))]
5409 "!TARGET_PA_20"
5410 "@
5411 sub %1,%2,%0
5412 subi %1,%2,%0"
5413 [(set_attr "type" "binary,binary")
5414 (set_attr "length" "4,4")])
5415
5416 (define_insn ""
5417 [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5418 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5419 (match_operand:SI 2 "register_operand" "r,r,!r")))]
5420 "TARGET_PA_20"
5421 "@
5422 sub %1,%2,%0
5423 subi %1,%2,%0
5424 mtsarcm %2"
5425 [(set_attr "type" "binary,binary,move")
5426 (set_attr "length" "4,4,4")])
5427
5428 (define_insn "subvsi3"
5429 [(set (match_operand:SI 0 "register_operand" "=r,r")
5430 (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5431 (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5432 (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5433 (sign_extend:DI (match_dup 2)))
5434 (sign_extend:DI (minus:SI (match_dup 1)
5435 (match_dup 2))))
5436 (const_int 0))]
5437 ""
5438 "@
5439 {subo|sub,tsv} %1,%2,%0
5440 {subio|subi,tsv} %1,%2,%0"
5441 [(set_attr "type" "binary,binary")
5442 (set_attr "length" "4,4")])
5443
5444 ;; Trap instructions.
5445
5446 (define_insn "trap"
5447 [(trap_if (const_int 1) (const_int 0))]
5448 ""
5449 "{addit|addi,tc},<> 1,%%r0,%%r0"
5450 [(set_attr "type" "trap")
5451 (set_attr "length" "4")])
5452
5453 ;; Clobbering a "register_operand" instead of a match_scratch
5454 ;; in operand3 of millicode calls avoids spilling %r1 and
5455 ;; produces better code.
5456
5457 ;; The mulsi3 insns set up registers for the millicode call.
5458 (define_expand "mulsi3"
5459 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5460 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5461 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5462 (clobber (match_dup 3))
5463 (clobber (reg:SI 26))
5464 (clobber (reg:SI 25))
5465 (clobber (match_dup 4))])
5466 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5467 ""
5468 "
5469 {
5470 operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5471 if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5472 {
5473 rtx scratch = gen_reg_rtx (DImode);
5474 operands[1] = force_reg (SImode, operands[1]);
5475 operands[2] = force_reg (SImode, operands[2]);
5476 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5477 emit_insn (gen_movsi (operands[0],
5478 gen_rtx_SUBREG (SImode, scratch,
5479 GET_MODE_SIZE (SImode))));
5480 DONE;
5481 }
5482 operands[3] = gen_reg_rtx (SImode);
5483 }")
5484
5485 (define_insn "umulsidi3"
5486 [(set (match_operand:DI 0 "register_operand" "=f")
5487 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5488 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
5489 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5490 "xmpyu %1,%2,%0"
5491 [(set_attr "type" "fpmuldbl")
5492 (set_attr "length" "4")])
5493
5494 (define_insn ""
5495 [(set (match_operand:DI 0 "register_operand" "=f")
5496 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5497 (match_operand:DI 2 "uint32_operand" "f")))]
5498 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5499 "xmpyu %1,%R2,%0"
5500 [(set_attr "type" "fpmuldbl")
5501 (set_attr "length" "4")])
5502
5503 (define_insn ""
5504 [(set (match_operand:DI 0 "register_operand" "=f")
5505 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5506 (match_operand:DI 2 "uint32_operand" "f")))]
5507 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5508 "xmpyu %1,%2R,%0"
5509 [(set_attr "type" "fpmuldbl")
5510 (set_attr "length" "4")])
5511
5512 (define_insn ""
5513 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5514 (clobber (match_operand:SI 0 "register_operand" "=a"))
5515 (clobber (reg:SI 26))
5516 (clobber (reg:SI 25))
5517 (clobber (reg:SI 31))]
5518 "!TARGET_64BIT"
5519 "* return pa_output_mul_insn (0, insn);"
5520 [(set_attr "type" "milli")
5521 (set (attr "length")
5522 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5523 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5524
5525 (define_insn ""
5526 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5527 (clobber (match_operand:SI 0 "register_operand" "=a"))
5528 (clobber (reg:SI 26))
5529 (clobber (reg:SI 25))
5530 (clobber (reg:SI 2))]
5531 "TARGET_64BIT"
5532 "* return pa_output_mul_insn (0, insn);"
5533 [(set_attr "type" "milli")
5534 (set (attr "length")
5535 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5536 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5537
5538 (define_expand "muldi3"
5539 [(set (match_operand:DI 0 "register_operand" "")
5540 (mult:DI (match_operand:DI 1 "register_operand" "")
5541 (match_operand:DI 2 "register_operand" "")))]
5542 "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5543 "
5544 {
5545 rtx low_product = gen_reg_rtx (DImode);
5546 rtx cross_product1 = gen_reg_rtx (DImode);
5547 rtx cross_product2 = gen_reg_rtx (DImode);
5548 rtx cross_scratch = gen_reg_rtx (DImode);
5549 rtx cross_product = gen_reg_rtx (DImode);
5550 rtx op1l, op1r, op2l, op2r;
5551 rtx op1shifted, op2shifted;
5552
5553 op1shifted = gen_reg_rtx (DImode);
5554 op2shifted = gen_reg_rtx (DImode);
5555 op1l = gen_reg_rtx (SImode);
5556 op1r = gen_reg_rtx (SImode);
5557 op2l = gen_reg_rtx (SImode);
5558 op2r = gen_reg_rtx (SImode);
5559
5560 emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5561 GEN_INT (32)));
5562 emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5563 GEN_INT (32)));
5564 op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5565 op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5566 op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5567 op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5568
5569 /* Emit multiplies for the cross products. */
5570 emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5571 emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5572
5573 /* Emit a multiply for the low sub-word. */
5574 emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5575
5576 /* Sum the cross products and shift them into proper position. */
5577 emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5578 emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5579
5580 /* Add the cross product to the low product and store the result
5581 into the output operand . */
5582 emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5583 DONE;
5584 }")
5585
5586 ;;; Division and mod.
5587 (define_expand "divsi3"
5588 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5589 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5590 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5591 (clobber (match_dup 3))
5592 (clobber (match_dup 4))
5593 (clobber (reg:SI 26))
5594 (clobber (reg:SI 25))
5595 (clobber (match_dup 5))])
5596 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5597 ""
5598 "
5599 {
5600 operands[3] = gen_reg_rtx (SImode);
5601 if (TARGET_64BIT)
5602 {
5603 operands[5] = gen_rtx_REG (SImode, 2);
5604 operands[4] = operands[5];
5605 }
5606 else
5607 {
5608 operands[5] = gen_rtx_REG (SImode, 31);
5609 operands[4] = gen_reg_rtx (SImode);
5610 }
5611 if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5612 DONE;
5613 }")
5614
5615 (define_insn ""
5616 [(set (reg:SI 29)
5617 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5618 (clobber (match_operand:SI 1 "register_operand" "=a"))
5619 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5620 (clobber (reg:SI 26))
5621 (clobber (reg:SI 25))
5622 (clobber (reg:SI 31))]
5623 "!TARGET_64BIT"
5624 "*
5625 return pa_output_div_insn (operands, 0, insn);"
5626 [(set_attr "type" "milli")
5627 (set (attr "length")
5628 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5629 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5630
5631 (define_insn ""
5632 [(set (reg:SI 29)
5633 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5634 (clobber (match_operand:SI 1 "register_operand" "=a"))
5635 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5636 (clobber (reg:SI 26))
5637 (clobber (reg:SI 25))
5638 (clobber (reg:SI 2))]
5639 "TARGET_64BIT"
5640 "*
5641 return pa_output_div_insn (operands, 0, insn);"
5642 [(set_attr "type" "milli")
5643 (set (attr "length")
5644 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5645 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5646
5647 (define_expand "udivsi3"
5648 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5649 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5650 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5651 (clobber (match_dup 3))
5652 (clobber (match_dup 4))
5653 (clobber (reg:SI 26))
5654 (clobber (reg:SI 25))
5655 (clobber (match_dup 5))])
5656 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5657 ""
5658 "
5659 {
5660 operands[3] = gen_reg_rtx (SImode);
5661
5662 if (TARGET_64BIT)
5663 {
5664 operands[5] = gen_rtx_REG (SImode, 2);
5665 operands[4] = operands[5];
5666 }
5667 else
5668 {
5669 operands[5] = gen_rtx_REG (SImode, 31);
5670 operands[4] = gen_reg_rtx (SImode);
5671 }
5672 if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5673 DONE;
5674 }")
5675
5676 (define_insn ""
5677 [(set (reg:SI 29)
5678 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5679 (clobber (match_operand:SI 1 "register_operand" "=a"))
5680 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5681 (clobber (reg:SI 26))
5682 (clobber (reg:SI 25))
5683 (clobber (reg:SI 31))]
5684 "!TARGET_64BIT"
5685 "*
5686 return pa_output_div_insn (operands, 1, insn);"
5687 [(set_attr "type" "milli")
5688 (set (attr "length")
5689 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5690 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5691
5692 (define_insn ""
5693 [(set (reg:SI 29)
5694 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5695 (clobber (match_operand:SI 1 "register_operand" "=a"))
5696 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5697 (clobber (reg:SI 26))
5698 (clobber (reg:SI 25))
5699 (clobber (reg:SI 2))]
5700 "TARGET_64BIT"
5701 "*
5702 return pa_output_div_insn (operands, 1, insn);"
5703 [(set_attr "type" "milli")
5704 (set (attr "length")
5705 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5706 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5707
5708 (define_expand "modsi3"
5709 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5710 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5711 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5712 (clobber (match_dup 3))
5713 (clobber (match_dup 4))
5714 (clobber (reg:SI 26))
5715 (clobber (reg:SI 25))
5716 (clobber (match_dup 5))])
5717 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5718 ""
5719 "
5720 {
5721 if (TARGET_64BIT)
5722 {
5723 operands[5] = gen_rtx_REG (SImode, 2);
5724 operands[4] = operands[5];
5725 }
5726 else
5727 {
5728 operands[5] = gen_rtx_REG (SImode, 31);
5729 operands[4] = gen_reg_rtx (SImode);
5730 }
5731 operands[3] = gen_reg_rtx (SImode);
5732 }")
5733
5734 (define_insn ""
5735 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5736 (clobber (match_operand:SI 0 "register_operand" "=a"))
5737 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5738 (clobber (reg:SI 26))
5739 (clobber (reg:SI 25))
5740 (clobber (reg:SI 31))]
5741 "!TARGET_64BIT"
5742 "*
5743 return pa_output_mod_insn (0, insn);"
5744 [(set_attr "type" "milli")
5745 (set (attr "length")
5746 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5747 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5748
5749 (define_insn ""
5750 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5751 (clobber (match_operand:SI 0 "register_operand" "=a"))
5752 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5753 (clobber (reg:SI 26))
5754 (clobber (reg:SI 25))
5755 (clobber (reg:SI 2))]
5756 "TARGET_64BIT"
5757 "*
5758 return pa_output_mod_insn (0, insn);"
5759 [(set_attr "type" "milli")
5760 (set (attr "length")
5761 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5762 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5763
5764 (define_expand "umodsi3"
5765 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5766 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5767 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5768 (clobber (match_dup 3))
5769 (clobber (match_dup 4))
5770 (clobber (reg:SI 26))
5771 (clobber (reg:SI 25))
5772 (clobber (match_dup 5))])
5773 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5774 ""
5775 "
5776 {
5777 if (TARGET_64BIT)
5778 {
5779 operands[5] = gen_rtx_REG (SImode, 2);
5780 operands[4] = operands[5];
5781 }
5782 else
5783 {
5784 operands[5] = gen_rtx_REG (SImode, 31);
5785 operands[4] = gen_reg_rtx (SImode);
5786 }
5787 operands[3] = gen_reg_rtx (SImode);
5788 }")
5789
5790 (define_insn ""
5791 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5792 (clobber (match_operand:SI 0 "register_operand" "=a"))
5793 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5794 (clobber (reg:SI 26))
5795 (clobber (reg:SI 25))
5796 (clobber (reg:SI 31))]
5797 "!TARGET_64BIT"
5798 "*
5799 return pa_output_mod_insn (1, insn);"
5800 [(set_attr "type" "milli")
5801 (set (attr "length")
5802 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5803 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5804
5805 (define_insn ""
5806 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5807 (clobber (match_operand:SI 0 "register_operand" "=a"))
5808 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5809 (clobber (reg:SI 26))
5810 (clobber (reg:SI 25))
5811 (clobber (reg:SI 2))]
5812 "TARGET_64BIT"
5813 "*
5814 return pa_output_mod_insn (1, insn);"
5815 [(set_attr "type" "milli")
5816 (set (attr "length")
5817 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5818 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5819
5820 ;;- and instructions
5821 ;; We define DImode `and` so with DImode `not` we can get
5822 ;; DImode `andn`. Other combinations are possible.
5823
5824 (define_expand "anddi3"
5825 [(set (match_operand:DI 0 "register_operand" "")
5826 (and:DI (match_operand:DI 1 "register_operand" "")
5827 (match_operand:DI 2 "and_operand" "")))]
5828 "TARGET_64BIT"
5829 "")
5830
5831 (define_insn ""
5832 [(set (match_operand:DI 0 "register_operand" "=r,r")
5833 (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5834 (match_operand:DI 2 "and_operand" "rO,P")))]
5835 "TARGET_64BIT"
5836 "* return pa_output_64bit_and (operands); "
5837 [(set_attr "type" "binary")
5838 (set_attr "length" "4")])
5839
5840 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5841 ; constant with ldil;ldo.
5842 (define_insn "andsi3"
5843 [(set (match_operand:SI 0 "register_operand" "=r,r")
5844 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5845 (match_operand:SI 2 "and_operand" "rO,P")))]
5846 ""
5847 "* return pa_output_and (operands); "
5848 [(set_attr "type" "binary,shift")
5849 (set_attr "length" "4,4")])
5850
5851 (define_insn ""
5852 [(set (match_operand:DI 0 "register_operand" "=r")
5853 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5854 (match_operand:DI 2 "register_operand" "r")))]
5855 "TARGET_64BIT"
5856 "andcm %2,%1,%0"
5857 [(set_attr "type" "binary")
5858 (set_attr "length" "4")])
5859
5860 (define_insn ""
5861 [(set (match_operand:SI 0 "register_operand" "=r")
5862 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5863 (match_operand:SI 2 "register_operand" "r")))]
5864 ""
5865 "andcm %2,%1,%0"
5866 [(set_attr "type" "binary")
5867 (set_attr "length" "4")])
5868
5869 (define_expand "iordi3"
5870 [(set (match_operand:DI 0 "register_operand" "")
5871 (ior:DI (match_operand:DI 1 "register_operand" "")
5872 (match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5873 "TARGET_64BIT"
5874 "")
5875
5876 (define_insn ""
5877 [(set (match_operand:DI 0 "register_operand" "=r,r")
5878 (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5879 (match_operand:DI 2 "cint_ior_operand" "M,i")))]
5880 "TARGET_64BIT"
5881 "* return pa_output_64bit_ior (operands); "
5882 [(set_attr "type" "binary,shift")
5883 (set_attr "length" "4,4")])
5884
5885 (define_insn ""
5886 [(set (match_operand:DI 0 "register_operand" "=r")
5887 (ior:DI (match_operand:DI 1 "register_operand" "%r")
5888 (match_operand:DI 2 "register_operand" "r")))]
5889 "TARGET_64BIT"
5890 "or %1,%2,%0"
5891 [(set_attr "type" "binary")
5892 (set_attr "length" "4")])
5893
5894 ;; Need a define_expand because we've run out of CONST_OK... characters.
5895 (define_expand "iorsi3"
5896 [(set (match_operand:SI 0 "register_operand" "")
5897 (ior:SI (match_operand:SI 1 "register_operand" "")
5898 (match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5899 ""
5900 "")
5901
5902 (define_insn ""
5903 [(set (match_operand:SI 0 "register_operand" "=r,r")
5904 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5905 (match_operand:SI 2 "cint_ior_operand" "M,i")))]
5906 ""
5907 "* return pa_output_ior (operands); "
5908 [(set_attr "type" "binary,shift")
5909 (set_attr "length" "4,4")])
5910
5911 (define_insn ""
5912 [(set (match_operand:SI 0 "register_operand" "=r")
5913 (ior:SI (match_operand:SI 1 "register_operand" "%r")
5914 (match_operand:SI 2 "register_operand" "r")))]
5915 ""
5916 "or %1,%2,%0"
5917 [(set_attr "type" "binary")
5918 (set_attr "length" "4")])
5919
5920 (define_expand "xordi3"
5921 [(set (match_operand:DI 0 "register_operand" "")
5922 (xor:DI (match_operand:DI 1 "register_operand" "")
5923 (match_operand:DI 2 "register_operand" "")))]
5924 "TARGET_64BIT"
5925 "")
5926
5927 (define_insn ""
5928 [(set (match_operand:DI 0 "register_operand" "=r")
5929 (xor:DI (match_operand:DI 1 "register_operand" "%r")
5930 (match_operand:DI 2 "register_operand" "r")))]
5931 "TARGET_64BIT"
5932 "xor %1,%2,%0"
5933 [(set_attr "type" "binary")
5934 (set_attr "length" "4")])
5935
5936 (define_insn "xorsi3"
5937 [(set (match_operand:SI 0 "register_operand" "=r")
5938 (xor:SI (match_operand:SI 1 "register_operand" "%r")
5939 (match_operand:SI 2 "register_operand" "r")))]
5940 ""
5941 "xor %1,%2,%0"
5942 [(set_attr "type" "binary")
5943 (set_attr "length" "4")])
5944
5945 (define_expand "negdi2"
5946 [(set (match_operand:DI 0 "register_operand" "")
5947 (neg:DI (match_operand:DI 1 "register_operand" "")))]
5948 ""
5949 "")
5950
5951 (define_insn ""
5952 [(set (match_operand:DI 0 "register_operand" "=r")
5953 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5954 "!TARGET_64BIT"
5955 "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5956 [(set_attr "type" "unary")
5957 (set_attr "length" "8")])
5958
5959 (define_insn ""
5960 [(set (match_operand:DI 0 "register_operand" "=r")
5961 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5962 "TARGET_64BIT"
5963 "sub %%r0,%1,%0"
5964 [(set_attr "type" "unary")
5965 (set_attr "length" "4")])
5966
5967 (define_expand "negvdi2"
5968 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5969 (neg:DI (match_operand:DI 1 "register_operand" "")))
5970 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5971 (sign_extend:TI (neg:DI (match_dup 1))))
5972 (const_int 0))])]
5973 ""
5974 "")
5975
5976 (define_insn ""
5977 [(set (match_operand:DI 0 "register_operand" "=r")
5978 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5979 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5980 (sign_extend:TI (neg:DI (match_dup 1))))
5981 (const_int 0))]
5982 "!TARGET_64BIT"
5983 "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5984 [(set_attr "type" "unary")
5985 (set_attr "length" "8")])
5986
5987 (define_insn ""
5988 [(set (match_operand:DI 0 "register_operand" "=r")
5989 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5990 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5991 (sign_extend:TI (neg:DI (match_dup 1))))
5992 (const_int 0))]
5993 "TARGET_64BIT"
5994 "sub,tsv %%r0,%1,%0"
5995 [(set_attr "type" "unary")
5996 (set_attr "length" "4")])
5997
5998 (define_insn "negsi2"
5999 [(set (match_operand:SI 0 "register_operand" "=r")
6000 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
6001 ""
6002 "sub %%r0,%1,%0"
6003 [(set_attr "type" "unary")
6004 (set_attr "length" "4")])
6005
6006 (define_insn "negvsi2"
6007 [(set (match_operand:SI 0 "register_operand" "=r")
6008 (neg:SI (match_operand:SI 1 "register_operand" "r")))
6009 (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
6010 (sign_extend:DI (neg:SI (match_dup 1))))
6011 (const_int 0))]
6012 ""
6013 "{subo|sub,tsv} %%r0,%1,%0"
6014 [(set_attr "type" "unary")
6015 (set_attr "length" "4")])
6016
6017 (define_expand "one_cmpldi2"
6018 [(set (match_operand:DI 0 "register_operand" "")
6019 (not:DI (match_operand:DI 1 "register_operand" "")))]
6020 ""
6021 "
6022 {
6023 }")
6024
6025 (define_insn ""
6026 [(set (match_operand:DI 0 "register_operand" "=r")
6027 (not:DI (match_operand:DI 1 "register_operand" "r")))]
6028 "!TARGET_64BIT"
6029 "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
6030 [(set_attr "type" "unary")
6031 (set_attr "length" "8")])
6032
6033 (define_insn ""
6034 [(set (match_operand:DI 0 "register_operand" "=r")
6035 (not:DI (match_operand:DI 1 "register_operand" "r")))]
6036 "TARGET_64BIT"
6037 "uaddcm %%r0,%1,%0"
6038 [(set_attr "type" "unary")
6039 (set_attr "length" "4")])
6040
6041 (define_insn "one_cmplsi2"
6042 [(set (match_operand:SI 0 "register_operand" "=r")
6043 (not:SI (match_operand:SI 1 "register_operand" "r")))]
6044 ""
6045 "uaddcm %%r0,%1,%0"
6046 [(set_attr "type" "unary")
6047 (set_attr "length" "4")])
6048 \f
6049 ;; Floating point arithmetic instructions.
6050
6051 (define_insn "adddf3"
6052 [(set (match_operand:DF 0 "register_operand" "=f")
6053 (plus:DF (match_operand:DF 1 "register_operand" "f")
6054 (match_operand:DF 2 "register_operand" "f")))]
6055 "! TARGET_SOFT_FLOAT"
6056 "fadd,dbl %1,%2,%0"
6057 [(set_attr "type" "fpalu")
6058 (set_attr "pa_combine_type" "faddsub")
6059 (set_attr "length" "4")])
6060
6061 (define_insn "addsf3"
6062 [(set (match_operand:SF 0 "register_operand" "=f")
6063 (plus:SF (match_operand:SF 1 "register_operand" "f")
6064 (match_operand:SF 2 "register_operand" "f")))]
6065 "! TARGET_SOFT_FLOAT"
6066 "fadd,sgl %1,%2,%0"
6067 [(set_attr "type" "fpalu")
6068 (set_attr "pa_combine_type" "faddsub")
6069 (set_attr "length" "4")])
6070
6071 (define_insn "subdf3"
6072 [(set (match_operand:DF 0 "register_operand" "=f")
6073 (minus:DF (match_operand:DF 1 "register_operand" "f")
6074 (match_operand:DF 2 "register_operand" "f")))]
6075 "! TARGET_SOFT_FLOAT"
6076 "fsub,dbl %1,%2,%0"
6077 [(set_attr "type" "fpalu")
6078 (set_attr "pa_combine_type" "faddsub")
6079 (set_attr "length" "4")])
6080
6081 (define_insn "subsf3"
6082 [(set (match_operand:SF 0 "register_operand" "=f")
6083 (minus:SF (match_operand:SF 1 "register_operand" "f")
6084 (match_operand:SF 2 "register_operand" "f")))]
6085 "! TARGET_SOFT_FLOAT"
6086 "fsub,sgl %1,%2,%0"
6087 [(set_attr "type" "fpalu")
6088 (set_attr "pa_combine_type" "faddsub")
6089 (set_attr "length" "4")])
6090
6091 (define_insn "muldf3"
6092 [(set (match_operand:DF 0 "register_operand" "=f")
6093 (mult:DF (match_operand:DF 1 "register_operand" "f")
6094 (match_operand:DF 2 "register_operand" "f")))]
6095 "! TARGET_SOFT_FLOAT"
6096 "fmpy,dbl %1,%2,%0"
6097 [(set_attr "type" "fpmuldbl")
6098 (set_attr "pa_combine_type" "fmpy")
6099 (set_attr "length" "4")])
6100
6101 (define_insn "mulsf3"
6102 [(set (match_operand:SF 0 "register_operand" "=f")
6103 (mult:SF (match_operand:SF 1 "register_operand" "f")
6104 (match_operand:SF 2 "register_operand" "f")))]
6105 "! TARGET_SOFT_FLOAT"
6106 "fmpy,sgl %1,%2,%0"
6107 [(set_attr "type" "fpmulsgl")
6108 (set_attr "pa_combine_type" "fmpy")
6109 (set_attr "length" "4")])
6110
6111 (define_insn "divdf3"
6112 [(set (match_operand:DF 0 "register_operand" "=f")
6113 (div:DF (match_operand:DF 1 "register_operand" "f")
6114 (match_operand:DF 2 "register_operand" "f")))]
6115 "! TARGET_SOFT_FLOAT"
6116 "fdiv,dbl %1,%2,%0"
6117 [(set_attr "type" "fpdivdbl")
6118 (set_attr "length" "4")])
6119
6120 (define_insn "divsf3"
6121 [(set (match_operand:SF 0 "register_operand" "=f")
6122 (div:SF (match_operand:SF 1 "register_operand" "f")
6123 (match_operand:SF 2 "register_operand" "f")))]
6124 "! TARGET_SOFT_FLOAT"
6125 "fdiv,sgl %1,%2,%0"
6126 [(set_attr "type" "fpdivsgl")
6127 (set_attr "length" "4")])
6128
6129 ;; Processors prior to PA 2.0 don't have a fneg instruction. Fast
6130 ;; negation can be done by subtracting from plus zero. However, this
6131 ;; violates the IEEE standard when negating plus and minus zero.
6132 ;; The slow path toggles the sign bit in the general registers.
6133 (define_expand "negdf2"
6134 [(set (match_operand:DF 0 "register_operand" "")
6135 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6136 "!TARGET_SOFT_FLOAT"
6137 {
6138 if (TARGET_PA_20 || !flag_signed_zeros)
6139 emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6140 else
6141 emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6142 DONE;
6143 })
6144
6145 (define_insn "negdf2_slow"
6146 [(set (match_operand:DF 0 "register_operand" "=r")
6147 (neg:DF (match_operand:DF 1 "register_operand" "r")))]
6148 "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6149 "*
6150 {
6151 if (rtx_equal_p (operands[0], operands[1]))
6152 return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6153 else
6154 return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6155 }"
6156 [(set_attr "type" "multi")
6157 (set (attr "length")
6158 (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6159 (const_int 12)
6160 (const_int 16)))])
6161
6162 (define_insn "negdf2_fast"
6163 [(set (match_operand:DF 0 "register_operand" "=f")
6164 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
6165 "!TARGET_SOFT_FLOAT"
6166 "*
6167 {
6168 if (TARGET_PA_20)
6169 return \"fneg,dbl %1,%0\";
6170 else
6171 return \"fsub,dbl %%fr0,%1,%0\";
6172 }"
6173 [(set_attr "type" "fpalu")
6174 (set_attr "length" "4")])
6175
6176 (define_expand "negsf2"
6177 [(set (match_operand:SF 0 "register_operand" "")
6178 (neg:SF (match_operand:SF 1 "register_operand" "")))]
6179 "!TARGET_SOFT_FLOAT"
6180 {
6181 if (TARGET_PA_20 || !flag_signed_zeros)
6182 emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6183 else
6184 emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6185 DONE;
6186 })
6187
6188 (define_insn "negsf2_slow"
6189 [(set (match_operand:SF 0 "register_operand" "=r")
6190 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
6191 "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6192 "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6193 [(set_attr "type" "multi")
6194 (set_attr "length" "12")])
6195
6196 (define_insn "negsf2_fast"
6197 [(set (match_operand:SF 0 "register_operand" "=f")
6198 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6199 "!TARGET_SOFT_FLOAT"
6200 "*
6201 {
6202 if (TARGET_PA_20)
6203 return \"fneg,sgl %1,%0\";
6204 else
6205 return \"fsub,sgl %%fr0,%1,%0\";
6206 }"
6207 [(set_attr "type" "fpalu")
6208 (set_attr "length" "4")])
6209
6210 (define_insn "absdf2"
6211 [(set (match_operand:DF 0 "register_operand" "=f")
6212 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
6213 "! TARGET_SOFT_FLOAT"
6214 "fabs,dbl %1,%0"
6215 [(set_attr "type" "fpalu")
6216 (set_attr "length" "4")])
6217
6218 (define_insn "abssf2"
6219 [(set (match_operand:SF 0 "register_operand" "=f")
6220 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6221 "! TARGET_SOFT_FLOAT"
6222 "fabs,sgl %1,%0"
6223 [(set_attr "type" "fpalu")
6224 (set_attr "length" "4")])
6225
6226 (define_insn "sqrtdf2"
6227 [(set (match_operand:DF 0 "register_operand" "=f")
6228 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6229 "! TARGET_SOFT_FLOAT"
6230 "fsqrt,dbl %1,%0"
6231 [(set_attr "type" "fpsqrtdbl")
6232 (set_attr "length" "4")])
6233
6234 (define_insn "sqrtsf2"
6235 [(set (match_operand:SF 0 "register_operand" "=f")
6236 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6237 "! TARGET_SOFT_FLOAT"
6238 "fsqrt,sgl %1,%0"
6239 [(set_attr "type" "fpsqrtsgl")
6240 (set_attr "length" "4")])
6241
6242 ;; PA 2.0 floating point instructions
6243
6244 ; fmpyfadd patterns
6245 (define_insn "fmadf4"
6246 [(set (match_operand:DF 0 "register_operand" "=f")
6247 (fma:DF (match_operand:DF 1 "register_operand" "f")
6248 (match_operand:DF 2 "register_operand" "f")
6249 (match_operand:DF 3 "register_operand" "f")))]
6250 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6251 "fmpyfadd,dbl %1,%2,%3,%0"
6252 [(set_attr "type" "fpmuldbl")
6253 (set_attr "length" "4")])
6254
6255 (define_insn "fmasf4"
6256 [(set (match_operand:SF 0 "register_operand" "=f")
6257 (fma:SF (match_operand:SF 1 "register_operand" "f")
6258 (match_operand:SF 2 "register_operand" "f")
6259 (match_operand:SF 3 "register_operand" "f")))]
6260 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6261 "fmpyfadd,sgl %1,%2,%3,%0"
6262 [(set_attr "type" "fpmulsgl")
6263 (set_attr "length" "4")])
6264
6265 ; fmpynfadd patterns
6266 (define_insn "fnmadf4"
6267 [(set (match_operand:DF 0 "register_operand" "=f")
6268 (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6269 (match_operand:DF 2 "register_operand" "f")
6270 (match_operand:DF 3 "register_operand" "f")))]
6271 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6272 "fmpynfadd,dbl %1,%2,%3,%0"
6273 [(set_attr "type" "fpmuldbl")
6274 (set_attr "length" "4")])
6275
6276 (define_insn "fnmasf4"
6277 [(set (match_operand:SF 0 "register_operand" "=f")
6278 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6279 (match_operand:SF 2 "register_operand" "f")
6280 (match_operand:SF 3 "register_operand" "f")))]
6281 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6282 "fmpynfadd,sgl %1,%2,%3,%0"
6283 [(set_attr "type" "fpmulsgl")
6284 (set_attr "length" "4")])
6285
6286 ; fnegabs patterns
6287 (define_insn ""
6288 [(set (match_operand:DF 0 "register_operand" "=f")
6289 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6290 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6291 "fnegabs,dbl %1,%0"
6292 [(set_attr "type" "fpalu")
6293 (set_attr "length" "4")])
6294
6295 (define_insn ""
6296 [(set (match_operand:SF 0 "register_operand" "=f")
6297 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6298 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6299 "fnegabs,sgl %1,%0"
6300 [(set_attr "type" "fpalu")
6301 (set_attr "length" "4")])
6302
6303 (define_insn ""
6304 [(set (match_operand:DF 0 "register_operand" "=f")
6305 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6306 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6307 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6308 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6309 "#"
6310 [(set_attr "type" "fpalu")
6311 (set_attr "length" "8")])
6312
6313 (define_split
6314 [(set (match_operand:DF 0 "register_operand" "")
6315 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6316 (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6317 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6318 [(set (match_dup 2) (abs:DF (match_dup 1)))
6319 (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6320 "")
6321
6322 (define_insn ""
6323 [(set (match_operand:SF 0 "register_operand" "=f")
6324 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6325 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6326 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6327 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6328 "#"
6329 [(set_attr "type" "fpalu")
6330 (set_attr "length" "8")])
6331
6332 (define_split
6333 [(set (match_operand:SF 0 "register_operand" "")
6334 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6335 (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6336 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6337 [(set (match_dup 2) (abs:SF (match_dup 1)))
6338 (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6339 "")
6340
6341 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6342 ;; instruction if we can ignore the sign of zero.
6343 (define_insn ""
6344 [(set (match_operand:DF 0 "register_operand" "=f")
6345 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6346 (match_operand:DF 2 "register_operand" "f"))))]
6347 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6348 "fmpynfadd,dbl %1,%2,%%fr0,%0"
6349 [(set_attr "type" "fpmuldbl")
6350 (set_attr "length" "4")])
6351
6352 (define_insn ""
6353 [(set (match_operand:SF 0 "register_operand" "=f")
6354 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6355 (match_operand:SF 2 "register_operand" "f"))))]
6356 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6357 "fmpynfadd,sgl %1,%2,%%fr0,%0"
6358 [(set_attr "type" "fpmuldbl")
6359 (set_attr "length" "4")])
6360
6361 (define_insn ""
6362 [(set (match_operand:DF 0 "register_operand" "=f")
6363 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6364 (match_operand:DF 2 "register_operand" "f"))))
6365 (set (match_operand:DF 3 "register_operand" "=&f")
6366 (mult:DF (match_dup 1) (match_dup 2)))]
6367 "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6368 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6369 || reg_overlap_mentioned_p (operands[3], operands[2])))"
6370 "#"
6371 [(set_attr "type" "fpmuldbl")
6372 (set_attr "length" "8")])
6373
6374 (define_split
6375 [(set (match_operand:DF 0 "register_operand" "")
6376 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6377 (match_operand:DF 2 "register_operand" ""))))
6378 (set (match_operand:DF 3 "register_operand" "")
6379 (mult:DF (match_dup 1) (match_dup 2)))]
6380 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6381 [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6382 (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6383 "")
6384
6385 (define_insn ""
6386 [(set (match_operand:SF 0 "register_operand" "=f")
6387 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6388 (match_operand:SF 2 "register_operand" "f"))))
6389 (set (match_operand:SF 3 "register_operand" "=&f")
6390 (mult:SF (match_dup 1) (match_dup 2)))]
6391 "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6392 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6393 || reg_overlap_mentioned_p (operands[3], operands[2])))"
6394 "#"
6395 [(set_attr "type" "fpmuldbl")
6396 (set_attr "length" "8")])
6397
6398 (define_split
6399 [(set (match_operand:SF 0 "register_operand" "")
6400 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6401 (match_operand:SF 2 "register_operand" ""))))
6402 (set (match_operand:SF 3 "register_operand" "")
6403 (mult:SF (match_dup 1) (match_dup 2)))]
6404 "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6405 [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6406 (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6407 "")
6408 \f
6409 ;;- Shift instructions
6410
6411 ;; Optimized special case of shifting.
6412
6413 (define_insn ""
6414 [(set (match_operand:SI 0 "register_operand" "=r")
6415 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6416 (const_int 24)))]
6417 ""
6418 "ldb%M1 %1,%0"
6419 [(set_attr "type" "load")
6420 (set_attr "length" "4")])
6421
6422 (define_insn ""
6423 [(set (match_operand:SI 0 "register_operand" "=r")
6424 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6425 (const_int 16)))]
6426 ""
6427 "ldh%M1 %1,%0"
6428 [(set_attr "type" "load")
6429 (set_attr "length" "4")])
6430
6431 (define_insn ""
6432 [(set (match_operand:SI 0 "register_operand" "=r")
6433 (plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6434 (match_operand:SI 3 "shadd_operand" ""))
6435 (match_operand:SI 1 "register_operand" "r")))]
6436 ""
6437 "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6438 [(set_attr "type" "binary")
6439 (set_attr "length" "4")])
6440
6441 (define_insn ""
6442 [(set (match_operand:DI 0 "register_operand" "=r")
6443 (plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6444 (match_operand:DI 3 "shadd_operand" ""))
6445 (match_operand:DI 1 "register_operand" "r")))]
6446 "TARGET_64BIT"
6447 "shladd,l %2,%o3,%1,%0"
6448 [(set_attr "type" "binary")
6449 (set_attr "length" "4")])
6450
6451 (define_expand "ashlsi3"
6452 [(set (match_operand:SI 0 "register_operand" "")
6453 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6454 (match_operand:SI 2 "arith32_operand" "")))]
6455 ""
6456 "
6457 {
6458 if (GET_CODE (operands[2]) != CONST_INT)
6459 {
6460 rtx temp = gen_reg_rtx (SImode);
6461 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6462 if (GET_CODE (operands[1]) == CONST_INT)
6463 emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6464 else
6465 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6466 DONE;
6467 }
6468 /* Make sure both inputs are not constants,
6469 there are no patterns for that. */
6470 operands[1] = force_reg (SImode, operands[1]);
6471 }")
6472
6473 (define_insn ""
6474 [(set (match_operand:SI 0 "register_operand" "=r")
6475 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6476 (match_operand:SI 2 "const_int_operand" "n")))]
6477 ""
6478 "{zdep|depw,z} %1,%P2,%L2,%0"
6479 [(set_attr "type" "shift")
6480 (set_attr "length" "4")])
6481
6482 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6483 ; Doing it like this makes slightly better code since reload can
6484 ; replace a register with a known value in range -16..15 with a
6485 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
6486 ; but since we have no more CONST_OK... characters, that is not
6487 ; possible.
6488 (define_insn "zvdep32"
6489 [(set (match_operand:SI 0 "register_operand" "=r,r")
6490 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6491 (minus:SI (const_int 31)
6492 (match_operand:SI 2 "register_operand" "q,q"))))]
6493 ""
6494 "@
6495 {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6496 {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6497 [(set_attr "type" "shift,shift")
6498 (set_attr "length" "4,4")])
6499
6500 (define_insn "zvdep_imm32"
6501 [(set (match_operand:SI 0 "register_operand" "=r")
6502 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6503 (minus:SI (const_int 31)
6504 (match_operand:SI 2 "register_operand" "q"))))]
6505 ""
6506 "*
6507 {
6508 unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6509 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6510 operands[1] = GEN_INT ((x & 0xf) - 0x10);
6511 return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6512 }"
6513 [(set_attr "type" "shift")
6514 (set_attr "length" "4")])
6515
6516 (define_insn "vdepi_ior"
6517 [(set (match_operand:SI 0 "register_operand" "=r")
6518 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6519 (minus:SI (const_int 31)
6520 (match_operand:SI 2 "register_operand" "q")))
6521 (match_operand:SI 3 "register_operand" "0")))]
6522 ; accept ...0001...1, can this be generalized?
6523 "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6524 "*
6525 {
6526 HOST_WIDE_INT x = INTVAL (operands[1]);
6527 operands[2] = GEN_INT (exact_log2 (x + 1));
6528 return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6529 }"
6530 [(set_attr "type" "shift")
6531 (set_attr "length" "4")])
6532
6533 (define_insn "vdepi_and"
6534 [(set (match_operand:SI 0 "register_operand" "=r")
6535 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6536 (minus:SI (const_int 31)
6537 (match_operand:SI 2 "register_operand" "q")))
6538 (match_operand:SI 3 "register_operand" "0")))]
6539 ; this can be generalized...!
6540 "INTVAL (operands[1]) == -2"
6541 "*
6542 {
6543 HOST_WIDE_INT x = INTVAL (operands[1]);
6544 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6545 return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6546 }"
6547 [(set_attr "type" "shift")
6548 (set_attr "length" "4")])
6549
6550 (define_expand "ashldi3"
6551 [(set (match_operand:DI 0 "register_operand" "")
6552 (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6553 (match_operand:DI 2 "arith32_operand" "")))]
6554 "TARGET_64BIT"
6555 "
6556 {
6557 if (GET_CODE (operands[2]) != CONST_INT)
6558 {
6559 rtx temp = gen_reg_rtx (DImode);
6560 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6561 if (GET_CODE (operands[1]) == CONST_INT)
6562 emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6563 else
6564 emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6565 DONE;
6566 }
6567 /* Make sure both inputs are not constants,
6568 there are no patterns for that. */
6569 operands[1] = force_reg (DImode, operands[1]);
6570 }")
6571
6572 (define_insn ""
6573 [(set (match_operand:DI 0 "register_operand" "=r")
6574 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6575 (match_operand:DI 2 "const_int_operand" "n")))]
6576 "TARGET_64BIT"
6577 "depd,z %1,%p2,%Q2,%0"
6578 [(set_attr "type" "shift")
6579 (set_attr "length" "4")])
6580
6581 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6582 ; Doing it like this makes slightly better code since reload can
6583 ; replace a register with a known value in range -16..15 with a
6584 ; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
6585 ; but since we have no more CONST_OK... characters, that is not
6586 ; possible.
6587 (define_insn "zvdep64"
6588 [(set (match_operand:DI 0 "register_operand" "=r,r")
6589 (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6590 (minus:DI (const_int 63)
6591 (match_operand:DI 2 "register_operand" "q,q"))))]
6592 "TARGET_64BIT"
6593 "@
6594 depd,z %1,%%sar,64,%0
6595 depdi,z %1,%%sar,64,%0"
6596 [(set_attr "type" "shift,shift")
6597 (set_attr "length" "4,4")])
6598
6599 (define_insn "zvdep_imm64"
6600 [(set (match_operand:DI 0 "register_operand" "=r")
6601 (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6602 (minus:DI (const_int 63)
6603 (match_operand:DI 2 "register_operand" "q"))))]
6604 "TARGET_64BIT"
6605 "*
6606 {
6607 unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6608 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6609 operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6610 return \"depdi,z %1,%%sar,%2,%0\";
6611 }"
6612 [(set_attr "type" "shift")
6613 (set_attr "length" "4")])
6614
6615 (define_insn ""
6616 [(set (match_operand:DI 0 "register_operand" "=r")
6617 (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6618 (minus:DI (const_int 63)
6619 (match_operand:DI 2 "register_operand" "q")))
6620 (match_operand:DI 3 "register_operand" "0")))]
6621 ; accept ...0001...1, can this be generalized?
6622 "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6623 "*
6624 {
6625 HOST_WIDE_INT x = INTVAL (operands[1]);
6626 operands[2] = GEN_INT (exact_log2 (x + 1));
6627 return \"depdi -1,%%sar,%2,%0\";
6628 }"
6629 [(set_attr "type" "shift")
6630 (set_attr "length" "4")])
6631
6632 (define_insn ""
6633 [(set (match_operand:DI 0 "register_operand" "=r")
6634 (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6635 (minus:DI (const_int 63)
6636 (match_operand:DI 2 "register_operand" "q")))
6637 (match_operand:DI 3 "register_operand" "0")))]
6638 ; this can be generalized...!
6639 "TARGET_64BIT && INTVAL (operands[1]) == -2"
6640 "*
6641 {
6642 HOST_WIDE_INT x = INTVAL (operands[1]);
6643 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6644 return \"depdi 0,%%sar,%2,%0\";
6645 }"
6646 [(set_attr "type" "shift")
6647 (set_attr "length" "4")])
6648
6649 (define_expand "ashrsi3"
6650 [(set (match_operand:SI 0 "register_operand" "")
6651 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6652 (match_operand:SI 2 "arith32_operand" "")))]
6653 ""
6654 "
6655 {
6656 if (GET_CODE (operands[2]) != CONST_INT)
6657 {
6658 rtx temp = gen_reg_rtx (SImode);
6659 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6660 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6661 DONE;
6662 }
6663 }")
6664
6665 (define_insn ""
6666 [(set (match_operand:SI 0 "register_operand" "=r")
6667 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6668 (match_operand:SI 2 "const_int_operand" "n")))]
6669 ""
6670 "{extrs|extrw,s} %1,%P2,%L2,%0"
6671 [(set_attr "type" "shift")
6672 (set_attr "length" "4")])
6673
6674 (define_insn "vextrs32"
6675 [(set (match_operand:SI 0 "register_operand" "=r")
6676 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6677 (minus:SI (const_int 31)
6678 (match_operand:SI 2 "register_operand" "q"))))]
6679 ""
6680 "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6681 [(set_attr "type" "shift")
6682 (set_attr "length" "4")])
6683
6684 (define_expand "ashrdi3"
6685 [(set (match_operand:DI 0 "register_operand" "")
6686 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6687 (match_operand:DI 2 "arith32_operand" "")))]
6688 "TARGET_64BIT"
6689 "
6690 {
6691 if (GET_CODE (operands[2]) != CONST_INT)
6692 {
6693 rtx temp = gen_reg_rtx (DImode);
6694 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6695 emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6696 DONE;
6697 }
6698 }")
6699
6700 (define_insn ""
6701 [(set (match_operand:DI 0 "register_operand" "=r")
6702 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6703 (match_operand:DI 2 "const_int_operand" "n")))]
6704 "TARGET_64BIT"
6705 "extrd,s %1,%p2,%Q2,%0"
6706 [(set_attr "type" "shift")
6707 (set_attr "length" "4")])
6708
6709 (define_insn "vextrs64"
6710 [(set (match_operand:DI 0 "register_operand" "=r")
6711 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6712 (minus:DI (const_int 63)
6713 (match_operand:DI 2 "register_operand" "q"))))]
6714 "TARGET_64BIT"
6715 "extrd,s %1,%%sar,64,%0"
6716 [(set_attr "type" "shift")
6717 (set_attr "length" "4")])
6718
6719 (define_insn "lshrsi3"
6720 [(set (match_operand:SI 0 "register_operand" "=r,r")
6721 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6722 (match_operand:SI 2 "shift5_operand" "q,n")))]
6723 ""
6724 "@
6725 {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6726 {extru|extrw,u} %1,%P2,%L2,%0"
6727 [(set_attr "type" "shift")
6728 (set_attr "length" "4")])
6729
6730 (define_insn "lshrdi3"
6731 [(set (match_operand:DI 0 "register_operand" "=r,r")
6732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6733 (match_operand:DI 2 "shift6_operand" "q,n")))]
6734 "TARGET_64BIT"
6735 "@
6736 shrpd %%r0,%1,%%sar,%0
6737 extrd,u %1,%p2,%Q2,%0"
6738 [(set_attr "type" "shift")
6739 (set_attr "length" "4")])
6740
6741 ; Shift right pair word 0 to 31 bits.
6742 (define_insn "shrpsi4"
6743 [(set (match_operand:SI 0 "register_operand" "=r,r")
6744 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
6745 (minus:SI (const_int 32)
6746 (match_operand:SI 3 "shift5_operand" "q,n")))
6747 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r,r")
6748 (match_dup 3))))]
6749 ""
6750 "@
6751 {vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}
6752 {shd|shrpw} %1,%2,%3,%0"
6753 [(set_attr "type" "shift")
6754 (set_attr "length" "4")])
6755
6756 ; Shift right pair doubleword 0 to 63 bits.
6757 (define_insn "shrpdi4"
6758 [(set (match_operand:DI 0 "register_operand" "=r,r")
6759 (ior:DI (ashift:DI (match_operand:SI 1 "register_operand" "r,r")
6760 (minus:DI (const_int 64)
6761 (match_operand:DI 3 "shift6_operand" "q,n")))
6762 (lshiftrt:DI (match_operand:DI 2 "register_operand" "r,r")
6763 (match_dup 3))))]
6764 "TARGET_64BIT"
6765 "@
6766 shrpd %1,%2,%%sar,%0
6767 shrpd %1,%2,%3,%0"
6768 [(set_attr "type" "shift")
6769 (set_attr "length" "4")])
6770
6771 (define_insn "rotrsi3"
6772 [(set (match_operand:SI 0 "register_operand" "=r,r")
6773 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6774 (match_operand:SI 2 "shift5_operand" "q,n")))]
6775 ""
6776 "*
6777 {
6778 if (GET_CODE (operands[2]) == CONST_INT)
6779 {
6780 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6781 return \"{shd|shrpw} %1,%1,%2,%0\";
6782 }
6783 else
6784 return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6785 }"
6786 [(set_attr "type" "shift")
6787 (set_attr "length" "4")])
6788
6789 (define_expand "rotlsi3"
6790 [(set (match_operand:SI 0 "register_operand" "")
6791 (rotate:SI (match_operand:SI 1 "register_operand" "")
6792 (match_operand:SI 2 "arith32_operand" "")))]
6793 ""
6794 "
6795 {
6796 if (GET_CODE (operands[2]) != CONST_INT)
6797 {
6798 rtx temp = gen_reg_rtx (SImode);
6799 emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6800 emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6801 DONE;
6802 }
6803 /* Else expand normally. */
6804 }")
6805
6806 (define_insn ""
6807 [(set (match_operand:SI 0 "register_operand" "=r")
6808 (rotate:SI (match_operand:SI 1 "register_operand" "r")
6809 (match_operand:SI 2 "const_int_operand" "n")))]
6810 ""
6811 "*
6812 {
6813 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6814 return \"{shd|shrpw} %1,%1,%2,%0\";
6815 }"
6816 [(set_attr "type" "shift")
6817 (set_attr "length" "4")])
6818
6819 (define_insn ""
6820 [(set (match_operand:SI 0 "register_operand" "=r")
6821 (match_operator:SI 5 "plus_xor_ior_operator"
6822 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6823 (match_operand:SI 3 "const_int_operand" "n"))
6824 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6825 (match_operand:SI 4 "const_int_operand" "n"))]))]
6826 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6827 "{shd|shrpw} %1,%2,%4,%0"
6828 [(set_attr "type" "shift")
6829 (set_attr "length" "4")])
6830
6831 (define_insn ""
6832 [(set (match_operand:SI 0 "register_operand" "=r")
6833 (match_operator:SI 5 "plus_xor_ior_operator"
6834 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6835 (match_operand:SI 4 "const_int_operand" "n"))
6836 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6837 (match_operand:SI 3 "const_int_operand" "n"))]))]
6838 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6839 "{shd|shrpw} %1,%2,%4,%0"
6840 [(set_attr "type" "shift")
6841 (set_attr "length" "4")])
6842
6843 (define_insn ""
6844 [(set (match_operand:SI 0 "register_operand" "=r")
6845 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6846 (match_operand:SI 2 "const_int_operand" ""))
6847 (match_operand:SI 3 "const_int_operand" "")))]
6848 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6849 "*
6850 {
6851 int cnt = INTVAL (operands[2]) & 31;
6852 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6853 operands[2] = GEN_INT (31 - cnt);
6854 return \"{zdep|depw,z} %1,%2,%3,%0\";
6855 }"
6856 [(set_attr "type" "shift")
6857 (set_attr "length" "4")])
6858 \f
6859 ;; Unconditional and other jump instructions.
6860
6861 ;; Trivial return used when no epilogue is needed.
6862 (define_insn "return"
6863 [(return)
6864 (use (reg:SI 2))]
6865 "pa_can_use_return_insn ()"
6866 "*
6867 {
6868 if (TARGET_PA_20)
6869 return \"bve%* (%%r2)\";
6870 return \"bv%* %%r0(%%r2)\";
6871 }"
6872 [(set_attr "type" "branch")
6873 (set_attr "length" "4")])
6874
6875 ;; This is used for most returns.
6876 (define_insn "return_internal"
6877 [(return)
6878 (use (reg:SI 2))]
6879 ""
6880 "*
6881 {
6882 if (TARGET_PA_20)
6883 return \"bve%* (%%r2)\";
6884 return \"bv%* %%r0(%%r2)\";
6885 }"
6886 [(set_attr "type" "branch")
6887 (set_attr "length" "4")])
6888
6889 ;; This is used for eh returns which bypass the return stub.
6890 (define_insn "return_external_pic"
6891 [(return)
6892 (clobber (reg:SI 1))
6893 (use (reg:SI 2))]
6894 "!TARGET_NO_SPACE_REGS
6895 && !TARGET_PA_20
6896 && flag_pic && crtl->calls_eh_return"
6897 "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
6898 [(set_attr "type" "branch")
6899 (set_attr "length" "12")])
6900
6901 (define_expand "prologue"
6902 [(const_int 0)]
6903 ""
6904 "pa_expand_prologue ();DONE;")
6905
6906 (define_expand "sibcall_epilogue"
6907 [(return)]
6908 ""
6909 "
6910 {
6911 pa_expand_epilogue ();
6912 DONE;
6913 }")
6914
6915 (define_expand "epilogue"
6916 [(return)]
6917 ""
6918 "
6919 {
6920 rtx x;
6921
6922 /* Try to use the trivial return first. Else use the full epilogue. */
6923 if (pa_can_use_return_insn ())
6924 x = gen_return ();
6925 else
6926 {
6927 pa_expand_epilogue ();
6928
6929 /* EH returns bypass the normal return stub. Thus, we must do an
6930 interspace branch to return from functions that call eh_return.
6931 This is only a problem for returns from shared code on ports
6932 using space registers. */
6933 if (!TARGET_NO_SPACE_REGS
6934 && !TARGET_PA_20
6935 && flag_pic && crtl->calls_eh_return)
6936 x = gen_return_external_pic ();
6937 else
6938 x = gen_return_internal ();
6939 }
6940 emit_jump_insn (x);
6941 DONE;
6942 }")
6943
6944 ; Used by hppa_profile_hook to load the starting address of the current
6945 ; function; operand 1 contains the address of the label in operand 3
6946 (define_insn "load_offset_label_address"
6947 [(set (match_operand:SI 0 "register_operand" "=r")
6948 (plus:SI (match_operand:SI 1 "register_operand" "r")
6949 (minus:SI (match_operand:SI 2 "" "")
6950 (label_ref:SI (match_operand 3 "" "")))))]
6951 ""
6952 "ldo %2-%l3(%1),%0"
6953 [(set_attr "type" "multi")
6954 (set_attr "length" "4")])
6955
6956 ; Output a code label and load its address.
6957 (define_insn "lcla1"
6958 [(set (match_operand:SI 0 "register_operand" "=r")
6959 (label_ref:SI (match_operand 1 "" "")))
6960 (const_int 0)]
6961 "!TARGET_PA_20"
6962 "*
6963 {
6964 output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
6965 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6966 CODE_LABEL_NUMBER (operands[1]));
6967 return \"\";
6968 }"
6969 [(set_attr "type" "multi")
6970 (set_attr "length" "8")])
6971
6972 (define_insn "lcla2"
6973 [(set (match_operand:SI 0 "register_operand" "=r")
6974 (label_ref:SI (match_operand 1 "" "")))
6975 (const_int 0)]
6976 "TARGET_PA_20"
6977 "*
6978 {
6979 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6980 CODE_LABEL_NUMBER (operands[1]));
6981 return \"mfia %0\";
6982 }"
6983 [(set_attr "type" "move")
6984 (set_attr "length" "4")])
6985
6986 (define_insn "blockage"
6987 [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
6988 ""
6989 ""
6990 [(set_attr "length" "0")])
6991
6992 (define_insn "jump"
6993 [(set (pc) (label_ref (match_operand 0 "" "")))]
6994 ""
6995 "*
6996 {
6997 /* An unconditional branch which can reach its target. */
6998 if (get_attr_length (insn) < 16)
6999 return \"b%* %l0\";
7000
7001 return pa_output_lbranch (operands[0], insn, 1);
7002 }"
7003 [(set_attr "type" "uncond_branch")
7004 (set_attr "pa_combine_type" "uncond_branch")
7005 (set (attr "length")
7006 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7007 (const_int MAX_17BIT_OFFSET))
7008 (const_int 4)
7009 (match_test "TARGET_PORTABLE_RUNTIME")
7010 (const_int 20)
7011 (not (match_test "flag_pic"))
7012 (const_int 16)]
7013 (const_int 24)))])
7014
7015 ;;; Hope this is only within a function...
7016 (define_insn "indirect_jump"
7017 [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7018 ""
7019 "bv%* %%r0(%0)"
7020 [(set_attr "type" "branch")
7021 (set_attr "length" "4")])
7022
7023 ;;; An indirect jump can be optimized to a direct jump. GAS for the
7024 ;;; SOM target doesn't allow branching to a label inside a function.
7025 ;;; We also don't correctly compute branch distances for labels
7026 ;;; outside the current function. Thus, we use an indirect jump can't
7027 ;;; be optimized to a direct jump for all targets. We assume that
7028 ;;; the branch target is in the same space (i.e., nested function
7029 ;;; jumping to a label in an outer function in the same translation
7030 ;;; unit).
7031 (define_expand "nonlocal_goto"
7032 [(use (match_operand 0 "general_operand" ""))
7033 (use (match_operand 1 "general_operand" ""))
7034 (use (match_operand 2 "general_operand" ""))
7035 (use (match_operand 3 "general_operand" ""))]
7036 ""
7037 {
7038 rtx lab = operands[1];
7039 rtx stack = operands[2];
7040 rtx fp = operands[3];
7041
7042 lab = copy_to_reg (lab);
7043
7044 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7045 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7046
7047 /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
7048 instead of the hard_frame_pointer_rtx in the save area. As a
7049 result, an extra instruction is needed to adjust for the offset
7050 of the virtual stack variables and the hard frame pointer. */
7051 if (GET_CODE (fp) != REG)
7052 fp = force_reg (Pmode, fp);
7053 emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
7054
7055 emit_stack_restore (SAVE_NONLOCAL, stack);
7056
7057 emit_use (hard_frame_pointer_rtx);
7058 emit_use (stack_pointer_rtx);
7059
7060 /* Nonlocal goto jumps are only used between functions in the same
7061 translation unit. Thus, we can avoid the extra overhead of an
7062 interspace jump. */
7063 emit_jump_insn (gen_indirect_goto (lab));
7064 emit_barrier ();
7065 DONE;
7066 })
7067
7068 (define_insn "indirect_goto"
7069 [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7070 "GET_MODE (operands[0]) == word_mode"
7071 "bv%* %%r0(%0)"
7072 [(set_attr "type" "branch")
7073 (set_attr "length" "4")])
7074
7075 ;; Subroutines of "casesi".
7076 ;; operand 0 is index
7077 ;; operand 1 is the minimum bound
7078 ;; operand 2 is the maximum bound - minimum bound + 1
7079 ;; operand 3 is CODE_LABEL for the table;
7080 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7081
7082 (define_expand "casesi"
7083 [(match_operand:SI 0 "general_operand" "")
7084 (match_operand:SI 1 "const_int_operand" "")
7085 (match_operand:SI 2 "const_int_operand" "")
7086 (match_operand 3 "" "")
7087 (match_operand 4 "" "")]
7088 ""
7089 "
7090 {
7091 if (GET_CODE (operands[0]) != REG)
7092 operands[0] = force_reg (SImode, operands[0]);
7093
7094 if (operands[1] != const0_rtx)
7095 {
7096 rtx index = gen_reg_rtx (SImode);
7097
7098 operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7099 if (!INT_14_BITS (operands[1]))
7100 operands[1] = force_reg (SImode, operands[1]);
7101 emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7102 operands[0] = index;
7103 }
7104
7105 if (!INT_5_BITS (operands[2]))
7106 operands[2] = force_reg (SImode, operands[2]);
7107
7108 /* This branch prevents us finding an insn for the delay slot of the
7109 following vectored branch. It might be possible to use the delay
7110 slot if an index value of -1 was used to transfer to the out-of-range
7111 label. In order to do this, we would have to output the -1 vector
7112 element after the delay insn. The casesi output code would have to
7113 check if the casesi insn is in a delay branch sequence and output
7114 the delay insn if one is found. If this was done, then it might
7115 then be worthwhile to split the casesi patterns to improve scheduling.
7116 However, it's not clear that all this extra complexity is worth
7117 the effort. */
7118 {
7119 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7120 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7121 }
7122
7123 /* In 64bit mode we must make sure to wipe the upper bits of the register
7124 just in case the addition overflowed or we had random bits in the
7125 high part of the register. */
7126 if (TARGET_64BIT)
7127 {
7128 rtx index = gen_reg_rtx (DImode);
7129
7130 emit_insn (gen_extendsidi2 (index, operands[0]));
7131 operands[0] = index;
7132 }
7133
7134 if (TARGET_64BIT)
7135 emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7136 else if (flag_pic)
7137 emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7138 else
7139 emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7140 DONE;
7141 }")
7142
7143 ;;; 32-bit code, absolute branch table.
7144 (define_insn "casesi32"
7145 [(set (pc) (mem:SI (plus:SI
7146 (mult:SI (match_operand:SI 0 "register_operand" "r")
7147 (const_int 4))
7148 (label_ref (match_operand 1 "" "")))))
7149 (clobber (match_scratch:SI 2 "=&r"))]
7150 "!flag_pic"
7151 "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7152 [(set_attr "type" "multi")
7153 (set_attr "length" "16")])
7154
7155 ;;; 32-bit code, relative branch table.
7156 (define_insn "casesi32p"
7157 [(set (pc) (mem:SI (plus:SI
7158 (mult:SI (match_operand:SI 0 "register_operand" "r")
7159 (const_int 4))
7160 (label_ref (match_operand 1 "" "")))))
7161 (clobber (match_scratch:SI 2 "=&r"))
7162 (clobber (match_scratch:SI 3 "=&r"))]
7163 "flag_pic"
7164 "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7165 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7166 [(set_attr "type" "multi")
7167 (set (attr "length")
7168 (if_then_else (match_test "TARGET_PA_20")
7169 (const_int 20)
7170 (const_int 24)))])
7171
7172 ;;; 64-bit code, 32-bit relative branch table.
7173 (define_insn "casesi64p"
7174 [(set (pc) (mem:DI (plus:DI
7175 (mult:DI (match_operand:DI 0 "register_operand" "r")
7176 (const_int 8))
7177 (label_ref (match_operand 1 "" "")))))
7178 (clobber (match_scratch:DI 2 "=&r"))
7179 (clobber (match_scratch:DI 3 "=&r"))]
7180 ""
7181 "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7182 add,l %2,%3,%3\;bv,n %%r0(%3)"
7183 [(set_attr "type" "multi")
7184 (set_attr "length" "24")])
7185
7186
7187 ;; Call patterns.
7188 ;;- jump to subroutine
7189
7190 (define_expand "call"
7191 [(parallel [(call (match_operand:SI 0 "" "")
7192 (match_operand 1 "" ""))
7193 (clobber (reg:SI 2))])]
7194 ""
7195 "
7196 {
7197 rtx op;
7198 rtx nb = operands[1];
7199
7200 if (TARGET_PORTABLE_RUNTIME)
7201 op = force_reg (SImode, XEXP (operands[0], 0));
7202 else
7203 {
7204 op = XEXP (operands[0], 0);
7205
7206 /* Generate indirect long calls to non-local functions. */
7207 if (!TARGET_64BIT && TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7208 {
7209 tree call_decl = SYMBOL_REF_DECL (op);
7210 if (!(call_decl && targetm.binds_local_p (call_decl)))
7211 op = force_reg (word_mode, op);
7212 }
7213 }
7214
7215 if (TARGET_64BIT)
7216 {
7217 if (!virtuals_instantiated)
7218 emit_move_insn (arg_pointer_rtx,
7219 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7220 GEN_INT (64)));
7221 else
7222 {
7223 /* The loop pass can generate new libcalls after the virtual
7224 registers are instantiated when fpregs are disabled because
7225 the only method that we have for doing DImode multiplication
7226 is with a libcall. This could be trouble if we haven't
7227 allocated enough space for the outgoing arguments. */
7228 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7229
7230 emit_move_insn (arg_pointer_rtx,
7231 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7232 GEN_INT (STACK_POINTER_OFFSET + 64)));
7233 }
7234 }
7235
7236 /* Use two different patterns for calls to explicitly named functions
7237 and calls through function pointers. This is necessary as these two
7238 types of calls use different calling conventions, and CSE might try
7239 to change the named call into an indirect call in some cases (using
7240 two patterns keeps CSE from performing this optimization).
7241
7242 We now use even more call patterns as there was a subtle bug in
7243 attempting to restore the pic register after a call using a simple
7244 move insn. During reload, a instruction involving a pseudo register
7245 with no explicit dependence on the PIC register can be converted
7246 to an equivalent load from memory using the PIC register. If we
7247 emit a simple move to restore the PIC register in the initial rtl
7248 generation, then it can potentially be repositioned during scheduling.
7249 and an instruction that eventually uses the PIC register may end up
7250 between the call and the PIC register restore.
7251
7252 This only worked because there is a post call group of instructions
7253 that are scheduled with the call. These instructions are included
7254 in the same basic block as the call. However, calls can throw in
7255 C++ code and a basic block has to terminate at the call if the call
7256 can throw. This results in the PIC register restore being scheduled
7257 independently from the call. So, we now hide the save and restore
7258 of the PIC register in the call pattern until after reload. Then,
7259 we split the moves out. A small side benefit is that we now don't
7260 need to have a use of the PIC register in the return pattern and
7261 the final save/restore operation is not needed.
7262
7263 I elected to just use register %r4 in the PIC patterns instead
7264 of trying to force hppa_pic_save_rtx () to a callee saved register.
7265 This might have required a new register class and constraint. It
7266 was also simpler to just handle the restore from a register than a
7267 generic pseudo. */
7268 if (TARGET_64BIT)
7269 {
7270 rtx r4 = gen_rtx_REG (word_mode, 4);
7271 if (GET_CODE (op) == SYMBOL_REF)
7272 emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7273 else
7274 {
7275 op = force_reg (word_mode, op);
7276 emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7277 }
7278 }
7279 else
7280 {
7281 if (GET_CODE (op) == SYMBOL_REF)
7282 {
7283 if (flag_pic)
7284 {
7285 rtx r4 = gen_rtx_REG (word_mode, 4);
7286 emit_call_insn (gen_call_symref_pic (op, nb, r4));
7287 }
7288 else
7289 emit_call_insn (gen_call_symref (op, nb));
7290 }
7291 else
7292 {
7293 rtx tmpreg = gen_rtx_REG (word_mode, 22);
7294 emit_move_insn (tmpreg, force_reg (word_mode, op));
7295 if (flag_pic)
7296 {
7297 rtx r4 = gen_rtx_REG (word_mode, 4);
7298 emit_call_insn (gen_call_reg_pic (nb, r4));
7299 }
7300 else
7301 emit_call_insn (gen_call_reg (nb));
7302 }
7303 }
7304
7305 DONE;
7306 }")
7307
7308 ;; We use function calls to set the attribute length of calls and millicode
7309 ;; calls. This is necessary because of the large variety of call sequences.
7310 ;; Implementing the calculation in rtl is difficult as well as ugly. As
7311 ;; we need the same calculation in several places, maintenance becomes a
7312 ;; nightmare.
7313 ;;
7314 ;; However, this has a subtle impact on branch shortening. When the
7315 ;; expression used to set the length attribute of an instruction depends
7316 ;; on a relative address (e.g., pc or a branch address), genattrtab
7317 ;; notes that the insn's length is variable, and attempts to determine a
7318 ;; worst-case default length and code to compute an insn's current length.
7319
7320 ;; The use of a function call hides the variable dependence of our calls
7321 ;; and millicode calls. The result is genattrtab doesn't treat the operation
7322 ;; as variable and it only generates code for the default case using our
7323 ;; function call. Because of this, calls and millicode calls have a fixed
7324 ;; length in the branch shortening pass, and some branches will use a longer
7325 ;; code sequence than necessary. However, the length of any given call
7326 ;; will still reflect its final code location and it may be shorter than
7327 ;; the initial length estimate.
7328
7329 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7330 ;; in the set. However, when genattrtab hits a function call in its attempt
7331 ;; to compute the default length, it marks the result as unknown and sets
7332 ;; the default result to MAX_INT ;-( One possible fix that would allow
7333 ;; calls to participate in branch shortening would be to make the call to
7334 ;; insn_default_length a target option. Then, we could massage unknown
7335 ;; results. Another fix might be to change genattrtab so that it just does
7336 ;; the call in the variable case as it already does for the fixed case.
7337
7338 (define_insn "call_symref"
7339 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7340 (match_operand 1 "" "i"))
7341 (clobber (reg:SI 1))
7342 (clobber (reg:SI 2))
7343 (use (const_int 0))]
7344 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7345 "*
7346 {
7347 pa_output_arg_descriptor (insn);
7348 return pa_output_call (insn, operands[0], 0);
7349 }"
7350 [(set_attr "type" "call")
7351 (set (attr "length")
7352 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7353 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7354
7355 (define_insn "call_symref_pic"
7356 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7357 (match_operand 1 "" "i"))
7358 (clobber (reg:SI 1))
7359 (clobber (reg:SI 2))
7360 (clobber (match_operand 2))
7361 (use (reg:SI 19))
7362 (use (const_int 0))]
7363 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7364 "#")
7365
7366 ;; Split out the PIC register save and restore after reload. As the
7367 ;; split is done after reload, there are some situations in which we
7368 ;; unnecessarily save and restore %r4. This happens when there is a
7369 ;; single call and the PIC register is not used after the call.
7370 ;;
7371 ;; The split has to be done since call_from_call_insn () can't handle
7372 ;; the pattern as is. Noreturn calls are special because they have to
7373 ;; terminate the basic block. The split has to contain more than one
7374 ;; insn.
7375 (define_split
7376 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7377 (match_operand 1 "" ""))
7378 (clobber (reg:SI 1))
7379 (clobber (reg:SI 2))
7380 (clobber (match_operand 2))
7381 (use (reg:SI 19))
7382 (use (const_int 0))])]
7383 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7384 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7385 [(set (match_dup 2) (reg:SI 19))
7386 (parallel [(call (mem:SI (match_dup 0))
7387 (match_dup 1))
7388 (clobber (reg:SI 1))
7389 (clobber (reg:SI 2))
7390 (use (reg:SI 19))
7391 (use (const_int 0))])]
7392 "")
7393
7394 (define_split
7395 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7396 (match_operand 1 "" ""))
7397 (clobber (reg:SI 1))
7398 (clobber (reg:SI 2))
7399 (clobber (match_operand 2))
7400 (use (reg:SI 19))
7401 (use (const_int 0))])]
7402 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7403 [(set (match_dup 2) (reg:SI 19))
7404 (parallel [(call (mem:SI (match_dup 0))
7405 (match_dup 1))
7406 (clobber (reg:SI 1))
7407 (clobber (reg:SI 2))
7408 (use (reg:SI 19))
7409 (use (const_int 0))])
7410 (set (reg:SI 19) (match_dup 2))]
7411 "")
7412
7413 (define_insn "*call_symref_pic_post_reload"
7414 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7415 (match_operand 1 "" "i"))
7416 (clobber (reg:SI 1))
7417 (clobber (reg:SI 2))
7418 (use (reg:SI 19))
7419 (use (const_int 0))]
7420 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7421 "*
7422 {
7423 pa_output_arg_descriptor (insn);
7424 return pa_output_call (insn, operands[0], 0);
7425 }"
7426 [(set_attr "type" "call")
7427 (set (attr "length")
7428 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7429 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7430
7431 ;; This pattern is split if it is necessary to save and restore the
7432 ;; PIC register.
7433 (define_insn "call_symref_64bit"
7434 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7435 (match_operand 1 "" "i"))
7436 (clobber (reg:DI 1))
7437 (clobber (reg:DI 2))
7438 (clobber (match_operand 2))
7439 (use (reg:DI 27))
7440 (use (reg:DI 29))
7441 (use (const_int 0))]
7442 "TARGET_64BIT"
7443 "#")
7444
7445 ;; Split out the PIC register save and restore after reload. As the
7446 ;; split is done after reload, there are some situations in which we
7447 ;; unnecessarily save and restore %r4. This happens when there is a
7448 ;; single call and the PIC register is not used after the call.
7449 ;;
7450 ;; The split has to be done since call_from_call_insn () can't handle
7451 ;; the pattern as is. Noreturn calls are special because they have to
7452 ;; terminate the basic block. The split has to contain more than one
7453 ;; insn.
7454 (define_split
7455 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7456 (match_operand 1 "" ""))
7457 (clobber (reg:DI 1))
7458 (clobber (reg:DI 2))
7459 (clobber (match_operand 2))
7460 (use (reg:DI 27))
7461 (use (reg:DI 29))
7462 (use (const_int 0))])]
7463 "TARGET_64BIT && reload_completed
7464 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7465 [(set (match_dup 2) (reg:DI 27))
7466 (parallel [(call (mem:SI (match_dup 0))
7467 (match_dup 1))
7468 (clobber (reg:DI 1))
7469 (clobber (reg:DI 2))
7470 (use (reg:DI 27))
7471 (use (reg:DI 29))
7472 (use (const_int 0))])]
7473 "")
7474
7475 (define_split
7476 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7477 (match_operand 1 "" ""))
7478 (clobber (reg:DI 1))
7479 (clobber (reg:DI 2))
7480 (clobber (match_operand 2))
7481 (use (reg:DI 27))
7482 (use (reg:DI 29))
7483 (use (const_int 0))])]
7484 "TARGET_64BIT && reload_completed"
7485 [(set (match_dup 2) (reg:DI 27))
7486 (parallel [(call (mem:SI (match_dup 0))
7487 (match_dup 1))
7488 (clobber (reg:DI 1))
7489 (clobber (reg:DI 2))
7490 (use (reg:DI 27))
7491 (use (reg:DI 29))
7492 (use (const_int 0))])
7493 (set (reg:DI 27) (match_dup 2))]
7494 "")
7495
7496 (define_insn "*call_symref_64bit_post_reload"
7497 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7498 (match_operand 1 "" "i"))
7499 (clobber (reg:DI 1))
7500 (clobber (reg:DI 2))
7501 (use (reg:DI 27))
7502 (use (reg:DI 29))
7503 (use (const_int 0))]
7504 "TARGET_64BIT"
7505 "*
7506 {
7507 pa_output_arg_descriptor (insn);
7508 return pa_output_call (insn, operands[0], 0);
7509 }"
7510 [(set_attr "type" "call")
7511 (set (attr "length")
7512 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7513 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7514
7515 (define_insn "call_reg"
7516 [(call (mem:SI (reg:SI 22))
7517 (match_operand 0 "" "i"))
7518 (clobber (reg:SI 1))
7519 (clobber (reg:SI 2))
7520 (use (const_int 1))]
7521 "!TARGET_64BIT"
7522 "*
7523 {
7524 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7525 }"
7526 [(set_attr "type" "dyncall")
7527 (set (attr "length")
7528 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7529 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7530
7531 ;; This pattern is split if it is necessary to save and restore the
7532 ;; PIC register.
7533 (define_insn "call_reg_pic"
7534 [(call (mem:SI (reg:SI 22))
7535 (match_operand 0 "" "i"))
7536 (clobber (reg:SI 1))
7537 (clobber (reg:SI 2))
7538 (clobber (match_operand 1))
7539 (use (reg:SI 19))
7540 (use (const_int 1))]
7541 "!TARGET_64BIT"
7542 "#")
7543
7544 ;; Split out the PIC register save and restore after reload. As the
7545 ;; split is done after reload, there are some situations in which we
7546 ;; unnecessarily save and restore %r4. This happens when there is a
7547 ;; single call and the PIC register is not used after the call.
7548 ;;
7549 ;; The split has to be done since call_from_call_insn () can't handle
7550 ;; the pattern as is. Noreturn calls are special because they have to
7551 ;; terminate the basic block. The split has to contain more than one
7552 ;; insn.
7553 (define_split
7554 [(parallel [(call (mem:SI (reg:SI 22))
7555 (match_operand 0 "" ""))
7556 (clobber (reg:SI 1))
7557 (clobber (reg:SI 2))
7558 (clobber (match_operand 1))
7559 (use (reg:SI 19))
7560 (use (const_int 1))])]
7561 "!TARGET_64BIT && reload_completed
7562 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7563 [(set (match_dup 1) (reg:SI 19))
7564 (parallel [(call (mem:SI (reg:SI 22))
7565 (match_dup 0))
7566 (clobber (reg:SI 1))
7567 (clobber (reg:SI 2))
7568 (use (reg:SI 19))
7569 (use (const_int 1))])]
7570 "")
7571
7572 (define_split
7573 [(parallel [(call (mem:SI (reg:SI 22))
7574 (match_operand 0 "" ""))
7575 (clobber (reg:SI 1))
7576 (clobber (reg:SI 2))
7577 (clobber (match_operand 1))
7578 (use (reg:SI 19))
7579 (use (const_int 1))])]
7580 "!TARGET_64BIT && reload_completed"
7581 [(set (match_dup 1) (reg:SI 19))
7582 (parallel [(call (mem:SI (reg:SI 22))
7583 (match_dup 0))
7584 (clobber (reg:SI 1))
7585 (clobber (reg:SI 2))
7586 (use (reg:SI 19))
7587 (use (const_int 1))])
7588 (set (reg:SI 19) (match_dup 1))]
7589 "")
7590
7591 (define_insn "*call_reg_pic_post_reload"
7592 [(call (mem:SI (reg:SI 22))
7593 (match_operand 0 "" "i"))
7594 (clobber (reg:SI 1))
7595 (clobber (reg:SI 2))
7596 (use (reg:SI 19))
7597 (use (const_int 1))]
7598 "!TARGET_64BIT"
7599 "*
7600 {
7601 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7602 }"
7603 [(set_attr "type" "dyncall")
7604 (set (attr "length")
7605 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7606 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7607
7608 ;; This pattern is split if it is necessary to save and restore the
7609 ;; PIC register.
7610 (define_insn "call_reg_64bit"
7611 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7612 (match_operand 1 "" "i"))
7613 (clobber (reg:DI 2))
7614 (clobber (match_operand 2))
7615 (use (reg:DI 27))
7616 (use (reg:DI 29))
7617 (use (const_int 1))]
7618 "TARGET_64BIT"
7619 "#")
7620
7621 ;; Split out the PIC register save and restore after reload. As the
7622 ;; split is done after reload, there are some situations in which we
7623 ;; unnecessarily save and restore %r4. This happens when there is a
7624 ;; single call and the PIC register is not used after the call.
7625 ;;
7626 ;; The split has to be done since call_from_call_insn () can't handle
7627 ;; the pattern as is. Noreturn calls are special because they have to
7628 ;; terminate the basic block. The split has to contain more than one
7629 ;; insn.
7630 (define_split
7631 [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7632 (match_operand 1 "" ""))
7633 (clobber (reg:DI 2))
7634 (clobber (match_operand 2))
7635 (use (reg:DI 27))
7636 (use (reg:DI 29))
7637 (use (const_int 1))])]
7638 "TARGET_64BIT && reload_completed
7639 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7640 [(set (match_dup 2) (reg:DI 27))
7641 (parallel [(call (mem:SI (match_dup 0))
7642 (match_dup 1))
7643 (clobber (reg:DI 2))
7644 (use (reg:DI 27))
7645 (use (reg:DI 29))
7646 (use (const_int 1))])]
7647 "")
7648
7649 (define_split
7650 [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7651 (match_operand 1 "" ""))
7652 (clobber (reg:DI 2))
7653 (clobber (match_operand 2))
7654 (use (reg:DI 27))
7655 (use (reg:DI 29))
7656 (use (const_int 1))])]
7657 "TARGET_64BIT && reload_completed"
7658 [(set (match_dup 2) (reg:DI 27))
7659 (parallel [(call (mem:SI (match_dup 0))
7660 (match_dup 1))
7661 (clobber (reg:DI 2))
7662 (use (reg:DI 27))
7663 (use (reg:DI 29))
7664 (use (const_int 1))])
7665 (set (reg:DI 27) (match_dup 2))]
7666 "")
7667
7668 (define_insn "*call_reg_64bit_post_reload"
7669 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7670 (match_operand 1 "" "i"))
7671 (clobber (reg:DI 2))
7672 (use (reg:DI 27))
7673 (use (reg:DI 29))
7674 (use (const_int 1))]
7675 "TARGET_64BIT"
7676 "*
7677 {
7678 return pa_output_indirect_call (insn, operands[0]);
7679 }"
7680 [(set_attr "type" "dyncall")
7681 (set (attr "length")
7682 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7683 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7684
7685 (define_expand "call_value"
7686 [(parallel [(set (match_operand 0 "" "")
7687 (call (match_operand:SI 1 "" "")
7688 (match_operand 2 "" "")))
7689 (clobber (reg:SI 2))])]
7690 ""
7691 {
7692 rtx op;
7693 rtx dst = operands[0];
7694 rtx nb = operands[2];
7695 bool call_powf = false;
7696
7697 if (TARGET_PORTABLE_RUNTIME)
7698 op = force_reg (SImode, XEXP (operands[1], 0));
7699 else
7700 {
7701 op = XEXP (operands[1], 0);
7702 if (GET_CODE (op) == SYMBOL_REF)
7703 {
7704 /* Handle special call to buggy powf function. */
7705 if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
7706 && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7707 call_powf = true;
7708
7709 /* Generate indirect long calls to non-local functions. */
7710 else if (!TARGET_64BIT && TARGET_LONG_CALLS)
7711 {
7712 tree call_decl = SYMBOL_REF_DECL (op);
7713 if (!(call_decl && targetm.binds_local_p (call_decl)))
7714 op = force_reg (word_mode, op);
7715 }
7716 }
7717 }
7718
7719 if (TARGET_64BIT)
7720 {
7721 if (!virtuals_instantiated)
7722 emit_move_insn (arg_pointer_rtx,
7723 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7724 GEN_INT (64)));
7725 else
7726 {
7727 /* The loop pass can generate new libcalls after the virtual
7728 registers are instantiated when fpregs are disabled because
7729 the only method that we have for doing DImode multiplication
7730 is with a libcall. This could be trouble if we haven't
7731 allocated enough space for the outgoing arguments. */
7732 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7733
7734 emit_move_insn (arg_pointer_rtx,
7735 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7736 GEN_INT (STACK_POINTER_OFFSET + 64)));
7737 }
7738 }
7739
7740 /* Use two different patterns for calls to explicitly named functions
7741 and calls through function pointers. This is necessary as these two
7742 types of calls use different calling conventions, and CSE might try
7743 to change the named call into an indirect call in some cases (using
7744 two patterns keeps CSE from performing this optimization).
7745
7746 We now use even more call patterns as there was a subtle bug in
7747 attempting to restore the pic register after a call using a simple
7748 move insn. During reload, a instruction involving a pseudo register
7749 with no explicit dependence on the PIC register can be converted
7750 to an equivalent load from memory using the PIC register. If we
7751 emit a simple move to restore the PIC register in the initial rtl
7752 generation, then it can potentially be repositioned during scheduling.
7753 and an instruction that eventually uses the PIC register may end up
7754 between the call and the PIC register restore.
7755
7756 This only worked because there is a post call group of instructions
7757 that are scheduled with the call. These instructions are included
7758 in the same basic block as the call. However, calls can throw in
7759 C++ code and a basic block has to terminate at the call if the call
7760 can throw. This results in the PIC register restore being scheduled
7761 independently from the call. So, we now hide the save and restore
7762 of the PIC register in the call pattern until after reload. Then,
7763 we split the moves out. A small side benefit is that we now don't
7764 need to have a use of the PIC register in the return pattern and
7765 the final save/restore operation is not needed.
7766
7767 I elected to just use register %r4 in the PIC patterns instead
7768 of trying to force hppa_pic_save_rtx () to a callee saved register.
7769 This might have required a new register class and constraint. It
7770 was also simpler to just handle the restore from a register than a
7771 generic pseudo. */
7772 if (TARGET_64BIT)
7773 {
7774 rtx r4 = gen_rtx_REG (word_mode, 4);
7775 if (GET_CODE (op) == SYMBOL_REF)
7776 {
7777 if (call_powf)
7778 emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
7779 else
7780 emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7781 }
7782 else
7783 {
7784 op = force_reg (word_mode, op);
7785 emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7786 }
7787 }
7788 else
7789 {
7790 if (GET_CODE (op) == SYMBOL_REF)
7791 {
7792 if (flag_pic)
7793 {
7794 rtx r4 = gen_rtx_REG (word_mode, 4);
7795
7796 if (call_powf)
7797 emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
7798 else
7799 emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7800 }
7801 else
7802 {
7803 if (call_powf)
7804 emit_call_insn (gen_call_val_powf (dst, op, nb));
7805 else
7806 emit_call_insn (gen_call_val_symref (dst, op, nb));
7807 }
7808 }
7809 else
7810 {
7811 rtx tmpreg = gen_rtx_REG (word_mode, 22);
7812 emit_move_insn (tmpreg, force_reg (word_mode, op));
7813 if (flag_pic)
7814 {
7815 rtx r4 = gen_rtx_REG (word_mode, 4);
7816 emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7817 }
7818 else
7819 emit_call_insn (gen_call_val_reg (dst, nb));
7820 }
7821 }
7822
7823 DONE;
7824 })
7825
7826 (define_insn "call_val_symref"
7827 [(set (match_operand 0 "" "")
7828 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7829 (match_operand 2 "" "i")))
7830 (clobber (reg:SI 1))
7831 (clobber (reg:SI 2))
7832 (use (const_int 0))]
7833 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7834 "*
7835 {
7836 pa_output_arg_descriptor (insn);
7837 return pa_output_call (insn, operands[1], 0);
7838 }"
7839 [(set_attr "type" "call")
7840 (set (attr "length")
7841 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7842 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7843
7844 ;; powf function clobbers %fr12
7845 (define_insn "call_val_powf"
7846 [(set (match_operand 0 "" "")
7847 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7848 (match_operand 2 "" "i")))
7849 (clobber (reg:SI 1))
7850 (clobber (reg:SI 2))
7851 (clobber (reg:DF 48))
7852 (use (const_int 1))]
7853 "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7854 "*
7855 {
7856 pa_output_arg_descriptor (insn);
7857 return pa_output_call (insn, operands[1], 0);
7858 }"
7859 [(set_attr "type" "call")
7860 (set (attr "length")
7861 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7862 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7863
7864 (define_insn "call_val_symref_pic"
7865 [(set (match_operand 0 "" "")
7866 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7867 (match_operand 2 "" "i")))
7868 (clobber (reg:SI 1))
7869 (clobber (reg:SI 2))
7870 (clobber (match_operand 3))
7871 (use (reg:SI 19))
7872 (use (const_int 0))]
7873 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7874 "#")
7875
7876 ;; Split out the PIC register save and restore after reload. As the
7877 ;; split is done after reload, there are some situations in which we
7878 ;; unnecessarily save and restore %r4. This happens when there is a
7879 ;; single call and the PIC register is not used after the call.
7880 ;;
7881 ;; The split has to be done since call_from_call_insn () can't handle
7882 ;; the pattern as is. Noreturn calls are special because they have to
7883 ;; terminate the basic block. The split has to contain more than one
7884 ;; insn.
7885 (define_split
7886 [(parallel [(set (match_operand 0 "" "")
7887 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7888 (match_operand 2 "" "")))
7889 (clobber (reg:SI 1))
7890 (clobber (reg:SI 2))
7891 (clobber (match_operand 3))
7892 (use (reg:SI 19))
7893 (use (const_int 0))])]
7894 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7895 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7896 [(set (match_dup 3) (reg:SI 19))
7897 (parallel [(set (match_dup 0)
7898 (call (mem:SI (match_dup 1))
7899 (match_dup 2)))
7900 (clobber (reg:SI 1))
7901 (clobber (reg:SI 2))
7902 (use (reg:SI 19))
7903 (use (const_int 0))])]
7904 "")
7905
7906 (define_split
7907 [(parallel [(set (match_operand 0 "" "")
7908 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7909 (match_operand 2 "" "")))
7910 (clobber (reg:SI 1))
7911 (clobber (reg:SI 2))
7912 (clobber (match_operand 3))
7913 (use (reg:SI 19))
7914 (use (const_int 0))])]
7915 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7916 [(set (match_dup 3) (reg:SI 19))
7917 (parallel [(set (match_dup 0)
7918 (call (mem:SI (match_dup 1))
7919 (match_dup 2)))
7920 (clobber (reg:SI 1))
7921 (clobber (reg:SI 2))
7922 (use (reg:SI 19))
7923 (use (const_int 0))])
7924 (set (reg:SI 19) (match_dup 3))]
7925 "")
7926
7927 (define_insn "*call_val_symref_pic_post_reload"
7928 [(set (match_operand 0 "" "")
7929 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7930 (match_operand 2 "" "i")))
7931 (clobber (reg:SI 1))
7932 (clobber (reg:SI 2))
7933 (use (reg:SI 19))
7934 (use (const_int 0))]
7935 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7936 "*
7937 {
7938 pa_output_arg_descriptor (insn);
7939 return pa_output_call (insn, operands[1], 0);
7940 }"
7941 [(set_attr "type" "call")
7942 (set (attr "length")
7943 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7944 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7945
7946 ;; powf function clobbers %fr12
7947 (define_insn "call_val_powf_pic"
7948 [(set (match_operand 0 "" "")
7949 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7950 (match_operand 2 "" "i")))
7951 (clobber (reg:SI 1))
7952 (clobber (reg:SI 2))
7953 (clobber (reg:DF 48))
7954 (clobber (match_operand 3))
7955 (use (reg:SI 19))
7956 (use (const_int 1))]
7957 "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7958 "#")
7959
7960 ;; Split out the PIC register save and restore after reload. As the
7961 ;; split is done after reload, there are some situations in which we
7962 ;; unnecessarily save and restore %r4. This happens when there is a
7963 ;; single call and the PIC register is not used after the call.
7964 ;;
7965 ;; The split has to be done since call_from_call_insn () can't handle
7966 ;; the pattern as is. Noreturn calls are special because they have to
7967 ;; terminate the basic block. The split has to contain more than one
7968 ;; insn.
7969 (define_split
7970 [(parallel [(set (match_operand 0 "" "")
7971 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7972 (match_operand 2 "" "")))
7973 (clobber (reg:SI 1))
7974 (clobber (reg:SI 2))
7975 (clobber (reg:DF 48))
7976 (clobber (match_operand 3))
7977 (use (reg:SI 19))
7978 (use (const_int 1))])]
7979 "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7980 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7981 [(set (match_dup 3) (reg:SI 19))
7982 (parallel [(set (match_dup 0)
7983 (call (mem:SI (match_dup 1))
7984 (match_dup 2)))
7985 (clobber (reg:SI 1))
7986 (clobber (reg:SI 2))
7987 (clobber (reg:DF 48))
7988 (use (reg:SI 19))
7989 (use (const_int 1))])]
7990 "")
7991
7992 (define_split
7993 [(parallel [(set (match_operand 0 "" "")
7994 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7995 (match_operand 2 "" "")))
7996 (clobber (reg:SI 1))
7997 (clobber (reg:SI 2))
7998 (clobber (reg:DF 48))
7999 (clobber (match_operand 3))
8000 (use (reg:SI 19))
8001 (use (const_int 1))])]
8002 "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8003 [(set (match_dup 3) (reg:SI 19))
8004 (parallel [(set (match_dup 0)
8005 (call (mem:SI (match_dup 1))
8006 (match_dup 2)))
8007 (clobber (reg:SI 1))
8008 (clobber (reg:SI 2))
8009 (clobber (reg:DF 48))
8010 (use (reg:SI 19))
8011 (use (const_int 1))])
8012 (set (reg:SI 19) (match_dup 3))]
8013 "")
8014
8015 (define_insn "*call_val_powf_pic_post_reload"
8016 [(set (match_operand 0 "" "")
8017 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8018 (match_operand 2 "" "i")))
8019 (clobber (reg:SI 1))
8020 (clobber (reg:SI 2))
8021 (clobber (reg:DF 48))
8022 (use (reg:SI 19))
8023 (use (const_int 1))]
8024 "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8025 "*
8026 {
8027 pa_output_arg_descriptor (insn);
8028 return pa_output_call (insn, operands[1], 0);
8029 }"
8030 [(set_attr "type" "call")
8031 (set (attr "length")
8032 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8033 (symbol_ref "pa_attr_length_call (insn, 0)")))])
8034
8035 ;; This pattern is split if it is necessary to save and restore the
8036 ;; PIC register.
8037 (define_insn "call_val_symref_64bit"
8038 [(set (match_operand 0 "" "")
8039 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8040 (match_operand 2 "" "i")))
8041 (clobber (reg:DI 1))
8042 (clobber (reg:DI 2))
8043 (clobber (match_operand 3))
8044 (use (reg:DI 27))
8045 (use (reg:DI 29))
8046 (use (const_int 0))]
8047 "TARGET_64BIT"
8048 "#")
8049
8050 ;; Split out the PIC register save and restore after reload. As the
8051 ;; split is done after reload, there are some situations in which we
8052 ;; unnecessarily save and restore %r4. This happens when there is a
8053 ;; single call and the PIC register is not used after the call.
8054 ;;
8055 ;; The split has to be done since call_from_call_insn () can't handle
8056 ;; the pattern as is. Noreturn calls are special because they have to
8057 ;; terminate the basic block. The split has to contain more than one
8058 ;; insn.
8059 (define_split
8060 [(parallel [(set (match_operand 0 "" "")
8061 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8062 (match_operand 2 "" "")))
8063 (clobber (reg:DI 1))
8064 (clobber (reg:DI 2))
8065 (clobber (match_operand 3))
8066 (use (reg:DI 27))
8067 (use (reg:DI 29))
8068 (use (const_int 0))])]
8069 "TARGET_64BIT && reload_completed
8070 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8071 [(set (match_dup 3) (reg:DI 27))
8072 (parallel [(set (match_dup 0)
8073 (call (mem:SI (match_dup 1))
8074 (match_dup 2)))
8075 (clobber (reg:DI 1))
8076 (clobber (reg:DI 2))
8077 (use (reg:DI 27))
8078 (use (reg:DI 29))
8079 (use (const_int 0))])]
8080 "")
8081
8082 (define_split
8083 [(parallel [(set (match_operand 0 "" "")
8084 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8085 (match_operand 2 "" "")))
8086 (clobber (reg:DI 1))
8087 (clobber (reg:DI 2))
8088 (clobber (match_operand 3))
8089 (use (reg:DI 27))
8090 (use (reg:DI 29))
8091 (use (const_int 0))])]
8092 "TARGET_64BIT && reload_completed"
8093 [(set (match_dup 3) (reg:DI 27))
8094 (parallel [(set (match_dup 0)
8095 (call (mem:SI (match_dup 1))
8096 (match_dup 2)))
8097 (clobber (reg:DI 1))
8098 (clobber (reg:DI 2))
8099 (use (reg:DI 27))
8100 (use (reg:DI 29))
8101 (use (const_int 0))])
8102 (set (reg:DI 27) (match_dup 3))]
8103 "")
8104
8105 (define_insn "*call_val_symref_64bit_post_reload"
8106 [(set (match_operand 0 "" "")
8107 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8108 (match_operand 2 "" "i")))
8109 (clobber (reg:DI 1))
8110 (clobber (reg:DI 2))
8111 (use (reg:DI 27))
8112 (use (reg:DI 29))
8113 (use (const_int 0))]
8114 "TARGET_64BIT"
8115 "*
8116 {
8117 pa_output_arg_descriptor (insn);
8118 return pa_output_call (insn, operands[1], 0);
8119 }"
8120 [(set_attr "type" "call")
8121 (set (attr "length")
8122 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8123 (symbol_ref "pa_attr_length_call (insn, 0)")))])
8124
8125 ;; powf function clobbers %fr12
8126 (define_insn "call_val_powf_64bit"
8127 [(set (match_operand 0 "" "")
8128 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8129 (match_operand 2 "" "i")))
8130 (clobber (reg:DI 1))
8131 (clobber (reg:DI 2))
8132 (clobber (reg:DF 40))
8133 (clobber (match_operand 3))
8134 (use (reg:DI 27))
8135 (use (reg:DI 29))
8136 (use (const_int 1))]
8137 "TARGET_64BIT && TARGET_HPUX"
8138 "#")
8139
8140 ;; Split out the PIC register save and restore after reload. As the
8141 ;; split is done after reload, there are some situations in which we
8142 ;; unnecessarily save and restore %r4. This happens when there is a
8143 ;; single call and the PIC register is not used after the call.
8144 ;;
8145 ;; The split has to be done since call_from_call_insn () can't handle
8146 ;; the pattern as is. Noreturn calls are special because they have to
8147 ;; terminate the basic block. The split has to contain more than one
8148 ;; insn.
8149 (define_split
8150 [(parallel [(set (match_operand 0 "" "")
8151 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8152 (match_operand 2 "" "")))
8153 (clobber (reg:DI 1))
8154 (clobber (reg:DI 2))
8155 (clobber (reg:DF 40))
8156 (clobber (match_operand 3))
8157 (use (reg:DI 27))
8158 (use (reg:DI 29))
8159 (use (const_int 1))])]
8160 "TARGET_64BIT && TARGET_HPUX && reload_completed
8161 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8162 [(set (match_dup 3) (reg:DI 27))
8163 (parallel [(set (match_dup 0)
8164 (call (mem:SI (match_dup 1))
8165 (match_dup 2)))
8166 (clobber (reg:DI 1))
8167 (clobber (reg:DI 2))
8168 (clobber (reg:DF 40))
8169 (use (reg:DI 27))
8170 (use (reg:DI 29))
8171 (use (const_int 1))])]
8172 "")
8173
8174 (define_split
8175 [(parallel [(set (match_operand 0 "" "")
8176 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8177 (match_operand 2 "" "")))
8178 (clobber (reg:DI 1))
8179 (clobber (reg:DI 2))
8180 (clobber (reg:DF 40))
8181 (clobber (match_operand 3))
8182 (use (reg:DI 27))
8183 (use (reg:DI 29))
8184 (use (const_int 1))])]
8185 "TARGET_64BIT && TARGET_HPUX && reload_completed"
8186 [(set (match_dup 3) (reg:DI 27))
8187 (parallel [(set (match_dup 0)
8188 (call (mem:SI (match_dup 1))
8189 (match_dup 2)))
8190 (clobber (reg:DI 1))
8191 (clobber (reg:DI 2))
8192 (clobber (reg:DF 40))
8193 (use (reg:DI 27))
8194 (use (reg:DI 29))
8195 (use (const_int 1))])
8196 (set (reg:DI 27) (match_dup 3))]
8197 "")
8198
8199 (define_insn "*call_val_powf_64bit_post_reload"
8200 [(set (match_operand 0 "" "")
8201 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8202 (match_operand 2 "" "i")))
8203 (clobber (reg:DI 1))
8204 (clobber (reg:DI 2))
8205 (clobber (reg:DF 40))
8206 (use (reg:DI 27))
8207 (use (reg:DI 29))
8208 (use (const_int 1))]
8209 "TARGET_64BIT && TARGET_HPUX"
8210 "*
8211 {
8212 pa_output_arg_descriptor (insn);
8213 return pa_output_call (insn, operands[1], 0);
8214 }"
8215 [(set_attr "type" "call")
8216 (set (attr "length")
8217 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8218 (symbol_ref "pa_attr_length_call (insn, 0)")))])
8219
8220 (define_insn "call_val_reg"
8221 [(set (match_operand 0 "" "")
8222 (call (mem:SI (reg:SI 22))
8223 (match_operand 1 "" "i")))
8224 (clobber (reg:SI 1))
8225 (clobber (reg:SI 2))
8226 (use (const_int 1))]
8227 "!TARGET_64BIT"
8228 "*
8229 {
8230 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8231 }"
8232 [(set_attr "type" "dyncall")
8233 (set (attr "length")
8234 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8235 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8236
8237 ;; This pattern is split if it is necessary to save and restore the
8238 ;; PIC register.
8239 (define_insn "call_val_reg_pic"
8240 [(set (match_operand 0 "" "")
8241 (call (mem:SI (reg:SI 22))
8242 (match_operand 1 "" "i")))
8243 (clobber (reg:SI 1))
8244 (clobber (reg:SI 2))
8245 (clobber (match_operand 2))
8246 (use (reg:SI 19))
8247 (use (const_int 1))]
8248 "!TARGET_64BIT"
8249 "#")
8250
8251 ;; Split out the PIC register save and restore after reload. As the
8252 ;; split is done after reload, there are some situations in which we
8253 ;; unnecessarily save and restore %r4. This happens when there is a
8254 ;; single call and the PIC register is not used after the call.
8255 ;;
8256 ;; The split has to be done since call_from_call_insn () can't handle
8257 ;; the pattern as is. Noreturn calls are special because they have to
8258 ;; terminate the basic block. The split has to contain more than one
8259 ;; insn.
8260 (define_split
8261 [(parallel [(set (match_operand 0 "" "")
8262 (call (mem:SI (reg:SI 22))
8263 (match_operand 1 "" "")))
8264 (clobber (reg:SI 1))
8265 (clobber (reg:SI 2))
8266 (clobber (match_operand 2))
8267 (use (reg:SI 19))
8268 (use (const_int 1))])]
8269 "!TARGET_64BIT && reload_completed
8270 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8271 [(set (match_dup 2) (reg:SI 19))
8272 (parallel [(set (match_dup 0)
8273 (call (mem:SI (reg:SI 22))
8274 (match_dup 1)))
8275 (clobber (reg:SI 1))
8276 (clobber (reg:SI 2))
8277 (use (reg:SI 19))
8278 (use (const_int 1))])]
8279 "")
8280
8281 (define_split
8282 [(parallel [(set (match_operand 0 "" "")
8283 (call (mem:SI (reg:SI 22))
8284 (match_operand 1 "" "")))
8285 (clobber (reg:SI 1))
8286 (clobber (reg:SI 2))
8287 (clobber (match_operand 2))
8288 (use (reg:SI 19))
8289 (use (const_int 1))])]
8290 "!TARGET_64BIT && reload_completed"
8291 [(set (match_dup 2) (reg:SI 19))
8292 (parallel [(set (match_dup 0)
8293 (call (mem:SI (reg:SI 22))
8294 (match_dup 1)))
8295 (clobber (reg:SI 1))
8296 (clobber (reg:SI 2))
8297 (use (reg:SI 19))
8298 (use (const_int 1))])
8299 (set (reg:SI 19) (match_dup 2))]
8300 "")
8301
8302 (define_insn "*call_val_reg_pic_post_reload"
8303 [(set (match_operand 0 "" "")
8304 (call (mem:SI (reg:SI 22))
8305 (match_operand 1 "" "i")))
8306 (clobber (reg:SI 1))
8307 (clobber (reg:SI 2))
8308 (use (reg:SI 19))
8309 (use (const_int 1))]
8310 "!TARGET_64BIT"
8311 "*
8312 {
8313 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8314 }"
8315 [(set_attr "type" "dyncall")
8316 (set (attr "length")
8317 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8318 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8319
8320 ;; This pattern is split if it is necessary to save and restore the
8321 ;; PIC register.
8322 (define_insn "call_val_reg_64bit"
8323 [(set (match_operand 0 "" "")
8324 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8325 (match_operand 2 "" "i")))
8326 (clobber (reg:DI 1))
8327 (clobber (reg:DI 2))
8328 (clobber (match_operand 3))
8329 (use (reg:DI 27))
8330 (use (reg:DI 29))
8331 (use (const_int 1))]
8332 "TARGET_64BIT"
8333 "#")
8334
8335 ;; Split out the PIC register save and restore after reload. As the
8336 ;; split is done after reload, there are some situations in which we
8337 ;; unnecessarily save and restore %r4. This happens when there is a
8338 ;; single call and the PIC register is not used after the call.
8339 ;;
8340 ;; The split has to be done since call_from_call_insn () can't handle
8341 ;; the pattern as is. Noreturn calls are special because they have to
8342 ;; terminate the basic block. The split has to contain more than one
8343 ;; insn.
8344 (define_split
8345 [(parallel [(set (match_operand 0 "" "")
8346 (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8347 (match_operand 2 "" "")))
8348 (clobber (reg:DI 1))
8349 (clobber (reg:DI 2))
8350 (clobber (match_operand 3))
8351 (use (reg:DI 27))
8352 (use (reg:DI 29))
8353 (use (const_int 1))])]
8354 "TARGET_64BIT && reload_completed
8355 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8356 [(set (match_dup 3) (reg:DI 27))
8357 (parallel [(set (match_dup 0)
8358 (call (mem:SI (match_dup 1))
8359 (match_dup 2)))
8360 (clobber (reg:DI 1))
8361 (clobber (reg:DI 2))
8362 (use (reg:DI 27))
8363 (use (reg:DI 29))
8364 (use (const_int 1))])]
8365 "")
8366
8367 (define_split
8368 [(parallel [(set (match_operand 0 "" "")
8369 (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8370 (match_operand 2 "" "")))
8371 (clobber (reg:DI 1))
8372 (clobber (reg:DI 2))
8373 (clobber (match_operand 3))
8374 (use (reg:DI 27))
8375 (use (reg:DI 29))
8376 (use (const_int 1))])]
8377 "TARGET_64BIT && reload_completed"
8378 [(set (match_dup 3) (reg:DI 27))
8379 (parallel [(set (match_dup 0)
8380 (call (mem:SI (match_dup 1))
8381 (match_dup 2)))
8382 (clobber (reg:DI 1))
8383 (clobber (reg:DI 2))
8384 (use (reg:DI 27))
8385 (use (reg:DI 29))
8386 (use (const_int 1))])
8387 (set (reg:DI 27) (match_dup 3))]
8388 "")
8389
8390 (define_insn "*call_val_reg_64bit_post_reload"
8391 [(set (match_operand 0 "" "")
8392 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8393 (match_operand 2 "" "i")))
8394 (clobber (reg:DI 1))
8395 (clobber (reg:DI 2))
8396 (use (reg:DI 27))
8397 (use (reg:DI 29))
8398 (use (const_int 1))]
8399 "TARGET_64BIT"
8400 "*
8401 {
8402 return pa_output_indirect_call (insn, operands[1]);
8403 }"
8404 [(set_attr "type" "dyncall")
8405 (set (attr "length")
8406 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8407 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8408
8409 ;; Call subroutine returning any type.
8410
8411 (define_expand "untyped_call"
8412 [(parallel [(call (match_operand 0 "" "")
8413 (const_int 0))
8414 (match_operand 1 "" "")
8415 (match_operand 2 "" "")])]
8416 ""
8417 "
8418 {
8419 int i;
8420
8421 emit_call_insn (gen_call (operands[0], const0_rtx));
8422
8423 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8424 {
8425 rtx set = XVECEXP (operands[2], 0, i);
8426 emit_move_insn (SET_DEST (set), SET_SRC (set));
8427 }
8428
8429 /* The optimizer does not know that the call sets the function value
8430 registers we stored in the result block. We avoid problems by
8431 claiming that all hard registers are used and clobbered at this
8432 point. */
8433 emit_insn (gen_blockage ());
8434
8435 DONE;
8436 }")
8437
8438 (define_expand "sibcall"
8439 [(call (match_operand:SI 0 "" "")
8440 (match_operand 1 "" ""))]
8441 "!TARGET_PORTABLE_RUNTIME"
8442 "
8443 {
8444 rtx op, call_insn;
8445 rtx nb = operands[1];
8446
8447 op = XEXP (operands[0], 0);
8448
8449 if (TARGET_64BIT)
8450 {
8451 if (!virtuals_instantiated)
8452 emit_move_insn (arg_pointer_rtx,
8453 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8454 GEN_INT (64)));
8455 else
8456 {
8457 /* The loop pass can generate new libcalls after the virtual
8458 registers are instantiated when fpregs are disabled because
8459 the only method that we have for doing DImode multiplication
8460 is with a libcall. This could be trouble if we haven't
8461 allocated enough space for the outgoing arguments. */
8462 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8463
8464 emit_move_insn (arg_pointer_rtx,
8465 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8466 GEN_INT (STACK_POINTER_OFFSET + 64)));
8467 }
8468 }
8469
8470 /* Indirect sibling calls are not allowed. */
8471 if (TARGET_64BIT)
8472 call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8473 else
8474 call_insn = gen_sibcall_internal_symref (op, operands[1]);
8475
8476 call_insn = emit_call_insn (call_insn);
8477
8478 if (TARGET_64BIT)
8479 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8480
8481 /* We don't have to restore the PIC register. */
8482 if (flag_pic)
8483 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8484
8485 DONE;
8486 }")
8487
8488 (define_insn "sibcall_internal_symref"
8489 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8490 (match_operand 1 "" "i"))
8491 (clobber (reg:SI 1))
8492 (use (reg:SI 2))
8493 (use (const_int 0))]
8494 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8495 "*
8496 {
8497 pa_output_arg_descriptor (insn);
8498 return pa_output_call (insn, operands[0], 1);
8499 }"
8500 [(set_attr "type" "sibcall")
8501 (set (attr "length")
8502 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8503 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8504
8505 (define_insn "sibcall_internal_symref_64bit"
8506 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8507 (match_operand 1 "" "i"))
8508 (clobber (reg:DI 1))
8509 (use (reg:DI 2))
8510 (use (const_int 0))]
8511 "TARGET_64BIT"
8512 "*
8513 {
8514 pa_output_arg_descriptor (insn);
8515 return pa_output_call (insn, operands[0], 1);
8516 }"
8517 [(set_attr "type" "sibcall")
8518 (set (attr "length")
8519 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8520 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8521
8522 (define_expand "sibcall_value"
8523 [(set (match_operand 0 "" "")
8524 (call (match_operand:SI 1 "" "")
8525 (match_operand 2 "" "")))]
8526 "!TARGET_PORTABLE_RUNTIME"
8527 "
8528 {
8529 rtx op, call_insn;
8530 rtx nb = operands[1];
8531
8532 op = XEXP (operands[1], 0);
8533
8534 if (TARGET_64BIT)
8535 {
8536 if (!virtuals_instantiated)
8537 emit_move_insn (arg_pointer_rtx,
8538 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8539 GEN_INT (64)));
8540 else
8541 {
8542 /* The loop pass can generate new libcalls after the virtual
8543 registers are instantiated when fpregs are disabled because
8544 the only method that we have for doing DImode multiplication
8545 is with a libcall. This could be trouble if we haven't
8546 allocated enough space for the outgoing arguments. */
8547 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8548
8549 emit_move_insn (arg_pointer_rtx,
8550 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8551 GEN_INT (STACK_POINTER_OFFSET + 64)));
8552 }
8553 }
8554
8555 /* Indirect sibling calls are not allowed. */
8556 if (TARGET_64BIT)
8557 call_insn
8558 = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8559 else
8560 call_insn
8561 = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8562
8563 call_insn = emit_call_insn (call_insn);
8564
8565 if (TARGET_64BIT)
8566 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8567
8568 /* We don't have to restore the PIC register. */
8569 if (flag_pic)
8570 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8571
8572 DONE;
8573 }")
8574
8575 (define_insn "sibcall_value_internal_symref"
8576 [(set (match_operand 0 "" "")
8577 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8578 (match_operand 2 "" "i")))
8579 (clobber (reg:SI 1))
8580 (use (reg:SI 2))
8581 (use (const_int 0))]
8582 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8583 "*
8584 {
8585 pa_output_arg_descriptor (insn);
8586 return pa_output_call (insn, operands[1], 1);
8587 }"
8588 [(set_attr "type" "sibcall")
8589 (set (attr "length")
8590 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8591 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8592
8593 (define_insn "sibcall_value_internal_symref_64bit"
8594 [(set (match_operand 0 "" "")
8595 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8596 (match_operand 2 "" "i")))
8597 (clobber (reg:DI 1))
8598 (use (reg:DI 2))
8599 (use (const_int 0))]
8600 "TARGET_64BIT"
8601 "*
8602 {
8603 pa_output_arg_descriptor (insn);
8604 return pa_output_call (insn, operands[1], 1);
8605 }"
8606 [(set_attr "type" "sibcall")
8607 (set (attr "length")
8608 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8609 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8610
8611 (define_insn "nop"
8612 [(const_int 0)]
8613 ""
8614 "nop"
8615 [(set_attr "type" "move")
8616 (set_attr "length" "4")])
8617
8618 ;;; EH does longjmp's from and within the data section. Thus,
8619 ;;; an interspace branch is required for the longjmp implementation.
8620 ;;; Registers r1 and r2 are used as scratch registers for the jump
8621 ;;; when necessary.
8622 (define_expand "interspace_jump"
8623 [(parallel
8624 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8625 (clobber (match_dup 1))])]
8626 ""
8627 "
8628 {
8629 operands[1] = gen_rtx_REG (word_mode, 2);
8630 }")
8631
8632 (define_insn ""
8633 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8634 (clobber (reg:SI 2))]
8635 "TARGET_PA_20 && !TARGET_64BIT"
8636 "bve%* (%0)"
8637 [(set_attr "type" "branch")
8638 (set_attr "length" "4")])
8639
8640 (define_insn ""
8641 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8642 (clobber (reg:SI 2))]
8643 "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8644 "be%* 0(%%sr4,%0)"
8645 [(set_attr "type" "branch")
8646 (set_attr "length" "4")])
8647
8648 (define_insn ""
8649 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8650 (clobber (reg:SI 2))]
8651 "!TARGET_64BIT"
8652 "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8653 [(set_attr "type" "branch")
8654 (set_attr "length" "12")])
8655
8656 (define_insn ""
8657 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8658 (clobber (reg:DI 2))]
8659 "TARGET_64BIT"
8660 "bve%* (%0)"
8661 [(set_attr "type" "branch")
8662 (set_attr "length" "4")])
8663
8664 (define_expand "builtin_longjmp"
8665 [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8666 ""
8667 "
8668 {
8669 /* The elements of the buffer are, in order: */
8670 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8671 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8672 POINTER_SIZE / BITS_PER_UNIT));
8673 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8674 (POINTER_SIZE * 2) / BITS_PER_UNIT));
8675 rtx pv = gen_rtx_REG (Pmode, 1);
8676
8677 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8678 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8679
8680 /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
8681 instead of the hard_frame_pointer_rtx in the save area. We need
8682 to adjust for the offset between these two values. */
8683 if (GET_CODE (fp) != REG)
8684 fp = force_reg (Pmode, fp);
8685 emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
8686
8687 /* This bit is the same as expand_builtin_longjmp. */
8688 emit_stack_restore (SAVE_NONLOCAL, stack);
8689 emit_use (hard_frame_pointer_rtx);
8690 emit_use (stack_pointer_rtx);
8691
8692 /* Load the label we are jumping through into r1 so that we know
8693 where to look for it when we get back to setjmp's function for
8694 restoring the gp. */
8695 emit_move_insn (pv, lab);
8696
8697 /* Prevent the insns above from being scheduled into the delay slot
8698 of the interspace jump because the space register could change. */
8699 emit_insn (gen_blockage ());
8700
8701 emit_jump_insn (gen_interspace_jump (pv));
8702 emit_barrier ();
8703 DONE;
8704 }")
8705
8706 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8707 (define_expand "extzvsi"
8708 [(set (match_operand:SI 0 "register_operand" "")
8709 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
8710 (match_operand:SI 2 "uint5_operand" "")
8711 (match_operand:SI 3 "uint5_operand" "")))]
8712 ""
8713 "
8714 {
8715 unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8716 unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8717
8718 /* PA extraction insns don't support zero length bitfields or fields
8719 extending beyond the left or right-most bits. Also, the predicate
8720 rejects lengths equal to a word as they are better handled by
8721 the move patterns. */
8722 if (len == 0 || pos + len > 32)
8723 FAIL;
8724
8725 /* From mips.md: extract_bit_field doesn't verify that our source
8726 matches the predicate, so check it again here. */
8727 if (!register_operand (operands[1], VOIDmode))
8728 FAIL;
8729
8730 emit_insn (gen_extzv_32 (operands[0], operands[1],
8731 operands[2], operands[3]));
8732 DONE;
8733 }")
8734
8735 (define_insn "extzv_32"
8736 [(set (match_operand:SI 0 "register_operand" "=r")
8737 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8738 (match_operand:SI 2 "uint5_operand" "")
8739 (match_operand:SI 3 "uint5_operand" "")))]
8740 "UINTVAL (operands[2]) > 0
8741 && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
8742 "{extru|extrw,u} %1,%3+%2-1,%2,%0"
8743 [(set_attr "type" "shift")
8744 (set_attr "length" "4")])
8745
8746 (define_insn ""
8747 [(set (match_operand:SI 0 "register_operand" "=r")
8748 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8749 (const_int 1)
8750 (match_operand:SI 2 "register_operand" "q")))]
8751 ""
8752 "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
8753 [(set_attr "type" "shift")
8754 (set_attr "length" "4")])
8755
8756 (define_expand "extzvdi"
8757 [(set (match_operand:DI 0 "register_operand" "")
8758 (zero_extract:DI (match_operand:DI 1 "register_operand" "")
8759 (match_operand:DI 2 "uint6_operand" "")
8760 (match_operand:DI 3 "uint6_operand" "")))]
8761 "TARGET_64BIT"
8762 "
8763 {
8764 unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8765 unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8766
8767 /* PA extraction insns don't support zero length bitfields or fields
8768 extending beyond the left or right-most bits. Also, the predicate
8769 rejects lengths equal to a doubleword as they are better handled by
8770 the move patterns. */
8771 if (len == 0 || pos + len > 64)
8772 FAIL;
8773
8774 /* From mips.md: extract_bit_field doesn't verify that our source
8775 matches the predicate, so check it again here. */
8776 if (!register_operand (operands[1], VOIDmode))
8777 FAIL;
8778
8779 emit_insn (gen_extzv_64 (operands[0], operands[1],
8780 operands[2], operands[3]));
8781 DONE;
8782 }")
8783
8784 (define_insn "extzv_64"
8785 [(set (match_operand:DI 0 "register_operand" "=r")
8786 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8787 (match_operand:DI 2 "uint6_operand" "")
8788 (match_operand:DI 3 "uint6_operand" "")))]
8789 "TARGET_64BIT
8790 && UINTVAL (operands[2]) > 0
8791 && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
8792 "extrd,u %1,%3+%2-1,%2,%0"
8793 [(set_attr "type" "shift")
8794 (set_attr "length" "4")])
8795
8796 (define_insn ""
8797 [(set (match_operand:DI 0 "register_operand" "=r")
8798 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8799 (const_int 1)
8800 (match_operand:DI 2 "register_operand" "q")))]
8801 "TARGET_64BIT"
8802 "extrd,u %1,%%sar,1,%0"
8803 [(set_attr "type" "shift")
8804 (set_attr "length" "4")])
8805
8806 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8807 (define_expand "extvsi"
8808 [(set (match_operand:SI 0 "register_operand" "")
8809 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
8810 (match_operand:SI 2 "uint5_operand" "")
8811 (match_operand:SI 3 "uint5_operand" "")))]
8812 ""
8813 "
8814 {
8815 unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8816 unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8817
8818 /* PA extraction insns don't support zero length bitfields or fields
8819 extending beyond the left or right-most bits. Also, the predicate
8820 rejects lengths equal to a word as they are better handled by
8821 the move patterns. */
8822 if (len == 0 || pos + len > 32)
8823 FAIL;
8824
8825 /* From mips.md: extract_bit_field doesn't verify that our source
8826 matches the predicate, so check it again here. */
8827 if (!register_operand (operands[1], VOIDmode))
8828 FAIL;
8829
8830 emit_insn (gen_extv_32 (operands[0], operands[1],
8831 operands[2], operands[3]));
8832 DONE;
8833 }")
8834
8835 (define_insn "extv_32"
8836 [(set (match_operand:SI 0 "register_operand" "=r")
8837 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8838 (match_operand:SI 2 "uint5_operand" "")
8839 (match_operand:SI 3 "uint5_operand" "")))]
8840 "UINTVAL (operands[2]) > 0
8841 && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
8842 "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
8843 [(set_attr "type" "shift")
8844 (set_attr "length" "4")])
8845
8846 (define_insn ""
8847 [(set (match_operand:SI 0 "register_operand" "=r")
8848 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8849 (const_int 1)
8850 (match_operand:SI 2 "register_operand" "q")))]
8851 "!TARGET_64BIT"
8852 "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
8853 [(set_attr "type" "shift")
8854 (set_attr "length" "4")])
8855
8856 (define_expand "extvdi"
8857 [(set (match_operand:DI 0 "register_operand" "")
8858 (sign_extract:DI (match_operand:DI 1 "register_operand" "")
8859 (match_operand:DI 2 "uint6_operand" "")
8860 (match_operand:DI 3 "uint6_operand" "")))]
8861 "TARGET_64BIT"
8862 "
8863 {
8864 unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8865 unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8866
8867 /* PA extraction insns don't support zero length bitfields or fields
8868 extending beyond the left or right-most bits. Also, the predicate
8869 rejects lengths equal to a doubleword as they are better handled by
8870 the move patterns. */
8871 if (len == 0 || pos + len > 64)
8872 FAIL;
8873
8874 /* From mips.md: extract_bit_field doesn't verify that our source
8875 matches the predicate, so check it again here. */
8876 if (!register_operand (operands[1], VOIDmode))
8877 FAIL;
8878
8879 emit_insn (gen_extv_64 (operands[0], operands[1],
8880 operands[2], operands[3]));
8881 DONE;
8882 }")
8883
8884 (define_insn "extv_64"
8885 [(set (match_operand:DI 0 "register_operand" "=r")
8886 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8887 (match_operand:DI 2 "uint6_operand" "")
8888 (match_operand:DI 3 "uint6_operand" "")))]
8889 "TARGET_64BIT
8890 && UINTVAL (operands[2]) > 0
8891 && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
8892 "extrd,s %1,%3+%2-1,%2,%0"
8893 [(set_attr "type" "shift")
8894 (set_attr "length" "4")])
8895
8896 (define_insn ""
8897 [(set (match_operand:DI 0 "register_operand" "=r")
8898 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8899 (const_int 1)
8900 (match_operand:DI 2 "register_operand" "q")))]
8901 "TARGET_64BIT"
8902 "extrd,s %1,%%sar,1,%0"
8903 [(set_attr "type" "shift")
8904 (set_attr "length" "4")])
8905
8906 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
8907 (define_expand "insvsi"
8908 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
8909 (match_operand:SI 1 "uint5_operand" "")
8910 (match_operand:SI 2 "uint5_operand" ""))
8911 (match_operand:SI 3 "arith5_operand" ""))]
8912 ""
8913 "
8914 {
8915 unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
8916 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
8917
8918 /* PA insertion insns don't support zero length bitfields or fields
8919 extending beyond the left or right-most bits. Also, the predicate
8920 rejects lengths equal to a word as they are better handled by
8921 the move patterns. */
8922 if (len <= 0 || pos + len > 32)
8923 FAIL;
8924
8925 /* From mips.md: insert_bit_field doesn't verify that our destination
8926 matches the predicate, so check it again here. */
8927 if (!register_operand (operands[0], VOIDmode))
8928 FAIL;
8929
8930 emit_insn (gen_insv_32 (operands[0], operands[1],
8931 operands[2], operands[3]));
8932 DONE;
8933 }")
8934
8935 (define_insn "insv_32"
8936 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
8937 (match_operand:SI 1 "uint5_operand" "")
8938 (match_operand:SI 2 "uint5_operand" ""))
8939 (match_operand:SI 3 "arith5_operand" "r,L"))]
8940 "UINTVAL (operands[1]) > 0
8941 && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
8942 "@
8943 {dep|depw} %3,%2+%1-1,%1,%0
8944 {depi|depwi} %3,%2+%1-1,%1,%0"
8945 [(set_attr "type" "shift,shift")
8946 (set_attr "length" "4,4")])
8947
8948 ;; Optimize insertion of const_int values of type 1...1xxxx.
8949 (define_insn ""
8950 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
8951 (match_operand:SI 1 "uint5_operand" "")
8952 (match_operand:SI 2 "uint5_operand" ""))
8953 (match_operand:SI 3 "const_int_operand" ""))]
8954 "(INTVAL (operands[3]) & 0x10) != 0 &&
8955 (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8956 "*
8957 {
8958 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8959 return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
8960 }"
8961 [(set_attr "type" "shift")
8962 (set_attr "length" "4")])
8963
8964 (define_expand "insvdi"
8965 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
8966 (match_operand:DI 1 "uint6_operand" "")
8967 (match_operand:DI 2 "uint6_operand" ""))
8968 (match_operand:DI 3 "arith5_operand" ""))]
8969 "TARGET_64BIT"
8970 "
8971 {
8972 unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
8973 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
8974
8975 /* PA insertion insns don't support zero length bitfields or fields
8976 extending beyond the left or right-most bits. Also, the predicate
8977 rejects lengths equal to a doubleword as they are better handled by
8978 the move patterns. */
8979 if (len <= 0 || pos + len > 64)
8980 FAIL;
8981
8982 /* From mips.md: insert_bit_field doesn't verify that our destination
8983 matches the predicate, so check it again here. */
8984 if (!register_operand (operands[0], VOIDmode))
8985 FAIL;
8986
8987 emit_insn (gen_insv_64 (operands[0], operands[1],
8988 operands[2], operands[3]));
8989 DONE;
8990 }")
8991
8992 (define_insn "insv_64"
8993 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
8994 (match_operand:DI 1 "uint6_operand" "")
8995 (match_operand:DI 2 "uint6_operand" ""))
8996 (match_operand:DI 3 "arith5_operand" "r,L"))]
8997 "TARGET_64BIT
8998 && UINTVAL (operands[1]) > 0
8999 && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9000 "@
9001 depd %3,%2+%1-1,%1,%0
9002 depdi %3,%2+%1-1,%1,%0"
9003 [(set_attr "type" "shift,shift")
9004 (set_attr "length" "4,4")])
9005
9006 ;; Optimize insertion of const_int values of type 1...1xxxx.
9007 (define_insn ""
9008 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9009 (match_operand:DI 1 "uint6_operand" "")
9010 (match_operand:DI 2 "uint6_operand" ""))
9011 (match_operand:DI 3 "const_int_operand" ""))]
9012 "(INTVAL (operands[3]) & 0x10) != 0
9013 && TARGET_64BIT
9014 && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9015 "*
9016 {
9017 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9018 return \"depdi %3,%2+%1-1,%1,%0\";
9019 }"
9020 [(set_attr "type" "shift")
9021 (set_attr "length" "4")])
9022
9023 (define_insn ""
9024 [(set (match_operand:DI 0 "register_operand" "=r")
9025 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9026 (const_int 32)))]
9027 "TARGET_64BIT"
9028 "depd,z %1,31,32,%0"
9029 [(set_attr "type" "shift")
9030 (set_attr "length" "4")])
9031
9032 ;; This insn is used for some loop tests, typically loops reversed when
9033 ;; strength reduction is used. It is actually created when the instruction
9034 ;; combination phase combines the special loop test. Since this insn
9035 ;; is both a jump insn and has an output, it must deal with its own
9036 ;; reloads, hence the `Q' constraints. The `!' constraints direct reload
9037 ;; to not choose the register alternatives in the event a reload is needed.
9038 (define_insn "decrement_and_branch_until_zero"
9039 [(set (pc)
9040 (if_then_else
9041 (match_operator 2 "comparison_operator"
9042 [(plus:SI
9043 (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9044 (match_operand:SI 1 "int5_operand" "L,L,L"))
9045 (const_int 0)])
9046 (label_ref (match_operand 3 "" ""))
9047 (pc)))
9048 (set (match_dup 0)
9049 (plus:SI (match_dup 0) (match_dup 1)))
9050 (clobber (match_scratch:SI 4 "=X,r,r"))]
9051 ""
9052 "* return pa_output_dbra (operands, insn, which_alternative); "
9053 ;; Do not expect to understand this the first time through.
9054 [(set_attr "type" "cbranch,multi,multi")
9055 (set (attr "length")
9056 (if_then_else (eq_attr "alternative" "0")
9057 ;; Loop counter in register case
9058 ;; Short branch has length of 4
9059 ;; Long branch has length of 8, 20, 24 or 28
9060 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9061 (const_int MAX_12BIT_OFFSET))
9062 (const_int 4)
9063 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9064 (const_int MAX_17BIT_OFFSET))
9065 (const_int 8)
9066 (match_test "TARGET_PORTABLE_RUNTIME")
9067 (const_int 24)
9068 (not (match_test "flag_pic"))
9069 (const_int 20)]
9070 (const_int 28))
9071
9072 ;; Loop counter in FP reg case.
9073 ;; Extra goo to deal with additional reload insns.
9074 (if_then_else (eq_attr "alternative" "1")
9075 (if_then_else (lt (match_dup 3) (pc))
9076 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9077 (const_int MAX_12BIT_OFFSET))
9078 (const_int 24)
9079 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9080 (const_int MAX_17BIT_OFFSET))
9081 (const_int 28)
9082 (match_test "TARGET_PORTABLE_RUNTIME")
9083 (const_int 44)
9084 (not (match_test "flag_pic"))
9085 (const_int 40)]
9086 (const_int 48))
9087 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9088 (const_int MAX_12BIT_OFFSET))
9089 (const_int 24)
9090 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9091 (const_int MAX_17BIT_OFFSET))
9092 (const_int 28)
9093 (match_test "TARGET_PORTABLE_RUNTIME")
9094 (const_int 44)
9095 (not (match_test "flag_pic"))
9096 (const_int 40)]
9097 (const_int 48)))
9098
9099 ;; Loop counter in memory case.
9100 ;; Extra goo to deal with additional reload insns.
9101 (if_then_else (lt (match_dup 3) (pc))
9102 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9103 (const_int MAX_12BIT_OFFSET))
9104 (const_int 12)
9105 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9106 (const_int MAX_17BIT_OFFSET))
9107 (const_int 16)
9108 (match_test "TARGET_PORTABLE_RUNTIME")
9109 (const_int 32)
9110 (not (match_test "flag_pic"))
9111 (const_int 28)]
9112 (const_int 36))
9113 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9114 (const_int MAX_12BIT_OFFSET))
9115 (const_int 12)
9116 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9117 (const_int MAX_17BIT_OFFSET))
9118 (const_int 16)
9119 (match_test "TARGET_PORTABLE_RUNTIME")
9120 (const_int 32)
9121 (not (match_test "flag_pic"))
9122 (const_int 28)]
9123 (const_int 36))))))])
9124
9125 (define_insn ""
9126 [(set (pc)
9127 (if_then_else
9128 (match_operator 2 "movb_comparison_operator"
9129 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9130 (label_ref (match_operand 3 "" ""))
9131 (pc)))
9132 (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9133 (match_dup 1))]
9134 ""
9135 "* return pa_output_movb (operands, insn, which_alternative, 0); "
9136 ;; Do not expect to understand this the first time through.
9137 [(set_attr "type" "cbranch,multi,multi,multi")
9138 (set (attr "length")
9139 (if_then_else (eq_attr "alternative" "0")
9140 ;; Loop counter in register case
9141 ;; Short branch has length of 4
9142 ;; Long branch has length of 8, 20, 24 or 28
9143 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9144 (const_int MAX_12BIT_OFFSET))
9145 (const_int 4)
9146 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9147 (const_int MAX_17BIT_OFFSET))
9148 (const_int 8)
9149 (match_test "TARGET_PORTABLE_RUNTIME")
9150 (const_int 24)
9151 (not (match_test "flag_pic"))
9152 (const_int 20)]
9153 (const_int 28))
9154
9155 ;; Loop counter in FP reg case.
9156 ;; Extra goo to deal with additional reload insns.
9157 (if_then_else (eq_attr "alternative" "1")
9158 (if_then_else (lt (match_dup 3) (pc))
9159 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9160 (const_int MAX_12BIT_OFFSET))
9161 (const_int 12)
9162 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9163 (const_int MAX_17BIT_OFFSET))
9164 (const_int 16)
9165 (match_test "TARGET_PORTABLE_RUNTIME")
9166 (const_int 32)
9167 (not (match_test "flag_pic"))
9168 (const_int 28)]
9169 (const_int 36))
9170 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9171 (const_int MAX_12BIT_OFFSET))
9172 (const_int 12)
9173 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9174 (const_int MAX_17BIT_OFFSET))
9175 (const_int 16)
9176 (match_test "TARGET_PORTABLE_RUNTIME")
9177 (const_int 32)
9178 (not (match_test "flag_pic"))
9179 (const_int 28)]
9180 (const_int 36)))
9181
9182 ;; Loop counter in memory or sar case.
9183 ;; Extra goo to deal with additional reload insns.
9184 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9185 (const_int MAX_12BIT_OFFSET))
9186 (const_int 8)
9187 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9188 (const_int MAX_17BIT_OFFSET))
9189 (const_int 12)
9190 (match_test "TARGET_PORTABLE_RUNTIME")
9191 (const_int 28)
9192 (not (match_test "flag_pic"))
9193 (const_int 24)]
9194 (const_int 32)))))])
9195
9196 ;; Handle negated branch.
9197 (define_insn ""
9198 [(set (pc)
9199 (if_then_else
9200 (match_operator 2 "movb_comparison_operator"
9201 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9202 (pc)
9203 (label_ref (match_operand 3 "" ""))))
9204 (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9205 (match_dup 1))]
9206 ""
9207 "* return pa_output_movb (operands, insn, which_alternative, 1); "
9208 ;; Do not expect to understand this the first time through.
9209 [(set_attr "type" "cbranch,multi,multi,multi")
9210 (set (attr "length")
9211 (if_then_else (eq_attr "alternative" "0")
9212 ;; Loop counter in register case
9213 ;; Short branch has length of 4
9214 ;; Long branch has length of 8
9215 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9216 (const_int MAX_12BIT_OFFSET))
9217 (const_int 4)
9218 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9219 (const_int MAX_17BIT_OFFSET))
9220 (const_int 8)
9221 (match_test "TARGET_PORTABLE_RUNTIME")
9222 (const_int 24)
9223 (not (match_test "flag_pic"))
9224 (const_int 20)]
9225 (const_int 28))
9226
9227 ;; Loop counter in FP reg case.
9228 ;; Extra goo to deal with additional reload insns.
9229 (if_then_else (eq_attr "alternative" "1")
9230 (if_then_else (lt (match_dup 3) (pc))
9231 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9232 (const_int MAX_12BIT_OFFSET))
9233 (const_int 12)
9234 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9235 (const_int MAX_17BIT_OFFSET))
9236 (const_int 16)
9237 (match_test "TARGET_PORTABLE_RUNTIME")
9238 (const_int 32)
9239 (not (match_test "flag_pic"))
9240 (const_int 28)]
9241 (const_int 36))
9242 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9243 (const_int MAX_12BIT_OFFSET))
9244 (const_int 12)
9245 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9246 (const_int MAX_17BIT_OFFSET))
9247 (const_int 16)
9248 (match_test "TARGET_PORTABLE_RUNTIME")
9249 (const_int 32)
9250 (not (match_test "flag_pic"))
9251 (const_int 28)]
9252 (const_int 36)))
9253
9254 ;; Loop counter in memory or SAR case.
9255 ;; Extra goo to deal with additional reload insns.
9256 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9257 (const_int MAX_12BIT_OFFSET))
9258 (const_int 8)
9259 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9260 (const_int MAX_17BIT_OFFSET))
9261 (const_int 12)
9262 (match_test "TARGET_PORTABLE_RUNTIME")
9263 (const_int 28)
9264 (not (match_test "flag_pic"))
9265 (const_int 24)]
9266 (const_int 32)))))])
9267
9268 (define_insn ""
9269 [(set (pc) (label_ref (match_operand 3 "" "" )))
9270 (set (match_operand:SI 0 "ireg_operand" "=r")
9271 (plus:SI (match_operand:SI 1 "ireg_operand" "r")
9272 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9273 "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9274 "*
9275 {
9276 return pa_output_parallel_addb (operands, insn);
9277 }"
9278 [(set_attr "type" "parallel_branch")
9279 (set (attr "length")
9280 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9281 (const_int MAX_12BIT_OFFSET))
9282 (const_int 4)
9283 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9284 (const_int MAX_17BIT_OFFSET))
9285 (const_int 8)
9286 (match_test "TARGET_PORTABLE_RUNTIME")
9287 (const_int 24)
9288 (not (match_test "flag_pic"))
9289 (const_int 20)]
9290 (const_int 28)))])
9291
9292 (define_insn ""
9293 [(set (pc) (label_ref (match_operand 2 "" "" )))
9294 (set (match_operand:SF 0 "ireg_operand" "=r")
9295 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9296 "reload_completed"
9297 "*
9298 {
9299 return pa_output_parallel_movb (operands, insn);
9300 }"
9301 [(set_attr "type" "parallel_branch")
9302 (set (attr "length")
9303 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9304 (const_int MAX_12BIT_OFFSET))
9305 (const_int 4)
9306 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9307 (const_int MAX_17BIT_OFFSET))
9308 (const_int 8)
9309 (match_test "TARGET_PORTABLE_RUNTIME")
9310 (const_int 24)
9311 (not (match_test "flag_pic"))
9312 (const_int 20)]
9313 (const_int 28)))])
9314
9315 (define_insn ""
9316 [(set (pc) (label_ref (match_operand 2 "" "" )))
9317 (set (match_operand:SI 0 "ireg_operand" "=r")
9318 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9319 "reload_completed"
9320 "*
9321 {
9322 return pa_output_parallel_movb (operands, insn);
9323 }"
9324 [(set_attr "type" "parallel_branch")
9325 (set (attr "length")
9326 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9327 (const_int MAX_12BIT_OFFSET))
9328 (const_int 4)
9329 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9330 (const_int MAX_17BIT_OFFSET))
9331 (const_int 8)
9332 (match_test "TARGET_PORTABLE_RUNTIME")
9333 (const_int 24)
9334 (not (match_test "flag_pic"))
9335 (const_int 20)]
9336 (const_int 28)))])
9337
9338 (define_insn ""
9339 [(set (pc) (label_ref (match_operand 2 "" "" )))
9340 (set (match_operand:HI 0 "ireg_operand" "=r")
9341 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9342 "reload_completed"
9343 "*
9344 {
9345 return pa_output_parallel_movb (operands, insn);
9346 }"
9347 [(set_attr "type" "parallel_branch")
9348 (set (attr "length")
9349 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9350 (const_int MAX_12BIT_OFFSET))
9351 (const_int 4)
9352 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9353 (const_int MAX_17BIT_OFFSET))
9354 (const_int 8)
9355 (match_test "TARGET_PORTABLE_RUNTIME")
9356 (const_int 24)
9357 (not (match_test "flag_pic"))
9358 (const_int 20)]
9359 (const_int 28)))])
9360
9361 (define_insn ""
9362 [(set (pc) (label_ref (match_operand 2 "" "" )))
9363 (set (match_operand:QI 0 "ireg_operand" "=r")
9364 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9365 "reload_completed"
9366 "*
9367 {
9368 return pa_output_parallel_movb (operands, insn);
9369 }"
9370 [(set_attr "type" "parallel_branch")
9371 (set (attr "length")
9372 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9373 (const_int MAX_12BIT_OFFSET))
9374 (const_int 4)
9375 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9376 (const_int MAX_17BIT_OFFSET))
9377 (const_int 8)
9378 (match_test "TARGET_PORTABLE_RUNTIME")
9379 (const_int 24)
9380 (not (match_test "flag_pic"))
9381 (const_int 20)]
9382 (const_int 28)))])
9383
9384 (define_insn ""
9385 [(set (match_operand 0 "register_operand" "=f")
9386 (mult (match_operand 1 "register_operand" "f")
9387 (match_operand 2 "register_operand" "f")))
9388 (set (match_operand 3 "register_operand" "+f")
9389 (plus (match_operand 4 "register_operand" "f")
9390 (match_operand 5 "register_operand" "f")))]
9391 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9392 && reload_completed && pa_fmpyaddoperands (operands)"
9393 "*
9394 {
9395 if (GET_MODE (operands[0]) == DFmode)
9396 {
9397 if (rtx_equal_p (operands[3], operands[5]))
9398 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9399 else
9400 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9401 }
9402 else
9403 {
9404 if (rtx_equal_p (operands[3], operands[5]))
9405 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9406 else
9407 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9408 }
9409 }"
9410 [(set_attr "type" "fpalu")
9411 (set_attr "length" "4")])
9412
9413 (define_insn ""
9414 [(set (match_operand 3 "register_operand" "+f")
9415 (plus (match_operand 4 "register_operand" "f")
9416 (match_operand 5 "register_operand" "f")))
9417 (set (match_operand 0 "register_operand" "=f")
9418 (mult (match_operand 1 "register_operand" "f")
9419 (match_operand 2 "register_operand" "f")))]
9420 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9421 && reload_completed && pa_fmpyaddoperands (operands)"
9422 "*
9423 {
9424 if (GET_MODE (operands[0]) == DFmode)
9425 {
9426 if (rtx_equal_p (operands[3], operands[5]))
9427 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9428 else
9429 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9430 }
9431 else
9432 {
9433 if (rtx_equal_p (operands[3], operands[5]))
9434 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9435 else
9436 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9437 }
9438 }"
9439 [(set_attr "type" "fpalu")
9440 (set_attr "length" "4")])
9441
9442 (define_insn ""
9443 [(set (match_operand 0 "register_operand" "=f")
9444 (mult (match_operand 1 "register_operand" "f")
9445 (match_operand 2 "register_operand" "f")))
9446 (set (match_operand 3 "register_operand" "+f")
9447 (minus (match_operand 4 "register_operand" "f")
9448 (match_operand 5 "register_operand" "f")))]
9449 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9450 && reload_completed && pa_fmpysuboperands (operands)"
9451 "*
9452 {
9453 if (GET_MODE (operands[0]) == DFmode)
9454 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9455 else
9456 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9457 }"
9458 [(set_attr "type" "fpalu")
9459 (set_attr "length" "4")])
9460
9461 (define_insn ""
9462 [(set (match_operand 3 "register_operand" "+f")
9463 (minus (match_operand 4 "register_operand" "f")
9464 (match_operand 5 "register_operand" "f")))
9465 (set (match_operand 0 "register_operand" "=f")
9466 (mult (match_operand 1 "register_operand" "f")
9467 (match_operand 2 "register_operand" "f")))]
9468 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9469 && reload_completed && pa_fmpysuboperands (operands)"
9470 "*
9471 {
9472 if (GET_MODE (operands[0]) == DFmode)
9473 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9474 else
9475 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9476 }"
9477 [(set_attr "type" "fpalu")
9478 (set_attr "length" "4")])
9479
9480 ;; The following two patterns are used by the trampoline code for nested
9481 ;; functions. They flush the I and D cache lines from the start address
9482 ;; (operand0) to the end address (operand1). No lines are flushed if the
9483 ;; end address is less than the start address (unsigned).
9484 ;;
9485 ;; Because the range of memory flushed is variable and the size of a MEM
9486 ;; can only be a CONST_INT, the patterns specify that they perform an
9487 ;; unspecified volatile operation on all memory.
9488 ;;
9489 ;; The address range for an icache flush must lie within a single
9490 ;; space on targets with non-equivalent space registers.
9491 ;;
9492 ;; Operand 0 contains the start address.
9493 ;; Operand 1 contains the end address.
9494 ;; Operand 2 contains the line length to use.
9495 (define_insn "dcacheflush<P:mode>"
9496 [(const_int 1)
9497 (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9498 (use (match_operand 0 "pmode_register_operand" "r"))
9499 (use (match_operand 1 "pmode_register_operand" "r"))
9500 (use (match_operand 2 "pmode_register_operand" "r"))
9501 (clobber (match_scratch:P 3 "=&0"))]
9502 ""
9503 "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9504 [(set_attr "type" "multi")
9505 (set_attr "length" "12")])
9506
9507 (define_insn "icacheflush<P:mode>"
9508 [(const_int 2)
9509 (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9510 (use (match_operand 0 "pmode_register_operand" "r"))
9511 (use (match_operand 1 "pmode_register_operand" "r"))
9512 (use (match_operand 2 "pmode_register_operand" "r"))
9513 (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9514 (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9515 (clobber (match_scratch:P 5 "=&0"))]
9516 ""
9517 "mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<dwc><<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
9518 [(set_attr "type" "multi")
9519 (set_attr "length" "52")])
9520
9521 ;; An out-of-line prologue.
9522 (define_insn "outline_prologue_call"
9523 [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9524 (clobber (reg:SI 31))
9525 (clobber (reg:SI 22))
9526 (clobber (reg:SI 21))
9527 (clobber (reg:SI 20))
9528 (clobber (reg:SI 19))
9529 (clobber (reg:SI 1))]
9530 ""
9531 "*
9532 {
9533
9534 /* We need two different versions depending on whether or not we
9535 need a frame pointer. Also note that we return to the instruction
9536 immediately after the branch rather than two instructions after the
9537 break as normally is the case. */
9538 if (frame_pointer_needed)
9539 {
9540 /* Must import the magic millicode routine(s). */
9541 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9542
9543 if (TARGET_PORTABLE_RUNTIME)
9544 {
9545 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9546 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9547 NULL);
9548 }
9549 else
9550 output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9551 }
9552 else
9553 {
9554 /* Must import the magic millicode routine(s). */
9555 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9556
9557 if (TARGET_PORTABLE_RUNTIME)
9558 {
9559 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9560 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9561 }
9562 else
9563 output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9564 }
9565 return \"\";
9566 }"
9567 [(set_attr "type" "multi")
9568 (set_attr "length" "8")])
9569
9570 ;; An out-of-line epilogue.
9571 (define_insn "outline_epilogue_call"
9572 [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9573 (use (reg:SI 29))
9574 (use (reg:SI 28))
9575 (clobber (reg:SI 31))
9576 (clobber (reg:SI 22))
9577 (clobber (reg:SI 21))
9578 (clobber (reg:SI 20))
9579 (clobber (reg:SI 19))
9580 (clobber (reg:SI 2))
9581 (clobber (reg:SI 1))]
9582 ""
9583 "*
9584 {
9585
9586 /* We need two different versions depending on whether or not we
9587 need a frame pointer. Also note that we return to the instruction
9588 immediately after the branch rather than two instructions after the
9589 break as normally is the case. */
9590 if (frame_pointer_needed)
9591 {
9592 /* Must import the magic millicode routine. */
9593 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9594
9595 /* The out-of-line prologue will make sure we return to the right
9596 instruction. */
9597 if (TARGET_PORTABLE_RUNTIME)
9598 {
9599 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9600 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9601 NULL);
9602 }
9603 else
9604 output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9605 }
9606 else
9607 {
9608 /* Must import the magic millicode routine. */
9609 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9610
9611 /* The out-of-line prologue will make sure we return to the right
9612 instruction. */
9613 if (TARGET_PORTABLE_RUNTIME)
9614 {
9615 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9616 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9617 }
9618 else
9619 output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9620 }
9621 return \"\";
9622 }"
9623 [(set_attr "type" "multi")
9624 (set_attr "length" "8")])
9625
9626 ;; Given a function pointer, canonicalize it so it can be
9627 ;; reliably compared to another function pointer. */
9628 (define_expand "canonicalize_funcptr_for_compare"
9629 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9630 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9631 (clobber (match_dup 2))
9632 (clobber (reg:SI 26))
9633 (clobber (reg:SI 22))
9634 (clobber (reg:SI 31))])
9635 (set (match_operand:SI 0 "register_operand" "")
9636 (reg:SI 29))]
9637 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9638 "
9639 {
9640 if (TARGET_ELF32)
9641 {
9642 rtx canonicalize_funcptr_for_compare_libfunc
9643 = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9644
9645 emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9646 operands[0], LCT_NORMAL, Pmode,
9647 1, operands[1], Pmode);
9648 DONE;
9649 }
9650
9651 operands[2] = gen_reg_rtx (SImode);
9652 if (GET_CODE (operands[1]) != REG)
9653 {
9654 rtx tmp = gen_reg_rtx (Pmode);
9655 emit_move_insn (tmp, operands[1]);
9656 operands[1] = tmp;
9657 }
9658 }")
9659
9660 (define_insn "*$$sh_func_adrs"
9661 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9662 (clobber (match_operand:SI 0 "register_operand" "=a"))
9663 (clobber (reg:SI 26))
9664 (clobber (reg:SI 22))
9665 (clobber (reg:SI 31))]
9666 "!TARGET_64BIT"
9667 "*
9668 {
9669 int length = get_attr_length (insn);
9670 rtx xoperands[2];
9671
9672 xoperands[0] = GEN_INT (length - 8);
9673 xoperands[1] = GEN_INT (length - 16);
9674
9675 /* Must import the magic millicode routine. */
9676 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9677
9678 /* This is absolutely amazing.
9679
9680 First, copy our input parameter into %r29 just in case we don't
9681 need to call $$sh_func_adrs. */
9682 output_asm_insn (\"copy %%r26,%%r29\", NULL);
9683 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9684
9685 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9686 we use %r26 unchanged. */
9687 output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9688 output_asm_insn (\"ldi 4096,%%r31\", NULL);
9689
9690 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9691 4096, then again we use %r26 unchanged. */
9692 output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9693
9694 /* Finally, call $$sh_func_adrs to extract the function's real add24. */
9695 return pa_output_millicode_call (insn,
9696 gen_rtx_SYMBOL_REF (SImode,
9697 \"$$sh_func_adrs\"));
9698 }"
9699 [(set_attr "type" "sh_func_adrs")
9700 (set (attr "length")
9701 (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
9702 (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9703 (const_int 20))))])
9704
9705 ;; On the PA, the PIC register is call clobbered, so it must
9706 ;; be saved & restored around calls by the caller. If the call
9707 ;; doesn't return normally (nonlocal goto, or an exception is
9708 ;; thrown), then the code at the exception handler label must
9709 ;; restore the PIC register.
9710 (define_expand "exception_receiver"
9711 [(const_int 4)]
9712 "flag_pic"
9713 "
9714 {
9715 /* On the 64-bit port, we need a blockage because there is
9716 confusion regarding the dependence of the restore on the
9717 frame pointer. As a result, the frame pointer and pic
9718 register restores sometimes are interchanged erroneously. */
9719 if (TARGET_64BIT)
9720 emit_insn (gen_blockage ());
9721 /* Restore the PIC register using hppa_pic_save_rtx (). The
9722 PIC register is not saved in the frame in 64-bit ABI. */
9723 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9724 emit_insn (gen_blockage ());
9725 DONE;
9726 }")
9727
9728 (define_expand "builtin_setjmp_receiver"
9729 [(label_ref (match_operand 0 "" ""))]
9730 "flag_pic"
9731 "
9732 {
9733 if (TARGET_64BIT)
9734 emit_insn (gen_blockage ());
9735 /* Restore the PIC register. Hopefully, this will always be from
9736 a stack slot. The only registers that are valid after a
9737 builtin_longjmp are the stack and frame pointers. */
9738 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9739 emit_insn (gen_blockage ());
9740 DONE;
9741 }")
9742
9743 ;; Allocate new stack space and update the saved stack pointer in the
9744 ;; frame marker. The HP C compilers also copy additional words in the
9745 ;; frame marker. The 64-bit compiler copies words at -48, -32 and -24.
9746 ;; The 32-bit compiler copies the word at -16 (Static Link). We
9747 ;; currently don't copy these values.
9748 ;;
9749 ;; Since the copy of the frame marker can't be done atomically, I
9750 ;; suspect that using it for unwind purposes may be somewhat unreliable.
9751 ;; The HP compilers appear to raise the stack and copy the frame
9752 ;; marker in a strict instruction sequence. This suggests that the
9753 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
9754 ;; is set in the callinfo data. We currently don't set ALLOCA_FRAME
9755 ;; as GAS doesn't support it, or try to keep the instructions emitted
9756 ;; here in strict sequence.
9757 (define_expand "allocate_stack"
9758 [(match_operand 0 "" "")
9759 (match_operand 1 "" "")]
9760 ""
9761 "
9762 {
9763 rtx addr;
9764
9765 /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
9766 in operand 0 before adjusting the stack. */
9767 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9768 anti_adjust_stack (operands[1]);
9769 if (TARGET_HPUX_UNWIND_LIBRARY)
9770 {
9771 addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
9772 GEN_INT (TARGET_64BIT ? -8 : -4));
9773 emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
9774 }
9775 if (!TARGET_64BIT && flag_pic)
9776 {
9777 rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
9778 emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
9779 }
9780 DONE;
9781 }")
9782
9783 (define_expand "prefetch"
9784 [(match_operand 0 "address_operand" "")
9785 (match_operand 1 "const_int_operand" "")
9786 (match_operand 2 "const_int_operand" "")]
9787 "TARGET_PA_20"
9788 {
9789 operands[0] = copy_addr_to_reg (operands[0]);
9790 emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
9791 DONE;
9792 })
9793
9794 (define_insn "prefetch_20"
9795 [(prefetch (match_operand 0 "pmode_register_operand" "r")
9796 (match_operand:SI 1 "const_int_operand" "n")
9797 (match_operand:SI 2 "const_int_operand" "n"))]
9798 "TARGET_PA_20"
9799 {
9800 /* The SL cache-control completer indicates good spatial locality but
9801 poor temporal locality. The ldw instruction with a target of general
9802 register 0 prefetches a cache line for a read. The ldd instruction
9803 prefetches a cache line for a write. */
9804 static const char * const instr[2][2] = {
9805 {
9806 "ldw,sl 0(%0),%%r0",
9807 "ldd,sl 0(%0),%%r0"
9808 },
9809 {
9810 "ldw 0(%0),%%r0",
9811 "ldd 0(%0),%%r0"
9812 }
9813 };
9814 int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
9815 int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
9816
9817 return instr [locality][read_or_write];
9818 }
9819 [(set_attr "type" "load")
9820 (set_attr "length" "4")])
9821
9822 ;; TLS Support
9823 (define_insn "tgd_load"
9824 [(set (match_operand:SI 0 "register_operand" "=r")
9825 (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
9826 (clobber (reg:SI 1))
9827 (use (reg:SI 27))]
9828 ""
9829 "*
9830 {
9831 return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
9832 }"
9833 [(set_attr "type" "multi")
9834 (set_attr "length" "8")])
9835
9836 (define_insn "tgd_load_pic"
9837 [(set (match_operand:SI 0 "register_operand" "=r")
9838 (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
9839 (clobber (reg:SI 1))
9840 (use (reg:SI 19))]
9841 ""
9842 "*
9843 {
9844 return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
9845 }"
9846 [(set_attr "type" "multi")
9847 (set_attr "length" "8")])
9848
9849 (define_insn "tld_load"
9850 [(set (match_operand:SI 0 "register_operand" "=r")
9851 (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
9852 (clobber (reg:SI 1))
9853 (use (reg:SI 27))]
9854 ""
9855 "*
9856 {
9857 return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
9858 }"
9859 [(set_attr "type" "multi")
9860 (set_attr "length" "8")])
9861
9862 (define_insn "tld_load_pic"
9863 [(set (match_operand:SI 0 "register_operand" "=r")
9864 (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
9865 (clobber (reg:SI 1))
9866 (use (reg:SI 19))]
9867 ""
9868 "*
9869 {
9870 return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
9871 }"
9872 [(set_attr "type" "multi")
9873 (set_attr "length" "8")])
9874
9875 (define_insn "tld_offset_load"
9876 [(set (match_operand:SI 0 "register_operand" "=r")
9877 (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
9878 UNSPEC_TLSLDO)
9879 (match_operand:SI 2 "register_operand" "r")))
9880 (clobber (reg:SI 1))]
9881 ""
9882 "*
9883 {
9884 return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
9885 }"
9886 [(set_attr "type" "multi")
9887 (set_attr "length" "8")])
9888
9889 (define_insn "tp_load"
9890 [(set (match_operand:SI 0 "register_operand" "=r")
9891 (unspec:SI [(const_int 0)] UNSPEC_TP))]
9892 ""
9893 "mfctl %%cr27,%0"
9894 [(set_attr "type" "multi")
9895 (set_attr "length" "4")])
9896
9897 (define_insn "tie_load"
9898 [(set (match_operand:SI 0 "register_operand" "=r")
9899 (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
9900 (clobber (reg:SI 1))
9901 (use (reg:SI 27))]
9902 ""
9903 "*
9904 {
9905 return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
9906 }"
9907 [(set_attr "type" "multi")
9908 (set_attr "length" "8")])
9909
9910 (define_insn "tie_load_pic"
9911 [(set (match_operand:SI 0 "register_operand" "=r")
9912 (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
9913 (clobber (reg:SI 1))
9914 (use (reg:SI 19))]
9915 ""
9916 "*
9917 {
9918 return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
9919 }"
9920 [(set_attr "type" "multi")
9921 (set_attr "length" "8")])
9922
9923 (define_insn "tle_load"
9924 [(set (match_operand:SI 0 "register_operand" "=r")
9925 (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
9926 UNSPEC_TLSLE)
9927 (match_operand:SI 2 "register_operand" "r")))
9928 (clobber (reg:SI 1))]
9929 ""
9930 "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
9931 [(set_attr "type" "multi")
9932 (set_attr "length" "8")])