]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/pa/pa.md
re PR target/55195 (shorten_branches generates incorrect forward branch distances)
[thirdparty/gcc.git] / gcc / config / pa / pa.md
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 ;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by the Center for Software Science at the University
6 ;; of Utah.
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24 ;; This gcc Version 2 machine description is inspired by sparc.md and
25 ;; mips.md.
26
27 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28
29 ;; Uses of UNSPEC in this file:
30
31 (define_c_enum "unspec"
32 [UNSPEC_CFFC ; canonicalize_funcptr_for_compare
33 UNSPEC_GOTO ; indirect_goto
34 UNSPEC_DLTIND14R
35 UNSPEC_TP
36 UNSPEC_TLSGD
37 UNSPEC_TLSLDM
38 UNSPEC_TLSLDO
39 UNSPEC_TLSLDBASE
40 UNSPEC_TLSIE
41 UNSPEC_TLSLE
42 UNSPEC_TLSGD_PIC
43 UNSPEC_TLSLDM_PIC
44 UNSPEC_TLSIE_PIC
45 ])
46
47 ;; UNSPEC_VOLATILE:
48
49 (define_c_enum "unspecv"
50 [UNSPECV_BLOCKAGE ; blockage
51 UNSPECV_DCACHE ; dcacheflush
52 UNSPECV_ICACHE ; icacheflush
53 UNSPECV_OPC ; outline_prologue_call
54 UNSPECV_OEC ; outline_epilogue_call
55 UNSPECV_LONGJMP ; builtin_longjmp
56 ])
57
58 ;; Maximum pc-relative branch offsets.
59
60 ;; These numbers are a bit smaller than the maximum allowable offsets
61 ;; so that a few instructions may be inserted before the actual branch.
62
63 (define_constants
64 [(MAX_12BIT_OFFSET 8184) ; 12-bit branch
65 (MAX_17BIT_OFFSET 262100) ; 17-bit branch
66 ])
67
68 ;; Mode and code iterators
69
70 ;; This mode iterator allows :P to be used for patterns that operate on
71 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
72 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
73
74 ;; This attribute defines the condition prefix for word and double word
75 ;; add, compare, subtract and logical instructions.
76 (define_mode_attr dwc [(SI "") (DI "*")])
77
78 ;; Insn type. Used to default other attribute values.
79
80 ;; type "unary" insns have one input operand (1) and one output operand (0)
81 ;; type "binary" insns have two input operands (1,2) and one output (0)
82
83 (define_attr "type"
84 "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_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"
85 (const_string "binary"))
86
87 (define_attr "pa_combine_type"
88 "fmpy,faddsub,uncond_branch,addmove,none"
89 (const_string "none"))
90
91 ;; Processor type (for scheduling, not code generation) -- this attribute
92 ;; must exactly match the processor_type enumeration in pa.h.
93 ;;
94 ;; FIXME: Add 800 scheduling for completeness?
95
96 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
97
98 ;; Length (in # of bytes).
99 (define_attr "length" ""
100 (cond [(eq_attr "type" "load,fpload")
101 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
102 (const_int 8) (const_int 4))
103
104 (eq_attr "type" "store,fpstore")
105 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
106 (const_int 8) (const_int 4))
107
108 (eq_attr "type" "binary,shift,nullshift")
109 (if_then_else (match_operand 2 "arith14_operand" "")
110 (const_int 4) (const_int 12))
111
112 (eq_attr "type" "move,unary,shift,nullshift")
113 (if_then_else (match_operand 1 "arith14_operand" "")
114 (const_int 4) (const_int 8))]
115
116 (const_int 4)))
117
118 (define_asm_attributes
119 [(set_attr "length" "4")
120 (set_attr "type" "multi")])
121
122 ;; Attributes for instruction and branch scheduling
123
124 ;; For conditional branches. Frame related instructions are not allowed
125 ;; because they confuse the unwind support.
126 (define_attr "in_branch_delay" "false,true"
127 (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
128 (eq_attr "length" "4")
129 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
130 (const_string "true")
131 (const_string "false")))
132
133 ;; Disallow instructions which use the FPU since they will tie up the FPU
134 ;; even if the instruction is nullified.
135 (define_attr "in_nullified_branch_delay" "false,true"
136 (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
137 (eq_attr "length" "4")
138 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
139 (const_string "true")
140 (const_string "false")))
141
142 ;; For calls and millicode calls. Allow unconditional branches in the
143 ;; delay slot.
144 (define_attr "in_call_delay" "false,true"
145 (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
146 (eq_attr "length" "4")
147 (not (match_test "RTX_FRAME_RELATED_P (insn)")))
148 (const_string "true")
149 (eq_attr "type" "uncond_branch")
150 (if_then_else (match_test "TARGET_JUMP_IN_DELAY")
151 (const_string "true")
152 (const_string "false"))]
153 (const_string "false")))
154
155
156 ;; Call delay slot description.
157 (define_delay (eq_attr "type" "call")
158 [(eq_attr "in_call_delay" "true") (nil) (nil)])
159
160 ;; Sibcall delay slot description.
161 (define_delay (eq_attr "type" "sibcall")
162 [(eq_attr "in_call_delay" "true") (nil) (nil)])
163
164 ;; Millicode call delay slot description.
165 (define_delay (eq_attr "type" "milli")
166 [(eq_attr "in_call_delay" "true") (nil) (nil)])
167
168 ;; Return and other similar instructions.
169 (define_delay (eq_attr "type" "btable_branch,branch,parallel_branch")
170 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
171
172 ;; Floating point conditional branch delay slot description.
173 (define_delay (eq_attr "type" "fbranch")
174 [(eq_attr "in_branch_delay" "true")
175 (eq_attr "in_nullified_branch_delay" "true")
176 (nil)])
177
178 ;; Integer conditional branch delay slot description.
179 ;; Nullification of conditional branches on the PA is dependent on the
180 ;; direction of the branch. Forward branches nullify true and
181 ;; backward branches nullify false. If the direction is unknown
182 ;; then nullification is not allowed.
183 (define_delay (eq_attr "type" "cbranch")
184 [(eq_attr "in_branch_delay" "true")
185 (and (eq_attr "in_nullified_branch_delay" "true")
186 (attr_flag "forward"))
187 (and (eq_attr "in_nullified_branch_delay" "true")
188 (attr_flag "backward"))])
189
190 (define_delay (and (eq_attr "type" "uncond_branch")
191 (not (match_test "pa_following_call (insn)")))
192 [(eq_attr "in_branch_delay" "true") (nil) (nil)])
193
194 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
195 ;; load: 2, fpload: 3
196 ;; store, fpstore: 3, no D-cache operations should be scheduled.
197
198 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
199 ;; Timings:
200 ;; Instruction Time Unit Minimum Distance (unit contention)
201 ;; fcpy 3 ALU 2
202 ;; fabs 3 ALU 2
203 ;; fadd 3 ALU 2
204 ;; fsub 3 ALU 2
205 ;; fcmp 3 ALU 2
206 ;; fcnv 3 ALU 2
207 ;; fmpyadd 3 ALU,MPY 2
208 ;; fmpysub 3 ALU,MPY 2
209 ;; fmpycfxt 3 ALU,MPY 2
210 ;; fmpy 3 MPY 2
211 ;; fmpyi 3 MPY 2
212 ;; fdiv,sgl 10 MPY 10
213 ;; fdiv,dbl 12 MPY 12
214 ;; fsqrt,sgl 14 MPY 14
215 ;; fsqrt,dbl 18 MPY 18
216 ;;
217 ;; We don't model fmpyadd/fmpysub properly as those instructions
218 ;; keep both the FP ALU and MPY units busy. Given that these
219 ;; processors are obsolete, I'm not going to spend the time to
220 ;; model those instructions correctly.
221
222 (define_automaton "pa700")
223 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
224
225 (define_insn_reservation "W0" 4
226 (and (eq_attr "type" "fpcc")
227 (eq_attr "cpu" "700"))
228 "fpalu_700*2")
229
230 (define_insn_reservation "W1" 3
231 (and (eq_attr "type" "fpalu")
232 (eq_attr "cpu" "700"))
233 "fpalu_700*2")
234
235 (define_insn_reservation "W2" 3
236 (and (eq_attr "type" "fpmulsgl,fpmuldbl")
237 (eq_attr "cpu" "700"))
238 "fpmpy_700*2")
239
240 (define_insn_reservation "W3" 10
241 (and (eq_attr "type" "fpdivsgl")
242 (eq_attr "cpu" "700"))
243 "fpmpy_700*10")
244
245 (define_insn_reservation "W4" 12
246 (and (eq_attr "type" "fpdivdbl")
247 (eq_attr "cpu" "700"))
248 "fpmpy_700*12")
249
250 (define_insn_reservation "W5" 14
251 (and (eq_attr "type" "fpsqrtsgl")
252 (eq_attr "cpu" "700"))
253 "fpmpy_700*14")
254
255 (define_insn_reservation "W6" 18
256 (and (eq_attr "type" "fpsqrtdbl")
257 (eq_attr "cpu" "700"))
258 "fpmpy_700*18")
259
260 (define_insn_reservation "W7" 2
261 (and (eq_attr "type" "load")
262 (eq_attr "cpu" "700"))
263 "mem_700")
264
265 (define_insn_reservation "W8" 2
266 (and (eq_attr "type" "fpload")
267 (eq_attr "cpu" "700"))
268 "mem_700")
269
270 (define_insn_reservation "W9" 3
271 (and (eq_attr "type" "store")
272 (eq_attr "cpu" "700"))
273 "mem_700*3")
274
275 (define_insn_reservation "W10" 3
276 (and (eq_attr "type" "fpstore")
277 (eq_attr "cpu" "700"))
278 "mem_700*3")
279
280 (define_insn_reservation "W11" 5
281 (and (eq_attr "type" "fpstore_load")
282 (eq_attr "cpu" "700"))
283 "mem_700*5")
284
285 (define_insn_reservation "W12" 6
286 (and (eq_attr "type" "store_fpload")
287 (eq_attr "cpu" "700"))
288 "mem_700*6")
289
290 (define_insn_reservation "W13" 1
291 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
292 (eq_attr "cpu" "700"))
293 "dummy_700")
294
295 ;; We have a bypass for all computations in the FP unit which feed an
296 ;; FP store as long as the sizes are the same.
297 (define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
298 (define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
299 (define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
300 (define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
301 (define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
302
303 ;; We have an "anti-bypass" for FP loads which feed an FP store.
304 (define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
305
306 ;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
307 ;; floating point computations with non-floating point computations (fp loads
308 ;; and stores are not fp computations).
309 ;;
310 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
311 ;; take two cycles, during which no Dcache operations should be scheduled.
312 ;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
313 ;; all have the same memory characteristics if one disregards cache misses.
314 ;;
315 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
316 ;; There's no value in modeling the ALU and MUL separately though
317 ;; since there can never be a functional unit conflict given the
318 ;; latency and issue rates for those units.
319 ;;
320 ;; Timings:
321 ;; Instruction Time Unit Minimum Distance (unit contention)
322 ;; fcpy 2 ALU 1
323 ;; fabs 2 ALU 1
324 ;; fadd 2 ALU 1
325 ;; fsub 2 ALU 1
326 ;; fcmp 2 ALU 1
327 ;; fcnv 2 ALU 1
328 ;; fmpyadd 2 ALU,MPY 1
329 ;; fmpysub 2 ALU,MPY 1
330 ;; fmpycfxt 2 ALU,MPY 1
331 ;; fmpy 2 MPY 1
332 ;; fmpyi 2 MPY 1
333 ;; fdiv,sgl 8 DIV 8
334 ;; fdiv,dbl 15 DIV 15
335 ;; fsqrt,sgl 8 DIV 8
336 ;; fsqrt,dbl 15 DIV 15
337
338 (define_automaton "pa7100")
339 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
340
341 (define_insn_reservation "X0" 2
342 (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
343 (eq_attr "cpu" "7100"))
344 "f_7100,fpmac_7100")
345
346 (define_insn_reservation "X1" 8
347 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
348 (eq_attr "cpu" "7100"))
349 "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
350
351 (define_insn_reservation "X2" 15
352 (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
353 (eq_attr "cpu" "7100"))
354 "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
355
356 (define_insn_reservation "X3" 2
357 (and (eq_attr "type" "load")
358 (eq_attr "cpu" "7100"))
359 "i_7100+mem_7100")
360
361 (define_insn_reservation "X4" 2
362 (and (eq_attr "type" "fpload")
363 (eq_attr "cpu" "7100"))
364 "i_7100+mem_7100")
365
366 (define_insn_reservation "X5" 2
367 (and (eq_attr "type" "store")
368 (eq_attr "cpu" "7100"))
369 "i_7100+mem_7100,mem_7100")
370
371 (define_insn_reservation "X6" 2
372 (and (eq_attr "type" "fpstore")
373 (eq_attr "cpu" "7100"))
374 "i_7100+mem_7100,mem_7100")
375
376 (define_insn_reservation "X7" 4
377 (and (eq_attr "type" "fpstore_load")
378 (eq_attr "cpu" "7100"))
379 "i_7100+mem_7100,mem_7100*3")
380
381 (define_insn_reservation "X8" 4
382 (and (eq_attr "type" "store_fpload")
383 (eq_attr "cpu" "7100"))
384 "i_7100+mem_7100,mem_7100*3")
385
386 (define_insn_reservation "X9" 1
387 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
388 (eq_attr "cpu" "7100"))
389 "i_7100")
390
391 ;; We have a bypass for all computations in the FP unit which feed an
392 ;; FP store as long as the sizes are the same.
393 (define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
394 (define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
395 (define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
396
397 ;; We have an "anti-bypass" for FP loads which feed an FP store.
398 (define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
399
400 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
401 ;; There's no value in modeling the ALU and MUL separately though
402 ;; since there can never be a functional unit conflict that
403 ;; can be avoided given the latency, issue rates and mandatory
404 ;; one cycle cpu-wide lock for a double precision fp multiply.
405 ;;
406 ;; Timings:
407 ;; Instruction Time Unit Minimum Distance (unit contention)
408 ;; fcpy 2 ALU 1
409 ;; fabs 2 ALU 1
410 ;; fadd 2 ALU 1
411 ;; fsub 2 ALU 1
412 ;; fcmp 2 ALU 1
413 ;; fcnv 2 ALU 1
414 ;; fmpyadd,sgl 2 ALU,MPY 1
415 ;; fmpyadd,dbl 3 ALU,MPY 2
416 ;; fmpysub,sgl 2 ALU,MPY 1
417 ;; fmpysub,dbl 3 ALU,MPY 2
418 ;; fmpycfxt,sgl 2 ALU,MPY 1
419 ;; fmpycfxt,dbl 3 ALU,MPY 2
420 ;; fmpy,sgl 2 MPY 1
421 ;; fmpy,dbl 3 MPY 2
422 ;; fmpyi 3 MPY 2
423 ;; fdiv,sgl 8 DIV 8
424 ;; fdiv,dbl 15 DIV 15
425 ;; fsqrt,sgl 8 DIV 8
426 ;; fsqrt,dbl 15 DIV 15
427 ;;
428 ;; The PA7200 is just like the PA7100LC except that there is
429 ;; no store-store penalty.
430 ;;
431 ;; The PA7300 is just like the PA7200 except that there is
432 ;; no store-load penalty.
433 ;;
434 ;; Note there are some aspects of the 7100LC we are not modeling
435 ;; at the moment. I'll be reviewing the 7100LC scheduling info
436 ;; shortly and updating this description.
437 ;;
438 ;; load-load pairs
439 ;; store-store pairs
440 ;; other issue modeling
441
442 (define_automaton "pa7100lc")
443 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
444 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
445 (define_cpu_unit "mem_7100lc" "pa7100lc")
446
447 ;; Double precision multiplies lock the entire CPU for one
448 ;; cycle. There is no way to avoid this lock and trying to
449 ;; schedule around the lock is pointless and thus there is no
450 ;; value in trying to model this lock.
451 ;;
452 ;; Not modeling the lock allows us to treat fp multiplies just
453 ;; like any other FP alu instruction. It allows for a smaller
454 ;; DFA and may reduce register pressure.
455 (define_insn_reservation "Y0" 2
456 (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
457 (eq_attr "cpu" "7100LC,7200,7300"))
458 "f_7100lc,fpmac_7100lc")
459
460 ;; fp division and sqrt instructions lock the entire CPU for
461 ;; 7 cycles (single precision) or 14 cycles (double precision).
462 ;; There is no way to avoid this lock and trying to schedule
463 ;; around the lock is pointless and thus there is no value in
464 ;; trying to model this lock. Not modeling the lock allows
465 ;; for a smaller DFA and may reduce register pressure.
466 (define_insn_reservation "Y1" 1
467 (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
468 (eq_attr "cpu" "7100LC,7200,7300"))
469 "f_7100lc")
470
471 (define_insn_reservation "Y2" 2
472 (and (eq_attr "type" "load")
473 (eq_attr "cpu" "7100LC,7200,7300"))
474 "i1_7100lc+mem_7100lc")
475
476 (define_insn_reservation "Y3" 2
477 (and (eq_attr "type" "fpload")
478 (eq_attr "cpu" "7100LC,7200,7300"))
479 "i1_7100lc+mem_7100lc")
480
481 (define_insn_reservation "Y4" 2
482 (and (eq_attr "type" "store")
483 (eq_attr "cpu" "7100LC"))
484 "i1_7100lc+mem_7100lc,mem_7100lc")
485
486 (define_insn_reservation "Y5" 2
487 (and (eq_attr "type" "fpstore")
488 (eq_attr "cpu" "7100LC"))
489 "i1_7100lc+mem_7100lc,mem_7100lc")
490
491 (define_insn_reservation "Y6" 4
492 (and (eq_attr "type" "fpstore_load")
493 (eq_attr "cpu" "7100LC"))
494 "i1_7100lc+mem_7100lc,mem_7100lc*3")
495
496 (define_insn_reservation "Y7" 4
497 (and (eq_attr "type" "store_fpload")
498 (eq_attr "cpu" "7100LC"))
499 "i1_7100lc+mem_7100lc,mem_7100lc*3")
500
501 (define_insn_reservation "Y8" 1
502 (and (eq_attr "type" "shift,nullshift")
503 (eq_attr "cpu" "7100LC,7200,7300"))
504 "i1_7100lc")
505
506 (define_insn_reservation "Y9" 1
507 (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
508 (eq_attr "cpu" "7100LC,7200,7300"))
509 "(i0_7100lc|i1_7100lc)")
510
511 ;; The 7200 has a store-load penalty
512 (define_insn_reservation "Y10" 2
513 (and (eq_attr "type" "store")
514 (eq_attr "cpu" "7200"))
515 "i1_7100lc,mem_7100lc")
516
517 (define_insn_reservation "Y11" 2
518 (and (eq_attr "type" "fpstore")
519 (eq_attr "cpu" "7200"))
520 "i1_7100lc,mem_7100lc")
521
522 (define_insn_reservation "Y12" 4
523 (and (eq_attr "type" "fpstore_load")
524 (eq_attr "cpu" "7200"))
525 "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
526
527 (define_insn_reservation "Y13" 4
528 (and (eq_attr "type" "store_fpload")
529 (eq_attr "cpu" "7200"))
530 "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
531
532 ;; The 7300 has no penalty for store-store or store-load
533 (define_insn_reservation "Y14" 2
534 (and (eq_attr "type" "store")
535 (eq_attr "cpu" "7300"))
536 "i1_7100lc")
537
538 (define_insn_reservation "Y15" 2
539 (and (eq_attr "type" "fpstore")
540 (eq_attr "cpu" "7300"))
541 "i1_7100lc")
542
543 (define_insn_reservation "Y16" 4
544 (and (eq_attr "type" "fpstore_load")
545 (eq_attr "cpu" "7300"))
546 "i1_7100lc,i1_7100lc+mem_7100lc")
547
548 (define_insn_reservation "Y17" 4
549 (and (eq_attr "type" "store_fpload")
550 (eq_attr "cpu" "7300"))
551 "i1_7100lc,i1_7100lc+mem_7100lc")
552
553 ;; We have an "anti-bypass" for FP loads which feed an FP store.
554 (define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
555
556 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
557 ;; traditional architecture.
558 ;;
559 ;; The PA8000 has a large (56) entry reorder buffer that is split between
560 ;; memory and non-memory operations.
561 ;;
562 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
563 ;; the function units, with the exception of branches and multi-output
564 ;; instructions. The PA8000 can retire two non-memory operations per cycle
565 ;; and two memory operations per cycle, only one of which may be a store.
566 ;;
567 ;; Given the large reorder buffer, the processor can hide most latencies.
568 ;; According to HP, they've got the best results by scheduling for retirement
569 ;; bandwidth with limited latency scheduling for floating point operations.
570 ;; Latency for integer operations and memory references is ignored.
571 ;;
572 ;;
573 ;; We claim floating point operations have a 2 cycle latency and are
574 ;; fully pipelined, except for div and sqrt which are not pipelined and
575 ;; take from 17 to 31 cycles to complete.
576 ;;
577 ;; It's worth noting that there is no way to saturate all the functional
578 ;; units on the PA8000 as there is not enough issue bandwidth.
579
580 (define_automaton "pa8000")
581 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
582 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
583 (define_cpu_unit "store_8000" "pa8000")
584 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
585 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
586 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
587 (define_reservation "im_8000" "im0_8000 | im1_8000")
588 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
589 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
590 (define_reservation "f_8000" "f0_8000 | f1_8000")
591 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
592
593 ;; We can issue any two memops per cycle, but we can only retire
594 ;; one memory store per cycle. We assume that the reorder buffer
595 ;; will hide any memory latencies per HP's recommendation.
596 (define_insn_reservation "Z0" 0
597 (and
598 (eq_attr "type" "load,fpload")
599 (eq_attr "cpu" "8000"))
600 "im_8000,rm_8000")
601
602 (define_insn_reservation "Z1" 0
603 (and
604 (eq_attr "type" "store,fpstore")
605 (eq_attr "cpu" "8000"))
606 "im_8000,rm_8000+store_8000")
607
608 (define_insn_reservation "Z2" 0
609 (and (eq_attr "type" "fpstore_load,store_fpload")
610 (eq_attr "cpu" "8000"))
611 "im_8000,rm_8000+store_8000,im_8000,rm_8000")
612
613 ;; We can issue and retire two non-memory operations per cycle with
614 ;; a few exceptions (branches). This group catches those we want
615 ;; to assume have zero latency.
616 (define_insn_reservation "Z3" 0
617 (and
618 (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_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")
619 (eq_attr "cpu" "8000"))
620 "inm_8000,rnm_8000")
621
622 ;; Branches use both slots in the non-memory issue and
623 ;; retirement unit.
624 (define_insn_reservation "Z4" 0
625 (and
626 (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
627 (eq_attr "cpu" "8000"))
628 "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
629
630 ;; We partial latency schedule the floating point units.
631 ;; They can issue/retire two at a time in the non-memory
632 ;; units. We fix their latency at 2 cycles and they
633 ;; are fully pipelined.
634 (define_insn_reservation "Z5" 1
635 (and
636 (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
637 (eq_attr "cpu" "8000"))
638 "inm_8000,f_8000,rnm_8000")
639
640 ;; The fdivsqrt units are not pipelined and have a very long latency.
641 ;; To keep the DFA from exploding, we do not show all the
642 ;; reservations for the divsqrt unit.
643 (define_insn_reservation "Z6" 17
644 (and
645 (eq_attr "type" "fpdivsgl,fpsqrtsgl")
646 (eq_attr "cpu" "8000"))
647 "inm_8000,fdivsqrt_8000*6,rnm_8000")
648
649 (define_insn_reservation "Z7" 31
650 (and
651 (eq_attr "type" "fpdivdbl,fpsqrtdbl")
652 (eq_attr "cpu" "8000"))
653 "inm_8000,fdivsqrt_8000*6,rnm_8000")
654
655 ;; Operand and operator predicates and constraints
656
657 (include "predicates.md")
658 (include "constraints.md")
659 \f
660 ;; Compare instructions.
661 ;; This controls RTL generation and register allocation.
662
663 (define_insn ""
664 [(set (reg:CCFP 0)
665 (match_operator:CCFP 2 "comparison_operator"
666 [(match_operand:SF 0 "reg_or_0_operand" "fG")
667 (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
668 "! TARGET_SOFT_FLOAT"
669 "fcmp,sgl,%Y2 %f0,%f1"
670 [(set_attr "length" "4")
671 (set_attr "type" "fpcc")])
672
673 (define_insn ""
674 [(set (reg:CCFP 0)
675 (match_operator:CCFP 2 "comparison_operator"
676 [(match_operand:DF 0 "reg_or_0_operand" "fG")
677 (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
678 "! TARGET_SOFT_FLOAT"
679 "fcmp,dbl,%Y2 %f0,%f1"
680 [(set_attr "length" "4")
681 (set_attr "type" "fpcc")])
682
683 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
684 ;; placeholders. This is necessary in rare situations when a
685 ;; placeholder is re-emitted (see PR 8705).
686
687 (define_expand "movccfp"
688 [(set (reg:CCFP 0)
689 (match_operand 0 "const_int_operand" ""))]
690 "! TARGET_SOFT_FLOAT"
691 "
692 {
693 if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
694 FAIL;
695 }")
696
697 ;; The following patterns are optimization placeholders. In almost
698 ;; all cases, the user of the condition code will be simplified and the
699 ;; original condition code setting insn should be eliminated.
700
701 (define_insn "*movccfp0"
702 [(set (reg:CCFP 0)
703 (const_int 0))]
704 "! TARGET_SOFT_FLOAT"
705 "fcmp,dbl,= %%fr0,%%fr0"
706 [(set_attr "length" "4")
707 (set_attr "type" "fpcc")])
708
709 (define_insn "*movccfp1"
710 [(set (reg:CCFP 0)
711 (const_int 1))]
712 "! TARGET_SOFT_FLOAT"
713 "fcmp,dbl,!= %%fr0,%%fr0"
714 [(set_attr "length" "4")
715 (set_attr "type" "fpcc")])
716
717 ;; scc insns.
718
719 (define_expand "cstoresi4"
720 [(set (match_operand:SI 0 "register_operand")
721 (match_operator:SI 1 "ordered_comparison_operator"
722 [(match_operand:SI 2 "reg_or_0_operand" "")
723 (match_operand:SI 3 "arith5_operand" "")]))]
724 "!TARGET_64BIT"
725 "")
726
727 ;; Instruction canonicalization puts immediate operands second, which
728 ;; is the reverse of what we want.
729
730 (define_insn "scc"
731 [(set (match_operand:SI 0 "register_operand" "=r")
732 (match_operator:SI 3 "comparison_operator"
733 [(match_operand:SI 1 "register_operand" "r")
734 (match_operand:SI 2 "arith11_operand" "rI")]))]
735 ""
736 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
737 [(set_attr "type" "binary")
738 (set_attr "length" "8")])
739
740 (define_insn ""
741 [(set (match_operand:DI 0 "register_operand" "=r")
742 (match_operator:DI 3 "comparison_operator"
743 [(match_operand:DI 1 "register_operand" "r")
744 (match_operand:DI 2 "arith11_operand" "rI")]))]
745 "TARGET_64BIT"
746 "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
747 [(set_attr "type" "binary")
748 (set_attr "length" "8")])
749
750 (define_insn "iorscc"
751 [(set (match_operand:SI 0 "register_operand" "=r")
752 (ior:SI (match_operator:SI 3 "comparison_operator"
753 [(match_operand:SI 1 "register_operand" "r")
754 (match_operand:SI 2 "arith11_operand" "rI")])
755 (match_operator:SI 6 "comparison_operator"
756 [(match_operand:SI 4 "register_operand" "r")
757 (match_operand:SI 5 "arith11_operand" "rI")])))]
758 ""
759 "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
760 [(set_attr "type" "binary")
761 (set_attr "length" "12")])
762
763 (define_insn ""
764 [(set (match_operand:DI 0 "register_operand" "=r")
765 (ior:DI (match_operator:DI 3 "comparison_operator"
766 [(match_operand:DI 1 "register_operand" "r")
767 (match_operand:DI 2 "arith11_operand" "rI")])
768 (match_operator:DI 6 "comparison_operator"
769 [(match_operand:DI 4 "register_operand" "r")
770 (match_operand:DI 5 "arith11_operand" "rI")])))]
771 "TARGET_64BIT"
772 "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
773 [(set_attr "type" "binary")
774 (set_attr "length" "12")])
775
776 ;; Combiner patterns for common operations performed with the output
777 ;; from an scc insn (negscc and incscc).
778 (define_insn "negscc"
779 [(set (match_operand:SI 0 "register_operand" "=r")
780 (neg:SI (match_operator:SI 3 "comparison_operator"
781 [(match_operand:SI 1 "register_operand" "r")
782 (match_operand:SI 2 "arith11_operand" "rI")])))]
783 ""
784 "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
785 [(set_attr "type" "binary")
786 (set_attr "length" "8")])
787
788 (define_insn ""
789 [(set (match_operand:DI 0 "register_operand" "=r")
790 (neg:DI (match_operator:DI 3 "comparison_operator"
791 [(match_operand:DI 1 "register_operand" "r")
792 (match_operand:DI 2 "arith11_operand" "rI")])))]
793 "TARGET_64BIT"
794 "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
795 [(set_attr "type" "binary")
796 (set_attr "length" "8")])
797
798 ;; Patterns for adding/subtracting the result of a boolean expression from
799 ;; a register. First we have special patterns that make use of the carry
800 ;; bit, and output only two instructions. For the cases we can't in
801 ;; general do in two instructions, the incscc pattern at the end outputs
802 ;; two or three instructions.
803
804 (define_insn ""
805 [(set (match_operand:SI 0 "register_operand" "=r")
806 (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
807 (match_operand:SI 3 "arith11_operand" "rI"))
808 (match_operand:SI 1 "register_operand" "r")))]
809 ""
810 "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
811 [(set_attr "type" "binary")
812 (set_attr "length" "8")])
813
814 (define_insn ""
815 [(set (match_operand:DI 0 "register_operand" "=r")
816 (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
817 (match_operand:DI 3 "arith11_operand" "rI"))
818 (match_operand:DI 1 "register_operand" "r")))]
819 "TARGET_64BIT"
820 "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
821 [(set_attr "type" "binary")
822 (set_attr "length" "8")])
823
824 ; This need only accept registers for op3, since canonicalization
825 ; replaces geu with gtu when op3 is an integer.
826 (define_insn ""
827 [(set (match_operand:SI 0 "register_operand" "=r")
828 (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
829 (match_operand:SI 3 "register_operand" "r"))
830 (match_operand:SI 1 "register_operand" "r")))]
831 ""
832 "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
833 [(set_attr "type" "binary")
834 (set_attr "length" "8")])
835
836 (define_insn ""
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
839 (match_operand:DI 3 "register_operand" "r"))
840 (match_operand:DI 1 "register_operand" "r")))]
841 "TARGET_64BIT"
842 "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
843 [(set_attr "type" "binary")
844 (set_attr "length" "8")])
845
846 ; Match only integers for op3 here. This is used as canonical form of the
847 ; geu pattern when op3 is an integer. Don't match registers since we can't
848 ; make better code than the general incscc pattern.
849 (define_insn ""
850 [(set (match_operand:SI 0 "register_operand" "=r")
851 (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
852 (match_operand:SI 3 "int11_operand" "I"))
853 (match_operand:SI 1 "register_operand" "r")))]
854 ""
855 "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
856 [(set_attr "type" "binary")
857 (set_attr "length" "8")])
858
859 (define_insn ""
860 [(set (match_operand:DI 0 "register_operand" "=r")
861 (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
862 (match_operand:DI 3 "int11_operand" "I"))
863 (match_operand:DI 1 "register_operand" "r")))]
864 "TARGET_64BIT"
865 "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
866 [(set_attr "type" "binary")
867 (set_attr "length" "8")])
868
869 (define_insn "incscc"
870 [(set (match_operand:SI 0 "register_operand" "=r,r")
871 (plus:SI (match_operator:SI 4 "comparison_operator"
872 [(match_operand:SI 2 "register_operand" "r,r")
873 (match_operand:SI 3 "arith11_operand" "rI,rI")])
874 (match_operand:SI 1 "register_operand" "0,?r")))]
875 ""
876 "@
877 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
878 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
879 [(set_attr "type" "binary,binary")
880 (set_attr "length" "8,12")])
881
882 (define_insn ""
883 [(set (match_operand:DI 0 "register_operand" "=r,r")
884 (plus:DI (match_operator:DI 4 "comparison_operator"
885 [(match_operand:DI 2 "register_operand" "r,r")
886 (match_operand:DI 3 "arith11_operand" "rI,rI")])
887 (match_operand:DI 1 "register_operand" "0,?r")))]
888 "TARGET_64BIT"
889 "@
890 cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
891 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
892 [(set_attr "type" "binary,binary")
893 (set_attr "length" "8,12")])
894
895 (define_insn ""
896 [(set (match_operand:SI 0 "register_operand" "=r")
897 (minus:SI (match_operand:SI 1 "register_operand" "r")
898 (gtu:SI (match_operand:SI 2 "register_operand" "r")
899 (match_operand:SI 3 "arith11_operand" "rI"))))]
900 ""
901 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
902 [(set_attr "type" "binary")
903 (set_attr "length" "8")])
904
905 (define_insn ""
906 [(set (match_operand:DI 0 "register_operand" "=r")
907 (minus:DI (match_operand:DI 1 "register_operand" "r")
908 (gtu:DI (match_operand:DI 2 "register_operand" "r")
909 (match_operand:DI 3 "arith11_operand" "rI"))))]
910 "TARGET_64BIT"
911 "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
912 [(set_attr "type" "binary")
913 (set_attr "length" "8")])
914
915 (define_insn ""
916 [(set (match_operand:SI 0 "register_operand" "=r")
917 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
918 (gtu:SI (match_operand:SI 2 "register_operand" "r")
919 (match_operand:SI 3 "arith11_operand" "rI")))
920 (match_operand:SI 4 "register_operand" "r")))]
921 ""
922 "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
923 [(set_attr "type" "binary")
924 (set_attr "length" "8")])
925
926 (define_insn ""
927 [(set (match_operand:DI 0 "register_operand" "=r")
928 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
929 (gtu:DI (match_operand:DI 2 "register_operand" "r")
930 (match_operand:DI 3 "arith11_operand" "rI")))
931 (match_operand:DI 4 "register_operand" "r")))]
932 "TARGET_64BIT"
933 "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
934 [(set_attr "type" "binary")
935 (set_attr "length" "8")])
936
937 ; This need only accept registers for op3, since canonicalization
938 ; replaces ltu with leu when op3 is an integer.
939 (define_insn ""
940 [(set (match_operand:SI 0 "register_operand" "=r")
941 (minus:SI (match_operand:SI 1 "register_operand" "r")
942 (ltu:SI (match_operand:SI 2 "register_operand" "r")
943 (match_operand:SI 3 "register_operand" "r"))))]
944 ""
945 "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
946 [(set_attr "type" "binary")
947 (set_attr "length" "8")])
948
949 (define_insn ""
950 [(set (match_operand:DI 0 "register_operand" "=r")
951 (minus:DI (match_operand:DI 1 "register_operand" "r")
952 (ltu:DI (match_operand:DI 2 "register_operand" "r")
953 (match_operand:DI 3 "register_operand" "r"))))]
954 "TARGET_64BIT"
955 "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
956 [(set_attr "type" "binary")
957 (set_attr "length" "8")])
958
959 (define_insn ""
960 [(set (match_operand:SI 0 "register_operand" "=r")
961 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
962 (ltu:SI (match_operand:SI 2 "register_operand" "r")
963 (match_operand:SI 3 "register_operand" "r")))
964 (match_operand:SI 4 "register_operand" "r")))]
965 ""
966 "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
967 [(set_attr "type" "binary")
968 (set_attr "length" "8")])
969
970 (define_insn ""
971 [(set (match_operand:DI 0 "register_operand" "=r")
972 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
973 (ltu:DI (match_operand:DI 2 "register_operand" "r")
974 (match_operand:DI 3 "register_operand" "r")))
975 (match_operand:DI 4 "register_operand" "r")))]
976 "TARGET_64BIT"
977 "sub %2,%3,%%r0\;sub,db %1,%4,%0"
978 [(set_attr "type" "binary")
979 (set_attr "length" "8")])
980
981 ; Match only integers for op3 here. This is used as canonical form of the
982 ; ltu pattern when op3 is an integer. Don't match registers since we can't
983 ; make better code than the general incscc pattern.
984 (define_insn ""
985 [(set (match_operand:SI 0 "register_operand" "=r")
986 (minus:SI (match_operand:SI 1 "register_operand" "r")
987 (leu:SI (match_operand:SI 2 "register_operand" "r")
988 (match_operand:SI 3 "int11_operand" "I"))))]
989 ""
990 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
991 [(set_attr "type" "binary")
992 (set_attr "length" "8")])
993
994 (define_insn ""
995 [(set (match_operand:DI 0 "register_operand" "=r")
996 (minus:DI (match_operand:DI 1 "register_operand" "r")
997 (leu:DI (match_operand:DI 2 "register_operand" "r")
998 (match_operand:DI 3 "int11_operand" "I"))))]
999 "TARGET_64BIT"
1000 "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1001 [(set_attr "type" "binary")
1002 (set_attr "length" "8")])
1003
1004 (define_insn ""
1005 [(set (match_operand:SI 0 "register_operand" "=r")
1006 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1007 (leu:SI (match_operand:SI 2 "register_operand" "r")
1008 (match_operand:SI 3 "int11_operand" "I")))
1009 (match_operand:SI 4 "register_operand" "r")))]
1010 ""
1011 "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1012 [(set_attr "type" "binary")
1013 (set_attr "length" "8")])
1014
1015 (define_insn ""
1016 [(set (match_operand:DI 0 "register_operand" "=r")
1017 (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1018 (leu:DI (match_operand:DI 2 "register_operand" "r")
1019 (match_operand:DI 3 "int11_operand" "I")))
1020 (match_operand:DI 4 "register_operand" "r")))]
1021 "TARGET_64BIT"
1022 "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1023 [(set_attr "type" "binary")
1024 (set_attr "length" "8")])
1025
1026 (define_insn "decscc"
1027 [(set (match_operand:SI 0 "register_operand" "=r,r")
1028 (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1029 (match_operator:SI 4 "comparison_operator"
1030 [(match_operand:SI 2 "register_operand" "r,r")
1031 (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1032 ""
1033 "@
1034 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1035 {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1036 [(set_attr "type" "binary,binary")
1037 (set_attr "length" "8,12")])
1038
1039 (define_insn ""
1040 [(set (match_operand:DI 0 "register_operand" "=r,r")
1041 (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1042 (match_operator:DI 4 "comparison_operator"
1043 [(match_operand:DI 2 "register_operand" "r,r")
1044 (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1045 "TARGET_64BIT"
1046 "@
1047 cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1048 cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1049 [(set_attr "type" "binary,binary")
1050 (set_attr "length" "8,12")])
1051
1052 ; Patterns for max and min. (There is no need for an earlyclobber in the
1053 ; last alternative since the middle alternative will match if op0 == op1.)
1054
1055 (define_insn "sminsi3"
1056 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1057 (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1058 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1059 ""
1060 "@
1061 {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1062 {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1063 {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1064 [(set_attr "type" "multi,multi,multi")
1065 (set_attr "length" "8,8,8")])
1066
1067 (define_insn "smindi3"
1068 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1069 (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1070 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1071 "TARGET_64BIT"
1072 "@
1073 cmpclr,*> %2,%0,%%r0\;copy %2,%0
1074 cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1075 cmpclr,*> %1,%r2,%0\;copy %1,%0"
1076 [(set_attr "type" "multi,multi,multi")
1077 (set_attr "length" "8,8,8")])
1078
1079 (define_insn "uminsi3"
1080 [(set (match_operand:SI 0 "register_operand" "=r,r")
1081 (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1082 (match_operand:SI 2 "arith11_operand" "r,I")))]
1083 ""
1084 "@
1085 {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1086 {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1087 [(set_attr "type" "multi,multi")
1088 (set_attr "length" "8,8")])
1089
1090 (define_insn "umindi3"
1091 [(set (match_operand:DI 0 "register_operand" "=r,r")
1092 (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1093 (match_operand:DI 2 "arith11_operand" "r,I")))]
1094 "TARGET_64BIT"
1095 "@
1096 cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1097 cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1098 [(set_attr "type" "multi,multi")
1099 (set_attr "length" "8,8")])
1100
1101 (define_insn "smaxsi3"
1102 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1103 (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1104 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1105 ""
1106 "@
1107 {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1108 {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1109 {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1110 [(set_attr "type" "multi,multi,multi")
1111 (set_attr "length" "8,8,8")])
1112
1113 (define_insn "smaxdi3"
1114 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1115 (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1116 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1117 "TARGET_64BIT"
1118 "@
1119 cmpclr,*< %2,%0,%%r0\;copy %2,%0
1120 cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1121 cmpclr,*< %1,%r2,%0\;copy %1,%0"
1122 [(set_attr "type" "multi,multi,multi")
1123 (set_attr "length" "8,8,8")])
1124
1125 (define_insn "umaxsi3"
1126 [(set (match_operand:SI 0 "register_operand" "=r,r")
1127 (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1128 (match_operand:SI 2 "arith11_operand" "r,I")))]
1129 ""
1130 "@
1131 {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1132 {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1133 [(set_attr "type" "multi,multi")
1134 (set_attr "length" "8,8")])
1135
1136 (define_insn "umaxdi3"
1137 [(set (match_operand:DI 0 "register_operand" "=r,r")
1138 (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1139 (match_operand:DI 2 "arith11_operand" "r,I")))]
1140 "TARGET_64BIT"
1141 "@
1142 cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1143 cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1144 [(set_attr "type" "multi,multi")
1145 (set_attr "length" "8,8")])
1146
1147 (define_insn "abssi2"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1150 ""
1151 "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1152 [(set_attr "type" "multi")
1153 (set_attr "length" "8")])
1154
1155 (define_insn "absdi2"
1156 [(set (match_operand:DI 0 "register_operand" "=r")
1157 (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1158 "TARGET_64BIT"
1159 "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1160 [(set_attr "type" "multi")
1161 (set_attr "length" "8")])
1162
1163 ;;; Experimental conditional move patterns
1164
1165 (define_expand "movsicc"
1166 [(set (match_operand:SI 0 "register_operand" "")
1167 (if_then_else:SI
1168 (match_operand 1 "comparison_operator" "")
1169 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1170 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1171 ""
1172 "
1173 {
1174 if (GET_MODE (XEXP (operands[1], 0)) != SImode
1175 || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1176 FAIL;
1177 }")
1178
1179 ;; We used to accept any register for op1.
1180 ;;
1181 ;; However, it loses sometimes because the compiler will end up using
1182 ;; different registers for op0 and op1 in some critical cases. local-alloc
1183 ;; will not tie op0 and op1 because op0 is used in multiple basic blocks.
1184 ;;
1185 ;; If/when global register allocation supports tying we should allow any
1186 ;; register for op1 again.
1187 (define_insn ""
1188 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1189 (if_then_else:SI
1190 (match_operator 2 "comparison_operator"
1191 [(match_operand:SI 3 "register_operand" "r,r,r,r")
1192 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1193 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1194 (const_int 0)))]
1195 ""
1196 "@
1197 {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1198 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1199 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1200 {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1201 [(set_attr "type" "multi,multi,multi,nullshift")
1202 (set_attr "length" "8,8,8,8")])
1203
1204 (define_insn ""
1205 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1206 (if_then_else:SI
1207 (match_operator 5 "comparison_operator"
1208 [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1209 (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1210 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1211 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1212 ""
1213 "@
1214 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1215 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1216 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1217 {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1218 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1219 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1220 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1221 {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1222 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1223 (set_attr "length" "8,8,8,8,8,8,8,8")])
1224
1225 (define_expand "movdicc"
1226 [(set (match_operand:DI 0 "register_operand" "")
1227 (if_then_else:DI
1228 (match_operand 1 "comparison_operator" "")
1229 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1230 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1231 "TARGET_64BIT"
1232 "
1233 {
1234 if (GET_MODE (XEXP (operands[1], 0)) != DImode
1235 || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1236 FAIL;
1237 }")
1238
1239 ; We need the first constraint alternative in order to avoid
1240 ; earlyclobbers on all other alternatives.
1241 (define_insn ""
1242 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1243 (if_then_else:DI
1244 (match_operator 2 "comparison_operator"
1245 [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1246 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1247 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1248 (const_int 0)))]
1249 "TARGET_64BIT"
1250 "@
1251 cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1252 cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1253 cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1254 cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1255 cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1256 [(set_attr "type" "multi,multi,multi,multi,nullshift")
1257 (set_attr "length" "8,8,8,8,8")])
1258
1259 (define_insn ""
1260 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1261 (if_then_else:DI
1262 (match_operator 5 "comparison_operator"
1263 [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1264 (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1265 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1266 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1267 "TARGET_64BIT"
1268 "@
1269 cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1270 cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1271 cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1272 cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1273 cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1274 cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1275 cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1276 cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1277 [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1278 (set_attr "length" "8,8,8,8,8,8,8,8")])
1279
1280 ;; Conditional Branches
1281
1282 (define_expand "cbranchdi4"
1283 [(set (pc)
1284 (if_then_else (match_operator 0 "ordered_comparison_operator"
1285 [(match_operand:DI 1 "reg_or_0_operand" "")
1286 (match_operand:DI 2 "register_operand" "")])
1287 (label_ref (match_operand 3 "" ""))
1288 (pc)))]
1289 "TARGET_64BIT"
1290 "")
1291
1292 (define_expand "cbranchsi4"
1293 [(set (pc)
1294 (if_then_else (match_operator 0 "ordered_comparison_operator"
1295 [(match_operand:SI 1 "reg_or_0_operand" "")
1296 (match_operand:SI 2 "arith5_operand" "")])
1297 (label_ref (match_operand 3 "" ""))
1298 (pc)))]
1299 ""
1300 "")
1301
1302 (define_expand "cbranchsf4"
1303 [(set (pc)
1304 (if_then_else (match_operator 0 "comparison_operator"
1305 [(match_operand:SF 1 "reg_or_0_operand" "")
1306 (match_operand:SF 2 "reg_or_0_operand" "")])
1307 (label_ref (match_operand 3 "" ""))
1308 (pc)))]
1309 ""
1310 "
1311 {
1312 pa_emit_bcond_fp (operands);
1313 DONE;
1314 }")
1315
1316
1317 (define_expand "cbranchdf4"
1318 [(set (pc)
1319 (if_then_else (match_operator 0 "comparison_operator"
1320 [(match_operand:DF 1 "reg_or_0_operand" "")
1321 (match_operand:DF 2 "reg_or_0_operand" "")])
1322 (label_ref (match_operand 3 "" ""))
1323 (pc)))]
1324 ""
1325 "
1326 {
1327 pa_emit_bcond_fp (operands);
1328 DONE;
1329 }")
1330
1331 ;; Match the branch patterns.
1332
1333
1334 ;; Note a long backward conditional branch with an annulled delay slot
1335 ;; has a length of 12.
1336 (define_insn ""
1337 [(set (pc)
1338 (if_then_else
1339 (match_operator 3 "comparison_operator"
1340 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1341 (match_operand:SI 2 "arith5_operand" "rL")])
1342 (label_ref (match_operand 0 "" ""))
1343 (pc)))]
1344 ""
1345 "*
1346 {
1347 return pa_output_cbranch (operands, 0, insn);
1348 }"
1349 [(set_attr "type" "cbranch")
1350 (set (attr "length")
1351 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1352 (const_int MAX_12BIT_OFFSET))
1353 (const_int 4)
1354 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1355 (const_int MAX_17BIT_OFFSET))
1356 (const_int 8)
1357 (match_test "TARGET_PORTABLE_RUNTIME")
1358 (const_int 24)
1359 (not (match_test "flag_pic"))
1360 (const_int 20)]
1361 (const_int 28)))])
1362
1363 ;; Match the negated branch.
1364
1365 (define_insn ""
1366 [(set (pc)
1367 (if_then_else
1368 (match_operator 3 "comparison_operator"
1369 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1370 (match_operand:SI 2 "arith5_operand" "rL")])
1371 (pc)
1372 (label_ref (match_operand 0 "" ""))))]
1373 ""
1374 "*
1375 {
1376 return pa_output_cbranch (operands, 1, insn);
1377 }"
1378 [(set_attr "type" "cbranch")
1379 (set (attr "length")
1380 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1381 (const_int MAX_12BIT_OFFSET))
1382 (const_int 4)
1383 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1384 (const_int MAX_17BIT_OFFSET))
1385 (const_int 8)
1386 (match_test "TARGET_PORTABLE_RUNTIME")
1387 (const_int 24)
1388 (not (match_test "flag_pic"))
1389 (const_int 20)]
1390 (const_int 28)))])
1391
1392 (define_insn ""
1393 [(set (pc)
1394 (if_then_else
1395 (match_operator 3 "comparison_operator"
1396 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1397 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1398 (label_ref (match_operand 0 "" ""))
1399 (pc)))]
1400 "TARGET_64BIT"
1401 "*
1402 {
1403 return pa_output_cbranch (operands, 0, insn);
1404 }"
1405 [(set_attr "type" "cbranch")
1406 (set (attr "length")
1407 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1408 (const_int MAX_12BIT_OFFSET))
1409 (const_int 4)
1410 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1411 (const_int MAX_17BIT_OFFSET))
1412 (const_int 8)
1413 (match_test "TARGET_PORTABLE_RUNTIME")
1414 (const_int 24)
1415 (not (match_test "flag_pic"))
1416 (const_int 20)]
1417 (const_int 28)))])
1418
1419 ;; Match the negated branch.
1420
1421 (define_insn ""
1422 [(set (pc)
1423 (if_then_else
1424 (match_operator 3 "comparison_operator"
1425 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1426 (match_operand:DI 2 "reg_or_0_operand" "rM")])
1427 (pc)
1428 (label_ref (match_operand 0 "" ""))))]
1429 "TARGET_64BIT"
1430 "*
1431 {
1432 return pa_output_cbranch (operands, 1, insn);
1433 }"
1434 [(set_attr "type" "cbranch")
1435 (set (attr "length")
1436 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1437 (const_int MAX_12BIT_OFFSET))
1438 (const_int 4)
1439 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1440 (const_int MAX_17BIT_OFFSET))
1441 (const_int 8)
1442 (match_test "TARGET_PORTABLE_RUNTIME")
1443 (const_int 24)
1444 (not (match_test "flag_pic"))
1445 (const_int 20)]
1446 (const_int 28)))])
1447 (define_insn ""
1448 [(set (pc)
1449 (if_then_else
1450 (match_operator 3 "cmpib_comparison_operator"
1451 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1452 (match_operand:DI 2 "arith5_operand" "rL")])
1453 (label_ref (match_operand 0 "" ""))
1454 (pc)))]
1455 "TARGET_64BIT"
1456 "*
1457 {
1458 return pa_output_cbranch (operands, 0, insn);
1459 }"
1460 [(set_attr "type" "cbranch")
1461 (set (attr "length")
1462 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1463 (const_int MAX_12BIT_OFFSET))
1464 (const_int 4)
1465 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1466 (const_int MAX_17BIT_OFFSET))
1467 (const_int 8)
1468 (match_test "TARGET_PORTABLE_RUNTIME")
1469 (const_int 24)
1470 (not (match_test "flag_pic"))
1471 (const_int 20)]
1472 (const_int 28)))])
1473
1474 ;; Match the negated branch.
1475
1476 (define_insn ""
1477 [(set (pc)
1478 (if_then_else
1479 (match_operator 3 "cmpib_comparison_operator"
1480 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1481 (match_operand:DI 2 "arith5_operand" "rL")])
1482 (pc)
1483 (label_ref (match_operand 0 "" ""))))]
1484 "TARGET_64BIT"
1485 "*
1486 {
1487 return pa_output_cbranch (operands, 1, insn);
1488 }"
1489 [(set_attr "type" "cbranch")
1490 (set (attr "length")
1491 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1492 (const_int MAX_12BIT_OFFSET))
1493 (const_int 4)
1494 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1495 (const_int MAX_17BIT_OFFSET))
1496 (const_int 8)
1497 (match_test "TARGET_PORTABLE_RUNTIME")
1498 (const_int 24)
1499 (not (match_test "flag_pic"))
1500 (const_int 20)]
1501 (const_int 28)))])
1502
1503 ;; Branch on Bit patterns.
1504 (define_insn ""
1505 [(set (pc)
1506 (if_then_else
1507 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1508 (const_int 1)
1509 (match_operand:SI 1 "uint5_operand" ""))
1510 (const_int 0))
1511 (label_ref (match_operand 2 "" ""))
1512 (pc)))]
1513 ""
1514 "*
1515 {
1516 return pa_output_bb (operands, 0, insn, 0);
1517 }"
1518 [(set_attr "type" "cbranch")
1519 (set (attr "length")
1520 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1521 (const_int MAX_12BIT_OFFSET))
1522 (const_int 4)
1523 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1524 (const_int MAX_17BIT_OFFSET))
1525 (const_int 8)
1526 (match_test "TARGET_PORTABLE_RUNTIME")
1527 (const_int 24)
1528 (not (match_test "flag_pic"))
1529 (const_int 20)]
1530 (const_int 28)))])
1531
1532 (define_insn ""
1533 [(set (pc)
1534 (if_then_else
1535 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1536 (const_int 1)
1537 (match_operand:DI 1 "uint32_operand" ""))
1538 (const_int 0))
1539 (label_ref (match_operand 2 "" ""))
1540 (pc)))]
1541 "TARGET_64BIT"
1542 "*
1543 {
1544 return pa_output_bb (operands, 0, insn, 0);
1545 }"
1546 [(set_attr "type" "cbranch")
1547 (set (attr "length")
1548 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1549 (const_int MAX_12BIT_OFFSET))
1550 (const_int 4)
1551 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1552 (const_int MAX_17BIT_OFFSET))
1553 (const_int 8)
1554 (match_test "TARGET_PORTABLE_RUNTIME")
1555 (const_int 24)
1556 (not (match_test "flag_pic"))
1557 (const_int 20)]
1558 (const_int 28)))])
1559
1560 (define_insn ""
1561 [(set (pc)
1562 (if_then_else
1563 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1564 (const_int 1)
1565 (match_operand:SI 1 "uint5_operand" ""))
1566 (const_int 0))
1567 (pc)
1568 (label_ref (match_operand 2 "" ""))))]
1569 ""
1570 "*
1571 {
1572 return pa_output_bb (operands, 1, insn, 0);
1573 }"
1574 [(set_attr "type" "cbranch")
1575 (set (attr "length")
1576 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1577 (const_int MAX_12BIT_OFFSET))
1578 (const_int 4)
1579 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1580 (const_int MAX_17BIT_OFFSET))
1581 (const_int 8)
1582 (match_test "TARGET_PORTABLE_RUNTIME")
1583 (const_int 24)
1584 (not (match_test "flag_pic"))
1585 (const_int 20)]
1586 (const_int 28)))])
1587
1588 (define_insn ""
1589 [(set (pc)
1590 (if_then_else
1591 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1592 (const_int 1)
1593 (match_operand:DI 1 "uint32_operand" ""))
1594 (const_int 0))
1595 (pc)
1596 (label_ref (match_operand 2 "" ""))))]
1597 "TARGET_64BIT"
1598 "*
1599 {
1600 return pa_output_bb (operands, 1, insn, 0);
1601 }"
1602 [(set_attr "type" "cbranch")
1603 (set (attr "length")
1604 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1605 (const_int MAX_12BIT_OFFSET))
1606 (const_int 4)
1607 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1608 (const_int MAX_17BIT_OFFSET))
1609 (const_int 8)
1610 (match_test "TARGET_PORTABLE_RUNTIME")
1611 (const_int 24)
1612 (not (match_test "flag_pic"))
1613 (const_int 20)]
1614 (const_int 28)))])
1615
1616 (define_insn ""
1617 [(set (pc)
1618 (if_then_else
1619 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1620 (const_int 1)
1621 (match_operand:SI 1 "uint5_operand" ""))
1622 (const_int 0))
1623 (label_ref (match_operand 2 "" ""))
1624 (pc)))]
1625 ""
1626 "*
1627 {
1628 return pa_output_bb (operands, 0, insn, 1);
1629 }"
1630 [(set_attr "type" "cbranch")
1631 (set (attr "length")
1632 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1633 (const_int MAX_12BIT_OFFSET))
1634 (const_int 4)
1635 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1636 (const_int MAX_17BIT_OFFSET))
1637 (const_int 8)
1638 (match_test "TARGET_PORTABLE_RUNTIME")
1639 (const_int 24)
1640 (not (match_test "flag_pic"))
1641 (const_int 20)]
1642 (const_int 28)))])
1643
1644 (define_insn ""
1645 [(set (pc)
1646 (if_then_else
1647 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1648 (const_int 1)
1649 (match_operand:DI 1 "uint32_operand" ""))
1650 (const_int 0))
1651 (label_ref (match_operand 2 "" ""))
1652 (pc)))]
1653 "TARGET_64BIT"
1654 "*
1655 {
1656 return pa_output_bb (operands, 0, insn, 1);
1657 }"
1658 [(set_attr "type" "cbranch")
1659 (set (attr "length")
1660 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1661 (const_int MAX_12BIT_OFFSET))
1662 (const_int 4)
1663 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1664 (const_int MAX_17BIT_OFFSET))
1665 (const_int 8)
1666 (match_test "TARGET_PORTABLE_RUNTIME")
1667 (const_int 24)
1668 (not (match_test "flag_pic"))
1669 (const_int 20)]
1670 (const_int 28)))])
1671
1672 (define_insn ""
1673 [(set (pc)
1674 (if_then_else
1675 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1676 (const_int 1)
1677 (match_operand:SI 1 "uint5_operand" ""))
1678 (const_int 0))
1679 (pc)
1680 (label_ref (match_operand 2 "" ""))))]
1681 ""
1682 "*
1683 {
1684 return pa_output_bb (operands, 1, insn, 1);
1685 }"
1686 [(set_attr "type" "cbranch")
1687 (set (attr "length")
1688 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1689 (const_int MAX_12BIT_OFFSET))
1690 (const_int 4)
1691 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1692 (const_int MAX_17BIT_OFFSET))
1693 (const_int 8)
1694 (match_test "TARGET_PORTABLE_RUNTIME")
1695 (const_int 24)
1696 (not (match_test "flag_pic"))
1697 (const_int 20)]
1698 (const_int 28)))])
1699
1700 (define_insn ""
1701 [(set (pc)
1702 (if_then_else
1703 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1704 (const_int 1)
1705 (match_operand:DI 1 "uint32_operand" ""))
1706 (const_int 0))
1707 (pc)
1708 (label_ref (match_operand 2 "" ""))))]
1709 "TARGET_64BIT"
1710 "*
1711 {
1712 return pa_output_bb (operands, 1, insn, 1);
1713 }"
1714 [(set_attr "type" "cbranch")
1715 (set (attr "length")
1716 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1717 (const_int MAX_12BIT_OFFSET))
1718 (const_int 4)
1719 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1720 (const_int MAX_17BIT_OFFSET))
1721 (const_int 8)
1722 (match_test "TARGET_PORTABLE_RUNTIME")
1723 (const_int 24)
1724 (not (match_test "flag_pic"))
1725 (const_int 20)]
1726 (const_int 28)))])
1727
1728 ;; Branch on Variable Bit patterns.
1729 (define_insn ""
1730 [(set (pc)
1731 (if_then_else
1732 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1733 (const_int 1)
1734 (match_operand:SI 1 "register_operand" "q"))
1735 (const_int 0))
1736 (label_ref (match_operand 2 "" ""))
1737 (pc)))]
1738 ""
1739 "*
1740 {
1741 return pa_output_bvb (operands, 0, insn, 0);
1742 }"
1743 [(set_attr "type" "cbranch")
1744 (set (attr "length")
1745 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1746 (const_int MAX_12BIT_OFFSET))
1747 (const_int 4)
1748 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1749 (const_int MAX_17BIT_OFFSET))
1750 (const_int 8)
1751 (match_test "TARGET_PORTABLE_RUNTIME")
1752 (const_int 24)
1753 (not (match_test "flag_pic"))
1754 (const_int 20)]
1755 (const_int 28)))])
1756
1757 (define_insn ""
1758 [(set (pc)
1759 (if_then_else
1760 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1761 (const_int 1)
1762 (match_operand:DI 1 "register_operand" "q"))
1763 (const_int 0))
1764 (label_ref (match_operand 2 "" ""))
1765 (pc)))]
1766 "TARGET_64BIT"
1767 "*
1768 {
1769 return pa_output_bvb (operands, 0, insn, 0);
1770 }"
1771 [(set_attr "type" "cbranch")
1772 (set (attr "length")
1773 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1774 (const_int MAX_12BIT_OFFSET))
1775 (const_int 4)
1776 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1777 (const_int MAX_17BIT_OFFSET))
1778 (const_int 8)
1779 (match_test "TARGET_PORTABLE_RUNTIME")
1780 (const_int 24)
1781 (not (match_test "flag_pic"))
1782 (const_int 20)]
1783 (const_int 28)))])
1784
1785 (define_insn ""
1786 [(set (pc)
1787 (if_then_else
1788 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1789 (const_int 1)
1790 (match_operand:SI 1 "register_operand" "q"))
1791 (const_int 0))
1792 (pc)
1793 (label_ref (match_operand 2 "" ""))))]
1794 ""
1795 "*
1796 {
1797 return pa_output_bvb (operands, 1, insn, 0);
1798 }"
1799 [(set_attr "type" "cbranch")
1800 (set (attr "length")
1801 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1802 (const_int MAX_12BIT_OFFSET))
1803 (const_int 4)
1804 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1805 (const_int MAX_17BIT_OFFSET))
1806 (const_int 8)
1807 (match_test "TARGET_PORTABLE_RUNTIME")
1808 (const_int 24)
1809 (not (match_test "flag_pic"))
1810 (const_int 20)]
1811 (const_int 28)))])
1812
1813 (define_insn ""
1814 [(set (pc)
1815 (if_then_else
1816 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1817 (const_int 1)
1818 (match_operand:DI 1 "register_operand" "q"))
1819 (const_int 0))
1820 (pc)
1821 (label_ref (match_operand 2 "" ""))))]
1822 "TARGET_64BIT"
1823 "*
1824 {
1825 return pa_output_bvb (operands, 1, insn, 0);
1826 }"
1827 [(set_attr "type" "cbranch")
1828 (set (attr "length")
1829 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1830 (const_int MAX_12BIT_OFFSET))
1831 (const_int 4)
1832 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1833 (const_int MAX_17BIT_OFFSET))
1834 (const_int 8)
1835 (match_test "TARGET_PORTABLE_RUNTIME")
1836 (const_int 24)
1837 (not (match_test "flag_pic"))
1838 (const_int 20)]
1839 (const_int 28)))])
1840
1841 (define_insn ""
1842 [(set (pc)
1843 (if_then_else
1844 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1845 (const_int 1)
1846 (match_operand:SI 1 "register_operand" "q"))
1847 (const_int 0))
1848 (label_ref (match_operand 2 "" ""))
1849 (pc)))]
1850 ""
1851 "*
1852 {
1853 return pa_output_bvb (operands, 0, insn, 1);
1854 }"
1855 [(set_attr "type" "cbranch")
1856 (set (attr "length")
1857 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1858 (const_int MAX_12BIT_OFFSET))
1859 (const_int 4)
1860 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1861 (const_int MAX_17BIT_OFFSET))
1862 (const_int 8)
1863 (match_test "TARGET_PORTABLE_RUNTIME")
1864 (const_int 24)
1865 (not (match_test "flag_pic"))
1866 (const_int 20)]
1867 (const_int 28)))])
1868
1869 (define_insn ""
1870 [(set (pc)
1871 (if_then_else
1872 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1873 (const_int 1)
1874 (match_operand:DI 1 "register_operand" "q"))
1875 (const_int 0))
1876 (label_ref (match_operand 2 "" ""))
1877 (pc)))]
1878 "TARGET_64BIT"
1879 "*
1880 {
1881 return pa_output_bvb (operands, 0, insn, 1);
1882 }"
1883 [(set_attr "type" "cbranch")
1884 (set (attr "length")
1885 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1886 (const_int MAX_12BIT_OFFSET))
1887 (const_int 4)
1888 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1889 (const_int MAX_17BIT_OFFSET))
1890 (const_int 8)
1891 (match_test "TARGET_PORTABLE_RUNTIME")
1892 (const_int 24)
1893 (not (match_test "flag_pic"))
1894 (const_int 20)]
1895 (const_int 28)))])
1896
1897 (define_insn ""
1898 [(set (pc)
1899 (if_then_else
1900 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1901 (const_int 1)
1902 (match_operand:SI 1 "register_operand" "q"))
1903 (const_int 0))
1904 (pc)
1905 (label_ref (match_operand 2 "" ""))))]
1906 ""
1907 "*
1908 {
1909 return pa_output_bvb (operands, 1, insn, 1);
1910 }"
1911 [(set_attr "type" "cbranch")
1912 (set (attr "length")
1913 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1914 (const_int MAX_12BIT_OFFSET))
1915 (const_int 4)
1916 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1917 (const_int MAX_17BIT_OFFSET))
1918 (const_int 8)
1919 (match_test "TARGET_PORTABLE_RUNTIME")
1920 (const_int 24)
1921 (not (match_test "flag_pic"))
1922 (const_int 20)]
1923 (const_int 28)))])
1924
1925 (define_insn ""
1926 [(set (pc)
1927 (if_then_else
1928 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1929 (const_int 1)
1930 (match_operand:DI 1 "register_operand" "q"))
1931 (const_int 0))
1932 (pc)
1933 (label_ref (match_operand 2 "" ""))))]
1934 "TARGET_64BIT"
1935 "*
1936 {
1937 return pa_output_bvb (operands, 1, insn, 1);
1938 }"
1939 [(set_attr "type" "cbranch")
1940 (set (attr "length")
1941 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1942 (const_int MAX_12BIT_OFFSET))
1943 (const_int 4)
1944 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1945 (const_int MAX_17BIT_OFFSET))
1946 (const_int 8)
1947 (match_test "TARGET_PORTABLE_RUNTIME")
1948 (const_int 24)
1949 (not (match_test "flag_pic"))
1950 (const_int 20)]
1951 (const_int 28)))])
1952
1953 ;; Floating point branches
1954
1955 ;; ??? Nullification is handled differently from other branches.
1956 ;; If nullification is specified, the delay slot is nullified on any
1957 ;; taken branch regardless of branch direction.
1958 (define_insn ""
1959 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1960 (label_ref (match_operand 0 "" ""))
1961 (pc)))]
1962 "!TARGET_SOFT_FLOAT"
1963 "*
1964 {
1965 int length = get_attr_length (insn);
1966 rtx xoperands[1];
1967 int nullify, xdelay;
1968
1969 if (length < 16)
1970 return \"ftest\;b%* %l0\";
1971
1972 if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
1973 {
1974 nullify = 1;
1975 xdelay = 0;
1976 xoperands[0] = GEN_INT (length - 8);
1977 }
1978 else
1979 {
1980 nullify = 0;
1981 xdelay = 1;
1982 xoperands[0] = GEN_INT (length - 4);
1983 }
1984
1985 if (nullify)
1986 output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
1987 else
1988 output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
1989 return pa_output_lbranch (operands[0], insn, xdelay);
1990 }"
1991 [(set_attr "type" "fbranch")
1992 (set (attr "length")
1993 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1994 (const_int MAX_17BIT_OFFSET))
1995 (const_int 8)
1996 (match_test "TARGET_PORTABLE_RUNTIME")
1997 (const_int 32)
1998 (not (match_test "flag_pic"))
1999 (const_int 28)]
2000 (const_int 36)))])
2001
2002 (define_insn ""
2003 [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2004 (pc)
2005 (label_ref (match_operand 0 "" ""))))]
2006 "!TARGET_SOFT_FLOAT"
2007 "*
2008 {
2009 int length = get_attr_length (insn);
2010 rtx xoperands[1];
2011 int nullify, xdelay;
2012
2013 if (length < 16)
2014 return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2015
2016 if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2017 {
2018 nullify = 1;
2019 xdelay = 0;
2020 xoperands[0] = GEN_INT (length - 4);
2021 }
2022 else
2023 {
2024 nullify = 0;
2025 xdelay = 1;
2026 xoperands[0] = GEN_INT (length);
2027 }
2028
2029 if (nullify)
2030 output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2031 else
2032 output_asm_insn (\"ftest\;b .+%0\", xoperands);
2033 return pa_output_lbranch (operands[0], insn, xdelay);
2034 }"
2035 [(set_attr "type" "fbranch")
2036 (set (attr "length")
2037 (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2038 (const_int MAX_17BIT_OFFSET))
2039 (const_int 12)
2040 (match_test "TARGET_PORTABLE_RUNTIME")
2041 (const_int 28)
2042 (not (match_test "flag_pic"))
2043 (const_int 24)]
2044 (const_int 32)))])
2045
2046 ;; Move instructions
2047
2048 (define_expand "movsi"
2049 [(set (match_operand:SI 0 "general_operand" "")
2050 (match_operand:SI 1 "general_operand" ""))]
2051 ""
2052 "
2053 {
2054 if (pa_emit_move_sequence (operands, SImode, 0))
2055 DONE;
2056 }")
2057
2058 ;; Handle SImode input reloads requiring %r1 as a scratch register.
2059 (define_expand "reload_insi_r1"
2060 [(set (match_operand:SI 0 "register_operand" "=Z")
2061 (match_operand:SI 1 "non_hard_reg_operand" ""))
2062 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2063 ""
2064 "
2065 {
2066 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2067 DONE;
2068
2069 /* We don't want the clobber emitted, so handle this ourselves. */
2070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2071 DONE;
2072 }")
2073
2074 ;; Handle SImode input reloads requiring a general register as a
2075 ;; scratch register.
2076 (define_expand "reload_insi"
2077 [(set (match_operand:SI 0 "register_operand" "=Z")
2078 (match_operand:SI 1 "non_hard_reg_operand" ""))
2079 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2080 ""
2081 "
2082 {
2083 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2084 DONE;
2085
2086 /* We don't want the clobber emitted, so handle this ourselves. */
2087 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2088 DONE;
2089 }")
2090
2091 ;; Handle SImode output reloads requiring a general register as a
2092 ;; scratch register.
2093 (define_expand "reload_outsi"
2094 [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2095 (match_operand:SI 1 "register_operand" "Z"))
2096 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2097 ""
2098 "
2099 {
2100 if (pa_emit_move_sequence (operands, SImode, operands[2]))
2101 DONE;
2102
2103 /* We don't want the clobber emitted, so handle this ourselves. */
2104 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2105 DONE;
2106 }")
2107
2108 (define_insn ""
2109 [(set (match_operand:SI 0 "move_dest_operand"
2110 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2111 (match_operand:SI 1 "move_src_operand"
2112 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2113 "(register_operand (operands[0], SImode)
2114 || reg_or_0_operand (operands[1], SImode))
2115 && !TARGET_SOFT_FLOAT
2116 && !TARGET_64BIT"
2117 "@
2118 ldw RT'%A1,%0
2119 copy %1,%0
2120 ldi %1,%0
2121 ldil L'%1,%0
2122 {zdepi|depwi,z} %Z1,%0
2123 ldw%M1 %1,%0
2124 stw%M0 %r1,%0
2125 mtsar %r1
2126 {mfctl|mfctl,w} %%sar,%0
2127 fcpy,sgl %f1,%0
2128 fldw%F1 %1,%0
2129 fstw%F0 %1,%0
2130 {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2131 {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2132 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2133 (set_attr "pa_combine_type" "addmove")
2134 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2135
2136 (define_insn ""
2137 [(set (match_operand:SI 0 "move_dest_operand"
2138 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2139 (match_operand:SI 1 "move_src_operand"
2140 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2141 "(register_operand (operands[0], SImode)
2142 || reg_or_0_operand (operands[1], SImode))
2143 && !TARGET_SOFT_FLOAT
2144 && TARGET_64BIT"
2145 "@
2146 ldw RT'%A1,%0
2147 copy %1,%0
2148 ldi %1,%0
2149 ldil L'%1,%0
2150 {zdepi|depwi,z} %Z1,%0
2151 ldw%M1 %1,%0
2152 stw%M0 %r1,%0
2153 mtsar %r1
2154 {mfctl|mfctl,w} %%sar,%0
2155 fcpy,sgl %f1,%0
2156 fldw%F1 %1,%0
2157 fstw%F0 %1,%0"
2158 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2159 (set_attr "pa_combine_type" "addmove")
2160 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2161
2162 (define_insn ""
2163 [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2164 (match_operand:SI 1 "register_operand" "f"))]
2165 "!TARGET_SOFT_FLOAT
2166 && !TARGET_DISABLE_INDEXING
2167 && reload_completed"
2168 "fstw%F0 %1,%0"
2169 [(set_attr "type" "fpstore")
2170 (set_attr "pa_combine_type" "addmove")
2171 (set_attr "length" "4")])
2172
2173 ; Rewrite RTL using an indexed store. This will allow the insn that
2174 ; computes the address to be deleted if the register it sets is dead.
2175 (define_peephole2
2176 [(set (match_operand:SI 0 "register_operand" "")
2177 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2178 (const_int 4))
2179 (match_operand:SI 2 "register_operand" "")))
2180 (set (mem:SI (match_dup 0))
2181 (match_operand:SI 3 "register_operand" ""))]
2182 "!TARGET_SOFT_FLOAT
2183 && !TARGET_DISABLE_INDEXING
2184 && REG_OK_FOR_BASE_P (operands[2])
2185 && FP_REGNO_P (REGNO (operands[3]))"
2186 [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2187 (match_dup 3))
2188 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2189 (match_dup 2)))]
2190 "")
2191
2192 (define_peephole2
2193 [(set (match_operand:SI 0 "register_operand" "")
2194 (plus:SI (match_operand:SI 2 "register_operand" "")
2195 (mult:SI (match_operand:SI 1 "register_operand" "")
2196 (const_int 4))))
2197 (set (mem:SI (match_dup 0))
2198 (match_operand:SI 3 "register_operand" ""))]
2199 "!TARGET_SOFT_FLOAT
2200 && !TARGET_DISABLE_INDEXING
2201 && REG_OK_FOR_BASE_P (operands[2])
2202 && FP_REGNO_P (REGNO (operands[3]))"
2203 [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2204 (match_dup 3))
2205 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2206 (match_dup 2)))]
2207 "")
2208
2209 (define_peephole2
2210 [(set (match_operand:DI 0 "register_operand" "")
2211 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2212 (const_int 4))
2213 (match_operand:DI 2 "register_operand" "")))
2214 (set (mem:SI (match_dup 0))
2215 (match_operand:SI 3 "register_operand" ""))]
2216 "!TARGET_SOFT_FLOAT
2217 && !TARGET_DISABLE_INDEXING
2218 && TARGET_64BIT
2219 && REG_OK_FOR_BASE_P (operands[2])
2220 && FP_REGNO_P (REGNO (operands[3]))"
2221 [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2222 (match_dup 3))
2223 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2224 (match_dup 2)))]
2225 "")
2226
2227 (define_peephole2
2228 [(set (match_operand:DI 0 "register_operand" "")
2229 (plus:DI (match_operand:DI 2 "register_operand" "")
2230 (mult:DI (match_operand:DI 1 "register_operand" "")
2231 (const_int 4))))
2232 (set (mem:SI (match_dup 0))
2233 (match_operand:SI 3 "register_operand" ""))]
2234 "!TARGET_SOFT_FLOAT
2235 && !TARGET_DISABLE_INDEXING
2236 && TARGET_64BIT
2237 && REG_OK_FOR_BASE_P (operands[2])
2238 && FP_REGNO_P (REGNO (operands[3]))"
2239 [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2240 (match_dup 3))
2241 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2242 (match_dup 2)))]
2243 "")
2244
2245 (define_peephole2
2246 [(set (match_operand:SI 0 "register_operand" "")
2247 (plus:SI (match_operand:SI 1 "register_operand" "")
2248 (match_operand:SI 2 "register_operand" "")))
2249 (set (mem:SI (match_dup 0))
2250 (match_operand:SI 3 "register_operand" ""))]
2251 "!TARGET_SOFT_FLOAT
2252 && !TARGET_DISABLE_INDEXING
2253 && TARGET_NO_SPACE_REGS
2254 && REG_OK_FOR_INDEX_P (operands[1])
2255 && REG_OK_FOR_BASE_P (operands[2])
2256 && FP_REGNO_P (REGNO (operands[3]))"
2257 [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2258 (match_dup 3))
2259 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2260 "")
2261
2262 (define_peephole2
2263 [(set (match_operand:SI 0 "register_operand" "")
2264 (plus:SI (match_operand:SI 1 "register_operand" "")
2265 (match_operand:SI 2 "register_operand" "")))
2266 (set (mem:SI (match_dup 0))
2267 (match_operand:SI 3 "register_operand" ""))]
2268 "!TARGET_SOFT_FLOAT
2269 && !TARGET_DISABLE_INDEXING
2270 && TARGET_NO_SPACE_REGS
2271 && REG_OK_FOR_BASE_P (operands[1])
2272 && REG_OK_FOR_INDEX_P (operands[2])
2273 && FP_REGNO_P (REGNO (operands[3]))"
2274 [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2275 (match_dup 3))
2276 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2277 "")
2278
2279 (define_peephole2
2280 [(set (match_operand:DI 0 "register_operand" "")
2281 (plus:DI (match_operand:DI 1 "register_operand" "")
2282 (match_operand:DI 2 "register_operand" "")))
2283 (set (mem:SI (match_dup 0))
2284 (match_operand:SI 3 "register_operand" ""))]
2285 "!TARGET_SOFT_FLOAT
2286 && !TARGET_DISABLE_INDEXING
2287 && TARGET_64BIT
2288 && TARGET_NO_SPACE_REGS
2289 && REG_OK_FOR_INDEX_P (operands[1])
2290 && REG_OK_FOR_BASE_P (operands[2])
2291 && FP_REGNO_P (REGNO (operands[3]))"
2292 [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2293 (match_dup 3))
2294 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2295 "")
2296
2297 (define_peephole2
2298 [(set (match_operand:DI 0 "register_operand" "")
2299 (plus:DI (match_operand:DI 1 "register_operand" "")
2300 (match_operand:DI 2 "register_operand" "")))
2301 (set (mem:SI (match_dup 0))
2302 (match_operand:SI 3 "register_operand" ""))]
2303 "!TARGET_SOFT_FLOAT
2304 && !TARGET_DISABLE_INDEXING
2305 && TARGET_64BIT
2306 && TARGET_NO_SPACE_REGS
2307 && REG_OK_FOR_BASE_P (operands[1])
2308 && REG_OK_FOR_INDEX_P (operands[2])
2309 && FP_REGNO_P (REGNO (operands[3]))"
2310 [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2311 (match_dup 3))
2312 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2313 "")
2314
2315 (define_insn ""
2316 [(set (match_operand:SI 0 "move_dest_operand"
2317 "=r,r,r,r,r,r,Q,!*q,!r")
2318 (match_operand:SI 1 "move_src_operand"
2319 "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2320 "(register_operand (operands[0], SImode)
2321 || reg_or_0_operand (operands[1], SImode))
2322 && TARGET_SOFT_FLOAT"
2323 "@
2324 ldw RT'%A1,%0
2325 copy %1,%0
2326 ldi %1,%0
2327 ldil L'%1,%0
2328 {zdepi|depwi,z} %Z1,%0
2329 ldw%M1 %1,%0
2330 stw%M0 %r1,%0
2331 mtsar %r1
2332 {mfctl|mfctl,w} %%sar,%0"
2333 [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2334 (set_attr "pa_combine_type" "addmove")
2335 (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2336
2337 ;; Load or store with base-register modification.
2338 (define_insn ""
2339 [(set (match_operand:SI 0 "register_operand" "=r")
2340 (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2341 (match_operand:DI 2 "int5_operand" "L"))))
2342 (set (match_dup 1)
2343 (plus:DI (match_dup 1) (match_dup 2)))]
2344 "TARGET_64BIT"
2345 "ldw,mb %2(%1),%0"
2346 [(set_attr "type" "load")
2347 (set_attr "length" "4")])
2348
2349 ; And a zero extended variant.
2350 (define_insn ""
2351 [(set (match_operand:DI 0 "register_operand" "=r")
2352 (zero_extend:DI (mem:SI
2353 (plus:DI
2354 (match_operand:DI 1 "register_operand" "+r")
2355 (match_operand:DI 2 "int5_operand" "L")))))
2356 (set (match_dup 1)
2357 (plus:DI (match_dup 1) (match_dup 2)))]
2358 "TARGET_64BIT"
2359 "ldw,mb %2(%1),%0"
2360 [(set_attr "type" "load")
2361 (set_attr "length" "4")])
2362
2363 (define_expand "pre_load"
2364 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2365 (mem (plus (match_operand 1 "register_operand" "")
2366 (match_operand 2 "pre_cint_operand" ""))))
2367 (set (match_dup 1)
2368 (plus (match_dup 1) (match_dup 2)))])]
2369 ""
2370 "
2371 {
2372 if (TARGET_64BIT)
2373 {
2374 emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2375 DONE;
2376 }
2377 emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2378 DONE;
2379 }")
2380
2381 (define_insn "pre_ldw"
2382 [(set (match_operand:SI 0 "register_operand" "=r")
2383 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2384 (match_operand:SI 2 "pre_cint_operand" ""))))
2385 (set (match_dup 1)
2386 (plus:SI (match_dup 1) (match_dup 2)))]
2387 ""
2388 "*
2389 {
2390 if (INTVAL (operands[2]) < 0)
2391 return \"{ldwm|ldw,mb} %2(%1),%0\";
2392 return \"{ldws|ldw},mb %2(%1),%0\";
2393 }"
2394 [(set_attr "type" "load")
2395 (set_attr "length" "4")])
2396
2397 (define_insn "pre_ldd"
2398 [(set (match_operand:DI 0 "register_operand" "=r")
2399 (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2400 (match_operand:DI 2 "pre_cint_operand" ""))))
2401 (set (match_dup 1)
2402 (plus:DI (match_dup 1) (match_dup 2)))]
2403 "TARGET_64BIT"
2404 "ldd,mb %2(%1),%0"
2405 [(set_attr "type" "load")
2406 (set_attr "length" "4")])
2407
2408 (define_insn ""
2409 [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2410 (match_operand:SI 1 "pre_cint_operand" "")))
2411 (match_operand:SI 2 "reg_or_0_operand" "rM"))
2412 (set (match_dup 0)
2413 (plus:SI (match_dup 0) (match_dup 1)))]
2414 ""
2415 "*
2416 {
2417 if (INTVAL (operands[1]) < 0)
2418 return \"{stwm|stw,mb} %r2,%1(%0)\";
2419 return \"{stws|stw},mb %r2,%1(%0)\";
2420 }"
2421 [(set_attr "type" "store")
2422 (set_attr "length" "4")])
2423
2424 (define_insn ""
2425 [(set (match_operand:SI 0 "register_operand" "=r")
2426 (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2427 (set (match_dup 1)
2428 (plus:SI (match_dup 1)
2429 (match_operand:SI 2 "post_cint_operand" "")))]
2430 ""
2431 "*
2432 {
2433 if (INTVAL (operands[2]) > 0)
2434 return \"{ldwm|ldw,ma} %2(%1),%0\";
2435 return \"{ldws|ldw},ma %2(%1),%0\";
2436 }"
2437 [(set_attr "type" "load")
2438 (set_attr "length" "4")])
2439
2440 (define_expand "post_store"
2441 [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2442 (match_operand 1 "reg_or_0_operand" ""))
2443 (set (match_dup 0)
2444 (plus (match_dup 0)
2445 (match_operand 2 "post_cint_operand" "")))])]
2446 ""
2447 "
2448 {
2449 if (TARGET_64BIT)
2450 {
2451 emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2452 DONE;
2453 }
2454 emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2455 DONE;
2456 }")
2457
2458 (define_insn "post_stw"
2459 [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2460 (match_operand:SI 1 "reg_or_0_operand" "rM"))
2461 (set (match_dup 0)
2462 (plus:SI (match_dup 0)
2463 (match_operand:SI 2 "post_cint_operand" "")))]
2464 ""
2465 "*
2466 {
2467 if (INTVAL (operands[2]) > 0)
2468 return \"{stwm|stw,ma} %r1,%2(%0)\";
2469 return \"{stws|stw},ma %r1,%2(%0)\";
2470 }"
2471 [(set_attr "type" "store")
2472 (set_attr "length" "4")])
2473
2474 (define_insn "post_std"
2475 [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2476 (match_operand:DI 1 "reg_or_0_operand" "rM"))
2477 (set (match_dup 0)
2478 (plus:DI (match_dup 0)
2479 (match_operand:DI 2 "post_cint_operand" "")))]
2480 "TARGET_64BIT"
2481 "std,ma %r1,%2(%0)"
2482 [(set_attr "type" "store")
2483 (set_attr "length" "4")])
2484
2485 ;; For loading the address of a label while generating PIC code.
2486 ;; Note since this pattern can be created at reload time (via movsi), all
2487 ;; the same rules for movsi apply here. (no new pseudos, no temporaries).
2488 (define_insn ""
2489 [(set (match_operand 0 "pmode_register_operand" "=a")
2490 (match_operand 1 "pic_label_operand" ""))]
2491 "TARGET_PA_20"
2492 "*
2493 {
2494 rtx xoperands[3];
2495
2496 xoperands[0] = operands[0];
2497 xoperands[1] = operands[1];
2498 xoperands[2] = gen_label_rtx ();
2499
2500 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2501 CODE_LABEL_NUMBER (xoperands[2]));
2502 output_asm_insn (\"mfia %0\", xoperands);
2503
2504 /* If we're trying to load the address of a label that happens to be
2505 close, then we can use a shorter sequence. */
2506 if (GET_CODE (operands[1]) == LABEL_REF
2507 && !LABEL_REF_NONLOCAL_P (operands[1])
2508 && INSN_ADDRESSES_SET_P ()
2509 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2510 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2511 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2512 else
2513 {
2514 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2515 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2516 }
2517 return \"\";
2518 }"
2519 [(set_attr "type" "multi")
2520 (set_attr "length" "12")]) ; 8 or 12
2521
2522 (define_insn ""
2523 [(set (match_operand 0 "pmode_register_operand" "=a")
2524 (match_operand 1 "pic_label_operand" ""))]
2525 "!TARGET_PA_20"
2526 "*
2527 {
2528 rtx xoperands[3];
2529
2530 xoperands[0] = operands[0];
2531 xoperands[1] = operands[1];
2532 xoperands[2] = gen_label_rtx ();
2533
2534 output_asm_insn (\"bl .+8,%0\", xoperands);
2535 output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2536 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2537 CODE_LABEL_NUMBER (xoperands[2]));
2538
2539 /* If we're trying to load the address of a label that happens to be
2540 close, then we can use a shorter sequence. */
2541 if (GET_CODE (operands[1]) == LABEL_REF
2542 && !LABEL_REF_NONLOCAL_P (operands[1])
2543 && INSN_ADDRESSES_SET_P ()
2544 && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2545 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2546 output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2547 else
2548 {
2549 output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2550 output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2551 }
2552 return \"\";
2553 }"
2554 [(set_attr "type" "multi")
2555 (set_attr "length" "16")]) ; 12 or 16
2556
2557 (define_insn ""
2558 [(set (match_operand:SI 0 "register_operand" "=a")
2559 (plus:SI (match_operand:SI 1 "register_operand" "r")
2560 (high:SI (match_operand 2 "" ""))))]
2561 "symbolic_operand (operands[2], Pmode)
2562 && ! function_label_operand (operands[2], Pmode)
2563 && flag_pic"
2564 "addil LT'%G2,%1"
2565 [(set_attr "type" "binary")
2566 (set_attr "length" "4")])
2567
2568 (define_insn ""
2569 [(set (match_operand:DI 0 "register_operand" "=a")
2570 (plus:DI (match_operand:DI 1 "register_operand" "r")
2571 (high:DI (match_operand 2 "" ""))))]
2572 "symbolic_operand (operands[2], Pmode)
2573 && ! function_label_operand (operands[2], Pmode)
2574 && TARGET_64BIT
2575 && flag_pic"
2576 "addil LT'%G2,%1"
2577 [(set_attr "type" "binary")
2578 (set_attr "length" "4")])
2579
2580 ;; Always use addil rather than ldil;add sequences. This allows the
2581 ;; HP linker to eliminate the dp relocation if the symbolic operand
2582 ;; lives in the TEXT space.
2583 (define_insn ""
2584 [(set (match_operand:SI 0 "register_operand" "=a")
2585 (high:SI (match_operand 1 "" "")))]
2586 "symbolic_operand (operands[1], Pmode)
2587 && ! function_label_operand (operands[1], Pmode)
2588 && ! read_only_operand (operands[1], Pmode)
2589 && ! flag_pic"
2590 "*
2591 {
2592 if (TARGET_LONG_LOAD_STORE)
2593 return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2594 else
2595 return \"addil LR'%H1,%%r27\";
2596 }"
2597 [(set_attr "type" "binary")
2598 (set (attr "length")
2599 (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2600 (const_int 4)
2601 (const_int 8)))])
2602
2603
2604 ;; This is for use in the prologue/epilogue code. We need it
2605 ;; to add large constants to a stack pointer or frame pointer.
2606 ;; Because of the additional %r1 pressure, we probably do not
2607 ;; want to use this in general code, so make it available
2608 ;; only after reload.
2609 (define_insn ""
2610 [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2611 (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2612 (high:SI (match_operand 2 "const_int_operand" ""))))]
2613 "reload_completed"
2614 "@
2615 addil L'%G2,%1
2616 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2617 [(set_attr "type" "binary,binary")
2618 (set_attr "length" "4,8")])
2619
2620 (define_insn ""
2621 [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2622 (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2623 (high:DI (match_operand 2 "const_int_operand" ""))))]
2624 "reload_completed && TARGET_64BIT"
2625 "@
2626 addil L'%G2,%1
2627 ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2628 [(set_attr "type" "binary,binary")
2629 (set_attr "length" "4,8")])
2630
2631 (define_insn ""
2632 [(set (match_operand:SI 0 "register_operand" "=r")
2633 (high:SI (match_operand 1 "" "")))]
2634 "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2635 && !pa_is_function_label_plus_const (operands[1])"
2636 "*
2637 {
2638 if (symbolic_operand (operands[1], Pmode))
2639 return \"ldil LR'%H1,%0\";
2640 else
2641 return \"ldil L'%G1,%0\";
2642 }"
2643 [(set_attr "type" "move")
2644 (set_attr "length" "4")])
2645
2646 (define_insn ""
2647 [(set (match_operand:DI 0 "register_operand" "=r")
2648 (high:DI (match_operand 1 "const_int_operand" "")))]
2649 "TARGET_64BIT"
2650 "ldil L'%G1,%0";
2651 [(set_attr "type" "move")
2652 (set_attr "length" "4")])
2653
2654 (define_insn ""
2655 [(set (match_operand:DI 0 "register_operand" "=r")
2656 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2657 (match_operand:DI 2 "const_int_operand" "i")))]
2658 "TARGET_64BIT"
2659 "ldo R'%G2(%1),%0";
2660 [(set_attr "type" "move")
2661 (set_attr "length" "4")])
2662
2663 (define_insn ""
2664 [(set (match_operand:SI 0 "register_operand" "=r")
2665 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2666 (match_operand:SI 2 "immediate_operand" "i")))]
2667 "!pa_is_function_label_plus_const (operands[2])"
2668 "*
2669 {
2670 gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2671
2672 if (symbolic_operand (operands[2], Pmode))
2673 return \"ldo RR'%G2(%1),%0\";
2674 else
2675 return \"ldo R'%G2(%1),%0\";
2676 }"
2677 [(set_attr "type" "move")
2678 (set_attr "length" "4")])
2679
2680 ;; Now that a symbolic_address plus a constant is broken up early
2681 ;; in the compilation phase (for better CSE) we need a special
2682 ;; combiner pattern to load the symbolic address plus the constant
2683 ;; in only 2 instructions. (For cases where the symbolic address
2684 ;; was not a common subexpression.)
2685 (define_split
2686 [(set (match_operand:SI 0 "register_operand" "")
2687 (match_operand:SI 1 "symbolic_operand" ""))
2688 (clobber (match_operand:SI 2 "register_operand" ""))]
2689 "! (flag_pic && pic_label_operand (operands[1], SImode))"
2690 [(set (match_dup 2) (high:SI (match_dup 1)))
2691 (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2692 "")
2693
2694 ;; hppa_legitimize_address goes to a great deal of trouble to
2695 ;; create addresses which use indexing. In some cases, this
2696 ;; is a lose because there isn't any store instructions which
2697 ;; allow indexed addresses (with integer register source).
2698 ;;
2699 ;; These define_splits try to turn a 3 insn store into
2700 ;; a 2 insn store with some creative RTL rewriting.
2701 (define_split
2702 [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2703 (match_operand:SI 1 "shadd_operand" ""))
2704 (plus:SI (match_operand:SI 2 "register_operand" "")
2705 (match_operand:SI 3 "const_int_operand" ""))))
2706 (match_operand:SI 4 "register_operand" ""))
2707 (clobber (match_operand:SI 5 "register_operand" ""))]
2708 ""
2709 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2710 (match_dup 2)))
2711 (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2712 "")
2713
2714 (define_split
2715 [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2716 (match_operand:SI 1 "shadd_operand" ""))
2717 (plus:SI (match_operand:SI 2 "register_operand" "")
2718 (match_operand:SI 3 "const_int_operand" ""))))
2719 (match_operand:HI 4 "register_operand" ""))
2720 (clobber (match_operand:SI 5 "register_operand" ""))]
2721 ""
2722 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2723 (match_dup 2)))
2724 (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2725 "")
2726
2727 (define_split
2728 [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2729 (match_operand:SI 1 "shadd_operand" ""))
2730 (plus:SI (match_operand:SI 2 "register_operand" "")
2731 (match_operand:SI 3 "const_int_operand" ""))))
2732 (match_operand:QI 4 "register_operand" ""))
2733 (clobber (match_operand:SI 5 "register_operand" ""))]
2734 ""
2735 [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2736 (match_dup 2)))
2737 (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2738 "")
2739
2740 (define_expand "movhi"
2741 [(set (match_operand:HI 0 "general_operand" "")
2742 (match_operand:HI 1 "general_operand" ""))]
2743 ""
2744 "
2745 {
2746 if (pa_emit_move_sequence (operands, HImode, 0))
2747 DONE;
2748 }")
2749
2750 ;; Handle HImode input reloads requiring a general register as a
2751 ;; scratch register.
2752 (define_expand "reload_inhi"
2753 [(set (match_operand:HI 0 "register_operand" "=Z")
2754 (match_operand:HI 1 "non_hard_reg_operand" ""))
2755 (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2756 ""
2757 "
2758 {
2759 if (pa_emit_move_sequence (operands, HImode, operands[2]))
2760 DONE;
2761
2762 /* We don't want the clobber emitted, so handle this ourselves. */
2763 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2764 DONE;
2765 }")
2766
2767 ;; Handle HImode output reloads requiring a general register as a
2768 ;; scratch register.
2769 (define_expand "reload_outhi"
2770 [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2771 (match_operand:HI 1 "register_operand" "Z"))
2772 (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2773 ""
2774 "
2775 {
2776 if (pa_emit_move_sequence (operands, HImode, operands[2]))
2777 DONE;
2778
2779 /* We don't want the clobber emitted, so handle this ourselves. */
2780 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2781 DONE;
2782 }")
2783
2784 (define_insn ""
2785 [(set (match_operand:HI 0 "move_dest_operand"
2786 "=r,r,r,r,r,Q,!*q,!r")
2787 (match_operand:HI 1 "move_src_operand"
2788 "r,J,N,K,RQ,rM,!rM,!*q"))]
2789 "(register_operand (operands[0], HImode)
2790 || reg_or_0_operand (operands[1], HImode))"
2791 "@
2792 copy %1,%0
2793 ldi %1,%0
2794 ldil L'%1,%0
2795 {zdepi|depwi,z} %Z1,%0
2796 ldh%M1 %1,%0
2797 sth%M0 %r1,%0
2798 mtsar %r1
2799 {mfctl|mfctl,w} %sar,%0"
2800 [(set_attr "type" "move,move,move,shift,load,store,move,move")
2801 (set_attr "pa_combine_type" "addmove")
2802 (set_attr "length" "4,4,4,4,4,4,4,4")])
2803
2804 (define_insn ""
2805 [(set (match_operand:HI 0 "register_operand" "=r")
2806 (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2807 (match_operand:SI 2 "int5_operand" "L"))))
2808 (set (match_dup 1)
2809 (plus:SI (match_dup 1) (match_dup 2)))]
2810 ""
2811 "{ldhs|ldh},mb %2(%1),%0"
2812 [(set_attr "type" "load")
2813 (set_attr "length" "4")])
2814
2815 (define_insn ""
2816 [(set (match_operand:HI 0 "register_operand" "=r")
2817 (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2818 (match_operand:DI 2 "int5_operand" "L"))))
2819 (set (match_dup 1)
2820 (plus:DI (match_dup 1) (match_dup 2)))]
2821 "TARGET_64BIT"
2822 "ldh,mb %2(%1),%0"
2823 [(set_attr "type" "load")
2824 (set_attr "length" "4")])
2825
2826 ; And a zero extended variant.
2827 (define_insn ""
2828 [(set (match_operand:DI 0 "register_operand" "=r")
2829 (zero_extend:DI (mem:HI
2830 (plus:DI
2831 (match_operand:DI 1 "register_operand" "+r")
2832 (match_operand:DI 2 "int5_operand" "L")))))
2833 (set (match_dup 1)
2834 (plus:DI (match_dup 1) (match_dup 2)))]
2835 "TARGET_64BIT"
2836 "ldh,mb %2(%1),%0"
2837 [(set_attr "type" "load")
2838 (set_attr "length" "4")])
2839
2840 (define_insn ""
2841 [(set (match_operand:SI 0 "register_operand" "=r")
2842 (zero_extend:SI (mem:HI
2843 (plus:SI
2844 (match_operand:SI 1 "register_operand" "+r")
2845 (match_operand:SI 2 "int5_operand" "L")))))
2846 (set (match_dup 1)
2847 (plus:SI (match_dup 1) (match_dup 2)))]
2848 ""
2849 "{ldhs|ldh},mb %2(%1),%0"
2850 [(set_attr "type" "load")
2851 (set_attr "length" "4")])
2852
2853 (define_insn ""
2854 [(set (match_operand:SI 0 "register_operand" "=r")
2855 (zero_extend:SI (mem:HI
2856 (plus:DI
2857 (match_operand:DI 1 "register_operand" "+r")
2858 (match_operand:DI 2 "int5_operand" "L")))))
2859 (set (match_dup 1)
2860 (plus:DI (match_dup 1) (match_dup 2)))]
2861 "TARGET_64BIT"
2862 "ldh,mb %2(%1),%0"
2863 [(set_attr "type" "load")
2864 (set_attr "length" "4")])
2865
2866 (define_insn ""
2867 [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2868 (match_operand:SI 1 "int5_operand" "L")))
2869 (match_operand:HI 2 "reg_or_0_operand" "rM"))
2870 (set (match_dup 0)
2871 (plus:SI (match_dup 0) (match_dup 1)))]
2872 ""
2873 "{sths|sth},mb %r2,%1(%0)"
2874 [(set_attr "type" "store")
2875 (set_attr "length" "4")])
2876
2877 (define_insn ""
2878 [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
2879 (match_operand:DI 1 "int5_operand" "L")))
2880 (match_operand:HI 2 "reg_or_0_operand" "rM"))
2881 (set (match_dup 0)
2882 (plus:DI (match_dup 0) (match_dup 1)))]
2883 "TARGET_64BIT"
2884 "sth,mb %r2,%1(%0)"
2885 [(set_attr "type" "store")
2886 (set_attr "length" "4")])
2887
2888 (define_insn "addhi3"
2889 [(set (match_operand:HI 0 "register_operand" "=r,r")
2890 (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
2891 (match_operand:HI 2 "arith14_operand" "r,J")))]
2892 ""
2893 "@
2894 {addl|add,l} %1,%2,%0
2895 ldo %2(%1),%0"
2896 [(set_attr "type" "binary,binary")
2897 (set_attr "pa_combine_type" "addmove")
2898 (set_attr "length" "4,4")])
2899
2900 (define_expand "movqi"
2901 [(set (match_operand:QI 0 "general_operand" "")
2902 (match_operand:QI 1 "general_operand" ""))]
2903 ""
2904 "
2905 {
2906 if (pa_emit_move_sequence (operands, QImode, 0))
2907 DONE;
2908 }")
2909
2910 ;; Handle QImode input reloads requiring a general register as a
2911 ;; scratch register.
2912 (define_expand "reload_inqi"
2913 [(set (match_operand:QI 0 "register_operand" "=Z")
2914 (match_operand:QI 1 "non_hard_reg_operand" ""))
2915 (clobber (match_operand:QI 2 "register_operand" "=&r"))]
2916 ""
2917 "
2918 {
2919 if (pa_emit_move_sequence (operands, QImode, operands[2]))
2920 DONE;
2921
2922 /* We don't want the clobber emitted, so handle this ourselves. */
2923 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2924 DONE;
2925 }")
2926
2927 ;; Handle QImode output reloads requiring a general register as a
2928 ;; scratch register.
2929 (define_expand "reload_outqi"
2930 [(set (match_operand:QI 0 "non_hard_reg_operand" "")
2931 (match_operand:QI 1 "register_operand" "Z"))
2932 (clobber (match_operand:QI 2 "register_operand" "=&r"))]
2933 ""
2934 "
2935 {
2936 if (pa_emit_move_sequence (operands, QImode, operands[2]))
2937 DONE;
2938
2939 /* We don't want the clobber emitted, so handle this ourselves. */
2940 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2941 DONE;
2942 }")
2943
2944 (define_insn ""
2945 [(set (match_operand:QI 0 "move_dest_operand"
2946 "=r,r,r,r,r,Q,!*q,!r")
2947 (match_operand:QI 1 "move_src_operand"
2948 "r,J,N,K,RQ,rM,!rM,!*q"))]
2949 "(register_operand (operands[0], QImode)
2950 || reg_or_0_operand (operands[1], QImode))"
2951 "@
2952 copy %1,%0
2953 ldi %1,%0
2954 ldil L'%1,%0
2955 {zdepi|depwi,z} %Z1,%0
2956 ldb%M1 %1,%0
2957 stb%M0 %r1,%0
2958 mtsar %r1
2959 {mfctl|mfctl,w} %%sar,%0"
2960 [(set_attr "type" "move,move,move,shift,load,store,move,move")
2961 (set_attr "pa_combine_type" "addmove")
2962 (set_attr "length" "4,4,4,4,4,4,4,4")])
2963
2964 (define_insn ""
2965 [(set (match_operand:QI 0 "register_operand" "=r")
2966 (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2967 (match_operand:SI 2 "int5_operand" "L"))))
2968 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2969 ""
2970 "{ldbs|ldb},mb %2(%1),%0"
2971 [(set_attr "type" "load")
2972 (set_attr "length" "4")])
2973
2974 (define_insn ""
2975 [(set (match_operand:QI 0 "register_operand" "=r")
2976 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2977 (match_operand:DI 2 "int5_operand" "L"))))
2978 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
2979 "TARGET_64BIT"
2980 "ldb,mb %2(%1),%0"
2981 [(set_attr "type" "load")
2982 (set_attr "length" "4")])
2983
2984 ; Now the same thing with zero extensions.
2985 (define_insn ""
2986 [(set (match_operand:DI 0 "register_operand" "=r")
2987 (zero_extend:DI (mem:QI (plus:DI
2988 (match_operand:DI 1 "register_operand" "+r")
2989 (match_operand:DI 2 "int5_operand" "L")))))
2990 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
2991 "TARGET_64BIT"
2992 "ldb,mb %2(%1),%0"
2993 [(set_attr "type" "load")
2994 (set_attr "length" "4")])
2995
2996 (define_insn ""
2997 [(set (match_operand:SI 0 "register_operand" "=r")
2998 (zero_extend:SI (mem:QI (plus:SI
2999 (match_operand:SI 1 "register_operand" "+r")
3000 (match_operand:SI 2 "int5_operand" "L")))))
3001 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3002 ""
3003 "{ldbs|ldb},mb %2(%1),%0"
3004 [(set_attr "type" "load")
3005 (set_attr "length" "4")])
3006
3007 (define_insn ""
3008 [(set (match_operand:SI 0 "register_operand" "=r")
3009 (zero_extend:SI (mem:QI (plus:DI
3010 (match_operand:DI 1 "register_operand" "+r")
3011 (match_operand:DI 2 "int5_operand" "L")))))
3012 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3013 "TARGET_64BIT"
3014 "ldb,mb %2(%1),%0"
3015 [(set_attr "type" "load")
3016 (set_attr "length" "4")])
3017
3018 (define_insn ""
3019 [(set (match_operand:HI 0 "register_operand" "=r")
3020 (zero_extend:HI (mem:QI (plus:SI
3021 (match_operand:SI 1 "register_operand" "+r")
3022 (match_operand:SI 2 "int5_operand" "L")))))
3023 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3024 ""
3025 "{ldbs|ldb},mb %2(%1),%0"
3026 [(set_attr "type" "load")
3027 (set_attr "length" "4")])
3028
3029 (define_insn ""
3030 [(set (match_operand:HI 0 "register_operand" "=r")
3031 (zero_extend:HI (mem:QI (plus:DI
3032 (match_operand:DI 1 "register_operand" "+r")
3033 (match_operand:DI 2 "int5_operand" "L")))))
3034 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3035 "TARGET_64BIT"
3036 "ldb,mb %2(%1),%0"
3037 [(set_attr "type" "load")
3038 (set_attr "length" "4")])
3039
3040 (define_insn ""
3041 [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3042 (match_operand:SI 1 "int5_operand" "L")))
3043 (match_operand:QI 2 "reg_or_0_operand" "rM"))
3044 (set (match_dup 0)
3045 (plus:SI (match_dup 0) (match_dup 1)))]
3046 ""
3047 "{stbs|stb},mb %r2,%1(%0)"
3048 [(set_attr "type" "store")
3049 (set_attr "length" "4")])
3050
3051 (define_insn ""
3052 [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3053 (match_operand:DI 1 "int5_operand" "L")))
3054 (match_operand:QI 2 "reg_or_0_operand" "rM"))
3055 (set (match_dup 0)
3056 (plus:DI (match_dup 0) (match_dup 1)))]
3057 "TARGET_64BIT"
3058 "stb,mb %r2,%1(%0)"
3059 [(set_attr "type" "store")
3060 (set_attr "length" "4")])
3061
3062 ;; The definition of this insn does not really explain what it does,
3063 ;; but it should suffice that anything generated as this insn will be
3064 ;; recognized as a movmemsi operation, and that it will not successfully
3065 ;; combine with anything.
3066 (define_expand "movmemsi"
3067 [(parallel [(set (match_operand:BLK 0 "" "")
3068 (match_operand:BLK 1 "" ""))
3069 (clobber (match_dup 4))
3070 (clobber (match_dup 5))
3071 (clobber (match_dup 6))
3072 (clobber (match_dup 7))
3073 (clobber (match_dup 8))
3074 (use (match_operand:SI 2 "arith14_operand" ""))
3075 (use (match_operand:SI 3 "const_int_operand" ""))])]
3076 "!TARGET_64BIT && optimize > 0"
3077 "
3078 {
3079 int size, align;
3080
3081 /* HP provides very fast block move library routine for the PA;
3082 this routine includes:
3083
3084 4x4 byte at a time block moves,
3085 1x4 byte at a time with alignment checked at runtime with
3086 attempts to align the source and destination as needed
3087 1x1 byte loop
3088
3089 With that in mind, here's the heuristics to try and guess when
3090 the inlined block move will be better than the library block
3091 move:
3092
3093 If the size isn't constant, then always use the library routines.
3094
3095 If the size is large in respect to the known alignment, then use
3096 the library routines.
3097
3098 If the size is small in respect to the known alignment, then open
3099 code the copy (since that will lead to better scheduling).
3100
3101 Else use the block move pattern. */
3102
3103 /* Undetermined size, use the library routine. */
3104 if (GET_CODE (operands[2]) != CONST_INT)
3105 FAIL;
3106
3107 size = INTVAL (operands[2]);
3108 align = INTVAL (operands[3]);
3109 align = align > 4 ? 4 : (align ? align : 1);
3110
3111 /* If size/alignment is large, then use the library routines. */
3112 if (size / align > 16)
3113 FAIL;
3114
3115 /* This does happen, but not often enough to worry much about. */
3116 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3117 FAIL;
3118
3119 /* Fall through means we're going to use our block move pattern. */
3120 operands[0]
3121 = replace_equiv_address (operands[0],
3122 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3123 operands[1]
3124 = replace_equiv_address (operands[1],
3125 copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3126 operands[4] = gen_reg_rtx (SImode);
3127 operands[5] = gen_reg_rtx (SImode);
3128 operands[6] = gen_reg_rtx (SImode);
3129 operands[7] = gen_reg_rtx (SImode);
3130 operands[8] = gen_reg_rtx (SImode);
3131 }")
3132
3133 ;; The operand constraints are written like this to support both compile-time
3134 ;; and run-time determined byte counts. The expander and pa_output_block_move
3135 ;; only support compile-time determined counts at this time.
3136 ;;
3137 ;; If the count is run-time determined, the register with the byte count
3138 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3139 ;;
3140 ;; We used to clobber operands 0 and 1. However, a change to regrename.c
3141 ;; broke this semantic for pseudo registers. We can't use match_scratch
3142 ;; as this requires two registers in the class R1_REGS when the MEMs for
3143 ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
3144 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3145 ;; respectively. We then split or peephole optimize after reload.
3146 (define_insn "movmemsi_prereload"
3147 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3148 (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3149 (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3150 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
3151 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
3152 (clobber (match_operand:SI 7 "register_operand" "=&r,&r")) ;item tmp3
3153 (clobber (match_operand:SI 8 "register_operand" "=&r,&r")) ;item tmp4
3154 (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count
3155 (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3156 "!TARGET_64BIT"
3157 "#"
3158 [(set_attr "type" "multi,multi")])
3159
3160 (define_split
3161 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3162 (match_operand:BLK 1 "memory_operand" ""))
3163 (clobber (match_operand:SI 2 "register_operand" ""))
3164 (clobber (match_operand:SI 3 "register_operand" ""))
3165 (clobber (match_operand:SI 6 "register_operand" ""))
3166 (clobber (match_operand:SI 7 "register_operand" ""))
3167 (clobber (match_operand:SI 8 "register_operand" ""))
3168 (use (match_operand:SI 4 "arith14_operand" ""))
3169 (use (match_operand:SI 5 "const_int_operand" ""))])]
3170 "!TARGET_64BIT && reload_completed && !flag_peephole2
3171 && GET_CODE (operands[0]) == MEM
3172 && register_operand (XEXP (operands[0], 0), SImode)
3173 && GET_CODE (operands[1]) == MEM
3174 && register_operand (XEXP (operands[1], 0), SImode)"
3175 [(set (match_dup 7) (match_dup 9))
3176 (set (match_dup 8) (match_dup 10))
3177 (parallel [(set (match_dup 0) (match_dup 1))
3178 (clobber (match_dup 2))
3179 (clobber (match_dup 3))
3180 (clobber (match_dup 6))
3181 (clobber (match_dup 7))
3182 (clobber (match_dup 8))
3183 (use (match_dup 4))
3184 (use (match_dup 5))
3185 (const_int 0)])]
3186 "
3187 {
3188 operands[9] = XEXP (operands[0], 0);
3189 operands[10] = XEXP (operands[1], 0);
3190 operands[0] = replace_equiv_address (operands[0], operands[7]);
3191 operands[1] = replace_equiv_address (operands[1], operands[8]);
3192 }")
3193
3194 (define_peephole2
3195 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3196 (match_operand:BLK 1 "memory_operand" ""))
3197 (clobber (match_operand:SI 2 "register_operand" ""))
3198 (clobber (match_operand:SI 3 "register_operand" ""))
3199 (clobber (match_operand:SI 6 "register_operand" ""))
3200 (clobber (match_operand:SI 7 "register_operand" ""))
3201 (clobber (match_operand:SI 8 "register_operand" ""))
3202 (use (match_operand:SI 4 "arith14_operand" ""))
3203 (use (match_operand:SI 5 "const_int_operand" ""))])]
3204 "!TARGET_64BIT
3205 && GET_CODE (operands[0]) == MEM
3206 && register_operand (XEXP (operands[0], 0), SImode)
3207 && GET_CODE (operands[1]) == MEM
3208 && register_operand (XEXP (operands[1], 0), SImode)"
3209 [(parallel [(set (match_dup 0) (match_dup 1))
3210 (clobber (match_dup 2))
3211 (clobber (match_dup 3))
3212 (clobber (match_dup 6))
3213 (clobber (match_dup 7))
3214 (clobber (match_dup 8))
3215 (use (match_dup 4))
3216 (use (match_dup 5))
3217 (const_int 0)])]
3218 "
3219 {
3220 rtx addr = XEXP (operands[0], 0);
3221 if (dead_or_set_p (curr_insn, addr))
3222 operands[7] = addr;
3223 else
3224 {
3225 emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3226 operands[0] = replace_equiv_address (operands[0], operands[7]);
3227 }
3228
3229 addr = XEXP (operands[1], 0);
3230 if (dead_or_set_p (curr_insn, addr))
3231 operands[8] = addr;
3232 else
3233 {
3234 emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3235 operands[1] = replace_equiv_address (operands[1], operands[8]);
3236 }
3237 }")
3238
3239 (define_insn "movmemsi_postreload"
3240 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3241 (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3242 (clobber (match_operand:SI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3243 (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp1
3244 (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
3245 (clobber (match_dup 0))
3246 (clobber (match_dup 1))
3247 (use (match_operand:SI 4 "arith14_operand" "J,2")) ;byte count
3248 (use (match_operand:SI 5 "const_int_operand" "n,n")) ;alignment
3249 (const_int 0)]
3250 "!TARGET_64BIT && reload_completed"
3251 "* return pa_output_block_move (operands, !which_alternative);"
3252 [(set_attr "type" "multi,multi")])
3253
3254 (define_expand "movmemdi"
3255 [(parallel [(set (match_operand:BLK 0 "" "")
3256 (match_operand:BLK 1 "" ""))
3257 (clobber (match_dup 4))
3258 (clobber (match_dup 5))
3259 (clobber (match_dup 6))
3260 (clobber (match_dup 7))
3261 (clobber (match_dup 8))
3262 (use (match_operand:DI 2 "arith14_operand" ""))
3263 (use (match_operand:DI 3 "const_int_operand" ""))])]
3264 "TARGET_64BIT && optimize > 0"
3265 "
3266 {
3267 int size, align;
3268
3269 /* HP provides very fast block move library routine for the PA;
3270 this routine includes:
3271
3272 4x4 byte at a time block moves,
3273 1x4 byte at a time with alignment checked at runtime with
3274 attempts to align the source and destination as needed
3275 1x1 byte loop
3276
3277 With that in mind, here's the heuristics to try and guess when
3278 the inlined block move will be better than the library block
3279 move:
3280
3281 If the size isn't constant, then always use the library routines.
3282
3283 If the size is large in respect to the known alignment, then use
3284 the library routines.
3285
3286 If the size is small in respect to the known alignment, then open
3287 code the copy (since that will lead to better scheduling).
3288
3289 Else use the block move pattern. */
3290
3291 /* Undetermined size, use the library routine. */
3292 if (GET_CODE (operands[2]) != CONST_INT)
3293 FAIL;
3294
3295 size = INTVAL (operands[2]);
3296 align = INTVAL (operands[3]);
3297 align = align > 8 ? 8 : (align ? align : 1);
3298
3299 /* If size/alignment is large, then use the library routines. */
3300 if (size / align > 16)
3301 FAIL;
3302
3303 /* This does happen, but not often enough to worry much about. */
3304 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3305 FAIL;
3306
3307 /* Fall through means we're going to use our block move pattern. */
3308 operands[0]
3309 = replace_equiv_address (operands[0],
3310 copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3311 operands[1]
3312 = replace_equiv_address (operands[1],
3313 copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3314 operands[4] = gen_reg_rtx (DImode);
3315 operands[5] = gen_reg_rtx (DImode);
3316 operands[6] = gen_reg_rtx (DImode);
3317 operands[7] = gen_reg_rtx (DImode);
3318 operands[8] = gen_reg_rtx (DImode);
3319 }")
3320
3321 ;; The operand constraints are written like this to support both compile-time
3322 ;; and run-time determined byte counts. The expander and pa_output_block_move
3323 ;; only support compile-time determined counts at this time.
3324 ;;
3325 ;; If the count is run-time determined, the register with the byte count
3326 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3327 ;;
3328 ;; We used to clobber operands 0 and 1. However, a change to regrename.c
3329 ;; broke this semantic for pseudo registers. We can't use match_scratch
3330 ;; as this requires two registers in the class R1_REGS when the MEMs for
3331 ;; operands 0 and 1 are both equivalent to symbolic MEMs. Thus, we are
3332 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3333 ;; respectively. We then split or peephole optimize after reload.
3334 (define_insn "movmemdi_prereload"
3335 [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3336 (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3337 (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3338 (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
3339 (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
3340 (clobber (match_operand:DI 7 "register_operand" "=&r,&r")) ;item tmp3
3341 (clobber (match_operand:DI 8 "register_operand" "=&r,&r")) ;item tmp4
3342 (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count
3343 (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3344 "TARGET_64BIT"
3345 "#"
3346 [(set_attr "type" "multi,multi")])
3347
3348 (define_split
3349 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3350 (match_operand:BLK 1 "memory_operand" ""))
3351 (clobber (match_operand:DI 2 "register_operand" ""))
3352 (clobber (match_operand:DI 3 "register_operand" ""))
3353 (clobber (match_operand:DI 6 "register_operand" ""))
3354 (clobber (match_operand:DI 7 "register_operand" ""))
3355 (clobber (match_operand:DI 8 "register_operand" ""))
3356 (use (match_operand:DI 4 "arith14_operand" ""))
3357 (use (match_operand:DI 5 "const_int_operand" ""))])]
3358 "TARGET_64BIT && reload_completed && !flag_peephole2
3359 && GET_CODE (operands[0]) == MEM
3360 && register_operand (XEXP (operands[0], 0), DImode)
3361 && GET_CODE (operands[1]) == MEM
3362 && register_operand (XEXP (operands[1], 0), DImode)"
3363 [(set (match_dup 7) (match_dup 9))
3364 (set (match_dup 8) (match_dup 10))
3365 (parallel [(set (match_dup 0) (match_dup 1))
3366 (clobber (match_dup 2))
3367 (clobber (match_dup 3))
3368 (clobber (match_dup 6))
3369 (clobber (match_dup 7))
3370 (clobber (match_dup 8))
3371 (use (match_dup 4))
3372 (use (match_dup 5))
3373 (const_int 0)])]
3374 "
3375 {
3376 operands[9] = XEXP (operands[0], 0);
3377 operands[10] = XEXP (operands[1], 0);
3378 operands[0] = replace_equiv_address (operands[0], operands[7]);
3379 operands[1] = replace_equiv_address (operands[1], operands[8]);
3380 }")
3381
3382 (define_peephole2
3383 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3384 (match_operand:BLK 1 "memory_operand" ""))
3385 (clobber (match_operand:DI 2 "register_operand" ""))
3386 (clobber (match_operand:DI 3 "register_operand" ""))
3387 (clobber (match_operand:DI 6 "register_operand" ""))
3388 (clobber (match_operand:DI 7 "register_operand" ""))
3389 (clobber (match_operand:DI 8 "register_operand" ""))
3390 (use (match_operand:DI 4 "arith14_operand" ""))
3391 (use (match_operand:DI 5 "const_int_operand" ""))])]
3392 "TARGET_64BIT
3393 && GET_CODE (operands[0]) == MEM
3394 && register_operand (XEXP (operands[0], 0), DImode)
3395 && GET_CODE (operands[1]) == MEM
3396 && register_operand (XEXP (operands[1], 0), DImode)"
3397 [(parallel [(set (match_dup 0) (match_dup 1))
3398 (clobber (match_dup 2))
3399 (clobber (match_dup 3))
3400 (clobber (match_dup 6))
3401 (clobber (match_dup 7))
3402 (clobber (match_dup 8))
3403 (use (match_dup 4))
3404 (use (match_dup 5))
3405 (const_int 0)])]
3406 "
3407 {
3408 rtx addr = XEXP (operands[0], 0);
3409 if (dead_or_set_p (curr_insn, addr))
3410 operands[7] = addr;
3411 else
3412 {
3413 emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3414 operands[0] = replace_equiv_address (operands[0], operands[7]);
3415 }
3416
3417 addr = XEXP (operands[1], 0);
3418 if (dead_or_set_p (curr_insn, addr))
3419 operands[8] = addr;
3420 else
3421 {
3422 emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3423 operands[1] = replace_equiv_address (operands[1], operands[8]);
3424 }
3425 }")
3426
3427 (define_insn "movmemdi_postreload"
3428 [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3429 (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3430 (clobber (match_operand:DI 2 "register_operand" "=&r,&r")) ;loop cnt/tmp
3431 (clobber (match_operand:DI 3 "register_operand" "=&r,&r")) ;item tmp1
3432 (clobber (match_operand:DI 6 "register_operand" "=&r,&r")) ;item tmp2
3433 (clobber (match_dup 0))
3434 (clobber (match_dup 1))
3435 (use (match_operand:DI 4 "arith14_operand" "J,2")) ;byte count
3436 (use (match_operand:DI 5 "const_int_operand" "n,n")) ;alignment
3437 (const_int 0)]
3438 "TARGET_64BIT && reload_completed"
3439 "* return pa_output_block_move (operands, !which_alternative);"
3440 [(set_attr "type" "multi,multi")])
3441
3442 (define_expand "setmemsi"
3443 [(parallel [(set (match_operand:BLK 0 "" "")
3444 (match_operand 2 "const_int_operand" ""))
3445 (clobber (match_dup 4))
3446 (clobber (match_dup 5))
3447 (use (match_operand:SI 1 "arith14_operand" ""))
3448 (use (match_operand:SI 3 "const_int_operand" ""))])]
3449 "!TARGET_64BIT && optimize > 0"
3450 "
3451 {
3452 int size, align;
3453
3454 /* If value to set is not zero, use the library routine. */
3455 if (operands[2] != const0_rtx)
3456 FAIL;
3457
3458 /* Undetermined size, use the library routine. */
3459 if (GET_CODE (operands[1]) != CONST_INT)
3460 FAIL;
3461
3462 size = INTVAL (operands[1]);
3463 align = INTVAL (operands[3]);
3464 align = align > 4 ? 4 : align;
3465
3466 /* If size/alignment is large, then use the library routines. */
3467 if (size / align > 16)
3468 FAIL;
3469
3470 /* This does happen, but not often enough to worry much about. */
3471 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3472 FAIL;
3473
3474 /* Fall through means we're going to use our block clear pattern. */
3475 operands[0]
3476 = replace_equiv_address (operands[0],
3477 copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3478 operands[4] = gen_reg_rtx (SImode);
3479 operands[5] = gen_reg_rtx (SImode);
3480 }")
3481
3482 (define_insn "clrmemsi_prereload"
3483 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3484 (const_int 0))
3485 (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3486 (clobber (match_operand:SI 4 "register_operand" "=&r,&r")) ;tmp1
3487 (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count
3488 (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3489 "!TARGET_64BIT"
3490 "#"
3491 [(set_attr "type" "multi,multi")])
3492
3493 (define_split
3494 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3495 (const_int 0))
3496 (clobber (match_operand:SI 1 "register_operand" ""))
3497 (clobber (match_operand:SI 4 "register_operand" ""))
3498 (use (match_operand:SI 2 "arith14_operand" ""))
3499 (use (match_operand:SI 3 "const_int_operand" ""))])]
3500 "!TARGET_64BIT && reload_completed && !flag_peephole2
3501 && GET_CODE (operands[0]) == MEM
3502 && register_operand (XEXP (operands[0], 0), SImode)"
3503 [(set (match_dup 4) (match_dup 5))
3504 (parallel [(set (match_dup 0) (const_int 0))
3505 (clobber (match_dup 1))
3506 (clobber (match_dup 4))
3507 (use (match_dup 2))
3508 (use (match_dup 3))
3509 (const_int 0)])]
3510 "
3511 {
3512 operands[5] = XEXP (operands[0], 0);
3513 operands[0] = replace_equiv_address (operands[0], operands[4]);
3514 }")
3515
3516 (define_peephole2
3517 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3518 (const_int 0))
3519 (clobber (match_operand:SI 1 "register_operand" ""))
3520 (clobber (match_operand:SI 4 "register_operand" ""))
3521 (use (match_operand:SI 2 "arith14_operand" ""))
3522 (use (match_operand:SI 3 "const_int_operand" ""))])]
3523 "!TARGET_64BIT
3524 && GET_CODE (operands[0]) == MEM
3525 && register_operand (XEXP (operands[0], 0), SImode)"
3526 [(parallel [(set (match_dup 0) (const_int 0))
3527 (clobber (match_dup 1))
3528 (clobber (match_dup 4))
3529 (use (match_dup 2))
3530 (use (match_dup 3))
3531 (const_int 0)])]
3532 "
3533 {
3534 rtx addr = XEXP (operands[0], 0);
3535 if (dead_or_set_p (curr_insn, addr))
3536 operands[4] = addr;
3537 else
3538 {
3539 emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3540 operands[0] = replace_equiv_address (operands[0], operands[4]);
3541 }
3542 }")
3543
3544 (define_insn "clrmemsi_postreload"
3545 [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3546 (const_int 0))
3547 (clobber (match_operand:SI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3548 (clobber (match_dup 0))
3549 (use (match_operand:SI 2 "arith14_operand" "J,1")) ;byte count
3550 (use (match_operand:SI 3 "const_int_operand" "n,n")) ;alignment
3551 (const_int 0)]
3552 "!TARGET_64BIT && reload_completed"
3553 "* return pa_output_block_clear (operands, !which_alternative);"
3554 [(set_attr "type" "multi,multi")])
3555
3556 (define_expand "setmemdi"
3557 [(parallel [(set (match_operand:BLK 0 "" "")
3558 (match_operand 2 "const_int_operand" ""))
3559 (clobber (match_dup 4))
3560 (clobber (match_dup 5))
3561 (use (match_operand:DI 1 "arith14_operand" ""))
3562 (use (match_operand:DI 3 "const_int_operand" ""))])]
3563 "TARGET_64BIT && optimize > 0"
3564 "
3565 {
3566 int size, align;
3567
3568 /* If value to set is not zero, use the library routine. */
3569 if (operands[2] != const0_rtx)
3570 FAIL;
3571
3572 /* Undetermined size, use the library routine. */
3573 if (GET_CODE (operands[1]) != CONST_INT)
3574 FAIL;
3575
3576 size = INTVAL (operands[1]);
3577 align = INTVAL (operands[3]);
3578 align = align > 8 ? 8 : align;
3579
3580 /* If size/alignment is large, then use the library routines. */
3581 if (size / align > 16)
3582 FAIL;
3583
3584 /* This does happen, but not often enough to worry much about. */
3585 if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3586 FAIL;
3587
3588 /* Fall through means we're going to use our block clear pattern. */
3589 operands[0]
3590 = replace_equiv_address (operands[0],
3591 copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3592 operands[4] = gen_reg_rtx (DImode);
3593 operands[5] = gen_reg_rtx (DImode);
3594 }")
3595
3596 (define_insn "clrmemdi_prereload"
3597 [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3598 (const_int 0))
3599 (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3600 (clobber (match_operand:DI 4 "register_operand" "=&r,&r")) ;item tmp1
3601 (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count
3602 (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3603 "TARGET_64BIT"
3604 "#"
3605 [(set_attr "type" "multi,multi")])
3606
3607 (define_split
3608 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3609 (const_int 0))
3610 (clobber (match_operand:DI 1 "register_operand" ""))
3611 (clobber (match_operand:DI 4 "register_operand" ""))
3612 (use (match_operand:DI 2 "arith14_operand" ""))
3613 (use (match_operand:DI 3 "const_int_operand" ""))])]
3614 "TARGET_64BIT && reload_completed && !flag_peephole2
3615 && GET_CODE (operands[0]) == MEM
3616 && register_operand (XEXP (operands[0], 0), DImode)"
3617 [(set (match_dup 4) (match_dup 5))
3618 (parallel [(set (match_dup 0) (const_int 0))
3619 (clobber (match_dup 1))
3620 (clobber (match_dup 4))
3621 (use (match_dup 2))
3622 (use (match_dup 3))
3623 (const_int 0)])]
3624 "
3625 {
3626 operands[5] = XEXP (operands[0], 0);
3627 operands[0] = replace_equiv_address (operands[0], operands[4]);
3628 }")
3629
3630 (define_peephole2
3631 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3632 (const_int 0))
3633 (clobber (match_operand:DI 1 "register_operand" ""))
3634 (clobber (match_operand:DI 4 "register_operand" ""))
3635 (use (match_operand:DI 2 "arith14_operand" ""))
3636 (use (match_operand:DI 3 "const_int_operand" ""))])]
3637 "TARGET_64BIT
3638 && GET_CODE (operands[0]) == MEM
3639 && register_operand (XEXP (operands[0], 0), DImode)"
3640 [(parallel [(set (match_dup 0) (const_int 0))
3641 (clobber (match_dup 1))
3642 (clobber (match_dup 4))
3643 (use (match_dup 2))
3644 (use (match_dup 3))
3645 (const_int 0)])]
3646 "
3647 {
3648 rtx addr = XEXP (operands[0], 0);
3649 if (dead_or_set_p (curr_insn, addr))
3650 operands[4] = addr;
3651 else
3652 {
3653 emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3654 operands[0] = replace_equiv_address (operands[0], operands[4]);
3655 }
3656 }")
3657
3658 (define_insn "clrmemdi_postreload"
3659 [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3660 (const_int 0))
3661 (clobber (match_operand:DI 1 "register_operand" "=&r,&r")) ;loop cnt/tmp
3662 (clobber (match_dup 0))
3663 (use (match_operand:DI 2 "arith14_operand" "J,1")) ;byte count
3664 (use (match_operand:DI 3 "const_int_operand" "n,n")) ;alignment
3665 (const_int 0)]
3666 "TARGET_64BIT && reload_completed"
3667 "* return pa_output_block_clear (operands, !which_alternative);"
3668 [(set_attr "type" "multi,multi")])
3669 \f
3670 ;; Floating point move insns
3671
3672 ;; This pattern forces (set (reg:DF ...) (const_double ...))
3673 ;; to be reloaded by putting the constant into memory when
3674 ;; reg is a floating point register.
3675 ;;
3676 ;; For integer registers we use ldil;ldo to set the appropriate
3677 ;; value.
3678 ;;
3679 ;; This must come before the movdf pattern, and it must be present
3680 ;; to handle obscure reloading cases.
3681 (define_insn ""
3682 [(set (match_operand:DF 0 "register_operand" "=?r,f")
3683 (match_operand:DF 1 "" "?F,m"))]
3684 "GET_CODE (operands[1]) == CONST_DOUBLE
3685 && operands[1] != CONST0_RTX (DFmode)
3686 && !TARGET_64BIT
3687 && !TARGET_SOFT_FLOAT"
3688 "* return (which_alternative == 0 ? pa_output_move_double (operands)
3689 : \"fldd%F1 %1,%0\");"
3690 [(set_attr "type" "move,fpload")
3691 (set_attr "length" "16,4")])
3692
3693 (define_expand "movdf"
3694 [(set (match_operand:DF 0 "general_operand" "")
3695 (match_operand:DF 1 "general_operand" ""))]
3696 ""
3697 "
3698 {
3699 if (GET_CODE (operands[1]) == CONST_DOUBLE
3700 && operands[1] != CONST0_RTX (DFmode))
3701 {
3702 /* Reject CONST_DOUBLE loads to all hard registers when
3703 generating 64-bit code and to floating point registers
3704 when generating 32-bit code. */
3705 if (REG_P (operands[0])
3706 && HARD_REGISTER_P (operands[0])
3707 && (TARGET_64BIT || REGNO (operands[0]) >= 32))
3708 FAIL;
3709
3710 if (TARGET_64BIT)
3711 operands[1] = force_const_mem (DFmode, operands[1]);
3712 }
3713
3714 if (pa_emit_move_sequence (operands, DFmode, 0))
3715 DONE;
3716 }")
3717
3718 ;; Handle DFmode input reloads requiring a general register as a
3719 ;; scratch register.
3720 (define_expand "reload_indf"
3721 [(set (match_operand:DF 0 "register_operand" "=Z")
3722 (match_operand:DF 1 "non_hard_reg_operand" ""))
3723 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3724 ""
3725 "
3726 {
3727 if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3728 DONE;
3729
3730 /* We don't want the clobber emitted, so handle this ourselves. */
3731 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3732 DONE;
3733 }")
3734
3735 ;; Handle DFmode output reloads requiring a general register as a
3736 ;; scratch register.
3737 (define_expand "reload_outdf"
3738 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3739 (match_operand:DF 1 "register_operand" "Z"))
3740 (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3741 ""
3742 "
3743 {
3744 if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3745 DONE;
3746
3747 /* We don't want the clobber emitted, so handle this ourselves. */
3748 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3749 DONE;
3750 }")
3751
3752 (define_insn ""
3753 [(set (match_operand:DF 0 "move_dest_operand"
3754 "=f,*r,Q,?o,?Q,f,*r,*r,?*r,?f")
3755 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3756 "fG,*rG,f,*r,*r,RQ,o,RQ,f,*r"))]
3757 "(register_operand (operands[0], DFmode)
3758 || reg_or_0_operand (operands[1], DFmode))
3759 && !(GET_CODE (operands[1]) == CONST_DOUBLE
3760 && GET_CODE (operands[0]) == MEM)
3761 && !TARGET_64BIT
3762 && !TARGET_SOFT_FLOAT"
3763 "*
3764 {
3765 if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3766 || operands[1] == CONST0_RTX (DFmode))
3767 && !(REG_P (operands[0]) && REG_P (operands[1])
3768 && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3769 return pa_output_fp_move_double (operands);
3770 return pa_output_move_double (operands);
3771 }"
3772 [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3773 (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3774
3775 (define_insn ""
3776 [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3777 (match_operand:DF 1 "reg_or_0_operand" "f"))]
3778 "!TARGET_SOFT_FLOAT
3779 && !TARGET_DISABLE_INDEXING
3780 && reload_completed"
3781 "fstd%F0 %1,%0"
3782 [(set_attr "type" "fpstore")
3783 (set_attr "pa_combine_type" "addmove")
3784 (set_attr "length" "4")])
3785
3786 (define_peephole2
3787 [(set (match_operand:SI 0 "register_operand" "")
3788 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3789 (const_int 8))
3790 (match_operand:SI 2 "register_operand" "")))
3791 (set (mem:DF (match_dup 0))
3792 (match_operand:DF 3 "register_operand" ""))]
3793 "!TARGET_SOFT_FLOAT
3794 && !TARGET_DISABLE_INDEXING
3795 && REG_OK_FOR_BASE_P (operands[2])
3796 && FP_REGNO_P (REGNO (operands[3]))"
3797 [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3798 (match_dup 3))
3799 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3800 (match_dup 2)))]
3801 "")
3802
3803 (define_peephole2
3804 [(set (match_operand:SI 0 "register_operand" "")
3805 (plus:SI (match_operand:SI 2 "register_operand" "")
3806 (mult:SI (match_operand:SI 1 "register_operand" "")
3807 (const_int 8))))
3808 (set (mem:DF (match_dup 0))
3809 (match_operand:DF 3 "register_operand" ""))]
3810 "!TARGET_SOFT_FLOAT
3811 && !TARGET_DISABLE_INDEXING
3812 && REG_OK_FOR_BASE_P (operands[2])
3813 && FP_REGNO_P (REGNO (operands[3]))"
3814 [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3815 (match_dup 3))
3816 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3817 (match_dup 2)))]
3818 "")
3819
3820 (define_peephole2
3821 [(set (match_operand:DI 0 "register_operand" "")
3822 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
3823 (const_int 8))
3824 (match_operand:DI 2 "register_operand" "")))
3825 (set (mem:DF (match_dup 0))
3826 (match_operand:DF 3 "register_operand" ""))]
3827 "!TARGET_SOFT_FLOAT
3828 && !TARGET_DISABLE_INDEXING
3829 && TARGET_64BIT
3830 && REG_OK_FOR_BASE_P (operands[2])
3831 && FP_REGNO_P (REGNO (operands[3]))"
3832 [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3833 (match_dup 3))
3834 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3835 (match_dup 2)))]
3836 "")
3837
3838 (define_peephole2
3839 [(set (match_operand:DI 0 "register_operand" "")
3840 (plus:DI (match_operand:DI 2 "register_operand" "")
3841 (mult:DI (match_operand:DI 1 "register_operand" "")
3842 (const_int 8))))
3843 (set (mem:DF (match_dup 0))
3844 (match_operand:DF 3 "register_operand" ""))]
3845 "!TARGET_SOFT_FLOAT
3846 && !TARGET_DISABLE_INDEXING
3847 && TARGET_64BIT
3848 && REG_OK_FOR_BASE_P (operands[2])
3849 && FP_REGNO_P (REGNO (operands[3]))"
3850 [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3851 (match_dup 3))
3852 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3853 (match_dup 2)))]
3854 "")
3855
3856 (define_peephole2
3857 [(set (match_operand:SI 0 "register_operand" "")
3858 (plus:SI (match_operand:SI 1 "register_operand" "")
3859 (match_operand:SI 2 "register_operand" "")))
3860 (set (mem:DF (match_dup 0))
3861 (match_operand:DF 3 "register_operand" ""))]
3862 "!TARGET_SOFT_FLOAT
3863 && !TARGET_DISABLE_INDEXING
3864 && TARGET_NO_SPACE_REGS
3865 && REG_OK_FOR_INDEX_P (operands[1])
3866 && REG_OK_FOR_BASE_P (operands[2])
3867 && FP_REGNO_P (REGNO (operands[3]))"
3868 [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3869 (match_dup 3))
3870 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3871 "")
3872
3873 (define_peephole2
3874 [(set (match_operand:SI 0 "register_operand" "")
3875 (plus:SI (match_operand:SI 1 "register_operand" "")
3876 (match_operand:SI 2 "register_operand" "")))
3877 (set (mem:DF (match_dup 0))
3878 (match_operand:DF 3 "register_operand" ""))]
3879 "!TARGET_SOFT_FLOAT
3880 && !TARGET_DISABLE_INDEXING
3881 && TARGET_NO_SPACE_REGS
3882 && REG_OK_FOR_BASE_P (operands[1])
3883 && REG_OK_FOR_INDEX_P (operands[2])
3884 && FP_REGNO_P (REGNO (operands[3]))"
3885 [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3886 (match_dup 3))
3887 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3888 "")
3889
3890 (define_peephole2
3891 [(set (match_operand:DI 0 "register_operand" "")
3892 (plus:DI (match_operand:DI 1 "register_operand" "")
3893 (match_operand:DI 2 "register_operand" "")))
3894 (set (mem:DF (match_dup 0))
3895 (match_operand:DF 3 "register_operand" ""))]
3896 "!TARGET_SOFT_FLOAT
3897 && !TARGET_DISABLE_INDEXING
3898 && TARGET_64BIT
3899 && TARGET_NO_SPACE_REGS
3900 && REG_OK_FOR_INDEX_P (operands[1])
3901 && REG_OK_FOR_BASE_P (operands[2])
3902 && FP_REGNO_P (REGNO (operands[3]))"
3903 [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
3904 (match_dup 3))
3905 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
3906 "")
3907
3908 (define_peephole2
3909 [(set (match_operand:DI 0 "register_operand" "")
3910 (plus:DI (match_operand:DI 1 "register_operand" "")
3911 (match_operand:DI 2 "register_operand" "")))
3912 (set (mem:DF (match_dup 0))
3913 (match_operand:DF 3 "register_operand" ""))]
3914 "!TARGET_SOFT_FLOAT
3915 && !TARGET_DISABLE_INDEXING
3916 && TARGET_64BIT
3917 && TARGET_NO_SPACE_REGS
3918 && REG_OK_FOR_BASE_P (operands[1])
3919 && REG_OK_FOR_INDEX_P (operands[2])
3920 && FP_REGNO_P (REGNO (operands[3]))"
3921 [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
3922 (match_dup 3))
3923 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
3924 "")
3925
3926 (define_insn ""
3927 [(set (match_operand:DF 0 "move_dest_operand"
3928 "=r,?o,?Q,r,r")
3929 (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3930 "rG,r,r,o,RQ"))]
3931 "(register_operand (operands[0], DFmode)
3932 || reg_or_0_operand (operands[1], DFmode))
3933 && !TARGET_64BIT
3934 && TARGET_SOFT_FLOAT"
3935 "*
3936 {
3937 return pa_output_move_double (operands);
3938 }"
3939 [(set_attr "type" "move,store,store,load,load")
3940 (set_attr "length" "8,8,16,8,16")])
3941
3942 (define_insn ""
3943 [(set (match_operand:DF 0 "move_dest_operand"
3944 "=!*r,*r,*r,*r,*r,Q,f,f,T")
3945 (match_operand:DF 1 "move_src_operand"
3946 "!*r,J,N,K,RQ,*rG,fG,RT,f"))]
3947 "(register_operand (operands[0], DFmode)
3948 || reg_or_0_operand (operands[1], DFmode))
3949 && !TARGET_SOFT_FLOAT && TARGET_64BIT"
3950 "@
3951 copy %1,%0
3952 ldi %1,%0
3953 ldil L'%1,%0
3954 depdi,z %z1,%0
3955 ldd%M1 %1,%0
3956 std%M0 %r1,%0
3957 fcpy,dbl %f1,%0
3958 fldd%F1 %1,%0
3959 fstd%F0 %1,%0"
3960 [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
3961 (set_attr "pa_combine_type" "addmove")
3962 (set_attr "length" "4,4,4,4,4,4,4,4,4")])
3963
3964 \f
3965 (define_expand "movdi"
3966 [(set (match_operand:DI 0 "general_operand" "")
3967 (match_operand:DI 1 "general_operand" ""))]
3968 ""
3969 "
3970 {
3971 /* Except for zero, we don't support loading a CONST_INT directly
3972 to a hard floating-point register since a scratch register is
3973 needed for the operation. While the operation could be handled
3974 before register allocation, the simplest solution is to fail. */
3975 if (TARGET_64BIT
3976 && GET_CODE (operands[1]) == CONST_INT
3977 && operands[1] != CONST0_RTX (DImode)
3978 && REG_P (operands[0])
3979 && HARD_REGISTER_P (operands[0])
3980 && REGNO (operands[0]) >= 32)
3981 FAIL;
3982
3983 if (pa_emit_move_sequence (operands, DImode, 0))
3984 DONE;
3985 }")
3986
3987 ;; Handle DImode input reloads requiring %r1 as a scratch register.
3988 (define_expand "reload_indi_r1"
3989 [(set (match_operand:DI 0 "register_operand" "=Z")
3990 (match_operand:DI 1 "non_hard_reg_operand" ""))
3991 (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3992 ""
3993 "
3994 {
3995 if (pa_emit_move_sequence (operands, DImode, operands[2]))
3996 DONE;
3997
3998 /* We don't want the clobber emitted, so handle this ourselves. */
3999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4000 DONE;
4001 }")
4002
4003 ;; Handle DImode input reloads requiring a general register as a
4004 ;; scratch register.
4005 (define_expand "reload_indi"
4006 [(set (match_operand:DI 0 "register_operand" "=Z")
4007 (match_operand:DI 1 "non_hard_reg_operand" ""))
4008 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4009 ""
4010 "
4011 {
4012 if (pa_emit_move_sequence (operands, DImode, operands[2]))
4013 DONE;
4014
4015 /* We don't want the clobber emitted, so handle this ourselves. */
4016 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4017 DONE;
4018 }")
4019
4020 ;; Handle DImode output reloads requiring a general register as a
4021 ;; scratch register.
4022 (define_expand "reload_outdi"
4023 [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4024 (match_operand:DI 1 "register_operand" "Z"))
4025 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4026 ""
4027 "
4028 {
4029 if (pa_emit_move_sequence (operands, DImode, operands[2]))
4030 DONE;
4031
4032 /* We don't want the clobber emitted, so handle this ourselves. */
4033 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4034 DONE;
4035 }")
4036
4037 (define_insn ""
4038 [(set (match_operand:DI 0 "register_operand" "=r")
4039 (high:DI (match_operand 1 "" "")))]
4040 "!TARGET_64BIT"
4041 "*
4042 {
4043 rtx op0 = operands[0];
4044 rtx op1 = operands[1];
4045
4046 switch (GET_CODE (op1))
4047 {
4048 case CONST_INT:
4049 #if HOST_BITS_PER_WIDE_INT <= 32
4050 operands[0] = operand_subword (op0, 1, 0, DImode);
4051 output_asm_insn (\"ldil L'%1,%0\", operands);
4052
4053 operands[0] = operand_subword (op0, 0, 0, DImode);
4054 if (INTVAL (op1) < 0)
4055 output_asm_insn (\"ldi -1,%0\", operands);
4056 else
4057 output_asm_insn (\"ldi 0,%0\", operands);
4058 #else
4059 operands[0] = operand_subword (op0, 1, 0, DImode);
4060 operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4061 output_asm_insn (\"ldil L'%1,%0\", operands);
4062
4063 operands[0] = operand_subword (op0, 0, 0, DImode);
4064 operands[1] = GEN_INT (INTVAL (op1) >> 32);
4065 output_asm_insn (pa_singlemove_string (operands), operands);
4066 #endif
4067 break;
4068
4069 case CONST_DOUBLE:
4070 operands[0] = operand_subword (op0, 1, 0, DImode);
4071 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4072 output_asm_insn (\"ldil L'%1,%0\", operands);
4073
4074 operands[0] = operand_subword (op0, 0, 0, DImode);
4075 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4076 output_asm_insn (pa_singlemove_string (operands), operands);
4077 break;
4078
4079 default:
4080 gcc_unreachable ();
4081 }
4082 return \"\";
4083 }"
4084 [(set_attr "type" "move")
4085 (set_attr "length" "12")])
4086
4087 (define_insn ""
4088 [(set (match_operand:DI 0 "move_dest_operand"
4089 "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4090 (match_operand:DI 1 "general_operand"
4091 "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4092 "(register_operand (operands[0], DImode)
4093 || reg_or_0_operand (operands[1], DImode))
4094 && !TARGET_64BIT
4095 && !TARGET_SOFT_FLOAT"
4096 "*
4097 {
4098 if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4099 || operands[1] == CONST0_RTX (DFmode))
4100 && !(REG_P (operands[0]) && REG_P (operands[1])
4101 && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4102 return pa_output_fp_move_double (operands);
4103 return pa_output_move_double (operands);
4104 }"
4105 [(set_attr "type"
4106 "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4107 (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4108
4109 (define_insn ""
4110 [(set (match_operand:DI 0 "move_dest_operand"
4111 "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4112 (match_operand:DI 1 "move_src_operand"
4113 "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4114 "(register_operand (operands[0], DImode)
4115 || reg_or_0_operand (operands[1], DImode))
4116 && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4117 "@
4118 ldd RT'%A1,%0
4119 copy %1,%0
4120 ldi %1,%0
4121 ldil L'%1,%0
4122 depdi,z %z1,%0
4123 ldd%M1 %1,%0
4124 std%M0 %r1,%0
4125 mtsar %r1
4126 {mfctl|mfctl,w} %%sar,%0
4127 fcpy,dbl %f1,%0
4128 fldd%F1 %1,%0
4129 fstd%F0 %1,%0"
4130 [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4131 (set_attr "pa_combine_type" "addmove")
4132 (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4133
4134 (define_insn ""
4135 [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4136 (match_operand:DI 1 "register_operand" "f"))]
4137 "!TARGET_SOFT_FLOAT
4138 && TARGET_64BIT
4139 && !TARGET_DISABLE_INDEXING
4140 && reload_completed"
4141 "fstd%F0 %1,%0"
4142 [(set_attr "type" "fpstore")
4143 (set_attr "pa_combine_type" "addmove")
4144 (set_attr "length" "4")])
4145
4146 (define_peephole2
4147 [(set (match_operand:DI 0 "register_operand" "")
4148 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4149 (const_int 8))
4150 (match_operand:DI 2 "register_operand" "")))
4151 (set (mem:DI (match_dup 0))
4152 (match_operand:DI 3 "register_operand" ""))]
4153 "!TARGET_SOFT_FLOAT
4154 && !TARGET_DISABLE_INDEXING
4155 && TARGET_64BIT
4156 && REG_OK_FOR_BASE_P (operands[2])
4157 && FP_REGNO_P (REGNO (operands[3]))"
4158 [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4159 (match_dup 3))
4160 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4161 (match_dup 2)))]
4162 "")
4163
4164 (define_peephole2
4165 [(set (match_operand:DI 0 "register_operand" "")
4166 (plus:DI (match_operand:DI 2 "register_operand" "")
4167 (mult:DI (match_operand:DI 1 "register_operand" "")
4168 (const_int 8))))
4169 (set (mem:DI (match_dup 0))
4170 (match_operand:DI 3 "register_operand" ""))]
4171 "!TARGET_SOFT_FLOAT
4172 && !TARGET_DISABLE_INDEXING
4173 && TARGET_64BIT
4174 && REG_OK_FOR_BASE_P (operands[2])
4175 && FP_REGNO_P (REGNO (operands[3]))"
4176 [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4177 (match_dup 3))
4178 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4179 (match_dup 2)))]
4180 "")
4181
4182 (define_peephole2
4183 [(set (match_operand:DI 0 "register_operand" "")
4184 (plus:DI (match_operand:DI 1 "register_operand" "")
4185 (match_operand:DI 2 "register_operand" "")))
4186 (set (mem:DI (match_dup 0))
4187 (match_operand:DI 3 "register_operand" ""))]
4188 "!TARGET_SOFT_FLOAT
4189 && !TARGET_DISABLE_INDEXING
4190 && TARGET_64BIT
4191 && TARGET_NO_SPACE_REGS
4192 && REG_OK_FOR_INDEX_P (operands[1])
4193 && REG_OK_FOR_BASE_P (operands[2])
4194 && FP_REGNO_P (REGNO (operands[3]))"
4195 [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4196 (match_dup 3))
4197 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4198 "")
4199
4200 (define_peephole2
4201 [(set (match_operand:DI 0 "register_operand" "")
4202 (plus:DI (match_operand:DI 1 "register_operand" "")
4203 (match_operand:DI 2 "register_operand" "")))
4204 (set (mem:DI (match_dup 0))
4205 (match_operand:DI 3 "register_operand" ""))]
4206 "!TARGET_SOFT_FLOAT
4207 && !TARGET_DISABLE_INDEXING
4208 && TARGET_64BIT
4209 && TARGET_NO_SPACE_REGS
4210 && REG_OK_FOR_BASE_P (operands[1])
4211 && REG_OK_FOR_INDEX_P (operands[2])
4212 && FP_REGNO_P (REGNO (operands[3]))"
4213 [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4214 (match_dup 3))
4215 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4216 "")
4217
4218 (define_insn ""
4219 [(set (match_operand:DI 0 "move_dest_operand"
4220 "=r,o,Q,r,r,r")
4221 (match_operand:DI 1 "general_operand"
4222 "rM,r,r,o,Q,i"))]
4223 "(register_operand (operands[0], DImode)
4224 || reg_or_0_operand (operands[1], DImode))
4225 && !TARGET_64BIT
4226 && TARGET_SOFT_FLOAT"
4227 "*
4228 {
4229 return pa_output_move_double (operands);
4230 }"
4231 [(set_attr "type" "move,store,store,load,load,multi")
4232 (set_attr "length" "8,8,16,8,16,16")])
4233
4234 (define_insn ""
4235 [(set (match_operand:DI 0 "register_operand" "=r,&r")
4236 (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4237 (match_operand:DI 2 "immediate_operand" "i,i")))]
4238 "!TARGET_64BIT"
4239 "*
4240 {
4241 /* Don't output a 64-bit constant, since we can't trust the assembler to
4242 handle it correctly. */
4243 if (GET_CODE (operands[2]) == CONST_DOUBLE)
4244 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4245 else if (HOST_BITS_PER_WIDE_INT > 32
4246 && GET_CODE (operands[2]) == CONST_INT)
4247 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4248 if (which_alternative == 1)
4249 output_asm_insn (\"copy %1,%0\", operands);
4250 return \"ldo R'%G2(%R1),%R0\";
4251 }"
4252 [(set_attr "type" "move,move")
4253 (set_attr "length" "4,8")])
4254
4255 ;; This pattern forces (set (reg:SF ...) (const_double ...))
4256 ;; to be reloaded by putting the constant into memory when
4257 ;; reg is a floating point register.
4258 ;;
4259 ;; For integer registers we use ldil;ldo to set the appropriate
4260 ;; value.
4261 ;;
4262 ;; This must come before the movsf pattern, and it must be present
4263 ;; to handle obscure reloading cases.
4264 (define_insn ""
4265 [(set (match_operand:SF 0 "register_operand" "=?r,f")
4266 (match_operand:SF 1 "" "?F,m"))]
4267 "GET_CODE (operands[1]) == CONST_DOUBLE
4268 && operands[1] != CONST0_RTX (SFmode)
4269 && ! TARGET_SOFT_FLOAT"
4270 "* return (which_alternative == 0 ? pa_singlemove_string (operands)
4271 : \" fldw%F1 %1,%0\");"
4272 [(set_attr "type" "move,fpload")
4273 (set_attr "length" "8,4")])
4274
4275 (define_expand "movsf"
4276 [(set (match_operand:SF 0 "general_operand" "")
4277 (match_operand:SF 1 "general_operand" ""))]
4278 ""
4279 "
4280 {
4281 /* Reject CONST_DOUBLE loads to floating point registers. */
4282 if (GET_CODE (operands[1]) == CONST_DOUBLE
4283 && operands[1] != CONST0_RTX (SFmode)
4284 && REG_P (operands[0])
4285 && HARD_REGISTER_P (operands[0])
4286 && REGNO (operands[0]) >= 32)
4287 FAIL;
4288
4289 if (pa_emit_move_sequence (operands, SFmode, 0))
4290 DONE;
4291 }")
4292
4293 ;; Handle SFmode input reloads requiring a general register as a
4294 ;; scratch register.
4295 (define_expand "reload_insf"
4296 [(set (match_operand:SF 0 "register_operand" "=Z")
4297 (match_operand:SF 1 "non_hard_reg_operand" ""))
4298 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4299 ""
4300 "
4301 {
4302 if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4303 DONE;
4304
4305 /* We don't want the clobber emitted, so handle this ourselves. */
4306 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4307 DONE;
4308 }")
4309
4310 ;; Handle SFmode output reloads requiring a general register as a
4311 ;; scratch register.
4312 (define_expand "reload_outsf"
4313 [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4314 (match_operand:SF 1 "register_operand" "Z"))
4315 (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4316 ""
4317 "
4318 {
4319 if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4320 DONE;
4321
4322 /* We don't want the clobber emitted, so handle this ourselves. */
4323 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4324 DONE;
4325 }")
4326
4327 (define_insn ""
4328 [(set (match_operand:SF 0 "move_dest_operand"
4329 "=f,!*r,f,*r,Q,Q,?*r,?f")
4330 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4331 "fG,!*rG,RQ,RQ,f,*rG,f,*r"))]
4332 "(register_operand (operands[0], SFmode)
4333 || reg_or_0_operand (operands[1], SFmode))
4334 && !TARGET_SOFT_FLOAT
4335 && !TARGET_64BIT"
4336 "@
4337 fcpy,sgl %f1,%0
4338 copy %r1,%0
4339 fldw%F1 %1,%0
4340 ldw%M1 %1,%0
4341 fstw%F0 %1,%0
4342 stw%M0 %r1,%0
4343 {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4344 {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4345 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4346 (set_attr "pa_combine_type" "addmove")
4347 (set_attr "length" "4,4,4,4,4,4,8,8")])
4348
4349 (define_insn ""
4350 [(set (match_operand:SF 0 "move_dest_operand"
4351 "=f,!*r,f,*r,Q,Q")
4352 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4353 "fG,!*rG,RQ,RQ,f,*rG"))]
4354 "(register_operand (operands[0], SFmode)
4355 || reg_or_0_operand (operands[1], SFmode))
4356 && !TARGET_SOFT_FLOAT
4357 && TARGET_64BIT"
4358 "@
4359 fcpy,sgl %f1,%0
4360 copy %r1,%0
4361 fldw%F1 %1,%0
4362 ldw%M1 %1,%0
4363 fstw%F0 %1,%0
4364 stw%M0 %r1,%0"
4365 [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4366 (set_attr "pa_combine_type" "addmove")
4367 (set_attr "length" "4,4,4,4,4,4")])
4368
4369 (define_insn ""
4370 [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4371 (match_operand:SF 1 "register_operand" "f"))]
4372 "!TARGET_SOFT_FLOAT
4373 && !TARGET_DISABLE_INDEXING
4374 && reload_completed"
4375 "fstw%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:SI 0 "register_operand" "")
4382 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4383 (const_int 4))
4384 (match_operand:SI 2 "register_operand" "")))
4385 (set (mem:SF (match_dup 0))
4386 (match_operand:SF 3 "register_operand" ""))]
4387 "!TARGET_SOFT_FLOAT
4388 && !TARGET_DISABLE_INDEXING
4389 && REG_OK_FOR_BASE_P (operands[2])
4390 && FP_REGNO_P (REGNO (operands[3]))"
4391 [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4392 (match_dup 3))
4393 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4394 (match_dup 2)))]
4395 "")
4396
4397 (define_peephole2
4398 [(set (match_operand:SI 0 "register_operand" "")
4399 (plus:SI (match_operand:SI 2 "register_operand" "")
4400 (mult:SI (match_operand:SI 1 "register_operand" "")
4401 (const_int 4))))
4402 (set (mem:SF (match_dup 0))
4403 (match_operand:SF 3 "register_operand" ""))]
4404 "!TARGET_SOFT_FLOAT
4405 && !TARGET_DISABLE_INDEXING
4406 && REG_OK_FOR_BASE_P (operands[2])
4407 && FP_REGNO_P (REGNO (operands[3]))"
4408 [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4409 (match_dup 3))
4410 (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4411 (match_dup 2)))]
4412 "")
4413
4414 (define_peephole2
4415 [(set (match_operand:DI 0 "register_operand" "")
4416 (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4417 (const_int 4))
4418 (match_operand:DI 2 "register_operand" "")))
4419 (set (mem:SF (match_dup 0))
4420 (match_operand:SF 3 "register_operand" ""))]
4421 "!TARGET_SOFT_FLOAT
4422 && !TARGET_DISABLE_INDEXING
4423 && TARGET_64BIT
4424 && REG_OK_FOR_BASE_P (operands[2])
4425 && FP_REGNO_P (REGNO (operands[3]))"
4426 [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4427 (match_dup 3))
4428 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4429 (match_dup 2)))]
4430 "")
4431
4432 (define_peephole2
4433 [(set (match_operand:DI 0 "register_operand" "")
4434 (plus:DI (match_operand:DI 2 "register_operand" "")
4435 (mult:DI (match_operand:DI 1 "register_operand" "")
4436 (const_int 4))))
4437 (set (mem:SF (match_dup 0))
4438 (match_operand:SF 3 "register_operand" ""))]
4439 "!TARGET_SOFT_FLOAT
4440 && !TARGET_DISABLE_INDEXING
4441 && TARGET_64BIT
4442 && REG_OK_FOR_BASE_P (operands[2])
4443 && FP_REGNO_P (REGNO (operands[3]))"
4444 [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4445 (match_dup 3))
4446 (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4447 (match_dup 2)))]
4448 "")
4449
4450 (define_peephole2
4451 [(set (match_operand:SI 0 "register_operand" "")
4452 (plus:SI (match_operand:SI 1 "register_operand" "")
4453 (match_operand:SI 2 "register_operand" "")))
4454 (set (mem:SF (match_dup 0))
4455 (match_operand:SF 3 "register_operand" ""))]
4456 "!TARGET_SOFT_FLOAT
4457 && !TARGET_DISABLE_INDEXING
4458 && TARGET_NO_SPACE_REGS
4459 && REG_OK_FOR_INDEX_P (operands[1])
4460 && REG_OK_FOR_BASE_P (operands[2])
4461 && FP_REGNO_P (REGNO (operands[3]))"
4462 [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4463 (match_dup 3))
4464 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4465 "")
4466
4467 (define_peephole2
4468 [(set (match_operand:SI 0 "register_operand" "")
4469 (plus:SI (match_operand:SI 1 "register_operand" "")
4470 (match_operand:SI 2 "register_operand" "")))
4471 (set (mem:SF (match_dup 0))
4472 (match_operand:SF 3 "register_operand" ""))]
4473 "!TARGET_SOFT_FLOAT
4474 && !TARGET_DISABLE_INDEXING
4475 && TARGET_NO_SPACE_REGS
4476 && REG_OK_FOR_BASE_P (operands[1])
4477 && REG_OK_FOR_INDEX_P (operands[2])
4478 && FP_REGNO_P (REGNO (operands[3]))"
4479 [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4480 (match_dup 3))
4481 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4482 "")
4483
4484 (define_peephole2
4485 [(set (match_operand:DI 0 "register_operand" "")
4486 (plus:DI (match_operand:DI 1 "register_operand" "")
4487 (match_operand:DI 2 "register_operand" "")))
4488 (set (mem:SF (match_dup 0))
4489 (match_operand:SF 3 "register_operand" ""))]
4490 "!TARGET_SOFT_FLOAT
4491 && !TARGET_DISABLE_INDEXING
4492 && TARGET_64BIT
4493 && TARGET_NO_SPACE_REGS
4494 && REG_OK_FOR_INDEX_P (operands[1])
4495 && REG_OK_FOR_BASE_P (operands[2])
4496 && FP_REGNO_P (REGNO (operands[3]))"
4497 [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4498 (match_dup 3))
4499 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4500 "")
4501
4502 (define_peephole2
4503 [(set (match_operand:DI 0 "register_operand" "")
4504 (plus:DI (match_operand:DI 1 "register_operand" "")
4505 (match_operand:DI 2 "register_operand" "")))
4506 (set (mem:SF (match_dup 0))
4507 (match_operand:SF 3 "register_operand" ""))]
4508 "!TARGET_SOFT_FLOAT
4509 && !TARGET_DISABLE_INDEXING
4510 && TARGET_64BIT
4511 && TARGET_NO_SPACE_REGS
4512 && REG_OK_FOR_BASE_P (operands[1])
4513 && REG_OK_FOR_INDEX_P (operands[2])
4514 && FP_REGNO_P (REGNO (operands[3]))"
4515 [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4516 (match_dup 3))
4517 (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4518 "")
4519
4520 (define_insn ""
4521 [(set (match_operand:SF 0 "move_dest_operand"
4522 "=r,r,Q")
4523 (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4524 "rG,RQ,rG"))]
4525 "(register_operand (operands[0], SFmode)
4526 || reg_or_0_operand (operands[1], SFmode))
4527 && TARGET_SOFT_FLOAT"
4528 "@
4529 copy %r1,%0
4530 ldw%M1 %1,%0
4531 stw%M0 %r1,%0"
4532 [(set_attr "type" "move,load,store")
4533 (set_attr "pa_combine_type" "addmove")
4534 (set_attr "length" "4,4,4")])
4535
4536 \f
4537
4538 ;;- zero extension instructions
4539 ;; We have define_expand for zero extension patterns to make sure the
4540 ;; operands get loaded into registers. The define_insns accept
4541 ;; memory operands. This gives us better overall code than just
4542 ;; having a pattern that does or does not accept memory operands.
4543
4544 (define_expand "zero_extendqihi2"
4545 [(set (match_operand:HI 0 "register_operand" "")
4546 (zero_extend:HI
4547 (match_operand:QI 1 "register_operand" "")))]
4548 ""
4549 "")
4550
4551 (define_insn ""
4552 [(set (match_operand:HI 0 "register_operand" "=r,r")
4553 (zero_extend:HI
4554 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4555 "GET_CODE (operands[1]) != CONST_INT"
4556 "@
4557 {extru|extrw,u} %1,31,8,%0
4558 ldb%M1 %1,%0"
4559 [(set_attr "type" "shift,load")
4560 (set_attr "length" "4,4")])
4561
4562 (define_expand "zero_extendqisi2"
4563 [(set (match_operand:SI 0 "register_operand" "")
4564 (zero_extend:SI
4565 (match_operand:QI 1 "register_operand" "")))]
4566 ""
4567 "")
4568
4569 (define_insn ""
4570 [(set (match_operand:SI 0 "register_operand" "=r,r")
4571 (zero_extend:SI
4572 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4573 "GET_CODE (operands[1]) != CONST_INT"
4574 "@
4575 {extru|extrw,u} %1,31,8,%0
4576 ldb%M1 %1,%0"
4577 [(set_attr "type" "shift,load")
4578 (set_attr "length" "4,4")])
4579
4580 (define_expand "zero_extendhisi2"
4581 [(set (match_operand:SI 0 "register_operand" "")
4582 (zero_extend:SI
4583 (match_operand:HI 1 "register_operand" "")))]
4584 ""
4585 "")
4586
4587 (define_insn ""
4588 [(set (match_operand:SI 0 "register_operand" "=r,r")
4589 (zero_extend:SI
4590 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4591 "GET_CODE (operands[1]) != CONST_INT"
4592 "@
4593 {extru|extrw,u} %1,31,16,%0
4594 ldh%M1 %1,%0"
4595 [(set_attr "type" "shift,load")
4596 (set_attr "length" "4,4")])
4597
4598 (define_expand "zero_extendqidi2"
4599 [(set (match_operand:DI 0 "register_operand" "")
4600 (zero_extend:DI
4601 (match_operand:QI 1 "register_operand" "")))]
4602 "TARGET_64BIT"
4603 "")
4604
4605 (define_insn ""
4606 [(set (match_operand:DI 0 "register_operand" "=r,r")
4607 (zero_extend:DI
4608 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4609 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4610 "@
4611 extrd,u %1,63,8,%0
4612 ldb%M1 %1,%0"
4613 [(set_attr "type" "shift,load")
4614 (set_attr "length" "4,4")])
4615
4616 (define_expand "zero_extendhidi2"
4617 [(set (match_operand:DI 0 "register_operand" "")
4618 (zero_extend:DI
4619 (match_operand:HI 1 "register_operand" "")))]
4620 "TARGET_64BIT"
4621 "")
4622
4623 (define_insn ""
4624 [(set (match_operand:DI 0 "register_operand" "=r,r")
4625 (zero_extend:DI
4626 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4627 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4628 "@
4629 extrd,u %1,63,16,%0
4630 ldh%M1 %1,%0"
4631 [(set_attr "type" "shift,load")
4632 (set_attr "length" "4,4")])
4633
4634 (define_expand "zero_extendsidi2"
4635 [(set (match_operand:DI 0 "register_operand" "")
4636 (zero_extend:DI
4637 (match_operand:SI 1 "register_operand" "")))]
4638 "TARGET_64BIT"
4639 "")
4640
4641 (define_insn ""
4642 [(set (match_operand:DI 0 "register_operand" "=r,r")
4643 (zero_extend:DI
4644 (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4645 "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4646 "@
4647 extrd,u %1,63,32,%0
4648 ldw%M1 %1,%0"
4649 [(set_attr "type" "shift,load")
4650 (set_attr "length" "4,4")])
4651
4652 ;;- sign extension instructions
4653
4654 (define_insn "extendhisi2"
4655 [(set (match_operand:SI 0 "register_operand" "=r")
4656 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4657 ""
4658 "{extrs|extrw,s} %1,31,16,%0"
4659 [(set_attr "type" "shift")
4660 (set_attr "length" "4")])
4661
4662 (define_insn "extendqihi2"
4663 [(set (match_operand:HI 0 "register_operand" "=r")
4664 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4665 ""
4666 "{extrs|extrw,s} %1,31,8,%0"
4667 [(set_attr "type" "shift")
4668 (set_attr "length" "4")])
4669
4670 (define_insn "extendqisi2"
4671 [(set (match_operand:SI 0 "register_operand" "=r")
4672 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4673 ""
4674 "{extrs|extrw,s} %1,31,8,%0"
4675 [(set_attr "type" "shift")
4676 (set_attr "length" "4")])
4677
4678 (define_insn "extendqidi2"
4679 [(set (match_operand:DI 0 "register_operand" "=r")
4680 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4681 "TARGET_64BIT"
4682 "extrd,s %1,63,8,%0"
4683 [(set_attr "type" "shift")
4684 (set_attr "length" "4")])
4685
4686 (define_insn "extendhidi2"
4687 [(set (match_operand:DI 0 "register_operand" "=r")
4688 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4689 "TARGET_64BIT"
4690 "extrd,s %1,63,16,%0"
4691 [(set_attr "type" "shift")
4692 (set_attr "length" "4")])
4693
4694 (define_insn "extendsidi2"
4695 [(set (match_operand:DI 0 "register_operand" "=r")
4696 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4697 "TARGET_64BIT"
4698 "extrd,s %1,63,32,%0"
4699 [(set_attr "type" "shift")
4700 (set_attr "length" "4")])
4701
4702 \f
4703 ;; Conversions between float and double.
4704
4705 (define_insn "extendsfdf2"
4706 [(set (match_operand:DF 0 "register_operand" "=f")
4707 (float_extend:DF
4708 (match_operand:SF 1 "register_operand" "f")))]
4709 "! TARGET_SOFT_FLOAT"
4710 "{fcnvff|fcnv},sgl,dbl %1,%0"
4711 [(set_attr "type" "fpalu")
4712 (set_attr "length" "4")])
4713
4714 (define_insn "truncdfsf2"
4715 [(set (match_operand:SF 0 "register_operand" "=f")
4716 (float_truncate:SF
4717 (match_operand:DF 1 "register_operand" "f")))]
4718 "! TARGET_SOFT_FLOAT"
4719 "{fcnvff|fcnv},dbl,sgl %1,%0"
4720 [(set_attr "type" "fpalu")
4721 (set_attr "length" "4")])
4722
4723 ;; Conversion between fixed point and floating point.
4724 ;; Note that among the fix-to-float insns
4725 ;; the ones that start with SImode come first.
4726 ;; That is so that an operand that is a CONST_INT
4727 ;; (and therefore lacks a specific machine mode).
4728 ;; will be recognized as SImode (which is always valid)
4729 ;; rather than as QImode or HImode.
4730
4731 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4732 ;; to be reloaded by putting the constant into memory.
4733 ;; It must come before the more general floatsisf2 pattern.
4734 (define_insn ""
4735 [(set (match_operand:SF 0 "register_operand" "=f")
4736 (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4737 "! TARGET_SOFT_FLOAT"
4738 "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4739 [(set_attr "type" "fpalu")
4740 (set_attr "length" "8")])
4741
4742 (define_insn "floatsisf2"
4743 [(set (match_operand:SF 0 "register_operand" "=f")
4744 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4745 "! TARGET_SOFT_FLOAT"
4746 "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4747 [(set_attr "type" "fpalu")
4748 (set_attr "length" "4")])
4749
4750 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4751 ;; to be reloaded by putting the constant into memory.
4752 ;; It must come before the more general floatsidf2 pattern.
4753 (define_insn ""
4754 [(set (match_operand:DF 0 "register_operand" "=f")
4755 (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4756 "! TARGET_SOFT_FLOAT"
4757 "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4758 [(set_attr "type" "fpalu")
4759 (set_attr "length" "8")])
4760
4761 (define_insn "floatsidf2"
4762 [(set (match_operand:DF 0 "register_operand" "=f")
4763 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4764 "! TARGET_SOFT_FLOAT"
4765 "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4766 [(set_attr "type" "fpalu")
4767 (set_attr "length" "4")])
4768
4769 (define_expand "floatunssisf2"
4770 [(set (subreg:SI (match_dup 2) 4)
4771 (match_operand:SI 1 "register_operand" ""))
4772 (set (subreg:SI (match_dup 2) 0)
4773 (const_int 0))
4774 (set (match_operand:SF 0 "register_operand" "")
4775 (float:SF (match_dup 2)))]
4776 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4777 "
4778 {
4779 if (TARGET_PA_20)
4780 {
4781 emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4782 DONE;
4783 }
4784 operands[2] = gen_reg_rtx (DImode);
4785 }")
4786
4787 (define_expand "floatunssidf2"
4788 [(set (subreg:SI (match_dup 2) 4)
4789 (match_operand:SI 1 "register_operand" ""))
4790 (set (subreg:SI (match_dup 2) 0)
4791 (const_int 0))
4792 (set (match_operand:DF 0 "register_operand" "")
4793 (float:DF (match_dup 2)))]
4794 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4795 "
4796 {
4797 if (TARGET_PA_20)
4798 {
4799 emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4800 DONE;
4801 }
4802 operands[2] = gen_reg_rtx (DImode);
4803 }")
4804
4805 (define_insn "floatdisf2"
4806 [(set (match_operand:SF 0 "register_operand" "=f")
4807 (float:SF (match_operand:DI 1 "register_operand" "f")))]
4808 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4809 "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4810 [(set_attr "type" "fpalu")
4811 (set_attr "length" "4")])
4812
4813 (define_insn "floatdidf2"
4814 [(set (match_operand:DF 0 "register_operand" "=f")
4815 (float:DF (match_operand:DI 1 "register_operand" "f")))]
4816 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4817 "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4818 [(set_attr "type" "fpalu")
4819 (set_attr "length" "4")])
4820
4821 ;; Convert a float to an actual integer.
4822 ;; Truncation is performed as part of the conversion.
4823
4824 (define_insn "fix_truncsfsi2"
4825 [(set (match_operand:SI 0 "register_operand" "=f")
4826 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4827 "! TARGET_SOFT_FLOAT"
4828 "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4829 [(set_attr "type" "fpalu")
4830 (set_attr "length" "4")])
4831
4832 (define_insn "fix_truncdfsi2"
4833 [(set (match_operand:SI 0 "register_operand" "=f")
4834 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4835 "! TARGET_SOFT_FLOAT"
4836 "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4837 [(set_attr "type" "fpalu")
4838 (set_attr "length" "4")])
4839
4840 (define_insn "fix_truncsfdi2"
4841 [(set (match_operand:DI 0 "register_operand" "=f")
4842 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4843 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4844 "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4845 [(set_attr "type" "fpalu")
4846 (set_attr "length" "4")])
4847
4848 (define_insn "fix_truncdfdi2"
4849 [(set (match_operand:DI 0 "register_operand" "=f")
4850 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4851 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4852 "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4853 [(set_attr "type" "fpalu")
4854 (set_attr "length" "4")])
4855
4856 (define_insn "floatunssidf2_pa20"
4857 [(set (match_operand:DF 0 "register_operand" "=f")
4858 (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4859 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4860 "fcnv,uw,dbl %1,%0"
4861 [(set_attr "type" "fpalu")
4862 (set_attr "length" "4")])
4863
4864 (define_insn "floatunssisf2_pa20"
4865 [(set (match_operand:SF 0 "register_operand" "=f")
4866 (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4867 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4868 "fcnv,uw,sgl %1,%0"
4869 [(set_attr "type" "fpalu")
4870 (set_attr "length" "4")])
4871
4872 (define_insn "floatunsdisf2"
4873 [(set (match_operand:SF 0 "register_operand" "=f")
4874 (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4875 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4876 "fcnv,udw,sgl %1,%0"
4877 [(set_attr "type" "fpalu")
4878 (set_attr "length" "4")])
4879
4880 (define_insn "floatunsdidf2"
4881 [(set (match_operand:DF 0 "register_operand" "=f")
4882 (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4883 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4884 "fcnv,udw,dbl %1,%0"
4885 [(set_attr "type" "fpalu")
4886 (set_attr "length" "4")])
4887
4888 (define_insn "fixuns_truncsfsi2"
4889 [(set (match_operand:SI 0 "register_operand" "=f")
4890 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4891 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4892 "fcnv,t,sgl,uw %1,%0"
4893 [(set_attr "type" "fpalu")
4894 (set_attr "length" "4")])
4895
4896 (define_insn "fixuns_truncdfsi2"
4897 [(set (match_operand:SI 0 "register_operand" "=f")
4898 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4899 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4900 "fcnv,t,dbl,uw %1,%0"
4901 [(set_attr "type" "fpalu")
4902 (set_attr "length" "4")])
4903
4904 (define_insn "fixuns_truncsfdi2"
4905 [(set (match_operand:DI 0 "register_operand" "=f")
4906 (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4907 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4908 "fcnv,t,sgl,udw %1,%0"
4909 [(set_attr "type" "fpalu")
4910 (set_attr "length" "4")])
4911
4912 (define_insn "fixuns_truncdfdi2"
4913 [(set (match_operand:DI 0 "register_operand" "=f")
4914 (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4915 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4916 "fcnv,t,dbl,udw %1,%0"
4917 [(set_attr "type" "fpalu")
4918 (set_attr "length" "4")])
4919 \f
4920 ;;- arithmetic instructions
4921
4922 (define_expand "adddi3"
4923 [(set (match_operand:DI 0 "register_operand" "")
4924 (plus:DI (match_operand:DI 1 "register_operand" "")
4925 (match_operand:DI 2 "adddi3_operand" "")))]
4926 ""
4927 "")
4928
4929 (define_insn ""
4930 [(set (match_operand:DI 0 "register_operand" "=r")
4931 (plus:DI (match_operand:DI 1 "register_operand" "%r")
4932 (match_operand:DI 2 "arith11_operand" "rI")))]
4933 "!TARGET_64BIT"
4934 "*
4935 {
4936 if (GET_CODE (operands[2]) == CONST_INT)
4937 {
4938 if (INTVAL (operands[2]) >= 0)
4939 return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
4940 else
4941 return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
4942 }
4943 else
4944 return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
4945 }"
4946 [(set_attr "type" "binary")
4947 (set_attr "length" "8")])
4948
4949 (define_insn ""
4950 [(set (match_operand:DI 0 "register_operand" "=r,r")
4951 (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4952 (match_operand:DI 2 "arith14_operand" "r,J")))]
4953 "TARGET_64BIT"
4954 "@
4955 add,l %1,%2,%0
4956 ldo %2(%1),%0"
4957 [(set_attr "type" "binary,binary")
4958 (set_attr "pa_combine_type" "addmove")
4959 (set_attr "length" "4,4")])
4960
4961 (define_insn ""
4962 [(set (match_operand:DI 0 "register_operand" "=r")
4963 (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4964 (match_operand:DI 2 "register_operand" "r")))]
4965 "TARGET_64BIT"
4966 "uaddcm %2,%1,%0"
4967 [(set_attr "type" "binary")
4968 (set_attr "length" "4")])
4969
4970 (define_insn ""
4971 [(set (match_operand:SI 0 "register_operand" "=r")
4972 (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4973 (match_operand:SI 2 "register_operand" "r")))]
4974 ""
4975 "uaddcm %2,%1,%0"
4976 [(set_attr "type" "binary")
4977 (set_attr "length" "4")])
4978
4979 (define_expand "addvdi3"
4980 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4981 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
4982 (match_operand:DI 2 "arith11_operand" "")))
4983 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
4984 (sign_extend:TI (match_dup 2)))
4985 (sign_extend:TI (plus:DI (match_dup 1)
4986 (match_dup 2))))
4987 (const_int 0))])]
4988 ""
4989 "")
4990
4991 (define_insn ""
4992 [(set (match_operand:DI 0 "register_operand" "=r,r")
4993 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
4994 (match_operand:DI 2 "arith11_operand" "r,I")))
4995 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
4996 (sign_extend:TI (match_dup 2)))
4997 (sign_extend:TI (plus:DI (match_dup 1)
4998 (match_dup 2))))
4999 (const_int 0))]
5000 "TARGET_64BIT"
5001 "@
5002 add,tsv,* %2,%1,%0
5003 addi,tsv,* %2,%1,%0"
5004 [(set_attr "type" "binary,binary")
5005 (set_attr "length" "4,4")])
5006
5007 (define_insn ""
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5009 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5010 (match_operand:DI 2 "arith11_operand" "rI")))
5011 (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5012 (sign_extend:TI (match_dup 2)))
5013 (sign_extend:TI (plus:DI (match_dup 1)
5014 (match_dup 2))))
5015 (const_int 0))]
5016 "!TARGET_64BIT"
5017 "*
5018 {
5019 if (GET_CODE (operands[2]) == CONST_INT)
5020 {
5021 if (INTVAL (operands[2]) >= 0)
5022 return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5023 else
5024 return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5025 }
5026 else
5027 return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5028 }"
5029 [(set_attr "type" "binary")
5030 (set_attr "length" "8")])
5031
5032 ;; define_splits to optimize cases of adding a constant integer
5033 ;; to a register when the constant does not fit in 14 bits. */
5034 (define_split
5035 [(set (match_operand:SI 0 "register_operand" "")
5036 (plus:SI (match_operand:SI 1 "register_operand" "")
5037 (match_operand:SI 2 "const_int_operand" "")))
5038 (clobber (match_operand:SI 4 "register_operand" ""))]
5039 "! pa_cint_ok_for_move (INTVAL (operands[2]))
5040 && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5041 [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5042 (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5043 "
5044 {
5045 int val = INTVAL (operands[2]);
5046 int low = (val < 0) ? -0x2000 : 0x1fff;
5047 int rest = val - low;
5048
5049 operands[2] = GEN_INT (rest);
5050 operands[3] = GEN_INT (low);
5051 }")
5052
5053 (define_split
5054 [(set (match_operand:SI 0 "register_operand" "")
5055 (plus:SI (match_operand:SI 1 "register_operand" "")
5056 (match_operand:SI 2 "const_int_operand" "")))
5057 (clobber (match_operand:SI 4 "register_operand" ""))]
5058 "! pa_cint_ok_for_move (INTVAL (operands[2]))"
5059 [(set (match_dup 4) (match_dup 2))
5060 (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
5061 (match_dup 1)))]
5062 "
5063 {
5064 HOST_WIDE_INT intval = INTVAL (operands[2]);
5065
5066 /* Try dividing the constant by 2, then 4, and finally 8 to see
5067 if we can get a constant which can be loaded into a register
5068 in a single instruction (pa_cint_ok_for_move).
5069
5070 If that fails, try to negate the constant and subtract it
5071 from our input operand. */
5072 if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5073 {
5074 operands[2] = GEN_INT (intval / 2);
5075 operands[3] = const2_rtx;
5076 }
5077 else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5078 {
5079 operands[2] = GEN_INT (intval / 4);
5080 operands[3] = GEN_INT (4);
5081 }
5082 else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5083 {
5084 operands[2] = GEN_INT (intval / 8);
5085 operands[3] = GEN_INT (8);
5086 }
5087 else if (pa_cint_ok_for_move (-intval))
5088 {
5089 emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
5090 emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5091 DONE;
5092 }
5093 else
5094 FAIL;
5095 }")
5096
5097 (define_insn "addsi3"
5098 [(set (match_operand:SI 0 "register_operand" "=r,r")
5099 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5100 (match_operand:SI 2 "arith14_operand" "r,J")))]
5101 ""
5102 "@
5103 {addl|add,l} %1,%2,%0
5104 ldo %2(%1),%0"
5105 [(set_attr "type" "binary,binary")
5106 (set_attr "pa_combine_type" "addmove")
5107 (set_attr "length" "4,4")])
5108
5109 (define_insn "addvsi3"
5110 [(set (match_operand:SI 0 "register_operand" "=r,r")
5111 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5112 (match_operand:SI 2 "arith11_operand" "r,I")))
5113 (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5114 (sign_extend:DI (match_dup 2)))
5115 (sign_extend:DI (plus:SI (match_dup 1)
5116 (match_dup 2))))
5117 (const_int 0))]
5118 ""
5119 "@
5120 {addo|add,tsv} %2,%1,%0
5121 {addio|addi,tsv} %2,%1,%0"
5122 [(set_attr "type" "binary,binary")
5123 (set_attr "length" "4,4")])
5124
5125 (define_expand "subdi3"
5126 [(set (match_operand:DI 0 "register_operand" "")
5127 (minus:DI (match_operand:DI 1 "arith11_operand" "")
5128 (match_operand:DI 2 "reg_or_0_operand" "")))]
5129 ""
5130 "")
5131
5132 (define_insn ""
5133 [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5134 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5135 (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5136 "TARGET_64BIT"
5137 "@
5138 sub %1,%2,%0
5139 subi %1,%2,%0
5140 mtsarcm %2"
5141 [(set_attr "type" "binary,binary,move")
5142 (set_attr "length" "4,4,4")])
5143
5144 (define_insn ""
5145 [(set (match_operand:DI 0 "register_operand" "=r,&r")
5146 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5147 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5148 "!TARGET_64BIT"
5149 "*
5150 {
5151 if (GET_CODE (operands[1]) == CONST_INT)
5152 {
5153 if (INTVAL (operands[1]) >= 0)
5154 return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5155 else
5156 return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5157 }
5158 else
5159 return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5160 }"
5161 [(set_attr "type" "binary")
5162 (set (attr "length")
5163 (if_then_else (eq_attr "alternative" "0")
5164 (const_int 8)
5165 (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5166 (const_int 0))
5167 (const_int 8)
5168 (const_int 12))))])
5169
5170 (define_expand "subvdi3"
5171 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5172 (minus:DI (match_operand:DI 1 "arith11_operand" "")
5173 (match_operand:DI 2 "reg_or_0_operand" "")))
5174 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5175 (sign_extend:TI (match_dup 2)))
5176 (sign_extend:TI (minus:DI (match_dup 1)
5177 (match_dup 2))))
5178 (const_int 0))])]
5179 ""
5180 "")
5181
5182 (define_insn ""
5183 [(set (match_operand:DI 0 "register_operand" "=r,r")
5184 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5185 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5186 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5187 (sign_extend:TI (match_dup 2)))
5188 (sign_extend:TI (minus:DI (match_dup 1)
5189 (match_dup 2))))
5190 (const_int 0))]
5191 "TARGET_64BIT"
5192 "@
5193 {subo|sub,tsv} %1,%2,%0
5194 {subio|subi,tsv} %1,%2,%0"
5195 [(set_attr "type" "binary,binary")
5196 (set_attr "length" "4,4")])
5197
5198 (define_insn ""
5199 [(set (match_operand:DI 0 "register_operand" "=r,&r")
5200 (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5201 (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5202 (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5203 (sign_extend:TI (match_dup 2)))
5204 (sign_extend:TI (minus:DI (match_dup 1)
5205 (match_dup 2))))
5206 (const_int 0))]
5207 "!TARGET_64BIT"
5208 "*
5209 {
5210 if (GET_CODE (operands[1]) == CONST_INT)
5211 {
5212 if (INTVAL (operands[1]) >= 0)
5213 return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5214 else
5215 return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5216 }
5217 else
5218 return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5219 }"
5220 [(set_attr "type" "binary,binary")
5221 (set (attr "length")
5222 (if_then_else (eq_attr "alternative" "0")
5223 (const_int 8)
5224 (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5225 (const_int 0))
5226 (const_int 8)
5227 (const_int 12))))])
5228
5229 (define_expand "subsi3"
5230 [(set (match_operand:SI 0 "register_operand" "")
5231 (minus:SI (match_operand:SI 1 "arith11_operand" "")
5232 (match_operand:SI 2 "register_operand" "")))]
5233 ""
5234 "")
5235
5236 (define_insn ""
5237 [(set (match_operand:SI 0 "register_operand" "=r,r")
5238 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5239 (match_operand:SI 2 "register_operand" "r,r")))]
5240 "!TARGET_PA_20"
5241 "@
5242 sub %1,%2,%0
5243 subi %1,%2,%0"
5244 [(set_attr "type" "binary,binary")
5245 (set_attr "length" "4,4")])
5246
5247 (define_insn ""
5248 [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5249 (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5250 (match_operand:SI 2 "register_operand" "r,r,!r")))]
5251 "TARGET_PA_20"
5252 "@
5253 sub %1,%2,%0
5254 subi %1,%2,%0
5255 mtsarcm %2"
5256 [(set_attr "type" "binary,binary,move")
5257 (set_attr "length" "4,4,4")])
5258
5259 (define_insn "subvsi3"
5260 [(set (match_operand:SI 0 "register_operand" "=r,r")
5261 (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5262 (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5263 (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5264 (sign_extend:DI (match_dup 2)))
5265 (sign_extend:DI (minus:SI (match_dup 1)
5266 (match_dup 2))))
5267 (const_int 0))]
5268 ""
5269 "@
5270 {subo|sub,tsv} %1,%2,%0
5271 {subio|subi,tsv} %1,%2,%0"
5272 [(set_attr "type" "binary,binary")
5273 (set_attr "length" "4,4")])
5274
5275 ;; Clobbering a "register_operand" instead of a match_scratch
5276 ;; in operand3 of millicode calls avoids spilling %r1 and
5277 ;; produces better code.
5278
5279 ;; The mulsi3 insns set up registers for the millicode call.
5280 (define_expand "mulsi3"
5281 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5282 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5283 (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5284 (clobber (match_dup 3))
5285 (clobber (reg:SI 26))
5286 (clobber (reg:SI 25))
5287 (clobber (match_dup 4))])
5288 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5289 ""
5290 "
5291 {
5292 operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5293 if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5294 {
5295 rtx scratch = gen_reg_rtx (DImode);
5296 operands[1] = force_reg (SImode, operands[1]);
5297 operands[2] = force_reg (SImode, operands[2]);
5298 emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5299 emit_insn (gen_movsi (operands[0],
5300 gen_rtx_SUBREG (SImode, scratch,
5301 GET_MODE_SIZE (SImode))));
5302 DONE;
5303 }
5304 operands[3] = gen_reg_rtx (SImode);
5305 }")
5306
5307 (define_insn "umulsidi3"
5308 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5309 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5310 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
5311 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5312 "xmpyu %1,%2,%0"
5313 [(set_attr "type" "fpmuldbl")
5314 (set_attr "length" "4")])
5315
5316 (define_insn ""
5317 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5318 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5319 (match_operand:DI 2 "uint32_operand" "f")))]
5320 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5321 "xmpyu %1,%R2,%0"
5322 [(set_attr "type" "fpmuldbl")
5323 (set_attr "length" "4")])
5324
5325 (define_insn ""
5326 [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5327 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5328 (match_operand:DI 2 "uint32_operand" "f")))]
5329 "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5330 "xmpyu %1,%2R,%0"
5331 [(set_attr "type" "fpmuldbl")
5332 (set_attr "length" "4")])
5333
5334 (define_insn ""
5335 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5336 (clobber (match_operand:SI 0 "register_operand" "=a"))
5337 (clobber (reg:SI 26))
5338 (clobber (reg:SI 25))
5339 (clobber (reg:SI 31))]
5340 "!TARGET_64BIT"
5341 "* return pa_output_mul_insn (0, insn);"
5342 [(set_attr "type" "milli")
5343 (set (attr "length")
5344 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5345 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5346
5347 (define_insn ""
5348 [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5349 (clobber (match_operand:SI 0 "register_operand" "=a"))
5350 (clobber (reg:SI 26))
5351 (clobber (reg:SI 25))
5352 (clobber (reg:SI 2))]
5353 "TARGET_64BIT"
5354 "* return pa_output_mul_insn (0, insn);"
5355 [(set_attr "type" "milli")
5356 (set (attr "length")
5357 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5358 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5359
5360 (define_expand "muldi3"
5361 [(set (match_operand:DI 0 "register_operand" "")
5362 (mult:DI (match_operand:DI 1 "register_operand" "")
5363 (match_operand:DI 2 "register_operand" "")))]
5364 "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5365 "
5366 {
5367 rtx low_product = gen_reg_rtx (DImode);
5368 rtx cross_product1 = gen_reg_rtx (DImode);
5369 rtx cross_product2 = gen_reg_rtx (DImode);
5370 rtx cross_scratch = gen_reg_rtx (DImode);
5371 rtx cross_product = gen_reg_rtx (DImode);
5372 rtx op1l, op1r, op2l, op2r;
5373 rtx op1shifted, op2shifted;
5374
5375 op1shifted = gen_reg_rtx (DImode);
5376 op2shifted = gen_reg_rtx (DImode);
5377 op1l = gen_reg_rtx (SImode);
5378 op1r = gen_reg_rtx (SImode);
5379 op2l = gen_reg_rtx (SImode);
5380 op2r = gen_reg_rtx (SImode);
5381
5382 emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5383 GEN_INT (32)));
5384 emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5385 GEN_INT (32)));
5386 op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5387 op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5388 op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5389 op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5390
5391 /* Emit multiplies for the cross products. */
5392 emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5393 emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5394
5395 /* Emit a multiply for the low sub-word. */
5396 emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5397
5398 /* Sum the cross products and shift them into proper position. */
5399 emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5400 emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5401
5402 /* Add the cross product to the low product and store the result
5403 into the output operand . */
5404 emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5405 DONE;
5406 }")
5407
5408 ;;; Division and mod.
5409 (define_expand "divsi3"
5410 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5411 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5412 (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5413 (clobber (match_dup 3))
5414 (clobber (match_dup 4))
5415 (clobber (reg:SI 26))
5416 (clobber (reg:SI 25))
5417 (clobber (match_dup 5))])
5418 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5419 ""
5420 "
5421 {
5422 operands[3] = gen_reg_rtx (SImode);
5423 if (TARGET_64BIT)
5424 {
5425 operands[5] = gen_rtx_REG (SImode, 2);
5426 operands[4] = operands[5];
5427 }
5428 else
5429 {
5430 operands[5] = gen_rtx_REG (SImode, 31);
5431 operands[4] = gen_reg_rtx (SImode);
5432 }
5433 if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5434 DONE;
5435 }")
5436
5437 (define_insn ""
5438 [(set (reg:SI 29)
5439 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5440 (clobber (match_operand:SI 1 "register_operand" "=a"))
5441 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5442 (clobber (reg:SI 26))
5443 (clobber (reg:SI 25))
5444 (clobber (reg:SI 31))]
5445 "!TARGET_64BIT"
5446 "*
5447 return pa_output_div_insn (operands, 0, insn);"
5448 [(set_attr "type" "milli")
5449 (set (attr "length")
5450 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5451 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5452
5453 (define_insn ""
5454 [(set (reg:SI 29)
5455 (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5456 (clobber (match_operand:SI 1 "register_operand" "=a"))
5457 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5458 (clobber (reg:SI 26))
5459 (clobber (reg:SI 25))
5460 (clobber (reg:SI 2))]
5461 "TARGET_64BIT"
5462 "*
5463 return pa_output_div_insn (operands, 0, insn);"
5464 [(set_attr "type" "milli")
5465 (set (attr "length")
5466 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5467 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5468
5469 (define_expand "udivsi3"
5470 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5471 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5472 (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5473 (clobber (match_dup 3))
5474 (clobber (match_dup 4))
5475 (clobber (reg:SI 26))
5476 (clobber (reg:SI 25))
5477 (clobber (match_dup 5))])
5478 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5479 ""
5480 "
5481 {
5482 operands[3] = gen_reg_rtx (SImode);
5483
5484 if (TARGET_64BIT)
5485 {
5486 operands[5] = gen_rtx_REG (SImode, 2);
5487 operands[4] = operands[5];
5488 }
5489 else
5490 {
5491 operands[5] = gen_rtx_REG (SImode, 31);
5492 operands[4] = gen_reg_rtx (SImode);
5493 }
5494 if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5495 DONE;
5496 }")
5497
5498 (define_insn ""
5499 [(set (reg:SI 29)
5500 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5501 (clobber (match_operand:SI 1 "register_operand" "=a"))
5502 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5503 (clobber (reg:SI 26))
5504 (clobber (reg:SI 25))
5505 (clobber (reg:SI 31))]
5506 "!TARGET_64BIT"
5507 "*
5508 return pa_output_div_insn (operands, 1, insn);"
5509 [(set_attr "type" "milli")
5510 (set (attr "length")
5511 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5512 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5513
5514 (define_insn ""
5515 [(set (reg:SI 29)
5516 (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5517 (clobber (match_operand:SI 1 "register_operand" "=a"))
5518 (clobber (match_operand:SI 2 "register_operand" "=&r"))
5519 (clobber (reg:SI 26))
5520 (clobber (reg:SI 25))
5521 (clobber (reg:SI 2))]
5522 "TARGET_64BIT"
5523 "*
5524 return pa_output_div_insn (operands, 1, insn);"
5525 [(set_attr "type" "milli")
5526 (set (attr "length")
5527 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5528 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5529
5530 (define_expand "modsi3"
5531 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5532 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5533 (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5534 (clobber (match_dup 3))
5535 (clobber (match_dup 4))
5536 (clobber (reg:SI 26))
5537 (clobber (reg:SI 25))
5538 (clobber (match_dup 5))])
5539 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5540 ""
5541 "
5542 {
5543 if (TARGET_64BIT)
5544 {
5545 operands[5] = gen_rtx_REG (SImode, 2);
5546 operands[4] = operands[5];
5547 }
5548 else
5549 {
5550 operands[5] = gen_rtx_REG (SImode, 31);
5551 operands[4] = gen_reg_rtx (SImode);
5552 }
5553 operands[3] = gen_reg_rtx (SImode);
5554 }")
5555
5556 (define_insn ""
5557 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5558 (clobber (match_operand:SI 0 "register_operand" "=a"))
5559 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5560 (clobber (reg:SI 26))
5561 (clobber (reg:SI 25))
5562 (clobber (reg:SI 31))]
5563 "!TARGET_64BIT"
5564 "*
5565 return pa_output_mod_insn (0, insn);"
5566 [(set_attr "type" "milli")
5567 (set (attr "length")
5568 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5569 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5570
5571 (define_insn ""
5572 [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5573 (clobber (match_operand:SI 0 "register_operand" "=a"))
5574 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5575 (clobber (reg:SI 26))
5576 (clobber (reg:SI 25))
5577 (clobber (reg:SI 2))]
5578 "TARGET_64BIT"
5579 "*
5580 return pa_output_mod_insn (0, insn);"
5581 [(set_attr "type" "milli")
5582 (set (attr "length")
5583 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5584 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5585
5586 (define_expand "umodsi3"
5587 [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5588 (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5589 (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5590 (clobber (match_dup 3))
5591 (clobber (match_dup 4))
5592 (clobber (reg:SI 26))
5593 (clobber (reg:SI 25))
5594 (clobber (match_dup 5))])
5595 (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5596 ""
5597 "
5598 {
5599 if (TARGET_64BIT)
5600 {
5601 operands[5] = gen_rtx_REG (SImode, 2);
5602 operands[4] = operands[5];
5603 }
5604 else
5605 {
5606 operands[5] = gen_rtx_REG (SImode, 31);
5607 operands[4] = gen_reg_rtx (SImode);
5608 }
5609 operands[3] = gen_reg_rtx (SImode);
5610 }")
5611
5612 (define_insn ""
5613 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5614 (clobber (match_operand:SI 0 "register_operand" "=a"))
5615 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5616 (clobber (reg:SI 26))
5617 (clobber (reg:SI 25))
5618 (clobber (reg:SI 31))]
5619 "!TARGET_64BIT"
5620 "*
5621 return pa_output_mod_insn (1, insn);"
5622 [(set_attr "type" "milli")
5623 (set (attr "length")
5624 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5625 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5626
5627 (define_insn ""
5628 [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5629 (clobber (match_operand:SI 0 "register_operand" "=a"))
5630 (clobber (match_operand:SI 1 "register_operand" "=&r"))
5631 (clobber (reg:SI 26))
5632 (clobber (reg:SI 25))
5633 (clobber (reg:SI 2))]
5634 "TARGET_64BIT"
5635 "*
5636 return pa_output_mod_insn (1, insn);"
5637 [(set_attr "type" "milli")
5638 (set (attr "length")
5639 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
5640 (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5641
5642 ;;- and instructions
5643 ;; We define DImode `and` so with DImode `not` we can get
5644 ;; DImode `andn`. Other combinations are possible.
5645
5646 (define_expand "anddi3"
5647 [(set (match_operand:DI 0 "register_operand" "")
5648 (and:DI (match_operand:DI 1 "register_operand" "")
5649 (match_operand:DI 2 "and_operand" "")))]
5650 "TARGET_64BIT"
5651 "")
5652
5653 (define_insn ""
5654 [(set (match_operand:DI 0 "register_operand" "=r,r")
5655 (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5656 (match_operand:DI 2 "and_operand" "rO,P")))]
5657 "TARGET_64BIT"
5658 "* return pa_output_64bit_and (operands); "
5659 [(set_attr "type" "binary")
5660 (set_attr "length" "4")])
5661
5662 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5663 ; constant with ldil;ldo.
5664 (define_insn "andsi3"
5665 [(set (match_operand:SI 0 "register_operand" "=r,r")
5666 (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5667 (match_operand:SI 2 "and_operand" "rO,P")))]
5668 ""
5669 "* return pa_output_and (operands); "
5670 [(set_attr "type" "binary,shift")
5671 (set_attr "length" "4,4")])
5672
5673 (define_insn ""
5674 [(set (match_operand:DI 0 "register_operand" "=r")
5675 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5676 (match_operand:DI 2 "register_operand" "r")))]
5677 "TARGET_64BIT"
5678 "andcm %2,%1,%0"
5679 [(set_attr "type" "binary")
5680 (set_attr "length" "4")])
5681
5682 (define_insn ""
5683 [(set (match_operand:SI 0 "register_operand" "=r")
5684 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5685 (match_operand:SI 2 "register_operand" "r")))]
5686 ""
5687 "andcm %2,%1,%0"
5688 [(set_attr "type" "binary")
5689 (set_attr "length" "4")])
5690
5691 (define_expand "iordi3"
5692 [(set (match_operand:DI 0 "register_operand" "")
5693 (ior:DI (match_operand:DI 1 "register_operand" "")
5694 (match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5695 "TARGET_64BIT"
5696 "")
5697
5698 (define_insn ""
5699 [(set (match_operand:DI 0 "register_operand" "=r,r")
5700 (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5701 (match_operand:DI 2 "cint_ior_operand" "M,i")))]
5702 "TARGET_64BIT"
5703 "* return pa_output_64bit_ior (operands); "
5704 [(set_attr "type" "binary,shift")
5705 (set_attr "length" "4,4")])
5706
5707 (define_insn ""
5708 [(set (match_operand:DI 0 "register_operand" "=r")
5709 (ior:DI (match_operand:DI 1 "register_operand" "%r")
5710 (match_operand:DI 2 "register_operand" "r")))]
5711 "TARGET_64BIT"
5712 "or %1,%2,%0"
5713 [(set_attr "type" "binary")
5714 (set_attr "length" "4")])
5715
5716 ;; Need a define_expand because we've run out of CONST_OK... characters.
5717 (define_expand "iorsi3"
5718 [(set (match_operand:SI 0 "register_operand" "")
5719 (ior:SI (match_operand:SI 1 "register_operand" "")
5720 (match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5721 ""
5722 "")
5723
5724 (define_insn ""
5725 [(set (match_operand:SI 0 "register_operand" "=r,r")
5726 (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5727 (match_operand:SI 2 "cint_ior_operand" "M,i")))]
5728 ""
5729 "* return pa_output_ior (operands); "
5730 [(set_attr "type" "binary,shift")
5731 (set_attr "length" "4,4")])
5732
5733 (define_insn ""
5734 [(set (match_operand:SI 0 "register_operand" "=r")
5735 (ior:SI (match_operand:SI 1 "register_operand" "%r")
5736 (match_operand:SI 2 "register_operand" "r")))]
5737 ""
5738 "or %1,%2,%0"
5739 [(set_attr "type" "binary")
5740 (set_attr "length" "4")])
5741
5742 (define_expand "xordi3"
5743 [(set (match_operand:DI 0 "register_operand" "")
5744 (xor:DI (match_operand:DI 1 "register_operand" "")
5745 (match_operand:DI 2 "register_operand" "")))]
5746 "TARGET_64BIT"
5747 "")
5748
5749 (define_insn ""
5750 [(set (match_operand:DI 0 "register_operand" "=r")
5751 (xor:DI (match_operand:DI 1 "register_operand" "%r")
5752 (match_operand:DI 2 "register_operand" "r")))]
5753 "TARGET_64BIT"
5754 "xor %1,%2,%0"
5755 [(set_attr "type" "binary")
5756 (set_attr "length" "4")])
5757
5758 (define_insn "xorsi3"
5759 [(set (match_operand:SI 0 "register_operand" "=r")
5760 (xor:SI (match_operand:SI 1 "register_operand" "%r")
5761 (match_operand:SI 2 "register_operand" "r")))]
5762 ""
5763 "xor %1,%2,%0"
5764 [(set_attr "type" "binary")
5765 (set_attr "length" "4")])
5766
5767 (define_expand "negdi2"
5768 [(set (match_operand:DI 0 "register_operand" "")
5769 (neg:DI (match_operand:DI 1 "register_operand" "")))]
5770 ""
5771 "")
5772
5773 (define_insn ""
5774 [(set (match_operand:DI 0 "register_operand" "=r")
5775 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5776 "!TARGET_64BIT"
5777 "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5778 [(set_attr "type" "unary")
5779 (set_attr "length" "8")])
5780
5781 (define_insn ""
5782 [(set (match_operand:DI 0 "register_operand" "=r")
5783 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5784 "TARGET_64BIT"
5785 "sub %%r0,%1,%0"
5786 [(set_attr "type" "unary")
5787 (set_attr "length" "4")])
5788
5789 (define_expand "negvdi2"
5790 [(parallel [(set (match_operand:DI 0 "register_operand" "")
5791 (neg:DI (match_operand:DI 1 "register_operand" "")))
5792 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5793 (sign_extend:TI (neg:DI (match_dup 1))))
5794 (const_int 0))])]
5795 ""
5796 "")
5797
5798 (define_insn ""
5799 [(set (match_operand:DI 0 "register_operand" "=r")
5800 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5801 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5802 (sign_extend:TI (neg:DI (match_dup 1))))
5803 (const_int 0))]
5804 "!TARGET_64BIT"
5805 "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5806 [(set_attr "type" "unary")
5807 (set_attr "length" "8")])
5808
5809 (define_insn ""
5810 [(set (match_operand:DI 0 "register_operand" "=r")
5811 (neg:DI (match_operand:DI 1 "register_operand" "r")))
5812 (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5813 (sign_extend:TI (neg:DI (match_dup 1))))
5814 (const_int 0))]
5815 "TARGET_64BIT"
5816 "sub,tsv %%r0,%1,%0"
5817 [(set_attr "type" "unary")
5818 (set_attr "length" "4")])
5819
5820 (define_insn "negsi2"
5821 [(set (match_operand:SI 0 "register_operand" "=r")
5822 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
5823 ""
5824 "sub %%r0,%1,%0"
5825 [(set_attr "type" "unary")
5826 (set_attr "length" "4")])
5827
5828 (define_insn "negvsi2"
5829 [(set (match_operand:SI 0 "register_operand" "=r")
5830 (neg:SI (match_operand:SI 1 "register_operand" "r")))
5831 (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
5832 (sign_extend:DI (neg:SI (match_dup 1))))
5833 (const_int 0))]
5834 ""
5835 "{subo|sub,tsv} %%r0,%1,%0"
5836 [(set_attr "type" "unary")
5837 (set_attr "length" "4")])
5838
5839 (define_expand "one_cmpldi2"
5840 [(set (match_operand:DI 0 "register_operand" "")
5841 (not:DI (match_operand:DI 1 "register_operand" "")))]
5842 ""
5843 "
5844 {
5845 }")
5846
5847 (define_insn ""
5848 [(set (match_operand:DI 0 "register_operand" "=r")
5849 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5850 "!TARGET_64BIT"
5851 "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5852 [(set_attr "type" "unary")
5853 (set_attr "length" "8")])
5854
5855 (define_insn ""
5856 [(set (match_operand:DI 0 "register_operand" "=r")
5857 (not:DI (match_operand:DI 1 "register_operand" "r")))]
5858 "TARGET_64BIT"
5859 "uaddcm %%r0,%1,%0"
5860 [(set_attr "type" "unary")
5861 (set_attr "length" "4")])
5862
5863 (define_insn "one_cmplsi2"
5864 [(set (match_operand:SI 0 "register_operand" "=r")
5865 (not:SI (match_operand:SI 1 "register_operand" "r")))]
5866 ""
5867 "uaddcm %%r0,%1,%0"
5868 [(set_attr "type" "unary")
5869 (set_attr "length" "4")])
5870 \f
5871 ;; Floating point arithmetic instructions.
5872
5873 (define_insn "adddf3"
5874 [(set (match_operand:DF 0 "register_operand" "=f")
5875 (plus:DF (match_operand:DF 1 "register_operand" "f")
5876 (match_operand:DF 2 "register_operand" "f")))]
5877 "! TARGET_SOFT_FLOAT"
5878 "fadd,dbl %1,%2,%0"
5879 [(set_attr "type" "fpalu")
5880 (set_attr "pa_combine_type" "faddsub")
5881 (set_attr "length" "4")])
5882
5883 (define_insn "addsf3"
5884 [(set (match_operand:SF 0 "register_operand" "=f")
5885 (plus:SF (match_operand:SF 1 "register_operand" "f")
5886 (match_operand:SF 2 "register_operand" "f")))]
5887 "! TARGET_SOFT_FLOAT"
5888 "fadd,sgl %1,%2,%0"
5889 [(set_attr "type" "fpalu")
5890 (set_attr "pa_combine_type" "faddsub")
5891 (set_attr "length" "4")])
5892
5893 (define_insn "subdf3"
5894 [(set (match_operand:DF 0 "register_operand" "=f")
5895 (minus:DF (match_operand:DF 1 "register_operand" "f")
5896 (match_operand:DF 2 "register_operand" "f")))]
5897 "! TARGET_SOFT_FLOAT"
5898 "fsub,dbl %1,%2,%0"
5899 [(set_attr "type" "fpalu")
5900 (set_attr "pa_combine_type" "faddsub")
5901 (set_attr "length" "4")])
5902
5903 (define_insn "subsf3"
5904 [(set (match_operand:SF 0 "register_operand" "=f")
5905 (minus:SF (match_operand:SF 1 "register_operand" "f")
5906 (match_operand:SF 2 "register_operand" "f")))]
5907 "! TARGET_SOFT_FLOAT"
5908 "fsub,sgl %1,%2,%0"
5909 [(set_attr "type" "fpalu")
5910 (set_attr "pa_combine_type" "faddsub")
5911 (set_attr "length" "4")])
5912
5913 (define_insn "muldf3"
5914 [(set (match_operand:DF 0 "register_operand" "=f")
5915 (mult:DF (match_operand:DF 1 "register_operand" "f")
5916 (match_operand:DF 2 "register_operand" "f")))]
5917 "! TARGET_SOFT_FLOAT"
5918 "fmpy,dbl %1,%2,%0"
5919 [(set_attr "type" "fpmuldbl")
5920 (set_attr "pa_combine_type" "fmpy")
5921 (set_attr "length" "4")])
5922
5923 (define_insn "mulsf3"
5924 [(set (match_operand:SF 0 "register_operand" "=f")
5925 (mult:SF (match_operand:SF 1 "register_operand" "f")
5926 (match_operand:SF 2 "register_operand" "f")))]
5927 "! TARGET_SOFT_FLOAT"
5928 "fmpy,sgl %1,%2,%0"
5929 [(set_attr "type" "fpmulsgl")
5930 (set_attr "pa_combine_type" "fmpy")
5931 (set_attr "length" "4")])
5932
5933 (define_insn "divdf3"
5934 [(set (match_operand:DF 0 "register_operand" "=f")
5935 (div:DF (match_operand:DF 1 "register_operand" "f")
5936 (match_operand:DF 2 "register_operand" "f")))]
5937 "! TARGET_SOFT_FLOAT"
5938 "fdiv,dbl %1,%2,%0"
5939 [(set_attr "type" "fpdivdbl")
5940 (set_attr "length" "4")])
5941
5942 (define_insn "divsf3"
5943 [(set (match_operand:SF 0 "register_operand" "=f")
5944 (div:SF (match_operand:SF 1 "register_operand" "f")
5945 (match_operand:SF 2 "register_operand" "f")))]
5946 "! TARGET_SOFT_FLOAT"
5947 "fdiv,sgl %1,%2,%0"
5948 [(set_attr "type" "fpdivsgl")
5949 (set_attr "length" "4")])
5950
5951 ;; Processors prior to PA 2.0 don't have a fneg instruction. Fast
5952 ;; negation can be done by subtracting from plus zero. However, this
5953 ;; violates the IEEE standard when negating plus and minus zero.
5954 ;; The slow path toggles the sign bit in the general registers.
5955 (define_expand "negdf2"
5956 [(set (match_operand:DF 0 "register_operand" "")
5957 (neg:DF (match_operand:DF 1 "register_operand" "")))]
5958 "!TARGET_SOFT_FLOAT"
5959 {
5960 if (TARGET_PA_20 || !flag_signed_zeros)
5961 emit_insn (gen_negdf2_fast (operands[0], operands[1]));
5962 else
5963 emit_insn (gen_negdf2_slow (operands[0], operands[1]));
5964 DONE;
5965 })
5966
5967 (define_insn "negdf2_slow"
5968 [(set (match_operand:DF 0 "register_operand" "=r")
5969 (neg:DF (match_operand:DF 1 "register_operand" "r")))]
5970 "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
5971 "*
5972 {
5973 if (rtx_equal_p (operands[0], operands[1]))
5974 return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
5975 else
5976 return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
5977 }"
5978 [(set_attr "type" "multi")
5979 (set (attr "length")
5980 (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
5981 (const_int 12)
5982 (const_int 16)))])
5983
5984 (define_insn "negdf2_fast"
5985 [(set (match_operand:DF 0 "register_operand" "=f")
5986 (neg:DF (match_operand:DF 1 "register_operand" "f")))]
5987 "!TARGET_SOFT_FLOAT"
5988 "*
5989 {
5990 if (TARGET_PA_20)
5991 return \"fneg,dbl %1,%0\";
5992 else
5993 return \"fsub,dbl %%fr0,%1,%0\";
5994 }"
5995 [(set_attr "type" "fpalu")
5996 (set_attr "length" "4")])
5997
5998 (define_expand "negsf2"
5999 [(set (match_operand:SF 0 "register_operand" "")
6000 (neg:SF (match_operand:SF 1 "register_operand" "")))]
6001 "!TARGET_SOFT_FLOAT"
6002 {
6003 if (TARGET_PA_20 || !flag_signed_zeros)
6004 emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6005 else
6006 emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6007 DONE;
6008 })
6009
6010 (define_insn "negsf2_slow"
6011 [(set (match_operand:SF 0 "register_operand" "=r")
6012 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
6013 "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6014 "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6015 [(set_attr "type" "multi")
6016 (set_attr "length" "12")])
6017
6018 (define_insn "negsf2_fast"
6019 [(set (match_operand:SF 0 "register_operand" "=f")
6020 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6021 "!TARGET_SOFT_FLOAT"
6022 "*
6023 {
6024 if (TARGET_PA_20)
6025 return \"fneg,sgl %1,%0\";
6026 else
6027 return \"fsub,sgl %%fr0,%1,%0\";
6028 }"
6029 [(set_attr "type" "fpalu")
6030 (set_attr "length" "4")])
6031
6032 (define_insn "absdf2"
6033 [(set (match_operand:DF 0 "register_operand" "=f")
6034 (abs:DF (match_operand:DF 1 "register_operand" "f")))]
6035 "! TARGET_SOFT_FLOAT"
6036 "fabs,dbl %1,%0"
6037 [(set_attr "type" "fpalu")
6038 (set_attr "length" "4")])
6039
6040 (define_insn "abssf2"
6041 [(set (match_operand:SF 0 "register_operand" "=f")
6042 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6043 "! TARGET_SOFT_FLOAT"
6044 "fabs,sgl %1,%0"
6045 [(set_attr "type" "fpalu")
6046 (set_attr "length" "4")])
6047
6048 (define_insn "sqrtdf2"
6049 [(set (match_operand:DF 0 "register_operand" "=f")
6050 (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6051 "! TARGET_SOFT_FLOAT"
6052 "fsqrt,dbl %1,%0"
6053 [(set_attr "type" "fpsqrtdbl")
6054 (set_attr "length" "4")])
6055
6056 (define_insn "sqrtsf2"
6057 [(set (match_operand:SF 0 "register_operand" "=f")
6058 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6059 "! TARGET_SOFT_FLOAT"
6060 "fsqrt,sgl %1,%0"
6061 [(set_attr "type" "fpsqrtsgl")
6062 (set_attr "length" "4")])
6063
6064 ;; PA 2.0 floating point instructions
6065
6066 ; fmpyfadd patterns
6067 (define_insn "fmadf4"
6068 [(set (match_operand:DF 0 "register_operand" "=f")
6069 (fma:DF (match_operand:DF 1 "register_operand" "f")
6070 (match_operand:DF 2 "register_operand" "f")
6071 (match_operand:DF 3 "register_operand" "f")))]
6072 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6073 "fmpyfadd,dbl %1,%2,%3,%0"
6074 [(set_attr "type" "fpmuldbl")
6075 (set_attr "length" "4")])
6076
6077 (define_insn "fmasf4"
6078 [(set (match_operand:SF 0 "register_operand" "=f")
6079 (fma:SF (match_operand:SF 1 "register_operand" "f")
6080 (match_operand:SF 2 "register_operand" "f")
6081 (match_operand:SF 3 "register_operand" "f")))]
6082 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6083 "fmpyfadd,sgl %1,%2,%3,%0"
6084 [(set_attr "type" "fpmulsgl")
6085 (set_attr "length" "4")])
6086
6087 ; fmpynfadd patterns
6088 (define_insn "fnmadf4"
6089 [(set (match_operand:DF 0 "register_operand" "=f")
6090 (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6091 (match_operand:DF 2 "register_operand" "f")
6092 (match_operand:DF 3 "register_operand" "f")))]
6093 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6094 "fmpynfadd,dbl %1,%2,%3,%0"
6095 [(set_attr "type" "fpmuldbl")
6096 (set_attr "length" "4")])
6097
6098 (define_insn "fnmasf4"
6099 [(set (match_operand:SF 0 "register_operand" "=f")
6100 (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6101 (match_operand:SF 2 "register_operand" "f")
6102 (match_operand:SF 3 "register_operand" "f")))]
6103 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6104 "fmpynfadd,sgl %1,%2,%3,%0"
6105 [(set_attr "type" "fpmulsgl")
6106 (set_attr "length" "4")])
6107
6108 ; fnegabs patterns
6109 (define_insn ""
6110 [(set (match_operand:DF 0 "register_operand" "=f")
6111 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6112 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6113 "fnegabs,dbl %1,%0"
6114 [(set_attr "type" "fpalu")
6115 (set_attr "length" "4")])
6116
6117 (define_insn ""
6118 [(set (match_operand:SF 0 "register_operand" "=f")
6119 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6120 "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6121 "fnegabs,sgl %1,%0"
6122 [(set_attr "type" "fpalu")
6123 (set_attr "length" "4")])
6124
6125 (define_insn ""
6126 [(set (match_operand:DF 0 "register_operand" "=f")
6127 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6128 (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6129 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6130 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6131 "#"
6132 [(set_attr "type" "fpalu")
6133 (set_attr "length" "8")])
6134
6135 (define_split
6136 [(set (match_operand:DF 0 "register_operand" "")
6137 (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6138 (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6139 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6140 [(set (match_dup 2) (abs:DF (match_dup 1)))
6141 (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6142 "")
6143
6144 (define_insn ""
6145 [(set (match_operand:SF 0 "register_operand" "=f")
6146 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6147 (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6148 "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6149 && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6150 "#"
6151 [(set_attr "type" "fpalu")
6152 (set_attr "length" "8")])
6153
6154 (define_split
6155 [(set (match_operand:SF 0 "register_operand" "")
6156 (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6157 (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6158 "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6159 [(set (match_dup 2) (abs:SF (match_dup 1)))
6160 (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6161 "")
6162
6163 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6164 ;; instruction if we can ignore the sign of zero.
6165 (define_insn ""
6166 [(set (match_operand:DF 0 "register_operand" "=f")
6167 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6168 (match_operand:DF 2 "register_operand" "f"))))]
6169 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6170 "fmpynfadd,dbl %1,%2,%%fr0,%0"
6171 [(set_attr "type" "fpmuldbl")
6172 (set_attr "length" "4")])
6173
6174 (define_insn ""
6175 [(set (match_operand:SF 0 "register_operand" "=f")
6176 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6177 (match_operand:SF 2 "register_operand" "f"))))]
6178 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6179 "fmpynfadd,sgl %1,%2,%%fr0,%0"
6180 [(set_attr "type" "fpmuldbl")
6181 (set_attr "length" "4")])
6182
6183 (define_insn ""
6184 [(set (match_operand:DF 0 "register_operand" "=f")
6185 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6186 (match_operand:DF 2 "register_operand" "f"))))
6187 (set (match_operand:DF 3 "register_operand" "=&f")
6188 (mult:DF (match_dup 1) (match_dup 2)))]
6189 "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6190 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6191 || reg_overlap_mentioned_p (operands[3], operands[2])))"
6192 "#"
6193 [(set_attr "type" "fpmuldbl")
6194 (set_attr "length" "8")])
6195
6196 (define_split
6197 [(set (match_operand:DF 0 "register_operand" "")
6198 (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6199 (match_operand:DF 2 "register_operand" ""))))
6200 (set (match_operand:DF 3 "register_operand" "")
6201 (mult:DF (match_dup 1) (match_dup 2)))]
6202 "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6203 [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6204 (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6205 "")
6206
6207 (define_insn ""
6208 [(set (match_operand:SF 0 "register_operand" "=f")
6209 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6210 (match_operand:SF 2 "register_operand" "f"))))
6211 (set (match_operand:SF 3 "register_operand" "=&f")
6212 (mult:SF (match_dup 1) (match_dup 2)))]
6213 "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6214 && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6215 || reg_overlap_mentioned_p (operands[3], operands[2])))"
6216 "#"
6217 [(set_attr "type" "fpmuldbl")
6218 (set_attr "length" "8")])
6219
6220 (define_split
6221 [(set (match_operand:SF 0 "register_operand" "")
6222 (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6223 (match_operand:SF 2 "register_operand" ""))))
6224 (set (match_operand:SF 3 "register_operand" "")
6225 (mult:SF (match_dup 1) (match_dup 2)))]
6226 "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6227 [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6228 (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6229 "")
6230 \f
6231 ;;- Shift instructions
6232
6233 ;; Optimized special case of shifting.
6234
6235 (define_insn ""
6236 [(set (match_operand:SI 0 "register_operand" "=r")
6237 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6238 (const_int 24)))]
6239 ""
6240 "ldb%M1 %1,%0"
6241 [(set_attr "type" "load")
6242 (set_attr "length" "4")])
6243
6244 (define_insn ""
6245 [(set (match_operand:SI 0 "register_operand" "=r")
6246 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6247 (const_int 16)))]
6248 ""
6249 "ldh%M1 %1,%0"
6250 [(set_attr "type" "load")
6251 (set_attr "length" "4")])
6252
6253 (define_insn ""
6254 [(set (match_operand:SI 0 "register_operand" "=r")
6255 (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6256 (match_operand:SI 3 "shadd_operand" ""))
6257 (match_operand:SI 1 "register_operand" "r")))]
6258 ""
6259 "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
6260 [(set_attr "type" "binary")
6261 (set_attr "length" "4")])
6262
6263 (define_insn ""
6264 [(set (match_operand:DI 0 "register_operand" "=r")
6265 (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6266 (match_operand:DI 3 "shadd_operand" ""))
6267 (match_operand:DI 1 "register_operand" "r")))]
6268 "TARGET_64BIT"
6269 "shladd,l %2,%O3,%1,%0"
6270 [(set_attr "type" "binary")
6271 (set_attr "length" "4")])
6272
6273 (define_expand "ashlsi3"
6274 [(set (match_operand:SI 0 "register_operand" "")
6275 (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6276 (match_operand:SI 2 "arith32_operand" "")))]
6277 ""
6278 "
6279 {
6280 if (GET_CODE (operands[2]) != CONST_INT)
6281 {
6282 rtx temp = gen_reg_rtx (SImode);
6283 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6284 if (GET_CODE (operands[1]) == CONST_INT)
6285 emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6286 else
6287 emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6288 DONE;
6289 }
6290 /* Make sure both inputs are not constants,
6291 there are no patterns for that. */
6292 operands[1] = force_reg (SImode, operands[1]);
6293 }")
6294
6295 (define_insn ""
6296 [(set (match_operand:SI 0 "register_operand" "=r")
6297 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6298 (match_operand:SI 2 "const_int_operand" "n")))]
6299 ""
6300 "{zdep|depw,z} %1,%P2,%L2,%0"
6301 [(set_attr "type" "shift")
6302 (set_attr "length" "4")])
6303
6304 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6305 ; Doing it like this makes slightly better code since reload can
6306 ; replace a register with a known value in range -16..15 with a
6307 ; constant. Ideally, we would like to merge zvdep32 and zvdep_imm32,
6308 ; but since we have no more CONST_OK... characters, that is not
6309 ; possible.
6310 (define_insn "zvdep32"
6311 [(set (match_operand:SI 0 "register_operand" "=r,r")
6312 (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6313 (minus:SI (const_int 31)
6314 (match_operand:SI 2 "register_operand" "q,q"))))]
6315 ""
6316 "@
6317 {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6318 {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6319 [(set_attr "type" "shift,shift")
6320 (set_attr "length" "4,4")])
6321
6322 (define_insn "zvdep_imm32"
6323 [(set (match_operand:SI 0 "register_operand" "=r")
6324 (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6325 (minus:SI (const_int 31)
6326 (match_operand:SI 2 "register_operand" "q"))))]
6327 ""
6328 "*
6329 {
6330 unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6331 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6332 operands[1] = GEN_INT ((x & 0xf) - 0x10);
6333 return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6334 }"
6335 [(set_attr "type" "shift")
6336 (set_attr "length" "4")])
6337
6338 (define_insn "vdepi_ior"
6339 [(set (match_operand:SI 0 "register_operand" "=r")
6340 (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6341 (minus:SI (const_int 31)
6342 (match_operand:SI 2 "register_operand" "q")))
6343 (match_operand:SI 3 "register_operand" "0")))]
6344 ; accept ...0001...1, can this be generalized?
6345 "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6346 "*
6347 {
6348 HOST_WIDE_INT x = INTVAL (operands[1]);
6349 operands[2] = GEN_INT (exact_log2 (x + 1));
6350 return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6351 }"
6352 [(set_attr "type" "shift")
6353 (set_attr "length" "4")])
6354
6355 (define_insn "vdepi_and"
6356 [(set (match_operand:SI 0 "register_operand" "=r")
6357 (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6358 (minus:SI (const_int 31)
6359 (match_operand:SI 2 "register_operand" "q")))
6360 (match_operand:SI 3 "register_operand" "0")))]
6361 ; this can be generalized...!
6362 "INTVAL (operands[1]) == -2"
6363 "*
6364 {
6365 HOST_WIDE_INT x = INTVAL (operands[1]);
6366 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6367 return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6368 }"
6369 [(set_attr "type" "shift")
6370 (set_attr "length" "4")])
6371
6372 (define_expand "ashldi3"
6373 [(set (match_operand:DI 0 "register_operand" "")
6374 (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6375 (match_operand:DI 2 "arith32_operand" "")))]
6376 "TARGET_64BIT"
6377 "
6378 {
6379 if (GET_CODE (operands[2]) != CONST_INT)
6380 {
6381 rtx temp = gen_reg_rtx (DImode);
6382 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6383 if (GET_CODE (operands[1]) == CONST_INT)
6384 emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6385 else
6386 emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6387 DONE;
6388 }
6389 /* Make sure both inputs are not constants,
6390 there are no patterns for that. */
6391 operands[1] = force_reg (DImode, operands[1]);
6392 }")
6393
6394 (define_insn ""
6395 [(set (match_operand:DI 0 "register_operand" "=r")
6396 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6397 (match_operand:DI 2 "const_int_operand" "n")))]
6398 "TARGET_64BIT"
6399 "depd,z %1,%p2,%Q2,%0"
6400 [(set_attr "type" "shift")
6401 (set_attr "length" "4")])
6402
6403 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6404 ; Doing it like this makes slightly better code since reload can
6405 ; replace a register with a known value in range -16..15 with a
6406 ; constant. Ideally, we would like to merge zvdep64 and zvdep_imm64,
6407 ; but since we have no more CONST_OK... characters, that is not
6408 ; possible.
6409 (define_insn "zvdep64"
6410 [(set (match_operand:DI 0 "register_operand" "=r,r")
6411 (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6412 (minus:DI (const_int 63)
6413 (match_operand:DI 2 "register_operand" "q,q"))))]
6414 "TARGET_64BIT"
6415 "@
6416 depd,z %1,%%sar,64,%0
6417 depdi,z %1,%%sar,64,%0"
6418 [(set_attr "type" "shift,shift")
6419 (set_attr "length" "4,4")])
6420
6421 (define_insn "zvdep_imm64"
6422 [(set (match_operand:DI 0 "register_operand" "=r")
6423 (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6424 (minus:DI (const_int 63)
6425 (match_operand:DI 2 "register_operand" "q"))))]
6426 "TARGET_64BIT"
6427 "*
6428 {
6429 unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6430 operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6431 operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6432 return \"depdi,z %1,%%sar,%2,%0\";
6433 }"
6434 [(set_attr "type" "shift")
6435 (set_attr "length" "4")])
6436
6437 (define_insn ""
6438 [(set (match_operand:DI 0 "register_operand" "=r")
6439 (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6440 (minus:DI (const_int 63)
6441 (match_operand:DI 2 "register_operand" "q")))
6442 (match_operand:DI 3 "register_operand" "0")))]
6443 ; accept ...0001...1, can this be generalized?
6444 "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6445 "*
6446 {
6447 HOST_WIDE_INT x = INTVAL (operands[1]);
6448 operands[2] = GEN_INT (exact_log2 (x + 1));
6449 return \"depdi -1,%%sar,%2,%0\";
6450 }"
6451 [(set_attr "type" "shift")
6452 (set_attr "length" "4")])
6453
6454 (define_insn ""
6455 [(set (match_operand:DI 0 "register_operand" "=r")
6456 (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6457 (minus:DI (const_int 63)
6458 (match_operand:DI 2 "register_operand" "q")))
6459 (match_operand:DI 3 "register_operand" "0")))]
6460 ; this can be generalized...!
6461 "TARGET_64BIT && INTVAL (operands[1]) == -2"
6462 "*
6463 {
6464 HOST_WIDE_INT x = INTVAL (operands[1]);
6465 operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6466 return \"depdi 0,%%sar,%2,%0\";
6467 }"
6468 [(set_attr "type" "shift")
6469 (set_attr "length" "4")])
6470
6471 (define_expand "ashrsi3"
6472 [(set (match_operand:SI 0 "register_operand" "")
6473 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6474 (match_operand:SI 2 "arith32_operand" "")))]
6475 ""
6476 "
6477 {
6478 if (GET_CODE (operands[2]) != CONST_INT)
6479 {
6480 rtx temp = gen_reg_rtx (SImode);
6481 emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6482 emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6483 DONE;
6484 }
6485 }")
6486
6487 (define_insn ""
6488 [(set (match_operand:SI 0 "register_operand" "=r")
6489 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6490 (match_operand:SI 2 "const_int_operand" "n")))]
6491 ""
6492 "{extrs|extrw,s} %1,%P2,%L2,%0"
6493 [(set_attr "type" "shift")
6494 (set_attr "length" "4")])
6495
6496 (define_insn "vextrs32"
6497 [(set (match_operand:SI 0 "register_operand" "=r")
6498 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6499 (minus:SI (const_int 31)
6500 (match_operand:SI 2 "register_operand" "q"))))]
6501 ""
6502 "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6503 [(set_attr "type" "shift")
6504 (set_attr "length" "4")])
6505
6506 (define_expand "ashrdi3"
6507 [(set (match_operand:DI 0 "register_operand" "")
6508 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6509 (match_operand:DI 2 "arith32_operand" "")))]
6510 "TARGET_64BIT"
6511 "
6512 {
6513 if (GET_CODE (operands[2]) != CONST_INT)
6514 {
6515 rtx temp = gen_reg_rtx (DImode);
6516 emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6517 emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6518 DONE;
6519 }
6520 }")
6521
6522 (define_insn ""
6523 [(set (match_operand:DI 0 "register_operand" "=r")
6524 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6525 (match_operand:DI 2 "const_int_operand" "n")))]
6526 "TARGET_64BIT"
6527 "extrd,s %1,%p2,%Q2,%0"
6528 [(set_attr "type" "shift")
6529 (set_attr "length" "4")])
6530
6531 (define_insn "vextrs64"
6532 [(set (match_operand:DI 0 "register_operand" "=r")
6533 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6534 (minus:DI (const_int 63)
6535 (match_operand:DI 2 "register_operand" "q"))))]
6536 "TARGET_64BIT"
6537 "extrd,s %1,%%sar,64,%0"
6538 [(set_attr "type" "shift")
6539 (set_attr "length" "4")])
6540
6541 (define_insn "lshrsi3"
6542 [(set (match_operand:SI 0 "register_operand" "=r,r")
6543 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6544 (match_operand:SI 2 "arith32_operand" "q,n")))]
6545 ""
6546 "@
6547 {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6548 {extru|extrw,u} %1,%P2,%L2,%0"
6549 [(set_attr "type" "shift")
6550 (set_attr "length" "4")])
6551
6552 (define_insn "lshrdi3"
6553 [(set (match_operand:DI 0 "register_operand" "=r,r")
6554 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6555 (match_operand:DI 2 "arith32_operand" "q,n")))]
6556 "TARGET_64BIT"
6557 "@
6558 shrpd %%r0,%1,%%sar,%0
6559 extrd,u %1,%p2,%Q2,%0"
6560 [(set_attr "type" "shift")
6561 (set_attr "length" "4")])
6562
6563 (define_insn "rotrsi3"
6564 [(set (match_operand:SI 0 "register_operand" "=r,r")
6565 (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6566 (match_operand:SI 2 "arith32_operand" "q,n")))]
6567 ""
6568 "*
6569 {
6570 if (GET_CODE (operands[2]) == CONST_INT)
6571 {
6572 operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6573 return \"{shd|shrpw} %1,%1,%2,%0\";
6574 }
6575 else
6576 return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6577 }"
6578 [(set_attr "type" "shift")
6579 (set_attr "length" "4")])
6580
6581 (define_expand "rotlsi3"
6582 [(set (match_operand:SI 0 "register_operand" "")
6583 (rotate:SI (match_operand:SI 1 "register_operand" "")
6584 (match_operand:SI 2 "arith32_operand" "")))]
6585 ""
6586 "
6587 {
6588 if (GET_CODE (operands[2]) != CONST_INT)
6589 {
6590 rtx temp = gen_reg_rtx (SImode);
6591 emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6592 emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6593 DONE;
6594 }
6595 /* Else expand normally. */
6596 }")
6597
6598 (define_insn ""
6599 [(set (match_operand:SI 0 "register_operand" "=r")
6600 (rotate:SI (match_operand:SI 1 "register_operand" "r")
6601 (match_operand:SI 2 "const_int_operand" "n")))]
6602 ""
6603 "*
6604 {
6605 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6606 return \"{shd|shrpw} %1,%1,%2,%0\";
6607 }"
6608 [(set_attr "type" "shift")
6609 (set_attr "length" "4")])
6610
6611 (define_insn ""
6612 [(set (match_operand:SI 0 "register_operand" "=r")
6613 (match_operator:SI 5 "plus_xor_ior_operator"
6614 [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6615 (match_operand:SI 3 "const_int_operand" "n"))
6616 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6617 (match_operand:SI 4 "const_int_operand" "n"))]))]
6618 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6619 "{shd|shrpw} %1,%2,%4,%0"
6620 [(set_attr "type" "shift")
6621 (set_attr "length" "4")])
6622
6623 (define_insn ""
6624 [(set (match_operand:SI 0 "register_operand" "=r")
6625 (match_operator:SI 5 "plus_xor_ior_operator"
6626 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6627 (match_operand:SI 4 "const_int_operand" "n"))
6628 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6629 (match_operand:SI 3 "const_int_operand" "n"))]))]
6630 "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6631 "{shd|shrpw} %1,%2,%4,%0"
6632 [(set_attr "type" "shift")
6633 (set_attr "length" "4")])
6634
6635 (define_insn ""
6636 [(set (match_operand:SI 0 "register_operand" "=r")
6637 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6638 (match_operand:SI 2 "const_int_operand" ""))
6639 (match_operand:SI 3 "const_int_operand" "")))]
6640 "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6641 "*
6642 {
6643 int cnt = INTVAL (operands[2]) & 31;
6644 operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6645 operands[2] = GEN_INT (31 - cnt);
6646 return \"{zdep|depw,z} %1,%2,%3,%0\";
6647 }"
6648 [(set_attr "type" "shift")
6649 (set_attr "length" "4")])
6650 \f
6651 ;; Unconditional and other jump instructions.
6652
6653 ;; Trivial return used when no epilogue is needed.
6654 (define_insn "return"
6655 [(return)
6656 (use (reg:SI 2))]
6657 "pa_can_use_return_insn ()"
6658 "*
6659 {
6660 if (TARGET_PA_20)
6661 return \"bve%* (%%r2)\";
6662 return \"bv%* %%r0(%%r2)\";
6663 }"
6664 [(set_attr "type" "branch")
6665 (set_attr "length" "4")])
6666
6667 ;; This is used for most returns.
6668 (define_insn "return_internal"
6669 [(return)
6670 (use (reg:SI 2))]
6671 ""
6672 "*
6673 {
6674 if (TARGET_PA_20)
6675 return \"bve%* (%%r2)\";
6676 return \"bv%* %%r0(%%r2)\";
6677 }"
6678 [(set_attr "type" "branch")
6679 (set_attr "length" "4")])
6680
6681 ;; This is used for eh returns which bypass the return stub.
6682 (define_insn "return_external_pic"
6683 [(return)
6684 (clobber (reg:SI 1))
6685 (use (reg:SI 2))]
6686 "!TARGET_NO_SPACE_REGS
6687 && !TARGET_PA_20
6688 && flag_pic && crtl->calls_eh_return"
6689 "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
6690 [(set_attr "type" "branch")
6691 (set_attr "length" "12")])
6692
6693 (define_expand "prologue"
6694 [(const_int 0)]
6695 ""
6696 "pa_expand_prologue ();DONE;")
6697
6698 (define_expand "sibcall_epilogue"
6699 [(return)]
6700 ""
6701 "
6702 {
6703 pa_expand_epilogue ();
6704 DONE;
6705 }")
6706
6707 (define_expand "epilogue"
6708 [(return)]
6709 ""
6710 "
6711 {
6712 rtx x;
6713
6714 /* Try to use the trivial return first. Else use the full epilogue. */
6715 if (pa_can_use_return_insn ())
6716 x = gen_return ();
6717 else
6718 {
6719 pa_expand_epilogue ();
6720
6721 /* EH returns bypass the normal return stub. Thus, we must do an
6722 interspace branch to return from functions that call eh_return.
6723 This is only a problem for returns from shared code on ports
6724 using space registers. */
6725 if (!TARGET_NO_SPACE_REGS
6726 && !TARGET_PA_20
6727 && flag_pic && crtl->calls_eh_return)
6728 x = gen_return_external_pic ();
6729 else
6730 x = gen_return_internal ();
6731 }
6732 emit_jump_insn (x);
6733 DONE;
6734 }")
6735
6736 ; Used by hppa_profile_hook to load the starting address of the current
6737 ; function; operand 1 contains the address of the label in operand 3
6738 (define_insn "load_offset_label_address"
6739 [(set (match_operand:SI 0 "register_operand" "=r")
6740 (plus:SI (match_operand:SI 1 "register_operand" "r")
6741 (minus:SI (match_operand:SI 2 "" "")
6742 (label_ref:SI (match_operand 3 "" "")))))]
6743 ""
6744 "ldo %2-%l3(%1),%0"
6745 [(set_attr "type" "multi")
6746 (set_attr "length" "4")])
6747
6748 ; Output a code label and load its address.
6749 (define_insn "lcla1"
6750 [(set (match_operand:SI 0 "register_operand" "=r")
6751 (label_ref:SI (match_operand 1 "" "")))
6752 (const_int 0)]
6753 "!TARGET_PA_20"
6754 "*
6755 {
6756 output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
6757 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6758 CODE_LABEL_NUMBER (operands[1]));
6759 return \"\";
6760 }"
6761 [(set_attr "type" "multi")
6762 (set_attr "length" "8")])
6763
6764 (define_insn "lcla2"
6765 [(set (match_operand:SI 0 "register_operand" "=r")
6766 (label_ref:SI (match_operand 1 "" "")))
6767 (const_int 0)]
6768 "TARGET_PA_20"
6769 "*
6770 {
6771 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6772 CODE_LABEL_NUMBER (operands[1]));
6773 return \"mfia %0\";
6774 }"
6775 [(set_attr "type" "move")
6776 (set_attr "length" "4")])
6777
6778 (define_insn "blockage"
6779 [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
6780 ""
6781 ""
6782 [(set_attr "length" "0")])
6783
6784 (define_insn "jump"
6785 [(set (pc) (label_ref (match_operand 0 "" "")))]
6786 ""
6787 "*
6788 {
6789 /* An unconditional branch which can reach its target. */
6790 if (get_attr_length (insn) < 16)
6791 return \"b%* %l0\";
6792
6793 return pa_output_lbranch (operands[0], insn, 1);
6794 }"
6795 [(set_attr "type" "uncond_branch")
6796 (set_attr "pa_combine_type" "uncond_branch")
6797 (set (attr "length")
6798 (cond [(match_test "pa_jump_in_call_delay (insn)")
6799 (if_then_else (lt (abs (minus (match_dup 0)
6800 (plus (pc) (const_int 8))))
6801 (const_int MAX_12BIT_OFFSET))
6802 (const_int 4)
6803 (const_int 8))
6804 (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
6805 (const_int MAX_17BIT_OFFSET))
6806 (const_int 4)
6807 (match_test "TARGET_PORTABLE_RUNTIME")
6808 (const_int 20)
6809 (not (match_test "flag_pic"))
6810 (const_int 16)]
6811 (const_int 24)))])
6812
6813 ;;; Hope this is only within a function...
6814 (define_insn "indirect_jump"
6815 [(set (pc) (match_operand 0 "register_operand" "r"))]
6816 "GET_MODE (operands[0]) == word_mode"
6817 "bv%* %%r0(%0)"
6818 [(set_attr "type" "branch")
6819 (set_attr "length" "4")])
6820
6821 ;;; An indirect jump can be optimized to a direct jump. GAS for the
6822 ;;; SOM target doesn't allow branching to a label inside a function.
6823 ;;; We also don't correctly compute branch distances for labels
6824 ;;; outside the current function. Thus, we use an indirect jump can't
6825 ;;; be optimized to a direct jump for all targets. We assume that
6826 ;;; the branch target is in the same space (i.e., nested function
6827 ;;; jumping to a label in an outer function in the same translation
6828 ;;; unit).
6829 (define_expand "nonlocal_goto"
6830 [(use (match_operand 0 "general_operand" ""))
6831 (use (match_operand 1 "general_operand" ""))
6832 (use (match_operand 2 "general_operand" ""))
6833 (use (match_operand 3 "general_operand" ""))]
6834 ""
6835 {
6836 rtx lab = operands[1];
6837 rtx stack = operands[2];
6838 rtx fp = operands[3];
6839
6840 lab = copy_to_reg (lab);
6841
6842 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6843 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6844
6845 /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
6846 instead of the hard_frame_pointer_rtx in the save area. As a
6847 result, an extra instruction is needed to adjust for the offset
6848 of the virtual stack variables and the hard frame pointer. */
6849 if (GET_CODE (fp) != REG)
6850 fp = force_reg (Pmode, fp);
6851 emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
6852
6853 emit_stack_restore (SAVE_NONLOCAL, stack);
6854
6855 emit_use (hard_frame_pointer_rtx);
6856 emit_use (stack_pointer_rtx);
6857
6858 /* Nonlocal goto jumps are only used between functions in the same
6859 translation unit. Thus, we can avoid the extra overhead of an
6860 interspace jump. */
6861 emit_jump_insn (gen_indirect_goto (lab));
6862 emit_barrier ();
6863 DONE;
6864 })
6865
6866 (define_insn "indirect_goto"
6867 [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
6868 "GET_MODE (operands[0]) == word_mode"
6869 "bv%* %%r0(%0)"
6870 [(set_attr "type" "branch")
6871 (set_attr "length" "4")])
6872
6873 ;;; This jump is used in branch tables where the insn length is fixed.
6874 ;;; The length of this insn is adjusted if the delay slot is not filled.
6875 (define_insn "short_jump"
6876 [(set (pc) (label_ref (match_operand 0 "" "")))
6877 (const_int 0)]
6878 ""
6879 "b%* %l0%#"
6880 [(set_attr "type" "btable_branch")
6881 (set_attr "length" "4")])
6882
6883 ;; Subroutines of "casesi".
6884 ;; operand 0 is index
6885 ;; operand 1 is the minimum bound
6886 ;; operand 2 is the maximum bound - minimum bound + 1
6887 ;; operand 3 is CODE_LABEL for the table;
6888 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6889
6890 (define_expand "casesi"
6891 [(match_operand:SI 0 "general_operand" "")
6892 (match_operand:SI 1 "const_int_operand" "")
6893 (match_operand:SI 2 "const_int_operand" "")
6894 (match_operand 3 "" "")
6895 (match_operand 4 "" "")]
6896 ""
6897 "
6898 {
6899 if (GET_CODE (operands[0]) != REG)
6900 operands[0] = force_reg (SImode, operands[0]);
6901
6902 if (operands[1] != const0_rtx)
6903 {
6904 rtx index = gen_reg_rtx (SImode);
6905
6906 operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
6907 if (!INT_14_BITS (operands[1]))
6908 operands[1] = force_reg (SImode, operands[1]);
6909 emit_insn (gen_addsi3 (index, operands[0], operands[1]));
6910 operands[0] = index;
6911 }
6912
6913 if (!INT_5_BITS (operands[2]))
6914 operands[2] = force_reg (SImode, operands[2]);
6915
6916 /* This branch prevents us finding an insn for the delay slot of the
6917 following vectored branch. It might be possible to use the delay
6918 slot if an index value of -1 was used to transfer to the out-of-range
6919 label. In order to do this, we would have to output the -1 vector
6920 element after the delay insn. The casesi output code would have to
6921 check if the casesi insn is in a delay branch sequence and output
6922 the delay insn if one is found. If this was done, then it might
6923 then be worthwhile to split the casesi patterns to improve scheduling.
6924 However, it's not clear that all this extra complexity is worth
6925 the effort. */
6926 {
6927 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
6928 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
6929 }
6930
6931 /* In 64bit mode we must make sure to wipe the upper bits of the register
6932 just in case the addition overflowed or we had random bits in the
6933 high part of the register. */
6934 if (TARGET_64BIT)
6935 {
6936 rtx index = gen_reg_rtx (DImode);
6937
6938 emit_insn (gen_extendsidi2 (index, operands[0]));
6939 operands[0] = index;
6940 }
6941
6942 if (TARGET_BIG_SWITCH)
6943 {
6944 if (TARGET_64BIT)
6945 emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
6946 else if (flag_pic)
6947 emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
6948 else
6949 emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
6950 }
6951 else
6952 emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
6953 DONE;
6954 }")
6955
6956 ;;; The rtl for this pattern doesn't accurately describe what the insn
6957 ;;; actually does, particularly when case-vector elements are exploded
6958 ;;; in pa_reorg. However, the initial SET in these patterns must show
6959 ;;; the connection of the insn to the following jump table.
6960 (define_insn "casesi0"
6961 [(set (pc) (mem:SI (plus:SI
6962 (mult:SI (match_operand:SI 0 "register_operand" "r")
6963 (const_int 4))
6964 (label_ref (match_operand 1 "" "")))))]
6965 ""
6966 "blr,n %0,%%r0\;nop"
6967 [(set_attr "type" "multi")
6968 (set_attr "length" "8")])
6969
6970 ;;; 32-bit code, absolute branch table.
6971 (define_insn "casesi32"
6972 [(set (pc) (mem:SI (plus:SI
6973 (mult:SI (match_operand:SI 0 "register_operand" "r")
6974 (const_int 4))
6975 (label_ref (match_operand 1 "" "")))))
6976 (clobber (match_scratch:SI 2 "=&r"))]
6977 "!flag_pic"
6978 "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
6979 [(set_attr "type" "multi")
6980 (set_attr "length" "16")])
6981
6982 ;;; 32-bit code, relative branch table.
6983 (define_insn "casesi32p"
6984 [(set (pc) (mem:SI (plus:SI
6985 (mult:SI (match_operand:SI 0 "register_operand" "r")
6986 (const_int 4))
6987 (label_ref (match_operand 1 "" "")))))
6988 (clobber (match_scratch:SI 2 "=&r"))
6989 (clobber (match_scratch:SI 3 "=&r"))]
6990 "flag_pic"
6991 "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
6992 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
6993 [(set_attr "type" "multi")
6994 (set (attr "length")
6995 (if_then_else (match_test "TARGET_PA_20")
6996 (const_int 20)
6997 (const_int 24)))])
6998
6999 ;;; 64-bit code, 32-bit relative branch table.
7000 (define_insn "casesi64p"
7001 [(set (pc) (mem:DI (plus:DI
7002 (mult:DI (match_operand:DI 0 "register_operand" "r")
7003 (const_int 8))
7004 (label_ref (match_operand 1 "" "")))))
7005 (clobber (match_scratch:DI 2 "=&r"))
7006 (clobber (match_scratch:DI 3 "=&r"))]
7007 ""
7008 "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7009 add,l %2,%3,%3\;bv,n %%r0(%3)"
7010 [(set_attr "type" "multi")
7011 (set_attr "length" "24")])
7012
7013
7014 ;; Call patterns.
7015 ;;- jump to subroutine
7016
7017 (define_expand "call"
7018 [(parallel [(call (match_operand:SI 0 "" "")
7019 (match_operand 1 "" ""))
7020 (clobber (reg:SI 2))])]
7021 ""
7022 "
7023 {
7024 rtx op;
7025 rtx nb = operands[1];
7026
7027 if (TARGET_PORTABLE_RUNTIME)
7028 op = force_reg (SImode, XEXP (operands[0], 0));
7029 else
7030 op = XEXP (operands[0], 0);
7031
7032 if (TARGET_64BIT)
7033 {
7034 if (!virtuals_instantiated)
7035 emit_move_insn (arg_pointer_rtx,
7036 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7037 GEN_INT (64)));
7038 else
7039 {
7040 /* The loop pass can generate new libcalls after the virtual
7041 registers are instantiated when fpregs are disabled because
7042 the only method that we have for doing DImode multiplication
7043 is with a libcall. This could be trouble if we haven't
7044 allocated enough space for the outgoing arguments. */
7045 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7046
7047 emit_move_insn (arg_pointer_rtx,
7048 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7049 GEN_INT (STACK_POINTER_OFFSET + 64)));
7050 }
7051 }
7052
7053 /* Use two different patterns for calls to explicitly named functions
7054 and calls through function pointers. This is necessary as these two
7055 types of calls use different calling conventions, and CSE might try
7056 to change the named call into an indirect call in some cases (using
7057 two patterns keeps CSE from performing this optimization).
7058
7059 We now use even more call patterns as there was a subtle bug in
7060 attempting to restore the pic register after a call using a simple
7061 move insn. During reload, a instruction involving a pseudo register
7062 with no explicit dependence on the PIC register can be converted
7063 to an equivalent load from memory using the PIC register. If we
7064 emit a simple move to restore the PIC register in the initial rtl
7065 generation, then it can potentially be repositioned during scheduling.
7066 and an instruction that eventually uses the PIC register may end up
7067 between the call and the PIC register restore.
7068
7069 This only worked because there is a post call group of instructions
7070 that are scheduled with the call. These instructions are included
7071 in the same basic block as the call. However, calls can throw in
7072 C++ code and a basic block has to terminate at the call if the call
7073 can throw. This results in the PIC register restore being scheduled
7074 independently from the call. So, we now hide the save and restore
7075 of the PIC register in the call pattern until after reload. Then,
7076 we split the moves out. A small side benefit is that we now don't
7077 need to have a use of the PIC register in the return pattern and
7078 the final save/restore operation is not needed.
7079
7080 I elected to just use register %r4 in the PIC patterns instead
7081 of trying to force hppa_pic_save_rtx () to a callee saved register.
7082 This might have required a new register class and constraint. It
7083 was also simpler to just handle the restore from a register than a
7084 generic pseudo. */
7085 if (TARGET_64BIT)
7086 {
7087 rtx r4 = gen_rtx_REG (word_mode, 4);
7088 if (GET_CODE (op) == SYMBOL_REF)
7089 emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7090 else
7091 {
7092 op = force_reg (word_mode, op);
7093 emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7094 }
7095 }
7096 else
7097 {
7098 if (GET_CODE (op) == SYMBOL_REF)
7099 {
7100 if (flag_pic)
7101 {
7102 rtx r4 = gen_rtx_REG (word_mode, 4);
7103 emit_call_insn (gen_call_symref_pic (op, nb, r4));
7104 }
7105 else
7106 emit_call_insn (gen_call_symref (op, nb));
7107 }
7108 else
7109 {
7110 rtx tmpreg = gen_rtx_REG (word_mode, 22);
7111 emit_move_insn (tmpreg, force_reg (word_mode, op));
7112 if (flag_pic)
7113 {
7114 rtx r4 = gen_rtx_REG (word_mode, 4);
7115 emit_call_insn (gen_call_reg_pic (nb, r4));
7116 }
7117 else
7118 emit_call_insn (gen_call_reg (nb));
7119 }
7120 }
7121
7122 DONE;
7123 }")
7124
7125 ;; We use function calls to set the attribute length of calls and millicode
7126 ;; calls. This is necessary because of the large variety of call sequences.
7127 ;; Implementing the calculation in rtl is difficult as well as ugly. As
7128 ;; we need the same calculation in several places, maintenance becomes a
7129 ;; nightmare.
7130 ;;
7131 ;; However, this has a subtle impact on branch shortening. When the
7132 ;; expression used to set the length attribute of an instruction depends
7133 ;; on a relative address (e.g., pc or a branch address), genattrtab
7134 ;; notes that the insn's length is variable, and attempts to determine a
7135 ;; worst-case default length and code to compute an insn's current length.
7136
7137 ;; The use of a function call hides the variable dependence of our calls
7138 ;; and millicode calls. The result is genattrtab doesn't treat the operation
7139 ;; as variable and it only generates code for the default case using our
7140 ;; function call. Because of this, calls and millicode calls have a fixed
7141 ;; length in the branch shortening pass, and some branches will use a longer
7142 ;; code sequence than necessary. However, the length of any given call
7143 ;; will still reflect its final code location and it may be shorter than
7144 ;; the initial length estimate.
7145
7146 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7147 ;; in the set. However, when genattrtab hits a function call in its attempt
7148 ;; to compute the default length, it marks the result as unknown and sets
7149 ;; the default result to MAX_INT ;-( One possible fix that would allow
7150 ;; calls to participate in branch shortening would be to make the call to
7151 ;; insn_default_length a target option. Then, we could massage unknown
7152 ;; results. Another fix might be to change genattrtab so that it just does
7153 ;; the call in the variable case as it already does for the fixed case.
7154
7155 (define_insn "call_symref"
7156 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7157 (match_operand 1 "" "i"))
7158 (clobber (reg:SI 1))
7159 (clobber (reg:SI 2))
7160 (use (const_int 0))]
7161 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7162 "*
7163 {
7164 pa_output_arg_descriptor (insn);
7165 return pa_output_call (insn, operands[0], 0);
7166 }"
7167 [(set_attr "type" "call")
7168 (set (attr "length")
7169 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7170 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7171
7172 (define_insn "call_symref_pic"
7173 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7174 (match_operand 1 "" "i"))
7175 (clobber (reg:SI 1))
7176 (clobber (reg:SI 2))
7177 (clobber (match_operand 2))
7178 (use (reg:SI 19))
7179 (use (const_int 0))]
7180 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7181 "#")
7182
7183 ;; Split out the PIC register save and restore after reload. As the
7184 ;; split is done after reload, there are some situations in which we
7185 ;; unnecessarily save and restore %r4. This happens when there is a
7186 ;; single call and the PIC register is not used after the call.
7187 ;;
7188 ;; The split has to be done since call_from_call_insn () can't handle
7189 ;; the pattern as is. Noreturn calls are special because they have to
7190 ;; terminate the basic block. The split has to contain more than one
7191 ;; insn.
7192 (define_split
7193 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7194 (match_operand 1 "" ""))
7195 (clobber (reg:SI 1))
7196 (clobber (reg:SI 2))
7197 (clobber (match_operand 2))
7198 (use (reg:SI 19))
7199 (use (const_int 0))])]
7200 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7201 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7202 [(set (match_dup 2) (reg:SI 19))
7203 (parallel [(call (mem:SI (match_dup 0))
7204 (match_dup 1))
7205 (clobber (reg:SI 1))
7206 (clobber (reg:SI 2))
7207 (use (reg:SI 19))
7208 (use (const_int 0))])]
7209 "")
7210
7211 (define_split
7212 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7213 (match_operand 1 "" ""))
7214 (clobber (reg:SI 1))
7215 (clobber (reg:SI 2))
7216 (clobber (match_operand 2))
7217 (use (reg:SI 19))
7218 (use (const_int 0))])]
7219 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7220 [(set (match_dup 2) (reg:SI 19))
7221 (parallel [(call (mem:SI (match_dup 0))
7222 (match_dup 1))
7223 (clobber (reg:SI 1))
7224 (clobber (reg:SI 2))
7225 (use (reg:SI 19))
7226 (use (const_int 0))])
7227 (set (reg:SI 19) (match_dup 2))]
7228 "")
7229
7230 (define_insn "*call_symref_pic_post_reload"
7231 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7232 (match_operand 1 "" "i"))
7233 (clobber (reg:SI 1))
7234 (clobber (reg:SI 2))
7235 (use (reg:SI 19))
7236 (use (const_int 0))]
7237 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7238 "*
7239 {
7240 pa_output_arg_descriptor (insn);
7241 return pa_output_call (insn, operands[0], 0);
7242 }"
7243 [(set_attr "type" "call")
7244 (set (attr "length")
7245 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7246 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7247
7248 ;; This pattern is split if it is necessary to save and restore the
7249 ;; PIC register.
7250 (define_insn "call_symref_64bit"
7251 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7252 (match_operand 1 "" "i"))
7253 (clobber (reg:DI 1))
7254 (clobber (reg:DI 2))
7255 (clobber (match_operand 2))
7256 (use (reg:DI 27))
7257 (use (reg:DI 29))
7258 (use (const_int 0))]
7259 "TARGET_64BIT"
7260 "#")
7261
7262 ;; Split out the PIC register save and restore after reload. As the
7263 ;; split is done after reload, there are some situations in which we
7264 ;; unnecessarily save and restore %r4. This happens when there is a
7265 ;; single call and the PIC register is not used after the call.
7266 ;;
7267 ;; The split has to be done since call_from_call_insn () can't handle
7268 ;; the pattern as is. Noreturn calls are special because they have to
7269 ;; terminate the basic block. The split has to contain more than one
7270 ;; insn.
7271 (define_split
7272 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7273 (match_operand 1 "" ""))
7274 (clobber (reg:DI 1))
7275 (clobber (reg:DI 2))
7276 (clobber (match_operand 2))
7277 (use (reg:DI 27))
7278 (use (reg:DI 29))
7279 (use (const_int 0))])]
7280 "TARGET_64BIT && reload_completed
7281 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7282 [(set (match_dup 2) (reg:DI 27))
7283 (parallel [(call (mem:SI (match_dup 0))
7284 (match_dup 1))
7285 (clobber (reg:DI 1))
7286 (clobber (reg:DI 2))
7287 (use (reg:DI 27))
7288 (use (reg:DI 29))
7289 (use (const_int 0))])]
7290 "")
7291
7292 (define_split
7293 [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7294 (match_operand 1 "" ""))
7295 (clobber (reg:DI 1))
7296 (clobber (reg:DI 2))
7297 (clobber (match_operand 2))
7298 (use (reg:DI 27))
7299 (use (reg:DI 29))
7300 (use (const_int 0))])]
7301 "TARGET_64BIT && reload_completed"
7302 [(set (match_dup 2) (reg:DI 27))
7303 (parallel [(call (mem:SI (match_dup 0))
7304 (match_dup 1))
7305 (clobber (reg:DI 1))
7306 (clobber (reg:DI 2))
7307 (use (reg:DI 27))
7308 (use (reg:DI 29))
7309 (use (const_int 0))])
7310 (set (reg:DI 27) (match_dup 2))]
7311 "")
7312
7313 (define_insn "*call_symref_64bit_post_reload"
7314 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7315 (match_operand 1 "" "i"))
7316 (clobber (reg:DI 1))
7317 (clobber (reg:DI 2))
7318 (use (reg:DI 27))
7319 (use (reg:DI 29))
7320 (use (const_int 0))]
7321 "TARGET_64BIT"
7322 "*
7323 {
7324 pa_output_arg_descriptor (insn);
7325 return pa_output_call (insn, operands[0], 0);
7326 }"
7327 [(set_attr "type" "call")
7328 (set (attr "length")
7329 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7330 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7331
7332 (define_insn "call_reg"
7333 [(call (mem:SI (reg:SI 22))
7334 (match_operand 0 "" "i"))
7335 (clobber (reg:SI 1))
7336 (clobber (reg:SI 2))
7337 (use (const_int 1))]
7338 "!TARGET_64BIT"
7339 "*
7340 {
7341 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7342 }"
7343 [(set_attr "type" "dyncall")
7344 (set (attr "length")
7345 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7346 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7347
7348 ;; This pattern is split if it is necessary to save and restore the
7349 ;; PIC register.
7350 (define_insn "call_reg_pic"
7351 [(call (mem:SI (reg:SI 22))
7352 (match_operand 0 "" "i"))
7353 (clobber (reg:SI 1))
7354 (clobber (reg:SI 2))
7355 (clobber (match_operand 1))
7356 (use (reg:SI 19))
7357 (use (const_int 1))]
7358 "!TARGET_64BIT"
7359 "#")
7360
7361 ;; Split out the PIC register save and restore after reload. As the
7362 ;; split is done after reload, there are some situations in which we
7363 ;; unnecessarily save and restore %r4. This happens when there is a
7364 ;; single call and the PIC register is not used after the call.
7365 ;;
7366 ;; The split has to be done since call_from_call_insn () can't handle
7367 ;; the pattern as is. Noreturn calls are special because they have to
7368 ;; terminate the basic block. The split has to contain more than one
7369 ;; insn.
7370 (define_split
7371 [(parallel [(call (mem:SI (reg:SI 22))
7372 (match_operand 0 "" ""))
7373 (clobber (reg:SI 1))
7374 (clobber (reg:SI 2))
7375 (clobber (match_operand 1))
7376 (use (reg:SI 19))
7377 (use (const_int 1))])]
7378 "!TARGET_64BIT && reload_completed
7379 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7380 [(set (match_dup 1) (reg:SI 19))
7381 (parallel [(call (mem:SI (reg:SI 22))
7382 (match_dup 0))
7383 (clobber (reg:SI 1))
7384 (clobber (reg:SI 2))
7385 (use (reg:SI 19))
7386 (use (const_int 1))])]
7387 "")
7388
7389 (define_split
7390 [(parallel [(call (mem:SI (reg:SI 22))
7391 (match_operand 0 "" ""))
7392 (clobber (reg:SI 1))
7393 (clobber (reg:SI 2))
7394 (clobber (match_operand 1))
7395 (use (reg:SI 19))
7396 (use (const_int 1))])]
7397 "!TARGET_64BIT && reload_completed"
7398 [(set (match_dup 1) (reg:SI 19))
7399 (parallel [(call (mem:SI (reg:SI 22))
7400 (match_dup 0))
7401 (clobber (reg:SI 1))
7402 (clobber (reg:SI 2))
7403 (use (reg:SI 19))
7404 (use (const_int 1))])
7405 (set (reg:SI 19) (match_dup 1))]
7406 "")
7407
7408 (define_insn "*call_reg_pic_post_reload"
7409 [(call (mem:SI (reg:SI 22))
7410 (match_operand 0 "" "i"))
7411 (clobber (reg:SI 1))
7412 (clobber (reg:SI 2))
7413 (use (reg:SI 19))
7414 (use (const_int 1))]
7415 "!TARGET_64BIT"
7416 "*
7417 {
7418 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7419 }"
7420 [(set_attr "type" "dyncall")
7421 (set (attr "length")
7422 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7423 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7424
7425 ;; This pattern is split if it is necessary to save and restore the
7426 ;; PIC register.
7427 (define_insn "call_reg_64bit"
7428 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7429 (match_operand 1 "" "i"))
7430 (clobber (reg:DI 1))
7431 (clobber (reg:DI 2))
7432 (clobber (match_operand 2))
7433 (use (reg:DI 27))
7434 (use (reg:DI 29))
7435 (use (const_int 1))]
7436 "TARGET_64BIT"
7437 "#")
7438
7439 ;; Split out the PIC register save and restore after reload. As the
7440 ;; split is done after reload, there are some situations in which we
7441 ;; unnecessarily save and restore %r4. This happens when there is a
7442 ;; single call and the PIC register is not used after the call.
7443 ;;
7444 ;; The split has to be done since call_from_call_insn () can't handle
7445 ;; the pattern as is. Noreturn calls are special because they have to
7446 ;; terminate the basic block. The split has to contain more than one
7447 ;; insn.
7448 (define_split
7449 [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7450 (match_operand 1 "" ""))
7451 (clobber (reg:DI 1))
7452 (clobber (reg:DI 2))
7453 (clobber (match_operand 2))
7454 (use (reg:DI 27))
7455 (use (reg:DI 29))
7456 (use (const_int 1))])]
7457 "TARGET_64BIT && reload_completed
7458 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7459 [(set (match_dup 2) (reg:DI 27))
7460 (parallel [(call (mem:SI (match_dup 0))
7461 (match_dup 1))
7462 (clobber (reg:DI 1))
7463 (clobber (reg:DI 2))
7464 (use (reg:DI 27))
7465 (use (reg:DI 29))
7466 (use (const_int 1))])]
7467 "")
7468
7469 (define_split
7470 [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7471 (match_operand 1 "" ""))
7472 (clobber (reg:DI 1))
7473 (clobber (reg:DI 2))
7474 (clobber (match_operand 2))
7475 (use (reg:DI 27))
7476 (use (reg:DI 29))
7477 (use (const_int 1))])]
7478 "TARGET_64BIT && reload_completed"
7479 [(set (match_dup 2) (reg:DI 27))
7480 (parallel [(call (mem:SI (match_dup 0))
7481 (match_dup 1))
7482 (clobber (reg:DI 1))
7483 (clobber (reg:DI 2))
7484 (use (reg:DI 27))
7485 (use (reg:DI 29))
7486 (use (const_int 1))])
7487 (set (reg:DI 27) (match_dup 2))]
7488 "")
7489
7490 (define_insn "*call_reg_64bit_post_reload"
7491 [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7492 (match_operand 1 "" "i"))
7493 (clobber (reg:DI 1))
7494 (clobber (reg:DI 2))
7495 (use (reg:DI 27))
7496 (use (reg:DI 29))
7497 (use (const_int 1))]
7498 "TARGET_64BIT"
7499 "*
7500 {
7501 return pa_output_indirect_call (insn, operands[0]);
7502 }"
7503 [(set_attr "type" "dyncall")
7504 (set (attr "length")
7505 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 12)]
7506 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7507
7508 (define_expand "call_value"
7509 [(parallel [(set (match_operand 0 "" "")
7510 (call (match_operand:SI 1 "" "")
7511 (match_operand 2 "" "")))
7512 (clobber (reg:SI 2))])]
7513 ""
7514 "
7515 {
7516 rtx op;
7517 rtx dst = operands[0];
7518 rtx nb = operands[2];
7519
7520 if (TARGET_PORTABLE_RUNTIME)
7521 op = force_reg (SImode, XEXP (operands[1], 0));
7522 else
7523 op = XEXP (operands[1], 0);
7524
7525 if (TARGET_64BIT)
7526 {
7527 if (!virtuals_instantiated)
7528 emit_move_insn (arg_pointer_rtx,
7529 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7530 GEN_INT (64)));
7531 else
7532 {
7533 /* The loop pass can generate new libcalls after the virtual
7534 registers are instantiated when fpregs are disabled because
7535 the only method that we have for doing DImode multiplication
7536 is with a libcall. This could be trouble if we haven't
7537 allocated enough space for the outgoing arguments. */
7538 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7539
7540 emit_move_insn (arg_pointer_rtx,
7541 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7542 GEN_INT (STACK_POINTER_OFFSET + 64)));
7543 }
7544 }
7545
7546 /* Use two different patterns for calls to explicitly named functions
7547 and calls through function pointers. This is necessary as these two
7548 types of calls use different calling conventions, and CSE might try
7549 to change the named call into an indirect call in some cases (using
7550 two patterns keeps CSE from performing this optimization).
7551
7552 We now use even more call patterns as there was a subtle bug in
7553 attempting to restore the pic register after a call using a simple
7554 move insn. During reload, a instruction involving a pseudo register
7555 with no explicit dependence on the PIC register can be converted
7556 to an equivalent load from memory using the PIC register. If we
7557 emit a simple move to restore the PIC register in the initial rtl
7558 generation, then it can potentially be repositioned during scheduling.
7559 and an instruction that eventually uses the PIC register may end up
7560 between the call and the PIC register restore.
7561
7562 This only worked because there is a post call group of instructions
7563 that are scheduled with the call. These instructions are included
7564 in the same basic block as the call. However, calls can throw in
7565 C++ code and a basic block has to terminate at the call if the call
7566 can throw. This results in the PIC register restore being scheduled
7567 independently from the call. So, we now hide the save and restore
7568 of the PIC register in the call pattern until after reload. Then,
7569 we split the moves out. A small side benefit is that we now don't
7570 need to have a use of the PIC register in the return pattern and
7571 the final save/restore operation is not needed.
7572
7573 I elected to just use register %r4 in the PIC patterns instead
7574 of trying to force hppa_pic_save_rtx () to a callee saved register.
7575 This might have required a new register class and constraint. It
7576 was also simpler to just handle the restore from a register than a
7577 generic pseudo. */
7578 if (TARGET_64BIT)
7579 {
7580 rtx r4 = gen_rtx_REG (word_mode, 4);
7581 if (GET_CODE (op) == SYMBOL_REF)
7582 emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7583 else
7584 {
7585 op = force_reg (word_mode, op);
7586 emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7587 }
7588 }
7589 else
7590 {
7591 if (GET_CODE (op) == SYMBOL_REF)
7592 {
7593 if (flag_pic)
7594 {
7595 rtx r4 = gen_rtx_REG (word_mode, 4);
7596 emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7597 }
7598 else
7599 emit_call_insn (gen_call_val_symref (dst, op, nb));
7600 }
7601 else
7602 {
7603 rtx tmpreg = gen_rtx_REG (word_mode, 22);
7604 emit_move_insn (tmpreg, force_reg (word_mode, op));
7605 if (flag_pic)
7606 {
7607 rtx r4 = gen_rtx_REG (word_mode, 4);
7608 emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7609 }
7610 else
7611 emit_call_insn (gen_call_val_reg (dst, nb));
7612 }
7613 }
7614
7615 DONE;
7616 }")
7617
7618 (define_insn "call_val_symref"
7619 [(set (match_operand 0 "" "")
7620 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7621 (match_operand 2 "" "i")))
7622 (clobber (reg:SI 1))
7623 (clobber (reg:SI 2))
7624 (use (const_int 0))]
7625 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7626 "*
7627 {
7628 pa_output_arg_descriptor (insn);
7629 return pa_output_call (insn, operands[1], 0);
7630 }"
7631 [(set_attr "type" "call")
7632 (set (attr "length")
7633 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7634 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7635
7636 (define_insn "call_val_symref_pic"
7637 [(set (match_operand 0 "" "")
7638 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7639 (match_operand 2 "" "i")))
7640 (clobber (reg:SI 1))
7641 (clobber (reg:SI 2))
7642 (clobber (match_operand 3))
7643 (use (reg:SI 19))
7644 (use (const_int 0))]
7645 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7646 "#")
7647
7648 ;; Split out the PIC register save and restore after reload. As the
7649 ;; split is done after reload, there are some situations in which we
7650 ;; unnecessarily save and restore %r4. This happens when there is a
7651 ;; single call and the PIC register is not used after the call.
7652 ;;
7653 ;; The split has to be done since call_from_call_insn () can't handle
7654 ;; the pattern as is. Noreturn calls are special because they have to
7655 ;; terminate the basic block. The split has to contain more than one
7656 ;; insn.
7657 (define_split
7658 [(parallel [(set (match_operand 0 "" "")
7659 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7660 (match_operand 2 "" "")))
7661 (clobber (reg:SI 1))
7662 (clobber (reg:SI 2))
7663 (clobber (match_operand 3))
7664 (use (reg:SI 19))
7665 (use (const_int 0))])]
7666 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7667 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7668 [(set (match_dup 3) (reg:SI 19))
7669 (parallel [(set (match_dup 0)
7670 (call (mem:SI (match_dup 1))
7671 (match_dup 2)))
7672 (clobber (reg:SI 1))
7673 (clobber (reg:SI 2))
7674 (use (reg:SI 19))
7675 (use (const_int 0))])]
7676 "")
7677
7678 (define_split
7679 [(parallel [(set (match_operand 0 "" "")
7680 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7681 (match_operand 2 "" "")))
7682 (clobber (reg:SI 1))
7683 (clobber (reg:SI 2))
7684 (clobber (match_operand 3))
7685 (use (reg:SI 19))
7686 (use (const_int 0))])]
7687 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7688 [(set (match_dup 3) (reg:SI 19))
7689 (parallel [(set (match_dup 0)
7690 (call (mem:SI (match_dup 1))
7691 (match_dup 2)))
7692 (clobber (reg:SI 1))
7693 (clobber (reg:SI 2))
7694 (use (reg:SI 19))
7695 (use (const_int 0))])
7696 (set (reg:SI 19) (match_dup 3))]
7697 "")
7698
7699 (define_insn "*call_val_symref_pic_post_reload"
7700 [(set (match_operand 0 "" "")
7701 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7702 (match_operand 2 "" "i")))
7703 (clobber (reg:SI 1))
7704 (clobber (reg:SI 2))
7705 (use (reg:SI 19))
7706 (use (const_int 0))]
7707 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7708 "*
7709 {
7710 pa_output_arg_descriptor (insn);
7711 return pa_output_call (insn, operands[1], 0);
7712 }"
7713 [(set_attr "type" "call")
7714 (set (attr "length")
7715 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7716 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7717
7718 ;; This pattern is split if it is necessary to save and restore the
7719 ;; PIC register.
7720 (define_insn "call_val_symref_64bit"
7721 [(set (match_operand 0 "" "")
7722 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7723 (match_operand 2 "" "i")))
7724 (clobber (reg:DI 1))
7725 (clobber (reg:DI 2))
7726 (clobber (match_operand 3))
7727 (use (reg:DI 27))
7728 (use (reg:DI 29))
7729 (use (const_int 0))]
7730 "TARGET_64BIT"
7731 "#")
7732
7733 ;; Split out the PIC register save and restore after reload. As the
7734 ;; split is done after reload, there are some situations in which we
7735 ;; unnecessarily save and restore %r4. This happens when there is a
7736 ;; single call and the PIC register is not used after the call.
7737 ;;
7738 ;; The split has to be done since call_from_call_insn () can't handle
7739 ;; the pattern as is. Noreturn calls are special because they have to
7740 ;; terminate the basic block. The split has to contain more than one
7741 ;; insn.
7742 (define_split
7743 [(parallel [(set (match_operand 0 "" "")
7744 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7745 (match_operand 2 "" "")))
7746 (clobber (reg:DI 1))
7747 (clobber (reg:DI 2))
7748 (clobber (match_operand 3))
7749 (use (reg:DI 27))
7750 (use (reg:DI 29))
7751 (use (const_int 0))])]
7752 "TARGET_64BIT && reload_completed
7753 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7754 [(set (match_dup 3) (reg:DI 27))
7755 (parallel [(set (match_dup 0)
7756 (call (mem:SI (match_dup 1))
7757 (match_dup 2)))
7758 (clobber (reg:DI 1))
7759 (clobber (reg:DI 2))
7760 (use (reg:DI 27))
7761 (use (reg:DI 29))
7762 (use (const_int 0))])]
7763 "")
7764
7765 (define_split
7766 [(parallel [(set (match_operand 0 "" "")
7767 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7768 (match_operand 2 "" "")))
7769 (clobber (reg:DI 1))
7770 (clobber (reg:DI 2))
7771 (clobber (match_operand 3))
7772 (use (reg:DI 27))
7773 (use (reg:DI 29))
7774 (use (const_int 0))])]
7775 "TARGET_64BIT && reload_completed"
7776 [(set (match_dup 3) (reg:DI 27))
7777 (parallel [(set (match_dup 0)
7778 (call (mem:SI (match_dup 1))
7779 (match_dup 2)))
7780 (clobber (reg:DI 1))
7781 (clobber (reg:DI 2))
7782 (use (reg:DI 27))
7783 (use (reg:DI 29))
7784 (use (const_int 0))])
7785 (set (reg:DI 27) (match_dup 3))]
7786 "")
7787
7788 (define_insn "*call_val_symref_64bit_post_reload"
7789 [(set (match_operand 0 "" "")
7790 (call (mem:SI (match_operand 1 "call_operand_address" ""))
7791 (match_operand 2 "" "i")))
7792 (clobber (reg:DI 1))
7793 (clobber (reg:DI 2))
7794 (use (reg:DI 27))
7795 (use (reg:DI 29))
7796 (use (const_int 0))]
7797 "TARGET_64BIT"
7798 "*
7799 {
7800 pa_output_arg_descriptor (insn);
7801 return pa_output_call (insn, operands[1], 0);
7802 }"
7803 [(set_attr "type" "call")
7804 (set (attr "length")
7805 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7806 (symbol_ref "pa_attr_length_call (insn, 0)")))])
7807
7808 (define_insn "call_val_reg"
7809 [(set (match_operand 0 "" "")
7810 (call (mem:SI (reg:SI 22))
7811 (match_operand 1 "" "i")))
7812 (clobber (reg:SI 1))
7813 (clobber (reg:SI 2))
7814 (use (const_int 1))]
7815 "!TARGET_64BIT"
7816 "*
7817 {
7818 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7819 }"
7820 [(set_attr "type" "dyncall")
7821 (set (attr "length")
7822 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7823 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7824
7825 ;; This pattern is split if it is necessary to save and restore the
7826 ;; PIC register.
7827 (define_insn "call_val_reg_pic"
7828 [(set (match_operand 0 "" "")
7829 (call (mem:SI (reg:SI 22))
7830 (match_operand 1 "" "i")))
7831 (clobber (reg:SI 1))
7832 (clobber (reg:SI 2))
7833 (clobber (match_operand 2))
7834 (use (reg:SI 19))
7835 (use (const_int 1))]
7836 "!TARGET_64BIT"
7837 "#")
7838
7839 ;; Split out the PIC register save and restore after reload. As the
7840 ;; split is done after reload, there are some situations in which we
7841 ;; unnecessarily save and restore %r4. This happens when there is a
7842 ;; single call and the PIC register is not used after the call.
7843 ;;
7844 ;; The split has to be done since call_from_call_insn () can't handle
7845 ;; the pattern as is. Noreturn calls are special because they have to
7846 ;; terminate the basic block. The split has to contain more than one
7847 ;; insn.
7848 (define_split
7849 [(parallel [(set (match_operand 0 "" "")
7850 (call (mem:SI (reg:SI 22))
7851 (match_operand 1 "" "")))
7852 (clobber (reg:SI 1))
7853 (clobber (reg:SI 2))
7854 (clobber (match_operand 2))
7855 (use (reg:SI 19))
7856 (use (const_int 1))])]
7857 "!TARGET_64BIT && reload_completed
7858 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7859 [(set (match_dup 2) (reg:SI 19))
7860 (parallel [(set (match_dup 0)
7861 (call (mem:SI (reg:SI 22))
7862 (match_dup 1)))
7863 (clobber (reg:SI 1))
7864 (clobber (reg:SI 2))
7865 (use (reg:SI 19))
7866 (use (const_int 1))])]
7867 "")
7868
7869 (define_split
7870 [(parallel [(set (match_operand 0 "" "")
7871 (call (mem:SI (reg:SI 22))
7872 (match_operand 1 "" "")))
7873 (clobber (reg:SI 1))
7874 (clobber (reg:SI 2))
7875 (clobber (match_operand 2))
7876 (use (reg:SI 19))
7877 (use (const_int 1))])]
7878 "!TARGET_64BIT && reload_completed"
7879 [(set (match_dup 2) (reg:SI 19))
7880 (parallel [(set (match_dup 0)
7881 (call (mem:SI (reg:SI 22))
7882 (match_dup 1)))
7883 (clobber (reg:SI 1))
7884 (clobber (reg:SI 2))
7885 (use (reg:SI 19))
7886 (use (const_int 1))])
7887 (set (reg:SI 19) (match_dup 2))]
7888 "")
7889
7890 (define_insn "*call_val_reg_pic_post_reload"
7891 [(set (match_operand 0 "" "")
7892 (call (mem:SI (reg:SI 22))
7893 (match_operand 1 "" "i")))
7894 (clobber (reg:SI 1))
7895 (clobber (reg:SI 2))
7896 (use (reg:SI 19))
7897 (use (const_int 1))]
7898 "!TARGET_64BIT"
7899 "*
7900 {
7901 return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7902 }"
7903 [(set_attr "type" "dyncall")
7904 (set (attr "length")
7905 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
7906 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7907
7908 ;; This pattern is split if it is necessary to save and restore the
7909 ;; PIC register.
7910 (define_insn "call_val_reg_64bit"
7911 [(set (match_operand 0 "" "")
7912 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
7913 (match_operand 2 "" "i")))
7914 (clobber (reg:DI 1))
7915 (clobber (reg:DI 2))
7916 (clobber (match_operand 3))
7917 (use (reg:DI 27))
7918 (use (reg:DI 29))
7919 (use (const_int 1))]
7920 "TARGET_64BIT"
7921 "#")
7922
7923 ;; Split out the PIC register save and restore after reload. As the
7924 ;; split is done after reload, there are some situations in which we
7925 ;; unnecessarily save and restore %r4. This happens when there is a
7926 ;; single call and the PIC register is not used after the call.
7927 ;;
7928 ;; The split has to be done since call_from_call_insn () can't handle
7929 ;; the pattern as is. Noreturn calls are special because they have to
7930 ;; terminate the basic block. The split has to contain more than one
7931 ;; insn.
7932 (define_split
7933 [(parallel [(set (match_operand 0 "" "")
7934 (call (mem:SI (match_operand:DI 1 "register_operand" ""))
7935 (match_operand 2 "" "")))
7936 (clobber (reg:DI 1))
7937 (clobber (reg:DI 2))
7938 (clobber (match_operand 3))
7939 (use (reg:DI 27))
7940 (use (reg:DI 29))
7941 (use (const_int 1))])]
7942 "TARGET_64BIT && reload_completed
7943 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7944 [(set (match_dup 3) (reg:DI 27))
7945 (parallel [(set (match_dup 0)
7946 (call (mem:SI (match_dup 1))
7947 (match_dup 2)))
7948 (clobber (reg:DI 1))
7949 (clobber (reg:DI 2))
7950 (use (reg:DI 27))
7951 (use (reg:DI 29))
7952 (use (const_int 1))])]
7953 "")
7954
7955 (define_split
7956 [(parallel [(set (match_operand 0 "" "")
7957 (call (mem:SI (match_operand:DI 1 "register_operand" ""))
7958 (match_operand 2 "" "")))
7959 (clobber (reg:DI 1))
7960 (clobber (reg:DI 2))
7961 (clobber (match_operand 3))
7962 (use (reg:DI 27))
7963 (use (reg:DI 29))
7964 (use (const_int 1))])]
7965 "TARGET_64BIT && reload_completed"
7966 [(set (match_dup 3) (reg:DI 27))
7967 (parallel [(set (match_dup 0)
7968 (call (mem:SI (match_dup 1))
7969 (match_dup 2)))
7970 (clobber (reg:DI 1))
7971 (clobber (reg:DI 2))
7972 (use (reg:DI 27))
7973 (use (reg:DI 29))
7974 (use (const_int 1))])
7975 (set (reg:DI 27) (match_dup 3))]
7976 "")
7977
7978 (define_insn "*call_val_reg_64bit_post_reload"
7979 [(set (match_operand 0 "" "")
7980 (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
7981 (match_operand 2 "" "i")))
7982 (clobber (reg:DI 1))
7983 (clobber (reg:DI 2))
7984 (use (reg:DI 27))
7985 (use (reg:DI 29))
7986 (use (const_int 1))]
7987 "TARGET_64BIT"
7988 "*
7989 {
7990 return pa_output_indirect_call (insn, operands[1]);
7991 }"
7992 [(set_attr "type" "dyncall")
7993 (set (attr "length")
7994 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 12)]
7995 (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7996
7997 ;; Call subroutine returning any type.
7998
7999 (define_expand "untyped_call"
8000 [(parallel [(call (match_operand 0 "" "")
8001 (const_int 0))
8002 (match_operand 1 "" "")
8003 (match_operand 2 "" "")])]
8004 ""
8005 "
8006 {
8007 int i;
8008
8009 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
8010
8011 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8012 {
8013 rtx set = XVECEXP (operands[2], 0, i);
8014 emit_move_insn (SET_DEST (set), SET_SRC (set));
8015 }
8016
8017 /* The optimizer does not know that the call sets the function value
8018 registers we stored in the result block. We avoid problems by
8019 claiming that all hard registers are used and clobbered at this
8020 point. */
8021 emit_insn (gen_blockage ());
8022
8023 DONE;
8024 }")
8025
8026 (define_expand "sibcall"
8027 [(call (match_operand:SI 0 "" "")
8028 (match_operand 1 "" ""))]
8029 "!TARGET_PORTABLE_RUNTIME"
8030 "
8031 {
8032 rtx op, call_insn;
8033 rtx nb = operands[1];
8034
8035 op = XEXP (operands[0], 0);
8036
8037 if (TARGET_64BIT)
8038 {
8039 if (!virtuals_instantiated)
8040 emit_move_insn (arg_pointer_rtx,
8041 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8042 GEN_INT (64)));
8043 else
8044 {
8045 /* The loop pass can generate new libcalls after the virtual
8046 registers are instantiated when fpregs are disabled because
8047 the only method that we have for doing DImode multiplication
8048 is with a libcall. This could be trouble if we haven't
8049 allocated enough space for the outgoing arguments. */
8050 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8051
8052 emit_move_insn (arg_pointer_rtx,
8053 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8054 GEN_INT (STACK_POINTER_OFFSET + 64)));
8055 }
8056 }
8057
8058 /* Indirect sibling calls are not allowed. */
8059 if (TARGET_64BIT)
8060 call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8061 else
8062 call_insn = gen_sibcall_internal_symref (op, operands[1]);
8063
8064 call_insn = emit_call_insn (call_insn);
8065
8066 if (TARGET_64BIT)
8067 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8068
8069 /* We don't have to restore the PIC register. */
8070 if (flag_pic)
8071 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8072
8073 DONE;
8074 }")
8075
8076 (define_insn "sibcall_internal_symref"
8077 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8078 (match_operand 1 "" "i"))
8079 (clobber (reg:SI 1))
8080 (use (reg:SI 2))
8081 (use (const_int 0))]
8082 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8083 "*
8084 {
8085 pa_output_arg_descriptor (insn);
8086 return pa_output_call (insn, operands[0], 1);
8087 }"
8088 [(set_attr "type" "sibcall")
8089 (set (attr "length")
8090 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
8091 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8092
8093 (define_insn "sibcall_internal_symref_64bit"
8094 [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8095 (match_operand 1 "" "i"))
8096 (clobber (reg:DI 1))
8097 (use (reg:DI 2))
8098 (use (const_int 0))]
8099 "TARGET_64BIT"
8100 "*
8101 {
8102 pa_output_arg_descriptor (insn);
8103 return pa_output_call (insn, operands[0], 1);
8104 }"
8105 [(set_attr "type" "sibcall")
8106 (set (attr "length")
8107 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
8108 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8109
8110 (define_expand "sibcall_value"
8111 [(set (match_operand 0 "" "")
8112 (call (match_operand:SI 1 "" "")
8113 (match_operand 2 "" "")))]
8114 "!TARGET_PORTABLE_RUNTIME"
8115 "
8116 {
8117 rtx op, call_insn;
8118 rtx nb = operands[1];
8119
8120 op = XEXP (operands[1], 0);
8121
8122 if (TARGET_64BIT)
8123 {
8124 if (!virtuals_instantiated)
8125 emit_move_insn (arg_pointer_rtx,
8126 gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8127 GEN_INT (64)));
8128 else
8129 {
8130 /* The loop pass can generate new libcalls after the virtual
8131 registers are instantiated when fpregs are disabled because
8132 the only method that we have for doing DImode multiplication
8133 is with a libcall. This could be trouble if we haven't
8134 allocated enough space for the outgoing arguments. */
8135 gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8136
8137 emit_move_insn (arg_pointer_rtx,
8138 gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8139 GEN_INT (STACK_POINTER_OFFSET + 64)));
8140 }
8141 }
8142
8143 /* Indirect sibling calls are not allowed. */
8144 if (TARGET_64BIT)
8145 call_insn
8146 = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8147 else
8148 call_insn
8149 = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8150
8151 call_insn = emit_call_insn (call_insn);
8152
8153 if (TARGET_64BIT)
8154 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8155
8156 /* We don't have to restore the PIC register. */
8157 if (flag_pic)
8158 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8159
8160 DONE;
8161 }")
8162
8163 (define_insn "sibcall_value_internal_symref"
8164 [(set (match_operand 0 "" "")
8165 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8166 (match_operand 2 "" "i")))
8167 (clobber (reg:SI 1))
8168 (use (reg:SI 2))
8169 (use (const_int 0))]
8170 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8171 "*
8172 {
8173 pa_output_arg_descriptor (insn);
8174 return pa_output_call (insn, operands[1], 1);
8175 }"
8176 [(set_attr "type" "sibcall")
8177 (set (attr "length")
8178 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
8179 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8180
8181 (define_insn "sibcall_value_internal_symref_64bit"
8182 [(set (match_operand 0 "" "")
8183 (call (mem:SI (match_operand 1 "call_operand_address" ""))
8184 (match_operand 2 "" "i")))
8185 (clobber (reg:DI 1))
8186 (use (reg:DI 2))
8187 (use (const_int 0))]
8188 "TARGET_64BIT"
8189 "*
8190 {
8191 pa_output_arg_descriptor (insn);
8192 return pa_output_call (insn, operands[1], 1);
8193 }"
8194 [(set_attr "type" "sibcall")
8195 (set (attr "length")
8196 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)]
8197 (symbol_ref "pa_attr_length_call (insn, 1)")))])
8198
8199 (define_insn "nop"
8200 [(const_int 0)]
8201 ""
8202 "nop"
8203 [(set_attr "type" "move")
8204 (set_attr "length" "4")])
8205
8206 ;; These are just placeholders so we know where branch tables
8207 ;; begin and end.
8208 (define_insn "begin_brtab"
8209 [(const_int 1)]
8210 ""
8211 "*
8212 {
8213 /* Only GAS actually supports this pseudo-op. */
8214 if (TARGET_GAS)
8215 return \".begin_brtab\";
8216 else
8217 return \"\";
8218 }"
8219 [(set_attr "type" "move")
8220 (set_attr "length" "0")])
8221
8222 (define_insn "end_brtab"
8223 [(const_int 2)]
8224 ""
8225 "*
8226 {
8227 /* Only GAS actually supports this pseudo-op. */
8228 if (TARGET_GAS)
8229 return \".end_brtab\";
8230 else
8231 return \"\";
8232 }"
8233 [(set_attr "type" "move")
8234 (set_attr "length" "0")])
8235
8236 ;;; EH does longjmp's from and within the data section. Thus,
8237 ;;; an interspace branch is required for the longjmp implementation.
8238 ;;; Registers r1 and r2 are used as scratch registers for the jump
8239 ;;; when necessary.
8240 (define_expand "interspace_jump"
8241 [(parallel
8242 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8243 (clobber (match_dup 1))])]
8244 ""
8245 "
8246 {
8247 operands[1] = gen_rtx_REG (word_mode, 2);
8248 }")
8249
8250 (define_insn ""
8251 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8252 (clobber (reg:SI 2))]
8253 "TARGET_PA_20 && !TARGET_64BIT"
8254 "bve%* (%0)"
8255 [(set_attr "type" "branch")
8256 (set_attr "length" "4")])
8257
8258 (define_insn ""
8259 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8260 (clobber (reg:SI 2))]
8261 "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8262 "be%* 0(%%sr4,%0)"
8263 [(set_attr "type" "branch")
8264 (set_attr "length" "4")])
8265
8266 (define_insn ""
8267 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8268 (clobber (reg:SI 2))]
8269 "!TARGET_64BIT"
8270 "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8271 [(set_attr "type" "branch")
8272 (set_attr "length" "12")])
8273
8274 (define_insn ""
8275 [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8276 (clobber (reg:DI 2))]
8277 "TARGET_64BIT"
8278 "bve%* (%0)"
8279 [(set_attr "type" "branch")
8280 (set_attr "length" "4")])
8281
8282 (define_expand "builtin_longjmp"
8283 [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8284 ""
8285 "
8286 {
8287 /* The elements of the buffer are, in order: */
8288 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8289 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8290 POINTER_SIZE / BITS_PER_UNIT));
8291 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8292 (POINTER_SIZE * 2) / BITS_PER_UNIT));
8293 rtx pv = gen_rtx_REG (Pmode, 1);
8294
8295 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8296 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8297
8298 /* Restore the frame pointer. The virtual_stack_vars_rtx is saved
8299 instead of the hard_frame_pointer_rtx in the save area. We need
8300 to adjust for the offset between these two values. */
8301 if (GET_CODE (fp) != REG)
8302 fp = force_reg (Pmode, fp);
8303 emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
8304
8305 /* This bit is the same as expand_builtin_longjmp. */
8306 emit_stack_restore (SAVE_NONLOCAL, stack);
8307 emit_use (hard_frame_pointer_rtx);
8308 emit_use (stack_pointer_rtx);
8309
8310 /* Load the label we are jumping through into r1 so that we know
8311 where to look for it when we get back to setjmp's function for
8312 restoring the gp. */
8313 emit_move_insn (pv, lab);
8314
8315 /* Prevent the insns above from being scheduled into the delay slot
8316 of the interspace jump because the space register could change. */
8317 emit_insn (gen_blockage ());
8318
8319 emit_jump_insn (gen_interspace_jump (pv));
8320 emit_barrier ();
8321 DONE;
8322 }")
8323
8324 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8325 (define_expand "extzv"
8326 [(set (match_operand 0 "register_operand" "")
8327 (zero_extract (match_operand 1 "register_operand" "")
8328 (match_operand 2 "uint32_operand" "")
8329 (match_operand 3 "uint32_operand" "")))]
8330 ""
8331 "
8332 {
8333 HOST_WIDE_INT len = INTVAL (operands[2]);
8334 HOST_WIDE_INT pos = INTVAL (operands[3]);
8335
8336 /* PA extraction insns don't support zero length bitfields or fields
8337 extending beyond the left or right-most bits. Also, we reject lengths
8338 equal to a word as they are better handled by the move patterns. */
8339 if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8340 FAIL;
8341
8342 /* From mips.md: extract_bit_field doesn't verify that our source
8343 matches the predicate, so check it again here. */
8344 if (!register_operand (operands[1], VOIDmode))
8345 FAIL;
8346
8347 if (TARGET_64BIT)
8348 emit_insn (gen_extzv_64 (operands[0], operands[1],
8349 operands[2], operands[3]));
8350 else
8351 emit_insn (gen_extzv_32 (operands[0], operands[1],
8352 operands[2], operands[3]));
8353 DONE;
8354 }")
8355
8356 (define_insn "extzv_32"
8357 [(set (match_operand:SI 0 "register_operand" "=r")
8358 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8359 (match_operand:SI 2 "uint5_operand" "")
8360 (match_operand:SI 3 "uint5_operand" "")))]
8361 ""
8362 "{extru|extrw,u} %1,%3+%2-1,%2,%0"
8363 [(set_attr "type" "shift")
8364 (set_attr "length" "4")])
8365
8366 (define_insn ""
8367 [(set (match_operand:SI 0 "register_operand" "=r")
8368 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8369 (const_int 1)
8370 (match_operand:SI 2 "register_operand" "q")))]
8371 ""
8372 "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
8373 [(set_attr "type" "shift")
8374 (set_attr "length" "4")])
8375
8376 (define_insn "extzv_64"
8377 [(set (match_operand:DI 0 "register_operand" "=r")
8378 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8379 (match_operand:DI 2 "uint32_operand" "")
8380 (match_operand:DI 3 "uint32_operand" "")))]
8381 "TARGET_64BIT"
8382 "extrd,u %1,%3+%2-1,%2,%0"
8383 [(set_attr "type" "shift")
8384 (set_attr "length" "4")])
8385
8386 (define_insn ""
8387 [(set (match_operand:DI 0 "register_operand" "=r")
8388 (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8389 (const_int 1)
8390 (match_operand:DI 2 "register_operand" "q")))]
8391 "TARGET_64BIT"
8392 "extrd,u %1,%%sar,1,%0"
8393 [(set_attr "type" "shift")
8394 (set_attr "length" "4")])
8395
8396 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8397 (define_expand "extv"
8398 [(set (match_operand 0 "register_operand" "")
8399 (sign_extract (match_operand 1 "register_operand" "")
8400 (match_operand 2 "uint32_operand" "")
8401 (match_operand 3 "uint32_operand" "")))]
8402 ""
8403 "
8404 {
8405 HOST_WIDE_INT len = INTVAL (operands[2]);
8406 HOST_WIDE_INT pos = INTVAL (operands[3]);
8407
8408 /* PA extraction insns don't support zero length bitfields or fields
8409 extending beyond the left or right-most bits. Also, we reject lengths
8410 equal to a word as they are better handled by the move patterns. */
8411 if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8412 FAIL;
8413
8414 /* From mips.md: extract_bit_field doesn't verify that our source
8415 matches the predicate, so check it again here. */
8416 if (!register_operand (operands[1], VOIDmode))
8417 FAIL;
8418
8419 if (TARGET_64BIT)
8420 emit_insn (gen_extv_64 (operands[0], operands[1],
8421 operands[2], operands[3]));
8422 else
8423 emit_insn (gen_extv_32 (operands[0], operands[1],
8424 operands[2], operands[3]));
8425 DONE;
8426 }")
8427
8428 (define_insn "extv_32"
8429 [(set (match_operand:SI 0 "register_operand" "=r")
8430 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8431 (match_operand:SI 2 "uint5_operand" "")
8432 (match_operand:SI 3 "uint5_operand" "")))]
8433 ""
8434 "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
8435 [(set_attr "type" "shift")
8436 (set_attr "length" "4")])
8437
8438 (define_insn ""
8439 [(set (match_operand:SI 0 "register_operand" "=r")
8440 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8441 (const_int 1)
8442 (match_operand:SI 2 "register_operand" "q")))]
8443 "!TARGET_64BIT"
8444 "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
8445 [(set_attr "type" "shift")
8446 (set_attr "length" "4")])
8447
8448 (define_insn "extv_64"
8449 [(set (match_operand:DI 0 "register_operand" "=r")
8450 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8451 (match_operand:DI 2 "uint32_operand" "")
8452 (match_operand:DI 3 "uint32_operand" "")))]
8453 "TARGET_64BIT"
8454 "extrd,s %1,%3+%2-1,%2,%0"
8455 [(set_attr "type" "shift")
8456 (set_attr "length" "4")])
8457
8458 (define_insn ""
8459 [(set (match_operand:DI 0 "register_operand" "=r")
8460 (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8461 (const_int 1)
8462 (match_operand:DI 2 "register_operand" "q")))]
8463 "TARGET_64BIT"
8464 "extrd,s %1,%%sar,1,%0"
8465 [(set_attr "type" "shift")
8466 (set_attr "length" "4")])
8467
8468 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
8469 (define_expand "insv"
8470 [(set (zero_extract (match_operand 0 "register_operand" "")
8471 (match_operand 1 "uint32_operand" "")
8472 (match_operand 2 "uint32_operand" ""))
8473 (match_operand 3 "arith5_operand" ""))]
8474 ""
8475 "
8476 {
8477 HOST_WIDE_INT len = INTVAL (operands[1]);
8478 HOST_WIDE_INT pos = INTVAL (operands[2]);
8479
8480 /* PA insertion insns don't support zero length bitfields or fields
8481 extending beyond the left or right-most bits. Also, we reject lengths
8482 equal to a word as they are better handled by the move patterns. */
8483 if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8484 FAIL;
8485
8486 /* From mips.md: insert_bit_field doesn't verify that our destination
8487 matches the predicate, so check it again here. */
8488 if (!register_operand (operands[0], VOIDmode))
8489 FAIL;
8490
8491 if (TARGET_64BIT)
8492 emit_insn (gen_insv_64 (operands[0], operands[1],
8493 operands[2], operands[3]));
8494 else
8495 emit_insn (gen_insv_32 (operands[0], operands[1],
8496 operands[2], operands[3]));
8497 DONE;
8498 }")
8499
8500 (define_insn "insv_32"
8501 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
8502 (match_operand:SI 1 "uint5_operand" "")
8503 (match_operand:SI 2 "uint5_operand" ""))
8504 (match_operand:SI 3 "arith5_operand" "r,L"))]
8505 ""
8506 "@
8507 {dep|depw} %3,%2+%1-1,%1,%0
8508 {depi|depwi} %3,%2+%1-1,%1,%0"
8509 [(set_attr "type" "shift,shift")
8510 (set_attr "length" "4,4")])
8511
8512 ;; Optimize insertion of const_int values of type 1...1xxxx.
8513 (define_insn ""
8514 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
8515 (match_operand:SI 1 "uint5_operand" "")
8516 (match_operand:SI 2 "uint5_operand" ""))
8517 (match_operand:SI 3 "const_int_operand" ""))]
8518 "(INTVAL (operands[3]) & 0x10) != 0 &&
8519 (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8520 "*
8521 {
8522 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8523 return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
8524 }"
8525 [(set_attr "type" "shift")
8526 (set_attr "length" "4")])
8527
8528 (define_insn "insv_64"
8529 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
8530 (match_operand:DI 1 "uint32_operand" "")
8531 (match_operand:DI 2 "uint32_operand" ""))
8532 (match_operand:DI 3 "arith32_operand" "r,L"))]
8533 "TARGET_64BIT"
8534 "@
8535 depd %3,%2+%1-1,%1,%0
8536 depdi %3,%2+%1-1,%1,%0"
8537 [(set_attr "type" "shift,shift")
8538 (set_attr "length" "4,4")])
8539
8540 ;; Optimize insertion of const_int values of type 1...1xxxx.
8541 (define_insn ""
8542 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
8543 (match_operand:DI 1 "uint32_operand" "")
8544 (match_operand:DI 2 "uint32_operand" ""))
8545 (match_operand:DI 3 "const_int_operand" ""))]
8546 "(INTVAL (operands[3]) & 0x10) != 0
8547 && TARGET_64BIT
8548 && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8549 "*
8550 {
8551 operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8552 return \"depdi %3,%2+%1-1,%1,%0\";
8553 }"
8554 [(set_attr "type" "shift")
8555 (set_attr "length" "4")])
8556
8557 (define_insn ""
8558 [(set (match_operand:DI 0 "register_operand" "=r")
8559 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
8560 (const_int 32)))]
8561 "TARGET_64BIT"
8562 "depd,z %1,31,32,%0"
8563 [(set_attr "type" "shift")
8564 (set_attr "length" "4")])
8565
8566 ;; This insn is used for some loop tests, typically loops reversed when
8567 ;; strength reduction is used. It is actually created when the instruction
8568 ;; combination phase combines the special loop test. Since this insn
8569 ;; is both a jump insn and has an output, it must deal with its own
8570 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
8571 ;; to not choose the register alternatives in the event a reload is needed.
8572 (define_insn "decrement_and_branch_until_zero"
8573 [(set (pc)
8574 (if_then_else
8575 (match_operator 2 "comparison_operator"
8576 [(plus:SI
8577 (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
8578 (match_operand:SI 1 "int5_operand" "L,L,L"))
8579 (const_int 0)])
8580 (label_ref (match_operand 3 "" ""))
8581 (pc)))
8582 (set (match_dup 0)
8583 (plus:SI (match_dup 0) (match_dup 1)))
8584 (clobber (match_scratch:SI 4 "=X,r,r"))]
8585 ""
8586 "* return pa_output_dbra (operands, insn, which_alternative); "
8587 ;; Do not expect to understand this the first time through.
8588 [(set_attr "type" "cbranch,multi,multi")
8589 (set (attr "length")
8590 (if_then_else (eq_attr "alternative" "0")
8591 ;; Loop counter in register case
8592 ;; Short branch has length of 4
8593 ;; Long branch has length of 8, 20, 24 or 28
8594 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8595 (const_int MAX_12BIT_OFFSET))
8596 (const_int 4)
8597 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8598 (const_int MAX_17BIT_OFFSET))
8599 (const_int 8)
8600 (match_test "TARGET_PORTABLE_RUNTIME")
8601 (const_int 24)
8602 (not (match_test "flag_pic"))
8603 (const_int 20)]
8604 (const_int 28))
8605
8606 ;; Loop counter in FP reg case.
8607 ;; Extra goo to deal with additional reload insns.
8608 (if_then_else (eq_attr "alternative" "1")
8609 (if_then_else (lt (match_dup 3) (pc))
8610 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
8611 (const_int MAX_12BIT_OFFSET))
8612 (const_int 24)
8613 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
8614 (const_int MAX_17BIT_OFFSET))
8615 (const_int 28)
8616 (match_test "TARGET_PORTABLE_RUNTIME")
8617 (const_int 44)
8618 (not (match_test "flag_pic"))
8619 (const_int 40)]
8620 (const_int 48))
8621 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8622 (const_int MAX_12BIT_OFFSET))
8623 (const_int 24)
8624 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8625 (const_int MAX_17BIT_OFFSET))
8626 (const_int 28)
8627 (match_test "TARGET_PORTABLE_RUNTIME")
8628 (const_int 44)
8629 (not (match_test "flag_pic"))
8630 (const_int 40)]
8631 (const_int 48)))
8632
8633 ;; Loop counter in memory case.
8634 ;; Extra goo to deal with additional reload insns.
8635 (if_then_else (lt (match_dup 3) (pc))
8636 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8637 (const_int MAX_12BIT_OFFSET))
8638 (const_int 12)
8639 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8640 (const_int MAX_17BIT_OFFSET))
8641 (const_int 16)
8642 (match_test "TARGET_PORTABLE_RUNTIME")
8643 (const_int 32)
8644 (not (match_test "flag_pic"))
8645 (const_int 28)]
8646 (const_int 36))
8647 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8648 (const_int MAX_12BIT_OFFSET))
8649 (const_int 12)
8650 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8651 (const_int MAX_17BIT_OFFSET))
8652 (const_int 16)
8653 (match_test "TARGET_PORTABLE_RUNTIME")
8654 (const_int 32)
8655 (not (match_test "flag_pic"))
8656 (const_int 28)]
8657 (const_int 36))))))])
8658
8659 (define_insn ""
8660 [(set (pc)
8661 (if_then_else
8662 (match_operator 2 "movb_comparison_operator"
8663 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
8664 (label_ref (match_operand 3 "" ""))
8665 (pc)))
8666 (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
8667 (match_dup 1))]
8668 ""
8669 "* return pa_output_movb (operands, insn, which_alternative, 0); "
8670 ;; Do not expect to understand this the first time through.
8671 [(set_attr "type" "cbranch,multi,multi,multi")
8672 (set (attr "length")
8673 (if_then_else (eq_attr "alternative" "0")
8674 ;; Loop counter in register case
8675 ;; Short branch has length of 4
8676 ;; Long branch has length of 8, 20, 24 or 28
8677 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8678 (const_int MAX_12BIT_OFFSET))
8679 (const_int 4)
8680 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8681 (const_int MAX_17BIT_OFFSET))
8682 (const_int 8)
8683 (match_test "TARGET_PORTABLE_RUNTIME")
8684 (const_int 24)
8685 (not (match_test "flag_pic"))
8686 (const_int 20)]
8687 (const_int 28))
8688
8689 ;; Loop counter in FP reg case.
8690 ;; Extra goo to deal with additional reload insns.
8691 (if_then_else (eq_attr "alternative" "1")
8692 (if_then_else (lt (match_dup 3) (pc))
8693 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8694 (const_int MAX_12BIT_OFFSET))
8695 (const_int 12)
8696 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8697 (const_int MAX_17BIT_OFFSET))
8698 (const_int 16)
8699 (match_test "TARGET_PORTABLE_RUNTIME")
8700 (const_int 32)
8701 (not (match_test "flag_pic"))
8702 (const_int 28)]
8703 (const_int 36))
8704 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8705 (const_int MAX_12BIT_OFFSET))
8706 (const_int 12)
8707 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8708 (const_int MAX_17BIT_OFFSET))
8709 (const_int 16)
8710 (match_test "TARGET_PORTABLE_RUNTIME")
8711 (const_int 32)
8712 (not (match_test "flag_pic"))
8713 (const_int 28)]
8714 (const_int 36)))
8715
8716 ;; Loop counter in memory or sar case.
8717 ;; Extra goo to deal with additional reload insns.
8718 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8719 (const_int MAX_12BIT_OFFSET))
8720 (const_int 8)
8721 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8722 (const_int MAX_17BIT_OFFSET))
8723 (const_int 12)
8724 (match_test "TARGET_PORTABLE_RUNTIME")
8725 (const_int 28)
8726 (not (match_test "flag_pic"))
8727 (const_int 24)]
8728 (const_int 32)))))])
8729
8730 ;; Handle negated branch.
8731 (define_insn ""
8732 [(set (pc)
8733 (if_then_else
8734 (match_operator 2 "movb_comparison_operator"
8735 [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
8736 (pc)
8737 (label_ref (match_operand 3 "" ""))))
8738 (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
8739 (match_dup 1))]
8740 ""
8741 "* return pa_output_movb (operands, insn, which_alternative, 1); "
8742 ;; Do not expect to understand this the first time through.
8743 [(set_attr "type" "cbranch,multi,multi,multi")
8744 (set (attr "length")
8745 (if_then_else (eq_attr "alternative" "0")
8746 ;; Loop counter in register case
8747 ;; Short branch has length of 4
8748 ;; Long branch has length of 8
8749 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8750 (const_int MAX_12BIT_OFFSET))
8751 (const_int 4)
8752 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8753 (const_int MAX_17BIT_OFFSET))
8754 (const_int 8)
8755 (match_test "TARGET_PORTABLE_RUNTIME")
8756 (const_int 24)
8757 (not (match_test "flag_pic"))
8758 (const_int 20)]
8759 (const_int 28))
8760
8761 ;; Loop counter in FP reg case.
8762 ;; Extra goo to deal with additional reload insns.
8763 (if_then_else (eq_attr "alternative" "1")
8764 (if_then_else (lt (match_dup 3) (pc))
8765 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8766 (const_int MAX_12BIT_OFFSET))
8767 (const_int 12)
8768 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8769 (const_int MAX_17BIT_OFFSET))
8770 (const_int 16)
8771 (match_test "TARGET_PORTABLE_RUNTIME")
8772 (const_int 32)
8773 (not (match_test "flag_pic"))
8774 (const_int 28)]
8775 (const_int 36))
8776 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8777 (const_int MAX_12BIT_OFFSET))
8778 (const_int 12)
8779 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8780 (const_int MAX_17BIT_OFFSET))
8781 (const_int 16)
8782 (match_test "TARGET_PORTABLE_RUNTIME")
8783 (const_int 32)
8784 (not (match_test "flag_pic"))
8785 (const_int 28)]
8786 (const_int 36)))
8787
8788 ;; Loop counter in memory or SAR case.
8789 ;; Extra goo to deal with additional reload insns.
8790 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8791 (const_int MAX_12BIT_OFFSET))
8792 (const_int 8)
8793 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8794 (const_int MAX_17BIT_OFFSET))
8795 (const_int 12)
8796 (match_test "TARGET_PORTABLE_RUNTIME")
8797 (const_int 28)
8798 (not (match_test "flag_pic"))
8799 (const_int 24)]
8800 (const_int 32)))))])
8801
8802 (define_insn ""
8803 [(set (pc) (label_ref (match_operand 3 "" "" )))
8804 (set (match_operand:SI 0 "ireg_operand" "=r")
8805 (plus:SI (match_operand:SI 1 "ireg_operand" "r")
8806 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
8807 "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
8808 "*
8809 {
8810 return pa_output_parallel_addb (operands, insn);
8811 }"
8812 [(set_attr "type" "parallel_branch")
8813 (set (attr "length")
8814 (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8815 (const_int MAX_12BIT_OFFSET))
8816 (const_int 4)
8817 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8818 (const_int MAX_17BIT_OFFSET))
8819 (const_int 8)
8820 (match_test "TARGET_PORTABLE_RUNTIME")
8821 (const_int 24)
8822 (not (match_test "flag_pic"))
8823 (const_int 20)]
8824 (const_int 28)))])
8825
8826 (define_insn ""
8827 [(set (pc) (label_ref (match_operand 2 "" "" )))
8828 (set (match_operand:SF 0 "ireg_operand" "=r")
8829 (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
8830 "reload_completed"
8831 "*
8832 {
8833 return pa_output_parallel_movb (operands, insn);
8834 }"
8835 [(set_attr "type" "parallel_branch")
8836 (set (attr "length")
8837 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8838 (const_int MAX_12BIT_OFFSET))
8839 (const_int 4)
8840 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8841 (const_int MAX_17BIT_OFFSET))
8842 (const_int 8)
8843 (match_test "TARGET_PORTABLE_RUNTIME")
8844 (const_int 24)
8845 (not (match_test "flag_pic"))
8846 (const_int 20)]
8847 (const_int 28)))])
8848
8849 (define_insn ""
8850 [(set (pc) (label_ref (match_operand 2 "" "" )))
8851 (set (match_operand:SI 0 "ireg_operand" "=r")
8852 (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
8853 "reload_completed"
8854 "*
8855 {
8856 return pa_output_parallel_movb (operands, insn);
8857 }"
8858 [(set_attr "type" "parallel_branch")
8859 (set (attr "length")
8860 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8861 (const_int MAX_12BIT_OFFSET))
8862 (const_int 4)
8863 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8864 (const_int MAX_17BIT_OFFSET))
8865 (const_int 8)
8866 (match_test "TARGET_PORTABLE_RUNTIME")
8867 (const_int 24)
8868 (not (match_test "flag_pic"))
8869 (const_int 20)]
8870 (const_int 28)))])
8871
8872 (define_insn ""
8873 [(set (pc) (label_ref (match_operand 2 "" "" )))
8874 (set (match_operand:HI 0 "ireg_operand" "=r")
8875 (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
8876 "reload_completed"
8877 "*
8878 {
8879 return pa_output_parallel_movb (operands, insn);
8880 }"
8881 [(set_attr "type" "parallel_branch")
8882 (set (attr "length")
8883 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8884 (const_int MAX_12BIT_OFFSET))
8885 (const_int 4)
8886 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8887 (const_int MAX_17BIT_OFFSET))
8888 (const_int 8)
8889 (match_test "TARGET_PORTABLE_RUNTIME")
8890 (const_int 24)
8891 (not (match_test "flag_pic"))
8892 (const_int 20)]
8893 (const_int 28)))])
8894
8895 (define_insn ""
8896 [(set (pc) (label_ref (match_operand 2 "" "" )))
8897 (set (match_operand:QI 0 "ireg_operand" "=r")
8898 (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
8899 "reload_completed"
8900 "*
8901 {
8902 return pa_output_parallel_movb (operands, insn);
8903 }"
8904 [(set_attr "type" "parallel_branch")
8905 (set (attr "length")
8906 (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8907 (const_int MAX_12BIT_OFFSET))
8908 (const_int 4)
8909 (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8910 (const_int MAX_17BIT_OFFSET))
8911 (const_int 8)
8912 (match_test "TARGET_PORTABLE_RUNTIME")
8913 (const_int 24)
8914 (not (match_test "flag_pic"))
8915 (const_int 20)]
8916 (const_int 28)))])
8917
8918 (define_insn ""
8919 [(set (match_operand 0 "register_operand" "=f")
8920 (mult (match_operand 1 "register_operand" "f")
8921 (match_operand 2 "register_operand" "f")))
8922 (set (match_operand 3 "register_operand" "+f")
8923 (plus (match_operand 4 "register_operand" "f")
8924 (match_operand 5 "register_operand" "f")))]
8925 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8926 && reload_completed && pa_fmpyaddoperands (operands)"
8927 "*
8928 {
8929 if (GET_MODE (operands[0]) == DFmode)
8930 {
8931 if (rtx_equal_p (operands[3], operands[5]))
8932 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
8933 else
8934 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
8935 }
8936 else
8937 {
8938 if (rtx_equal_p (operands[3], operands[5]))
8939 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
8940 else
8941 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
8942 }
8943 }"
8944 [(set_attr "type" "fpalu")
8945 (set_attr "length" "4")])
8946
8947 (define_insn ""
8948 [(set (match_operand 3 "register_operand" "+f")
8949 (plus (match_operand 4 "register_operand" "f")
8950 (match_operand 5 "register_operand" "f")))
8951 (set (match_operand 0 "register_operand" "=f")
8952 (mult (match_operand 1 "register_operand" "f")
8953 (match_operand 2 "register_operand" "f")))]
8954 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8955 && reload_completed && pa_fmpyaddoperands (operands)"
8956 "*
8957 {
8958 if (GET_MODE (operands[0]) == DFmode)
8959 {
8960 if (rtx_equal_p (operands[3], operands[5]))
8961 return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
8962 else
8963 return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
8964 }
8965 else
8966 {
8967 if (rtx_equal_p (operands[3], operands[5]))
8968 return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
8969 else
8970 return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
8971 }
8972 }"
8973 [(set_attr "type" "fpalu")
8974 (set_attr "length" "4")])
8975
8976 (define_insn ""
8977 [(set (match_operand 0 "register_operand" "=f")
8978 (mult (match_operand 1 "register_operand" "f")
8979 (match_operand 2 "register_operand" "f")))
8980 (set (match_operand 3 "register_operand" "+f")
8981 (minus (match_operand 4 "register_operand" "f")
8982 (match_operand 5 "register_operand" "f")))]
8983 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8984 && reload_completed && pa_fmpysuboperands (operands)"
8985 "*
8986 {
8987 if (GET_MODE (operands[0]) == DFmode)
8988 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
8989 else
8990 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
8991 }"
8992 [(set_attr "type" "fpalu")
8993 (set_attr "length" "4")])
8994
8995 (define_insn ""
8996 [(set (match_operand 3 "register_operand" "+f")
8997 (minus (match_operand 4 "register_operand" "f")
8998 (match_operand 5 "register_operand" "f")))
8999 (set (match_operand 0 "register_operand" "=f")
9000 (mult (match_operand 1 "register_operand" "f")
9001 (match_operand 2 "register_operand" "f")))]
9002 "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9003 && reload_completed && pa_fmpysuboperands (operands)"
9004 "*
9005 {
9006 if (GET_MODE (operands[0]) == DFmode)
9007 return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9008 else
9009 return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9010 }"
9011 [(set_attr "type" "fpalu")
9012 (set_attr "length" "4")])
9013
9014 ;; The following two patterns are used by the trampoline code for nested
9015 ;; functions. They flush the I and D cache lines from the start address
9016 ;; (operand0) to the end address (operand1). No lines are flushed if the
9017 ;; end address is less than the start address (unsigned).
9018 ;;
9019 ;; Because the range of memory flushed is variable and the size of a MEM
9020 ;; can only be a CONST_INT, the patterns specify that they perform an
9021 ;; unspecified volatile operation on all memory.
9022 ;;
9023 ;; The address range for an icache flush must lie within a single
9024 ;; space on targets with non-equivalent space registers.
9025 ;;
9026 ;; Operand 0 contains the start address.
9027 ;; Operand 1 contains the end address.
9028 ;; Operand 2 contains the line length to use.
9029 (define_insn "dcacheflush<P:mode>"
9030 [(const_int 1)
9031 (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9032 (use (match_operand 0 "pmode_register_operand" "r"))
9033 (use (match_operand 1 "pmode_register_operand" "r"))
9034 (use (match_operand 2 "pmode_register_operand" "r"))
9035 (clobber (match_scratch:P 3 "=&0"))]
9036 ""
9037 "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9038 [(set_attr "type" "multi")
9039 (set_attr "length" "12")])
9040
9041 (define_insn "icacheflush<P:mode>"
9042 [(const_int 2)
9043 (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9044 (use (match_operand 0 "pmode_register_operand" "r"))
9045 (use (match_operand 1 "pmode_register_operand" "r"))
9046 (use (match_operand 2 "pmode_register_operand" "r"))
9047 (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9048 (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9049 (clobber (match_scratch:P 5 "=&0"))]
9050 ""
9051 "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"
9052 [(set_attr "type" "multi")
9053 (set_attr "length" "52")])
9054
9055 ;; An out-of-line prologue.
9056 (define_insn "outline_prologue_call"
9057 [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9058 (clobber (reg:SI 31))
9059 (clobber (reg:SI 22))
9060 (clobber (reg:SI 21))
9061 (clobber (reg:SI 20))
9062 (clobber (reg:SI 19))
9063 (clobber (reg:SI 1))]
9064 ""
9065 "*
9066 {
9067
9068 /* We need two different versions depending on whether or not we
9069 need a frame pointer. Also note that we return to the instruction
9070 immediately after the branch rather than two instructions after the
9071 break as normally is the case. */
9072 if (frame_pointer_needed)
9073 {
9074 /* Must import the magic millicode routine(s). */
9075 output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9076
9077 if (TARGET_PORTABLE_RUNTIME)
9078 {
9079 output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9080 output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9081 NULL);
9082 }
9083 else
9084 output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9085 }
9086 else
9087 {
9088 /* Must import the magic millicode routine(s). */
9089 output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9090
9091 if (TARGET_PORTABLE_RUNTIME)
9092 {
9093 output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9094 output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9095 }
9096 else
9097 output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9098 }
9099 return \"\";
9100 }"
9101 [(set_attr "type" "multi")
9102 (set_attr "length" "8")])
9103
9104 ;; An out-of-line epilogue.
9105 (define_insn "outline_epilogue_call"
9106 [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9107 (use (reg:SI 29))
9108 (use (reg:SI 28))
9109 (clobber (reg:SI 31))
9110 (clobber (reg:SI 22))
9111 (clobber (reg:SI 21))
9112 (clobber (reg:SI 20))
9113 (clobber (reg:SI 19))
9114 (clobber (reg:SI 2))
9115 (clobber (reg:SI 1))]
9116 ""
9117 "*
9118 {
9119
9120 /* We need two different versions depending on whether or not we
9121 need a frame pointer. Also note that we return to the instruction
9122 immediately after the branch rather than two instructions after the
9123 break as normally is the case. */
9124 if (frame_pointer_needed)
9125 {
9126 /* Must import the magic millicode routine. */
9127 output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9128
9129 /* The out-of-line prologue will make sure we return to the right
9130 instruction. */
9131 if (TARGET_PORTABLE_RUNTIME)
9132 {
9133 output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9134 output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9135 NULL);
9136 }
9137 else
9138 output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9139 }
9140 else
9141 {
9142 /* Must import the magic millicode routine. */
9143 output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9144
9145 /* The out-of-line prologue will make sure we return to the right
9146 instruction. */
9147 if (TARGET_PORTABLE_RUNTIME)
9148 {
9149 output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9150 output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9151 }
9152 else
9153 output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9154 }
9155 return \"\";
9156 }"
9157 [(set_attr "type" "multi")
9158 (set_attr "length" "8")])
9159
9160 ;; Given a function pointer, canonicalize it so it can be
9161 ;; reliably compared to another function pointer. */
9162 (define_expand "canonicalize_funcptr_for_compare"
9163 [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9164 (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9165 (clobber (match_dup 2))
9166 (clobber (reg:SI 26))
9167 (clobber (reg:SI 22))
9168 (clobber (reg:SI 31))])
9169 (set (match_operand:SI 0 "register_operand" "")
9170 (reg:SI 29))]
9171 "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9172 "
9173 {
9174 if (TARGET_ELF32)
9175 {
9176 rtx canonicalize_funcptr_for_compare_libfunc
9177 = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9178
9179 emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9180 operands[0], LCT_NORMAL, Pmode,
9181 1, operands[1], Pmode);
9182 DONE;
9183 }
9184
9185 operands[2] = gen_reg_rtx (SImode);
9186 if (GET_CODE (operands[1]) != REG)
9187 {
9188 rtx tmp = gen_reg_rtx (Pmode);
9189 emit_move_insn (tmp, operands[1]);
9190 operands[1] = tmp;
9191 }
9192 }")
9193
9194 (define_insn "*$$sh_func_adrs"
9195 [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9196 (clobber (match_operand:SI 0 "register_operand" "=a"))
9197 (clobber (reg:SI 26))
9198 (clobber (reg:SI 22))
9199 (clobber (reg:SI 31))]
9200 "!TARGET_64BIT"
9201 "*
9202 {
9203 int length = get_attr_length (insn);
9204 rtx xoperands[2];
9205
9206 xoperands[0] = GEN_INT (length - 8);
9207 xoperands[1] = GEN_INT (length - 16);
9208
9209 /* Must import the magic millicode routine. */
9210 output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9211
9212 /* This is absolutely amazing.
9213
9214 First, copy our input parameter into %r29 just in case we don't
9215 need to call $$sh_func_adrs. */
9216 output_asm_insn (\"copy %%r26,%%r29\", NULL);
9217 output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9218
9219 /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9220 we use %r26 unchanged. */
9221 output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9222 output_asm_insn (\"ldi 4096,%%r31\", NULL);
9223
9224 /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9225 4096, then again we use %r26 unchanged. */
9226 output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9227
9228 /* Finally, call $$sh_func_adrs to extract the function's real add24. */
9229 return pa_output_millicode_call (insn,
9230 gen_rtx_SYMBOL_REF (SImode,
9231 \"$$sh_func_adrs\"));
9232 }"
9233 [(set_attr "type" "sh_func_adrs")
9234 (set (attr "length")
9235 (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 28)]
9236 (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9237 (const_int 20))))])
9238
9239 ;; On the PA, the PIC register is call clobbered, so it must
9240 ;; be saved & restored around calls by the caller. If the call
9241 ;; doesn't return normally (nonlocal goto, or an exception is
9242 ;; thrown), then the code at the exception handler label must
9243 ;; restore the PIC register.
9244 (define_expand "exception_receiver"
9245 [(const_int 4)]
9246 "flag_pic"
9247 "
9248 {
9249 /* On the 64-bit port, we need a blockage because there is
9250 confusion regarding the dependence of the restore on the
9251 frame pointer. As a result, the frame pointer and pic
9252 register restores sometimes are interchanged erroneously. */
9253 if (TARGET_64BIT)
9254 emit_insn (gen_blockage ());
9255 /* Restore the PIC register using hppa_pic_save_rtx (). The
9256 PIC register is not saved in the frame in 64-bit ABI. */
9257 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9258 emit_insn (gen_blockage ());
9259 DONE;
9260 }")
9261
9262 (define_expand "builtin_setjmp_receiver"
9263 [(label_ref (match_operand 0 "" ""))]
9264 "flag_pic"
9265 "
9266 {
9267 if (TARGET_64BIT)
9268 emit_insn (gen_blockage ());
9269 /* Restore the PIC register. Hopefully, this will always be from
9270 a stack slot. The only registers that are valid after a
9271 builtin_longjmp are the stack and frame pointers. */
9272 emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9273 emit_insn (gen_blockage ());
9274 DONE;
9275 }")
9276
9277 ;; Allocate new stack space and update the saved stack pointer in the
9278 ;; frame marker. The HP C compilers also copy additional words in the
9279 ;; frame marker. The 64-bit compiler copies words at -48, -32 and -24.
9280 ;; The 32-bit compiler copies the word at -16 (Static Link). We
9281 ;; currently don't copy these values.
9282 ;;
9283 ;; Since the copy of the frame marker can't be done atomically, I
9284 ;; suspect that using it for unwind purposes may be somewhat unreliable.
9285 ;; The HP compilers appear to raise the stack and copy the frame
9286 ;; marker in a strict instruction sequence. This suggests that the
9287 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
9288 ;; is set in the callinfo data. We currently don't set ALLOCA_FRAME
9289 ;; as GAS doesn't support it, or try to keep the instructions emitted
9290 ;; here in strict sequence.
9291 (define_expand "allocate_stack"
9292 [(match_operand 0 "" "")
9293 (match_operand 1 "" "")]
9294 ""
9295 "
9296 {
9297 rtx addr;
9298
9299 /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
9300 in operand 0 before adjusting the stack. */
9301 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9302 anti_adjust_stack (operands[1]);
9303 if (TARGET_HPUX_UNWIND_LIBRARY)
9304 {
9305 addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
9306 GEN_INT (TARGET_64BIT ? -8 : -4));
9307 emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
9308 }
9309 if (!TARGET_64BIT && flag_pic)
9310 {
9311 rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
9312 emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
9313 }
9314 DONE;
9315 }")
9316
9317 (define_expand "prefetch"
9318 [(match_operand 0 "address_operand" "")
9319 (match_operand 1 "const_int_operand" "")
9320 (match_operand 2 "const_int_operand" "")]
9321 "TARGET_PA_20"
9322 {
9323 operands[0] = copy_addr_to_reg (operands[0]);
9324 emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
9325 DONE;
9326 })
9327
9328 (define_insn "prefetch_20"
9329 [(prefetch (match_operand 0 "pmode_register_operand" "r")
9330 (match_operand:SI 1 "const_int_operand" "n")
9331 (match_operand:SI 2 "const_int_operand" "n"))]
9332 "TARGET_PA_20"
9333 {
9334 /* The SL cache-control completer indicates good spatial locality but
9335 poor temporal locality. The ldw instruction with a target of general
9336 register 0 prefetches a cache line for a read. The ldd instruction
9337 prefetches a cache line for a write. */
9338 static const char * const instr[2][2] = {
9339 {
9340 "ldw,sl 0(%0),%%r0",
9341 "ldd,sl 0(%0),%%r0"
9342 },
9343 {
9344 "ldw 0(%0),%%r0",
9345 "ldd 0(%0),%%r0"
9346 }
9347 };
9348 int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
9349 int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
9350
9351 return instr [locality][read_or_write];
9352 }
9353 [(set_attr "type" "load")
9354 (set_attr "length" "4")])
9355
9356 ;; TLS Support
9357 (define_insn "tgd_load"
9358 [(set (match_operand:SI 0 "register_operand" "=r")
9359 (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
9360 (clobber (reg:SI 1))
9361 (use (reg:SI 27))]
9362 ""
9363 "*
9364 {
9365 return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
9366 }"
9367 [(set_attr "type" "multi")
9368 (set_attr "length" "8")])
9369
9370 (define_insn "tgd_load_pic"
9371 [(set (match_operand:SI 0 "register_operand" "=r")
9372 (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
9373 (clobber (reg:SI 1))
9374 (use (reg:SI 19))]
9375 ""
9376 "*
9377 {
9378 return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
9379 }"
9380 [(set_attr "type" "multi")
9381 (set_attr "length" "8")])
9382
9383 (define_insn "tld_load"
9384 [(set (match_operand:SI 0 "register_operand" "=r")
9385 (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
9386 (clobber (reg:SI 1))
9387 (use (reg:SI 27))]
9388 ""
9389 "*
9390 {
9391 return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
9392 }"
9393 [(set_attr "type" "multi")
9394 (set_attr "length" "8")])
9395
9396 (define_insn "tld_load_pic"
9397 [(set (match_operand:SI 0 "register_operand" "=r")
9398 (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
9399 (clobber (reg:SI 1))
9400 (use (reg:SI 19))]
9401 ""
9402 "*
9403 {
9404 return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
9405 }"
9406 [(set_attr "type" "multi")
9407 (set_attr "length" "8")])
9408
9409 (define_insn "tld_offset_load"
9410 [(set (match_operand:SI 0 "register_operand" "=r")
9411 (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
9412 UNSPEC_TLSLDO)
9413 (match_operand:SI 2 "register_operand" "r")))
9414 (clobber (reg:SI 1))]
9415 ""
9416 "*
9417 {
9418 return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
9419 }"
9420 [(set_attr "type" "multi")
9421 (set_attr "length" "8")])
9422
9423 (define_insn "tp_load"
9424 [(set (match_operand:SI 0 "register_operand" "=r")
9425 (unspec:SI [(const_int 0)] UNSPEC_TP))]
9426 ""
9427 "mfctl %%cr27,%0"
9428 [(set_attr "type" "multi")
9429 (set_attr "length" "4")])
9430
9431 (define_insn "tie_load"
9432 [(set (match_operand:SI 0 "register_operand" "=r")
9433 (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
9434 (clobber (reg:SI 1))
9435 (use (reg:SI 27))]
9436 ""
9437 "*
9438 {
9439 return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
9440 }"
9441 [(set_attr "type" "multi")
9442 (set_attr "length" "8")])
9443
9444 (define_insn "tie_load_pic"
9445 [(set (match_operand:SI 0 "register_operand" "=r")
9446 (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
9447 (clobber (reg:SI 1))
9448 (use (reg:SI 19))]
9449 ""
9450 "*
9451 {
9452 return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
9453 }"
9454 [(set_attr "type" "multi")
9455 (set_attr "length" "8")])
9456
9457 (define_insn "tle_load"
9458 [(set (match_operand:SI 0 "register_operand" "=r")
9459 (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
9460 UNSPEC_TLSLE)
9461 (match_operand:SI 2 "register_operand" "r")))
9462 (clobber (reg:SI 1))]
9463 ""
9464 "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
9465 [(set_attr "type" "multi")
9466 (set_attr "length" "8")])