OSDN Git Service

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