OSDN Git Service

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