OSDN Git Service

* pa.md (exception_receiver, builtin_setjmp_receiver): Add blockage
[pf3gnuchains/gcc-fork.git] / gcc / config / pa / pa.md
1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;;   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 ;;   2002 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 GNU CC.
8
9 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 ;; Insn type.  Used to default other attribute values.
30
31 ;; type "unary" insns have one input operand (1) and one output operand (0)
32 ;; type "binary" insns have two input operands (1,2) and one output (0)
33
34 (define_attr "type"
35   "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
36   (const_string "binary"))
37
38 (define_attr "pa_combine_type"
39   "fmpy,faddsub,uncond_branch,addmove,none"
40   (const_string "none"))
41
42 ;; Processor type (for scheduling, not code generation) -- this attribute
43 ;; must exactly match the processor_type enumeration in pa.h.
44 ;;
45 ;; FIXME: Add 800 scheduling for completeness?
46
47 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
48
49 ;; Length (in # of bytes).
50 (define_attr "length" ""
51   (cond [(eq_attr "type" "load,fpload")
52          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
53                        (const_int 8) (const_int 4))
54
55          (eq_attr "type" "store,fpstore")
56          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
57                        (const_int 8) (const_int 4))
58
59          (eq_attr "type" "binary,shift,nullshift")
60          (if_then_else (match_operand 2 "arith_operand" "")
61                        (const_int 4) (const_int 12))
62
63          (eq_attr "type" "move,unary,shift,nullshift")
64          (if_then_else (match_operand 1 "arith_operand" "")
65                        (const_int 4) (const_int 8))]
66
67         (const_int 4)))
68
69 (define_asm_attributes
70   [(set_attr "length" "4")
71    (set_attr "type" "multi")])
72
73 ;; Attributes for instruction and branch scheduling
74
75 ;; For conditional branches.
76 (define_attr "in_branch_delay" "false,true"
77   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
78                      (eq_attr "length" "4"))
79                 (const_string "true")
80                 (const_string "false")))
81
82 ;; Disallow instructions which use the FPU since they will tie up the FPU
83 ;; even if the instruction is nullified.
84 (define_attr "in_nullified_branch_delay" "false,true"
85   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
86                      (eq_attr "length" "4"))
87                 (const_string "true")
88                 (const_string "false")))
89
90 ;; For calls and millicode calls.  Allow unconditional branches in the
91 ;; delay slot.
92 (define_attr "in_call_delay" "false,true"
93   (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
94               (eq_attr "length" "4"))
95            (const_string "true")
96          (eq_attr "type" "uncond_branch")
97            (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
98                              (const_int 0))
99                          (const_string "true")
100                          (const_string "false"))]
101         (const_string "false")))
102
103
104 ;; Call delay slot description.
105 (define_delay (eq_attr "type" "call")
106   [(eq_attr "in_call_delay" "true") (nil) (nil)])
107
108 ;; millicode call delay slot description.  Note it disallows delay slot
109 ;; when TARGET_PORTABLE_RUNTIME is true.
110 (define_delay (eq_attr "type" "milli")
111   [(and (eq_attr "in_call_delay" "true")
112         (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
113    (nil) (nil)])
114
115 ;; Return and other similar instructions.
116 (define_delay (eq_attr "type" "branch,parallel_branch")
117   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
118
119 ;; Floating point conditional branch delay slot description and
120 (define_delay (eq_attr "type" "fbranch")
121   [(eq_attr "in_branch_delay" "true")
122    (eq_attr "in_nullified_branch_delay" "true")
123    (nil)])
124
125 ;; Integer conditional branch delay slot description.
126 ;; Nullification of conditional branches on the PA is dependent on the
127 ;; direction of the branch.  Forward branches nullify true and
128 ;; backward branches nullify false.  If the direction is unknown
129 ;; then nullification is not allowed.
130 (define_delay (eq_attr "type" "cbranch")
131   [(eq_attr "in_branch_delay" "true")
132    (and (eq_attr "in_nullified_branch_delay" "true")
133         (attr_flag "forward"))
134    (and (eq_attr "in_nullified_branch_delay" "true")
135         (attr_flag "backward"))])
136
137 (define_delay (and (eq_attr "type" "uncond_branch")
138                    (eq (symbol_ref "following_call (insn)")
139                        (const_int 0)))
140   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
141
142 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
143 ;; load: 2, fpload: 3
144 ;; store, fpstore: 3, no D-cache operations should be scheduled.
145
146 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
147 ;; Timings:
148 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
149 ;; fcpy         3       ALU     2
150 ;; fabs         3       ALU     2
151 ;; fadd         3       ALU     2
152 ;; fsub         3       ALU     2
153 ;; fcmp         3       ALU     2
154 ;; fcnv         3       ALU     2
155 ;; fmpyadd      3       ALU,MPY 2
156 ;; fmpysub      3       ALU,MPY 2
157 ;; fmpycfxt     3       ALU,MPY 2
158 ;; fmpy         3       MPY     2
159 ;; fmpyi        3       MPY     2
160 ;; fdiv,sgl     10      MPY     10
161 ;; fdiv,dbl     12      MPY     12
162 ;; fsqrt,sgl    14      MPY     14
163 ;; fsqrt,dbl    18      MPY     18
164 ;;
165 ;; We don't model fmpyadd/fmpysub properly as those instructions
166 ;; keep both the FP ALU and MPY units busy.  Given that these
167 ;; processors are obsolete, I'm not going to spend the time to
168 ;; model those instructions correctly.
169
170 (define_automaton "pa700")
171 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
172
173 (define_insn_reservation "W0" 4
174   (and (eq_attr "type" "fpcc")
175        (eq_attr "cpu" "700"))
176   "fpalu_700*2")
177
178 (define_insn_reservation "W1" 3
179   (and (eq_attr "type" "fpalu")
180        (eq_attr "cpu" "700"))
181   "fpalu_700*2")
182
183 (define_insn_reservation "W2" 3
184   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
185        (eq_attr "cpu" "700"))
186   "fpmpy_700*2")
187
188 (define_insn_reservation "W3" 10
189   (and (eq_attr "type" "fpdivsgl")
190        (eq_attr "cpu" "700"))
191   "fpmpy_700*10")
192
193 (define_insn_reservation "W4" 12
194   (and (eq_attr "type" "fpdivdbl")
195        (eq_attr "cpu" "700"))
196   "fpmpy_700*12")
197
198 (define_insn_reservation "W5" 14
199   (and (eq_attr "type" "fpsqrtsgl")
200        (eq_attr "cpu" "700"))
201   "fpmpy_700*14")
202
203 (define_insn_reservation "W6" 18
204   (and (eq_attr "type" "fpsqrtdbl")
205        (eq_attr "cpu" "700"))
206   "fpmpy_700*18")
207
208 (define_insn_reservation "W7" 2
209   (and (eq_attr "type" "load")
210        (eq_attr "cpu" "700"))
211   "mem_700")
212
213 (define_insn_reservation "W8" 2
214   (and (eq_attr "type" "fpload")
215        (eq_attr "cpu" "700"))
216   "mem_700")
217
218 (define_insn_reservation "W9" 3
219   (and (eq_attr "type" "store")
220        (eq_attr "cpu" "700"))
221   "mem_700*3")
222
223 (define_insn_reservation "W10" 3
224   (and (eq_attr "type" "fpstore")
225        (eq_attr "cpu" "700"))
226   "mem_700*3")
227
228 (define_insn_reservation "W11" 1
229   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore")
230        (eq_attr "cpu" "700"))
231   "dummy_700")
232
233 ;; We have a bypass for all computations in the FP unit which feed an
234 ;; FP store as long as the sizes are the same.
235 (define_bypass 2 "W1,W2" "W10" "hppa_fpstore_bypass_p")
236 (define_bypass 9 "W3" "W10" "hppa_fpstore_bypass_p")
237 (define_bypass 11 "W4" "W10" "hppa_fpstore_bypass_p")
238 (define_bypass 13 "W5" "W10" "hppa_fpstore_bypass_p")
239 (define_bypass 17 "W6" "W10" "hppa_fpstore_bypass_p")
240
241 ;; We have an "anti-bypass" for FP loads which feed an FP store.
242 (define_bypass 4 "W8" "W10" "hppa_fpstore_bypass_p")
243
244 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
245 ;; floating point computations with non-floating point computations (fp loads
246 ;; and stores are not fp computations).
247 ;;
248 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
249 ;; take two cycles, during which no Dcache operations should be scheduled.
250 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
251 ;; all have the same memory characteristics if one disregards cache misses.
252 ;;
253 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
254 ;; There's no value in modeling the ALU and MUL separately though
255 ;; since there can never be a functional unit conflict given the
256 ;; latency and issue rates for those units.
257 ;;
258 ;; Timings:
259 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
260 ;; fcpy         2       ALU     1
261 ;; fabs         2       ALU     1
262 ;; fadd         2       ALU     1
263 ;; fsub         2       ALU     1
264 ;; fcmp         2       ALU     1
265 ;; fcnv         2       ALU     1
266 ;; fmpyadd      2       ALU,MPY 1
267 ;; fmpysub      2       ALU,MPY 1
268 ;; fmpycfxt     2       ALU,MPY 1
269 ;; fmpy         2       MPY     1
270 ;; fmpyi        2       MPY     1
271 ;; fdiv,sgl     8       DIV     8
272 ;; fdiv,dbl     15      DIV     15
273 ;; fsqrt,sgl    8       DIV     8
274 ;; fsqrt,dbl    15      DIV     15
275
276 (define_automaton "pa7100")
277 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
278
279 (define_insn_reservation "X0" 2
280   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
281        (eq_attr "cpu" "7100"))
282   "f_7100,fpmac_7100")
283
284 (define_insn_reservation "X1" 8
285   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
286        (eq_attr "cpu" "7100"))
287   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
288
289 (define_insn_reservation "X2" 15
290   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
291        (eq_attr "cpu" "7100"))
292   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
293
294 (define_insn_reservation "X3" 2
295   (and (eq_attr "type" "load")
296        (eq_attr "cpu" "7100"))
297   "i_7100+mem_7100")
298
299 (define_insn_reservation "X4" 2
300   (and (eq_attr "type" "fpload")
301        (eq_attr "cpu" "7100"))
302   "i_7100+mem_7100")
303
304 (define_insn_reservation "X5" 2
305   (and (eq_attr "type" "store")
306        (eq_attr "cpu" "7100"))
307   "i_7100+mem_7100,mem_7100")
308
309 (define_insn_reservation "X6" 2
310   (and (eq_attr "type" "fpstore")
311        (eq_attr "cpu" "7100"))
312   "i_7100+mem_7100,mem_7100")
313
314 (define_insn_reservation "X7" 1
315   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore")
316        (eq_attr "cpu" "7100"))
317   "i_7100")
318
319 ;; We have a bypass for all computations in the FP unit which feed an
320 ;; FP store as long as the sizes are the same.
321 (define_bypass 1 "X0" "X6" "hppa_fpstore_bypass_p")
322 (define_bypass 7 "X1" "X6" "hppa_fpstore_bypass_p")
323 (define_bypass 14 "X2" "X6" "hppa_fpstore_bypass_p")
324
325 ;; We have an "anti-bypass" for FP loads which feed an FP store.
326 (define_bypass 3 "X4" "X6" "hppa_fpstore_bypass_p")
327
328 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
329 ;; There's no value in modeling the ALU and MUL separately though
330 ;; since there can never be a functional unit conflict that
331 ;; can be avoided given the latency, issue rates and mandatory
332 ;; one cycle cpu-wide lock for a double precision fp multiply.
333 ;;
334 ;; Timings:
335 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
336 ;; fcpy         2       ALU     1
337 ;; fabs         2       ALU     1
338 ;; fadd         2       ALU     1
339 ;; fsub         2       ALU     1
340 ;; fcmp         2       ALU     1
341 ;; fcnv         2       ALU     1
342 ;; fmpyadd,sgl  2       ALU,MPY 1
343 ;; fmpyadd,dbl  3       ALU,MPY 2
344 ;; fmpysub,sgl  2       ALU,MPY 1
345 ;; fmpysub,dbl  3       ALU,MPY 2
346 ;; fmpycfxt,sgl 2       ALU,MPY 1
347 ;; fmpycfxt,dbl 3       ALU,MPY 2
348 ;; fmpy,sgl     2       MPY     1
349 ;; fmpy,dbl     3       MPY     2
350 ;; fmpyi        3       MPY     2
351 ;; fdiv,sgl     8       DIV     8
352 ;; fdiv,dbl     15      DIV     15
353 ;; fsqrt,sgl    8       DIV     8
354 ;; fsqrt,dbl    15      DIV     15
355 ;;
356 ;; The PA7200 is just like the PA7100LC except that there is
357 ;; no store-store penalty.
358 ;;
359 ;; The PA7300 is just like the PA7200 except that there is
360 ;; no store-load penalty.
361 ;;
362 ;; Note there are some aspects of the 7100LC we are not modeling
363 ;; at the moment.  I'll be reviewing the 7100LC scheduling info
364 ;; shortly and updating this description.
365 ;;
366 ;;   load-load pairs
367 ;;   store-store pairs
368 ;;   other issue modeling
369
370 (define_automaton "pa7100lc")
371 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
372 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
373 (define_cpu_unit "mem_7100lc" "pa7100lc")
374
375 ;; Double precision multiplies lock the entire CPU for one
376 ;; cycle.  There is no way to avoid this lock and trying to
377 ;; schedule around the lock is pointless and thus there is no
378 ;; value in trying to model this lock.
379 ;;
380 ;; Not modeling the lock allows us to treat fp multiplies just
381 ;; like any other FP alu instruction.  It allows for a smaller
382 ;; DFA and may reduce register pressure.
383 (define_insn_reservation "Y0" 2
384   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
385        (eq_attr "cpu" "7100LC,7200,7300"))
386   "f_7100lc,fpmac_7100lc")
387
388 ;; fp division and sqrt instructions lock the entire CPU for
389 ;; 7 cycles (single precision) or 14 cycles (double precision).
390 ;; There is no way to avoid this lock and trying to schedule
391 ;; around the lock is pointless and thus there is no value in
392 ;; trying to model this lock.  Not modeling the lock allows
393 ;; for a smaller DFA and may reduce register pressure.
394 (define_insn_reservation "Y1" 1
395   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
396        (eq_attr "cpu" "7100LC,7200,7300"))
397   "f_7100lc")
398
399 (define_insn_reservation "Y2" 2
400   (and (eq_attr "type" "load")
401        (eq_attr "cpu" "7100LC,7200,7300"))
402   "i1_7100lc+mem_7100lc")
403
404 (define_insn_reservation "Y3" 2
405   (and (eq_attr "type" "fpload")
406        (eq_attr "cpu" "7100LC,7200,7300"))
407   "i1_7100lc+mem_7100lc")
408
409 (define_insn_reservation "Y4" 2
410   (and (eq_attr "type" "store")
411        (eq_attr "cpu" "7100LC"))
412   "i1_7100lc+mem_7100lc,mem_7100lc")
413
414 (define_insn_reservation "Y5" 2
415   (and (eq_attr "type" "fpstore")
416        (eq_attr "cpu" "7100LC"))
417   "i1_7100lc+mem_7100lc,mem_7100lc")
418
419 (define_insn_reservation "Y6" 1
420   (and (eq_attr "type" "shift,nullshift")
421        (eq_attr "cpu" "7100LC,7200,7300"))
422   "i1_7100lc")
423
424 (define_insn_reservation "Y7" 1
425   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
426        (eq_attr "cpu" "7100LC,7200,7300"))
427   "(i0_7100lc|i1_7100lc)")
428
429 ;; The 7200 has a store-load penalty
430 (define_insn_reservation "Y8" 2
431   (and (eq_attr "type" "store")
432        (eq_attr "cpu" "7200"))
433   "i1_7100lc,mem_7100lc")
434
435 (define_insn_reservation "Y9" 2
436   (and (eq_attr "type" "fpstore")
437        (eq_attr "cpu" "7200"))
438   "i1_7100lc,mem_7100lc")
439
440 ;; The 7300 has no penalty for store-store or store-load
441 (define_insn_reservation "Y10" 2
442   (and (eq_attr "type" "store")
443        (eq_attr "cpu" "7300"))
444   "i1_7100lc")
445
446 (define_insn_reservation "Y11" 2
447   (and (eq_attr "type" "fpstore")
448        (eq_attr "cpu" "7300"))
449   "i1_7100lc")
450
451 ;; We have an "anti-bypass" for FP loads which feed an FP store.
452 (define_bypass 3 "Y3" "Y5,Y9,Y11" "hppa_fpstore_bypass_p")
453
454 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
455 ;; traditional architecture.
456 ;;
457 ;; The PA8000 has a large (56) entry reorder buffer that is split between
458 ;; memory and non-memory operations.
459 ;;
460 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
461 ;; the function units, with the exception of branches and multi-output
462 ;; instructions.  The PA8000 can retire two non-memory operations per cycle
463 ;; and two memory operations per cycle, only one of which may be a store.
464 ;;
465 ;; Given the large reorder buffer, the processor can hide most latencies.
466 ;; According to HP, they've got the best results by scheduling for retirement
467 ;; bandwidth with limited latency scheduling for floating point operations.
468 ;; Latency for integer operations and memory references is ignored.
469 ;;
470 ;;
471 ;; We claim floating point operations have a 2 cycle latency and are
472 ;; fully pipelined, except for div and sqrt which are not pipelined and
473 ;; take from 17 to 31 cycles to complete.
474 ;;
475 ;; It's worth noting that there is no way to saturate all the functional
476 ;; units on the PA8000 as there is not enough issue bandwidth.
477
478 (define_automaton "pa8000")
479 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
480 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
481 (define_cpu_unit "store_8000" "pa8000")
482 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
483 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
484 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
485 (define_reservation "im_8000" "im0_8000 | im1_8000")
486 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
487 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
488 (define_reservation "f_8000" "f0_8000 | f1_8000")
489 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
490
491 ;; We can issue any two memops per cycle, but we can only retire
492 ;; one memory store per cycle.  We assume that the reorder buffer
493 ;; will hide any memory latencies per HP's recommendation.
494 (define_insn_reservation "Z0" 0
495   (and
496     (eq_attr "type" "load,fpload")
497     (eq_attr "cpu" "8000"))
498   "im_8000,rm_8000")
499
500 (define_insn_reservation "Z1" 0
501   (and
502     (eq_attr "type" "store,fpstore")
503     (eq_attr "cpu" "8000"))
504   "im_8000,rm_8000+store_8000")
505
506 ;; We can issue and retire two non-memory operations per cycle with
507 ;; a few exceptions (branches).  This group catches those we want
508 ;; to assume have zero latency.
509 (define_insn_reservation "Z2" 0
510   (and
511     (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl")
512     (eq_attr "cpu" "8000"))
513   "inm_8000,rnm_8000")
514
515 ;; Branches use both slots in the non-memory issue and
516 ;; retirement unit.
517 (define_insn_reservation "Z3" 0
518   (and
519     (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
520     (eq_attr "cpu" "8000"))
521   "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
522
523 ;; We partial latency schedule the floating point units.
524 ;; They can issue/retire two at a time in the non-memory
525 ;; units.  We fix their latency at 2 cycles and they
526 ;; are fully pipelined.
527 (define_insn_reservation "Z4" 1
528  (and
529    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
530    (eq_attr "cpu" "8000"))
531  "inm_8000,f_8000,rnm_8000")
532
533 ;; The fdivsqrt units are not pipelined and have a very long latency.  
534 ;; To keep the DFA from exploding, we do not show all the
535 ;; reservations for the divsqrt unit.
536 (define_insn_reservation "Z5" 17
537  (and
538    (eq_attr "type" "fpdivsgl,fpsqrtsgl")
539    (eq_attr "cpu" "8000"))
540  "inm_8000,fdivsqrt_8000*6,rnm_8000")
541
542 (define_insn_reservation "Z6" 31
543  (and
544    (eq_attr "type" "fpdivdbl,fpsqrtdbl")
545    (eq_attr "cpu" "8000"))
546  "inm_8000,fdivsqrt_8000*6,rnm_8000")
547
548
549 \f
550 ;; Compare instructions.
551 ;; This controls RTL generation and register allocation.
552
553 ;; We generate RTL for comparisons and branches by having the cmpxx
554 ;; patterns store away the operands.  Then, the scc and bcc patterns
555 ;; emit RTL for both the compare and the branch.
556 ;;
557
558 (define_expand "cmpdi"
559   [(set (reg:CC 0)
560         (compare:CC (match_operand:DI 0 "reg_or_0_operand" "")
561                     (match_operand:DI 1 "register_operand" "")))]
562   "TARGET_64BIT"
563
564   "
565 {
566  hppa_compare_op0 = operands[0];
567  hppa_compare_op1 = operands[1];
568  hppa_branch_type = CMP_SI;
569  DONE;
570 }")
571
572 (define_expand "cmpsi"
573   [(set (reg:CC 0)
574         (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
575                     (match_operand:SI 1 "arith5_operand" "")))]
576   ""
577   "
578 {
579  hppa_compare_op0 = operands[0];
580  hppa_compare_op1 = operands[1];
581  hppa_branch_type = CMP_SI;
582  DONE;
583 }")
584
585 (define_expand "cmpsf"
586   [(set (reg:CCFP 0)
587         (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
588                       (match_operand:SF 1 "reg_or_0_operand" "")))]
589   "! TARGET_SOFT_FLOAT"
590   "
591 {
592   hppa_compare_op0 = operands[0];
593   hppa_compare_op1 = operands[1];
594   hppa_branch_type = CMP_SF;
595   DONE;
596 }")
597
598 (define_expand "cmpdf"
599   [(set (reg:CCFP 0)
600       (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
601                     (match_operand:DF 1 "reg_or_0_operand" "")))]
602   "! TARGET_SOFT_FLOAT"
603   "
604 {
605   hppa_compare_op0 = operands[0];
606   hppa_compare_op1 = operands[1];
607   hppa_branch_type = CMP_DF;
608   DONE;
609 }")
610
611 (define_insn ""
612   [(set (reg:CCFP 0)
613         (match_operator:CCFP 2 "comparison_operator"
614                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
615                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
616   "! TARGET_SOFT_FLOAT"
617   "fcmp,sgl,%Y2 %f0,%f1"
618   [(set_attr "length" "4")
619    (set_attr "type" "fpcc")])
620
621 (define_insn ""
622   [(set (reg:CCFP 0)
623         (match_operator:CCFP 2 "comparison_operator"
624                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
625                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
626   "! TARGET_SOFT_FLOAT"
627   "fcmp,dbl,%Y2 %f0,%f1"
628   [(set_attr "length" "4")
629    (set_attr "type" "fpcc")])
630
631 ;; The following two patterns are optimization placeholders.  In almost
632 ;; all cases, the user of the condition code will be simplified and the
633 ;; original condition code setting insn should be eliminated.
634
635 (define_insn "*setccfp0"
636   [(set (reg:CCFP 0)
637         (const_int 0))]
638   "! TARGET_SOFT_FLOAT"
639   "fcmp,dbl,!= %%fr0,%%fr0"
640   [(set_attr "length" "4")
641    (set_attr "type" "fpcc")])
642
643 (define_insn "*setccfp1"
644   [(set (reg:CCFP 0)
645         (const_int 1))]
646   "! TARGET_SOFT_FLOAT"
647   "fcmp,dbl,= %%fr0,%%fr0"
648   [(set_attr "length" "4")
649    (set_attr "type" "fpcc")])
650
651 ;; scc insns.
652
653 (define_expand "seq"
654   [(set (match_operand:SI 0 "register_operand" "")
655         (eq:SI (match_dup 1)
656                (match_dup 2)))]
657   "!TARGET_64BIT"
658   "
659 {
660   /* fp scc patterns rarely match, and are not a win on the PA.  */
661   if (hppa_branch_type != CMP_SI)
662     FAIL;
663   /* set up operands from compare.  */
664   operands[1] = hppa_compare_op0;
665   operands[2] = hppa_compare_op1;
666   /* fall through and generate default code */
667 }")
668
669 (define_expand "sne"
670   [(set (match_operand:SI 0 "register_operand" "")
671         (ne:SI (match_dup 1)
672                (match_dup 2)))]
673   "!TARGET_64BIT"
674   "
675 {
676   /* fp scc patterns rarely match, and are not a win on the PA.  */
677   if (hppa_branch_type != CMP_SI)
678     FAIL;
679   operands[1] = hppa_compare_op0;
680   operands[2] = hppa_compare_op1;
681 }")
682
683 (define_expand "slt"
684   [(set (match_operand:SI 0 "register_operand" "")
685         (lt: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   operands[1] = hppa_compare_op0;
694   operands[2] = hppa_compare_op1;
695 }")
696
697 (define_expand "sgt"
698   [(set (match_operand:SI 0 "register_operand" "")
699         (gt:SI (match_dup 1)
700                (match_dup 2)))]
701   "!TARGET_64BIT"
702   "
703 {
704   /* fp scc patterns rarely match, and are not a win on the PA.  */
705   if (hppa_branch_type != CMP_SI)
706     FAIL;
707   operands[1] = hppa_compare_op0;
708   operands[2] = hppa_compare_op1;
709 }")
710
711 (define_expand "sle"
712   [(set (match_operand:SI 0 "register_operand" "")
713         (le:SI (match_dup 1)
714                (match_dup 2)))]
715   "!TARGET_64BIT"
716   "
717 {
718   /* fp scc patterns rarely match, and are not a win on the PA.  */
719   if (hppa_branch_type != CMP_SI)
720     FAIL;
721   operands[1] = hppa_compare_op0;
722   operands[2] = hppa_compare_op1;
723 }")
724
725 (define_expand "sge"
726   [(set (match_operand:SI 0 "register_operand" "")
727         (ge:SI (match_dup 1)
728                (match_dup 2)))]
729   "!TARGET_64BIT"
730   "
731 {
732   /* fp scc patterns rarely match, and are not a win on the PA.  */
733   if (hppa_branch_type != CMP_SI)
734     FAIL;
735   operands[1] = hppa_compare_op0;
736   operands[2] = hppa_compare_op1;
737 }")
738
739 (define_expand "sltu"
740   [(set (match_operand:SI 0 "register_operand" "")
741         (ltu:SI (match_dup 1)
742                 (match_dup 2)))]
743   "!TARGET_64BIT"
744   "
745 {
746   if (hppa_branch_type != CMP_SI)
747     FAIL;
748   operands[1] = hppa_compare_op0;
749   operands[2] = hppa_compare_op1;
750 }")
751
752 (define_expand "sgtu"
753   [(set (match_operand:SI 0 "register_operand" "")
754         (gtu:SI (match_dup 1)
755                 (match_dup 2)))]
756   "!TARGET_64BIT"
757   "
758 {
759   if (hppa_branch_type != CMP_SI)
760     FAIL;
761   operands[1] = hppa_compare_op0;
762   operands[2] = hppa_compare_op1;
763 }")
764
765 (define_expand "sleu"
766   [(set (match_operand:SI 0 "register_operand" "")
767         (leu:SI (match_dup 1)
768                 (match_dup 2)))]
769   "!TARGET_64BIT"
770   "
771 {
772   if (hppa_branch_type != CMP_SI)
773     FAIL;
774   operands[1] = hppa_compare_op0;
775   operands[2] = hppa_compare_op1;
776 }")
777
778 (define_expand "sgeu"
779   [(set (match_operand:SI 0 "register_operand" "")
780         (geu:SI (match_dup 1)
781                 (match_dup 2)))]
782   "!TARGET_64BIT"
783   "
784 {
785   if (hppa_branch_type != CMP_SI)
786     FAIL;
787   operands[1] = hppa_compare_op0;
788   operands[2] = hppa_compare_op1;
789 }")
790
791 ;; Instruction canonicalization puts immediate operands second, which
792 ;; is the reverse of what we want.
793
794 (define_insn "scc"
795   [(set (match_operand:SI 0 "register_operand" "=r")
796         (match_operator:SI 3 "comparison_operator"
797                            [(match_operand:SI 1 "register_operand" "r")
798                             (match_operand:SI 2 "arith11_operand" "rI")]))]
799   ""
800   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
801   [(set_attr "type" "binary")
802    (set_attr "length" "8")])
803
804 (define_insn ""
805   [(set (match_operand:DI 0 "register_operand" "=r")
806         (match_operator:DI 3 "comparison_operator"
807                            [(match_operand:DI 1 "register_operand" "r")
808                             (match_operand:DI 2 "arith11_operand" "rI")]))]
809   "TARGET_64BIT"
810   "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
811   [(set_attr "type" "binary")
812    (set_attr "length" "8")])
813
814 (define_insn "iorscc"
815   [(set (match_operand:SI 0 "register_operand" "=r")
816         (ior:SI (match_operator:SI 3 "comparison_operator"
817                                    [(match_operand:SI 1 "register_operand" "r")
818                                     (match_operand:SI 2 "arith11_operand" "rI")])
819                 (match_operator:SI 6 "comparison_operator"
820                                    [(match_operand:SI 4 "register_operand" "r")
821                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
822   ""
823   "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
824   [(set_attr "type" "binary")
825    (set_attr "length" "12")])
826
827 (define_insn ""
828   [(set (match_operand:DI 0 "register_operand" "=r")
829         (ior:DI (match_operator:DI 3 "comparison_operator"
830                                    [(match_operand:DI 1 "register_operand" "r")
831                                     (match_operand:DI 2 "arith11_operand" "rI")])
832                 (match_operator:DI 6 "comparison_operator"
833                                    [(match_operand:DI 4 "register_operand" "r")
834                                     (match_operand:DI 5 "arith11_operand" "rI")])))]
835   "TARGET_64BIT"
836   "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
837   [(set_attr "type" "binary")
838    (set_attr "length" "12")])
839
840 ;; Combiner patterns for common operations performed with the output
841 ;; from an scc insn (negscc and incscc).
842 (define_insn "negscc"
843   [(set (match_operand:SI 0 "register_operand" "=r")
844         (neg:SI (match_operator:SI 3 "comparison_operator"
845                [(match_operand:SI 1 "register_operand" "r")
846                 (match_operand:SI 2 "arith11_operand" "rI")])))]
847   ""
848   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
849   [(set_attr "type" "binary")
850    (set_attr "length" "8")])
851
852 (define_insn ""
853   [(set (match_operand:DI 0 "register_operand" "=r")
854         (neg:DI (match_operator:DI 3 "comparison_operator"
855                [(match_operand:DI 1 "register_operand" "r")
856                 (match_operand:DI 2 "arith11_operand" "rI")])))]
857   "TARGET_64BIT"
858   "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
859   [(set_attr "type" "binary")
860    (set_attr "length" "8")])
861
862 ;; Patterns for adding/subtracting the result of a boolean expression from
863 ;; a register.  First we have special patterns that make use of the carry
864 ;; bit, and output only two instructions.  For the cases we can't in
865 ;; general do in two instructions, the incscc pattern at the end outputs
866 ;; two or three instructions.
867
868 (define_insn ""
869   [(set (match_operand:SI 0 "register_operand" "=r")
870         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
871                          (match_operand:SI 3 "arith11_operand" "rI"))
872                  (match_operand:SI 1 "register_operand" "r")))]
873   ""
874   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
875   [(set_attr "type" "binary")
876    (set_attr "length" "8")])
877
878 (define_insn ""
879   [(set (match_operand:DI 0 "register_operand" "=r")
880         (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
881                          (match_operand:DI 3 "arith11_operand" "rI"))
882                  (match_operand:DI 1 "register_operand" "r")))]
883   "TARGET_64BIT"
884   "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
885   [(set_attr "type" "binary")
886    (set_attr "length" "8")])
887
888 ; This need only accept registers for op3, since canonicalization
889 ; replaces geu with gtu when op3 is an integer.
890 (define_insn ""
891   [(set (match_operand:SI 0 "register_operand" "=r")
892         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
893                          (match_operand:SI 3 "register_operand" "r"))
894                  (match_operand:SI 1 "register_operand" "r")))]
895   ""
896   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
897   [(set_attr "type" "binary")
898    (set_attr "length" "8")])
899
900 (define_insn ""
901   [(set (match_operand:DI 0 "register_operand" "=r")
902         (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
903                          (match_operand:DI 3 "register_operand" "r"))
904                  (match_operand:DI 1 "register_operand" "r")))]
905   "TARGET_64BIT"
906   "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
907   [(set_attr "type" "binary")
908    (set_attr "length" "8")])
909
910 ; Match only integers for op3 here.  This is used as canonical form of the
911 ; geu pattern when op3 is an integer.  Don't match registers since we can't
912 ; make better code than the general incscc pattern.
913 (define_insn ""
914   [(set (match_operand:SI 0 "register_operand" "=r")
915         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
916                          (match_operand:SI 3 "int11_operand" "I"))
917                  (match_operand:SI 1 "register_operand" "r")))]
918   ""
919   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
920   [(set_attr "type" "binary")
921    (set_attr "length" "8")])
922
923 (define_insn ""
924   [(set (match_operand:DI 0 "register_operand" "=r")
925         (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
926                          (match_operand:DI 3 "int11_operand" "I"))
927                  (match_operand:DI 1 "register_operand" "r")))]
928   "TARGET_64BIT"
929   "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
930   [(set_attr "type" "binary")
931    (set_attr "length" "8")])
932
933 (define_insn "incscc"
934   [(set (match_operand:SI 0 "register_operand" "=r,r")
935         (plus:SI (match_operator:SI 4 "comparison_operator"
936                     [(match_operand:SI 2 "register_operand" "r,r")
937                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
938                  (match_operand:SI 1 "register_operand" "0,?r")))]
939   ""
940   "@
941    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
942    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
943   [(set_attr "type" "binary,binary")
944    (set_attr "length" "8,12")])
945
946 (define_insn ""
947   [(set (match_operand:DI 0 "register_operand" "=r,r")
948         (plus:DI (match_operator:DI 4 "comparison_operator"
949                     [(match_operand:DI 2 "register_operand" "r,r")
950                      (match_operand:DI 3 "arith11_operand" "rI,rI")])
951                  (match_operand:DI 1 "register_operand" "0,?r")))]
952   "TARGET_64BIT"
953   "@
954    cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
955    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
956   [(set_attr "type" "binary,binary")
957    (set_attr "length" "8,12")])
958
959 (define_insn ""
960   [(set (match_operand:SI 0 "register_operand" "=r")
961         (minus:SI (match_operand:SI 1 "register_operand" "r")
962                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
963                           (match_operand:SI 3 "arith11_operand" "rI"))))]
964   ""
965   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
966   [(set_attr "type" "binary")
967    (set_attr "length" "8")])
968
969 (define_insn ""
970   [(set (match_operand:DI 0 "register_operand" "=r")
971         (minus:DI (match_operand:DI 1 "register_operand" "r")
972                   (gtu:DI (match_operand:DI 2 "register_operand" "r")
973                           (match_operand:DI 3 "arith11_operand" "rI"))))]
974   "TARGET_64BIT"
975   "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
976   [(set_attr "type" "binary")
977    (set_attr "length" "8")])
978
979 (define_insn ""
980   [(set (match_operand:SI 0 "register_operand" "=r")
981         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
982                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
983                                     (match_operand:SI 3 "arith11_operand" "rI")))
984                   (match_operand:SI 4 "register_operand" "r")))]
985   ""
986   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
987   [(set_attr "type" "binary")
988    (set_attr "length" "8")])
989
990 (define_insn ""
991   [(set (match_operand:DI 0 "register_operand" "=r")
992         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
993                             (gtu:DI (match_operand:DI 2 "register_operand" "r")
994                                     (match_operand:DI 3 "arith11_operand" "rI")))
995                   (match_operand:DI 4 "register_operand" "r")))]
996   "TARGET_64BIT"
997   "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
998   [(set_attr "type" "binary")
999    (set_attr "length" "8")])
1000
1001 ; This need only accept registers for op3, since canonicalization
1002 ; replaces ltu with leu when op3 is an integer.
1003 (define_insn ""
1004   [(set (match_operand:SI 0 "register_operand" "=r")
1005         (minus:SI (match_operand:SI 1 "register_operand" "r")
1006                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
1007                           (match_operand:SI 3 "register_operand" "r"))))]
1008   ""
1009   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
1010   [(set_attr "type" "binary")
1011    (set_attr "length" "8")])
1012
1013 (define_insn ""
1014   [(set (match_operand:DI 0 "register_operand" "=r")
1015         (minus:DI (match_operand:DI 1 "register_operand" "r")
1016                   (ltu:DI (match_operand:DI 2 "register_operand" "r")
1017                           (match_operand:DI 3 "register_operand" "r"))))]
1018   "TARGET_64BIT"
1019   "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
1020   [(set_attr "type" "binary")
1021    (set_attr "length" "8")])
1022
1023 (define_insn ""
1024   [(set (match_operand:SI 0 "register_operand" "=r")
1025         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1026                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
1027                                     (match_operand:SI 3 "register_operand" "r")))
1028                   (match_operand:SI 4 "register_operand" "r")))]
1029   ""
1030   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1031   [(set_attr "type" "binary")
1032    (set_attr "length" "8")])
1033
1034 (define_insn ""
1035   [(set (match_operand:DI 0 "register_operand" "=r")
1036         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1037                             (ltu:DI (match_operand:DI 2 "register_operand" "r")
1038                                     (match_operand:DI 3 "register_operand" "r")))
1039                   (match_operand:DI 4 "register_operand" "r")))]
1040   "TARGET_64BIT"
1041   "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1042   [(set_attr "type" "binary")
1043    (set_attr "length" "8")])
1044
1045 ; Match only integers for op3 here.  This is used as canonical form of the
1046 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
1047 ; make better code than the general incscc pattern.
1048 (define_insn ""
1049   [(set (match_operand:SI 0 "register_operand" "=r")
1050         (minus:SI (match_operand:SI 1 "register_operand" "r")
1051                   (leu:SI (match_operand:SI 2 "register_operand" "r")
1052                           (match_operand:SI 3 "int11_operand" "I"))))]
1053   ""
1054   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1055   [(set_attr "type" "binary")
1056    (set_attr "length" "8")])
1057
1058 (define_insn ""
1059   [(set (match_operand:DI 0 "register_operand" "=r")
1060         (minus:DI (match_operand:DI 1 "register_operand" "r")
1061                   (leu:DI (match_operand:DI 2 "register_operand" "r")
1062                           (match_operand:DI 3 "int11_operand" "I"))))]
1063   "TARGET_64BIT"
1064   "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1065   [(set_attr "type" "binary")
1066    (set_attr "length" "8")])
1067
1068 (define_insn ""
1069   [(set (match_operand:SI 0 "register_operand" "=r")
1070         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1071                             (leu:SI (match_operand:SI 2 "register_operand" "r")
1072                                     (match_operand:SI 3 "int11_operand" "I")))
1073                   (match_operand:SI 4 "register_operand" "r")))]
1074   ""
1075   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1076   [(set_attr "type" "binary")
1077    (set_attr "length" "8")])
1078
1079 (define_insn ""
1080   [(set (match_operand:DI 0 "register_operand" "=r")
1081         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1082                             (leu:DI (match_operand:DI 2 "register_operand" "r")
1083                                     (match_operand:DI 3 "int11_operand" "I")))
1084                   (match_operand:DI 4 "register_operand" "r")))]
1085   "TARGET_64BIT"
1086   "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1087   [(set_attr "type" "binary")
1088    (set_attr "length" "8")])
1089
1090 (define_insn "decscc"
1091   [(set (match_operand:SI 0 "register_operand" "=r,r")
1092         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1093                   (match_operator:SI 4 "comparison_operator"
1094                      [(match_operand:SI 2 "register_operand" "r,r")
1095                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1096   ""
1097   "@
1098    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1099    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1100   [(set_attr "type" "binary,binary")
1101    (set_attr "length" "8,12")])
1102
1103 (define_insn ""
1104   [(set (match_operand:DI 0 "register_operand" "=r,r")
1105         (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1106                   (match_operator:DI 4 "comparison_operator"
1107                      [(match_operand:DI 2 "register_operand" "r,r")
1108                       (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1109   "TARGET_64BIT"
1110   "@
1111    cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1112    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1113   [(set_attr "type" "binary,binary")
1114    (set_attr "length" "8,12")])
1115
1116 ; Patterns for max and min.  (There is no need for an earlyclobber in the
1117 ; last alternative since the middle alternative will match if op0 == op1.)
1118
1119 (define_insn "sminsi3"
1120   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1121         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1122                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1123   ""
1124   "@
1125   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1126   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1127   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1128 [(set_attr "type" "multi,multi,multi")
1129  (set_attr "length" "8,8,8")])
1130
1131 (define_insn "smindi3"
1132   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1133         (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1134                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1135   "TARGET_64BIT"
1136   "@
1137   cmpclr,*> %2,%0,%%r0\;copy %2,%0
1138   cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1139   cmpclr,*> %1,%r2,%0\;copy %1,%0"
1140 [(set_attr "type" "multi,multi,multi")
1141  (set_attr "length" "8,8,8")])
1142
1143 (define_insn "uminsi3"
1144   [(set (match_operand:SI 0 "register_operand" "=r,r")
1145         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1146                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1147   ""
1148   "@
1149   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1150   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1151 [(set_attr "type" "multi,multi")
1152  (set_attr "length" "8,8")])
1153
1154 (define_insn "umindi3"
1155   [(set (match_operand:DI 0 "register_operand" "=r,r")
1156         (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1157                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1158   "TARGET_64BIT"
1159   "@
1160   cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1161   cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1162 [(set_attr "type" "multi,multi")
1163  (set_attr "length" "8,8")])
1164
1165 (define_insn "smaxsi3"
1166   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1167         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1168                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1169   ""
1170   "@
1171   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1172   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1173   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1174 [(set_attr "type" "multi,multi,multi")
1175  (set_attr "length" "8,8,8")])
1176
1177 (define_insn "smaxdi3"
1178   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1179         (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1180                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1181   "TARGET_64BIT"
1182   "@
1183   cmpclr,*< %2,%0,%%r0\;copy %2,%0
1184   cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1185   cmpclr,*< %1,%r2,%0\;copy %1,%0"
1186 [(set_attr "type" "multi,multi,multi")
1187  (set_attr "length" "8,8,8")])
1188
1189 (define_insn "umaxsi3"
1190   [(set (match_operand:SI 0 "register_operand" "=r,r")
1191         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1192                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1193   ""
1194   "@
1195   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1196   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1197 [(set_attr "type" "multi,multi")
1198  (set_attr "length" "8,8")])
1199
1200 (define_insn "umaxdi3"
1201   [(set (match_operand:DI 0 "register_operand" "=r,r")
1202         (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1203                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1204   "TARGET_64BIT"
1205   "@
1206   cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1207   cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1208 [(set_attr "type" "multi,multi")
1209  (set_attr "length" "8,8")])
1210
1211 (define_insn "abssi2"
1212   [(set (match_operand:SI 0 "register_operand" "=r")
1213         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1214   ""
1215   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1216   [(set_attr "type" "multi")
1217    (set_attr "length" "8")])
1218
1219 (define_insn "absdi2"
1220   [(set (match_operand:DI 0 "register_operand" "=r")
1221         (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1222   "TARGET_64BIT"
1223   "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1224   [(set_attr "type" "multi")
1225    (set_attr "length" "8")])
1226
1227 ;;; Experimental conditional move patterns
1228
1229 (define_expand "movsicc"
1230   [(set (match_operand:SI 0 "register_operand" "")
1231         (if_then_else:SI
1232          (match_operator 1 "comparison_operator"
1233             [(match_dup 4)
1234              (match_dup 5)])
1235          (match_operand:SI 2 "reg_or_cint_move_operand" "")
1236          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1237   ""
1238   "
1239 {
1240   enum rtx_code code = GET_CODE (operands[1]);
1241
1242   if (hppa_branch_type != CMP_SI)
1243     FAIL;
1244
1245   if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1246       || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1247     FAIL;
1248
1249   /* operands[1] is currently the result of compare_from_rtx.  We want to
1250      emit a compare of the original operands.  */
1251   operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
1252   operands[4] = hppa_compare_op0;
1253   operands[5] = hppa_compare_op1;
1254 }")
1255
1256 ;; We used to accept any register for op1.
1257 ;;
1258 ;; However, it loses sometimes because the compiler will end up using
1259 ;; different registers for op0 and op1 in some critical cases.  local-alloc
1260 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1261 ;;
1262 ;; If/when global register allocation supports tying we should allow any
1263 ;; register for op1 again.
1264 (define_insn ""
1265   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1266         (if_then_else:SI
1267          (match_operator 2 "comparison_operator"
1268             [(match_operand:SI 3 "register_operand" "r,r,r,r")
1269              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1270          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1271          (const_int 0)))]
1272   ""
1273   "@
1274    {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1275    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1276    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1277    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1278   [(set_attr "type" "multi,multi,multi,nullshift")
1279    (set_attr "length" "8,8,8,8")])
1280
1281 (define_insn ""
1282   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1283         (if_then_else:SI
1284          (match_operator 5 "comparison_operator"
1285             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1286              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1287          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1288          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1289   ""
1290   "@
1291    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1292    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1293    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1294    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1295    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1296    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1297    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1298    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1299   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1300    (set_attr "length" "8,8,8,8,8,8,8,8")])
1301
1302 (define_expand "movdicc"
1303   [(set (match_operand:DI 0 "register_operand" "")
1304         (if_then_else:DI
1305          (match_operator 1 "comparison_operator"
1306             [(match_dup 4)
1307              (match_dup 5)])
1308          (match_operand:DI 2 "reg_or_cint_move_operand" "")
1309          (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1310   "TARGET_64BIT"
1311   "
1312 {
1313   enum rtx_code code = GET_CODE (operands[1]);
1314
1315   if (hppa_branch_type != CMP_SI)
1316     FAIL;
1317
1318   if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1319       || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1320     FAIL;
1321
1322   /* operands[1] is currently the result of compare_from_rtx.  We want to
1323      emit a compare of the original operands.  */
1324   operands[1] = gen_rtx_fmt_ee (code, DImode, hppa_compare_op0, hppa_compare_op1);
1325   operands[4] = hppa_compare_op0;
1326   operands[5] = hppa_compare_op1;
1327 }")
1328
1329 ; We need the first constraint alternative in order to avoid
1330 ; earlyclobbers on all other alternatives.
1331 (define_insn ""
1332   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1333         (if_then_else:DI
1334          (match_operator 2 "comparison_operator"
1335             [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1336              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1337          (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1338          (const_int 0)))]
1339   "TARGET_64BIT"
1340   "@
1341    cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1342    cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1343    cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1344    cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1345    cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1346   [(set_attr "type" "multi,multi,multi,multi,nullshift")
1347    (set_attr "length" "8,8,8,8,8")])
1348
1349 (define_insn ""
1350   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1351         (if_then_else:DI
1352          (match_operator 5 "comparison_operator"
1353             [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1354              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1355          (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1356          (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1357   "TARGET_64BIT"
1358   "@
1359    cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1360    cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1361    cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1362    cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1363    cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1364    cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1365    cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1366    cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1367   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1368    (set_attr "length" "8,8,8,8,8,8,8,8")])
1369
1370 ;; Conditional Branches
1371
1372 (define_expand "beq"
1373   [(set (pc)
1374         (if_then_else (eq (match_dup 1) (match_dup 2))
1375                       (label_ref (match_operand 0 "" ""))
1376                       (pc)))]
1377   ""
1378   "
1379 {
1380   if (hppa_branch_type != CMP_SI)
1381     {
1382       emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
1383       emit_bcond_fp (NE, operands[0]);
1384       DONE;
1385     }
1386   /* set up operands from compare.  */
1387   operands[1] = hppa_compare_op0;
1388   operands[2] = hppa_compare_op1;
1389   /* fall through and generate default code */
1390 }")
1391
1392 (define_expand "bne"
1393   [(set (pc)
1394         (if_then_else (ne (match_dup 1) (match_dup 2))
1395                       (label_ref (match_operand 0 "" ""))
1396                       (pc)))]
1397   ""
1398   "
1399 {
1400   if (hppa_branch_type != CMP_SI)
1401     {
1402       emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
1403       emit_bcond_fp (NE, operands[0]);
1404       DONE;
1405     }
1406   operands[1] = hppa_compare_op0;
1407   operands[2] = hppa_compare_op1;
1408 }")
1409
1410 (define_expand "bgt"
1411   [(set (pc)
1412         (if_then_else (gt (match_dup 1) (match_dup 2))
1413                       (label_ref (match_operand 0 "" ""))
1414                       (pc)))]
1415   ""
1416   "
1417 {
1418   if (hppa_branch_type != CMP_SI)
1419     {
1420       emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
1421       emit_bcond_fp (NE, operands[0]);
1422       DONE;
1423     }
1424   operands[1] = hppa_compare_op0;
1425   operands[2] = hppa_compare_op1;
1426 }")
1427
1428 (define_expand "blt"
1429   [(set (pc)
1430         (if_then_else (lt (match_dup 1) (match_dup 2))
1431                       (label_ref (match_operand 0 "" ""))
1432                       (pc)))]
1433   ""
1434   "
1435 {
1436   if (hppa_branch_type != CMP_SI)
1437     {
1438       emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
1439       emit_bcond_fp (NE, operands[0]);
1440       DONE;
1441     }
1442   operands[1] = hppa_compare_op0;
1443   operands[2] = hppa_compare_op1;
1444 }")
1445
1446 (define_expand "bge"
1447   [(set (pc)
1448         (if_then_else (ge (match_dup 1) (match_dup 2))
1449                       (label_ref (match_operand 0 "" ""))
1450                       (pc)))]
1451   ""
1452   "
1453 {
1454   if (hppa_branch_type != CMP_SI)
1455     {
1456       emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
1457       emit_bcond_fp (NE, operands[0]);
1458       DONE;
1459     }
1460   operands[1] = hppa_compare_op0;
1461   operands[2] = hppa_compare_op1;
1462 }")
1463
1464 (define_expand "ble"
1465   [(set (pc)
1466         (if_then_else (le (match_dup 1) (match_dup 2))
1467                       (label_ref (match_operand 0 "" ""))
1468                       (pc)))]
1469   ""
1470   "
1471 {
1472   if (hppa_branch_type != CMP_SI)
1473     {
1474       emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
1475       emit_bcond_fp (NE, operands[0]);
1476       DONE;
1477     }
1478   operands[1] = hppa_compare_op0;
1479   operands[2] = hppa_compare_op1;
1480 }")
1481
1482 (define_expand "bgtu"
1483   [(set (pc)
1484         (if_then_else (gtu (match_dup 1) (match_dup 2))
1485                       (label_ref (match_operand 0 "" ""))
1486                       (pc)))]
1487   ""
1488   "
1489 {
1490   if (hppa_branch_type != CMP_SI)
1491     FAIL;
1492   operands[1] = hppa_compare_op0;
1493   operands[2] = hppa_compare_op1;
1494 }")
1495
1496 (define_expand "bltu"
1497   [(set (pc)
1498         (if_then_else (ltu (match_dup 1) (match_dup 2))
1499                       (label_ref (match_operand 0 "" ""))
1500                       (pc)))]
1501   ""
1502   "
1503 {
1504   if (hppa_branch_type != CMP_SI)
1505     FAIL;
1506   operands[1] = hppa_compare_op0;
1507   operands[2] = hppa_compare_op1;
1508 }")
1509
1510 (define_expand "bgeu"
1511   [(set (pc)
1512         (if_then_else (geu (match_dup 1) (match_dup 2))
1513                       (label_ref (match_operand 0 "" ""))
1514                       (pc)))]
1515   ""
1516   "
1517 {
1518   if (hppa_branch_type != CMP_SI)
1519     FAIL;
1520   operands[1] = hppa_compare_op0;
1521   operands[2] = hppa_compare_op1;
1522 }")
1523
1524 (define_expand "bleu"
1525   [(set (pc)
1526         (if_then_else (leu (match_dup 1) (match_dup 2))
1527                       (label_ref (match_operand 0 "" ""))
1528                       (pc)))]
1529   ""
1530   "
1531 {
1532   if (hppa_branch_type != CMP_SI)
1533     FAIL;
1534   operands[1] = hppa_compare_op0;
1535   operands[2] = hppa_compare_op1;
1536 }")
1537
1538 (define_expand "bltgt"
1539   [(set (pc)
1540         (if_then_else (ltgt (match_dup 1) (match_dup 2))
1541                       (label_ref (match_operand 0 "" ""))
1542                       (pc)))]
1543   ""
1544   "
1545 {
1546   if (hppa_branch_type == CMP_SI)
1547     FAIL;
1548   emit_insn (gen_cmp_fp (LTGT, hppa_compare_op0, hppa_compare_op1));
1549   emit_bcond_fp (NE, operands[0]);
1550   DONE;
1551 }")
1552
1553 (define_expand "bunle"
1554   [(set (pc)
1555         (if_then_else (unle (match_dup 1) (match_dup 2))
1556                       (label_ref (match_operand 0 "" ""))
1557                       (pc)))]
1558   ""
1559   "
1560 {
1561   if (hppa_branch_type == CMP_SI)
1562     FAIL;
1563   emit_insn (gen_cmp_fp (UNLE, hppa_compare_op0, hppa_compare_op1));
1564   emit_bcond_fp (NE, operands[0]);
1565   DONE;
1566 }")
1567
1568 (define_expand "bunlt"
1569   [(set (pc)
1570         (if_then_else (unlt (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 (UNLT, hppa_compare_op0, hppa_compare_op1));
1579   emit_bcond_fp (NE, operands[0]);
1580   DONE;
1581 }")
1582
1583 (define_expand "bunge"
1584   [(set (pc)
1585         (if_then_else (unge (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 (UNGE, hppa_compare_op0, hppa_compare_op1));
1594   emit_bcond_fp (NE, operands[0]);
1595   DONE;
1596 }")
1597
1598 (define_expand "bungt"
1599   [(set (pc)
1600         (if_then_else (ungt (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 (UNGT, hppa_compare_op0, hppa_compare_op1));
1609   emit_bcond_fp (NE, operands[0]);
1610   DONE;
1611 }")
1612
1613 (define_expand "buneq"
1614   [(set (pc)
1615         (if_then_else (uneq (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 (UNEQ, hppa_compare_op0, hppa_compare_op1));
1624   emit_bcond_fp (NE, operands[0]);
1625   DONE;
1626 }")
1627
1628 (define_expand "bunordered"
1629   [(set (pc)
1630         (if_then_else (unordered (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 (UNORDERED, hppa_compare_op0, hppa_compare_op1));
1639   emit_bcond_fp (NE, operands[0]);
1640   DONE;
1641 }")
1642
1643 (define_expand "bordered"
1644   [(set (pc)
1645         (if_then_else (ordered (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 (ORDERED, hppa_compare_op0, hppa_compare_op1));
1654   emit_bcond_fp (NE, operands[0]);
1655   DONE;
1656 }")
1657
1658 ;; Match the branch patterns.
1659
1660
1661 ;; Note a long backward conditional branch with an annulled delay slot
1662 ;; has a length of 12.
1663 (define_insn ""
1664   [(set (pc)
1665         (if_then_else
1666          (match_operator 3 "comparison_operator"
1667                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1668                           (match_operand:SI 2 "arith5_operand" "rL")])
1669          (label_ref (match_operand 0 "" ""))
1670          (pc)))]
1671   ""
1672   "*
1673 {
1674   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1675                          get_attr_length (insn), 0, insn);
1676 }"
1677 [(set_attr "type" "cbranch")
1678  (set (attr "length")
1679     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1680                (const_int 8184))
1681            (const_int 4)
1682            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1683                (const_int 262100))
1684            (const_int 8)
1685            (eq (symbol_ref "flag_pic") (const_int 0))
1686            (const_int 20)]
1687           (const_int 28)))])
1688
1689 ;; Match the negated branch.
1690
1691 (define_insn ""
1692   [(set (pc)
1693         (if_then_else
1694          (match_operator 3 "comparison_operator"
1695                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1696                           (match_operand:SI 2 "arith5_operand" "rL")])
1697          (pc)
1698          (label_ref (match_operand 0 "" ""))))]
1699   ""
1700   "*
1701 {
1702   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1703                          get_attr_length (insn), 1, insn);
1704 }"
1705 [(set_attr "type" "cbranch")
1706  (set (attr "length")
1707     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1708                (const_int 8184))
1709            (const_int 4)
1710            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1711                (const_int 262100))
1712            (const_int 8)
1713            (eq (symbol_ref "flag_pic") (const_int 0))
1714            (const_int 20)]
1715           (const_int 28)))])
1716
1717 (define_insn ""
1718   [(set (pc)
1719         (if_then_else
1720          (match_operator 3 "comparison_operator"
1721                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1722                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1723          (label_ref (match_operand 0 "" ""))
1724          (pc)))]
1725   "TARGET_64BIT"
1726   "*
1727 {
1728   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1729                          get_attr_length (insn), 0, insn);
1730 }"
1731 [(set_attr "type" "cbranch")
1732  (set (attr "length")
1733     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1734                (const_int 8184))
1735            (const_int 4)
1736            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1737                (const_int 262100))
1738            (const_int 8)
1739            (eq (symbol_ref "flag_pic") (const_int 0))
1740            (const_int 20)]
1741           (const_int 28)))])
1742
1743 ;; Match the negated branch.
1744
1745 (define_insn ""
1746   [(set (pc)
1747         (if_then_else
1748          (match_operator 3 "comparison_operator"
1749                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1750                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1751          (pc)
1752          (label_ref (match_operand 0 "" ""))))]
1753   "TARGET_64BIT"
1754   "*
1755 {
1756   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1757                          get_attr_length (insn), 1, insn);
1758 }"
1759 [(set_attr "type" "cbranch")
1760  (set (attr "length")
1761     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1762                (const_int 8184))
1763            (const_int 4)
1764            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1765                (const_int 262100))
1766            (const_int 8)
1767            (eq (symbol_ref "flag_pic") (const_int 0))
1768            (const_int 20)]
1769           (const_int 28)))])
1770 (define_insn ""
1771   [(set (pc)
1772         (if_then_else
1773          (match_operator 3 "cmpib_comparison_operator"
1774                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1775                           (match_operand:DI 2 "arith5_operand" "rL")])
1776          (label_ref (match_operand 0 "" ""))
1777          (pc)))]
1778   "TARGET_64BIT"
1779   "*
1780 {
1781   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1782                          get_attr_length (insn), 0, insn);
1783 }"
1784 [(set_attr "type" "cbranch")
1785  (set (attr "length")
1786     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1787                (const_int 8184))
1788            (const_int 4)
1789            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1790                (const_int 262100))
1791            (const_int 8)
1792            (eq (symbol_ref "flag_pic") (const_int 0))
1793            (const_int 20)]
1794           (const_int 28)))])
1795
1796 ;; Match the negated branch.
1797
1798 (define_insn ""
1799   [(set (pc)
1800         (if_then_else
1801          (match_operator 3 "cmpib_comparison_operator"
1802                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1803                           (match_operand:DI 2 "arith5_operand" "rL")])
1804          (pc)
1805          (label_ref (match_operand 0 "" ""))))]
1806   "TARGET_64BIT"
1807   "*
1808 {
1809   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1810                          get_attr_length (insn), 1, insn);
1811 }"
1812 [(set_attr "type" "cbranch")
1813  (set (attr "length")
1814     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1815                (const_int 8184))
1816            (const_int 4)
1817            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1818                (const_int 262100))
1819            (const_int 8)
1820            (eq (symbol_ref "flag_pic") (const_int 0))
1821            (const_int 20)]
1822           (const_int 28)))])
1823
1824 ;; Branch on Bit patterns.
1825 (define_insn ""
1826   [(set (pc)
1827         (if_then_else
1828          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1829                               (const_int 1)
1830                               (match_operand:SI 1 "uint5_operand" ""))
1831              (const_int 0))
1832          (label_ref (match_operand 2 "" ""))
1833          (pc)))]
1834   ""
1835   "*
1836 {
1837   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1838                          get_attr_length (insn), 0, insn, 0);
1839 }"
1840 [(set_attr "type" "cbranch")
1841  (set (attr "length")
1842     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1843                       (const_int 8184))
1844            (const_int 4)
1845            (const_int 8)))])
1846
1847 (define_insn ""
1848   [(set (pc)
1849         (if_then_else
1850          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1851                               (const_int 1)
1852                               (match_operand:DI 1 "uint32_operand" ""))
1853              (const_int 0))
1854          (label_ref (match_operand 2 "" ""))
1855          (pc)))]
1856   "TARGET_64BIT"
1857   "*
1858 {
1859   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1860                          get_attr_length (insn), 0, insn, 0);
1861 }"
1862 [(set_attr "type" "cbranch")
1863  (set (attr "length")
1864     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1865                       (const_int 8184))
1866            (const_int 4)
1867            (const_int 8)))])
1868
1869 (define_insn ""
1870   [(set (pc)
1871         (if_then_else
1872          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1873                               (const_int 1)
1874                               (match_operand:SI 1 "uint5_operand" ""))
1875              (const_int 0))
1876          (pc)
1877          (label_ref (match_operand 2 "" ""))))]
1878   ""
1879   "*
1880 {
1881   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1882                          get_attr_length (insn), 1, insn, 0);
1883 }"
1884 [(set_attr "type" "cbranch")
1885  (set (attr "length")
1886     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1887                       (const_int 8184))
1888            (const_int 4)
1889            (const_int 8)))])
1890
1891 (define_insn ""
1892   [(set (pc)
1893         (if_then_else
1894          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1895                               (const_int 1)
1896                               (match_operand:DI 1 "uint32_operand" ""))
1897              (const_int 0))
1898          (pc)
1899          (label_ref (match_operand 2 "" ""))))]
1900   "TARGET_64BIT"
1901   "*
1902 {
1903   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1904                          get_attr_length (insn), 1, insn, 0);
1905 }"
1906 [(set_attr "type" "cbranch")
1907  (set (attr "length")
1908     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1909                       (const_int 8184))
1910            (const_int 4)
1911            (const_int 8)))])
1912
1913 (define_insn ""
1914   [(set (pc)
1915         (if_then_else
1916          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1917                               (const_int 1)
1918                               (match_operand:SI 1 "uint5_operand" ""))
1919              (const_int 0))
1920          (label_ref (match_operand 2 "" ""))
1921          (pc)))]
1922   ""
1923   "*
1924 {
1925   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1926                          get_attr_length (insn), 0, insn, 1);
1927 }"
1928 [(set_attr "type" "cbranch")
1929  (set (attr "length")
1930     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1931                       (const_int 8184))
1932            (const_int 4)
1933            (const_int 8)))])
1934
1935 (define_insn ""
1936   [(set (pc)
1937         (if_then_else
1938          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1939                               (const_int 1)
1940                               (match_operand:DI 1 "uint32_operand" ""))
1941              (const_int 0))
1942          (label_ref (match_operand 2 "" ""))
1943          (pc)))]
1944   "TARGET_64BIT"
1945   "*
1946 {
1947   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1948                          get_attr_length (insn), 0, insn, 1);
1949 }"
1950 [(set_attr "type" "cbranch")
1951  (set (attr "length")
1952     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1953                       (const_int 8184))
1954            (const_int 4)
1955            (const_int 8)))])
1956
1957 (define_insn ""
1958   [(set (pc)
1959         (if_then_else
1960          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1961                               (const_int 1)
1962                               (match_operand:SI 1 "uint5_operand" ""))
1963              (const_int 0))
1964          (pc)
1965          (label_ref (match_operand 2 "" ""))))]
1966   ""
1967   "*
1968 {
1969   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1970                          get_attr_length (insn), 1, insn, 1);
1971 }"
1972 [(set_attr "type" "cbranch")
1973  (set (attr "length")
1974     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1975                       (const_int 8184))
1976            (const_int 4)
1977            (const_int 8)))])
1978
1979 (define_insn ""
1980   [(set (pc)
1981         (if_then_else
1982          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1983                               (const_int 1)
1984                               (match_operand:DI 1 "uint32_operand" ""))
1985              (const_int 0))
1986          (pc)
1987          (label_ref (match_operand 2 "" ""))))]
1988   "TARGET_64BIT"
1989   "*
1990 {
1991   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1992                          get_attr_length (insn), 1, insn, 1);
1993 }"
1994 [(set_attr "type" "cbranch")
1995  (set (attr "length")
1996     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1997                       (const_int 8184))
1998            (const_int 4)
1999            (const_int 8)))])
2000
2001 ;; Branch on Variable Bit patterns.
2002 (define_insn ""
2003   [(set (pc)
2004         (if_then_else
2005          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2006                               (const_int 1)
2007                               (match_operand:SI 1 "register_operand" "q"))
2008              (const_int 0))
2009          (label_ref (match_operand 2 "" ""))
2010          (pc)))]
2011   ""
2012   "*
2013 {
2014   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2015                      get_attr_length (insn), 0, insn, 0);
2016 }"
2017 [(set_attr "type" "cbranch")
2018  (set (attr "length")
2019     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2020                       (const_int 8184))
2021            (const_int 4)
2022            (const_int 8)))])
2023
2024 (define_insn ""
2025   [(set (pc)
2026         (if_then_else
2027          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2028                               (const_int 1)
2029                               (match_operand:DI 1 "register_operand" "q"))
2030              (const_int 0))
2031          (label_ref (match_operand 2 "" ""))
2032          (pc)))]
2033   "TARGET_64BIT"
2034   "*
2035 {
2036   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2037                      get_attr_length (insn), 0, insn, 0);
2038 }"
2039 [(set_attr "type" "cbranch")
2040  (set (attr "length")
2041     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2042                       (const_int 8184))
2043            (const_int 4)
2044            (const_int 8)))])
2045
2046 (define_insn ""
2047   [(set (pc)
2048         (if_then_else
2049          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2050                               (const_int 1)
2051                               (match_operand:SI 1 "register_operand" "q"))
2052              (const_int 0))
2053          (pc)
2054          (label_ref (match_operand 2 "" ""))))]
2055   ""
2056   "*
2057 {
2058   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2059                      get_attr_length (insn), 1, insn, 0);
2060 }"
2061 [(set_attr "type" "cbranch")
2062  (set (attr "length")
2063     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2064                       (const_int 8184))
2065            (const_int 4)
2066            (const_int 8)))])
2067
2068 (define_insn ""
2069   [(set (pc)
2070         (if_then_else
2071          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2072                               (const_int 1)
2073                               (match_operand:DI 1 "register_operand" "q"))
2074              (const_int 0))
2075          (pc)
2076          (label_ref (match_operand 2 "" ""))))]
2077   "TARGET_64BIT"
2078   "*
2079 {
2080   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2081                      get_attr_length (insn), 1, insn, 0);
2082 }"
2083 [(set_attr "type" "cbranch")
2084  (set (attr "length")
2085     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2086                       (const_int 8184))
2087            (const_int 4)
2088            (const_int 8)))])
2089
2090 (define_insn ""
2091   [(set (pc)
2092         (if_then_else
2093          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2094                               (const_int 1)
2095                               (match_operand:SI 1 "register_operand" "q"))
2096              (const_int 0))
2097          (label_ref (match_operand 2 "" ""))
2098          (pc)))]
2099   ""
2100   "*
2101 {
2102   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2103                      get_attr_length (insn), 0, insn, 1);
2104 }"
2105 [(set_attr "type" "cbranch")
2106  (set (attr "length")
2107     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2108                       (const_int 8184))
2109            (const_int 4)
2110            (const_int 8)))])
2111
2112 (define_insn ""
2113   [(set (pc)
2114         (if_then_else
2115          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2116                               (const_int 1)
2117                               (match_operand:DI 1 "register_operand" "q"))
2118              (const_int 0))
2119          (label_ref (match_operand 2 "" ""))
2120          (pc)))]
2121   "TARGET_64BIT"
2122   "*
2123 {
2124   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2125                      get_attr_length (insn), 0, insn, 1);
2126 }"
2127 [(set_attr "type" "cbranch")
2128  (set (attr "length")
2129     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2130                       (const_int 8184))
2131            (const_int 4)
2132            (const_int 8)))])
2133
2134 (define_insn ""
2135   [(set (pc)
2136         (if_then_else
2137          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2138                               (const_int 1)
2139                               (match_operand:SI 1 "register_operand" "q"))
2140              (const_int 0))
2141          (pc)
2142          (label_ref (match_operand 2 "" ""))))]
2143   ""
2144   "*
2145 {
2146   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2147                      get_attr_length (insn), 1, insn, 1);
2148 }"
2149 [(set_attr "type" "cbranch")
2150  (set (attr "length")
2151     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2152                       (const_int 8184))
2153            (const_int 4)
2154            (const_int 8)))])
2155
2156 (define_insn ""
2157   [(set (pc)
2158         (if_then_else
2159          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2160                               (const_int 1)
2161                               (match_operand:DI 1 "register_operand" "q"))
2162              (const_int 0))
2163          (pc)
2164          (label_ref (match_operand 2 "" ""))))]
2165   "TARGET_64BIT"
2166   "*
2167 {
2168   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2169                      get_attr_length (insn), 1, insn, 1);
2170 }"
2171 [(set_attr "type" "cbranch")
2172  (set (attr "length")
2173     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2174                       (const_int 8184))
2175            (const_int 4)
2176            (const_int 8)))])
2177
2178 ;; Floating point branches
2179 (define_insn ""
2180   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2181                            (label_ref (match_operand 0 "" ""))
2182                            (pc)))]
2183   "! TARGET_SOFT_FLOAT"
2184   "*
2185 {
2186   if (INSN_ANNULLED_BRANCH_P (insn))
2187     return \"ftest\;b,n %0\";
2188   else
2189     return \"ftest\;b%* %0\";
2190 }"
2191   [(set_attr "type" "fbranch")
2192    (set_attr "length" "8")])
2193
2194 (define_insn ""
2195   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2196                            (pc)
2197                            (label_ref (match_operand 0 "" ""))))]
2198   "! TARGET_SOFT_FLOAT"
2199   "*
2200 {
2201   if (INSN_ANNULLED_BRANCH_P (insn))
2202     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
2203   else
2204     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2205 }"
2206   [(set_attr "type" "fbranch")
2207    (set_attr "length" "12")])
2208
2209 ;; Move instructions
2210
2211 (define_expand "movsi"
2212   [(set (match_operand:SI 0 "general_operand" "")
2213         (match_operand:SI 1 "general_operand" ""))]
2214   ""
2215   "
2216 {
2217   if (emit_move_sequence (operands, SImode, 0))
2218     DONE;
2219 }")
2220
2221 ;; Reloading an SImode or DImode value requires a scratch register if
2222 ;; going in to or out of float point registers.
2223
2224 (define_expand "reload_insi"
2225   [(set (match_operand:SI 0 "register_operand" "=Z")
2226         (match_operand:SI 1 "non_hard_reg_operand" ""))
2227    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2228   ""
2229   "
2230 {
2231   if (emit_move_sequence (operands, SImode, operands[2]))
2232     DONE;
2233
2234   /* We don't want the clobber emitted, so handle this ourselves.  */
2235   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2236   DONE;
2237 }")
2238
2239 (define_expand "reload_outsi"
2240   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2241         (match_operand:SI 1  "register_operand" "Z"))
2242    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2243   ""
2244   "
2245 {
2246   if (emit_move_sequence (operands, SImode, operands[2]))
2247     DONE;
2248
2249   /* We don't want the clobber emitted, so handle this ourselves.  */
2250   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2251   DONE;
2252 }")
2253
2254 (define_insn ""
2255   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2256                                 "=r,r,r,r,r,r,Q,*q,!f,f,*TR")
2257         (match_operand:SI 1 "move_operand"
2258                                 "A,r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
2259   "(register_operand (operands[0], SImode)
2260     || reg_or_0_operand (operands[1], SImode))
2261    && ! TARGET_SOFT_FLOAT"
2262   "@
2263    ldw RT'%A1,%0
2264    copy %1,%0
2265    ldi %1,%0
2266    ldil L'%1,%0
2267    {zdepi|depwi,z} %Z1,%0
2268    ldw%M1 %1,%0
2269    stw%M0 %r1,%0
2270    mtsar %r1
2271    fcpy,sgl %f1,%0
2272    fldw%F1 %1,%0
2273    fstw%F0 %1,%0"
2274   [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
2275    (set_attr "pa_combine_type" "addmove")
2276    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
2277
2278 (define_insn ""
2279   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
2280                                 "=r,r,r,r,r,r,Q,*q")
2281         (match_operand:SI 1 "move_operand"
2282                                 "A,r,J,N,K,RQ,rM,rM"))]
2283   "(register_operand (operands[0], SImode)
2284     || reg_or_0_operand (operands[1], SImode))
2285    && TARGET_SOFT_FLOAT"
2286   "@
2287    ldw RT'%A1,%0
2288    copy %1,%0
2289    ldi %1,%0
2290    ldil L'%1,%0
2291    {zdepi|depwi,z} %Z1,%0
2292    ldw%M1 %1,%0
2293    stw%M0 %r1,%0
2294    mtsar %r1"
2295   [(set_attr "type" "load,move,move,move,move,load,store,move")
2296    (set_attr "pa_combine_type" "addmove")
2297    (set_attr "length" "4,4,4,4,4,4,4,4")])
2298
2299 (define_insn ""
2300   [(set (match_operand:SI 0 "register_operand" "=r")
2301         (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2302                          (match_operand:SI 2 "register_operand" "r"))))]
2303   "! TARGET_DISABLE_INDEXING"
2304   "{ldwx|ldw} %2(%1),%0"
2305   [(set_attr "type" "load")
2306    (set_attr "length" "4")])
2307
2308 (define_insn ""
2309   [(set (match_operand:SI 0 "register_operand" "=r")
2310         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
2311                          (match_operand:SI 2 "basereg_operand" "r"))))]
2312   "! TARGET_DISABLE_INDEXING"
2313   "{ldwx|ldw} %1(%2),%0"
2314   [(set_attr "type" "load")
2315    (set_attr "length" "4")])
2316
2317 ;; Load or store with base-register modification.
2318
2319 (define_expand "pre_load"
2320   [(parallel [(set (match_operand:SI 0 "register_operand" "")
2321               (mem (plus (match_operand 1 "register_operand" "")
2322                                (match_operand 2 "pre_cint_operand" ""))))
2323               (set (match_dup 1)
2324                    (plus (match_dup 1) (match_dup 2)))])]
2325   ""
2326   "
2327 {
2328   if (TARGET_64BIT)
2329     {
2330       emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2331       DONE;
2332     }
2333   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2334   DONE;
2335 }")
2336
2337 (define_insn "pre_ldw"
2338   [(set (match_operand:SI 0 "register_operand" "=r")
2339         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2340                          (match_operand:SI 2 "pre_cint_operand" ""))))
2341    (set (match_dup 1)
2342         (plus:SI (match_dup 1) (match_dup 2)))]
2343   ""
2344   "*
2345 {
2346   if (INTVAL (operands[2]) < 0)
2347     return \"{ldwm|ldw,mb} %2(%1),%0\";
2348   return \"{ldws|ldw},mb %2(%1),%0\";
2349 }"
2350   [(set_attr "type" "load")
2351    (set_attr "length" "4")])
2352
2353 (define_insn "pre_ldd"
2354   [(set (match_operand:DI 0 "register_operand" "=r")
2355         (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2356                          (match_operand:DI 2 "pre_cint_operand" ""))))
2357    (set (match_dup 1)
2358         (plus:DI (match_dup 1) (match_dup 2)))]
2359   "TARGET_64BIT"
2360   "ldd,mb %2(%1),%0"
2361   [(set_attr "type" "load")
2362    (set_attr "length" "4")])
2363
2364 (define_insn ""
2365   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2366                          (match_operand:SI 1 "pre_cint_operand" "")))
2367         (match_operand:SI 2 "reg_or_0_operand" "rM"))
2368    (set (match_dup 0)
2369         (plus:SI (match_dup 0) (match_dup 1)))]
2370   ""
2371   "*
2372 {
2373   if (INTVAL (operands[1]) < 0)
2374     return \"{stwm|stw,mb} %r2,%1(%0)\";
2375   return \"{stws|stw},mb %r2,%1(%0)\";
2376 }"
2377   [(set_attr "type" "store")
2378    (set_attr "length" "4")])
2379
2380 (define_insn ""
2381   [(set (match_operand:SI 0 "register_operand" "=r")
2382         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2383    (set (match_dup 1)
2384         (plus:SI (match_dup 1)
2385                  (match_operand:SI 2 "post_cint_operand" "")))]
2386   ""
2387   "*
2388 {
2389   if (INTVAL (operands[2]) > 0)
2390     return \"{ldwm|ldw,ma} %2(%1),%0\";
2391   return \"{ldws|ldw},ma %2(%1),%0\";
2392 }"
2393   [(set_attr "type" "load")
2394    (set_attr "length" "4")])
2395
2396 (define_expand "post_store"
2397   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2398                    (match_operand 1 "reg_or_0_operand" ""))
2399               (set (match_dup 0)
2400                    (plus (match_dup 0)
2401                          (match_operand 2 "post_cint_operand" "")))])]
2402   ""
2403   "
2404 {
2405   if (TARGET_64BIT)
2406     {
2407       emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2408       DONE;
2409     }
2410   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2411   DONE;
2412 }")
2413
2414 (define_insn "post_stw"
2415   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2416         (match_operand:SI 1 "reg_or_0_operand" "rM"))
2417    (set (match_dup 0)
2418         (plus:SI (match_dup 0)
2419                  (match_operand:SI 2 "post_cint_operand" "")))]
2420   ""
2421   "*
2422 {
2423   if (INTVAL (operands[2]) > 0)
2424     return \"{stwm|stw,ma} %r1,%2(%0)\";
2425   return \"{stws|stw},ma %r1,%2(%0)\";
2426 }"
2427   [(set_attr "type" "store")
2428    (set_attr "length" "4")])
2429
2430 (define_insn "post_std"
2431   [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2432         (match_operand:DI 1 "reg_or_0_operand" "rM"))
2433    (set (match_dup 0)
2434         (plus:DI (match_dup 0)
2435                  (match_operand:DI 2 "post_cint_operand" "")))]
2436   "TARGET_64BIT"
2437   "std,ma %r1,%2(%0)"
2438   [(set_attr "type" "store")
2439    (set_attr "length" "4")])
2440
2441 ;; For loading the address of a label while generating PIC code.
2442 ;; Note since this pattern can be created at reload time (via movsi), all
2443 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2444 (define_insn ""
2445   [(set (match_operand 0 "pmode_register_operand" "=a")
2446         (match_operand 1 "pic_label_operand" ""))]
2447   ""
2448   "*
2449 {
2450   rtx xoperands[3];
2451   extern FILE *asm_out_file;
2452
2453   xoperands[0] = operands[0];
2454   xoperands[1] = operands[1];
2455   if (TARGET_SOM || ! TARGET_GAS)
2456     xoperands[2] = gen_label_rtx ();
2457
2458   output_asm_insn (\"{bl|b,l} .+8,%0\", xoperands);
2459   output_asm_insn (\"{depi|depwi} 0,31,2,%0\", xoperands);
2460   if (TARGET_SOM || ! TARGET_GAS)
2461     ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
2462                                CODE_LABEL_NUMBER (xoperands[2]));
2463
2464   /* If we're trying to load the address of a label that happens to be
2465      close, then we can use a shorter sequence.  */
2466   if (GET_CODE (operands[1]) == LABEL_REF
2467       && INSN_ADDRESSES_SET_P ()
2468       && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2469                 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2470     {
2471       /* Prefixing with R% here is wrong, it extracts just 11 bits and is
2472          always non-negative.  */
2473       if (TARGET_SOM || ! TARGET_GAS)
2474         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2475       else
2476         output_asm_insn (\"ldo %1-$PIC_pcrel$0+8(%0),%0\", xoperands);
2477     }
2478   else
2479     {
2480       if (TARGET_SOM || ! TARGET_GAS)
2481         {
2482           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2483           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2484         }
2485       else
2486         {
2487           output_asm_insn (\"addil L%%%1-$PIC_pcrel$0+8,%0\", xoperands);
2488           output_asm_insn (\"ldo R%%%1-$PIC_pcrel$0+12(%0),%0\",
2489                            xoperands);
2490         }
2491     }
2492   return \"\";
2493 }"
2494   [(set_attr "type" "multi")
2495    (set_attr "length" "16")])           ; 12 or 16
2496
2497 (define_insn ""
2498   [(set (match_operand:SI 0 "register_operand" "=a")
2499         (plus:SI (match_operand:SI 1 "register_operand" "r")
2500                  (high:SI (match_operand 2 "" ""))))]
2501   "symbolic_operand (operands[2], Pmode)
2502    && ! function_label_operand (operands[2], Pmode)
2503    && flag_pic"
2504   "addil LT'%G2,%1"
2505   [(set_attr "type" "binary")
2506    (set_attr "length" "4")])
2507
2508 (define_insn ""
2509   [(set (match_operand:DI 0 "register_operand" "=a")
2510         (plus:DI (match_operand:DI 1 "register_operand" "r")
2511                  (high:DI (match_operand 2 "" ""))))]
2512   "symbolic_operand (operands[2], Pmode)
2513    && ! function_label_operand (operands[2], Pmode)
2514    && TARGET_64BIT
2515    && flag_pic"
2516   "addil LT'%G2,%1"
2517   [(set_attr "type" "binary")
2518    (set_attr "length" "4")])
2519
2520 ;; Always use addil rather than ldil;add sequences.  This allows the
2521 ;; HP linker to eliminate the dp relocation if the symbolic operand
2522 ;; lives in the TEXT space.
2523 (define_insn ""
2524   [(set (match_operand:SI 0 "register_operand" "=a")
2525         (high:SI (match_operand 1 "" "")))]
2526   "symbolic_operand (operands[1], Pmode)
2527    && ! function_label_operand (operands[1], Pmode)
2528    && ! read_only_operand (operands[1], Pmode)
2529    && ! flag_pic"
2530   "*
2531 {
2532   if (TARGET_LONG_LOAD_STORE)
2533     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2534   else
2535     return \"addil LR'%H1,%%r27\";
2536 }"
2537   [(set_attr "type" "binary")
2538    (set (attr "length")
2539       (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
2540                     (const_int 4)
2541                     (const_int 8)))])
2542
2543
2544 ;; This is for use in the prologue/epilogue code.  We need it
2545 ;; to add large constants to a stack pointer or frame pointer.
2546 ;; Because of the additional %r1 pressure, we probably do not
2547 ;; want to use this in general code, so make it available
2548 ;; only after reload.
2549 (define_insn ""
2550   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2551         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2552                  (high:SI (match_operand 2 "const_int_operand" ""))))]
2553   "reload_completed"
2554   "@
2555    addil L'%G2,%1
2556    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2557   [(set_attr "type" "binary,binary")
2558    (set_attr "length" "4,8")])
2559
2560 (define_insn ""
2561   [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2562         (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2563                  (high:DI (match_operand 2 "const_int_operand" ""))))]
2564   "reload_completed && TARGET_64BIT"
2565   "@
2566    addil L'%G2,%1
2567    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2568   [(set_attr "type" "binary,binary")
2569    (set_attr "length" "4,8")])
2570
2571 (define_insn ""
2572   [(set (match_operand:SI 0 "register_operand" "=r")
2573         (high:SI (match_operand 1 "" "")))]
2574   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2575     && !is_function_label_plus_const (operands[1])"
2576   "*
2577 {
2578   if (symbolic_operand (operands[1], Pmode))
2579     return \"ldil LR'%H1,%0\";
2580   else
2581     return \"ldil L'%G1,%0\";
2582 }"
2583   [(set_attr "type" "move")
2584    (set_attr "length" "4")])
2585
2586 (define_insn ""
2587   [(set (match_operand:DI 0 "register_operand" "=r")
2588         (high:DI (match_operand 1 "const_int_operand" "")))]
2589   "TARGET_64BIT"
2590   "ldil L'%G1,%0";
2591   [(set_attr "type" "move")
2592    (set_attr "length" "4")])
2593
2594 (define_insn ""
2595   [(set (match_operand:DI 0 "register_operand" "=r")
2596         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2597                    (match_operand:DI 2 "const_int_operand" "i")))]
2598   "TARGET_64BIT"
2599   "ldo R'%G2(%1),%0";
2600   [(set_attr "type" "move")
2601    (set_attr "length" "4")])
2602
2603 (define_insn ""
2604   [(set (match_operand:SI 0 "register_operand" "=r")
2605         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2606                    (match_operand:SI 2 "immediate_operand" "i")))]
2607   "!is_function_label_plus_const (operands[2])"
2608   "*
2609 {
2610   if (flag_pic && symbolic_operand (operands[2], Pmode))
2611     abort ();
2612   else if (symbolic_operand (operands[2], Pmode))
2613     return \"ldo RR'%G2(%1),%0\";
2614   else
2615     return \"ldo R'%G2(%1),%0\";
2616 }"
2617   [(set_attr "type" "move")
2618    (set_attr "length" "4")])
2619
2620 ;; Now that a symbolic_address plus a constant is broken up early
2621 ;; in the compilation phase (for better CSE) we need a special
2622 ;; combiner pattern to load the symbolic address plus the constant
2623 ;; in only 2 instructions. (For cases where the symbolic address
2624 ;; was not a common subexpression.)
2625 (define_split
2626   [(set (match_operand:SI 0 "register_operand" "")
2627         (match_operand:SI 1 "symbolic_operand" ""))
2628    (clobber (match_operand:SI 2 "register_operand" ""))]
2629   "! (flag_pic && pic_label_operand (operands[1], SImode))"
2630   [(set (match_dup 2) (high:SI (match_dup 1)))
2631    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2632   "")
2633
2634 ;; hppa_legitimize_address goes to a great deal of trouble to
2635 ;; create addresses which use indexing.  In some cases, this
2636 ;; is a lose because there isn't any store instructions which
2637 ;; allow indexed addresses (with integer register source).
2638 ;;
2639 ;; These define_splits try to turn a 3 insn store into
2640 ;; a 2 insn store with some creative RTL rewriting.
2641 (define_split
2642   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2643                                (match_operand:SI 1 "shadd_operand" ""))
2644                    (plus:SI (match_operand:SI 2 "register_operand" "")
2645                             (match_operand:SI 3 "const_int_operand" ""))))
2646         (match_operand:SI 4 "register_operand" ""))
2647    (clobber (match_operand:SI 5 "register_operand" ""))]
2648   ""
2649   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2650                                (match_dup 2)))
2651    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2652   "")
2653
2654 (define_split
2655   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2656                                (match_operand:SI 1 "shadd_operand" ""))
2657                    (plus:SI (match_operand:SI 2 "register_operand" "")
2658                             (match_operand:SI 3 "const_int_operand" ""))))
2659         (match_operand:HI 4 "register_operand" ""))
2660    (clobber (match_operand:SI 5 "register_operand" ""))]
2661   ""
2662   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2663                                (match_dup 2)))
2664    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2665   "")
2666
2667 (define_split
2668   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2669                                (match_operand:SI 1 "shadd_operand" ""))
2670                    (plus:SI (match_operand:SI 2 "register_operand" "")
2671                             (match_operand:SI 3 "const_int_operand" ""))))
2672         (match_operand:QI 4 "register_operand" ""))
2673    (clobber (match_operand:SI 5 "register_operand" ""))]
2674   ""
2675   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2676                                (match_dup 2)))
2677    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2678   "")
2679
2680 (define_expand "movhi"
2681   [(set (match_operand:HI 0 "general_operand" "")
2682         (match_operand:HI 1 "general_operand" ""))]
2683   ""
2684   "
2685 {
2686   if (emit_move_sequence (operands, HImode, 0))
2687     DONE;
2688 }")
2689
2690 (define_insn ""
2691   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2692         (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2693   "register_operand (operands[0], HImode)
2694    || reg_or_0_operand (operands[1], HImode)"
2695   "@
2696    copy %1,%0
2697    ldi %1,%0
2698    ldil L'%1,%0
2699    {zdepi|depwi,z} %Z1,%0
2700    ldh%M1 %1,%0
2701    sth%M0 %r1,%0
2702    mtsar %r1
2703    fcpy,sgl %f1,%0"
2704   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2705    (set_attr "pa_combine_type" "addmove")
2706    (set_attr "length" "4,4,4,4,4,4,4,4")])
2707
2708 (define_insn ""
2709   [(set (match_operand:HI 0 "register_operand" "=r")
2710         (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2711                          (match_operand:SI 2 "register_operand" "r"))))]
2712   "! TARGET_DISABLE_INDEXING"
2713   "{ldhx|ldh} %2(%1),%0"
2714   [(set_attr "type" "load")
2715    (set_attr "length" "4")])
2716
2717 (define_insn ""
2718   [(set (match_operand:HI 0 "register_operand" "=r")
2719         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
2720                          (match_operand:SI 2 "basereg_operand" "r"))))]
2721   "! TARGET_DISABLE_INDEXING"
2722   "{ldhx|ldh} %1(%2),%0"
2723   [(set_attr "type" "load")
2724    (set_attr "length" "4")])
2725
2726 ; Now zero extended variants.
2727 (define_insn ""
2728   [(set (match_operand:SI 0 "register_operand" "=r")
2729         (zero_extend:SI (mem:HI
2730                           (plus:SI
2731                             (match_operand:SI 1 "basereg_operand" "r")
2732                             (match_operand:SI 2 "register_operand" "r")))))]
2733   "! TARGET_DISABLE_INDEXING"
2734   "{ldhx|ldh} %2(%1),%0"
2735   [(set_attr "type" "load")
2736    (set_attr "length" "4")])
2737
2738 (define_insn ""
2739   [(set (match_operand:SI 0 "register_operand" "=r")
2740         (zero_extend:SI (mem:HI
2741                           (plus:SI
2742                              (match_operand:SI 1 "register_operand" "r")
2743                              (match_operand:SI 2 "basereg_operand" "r")))))]
2744   "! TARGET_DISABLE_INDEXING"
2745   "{ldhx|ldh} %1(%2),%0"
2746   [(set_attr "type" "load")
2747    (set_attr "length" "4")])
2748
2749 (define_insn ""
2750   [(set (match_operand:HI 0 "register_operand" "=r")
2751         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2752                          (match_operand:SI 2 "int5_operand" "L"))))
2753    (set (match_dup 1)
2754         (plus:SI (match_dup 1) (match_dup 2)))]
2755   ""
2756   "{ldhs|ldh},mb %2(%1),%0"
2757   [(set_attr "type" "load")
2758    (set_attr "length" "4")])
2759
2760 ; And a zero extended variant.
2761 (define_insn ""
2762   [(set (match_operand:SI 0 "register_operand" "=r")
2763         (zero_extend:SI (mem:HI
2764                           (plus:SI
2765                             (match_operand:SI 1 "register_operand" "+r")
2766                             (match_operand:SI 2 "int5_operand" "L")))))
2767    (set (match_dup 1)
2768         (plus:SI (match_dup 1) (match_dup 2)))]
2769   ""
2770   "{ldhs|ldh},mb %2(%1),%0"
2771   [(set_attr "type" "load")
2772    (set_attr "length" "4")])
2773
2774 (define_insn ""
2775   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2776                          (match_operand:SI 1 "int5_operand" "L")))
2777         (match_operand:HI 2 "reg_or_0_operand" "rM"))
2778    (set (match_dup 0)
2779         (plus:SI (match_dup 0) (match_dup 1)))]
2780   ""
2781   "{sths|sth},mb %r2,%1(%0)"
2782   [(set_attr "type" "store")
2783    (set_attr "length" "4")])
2784
2785 (define_insn ""
2786   [(set (match_operand:HI 0 "register_operand" "=r")
2787         (plus:HI (match_operand:HI 1 "register_operand" "r")
2788                  (match_operand 2 "const_int_operand" "J")))]
2789   ""
2790   "ldo %2(%1),%0"
2791   [(set_attr "type" "binary")
2792    (set_attr "pa_combine_type" "addmove")
2793    (set_attr "length" "4")])
2794
2795 (define_expand "movqi"
2796   [(set (match_operand:QI 0 "general_operand" "")
2797         (match_operand:QI 1 "general_operand" ""))]
2798   ""
2799   "
2800 {
2801   if (emit_move_sequence (operands, QImode, 0))
2802     DONE;
2803 }")
2804
2805 (define_insn ""
2806   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
2807         (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
2808   "register_operand (operands[0], QImode)
2809    || reg_or_0_operand (operands[1], QImode)"
2810   "@
2811    copy %1,%0
2812    ldi %1,%0
2813    ldil L'%1,%0
2814    {zdepi|depwi,z} %Z1,%0
2815    ldb%M1 %1,%0
2816    stb%M0 %r1,%0
2817    mtsar %r1
2818    fcpy,sgl %f1,%0"
2819   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
2820    (set_attr "pa_combine_type" "addmove")
2821    (set_attr "length" "4,4,4,4,4,4,4,4")])
2822
2823 (define_insn ""
2824   [(set (match_operand:QI 0 "register_operand" "=r")
2825         (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2826                          (match_operand:SI 2 "register_operand" "r"))))]
2827   "! TARGET_DISABLE_INDEXING"
2828   "{ldbx|ldb} %2(%1),%0"
2829   [(set_attr "type" "load")
2830    (set_attr "length" "4")])
2831
2832 (define_insn ""
2833   [(set (match_operand:QI 0 "register_operand" "=r")
2834         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
2835                          (match_operand:SI 2 "basereg_operand" "r"))))]
2836   "! TARGET_DISABLE_INDEXING"
2837   "{ldbx|ldb} %1(%2),%0"
2838   [(set_attr "type" "load")
2839    (set_attr "length" "4")])
2840
2841 ; Indexed byte load with zero extension to SImode or HImode.
2842 (define_insn ""
2843   [(set (match_operand:SI 0 "register_operand" "=r")
2844         (zero_extend:SI (mem:QI
2845                           (plus:SI
2846                             (match_operand:SI 1 "basereg_operand" "r")
2847                             (match_operand:SI 2 "register_operand" "r")))))]
2848   "! TARGET_DISABLE_INDEXING"
2849   "{ldbx|ldb} %2(%1),%0"
2850   [(set_attr "type" "load")
2851    (set_attr "length" "4")])
2852
2853 (define_insn ""
2854   [(set (match_operand:SI 0 "register_operand" "=r")
2855         (zero_extend:SI (mem:QI
2856                           (plus:SI
2857                             (match_operand:SI 1 "register_operand" "r")
2858                             (match_operand:SI 2 "basereg_operand" "r")))))]
2859   "! TARGET_DISABLE_INDEXING"
2860   "{ldbx|ldb} %1(%2),%0"
2861   [(set_attr "type" "load")
2862    (set_attr "length" "4")])
2863
2864 (define_insn ""
2865   [(set (match_operand:HI 0 "register_operand" "=r")
2866         (zero_extend:HI (mem:QI
2867                           (plus:SI
2868                             (match_operand:SI 1 "basereg_operand" "r")
2869                             (match_operand:SI 2 "register_operand" "r")))))]
2870   "! TARGET_DISABLE_INDEXING"
2871   "{ldbx|ldb} %2(%1),%0"
2872   [(set_attr "type" "load")
2873    (set_attr "length" "4")])
2874
2875 (define_insn ""
2876   [(set (match_operand:HI 0 "register_operand" "=r")
2877         (zero_extend:HI (mem:QI
2878                           (plus:SI
2879                             (match_operand:SI 1 "register_operand" "r")
2880                             (match_operand:SI 2 "basereg_operand" "r")))))]
2881   "! TARGET_DISABLE_INDEXING"
2882   "{ldbx|ldb} %1(%2),%0"
2883   [(set_attr "type" "load")
2884    (set_attr "length" "4")])
2885
2886 (define_insn ""
2887   [(set (match_operand:QI 0 "register_operand" "=r")
2888         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2889                          (match_operand:SI 2 "int5_operand" "L"))))
2890    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2891   ""
2892   "{ldbs|ldb},mb %2(%1),%0"
2893   [(set_attr "type" "load")
2894    (set_attr "length" "4")])
2895
2896 ; Now the same thing with zero extensions.
2897 (define_insn ""
2898   [(set (match_operand:SI 0 "register_operand" "=r")
2899         (zero_extend:SI (mem:QI (plus:SI
2900                                   (match_operand:SI 1 "register_operand" "+r")
2901                                   (match_operand:SI 2 "int5_operand" "L")))))
2902    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2903   ""
2904   "{ldbs|ldb},mb %2(%1),%0"
2905   [(set_attr "type" "load")
2906    (set_attr "length" "4")])
2907
2908 (define_insn ""
2909   [(set (match_operand:HI 0 "register_operand" "=r")
2910         (zero_extend:HI (mem:QI (plus:SI
2911                                   (match_operand:SI 1 "register_operand" "+r")
2912                                   (match_operand:SI 2 "int5_operand" "L")))))
2913    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2914   ""
2915   "{ldbs|ldb},mb %2(%1),%0"
2916   [(set_attr "type" "load")
2917    (set_attr "length" "4")])
2918
2919 (define_insn ""
2920   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2921                          (match_operand:SI 1 "int5_operand" "L")))
2922         (match_operand:QI 2 "reg_or_0_operand" "rM"))
2923    (set (match_dup 0)
2924         (plus:SI (match_dup 0) (match_dup 1)))]
2925   ""
2926   "{stbs|stb},mb %r2,%1(%0)"
2927   [(set_attr "type" "store")
2928    (set_attr "length" "4")])
2929
2930 ;; The definition of this insn does not really explain what it does,
2931 ;; but it should suffice
2932 ;; that anything generated as this insn will be recognized as one
2933 ;; and that it will not successfully combine with anything.
2934 (define_expand "movstrsi"
2935   [(parallel [(set (match_operand:BLK 0 "" "")
2936                    (match_operand:BLK 1 "" ""))
2937               (clobber (match_dup 7))
2938               (clobber (match_dup 8))
2939               (clobber (match_dup 4))
2940               (clobber (match_dup 5))
2941               (clobber (match_dup 6))
2942               (use (match_operand:SI 2 "arith_operand" ""))
2943               (use (match_operand:SI 3 "const_int_operand" ""))])]
2944   "!TARGET_64BIT"
2945   "
2946 {
2947   int size, align;
2948
2949   /* HP provides very fast block move library routine for the PA;
2950      this routine includes:
2951
2952         4x4 byte at a time block moves,
2953         1x4 byte at a time with alignment checked at runtime with
2954             attempts to align the source and destination as needed
2955         1x1 byte loop
2956
2957      With that in mind, here's the heuristics to try and guess when
2958      the inlined block move will be better than the library block
2959      move:
2960
2961         If the size isn't constant, then always use the library routines.
2962
2963         If the size is large in respect to the known alignment, then use
2964         the library routines.
2965
2966         If the size is small in repsect to the known alignment, then open
2967         code the copy (since that will lead to better scheduling).
2968
2969         Else use the block move pattern.   */
2970
2971   /* Undetermined size, use the library routine.  */
2972   if (GET_CODE (operands[2]) != CONST_INT)
2973     FAIL;
2974
2975   size = INTVAL (operands[2]);
2976   align = INTVAL (operands[3]);
2977   align = align > 4 ? 4 : align;
2978
2979   /* If size/alignment > 8 (eg size is large in respect to alignment),
2980      then use the library routines.  */
2981   if (size / align > 16)
2982     FAIL;
2983
2984   /* This does happen, but not often enough to worry much about.  */
2985   if (size / align < MOVE_RATIO)
2986     FAIL;
2987   
2988   /* Fall through means we're going to use our block move pattern.  */
2989   operands[0]
2990     = replace_equiv_address (operands[0],
2991                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2992   operands[1]
2993     = replace_equiv_address (operands[1],
2994                              copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2995   operands[4] = gen_reg_rtx (SImode);
2996   operands[5] = gen_reg_rtx (SImode);
2997   operands[6] = gen_reg_rtx (SImode);
2998   operands[7] = XEXP (operands[0], 0);
2999   operands[8] = XEXP (operands[1], 0);
3000 }")
3001
3002 ;; The operand constraints are written like this to support both compile-time
3003 ;; and run-time determined byte count.  If the count is run-time determined,
3004 ;; the register with the byte count is clobbered by the copying code, and
3005 ;; therefore it is forced to operand 2.  If the count is compile-time
3006 ;; determined, we need two scratch registers for the unrolled code.
3007 (define_insn "movstrsi_internal"
3008   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3009         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3010    (clobber (match_dup 0))
3011    (clobber (match_dup 1))
3012    (clobber (match_operand:SI 2 "register_operand" "=r,r"))     ;loop cnt/tmp
3013    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp
3014    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3015    (use (match_operand:SI 4 "arith_operand" "J,2"))      ;byte count
3016    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3017   "!TARGET_64BIT"
3018   "* return output_block_move (operands, !which_alternative);"
3019   [(set_attr "type" "multi,multi")])
3020 \f
3021 ;; Floating point move insns
3022
3023 ;; This pattern forces (set (reg:DF ...) (const_double ...))
3024 ;; to be reloaded by putting the constant into memory when
3025 ;; reg is a floating point register.
3026 ;;
3027 ;; For integer registers we use ldil;ldo to set the appropriate
3028 ;; value.
3029 ;;
3030 ;; This must come before the movdf pattern, and it must be present
3031 ;; to handle obscure reloading cases.
3032 (define_insn ""
3033   [(set (match_operand:DF 0 "register_operand" "=?r,f")
3034         (match_operand:DF 1 "" "?F,m"))]
3035   "GET_CODE (operands[1]) == CONST_DOUBLE
3036    && operands[1] != CONST0_RTX (DFmode)
3037    && !TARGET_64BIT
3038    && ! TARGET_SOFT_FLOAT"
3039   "* return (which_alternative == 0 ? output_move_double (operands)
3040                                     : \"fldd%F1 %1,%0\");"
3041   [(set_attr "type" "move,fpload")
3042    (set_attr "length" "16,4")])
3043
3044 (define_expand "movdf"
3045   [(set (match_operand:DF 0 "general_operand" "")
3046         (match_operand:DF 1 "general_operand" ""))]
3047   ""
3048   "
3049 {
3050   if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
3051       operands[1] = force_const_mem (DFmode, operands[1]);
3052
3053   if (emit_move_sequence (operands, DFmode, 0))
3054     DONE;
3055 }")
3056
3057 ;; Reloading an SImode or DImode value requires a scratch register if
3058 ;; going in to or out of float point registers.
3059
3060 (define_expand "reload_indf"
3061   [(set (match_operand:DF 0 "register_operand" "=Z")
3062         (match_operand:DF 1 "non_hard_reg_operand" ""))
3063    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3064   ""
3065   "
3066 {
3067   if (emit_move_sequence (operands, DFmode, operands[2]))
3068     DONE;
3069
3070   /* We don't want the clobber emitted, so handle this ourselves.  */
3071   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3072   DONE;
3073 }")
3074
3075 (define_expand "reload_outdf" 
3076  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3077         (match_operand:DF 1  "register_operand" "Z"))
3078    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3079   ""
3080   "
3081 {
3082   if (emit_move_sequence (operands, DFmode, operands[2]))
3083     DONE;
3084
3085   /* We don't want the clobber emitted, so handle this ourselves.  */
3086   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3087   DONE;
3088 }")
3089
3090 (define_insn ""
3091   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
3092                           "=f,*r,RQ,?o,?Q,f,*r,*r")
3093         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3094                           "fG,*rG,f,*r,*r,RQ,o,RQ"))]
3095   "(register_operand (operands[0], DFmode)
3096     || reg_or_0_operand (operands[1], DFmode))
3097    && ! (GET_CODE (operands[1]) == CONST_DOUBLE
3098          && GET_CODE (operands[0]) == MEM)
3099    && ! TARGET_64BIT
3100    && ! TARGET_SOFT_FLOAT"
3101   "*
3102 {
3103   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3104       || operands[1] == CONST0_RTX (DFmode))
3105     return output_fp_move_double (operands);
3106   return output_move_double (operands);
3107 }"
3108   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
3109    (set_attr "length" "4,8,4,8,16,4,8,16")])
3110
3111 (define_insn ""
3112   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
3113                           "=r,?o,?Q,r,r")
3114         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3115                           "rG,r,r,o,Q"))]
3116   "(register_operand (operands[0], DFmode)
3117     || reg_or_0_operand (operands[1], DFmode))
3118    && ! TARGET_64BIT
3119    && TARGET_SOFT_FLOAT"
3120   "*
3121 {
3122   return output_move_double (operands);
3123 }"
3124   [(set_attr "type" "move,store,store,load,load")
3125    (set_attr "length" "8,8,16,8,16")])
3126
3127 (define_insn ""
3128   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
3129                                 "=r,r,r,r,r,Q,*q,!f,f,*TR")
3130         (match_operand:DF 1 "move_operand"
3131                                 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
3132   "(register_operand (operands[0], DFmode)
3133     || reg_or_0_operand (operands[1], DFmode))
3134    && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3135   "@
3136    copy %1,%0
3137    ldi %1,%0
3138    ldil L'%1,%0
3139    depdi,z %z1,%0
3140    ldd%M1 %1,%0
3141    std%M0 %r1,%0
3142    mtsar %r1
3143    fcpy,dbl %f1,%0
3144    fldd%F1 %1,%0
3145    fstd%F0 %1,%0"
3146   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
3147    (set_attr "pa_combine_type" "addmove")
3148    (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
3149
3150 (define_insn ""
3151   [(set (match_operand:DF 0 "register_operand" "=fx")
3152         (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3153                          (match_operand:SI 2 "register_operand" "r"))))]
3154   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3155   "{flddx|fldd} %2(%1),%0"
3156   [(set_attr "type" "fpload")
3157    (set_attr "length" "4")])
3158
3159 (define_insn ""
3160   [(set (match_operand:DF 0 "register_operand" "=fx")
3161         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
3162                          (match_operand:SI 2 "basereg_operand" "r"))))]
3163   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3164   "{flddx|fldd} %1(%2),%0"
3165   [(set_attr "type" "fpload")
3166    (set_attr "length" "4")])
3167
3168 (define_insn ""
3169   [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3170                          (match_operand:SI 2 "register_operand" "r")))
3171         (match_operand:DF 0 "register_operand" "fx"))]
3172   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3173   "{fstdx|fstd} %0,%2(%1)"
3174   [(set_attr "type" "fpstore")
3175    (set_attr "length" "4")])
3176
3177 (define_insn ""
3178   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
3179                          (match_operand:SI 2 "basereg_operand" "r")))
3180         (match_operand:DF 0 "register_operand" "fx"))]
3181   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3182   "{fstdx|fstd} %0,%1(%2)"
3183   [(set_attr "type" "fpstore")
3184    (set_attr "length" "4")])
3185
3186 (define_expand "movdi"
3187   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
3188         (match_operand:DI 1 "general_operand" ""))]
3189   ""
3190   "
3191 {
3192   if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
3193       operands[1] = force_const_mem (DImode, operands[1]);
3194
3195   if (emit_move_sequence (operands, DImode, 0))
3196     DONE;
3197 }")
3198
3199 (define_expand "reload_indi"
3200   [(set (match_operand:DI 0 "register_operand" "=Z")
3201         (match_operand:DI 1 "non_hard_reg_operand" ""))
3202    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3203   ""
3204   "
3205 {
3206   if (emit_move_sequence (operands, DImode, operands[2]))
3207     DONE;
3208
3209   /* We don't want the clobber emitted, so handle this ourselves.  */
3210   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3211   DONE;
3212 }")
3213
3214 (define_expand "reload_outdi"
3215   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
3216         (match_operand:DI 1 "register_operand" "Z"))
3217    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
3218   ""
3219   "
3220 {
3221   if (emit_move_sequence (operands, DImode, operands[2]))
3222     DONE;
3223
3224   /* We don't want the clobber emitted, so handle this ourselves.  */
3225   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3226   DONE;
3227 }")
3228
3229 (define_insn ""
3230   [(set (match_operand:DI 0 "register_operand" "=r")
3231         (high:DI (match_operand 1 "" "")))]
3232   "!TARGET_64BIT"
3233   "*
3234 {
3235   rtx op0 = operands[0];
3236   rtx op1 = operands[1];
3237
3238   if (GET_CODE (op1) == CONST_INT)
3239     {
3240       operands[0] = operand_subword (op0, 1, 0, DImode);
3241       output_asm_insn (\"ldil L'%1,%0\", operands);
3242
3243       operands[0] = operand_subword (op0, 0, 0, DImode);
3244       if (INTVAL (op1) < 0)
3245         output_asm_insn (\"ldi -1,%0\", operands);
3246       else
3247         output_asm_insn (\"ldi 0,%0\", operands);
3248       return \"\";
3249     }
3250   else if (GET_CODE (op1) == CONST_DOUBLE)
3251     {
3252       operands[0] = operand_subword (op0, 1, 0, DImode);
3253       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
3254       output_asm_insn (\"ldil L'%1,%0\", operands);
3255
3256       operands[0] = operand_subword (op0, 0, 0, DImode);
3257       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
3258       output_asm_insn (singlemove_string (operands), operands);
3259       return \"\";
3260     }
3261   else
3262     abort ();
3263 }"
3264   [(set_attr "type" "move")
3265    (set_attr "length" "8")])
3266
3267 (define_insn ""
3268   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3269                           "=r,o,Q,r,r,r,f,f,*TR")
3270         (match_operand:DI 1 "general_operand"
3271                           "rM,r,r,o*R,Q,i,fM,*TR,f"))]
3272   "(register_operand (operands[0], DImode)
3273     || reg_or_0_operand (operands[1], DImode))
3274    && ! TARGET_64BIT
3275    && ! TARGET_SOFT_FLOAT"
3276   "*
3277 {
3278   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3279       || (operands[1] == CONST0_RTX (DImode)))
3280     return output_fp_move_double (operands);
3281   return output_move_double (operands);
3282 }"
3283   [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
3284    (set_attr "length" "8,8,16,8,16,16,4,4,4")])
3285
3286 (define_insn ""
3287   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3288                                 "=r,r,r,r,r,r,Q,*q,!f,f,*TR")
3289         (match_operand:DI 1 "move_operand"
3290                                 "A,r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
3291   "(register_operand (operands[0], DImode)
3292     || reg_or_0_operand (operands[1], DImode))
3293    && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
3294   "@
3295    ldd RT'%A1,%0
3296    copy %1,%0
3297    ldi %1,%0
3298    ldil L'%1,%0
3299    depdi,z %z1,%0
3300    ldd%M1 %1,%0
3301    std%M0 %r1,%0
3302    mtsar %r1
3303    fcpy,dbl %f1,%0
3304    fldd%F1 %1,%0
3305    fstd%F0 %1,%0"
3306   [(set_attr "type" "load,move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
3307    (set_attr "pa_combine_type" "addmove")
3308    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4")])
3309
3310 (define_insn ""
3311   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
3312                           "=r,o,Q,r,r,r")
3313         (match_operand:DI 1 "general_operand"
3314                           "rM,r,r,o,Q,i"))]
3315   "(register_operand (operands[0], DImode)
3316     || reg_or_0_operand (operands[1], DImode))
3317    && ! TARGET_64BIT
3318    && TARGET_SOFT_FLOAT"
3319   "*
3320 {
3321   return output_move_double (operands);
3322 }"
3323   [(set_attr "type" "move,store,store,load,load,multi")
3324    (set_attr "length" "8,8,16,8,16,16")])
3325
3326 (define_insn ""
3327   [(set (match_operand:DI 0 "register_operand" "=r,&r")
3328         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
3329                    (match_operand:DI 2 "immediate_operand" "i,i")))]
3330   "!TARGET_64BIT"
3331   "*
3332 {
3333   /* Don't output a 64 bit constant, since we can't trust the assembler to
3334      handle it correctly.  */
3335   if (GET_CODE (operands[2]) == CONST_DOUBLE)
3336     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
3337   if (which_alternative == 1)
3338     output_asm_insn (\"copy %1,%0\", operands);
3339   return \"ldo R'%G2(%R1),%R0\";
3340 }"
3341   [(set_attr "type" "move,move")
3342    (set_attr "length" "4,8")])
3343
3344 ;; This pattern forces (set (reg:SF ...) (const_double ...))
3345 ;; to be reloaded by putting the constant into memory when
3346 ;; reg is a floating point register.
3347 ;;
3348 ;; For integer registers we use ldil;ldo to set the appropriate
3349 ;; value.
3350 ;;
3351 ;; This must come before the movsf pattern, and it must be present
3352 ;; to handle obscure reloading cases.
3353 (define_insn ""
3354   [(set (match_operand:SF 0 "register_operand" "=?r,f")
3355         (match_operand:SF 1 "" "?F,m"))]
3356   "GET_CODE (operands[1]) == CONST_DOUBLE
3357    && operands[1] != CONST0_RTX (SFmode)
3358    && ! TARGET_SOFT_FLOAT"
3359   "* return (which_alternative == 0 ? singlemove_string (operands)
3360                                     : \" fldw%F1 %1,%0\");"
3361   [(set_attr "type" "move,fpload")
3362    (set_attr "length" "8,4")])
3363
3364 (define_expand "movsf"
3365   [(set (match_operand:SF 0 "general_operand" "")
3366         (match_operand:SF 1 "general_operand" ""))]
3367   ""
3368   "
3369 {
3370   if (emit_move_sequence (operands, SFmode, 0))
3371     DONE;
3372 }")
3373
3374 ;; Reloading an SImode or DImode value requires a scratch register if
3375 ;; going in to or out of float point registers.
3376
3377 (define_expand "reload_insf"
3378   [(set (match_operand:SF 0 "register_operand" "=Z")
3379         (match_operand:SF 1 "non_hard_reg_operand" ""))
3380    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3381   ""
3382   "
3383 {
3384   if (emit_move_sequence (operands, SFmode, operands[2]))
3385     DONE;
3386
3387   /* We don't want the clobber emitted, so handle this ourselves.  */
3388   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3389   DONE;
3390 }")
3391
3392 (define_expand "reload_outsf"
3393   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
3394         (match_operand:SF 1  "register_operand" "Z"))
3395    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
3396   ""
3397   "
3398 {
3399   if (emit_move_sequence (operands, SFmode, operands[2]))
3400     DONE;
3401
3402   /* We don't want the clobber emitted, so handle this ourselves.  */
3403   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3404   DONE;
3405 }")
3406
3407 (define_insn ""
3408   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3409                           "=f,r,f,r,RQ,Q")
3410         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3411                           "fG,rG,RQ,RQ,f,rG"))]
3412   "(register_operand (operands[0], SFmode)
3413     || reg_or_0_operand (operands[1], SFmode))
3414    && ! TARGET_SOFT_FLOAT"
3415   "@
3416    fcpy,sgl %f1,%0
3417    copy %r1,%0
3418    fldw%F1 %1,%0
3419    ldw%M1 %1,%0
3420    fstw%F0 %r1,%0
3421    stw%M0 %r1,%0"
3422   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
3423    (set_attr "pa_combine_type" "addmove")
3424    (set_attr "length" "4,4,4,4,4,4")])
3425
3426 (define_insn ""
3427   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
3428                           "=r,r,Q")
3429         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
3430                           "rG,RQ,rG"))]
3431   "(register_operand (operands[0], SFmode)
3432     || reg_or_0_operand (operands[1], SFmode))
3433    && TARGET_SOFT_FLOAT"
3434   "@
3435    copy %r1,%0
3436    ldw%M1 %1,%0
3437    stw%M0 %r1,%0"
3438   [(set_attr "type" "move,load,store")
3439    (set_attr "pa_combine_type" "addmove")
3440    (set_attr "length" "4,4,4")])
3441
3442 (define_insn ""
3443   [(set (match_operand:SF 0 "register_operand" "=fx")
3444         (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3445                          (match_operand:SI 2 "register_operand" "r"))))]
3446   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3447   "{fldwx|fldw} %2(%1),%0"
3448   [(set_attr "type" "fpload")
3449    (set_attr "length" "4")])
3450
3451 (define_insn ""
3452   [(set (match_operand:SF 0 "register_operand" "=fx")
3453         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3454                          (match_operand:SI 2 "basereg_operand" "r"))))]
3455   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3456   "{fldwx|fldw} %1(%2),%0"
3457   [(set_attr "type" "fpload")
3458    (set_attr "length" "4")])
3459
3460 (define_insn ""
3461   [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
3462                          (match_operand:SI 2 "register_operand" "r")))
3463       (match_operand:SF 0 "register_operand" "fx"))]
3464   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3465   "{fstwx|fstw} %0,%2(%1)"
3466   [(set_attr "type" "fpstore")
3467    (set_attr "length" "4")])
3468 \f
3469 (define_insn ""
3470   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
3471                          (match_operand:SI 2 "basereg_operand" "r")))
3472       (match_operand:SF 0 "register_operand" "fx"))]
3473   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
3474   "{fstwx|fstw} %0,%1(%2)"
3475   [(set_attr "type" "fpstore")
3476    (set_attr "length" "4")])
3477 \f
3478
3479 ;;- zero extension instructions
3480 ;; We have define_expand for zero extension patterns to make sure the
3481 ;; operands get loaded into registers.  The define_insns accept
3482 ;; memory operands.  This gives us better overall code than just
3483 ;; having a pattern that does or does not accept memory operands.
3484
3485 (define_expand "zero_extendhisi2"
3486   [(set (match_operand:SI 0 "register_operand" "")
3487         (zero_extend:SI
3488          (match_operand:HI 1 "register_operand" "")))]
3489   ""
3490   "")
3491
3492 (define_insn ""
3493   [(set (match_operand:SI 0 "register_operand" "=r,r")
3494         (zero_extend:SI
3495          (match_operand:HI 1 "move_operand" "r,RQ")))]
3496   "GET_CODE (operands[1]) != CONST_INT"
3497   "@
3498    {extru|extrw,u} %1,31,16,%0
3499    ldh%M1 %1,%0"
3500   [(set_attr "type" "shift,load")
3501    (set_attr "length" "4,4")])
3502
3503 (define_expand "zero_extendqihi2"
3504   [(set (match_operand:HI 0 "register_operand" "")
3505         (zero_extend:HI
3506          (match_operand:QI 1 "register_operand" "")))]
3507   ""
3508   "")
3509
3510 (define_insn ""
3511   [(set (match_operand:HI 0 "register_operand" "=r,r")
3512         (zero_extend:HI
3513          (match_operand:QI 1 "move_operand" "r,RQ")))]
3514   "GET_CODE (operands[1]) != CONST_INT"
3515   "@
3516    {extru|extrw,u} %1,31,8,%0
3517    ldb%M1 %1,%0"
3518   [(set_attr "type" "shift,load")
3519    (set_attr "length" "4,4")])
3520
3521 (define_expand "zero_extendqisi2"
3522   [(set (match_operand:SI 0 "register_operand" "")
3523         (zero_extend:SI
3524          (match_operand:QI 1 "register_operand" "")))]
3525   ""
3526   "")
3527
3528 (define_insn ""
3529   [(set (match_operand:SI 0 "register_operand" "=r,r")
3530         (zero_extend:SI
3531          (match_operand:QI 1 "move_operand" "r,RQ")))]
3532   "GET_CODE (operands[1]) != CONST_INT"
3533   "@
3534    {extru|extrw,u} %1,31,8,%0
3535    ldb%M1 %1,%0"
3536   [(set_attr "type" "shift,load")
3537    (set_attr "length" "4,4")])
3538
3539 (define_insn "zero_extendqidi2"
3540   [(set (match_operand:DI 0 "register_operand" "=r")
3541         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3542   "TARGET_64BIT"
3543   "extrd,u %1,63,8,%0"
3544   [(set_attr "type" "shift") 
3545   (set_attr "length" "4")])
3546
3547 (define_insn "zero_extendhidi2"
3548   [(set (match_operand:DI 0 "register_operand" "=r")
3549         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3550   "TARGET_64BIT"
3551   "extrd,u %1,63,16,%0"
3552   [(set_attr "type" "shift") 
3553   (set_attr "length" "4")])
3554
3555 (define_insn "zero_extendsidi2"
3556   [(set (match_operand:DI 0 "register_operand" "=r")
3557         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3558   "TARGET_64BIT"
3559   "extrd,u %1,63,32,%0"
3560   [(set_attr "type" "shift") 
3561   (set_attr "length" "4")])
3562
3563 ;;- sign extension instructions
3564
3565 (define_insn "extendhisi2"
3566   [(set (match_operand:SI 0 "register_operand" "=r")
3567         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
3568   ""
3569   "{extrs|extrw,s} %1,31,16,%0"
3570   [(set_attr "type" "shift")
3571    (set_attr "length" "4")])
3572
3573 (define_insn "extendqihi2"
3574   [(set (match_operand:HI 0 "register_operand" "=r")
3575         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
3576   ""
3577   "{extrs|extrw,s} %1,31,8,%0"
3578   [(set_attr "type" "shift") 
3579   (set_attr "length" "4")])
3580
3581 (define_insn "extendqisi2"
3582   [(set (match_operand:SI 0 "register_operand" "=r")
3583         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
3584   ""
3585   "{extrs|extrw,s} %1,31,8,%0"
3586   [(set_attr "type" "shift")
3587    (set_attr "length" "4")])
3588
3589 (define_insn "extendqidi2"
3590   [(set (match_operand:DI 0 "register_operand" "=r")
3591         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3592   "TARGET_64BIT"
3593   "extrd,s %1,63,8,%0"
3594   [(set_attr "type" "shift") 
3595   (set_attr "length" "4")])
3596
3597 (define_insn "extendhidi2"
3598   [(set (match_operand:DI 0 "register_operand" "=r")
3599         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3600   "TARGET_64BIT"
3601   "extrd,s %1,63,16,%0"
3602   [(set_attr "type" "shift") 
3603   (set_attr "length" "4")])
3604
3605 (define_insn "extendsidi2"
3606   [(set (match_operand:DI 0 "register_operand" "=r")
3607         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3608   "TARGET_64BIT"
3609   "extrd,s %1,63,32,%0"
3610   [(set_attr "type" "shift") 
3611   (set_attr "length" "4")])
3612
3613 \f
3614 ;; Conversions between float and double.
3615
3616 (define_insn "extendsfdf2"
3617   [(set (match_operand:DF 0 "register_operand" "=f")
3618         (float_extend:DF
3619          (match_operand:SF 1 "register_operand" "f")))]
3620   "! TARGET_SOFT_FLOAT"
3621   "{fcnvff|fcnv},sgl,dbl %1,%0"
3622   [(set_attr "type" "fpalu")
3623    (set_attr "length" "4")])
3624
3625 (define_insn "truncdfsf2"
3626   [(set (match_operand:SF 0 "register_operand" "=f")
3627         (float_truncate:SF
3628          (match_operand:DF 1 "register_operand" "f")))]
3629   "! TARGET_SOFT_FLOAT"
3630   "{fcnvff|fcnv},dbl,sgl %1,%0"
3631   [(set_attr "type" "fpalu")
3632    (set_attr "length" "4")])
3633
3634 ;; Conversion between fixed point and floating point.
3635 ;; Note that among the fix-to-float insns
3636 ;; the ones that start with SImode come first.
3637 ;; That is so that an operand that is a CONST_INT
3638 ;; (and therefore lacks a specific machine mode).
3639 ;; will be recognized as SImode (which is always valid)
3640 ;; rather than as QImode or HImode.
3641
3642 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
3643 ;; to be reloaded by putting the constant into memory.
3644 ;; It must come before the more general floatsisf2 pattern.
3645 (define_insn ""
3646   [(set (match_operand:SF 0 "register_operand" "=f")
3647         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
3648   "! TARGET_SOFT_FLOAT"
3649   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
3650   [(set_attr "type" "fpalu")
3651    (set_attr "length" "8")])
3652
3653 (define_insn "floatsisf2"
3654   [(set (match_operand:SF 0 "register_operand" "=f")
3655         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3656   "! TARGET_SOFT_FLOAT"
3657   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
3658   [(set_attr "type" "fpalu")
3659    (set_attr "length" "4")])
3660
3661 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
3662 ;; to be reloaded by putting the constant into memory.
3663 ;; It must come before the more general floatsidf2 pattern.
3664 (define_insn ""
3665   [(set (match_operand:DF 0 "register_operand" "=f")
3666         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
3667   "! TARGET_SOFT_FLOAT"
3668   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
3669   [(set_attr "type" "fpalu")
3670    (set_attr "length" "8")])
3671
3672 (define_insn "floatsidf2"
3673   [(set (match_operand:DF 0 "register_operand" "=f")
3674         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3675   "! TARGET_SOFT_FLOAT"
3676   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
3677   [(set_attr "type" "fpalu")
3678    (set_attr "length" "4")])
3679
3680 (define_expand "floatunssisf2"
3681   [(set (subreg:SI (match_dup 2) 4)
3682         (match_operand:SI 1 "register_operand" ""))
3683    (set (subreg:SI (match_dup 2) 0)
3684         (const_int 0))
3685    (set (match_operand:SF 0 "register_operand" "")
3686         (float:SF (match_dup 2)))]
3687   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3688   "
3689 {
3690   if (TARGET_PA_20)
3691     {
3692       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
3693       DONE;
3694     }
3695   operands[2] = gen_reg_rtx (DImode);
3696 }")
3697
3698 (define_expand "floatunssidf2"
3699   [(set (subreg:SI (match_dup 2) 4)
3700         (match_operand:SI 1 "register_operand" ""))
3701    (set (subreg:SI (match_dup 2) 0)
3702         (const_int 0))
3703    (set (match_operand:DF 0 "register_operand" "")
3704         (float:DF (match_dup 2)))]
3705   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3706   "
3707 {
3708   if (TARGET_PA_20)
3709     {
3710       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
3711       DONE;
3712     }
3713   operands[2] = gen_reg_rtx (DImode);
3714 }")
3715
3716 (define_insn "floatdisf2"
3717   [(set (match_operand:SF 0 "register_operand" "=f")
3718         (float:SF (match_operand:DI 1 "register_operand" "f")))]
3719   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3720   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
3721   [(set_attr "type" "fpalu")
3722    (set_attr "length" "4")])
3723
3724 (define_insn "floatdidf2"
3725   [(set (match_operand:DF 0 "register_operand" "=f")
3726         (float:DF (match_operand:DI 1 "register_operand" "f")))]
3727   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3728   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
3729   [(set_attr "type" "fpalu")
3730    (set_attr "length" "4")])
3731
3732 ;; Convert a float to an actual integer.
3733 ;; Truncation is performed as part of the conversion.
3734
3735 (define_insn "fix_truncsfsi2"
3736   [(set (match_operand:SI 0 "register_operand" "=f")
3737         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3738   "! TARGET_SOFT_FLOAT"
3739   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
3740   [(set_attr "type" "fpalu")
3741    (set_attr "length" "4")])
3742
3743 (define_insn "fix_truncdfsi2"
3744   [(set (match_operand:SI 0 "register_operand" "=f")
3745         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3746   "! TARGET_SOFT_FLOAT"
3747   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
3748   [(set_attr "type" "fpalu")
3749    (set_attr "length" "4")])
3750
3751 (define_insn "fix_truncsfdi2"
3752   [(set (match_operand:DI 0 "register_operand" "=f")
3753         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3754   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3755   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
3756   [(set_attr "type" "fpalu")
3757    (set_attr "length" "4")])
3758
3759 (define_insn "fix_truncdfdi2"
3760   [(set (match_operand:DI 0 "register_operand" "=f")
3761         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3762   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
3763   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
3764   [(set_attr "type" "fpalu")
3765    (set_attr "length" "4")])
3766
3767 (define_insn "floatunssidf2_pa20"
3768   [(set (match_operand:DF 0 "register_operand" "=f")
3769         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
3770   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3771   "fcnv,uw,dbl %1,%0"
3772   [(set_attr "type" "fpalu")
3773    (set_attr "length" "4")])
3774
3775 (define_insn "floatunssisf2_pa20"
3776   [(set (match_operand:SF 0 "register_operand" "=f")
3777         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
3778   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3779   "fcnv,uw,sgl %1,%0"
3780   [(set_attr "type" "fpalu")
3781    (set_attr "length" "4")])
3782
3783 (define_insn "floatunsdisf2"
3784   [(set (match_operand:SF 0 "register_operand" "=f")
3785         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
3786   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3787   "fcnv,udw,sgl %1,%0"
3788   [(set_attr "type" "fpalu")
3789    (set_attr "length" "4")])
3790
3791 (define_insn "floatunsdidf2"
3792   [(set (match_operand:DF 0 "register_operand" "=f")
3793         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
3794   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3795   "fcnv,udw,dbl %1,%0"
3796   [(set_attr "type" "fpalu")
3797    (set_attr "length" "4")])
3798
3799 (define_insn "fixuns_truncsfsi2"
3800   [(set (match_operand:SI 0 "register_operand" "=f")
3801         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3802   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3803   "fcnv,t,sgl,uw %1,%0"
3804   [(set_attr "type" "fpalu")
3805    (set_attr "length" "4")])
3806
3807 (define_insn "fixuns_truncdfsi2"
3808   [(set (match_operand:SI 0 "register_operand" "=f")
3809         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3810   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3811   "fcnv,t,dbl,uw %1,%0"
3812   [(set_attr "type" "fpalu")
3813    (set_attr "length" "4")])
3814
3815 (define_insn "fixuns_truncsfdi2"
3816   [(set (match_operand:DI 0 "register_operand" "=f")
3817         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3818   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3819   "fcnv,t,sgl,udw %1,%0"
3820   [(set_attr "type" "fpalu")
3821    (set_attr "length" "4")])
3822
3823 (define_insn "fixuns_truncdfdi2"
3824   [(set (match_operand:DI 0 "register_operand" "=f")
3825         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3826   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3827   "fcnv,t,dbl,udw %1,%0"
3828   [(set_attr "type" "fpalu")
3829    (set_attr "length" "4")])
3830 \f
3831 ;;- arithmetic instructions
3832
3833 (define_expand "adddi3"
3834   [(set (match_operand:DI 0 "register_operand" "")
3835         (plus:DI (match_operand:DI 1 "register_operand" "")
3836                  (match_operand:DI 2 "adddi3_operand" "")))]
3837   ""
3838   "")
3839
3840 (define_insn ""
3841   [(set (match_operand:DI 0 "register_operand" "=r")
3842         (plus:DI (match_operand:DI 1 "register_operand" "%r")
3843                  (match_operand:DI 2 "arith11_operand" "rI")))]
3844   "!TARGET_64BIT"
3845   "*
3846 {
3847   if (GET_CODE (operands[2]) == CONST_INT)
3848     {
3849       if (INTVAL (operands[2]) >= 0)
3850         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
3851       else
3852         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
3853     }
3854   else
3855     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
3856 }"
3857   [(set_attr "type" "binary")
3858    (set_attr "length" "8")])
3859
3860 (define_insn ""
3861   [(set (match_operand:DI 0 "register_operand" "=r,r")
3862         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3863                  (match_operand:DI 2 "arith_operand" "r,J")))]
3864   "TARGET_64BIT"
3865   "@
3866    {addl|add,l} %1,%2,%0
3867    ldo %2(%1),%0"
3868   [(set_attr "type" "binary,binary")
3869    (set_attr "pa_combine_type" "addmove")
3870    (set_attr "length" "4,4")])
3871
3872 (define_insn ""
3873   [(set (match_operand:DI 0 "register_operand" "=r")
3874         (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3875                  (match_operand:DI 2 "register_operand" "r")))]
3876   "TARGET_64BIT"
3877   "uaddcm %2,%1,%0"
3878   [(set_attr "type" "binary")
3879    (set_attr "length" "4")])
3880
3881 (define_insn ""
3882   [(set (match_operand:SI 0 "register_operand" "=r")
3883         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3884                  (match_operand:SI 2 "register_operand" "r")))]
3885   ""
3886   "uaddcm %2,%1,%0"
3887   [(set_attr "type" "binary")
3888    (set_attr "length" "4")])
3889
3890 ;; define_splits to optimize cases of adding a constant integer
3891 ;; to a register when the constant does not fit in 14 bits.  */
3892 (define_split
3893   [(set (match_operand:SI 0 "register_operand" "")
3894         (plus:SI (match_operand:SI 1 "register_operand" "")
3895                  (match_operand:SI 2 "const_int_operand" "")))
3896    (clobber (match_operand:SI 4 "register_operand" ""))]
3897   "! cint_ok_for_move (INTVAL (operands[2]))
3898    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
3899   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
3900    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
3901   "
3902 {
3903   int val = INTVAL (operands[2]);
3904   int low = (val < 0) ? -0x2000 : 0x1fff;
3905   int rest = val - low;
3906
3907   operands[2] = GEN_INT (rest);
3908   operands[3] = GEN_INT (low);
3909 }")
3910
3911 (define_split
3912   [(set (match_operand:SI 0 "register_operand" "")
3913         (plus:SI (match_operand:SI 1 "register_operand" "")
3914                  (match_operand:SI 2 "const_int_operand" "")))
3915    (clobber (match_operand:SI 4 "register_operand" ""))]
3916   "! cint_ok_for_move (INTVAL (operands[2]))"
3917   [(set (match_dup 4) (match_dup 2))
3918    (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
3919                                (match_dup 1)))]
3920   "
3921 {
3922   HOST_WIDE_INT intval = INTVAL (operands[2]);
3923
3924   /* Try dividing the constant by 2, then 4, and finally 8 to see
3925      if we can get a constant which can be loaded into a register
3926      in a single instruction (cint_ok_for_move). 
3927
3928      If that fails, try to negate the constant and subtract it
3929      from our input operand.  */
3930   if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
3931     {
3932       operands[2] = GEN_INT (intval / 2);
3933       operands[3] = GEN_INT (2);
3934     }
3935   else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
3936     {
3937       operands[2] = GEN_INT (intval / 4);
3938       operands[3] = GEN_INT (4);
3939     }
3940   else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
3941     {
3942       operands[2] = GEN_INT (intval / 8);
3943       operands[3] = GEN_INT (8);
3944     }
3945   else if (cint_ok_for_move (-intval))
3946     {
3947       emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
3948       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
3949       DONE;
3950     }
3951   else
3952     FAIL;
3953 }")
3954
3955 (define_insn "addsi3"
3956   [(set (match_operand:SI 0 "register_operand" "=r,r")
3957         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3958                  (match_operand:SI 2 "arith_operand" "r,J")))]
3959   ""
3960   "@
3961    {addl|add,l} %1,%2,%0
3962    ldo %2(%1),%0"
3963   [(set_attr "type" "binary,binary")
3964    (set_attr "pa_combine_type" "addmove")
3965    (set_attr "length" "4,4")])
3966
3967 (define_expand "subdi3"
3968   [(set (match_operand:DI 0 "register_operand" "")
3969         (minus:DI (match_operand:DI 1 "register_operand" "")
3970                   (match_operand:DI 2 "register_operand" "")))]
3971   ""
3972   "")
3973
3974 (define_insn ""
3975   [(set (match_operand:DI 0 "register_operand" "=r")
3976         (minus:DI (match_operand:DI 1 "register_operand" "r")
3977                   (match_operand:DI 2 "register_operand" "r")))]
3978   "!TARGET_64BIT"
3979   "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
3980   [(set_attr "type" "binary")
3981   (set_attr "length" "8")])
3982
3983 (define_insn ""
3984   [(set (match_operand:DI 0 "register_operand" "=r,r,q")
3985         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,U")
3986                   (match_operand:DI 2 "register_operand" "r,r,r")))]
3987   "TARGET_64BIT"
3988   "@
3989    sub %1,%2,%0
3990    subi %1,%2,%0
3991    mtsarcm %2"
3992   [(set_attr "type" "binary,binary,move")
3993   (set_attr "length" "4,4,4")])
3994
3995 (define_expand "subsi3"
3996   [(set (match_operand:SI 0 "register_operand" "")
3997         (minus:SI (match_operand:SI 1 "arith11_operand" "")
3998                   (match_operand:SI 2 "register_operand" "")))]
3999   ""
4000   "")
4001
4002 (define_insn ""
4003   [(set (match_operand:SI 0 "register_operand" "=r,r")
4004         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
4005                   (match_operand:SI 2 "register_operand" "r,r")))]
4006   "!TARGET_PA_20"
4007   "@
4008    sub %1,%2,%0
4009    subi %1,%2,%0"
4010   [(set_attr "type" "binary,binary")
4011    (set_attr "length" "4,4")])
4012
4013 (define_insn ""
4014   [(set (match_operand:SI 0 "register_operand" "=r,r,q")
4015         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
4016                   (match_operand:SI 2 "register_operand" "r,r,r")))]
4017   "TARGET_PA_20"
4018   "@
4019    sub %1,%2,%0
4020    subi %1,%2,%0
4021    mtsarcm %2"
4022   [(set_attr "type" "binary,binary,move")
4023    (set_attr "length" "4,4,4")])
4024
4025 ;; Clobbering a "register_operand" instead of a match_scratch
4026 ;; in operand3 of millicode calls avoids spilling %r1 and
4027 ;; produces better code.
4028
4029 ;; The mulsi3 insns set up registers for the millicode call.
4030 (define_expand "mulsi3"
4031   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4032    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4033    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
4034               (clobber (match_dup 3))
4035               (clobber (reg:SI 26))
4036               (clobber (reg:SI 25))
4037               (clobber (match_dup 4))])
4038    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4039   ""
4040   "
4041 {
4042   operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
4043   if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
4044     {
4045       rtx scratch = gen_reg_rtx (DImode);
4046       operands[1] = force_reg (SImode, operands[1]);
4047       operands[2] = force_reg (SImode, operands[2]);
4048       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
4049       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4050                               gen_rtx_SUBREG (SImode, scratch, GET_MODE_SIZE (SImode))));
4051       DONE;
4052     }
4053   operands[3] = gen_reg_rtx (SImode);
4054 }")
4055
4056 (define_insn "umulsidi3"
4057   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
4058         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
4059                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
4060   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
4061   "xmpyu %1,%2,%0"
4062   [(set_attr "type" "fpmuldbl")
4063    (set_attr "length" "4")])
4064
4065 (define_insn ""
4066   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
4067         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
4068                  (match_operand:DI 2 "uint32_operand" "f")))]
4069   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
4070   "xmpyu %1,%R2,%0"
4071   [(set_attr "type" "fpmuldbl")
4072    (set_attr "length" "4")])
4073
4074 (define_insn ""
4075   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
4076         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
4077                  (match_operand:DI 2 "uint32_operand" "f")))]
4078   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
4079   "xmpyu %1,%2R,%0"
4080   [(set_attr "type" "fpmuldbl")
4081    (set_attr "length" "4")])
4082
4083 (define_insn ""
4084   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
4085    (clobber (match_operand:SI 0 "register_operand" "=a"))
4086    (clobber (reg:SI 26))
4087    (clobber (reg:SI 25))
4088    (clobber (reg:SI 31))]
4089   "!TARGET_64BIT"
4090   "* return output_mul_insn (0, insn);"
4091   [(set_attr "type" "milli")
4092    (set (attr "length")
4093      (cond [
4094 ;; Target (or stub) within reach
4095             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4096                      (const_int 240000))
4097                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4098                      (const_int 0)))
4099             (const_int 4)
4100
4101 ;; Out of reach PIC
4102             (ne (symbol_ref "flag_pic")
4103                 (const_int 0))
4104             (const_int 24)
4105
4106 ;; Out of reach PORTABLE_RUNTIME
4107             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4108                 (const_int 0))
4109             (const_int 20)]
4110
4111 ;; Out of reach, can use ble
4112           (const_int 12)))])
4113
4114 (define_insn ""
4115   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
4116    (clobber (match_operand:SI 0 "register_operand" "=a"))
4117    (clobber (reg:SI 26))
4118    (clobber (reg:SI 25))
4119    (clobber (reg:SI 2))]
4120   "TARGET_64BIT"
4121   "* return output_mul_insn (0, insn);"
4122   [(set_attr "type" "milli")
4123    (set (attr "length") (const_int 4))])
4124
4125 (define_expand "muldi3"
4126   [(set (match_operand:DI 0 "register_operand" "")
4127         (mult:DI (match_operand:DI 1 "register_operand" "")
4128                  (match_operand:DI 2 "register_operand" "")))]
4129   "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
4130   "
4131 {
4132   rtx low_product = gen_reg_rtx (DImode);
4133   rtx cross_product1 = gen_reg_rtx (DImode);
4134   rtx cross_product2 = gen_reg_rtx (DImode);
4135   rtx cross_scratch = gen_reg_rtx (DImode);
4136   rtx cross_product = gen_reg_rtx (DImode);
4137   rtx op1l, op1r, op2l, op2r;
4138   rtx op1shifted, op2shifted;
4139
4140   op1shifted = gen_reg_rtx (DImode);
4141   op2shifted = gen_reg_rtx (DImode);
4142   op1l = gen_reg_rtx (SImode);
4143   op1r = gen_reg_rtx (SImode);
4144   op2l = gen_reg_rtx (SImode);
4145   op2r = gen_reg_rtx (SImode);
4146
4147   emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
4148                                                 GEN_INT (32)));
4149   emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
4150                                                 GEN_INT (32)));
4151   op1r = gen_rtx_SUBREG (SImode, operands[1], 4);
4152   op2r = gen_rtx_SUBREG (SImode, operands[2], 4);
4153   op1l = gen_rtx_SUBREG (SImode, op1shifted, 4);
4154   op2l = gen_rtx_SUBREG (SImode, op2shifted, 4);
4155
4156   /* Emit multiplies for the cross products.  */
4157   emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
4158   emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
4159
4160   /* Emit a multiply for the low sub-word.  */
4161   emit_insn (gen_umulsidi3 (low_product, op2r, op1r));
4162
4163   /* Sum the cross products and shift them into proper position.  */
4164   emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
4165   emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
4166
4167   /* Add the cross product to the low product and store the result
4168      into the output operand .  */
4169   emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
4170   DONE;
4171 }")
4172
4173 ;;; Division and mod.
4174 (define_expand "divsi3"
4175   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4176    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4177    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
4178               (clobber (match_dup 3))
4179               (clobber (match_dup 4))
4180               (clobber (reg:SI 26))
4181               (clobber (reg:SI 25))
4182               (clobber (match_dup 5))])
4183    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4184   ""
4185   "
4186 {
4187   operands[3] = gen_reg_rtx (SImode);
4188   if (TARGET_64BIT)
4189     {
4190       operands[5] = gen_rtx_REG (SImode, 2);
4191       operands[4] = operands[5];
4192     }
4193   else
4194     {
4195       operands[5] = gen_rtx_REG (SImode, 31);
4196       operands[4] = gen_reg_rtx (SImode);
4197     }
4198   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
4199     DONE;
4200 }")
4201
4202 (define_insn ""
4203   [(set (reg:SI 29)
4204         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4205    (clobber (match_operand:SI 1 "register_operand" "=a"))
4206    (clobber (match_operand:SI 2 "register_operand" "=&r"))
4207    (clobber (reg:SI 26))
4208    (clobber (reg:SI 25))
4209    (clobber (reg:SI 31))]
4210   "!TARGET_64BIT"
4211   "*
4212    return output_div_insn (operands, 0, insn);"
4213   [(set_attr "type" "milli")
4214    (set (attr "length")
4215      (cond [
4216 ;; Target (or stub) within reach
4217             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4218                      (const_int 240000))
4219                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4220                      (const_int 0)))
4221             (const_int 4)
4222
4223 ;; Out of reach PIC
4224             (ne (symbol_ref "flag_pic")
4225                 (const_int 0))
4226             (const_int 24)
4227
4228 ;; Out of reach PORTABLE_RUNTIME
4229             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4230                 (const_int 0))
4231             (const_int 20)]
4232
4233 ;; Out of reach, can use ble
4234           (const_int 12)))])
4235
4236 (define_insn ""
4237   [(set (reg:SI 29)
4238         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4239    (clobber (match_operand:SI 1 "register_operand" "=a"))
4240    (clobber (match_operand:SI 2 "register_operand" "=&r"))
4241    (clobber (reg:SI 26))
4242    (clobber (reg:SI 25))
4243    (clobber (reg:SI 2))]
4244   "TARGET_64BIT"
4245   "*
4246    return output_div_insn (operands, 0, insn);"
4247   [(set_attr "type" "milli")
4248    (set (attr "length") (const_int 4))])
4249
4250 (define_expand "udivsi3"
4251   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4252    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4253    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
4254               (clobber (match_dup 3))
4255               (clobber (match_dup 4))
4256               (clobber (reg:SI 26))
4257               (clobber (reg:SI 25))
4258               (clobber (match_dup 5))])
4259    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4260   ""
4261   "
4262 {
4263   operands[3] = gen_reg_rtx (SImode);
4264   if (TARGET_64BIT)
4265     {
4266       operands[5] = gen_rtx_REG (SImode, 2);
4267       operands[4] = operands[5];
4268     }
4269   else
4270     {
4271       operands[5] = gen_rtx_REG (SImode, 31);
4272       operands[4] = gen_reg_rtx (SImode);
4273     }
4274   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
4275     DONE;
4276 }")
4277
4278 (define_insn ""
4279   [(set (reg:SI 29)
4280         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4281    (clobber (match_operand:SI 1 "register_operand" "=a"))
4282    (clobber (match_operand:SI 2 "register_operand" "=&r"))
4283    (clobber (reg:SI 26))
4284    (clobber (reg:SI 25))
4285    (clobber (reg:SI 31))]
4286   "!TARGET_64BIT"
4287   "*
4288    return output_div_insn (operands, 1, insn);"
4289   [(set_attr "type" "milli")
4290    (set (attr "length")
4291      (cond [
4292 ;; Target (or stub) within reach
4293             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4294                      (const_int 240000))
4295                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4296                      (const_int 0)))
4297             (const_int 4)
4298
4299 ;; Out of reach PIC
4300             (ne (symbol_ref "flag_pic")
4301                 (const_int 0))
4302             (const_int 24)
4303
4304 ;; Out of reach PORTABLE_RUNTIME
4305             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4306                 (const_int 0))
4307             (const_int 20)]
4308
4309 ;; Out of reach, can use ble
4310           (const_int 12)))])
4311
4312 (define_insn ""
4313   [(set (reg:SI 29)
4314         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
4315    (clobber (match_operand:SI 1 "register_operand" "=a"))
4316    (clobber (match_operand:SI 2 "register_operand" "=&r"))
4317    (clobber (reg:SI 26))
4318    (clobber (reg:SI 25))
4319    (clobber (reg:SI 2))]
4320   "TARGET_64BIT"
4321   "*
4322    return output_div_insn (operands, 1, insn);"
4323   [(set_attr "type" "milli")
4324    (set (attr "length") (const_int 4))])
4325
4326 (define_expand "modsi3"
4327   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4328    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4329    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4330               (clobber (match_dup 3))
4331               (clobber (match_dup 4))
4332               (clobber (reg:SI 26))
4333               (clobber (reg:SI 25))
4334               (clobber (match_dup 5))])
4335    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4336   ""
4337   "
4338 {
4339   if (TARGET_64BIT)
4340     {
4341       operands[5] = gen_rtx_REG (SImode, 2);
4342       operands[4] = operands[5];
4343     }
4344   else
4345     {
4346       operands[5] = gen_rtx_REG (SImode, 31);
4347       operands[4] = gen_reg_rtx (SImode);
4348     }
4349   operands[3] = gen_reg_rtx (SImode);
4350 }")
4351
4352 (define_insn ""
4353   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4354    (clobber (match_operand:SI 0 "register_operand" "=a"))
4355    (clobber (match_operand:SI 1 "register_operand" "=&r"))
4356    (clobber (reg:SI 26))
4357    (clobber (reg:SI 25))
4358    (clobber (reg:SI 31))]
4359   "!TARGET_64BIT"
4360   "*
4361   return output_mod_insn (0, insn);"
4362   [(set_attr "type" "milli")
4363    (set (attr "length")
4364      (cond [
4365 ;; Target (or stub) within reach
4366             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4367                      (const_int 240000))
4368                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4369                      (const_int 0)))
4370             (const_int 4)
4371
4372 ;; Out of reach PIC
4373             (ne (symbol_ref "flag_pic")
4374                 (const_int 0))
4375             (const_int 24)
4376
4377 ;; Out of reach PORTABLE_RUNTIME
4378             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4379                 (const_int 0))
4380             (const_int 20)]
4381
4382 ;; Out of reach, can use ble
4383           (const_int 12)))])
4384
4385 (define_insn ""
4386   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
4387    (clobber (match_operand:SI 0 "register_operand" "=a"))
4388    (clobber (match_operand:SI 1 "register_operand" "=&r"))
4389    (clobber (reg:SI 26))
4390    (clobber (reg:SI 25))
4391    (clobber (reg:SI 2))]
4392   "TARGET_64BIT"
4393   "*
4394   return output_mod_insn (0, insn);"
4395   [(set_attr "type" "milli")
4396    (set (attr "length") (const_int 4))])
4397
4398 (define_expand "umodsi3"
4399   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
4400    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
4401    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4402               (clobber (match_dup 3))
4403               (clobber (match_dup 4))
4404               (clobber (reg:SI 26))
4405               (clobber (reg:SI 25))
4406               (clobber (match_dup 5))])
4407    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
4408   ""
4409   "
4410 {
4411   if (TARGET_64BIT)
4412     {
4413       operands[5] = gen_rtx_REG (SImode, 2);
4414       operands[4] = operands[5];
4415     }
4416   else
4417     {
4418       operands[5] = gen_rtx_REG (SImode, 31);
4419       operands[4] = gen_reg_rtx (SImode);
4420     }
4421   operands[3] = gen_reg_rtx (SImode);
4422 }")
4423
4424 (define_insn ""
4425   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4426    (clobber (match_operand:SI 0 "register_operand" "=a"))
4427    (clobber (match_operand:SI 1 "register_operand" "=&r"))
4428    (clobber (reg:SI 26))
4429    (clobber (reg:SI 25))
4430    (clobber (reg:SI 31))]
4431   "!TARGET_64BIT"
4432   "*
4433   return output_mod_insn (1, insn);"
4434   [(set_attr "type" "milli")
4435    (set (attr "length")
4436      (cond [
4437 ;; Target (or stub) within reach
4438             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4439                      (const_int 240000))
4440                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4441                      (const_int 0)))
4442             (const_int 4)
4443
4444 ;; Out of reach PIC
4445             (ne (symbol_ref "flag_pic")
4446                 (const_int 0))
4447             (const_int 24)
4448
4449 ;; Out of reach PORTABLE_RUNTIME
4450             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4451                 (const_int 0))
4452             (const_int 20)]
4453
4454 ;; Out of reach, can use ble
4455           (const_int 12)))])
4456
4457 (define_insn ""
4458   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
4459    (clobber (match_operand:SI 0 "register_operand" "=a"))
4460    (clobber (match_operand:SI 1 "register_operand" "=&r"))
4461    (clobber (reg:SI 26))
4462    (clobber (reg:SI 25))
4463    (clobber (reg:SI 2))]
4464   "TARGET_64BIT"
4465   "*
4466   return output_mod_insn (1, insn);"
4467   [(set_attr "type" "milli")
4468    (set (attr "length") (const_int 4))])
4469
4470 ;;- and instructions
4471 ;; We define DImode `and` so with DImode `not` we can get
4472 ;; DImode `andn`.  Other combinations are possible.
4473
4474 (define_expand "anddi3"
4475   [(set (match_operand:DI 0 "register_operand" "")
4476         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4477                 (match_operand:DI 2 "arith_double_operand" "")))]
4478   ""
4479   "
4480 {
4481   if (! register_operand (operands[1], DImode)
4482       || ! register_operand (operands[2], DImode))
4483     /* Let GCC break this into word-at-a-time operations.  */
4484     FAIL;
4485 }")
4486
4487 (define_insn ""
4488   [(set (match_operand:DI 0 "register_operand" "=r")
4489         (and:DI (match_operand:DI 1 "register_operand" "%r")
4490                 (match_operand:DI 2 "register_operand" "r")))]
4491   "!TARGET_64BIT"
4492   "and %1,%2,%0\;and %R1,%R2,%R0"
4493   [(set_attr "type" "binary")
4494    (set_attr "length" "8")])
4495
4496 (define_insn ""
4497   [(set (match_operand:DI 0 "register_operand" "=r,r")
4498         (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
4499                 (match_operand:DI 2 "and_operand" "rO,P")))]
4500   "TARGET_64BIT"
4501   "* return output_64bit_and (operands); "
4502   [(set_attr "type" "binary")
4503    (set_attr "length" "4")])
4504
4505 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
4506 ; constant with ldil;ldo.
4507 (define_insn "andsi3"
4508   [(set (match_operand:SI 0 "register_operand" "=r,r")
4509         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
4510                 (match_operand:SI 2 "and_operand" "rO,P")))]
4511   ""
4512   "* return output_and (operands); "
4513   [(set_attr "type" "binary,shift")
4514    (set_attr "length" "4,4")])
4515
4516 (define_insn ""
4517   [(set (match_operand:DI 0 "register_operand" "=r")
4518         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4519                 (match_operand:DI 2 "register_operand" "r")))]
4520   "!TARGET_64BIT"
4521   "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
4522   [(set_attr "type" "binary")
4523    (set_attr "length" "8")])
4524
4525 (define_insn ""
4526   [(set (match_operand:DI 0 "register_operand" "=r")
4527         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4528                 (match_operand:DI 2 "register_operand" "r")))]
4529   "TARGET_64BIT"
4530   "andcm %2,%1,%0"
4531   [(set_attr "type" "binary")
4532    (set_attr "length" "4")])
4533
4534 (define_insn ""
4535   [(set (match_operand:SI 0 "register_operand" "=r")
4536         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4537                 (match_operand:SI 2 "register_operand" "r")))]
4538   ""
4539   "andcm %2,%1,%0"
4540   [(set_attr "type" "binary")
4541   (set_attr "length" "4")])
4542
4543 (define_expand "iordi3"
4544   [(set (match_operand:DI 0 "register_operand" "")
4545         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4546                 (match_operand:DI 2 "arith_double_operand" "")))]
4547   ""
4548   "
4549 {
4550   if (! register_operand (operands[1], DImode)
4551       || ! register_operand (operands[2], DImode))
4552     /* Let GCC break this into word-at-a-time operations.  */
4553     FAIL;
4554 }")
4555
4556 (define_insn ""
4557   [(set (match_operand:DI 0 "register_operand" "=r")
4558         (ior:DI (match_operand:DI 1 "register_operand" "%r")
4559                 (match_operand:DI 2 "register_operand" "r")))]
4560   "!TARGET_64BIT"
4561   "or %1,%2,%0\;or %R1,%R2,%R0"
4562   [(set_attr "type" "binary")
4563    (set_attr "length" "8")])
4564
4565 (define_insn ""
4566   [(set (match_operand:DI 0 "register_operand" "=r,r")
4567         (ior:DI (match_operand:DI 1 "register_operand" "0,0")
4568                 (match_operand:DI 2 "ior_operand" "M,i")))]
4569   "TARGET_64BIT"
4570   "* return output_64bit_ior (operands); "
4571   [(set_attr "type" "binary,shift")
4572    (set_attr "length" "4,4")])
4573
4574 (define_insn ""
4575   [(set (match_operand:DI 0 "register_operand" "=r")
4576         (ior:DI (match_operand:DI 1 "register_operand" "%r")
4577                 (match_operand:DI 2 "register_operand" "r")))]
4578   "TARGET_64BIT"
4579   "or %1,%2,%0"
4580   [(set_attr "type" "binary")
4581    (set_attr "length" "4")])
4582
4583 ;; Need a define_expand because we've run out of CONST_OK... characters.
4584 (define_expand "iorsi3"
4585   [(set (match_operand:SI 0 "register_operand" "")
4586         (ior:SI (match_operand:SI 1 "register_operand" "")
4587                 (match_operand:SI 2 "arith32_operand" "")))]
4588   ""
4589   "
4590 {
4591   if (! (ior_operand (operands[2], SImode)
4592          || register_operand (operands[2], SImode)))
4593     operands[2] = force_reg (SImode, operands[2]);
4594 }")
4595
4596 (define_insn ""
4597   [(set (match_operand:SI 0 "register_operand" "=r,r")
4598         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
4599                 (match_operand:SI 2 "ior_operand" "M,i")))]
4600   ""
4601   "* return output_ior (operands); "
4602   [(set_attr "type" "binary,shift")
4603    (set_attr "length" "4,4")])
4604
4605 (define_insn ""
4606   [(set (match_operand:SI 0 "register_operand" "=r")
4607         (ior:SI (match_operand:SI 1 "register_operand" "%r")
4608                 (match_operand:SI 2 "register_operand" "r")))]
4609   ""
4610   "or %1,%2,%0"
4611   [(set_attr "type" "binary")
4612    (set_attr "length" "4")])
4613
4614 (define_expand "xordi3"
4615   [(set (match_operand:DI 0 "register_operand" "")
4616         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4617                 (match_operand:DI 2 "arith_double_operand" "")))]
4618   ""
4619   "
4620 {
4621   if (! register_operand (operands[1], DImode)
4622       || ! register_operand (operands[2], DImode))
4623     /* Let GCC break this into word-at-a-time operations.  */
4624     FAIL;
4625 }")
4626
4627 (define_insn ""
4628   [(set (match_operand:DI 0 "register_operand" "=r")
4629         (xor:DI (match_operand:DI 1 "register_operand" "%r")
4630                 (match_operand:DI 2 "register_operand" "r")))]
4631   "!TARGET_64BIT"
4632   "xor %1,%2,%0\;xor %R1,%R2,%R0"
4633   [(set_attr "type" "binary")
4634    (set_attr "length" "8")])
4635
4636 (define_insn ""
4637   [(set (match_operand:DI 0 "register_operand" "=r")
4638         (xor:DI (match_operand:DI 1 "register_operand" "%r")
4639                 (match_operand:DI 2 "register_operand" "r")))]
4640   "TARGET_64BIT"
4641   "xor %1,%2,%0"
4642   [(set_attr "type" "binary")
4643    (set_attr "length" "4")])
4644
4645 (define_insn "xorsi3"
4646   [(set (match_operand:SI 0 "register_operand" "=r")
4647         (xor:SI (match_operand:SI 1 "register_operand" "%r")
4648                 (match_operand:SI 2 "register_operand" "r")))]
4649   ""
4650   "xor %1,%2,%0"
4651   [(set_attr "type" "binary")
4652    (set_attr "length" "4")])
4653
4654 (define_expand "negdi2"
4655   [(set (match_operand:DI 0 "register_operand" "")
4656         (neg:DI (match_operand:DI 1 "register_operand" "")))]
4657   ""
4658   "")
4659
4660 (define_insn ""
4661   [(set (match_operand:DI 0 "register_operand" "=r")
4662         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4663   "!TARGET_64BIT"
4664   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
4665   [(set_attr "type" "unary")
4666    (set_attr "length" "8")])
4667
4668 (define_insn ""
4669   [(set (match_operand:DI 0 "register_operand" "=r")
4670         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4671   "TARGET_64BIT"
4672   "sub %%r0,%1,%0"
4673   [(set_attr "type" "unary")
4674    (set_attr "length" "4")])
4675
4676 (define_insn "negsi2"
4677   [(set (match_operand:SI 0 "register_operand" "=r")
4678         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
4679   ""
4680   "sub %%r0,%1,%0"
4681   [(set_attr "type" "unary")
4682    (set_attr "length" "4")])
4683
4684 (define_expand "one_cmpldi2"
4685   [(set (match_operand:DI 0 "register_operand" "")
4686         (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
4687   ""
4688   "
4689 {
4690   if (! register_operand (operands[1], DImode))
4691     FAIL;
4692 }")
4693
4694 (define_insn ""
4695   [(set (match_operand:DI 0 "register_operand" "=r")
4696         (not:DI (match_operand:DI 1 "register_operand" "r")))]
4697   "!TARGET_64BIT"
4698   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
4699   [(set_attr "type" "unary")
4700    (set_attr "length" "8")])
4701
4702 (define_insn ""
4703   [(set (match_operand:DI 0 "register_operand" "=r")
4704         (not:DI (match_operand:DI 1 "register_operand" "r")))]
4705   "TARGET_64BIT"
4706   "uaddcm %%r0,%1,%0"
4707   [(set_attr "type" "unary")
4708    (set_attr "length" "4")])
4709
4710 (define_insn "one_cmplsi2"
4711   [(set (match_operand:SI 0 "register_operand" "=r")
4712         (not:SI (match_operand:SI 1 "register_operand" "r")))]
4713   ""
4714   "uaddcm %%r0,%1,%0"
4715   [(set_attr "type" "unary")
4716    (set_attr "length" "4")])
4717 \f
4718 ;; Floating point arithmetic instructions.
4719
4720 (define_insn "adddf3"
4721   [(set (match_operand:DF 0 "register_operand" "=f")
4722         (plus:DF (match_operand:DF 1 "register_operand" "f")
4723                  (match_operand:DF 2 "register_operand" "f")))]
4724   "! TARGET_SOFT_FLOAT"
4725   "fadd,dbl %1,%2,%0"
4726   [(set_attr "type" "fpalu")
4727    (set_attr "pa_combine_type" "faddsub")
4728    (set_attr "length" "4")])
4729
4730 (define_insn "addsf3"
4731   [(set (match_operand:SF 0 "register_operand" "=f")
4732         (plus:SF (match_operand:SF 1 "register_operand" "f")
4733                  (match_operand:SF 2 "register_operand" "f")))]
4734   "! TARGET_SOFT_FLOAT"
4735   "fadd,sgl %1,%2,%0"
4736   [(set_attr "type" "fpalu")
4737    (set_attr "pa_combine_type" "faddsub")
4738    (set_attr "length" "4")])
4739
4740 (define_insn "subdf3"
4741   [(set (match_operand:DF 0 "register_operand" "=f")
4742         (minus:DF (match_operand:DF 1 "register_operand" "f")
4743                   (match_operand:DF 2 "register_operand" "f")))]
4744   "! TARGET_SOFT_FLOAT"
4745   "fsub,dbl %1,%2,%0"
4746   [(set_attr "type" "fpalu")
4747    (set_attr "pa_combine_type" "faddsub")
4748    (set_attr "length" "4")])
4749
4750 (define_insn "subsf3"
4751   [(set (match_operand:SF 0 "register_operand" "=f")
4752         (minus:SF (match_operand:SF 1 "register_operand" "f")
4753                   (match_operand:SF 2 "register_operand" "f")))]
4754   "! TARGET_SOFT_FLOAT"
4755   "fsub,sgl %1,%2,%0"
4756   [(set_attr "type" "fpalu")
4757    (set_attr "pa_combine_type" "faddsub")
4758    (set_attr "length" "4")])
4759
4760 (define_insn "muldf3"
4761   [(set (match_operand:DF 0 "register_operand" "=f")
4762         (mult:DF (match_operand:DF 1 "register_operand" "f")
4763                  (match_operand:DF 2 "register_operand" "f")))]
4764   "! TARGET_SOFT_FLOAT"
4765   "fmpy,dbl %1,%2,%0"
4766   [(set_attr "type" "fpmuldbl")
4767    (set_attr "pa_combine_type" "fmpy")
4768    (set_attr "length" "4")])
4769
4770 (define_insn "mulsf3"
4771   [(set (match_operand:SF 0 "register_operand" "=f")
4772         (mult:SF (match_operand:SF 1 "register_operand" "f")
4773                  (match_operand:SF 2 "register_operand" "f")))]
4774   "! TARGET_SOFT_FLOAT"
4775   "fmpy,sgl %1,%2,%0"
4776   [(set_attr "type" "fpmulsgl")
4777    (set_attr "pa_combine_type" "fmpy")
4778    (set_attr "length" "4")])
4779
4780 (define_insn "divdf3"
4781   [(set (match_operand:DF 0 "register_operand" "=f")
4782         (div:DF (match_operand:DF 1 "register_operand" "f")
4783                 (match_operand:DF 2 "register_operand" "f")))]
4784   "! TARGET_SOFT_FLOAT"
4785   "fdiv,dbl %1,%2,%0"
4786   [(set_attr "type" "fpdivdbl")
4787    (set_attr "length" "4")])
4788
4789 (define_insn "divsf3"
4790   [(set (match_operand:SF 0 "register_operand" "=f")
4791         (div:SF (match_operand:SF 1 "register_operand" "f")
4792                 (match_operand:SF 2 "register_operand" "f")))]
4793   "! TARGET_SOFT_FLOAT"
4794   "fdiv,sgl %1,%2,%0"
4795   [(set_attr "type" "fpdivsgl")
4796    (set_attr "length" "4")])
4797
4798 ;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
4799 ;; negation can be done by subtracting from plus zero.  However, this
4800 ;; violates the IEEE standard when negating plus and minus zero.
4801 (define_expand "negdf2"
4802   [(parallel [(set (match_operand:DF 0 "register_operand" "")
4803                    (neg:DF (match_operand:DF 1 "register_operand" "")))
4804               (use (match_dup 2))])]
4805   "! TARGET_SOFT_FLOAT"
4806 {
4807   if (TARGET_PA_20 || flag_unsafe_math_optimizations)
4808     emit_insn (gen_negdf2_fast (operands[0], operands[1]));
4809   else
4810     {
4811       operands[2] = force_reg (DFmode,
4812         CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, DFmode));
4813       emit_insn (gen_muldf3 (operands[0], operands[1], operands[2]));
4814     }
4815   DONE;
4816 })
4817
4818 (define_insn "negdf2_fast"
4819   [(set (match_operand:DF 0 "register_operand" "=f")
4820         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
4821   "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
4822   "*
4823 {
4824   if (TARGET_PA_20)
4825     return \"fneg,dbl %1,%0\";
4826   else
4827     return \"fsub,dbl %%fr0,%1,%0\";
4828 }"
4829   [(set_attr "type" "fpalu")
4830    (set_attr "length" "4")])
4831
4832 (define_expand "negsf2"
4833   [(parallel [(set (match_operand:SF 0 "register_operand" "")
4834                    (neg:SF (match_operand:SF 1 "register_operand" "")))
4835               (use (match_dup 2))])]
4836   "! TARGET_SOFT_FLOAT"
4837 {
4838   if (TARGET_PA_20 || flag_unsafe_math_optimizations)
4839     emit_insn (gen_negsf2_fast (operands[0], operands[1]));
4840   else
4841     {
4842       operands[2] = force_reg (SFmode,
4843         CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, SFmode));
4844       emit_insn (gen_mulsf3 (operands[0], operands[1], operands[2]));
4845     }
4846   DONE;
4847 })
4848
4849 (define_insn "negsf2_fast"
4850   [(set (match_operand:SF 0 "register_operand" "=f")
4851         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4852   "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
4853   "*
4854 {
4855   if (TARGET_PA_20)
4856     return \"fneg,sgl %1,%0\";
4857   else
4858     return \"fsub,sgl %%fr0,%1,%0\";
4859 }"
4860   [(set_attr "type" "fpalu")
4861    (set_attr "length" "4")])
4862
4863 (define_insn "absdf2"
4864   [(set (match_operand:DF 0 "register_operand" "=f")
4865         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
4866   "! TARGET_SOFT_FLOAT"
4867   "fabs,dbl %1,%0"
4868   [(set_attr "type" "fpalu")
4869    (set_attr "length" "4")])
4870
4871 (define_insn "abssf2"
4872   [(set (match_operand:SF 0 "register_operand" "=f")
4873         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4874   "! TARGET_SOFT_FLOAT"
4875   "fabs,sgl %1,%0"
4876   [(set_attr "type" "fpalu")
4877    (set_attr "length" "4")])
4878
4879 (define_insn "sqrtdf2"
4880   [(set (match_operand:DF 0 "register_operand" "=f")
4881         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
4882   "! TARGET_SOFT_FLOAT"
4883   "fsqrt,dbl %1,%0"
4884   [(set_attr "type" "fpsqrtdbl")
4885    (set_attr "length" "4")])
4886
4887 (define_insn "sqrtsf2"
4888   [(set (match_operand:SF 0 "register_operand" "=f")
4889         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4890   "! TARGET_SOFT_FLOAT"
4891   "fsqrt,sgl %1,%0"
4892   [(set_attr "type" "fpsqrtsgl")
4893    (set_attr "length" "4")])
4894
4895 ;; PA 2.0 floating point instructions
4896
4897 ; fmpyfadd patterns
4898 (define_insn ""
4899   [(set (match_operand:DF 0 "register_operand" "=f")
4900         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4901                           (match_operand:DF 2 "register_operand" "f"))
4902                  (match_operand:DF 3 "register_operand" "f")))]
4903   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4904   "fmpyfadd,dbl %1,%2,%3,%0"
4905   [(set_attr "type" "fpmuldbl")
4906    (set_attr "length" "4")])
4907
4908 (define_insn ""
4909   [(set (match_operand:DF 0 "register_operand" "=f")
4910         (plus:DF (match_operand:DF 1 "register_operand" "f")
4911                  (mult:DF (match_operand:DF 2 "register_operand" "f")
4912                           (match_operand:DF 3 "register_operand" "f"))))]
4913   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4914   "fmpyfadd,dbl %2,%3,%1,%0"
4915   [(set_attr "type" "fpmuldbl")
4916    (set_attr "length" "4")])
4917
4918 (define_insn ""
4919   [(set (match_operand:SF 0 "register_operand" "=f")
4920         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4921                           (match_operand:SF 2 "register_operand" "f"))
4922                  (match_operand:SF 3 "register_operand" "f")))]
4923   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4924   "fmpyfadd,sgl %1,%2,%3,%0"
4925   [(set_attr "type" "fpmulsgl")
4926    (set_attr "length" "4")])
4927
4928 (define_insn ""
4929   [(set (match_operand:SF 0 "register_operand" "=f")
4930         (plus:SF (match_operand:SF 1 "register_operand" "f")
4931                  (mult:SF (match_operand:SF 2 "register_operand" "f")
4932                           (match_operand:SF 3 "register_operand" "f"))))]
4933   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4934   "fmpyfadd,sgl %2,%3,%1,%0"
4935   [(set_attr "type" "fpmulsgl")
4936    (set_attr "length" "4")])
4937
4938 ; fmpynfadd patterns
4939 (define_insn ""
4940   [(set (match_operand:DF 0 "register_operand" "=f")
4941         (minus:DF (match_operand:DF 1 "register_operand" "f")
4942                   (mult:DF (match_operand:DF 2 "register_operand" "f")
4943                            (match_operand:DF 3 "register_operand" "f"))))]
4944   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4945   "fmpynfadd,dbl %2,%3,%1,%0"
4946   [(set_attr "type" "fpmuldbl")
4947    (set_attr "length" "4")])
4948
4949 (define_insn ""
4950   [(set (match_operand:SF 0 "register_operand" "=f")
4951         (minus:SF (match_operand:SF 1 "register_operand" "f")
4952                   (mult:SF (match_operand:SF 2 "register_operand" "f")
4953                            (match_operand:SF 3 "register_operand" "f"))))]
4954   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4955   "fmpynfadd,sgl %2,%3,%1,%0"
4956   [(set_attr "type" "fpmulsgl")
4957    (set_attr "length" "4")])
4958
4959 ; fnegabs patterns
4960 (define_insn ""
4961   [(set (match_operand:DF 0 "register_operand" "=f")
4962         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
4963   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4964   "fnegabs,dbl %1,%0"
4965   [(set_attr "type" "fpalu")
4966    (set_attr "length" "4")])
4967
4968 (define_insn ""
4969   [(set (match_operand:SF 0 "register_operand" "=f")
4970         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
4971   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
4972   "fnegabs,sgl %1,%0"
4973   [(set_attr "type" "fpalu")
4974    (set_attr "length" "4")])
4975
4976 ;; Generating a fused multiply sequence is a win for this case as it will
4977 ;; reduce the latency for the fused case without impacting the plain
4978 ;; multiply case.
4979 ;;
4980 ;; Similar possibilities exist for fnegabs, shadd and other insns which
4981 ;; perform two operations with the result of the first feeding the second.
4982 (define_insn ""
4983   [(set (match_operand:DF 0 "register_operand" "=f")
4984         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4985                           (match_operand:DF 2 "register_operand" "f"))
4986                  (match_operand:DF 3 "register_operand" "f")))
4987    (set (match_operand:DF 4 "register_operand" "=&f")
4988         (mult:DF (match_dup 1) (match_dup 2)))]
4989   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4990     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4991           || reg_overlap_mentioned_p (operands[4], operands[2])))"
4992   "#"
4993   [(set_attr "type" "fpmuldbl")
4994    (set_attr "length" "8")])
4995
4996 ;; We want to split this up during scheduling since we want both insns
4997 ;; to schedule independently.
4998 (define_split
4999   [(set (match_operand:DF 0 "register_operand" "")
5000         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "")
5001                           (match_operand:DF 2 "register_operand" ""))
5002                  (match_operand:DF 3 "register_operand" "")))
5003    (set (match_operand:DF 4 "register_operand" "")
5004         (mult:DF (match_dup 1) (match_dup 2)))]
5005   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5006   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
5007    (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
5008                                (match_dup 3)))]
5009   "")
5010
5011 (define_insn ""
5012   [(set (match_operand:SF 0 "register_operand" "=f")
5013         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5014                           (match_operand:SF 2 "register_operand" "f"))
5015                  (match_operand:SF 3 "register_operand" "f")))
5016    (set (match_operand:SF 4 "register_operand" "=&f")
5017         (mult:SF (match_dup 1) (match_dup 2)))]
5018   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5019     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5020           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5021   "#"
5022   [(set_attr "type" "fpmuldbl")
5023    (set_attr "length" "8")])
5024
5025 ;; We want to split this up during scheduling since we want both insns
5026 ;; to schedule independently.
5027 (define_split
5028   [(set (match_operand:SF 0 "register_operand" "")
5029         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "")
5030                           (match_operand:SF 2 "register_operand" ""))
5031                  (match_operand:SF 3 "register_operand" "")))
5032    (set (match_operand:SF 4 "register_operand" "")
5033         (mult:SF (match_dup 1) (match_dup 2)))]
5034   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5035   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5036    (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
5037                                (match_dup 3)))]
5038   "")
5039
5040 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
5041 ;; instruction.
5042 (define_insn ""
5043   [(set (match_operand:DF 0 "register_operand" "=f")
5044         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5045                          (match_operand:DF 2 "register_operand" "f"))))]
5046   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5047   "fmpynfadd,dbl %1,%2,%%fr0,%0"
5048   [(set_attr "type" "fpmuldbl")
5049    (set_attr "length" "4")])
5050
5051 (define_insn ""
5052   [(set (match_operand:SF 0 "register_operand" "=f")
5053         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5054                          (match_operand:SF 2 "register_operand" "f"))))]
5055   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5056   "fmpynfadd,sgl %1,%2,%%fr0,%0"
5057   [(set_attr "type" "fpmuldbl")
5058    (set_attr "length" "4")])
5059
5060 (define_insn ""
5061   [(set (match_operand:DF 0 "register_operand" "=f")
5062         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5063                          (match_operand:DF 2 "register_operand" "f"))))
5064    (set (match_operand:DF 3 "register_operand" "=&f")
5065         (mult:DF (match_dup 1) (match_dup 2)))]
5066   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5067     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
5068           || reg_overlap_mentioned_p (operands[3], operands[2])))"
5069   "#"
5070   [(set_attr "type" "fpmuldbl")
5071    (set_attr "length" "8")])
5072
5073 (define_split
5074   [(set (match_operand:DF 0 "register_operand" "")
5075         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
5076                          (match_operand:DF 2 "register_operand" ""))))
5077    (set (match_operand:DF 3 "register_operand" "")
5078         (mult:DF (match_dup 1) (match_dup 2)))]
5079   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5080   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
5081    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
5082   "")
5083
5084 (define_insn ""
5085   [(set (match_operand:SF 0 "register_operand" "=f")
5086         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5087                          (match_operand:SF 2 "register_operand" "f"))))
5088    (set (match_operand:SF 3 "register_operand" "=&f")
5089         (mult:SF (match_dup 1) (match_dup 2)))]
5090   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5091     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
5092           || reg_overlap_mentioned_p (operands[3], operands[2])))"
5093   "#"
5094   [(set_attr "type" "fpmuldbl")
5095    (set_attr "length" "8")])
5096
5097 (define_split
5098   [(set (match_operand:SF 0 "register_operand" "")
5099         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
5100                          (match_operand:SF 2 "register_operand" ""))))
5101    (set (match_operand:SF 3 "register_operand" "")
5102         (mult:SF (match_dup 1) (match_dup 2)))]
5103   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5104   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
5105    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
5106   "")
5107
5108 ;; Now fused multiplies with the result of the multiply negated.
5109 (define_insn ""
5110   [(set (match_operand:DF 0 "register_operand" "=f")
5111         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5112                                   (match_operand:DF 2 "register_operand" "f")))
5113                  (match_operand:DF 3 "register_operand" "f")))]
5114   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5115   "fmpynfadd,dbl %1,%2,%3,%0"
5116   [(set_attr "type" "fpmuldbl")
5117    (set_attr "length" "4")])
5118
5119 (define_insn ""
5120   [(set (match_operand:SF 0 "register_operand" "=f")
5121         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5122                          (match_operand:SF 2 "register_operand" "f")))
5123                  (match_operand:SF 3 "register_operand" "f")))]
5124   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5125   "fmpynfadd,sgl %1,%2,%3,%0"
5126   [(set_attr "type" "fpmuldbl")
5127    (set_attr "length" "4")])
5128
5129 (define_insn ""
5130   [(set (match_operand:DF 0 "register_operand" "=f")
5131         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5132                                   (match_operand:DF 2 "register_operand" "f")))
5133                  (match_operand:DF 3 "register_operand" "f")))
5134    (set (match_operand:DF 4 "register_operand" "=&f")
5135         (mult:DF (match_dup 1) (match_dup 2)))]
5136   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5137     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5138           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5139   "#"
5140   [(set_attr "type" "fpmuldbl")
5141    (set_attr "length" "8")])
5142
5143 (define_split
5144   [(set (match_operand:DF 0 "register_operand" "")
5145         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
5146                                   (match_operand:DF 2 "register_operand" "")))
5147                  (match_operand:DF 3 "register_operand" "")))
5148    (set (match_operand:DF 4 "register_operand" "")
5149         (mult:DF (match_dup 1) (match_dup 2)))]
5150   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5151   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
5152    (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
5153                                (match_dup 3)))]
5154   "")
5155
5156 (define_insn ""
5157   [(set (match_operand:SF 0 "register_operand" "=f")
5158         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5159                                   (match_operand:SF 2 "register_operand" "f")))
5160                  (match_operand:SF 3 "register_operand" "f")))
5161    (set (match_operand:SF 4 "register_operand" "=&f")
5162         (mult:SF (match_dup 1) (match_dup 2)))]
5163   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5164     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5165           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5166   "#"
5167   [(set_attr "type" "fpmuldbl")
5168    (set_attr "length" "8")])
5169
5170 (define_split
5171   [(set (match_operand:SF 0 "register_operand" "")
5172         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
5173                                   (match_operand:SF 2 "register_operand" "")))
5174                  (match_operand:SF 3 "register_operand" "")))
5175    (set (match_operand:SF 4 "register_operand" "")
5176         (mult:SF (match_dup 1) (match_dup 2)))]
5177   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5178   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5179    (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
5180                                (match_dup 3)))]
5181   "")
5182
5183 (define_insn ""
5184   [(set (match_operand:DF 0 "register_operand" "=f")
5185         (minus:DF (match_operand:DF 3 "register_operand" "f")
5186                   (mult:DF (match_operand:DF 1 "register_operand" "f")
5187                            (match_operand:DF 2 "register_operand" "f"))))
5188    (set (match_operand:DF 4 "register_operand" "=&f")
5189         (mult:DF (match_dup 1) (match_dup 2)))]
5190   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5191     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5192           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5193   "#"
5194   [(set_attr "type" "fpmuldbl")
5195    (set_attr "length" "8")])
5196
5197 (define_split
5198   [(set (match_operand:DF 0 "register_operand" "")
5199         (minus:DF (match_operand:DF 3 "register_operand" "")
5200                   (mult:DF (match_operand:DF 1 "register_operand" "")
5201                            (match_operand:DF 2 "register_operand" ""))))
5202    (set (match_operand:DF 4 "register_operand" "")
5203         (mult:DF (match_dup 1) (match_dup 2)))]
5204   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5205   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
5206    (set (match_dup 0) (minus:DF (match_dup 3)
5207                                 (mult:DF (match_dup 1) (match_dup 2))))]
5208   "")
5209
5210 (define_insn ""
5211   [(set (match_operand:SF 0 "register_operand" "=f")
5212         (minus:SF (match_operand:SF 3 "register_operand" "f")
5213                   (mult:SF (match_operand:SF 1 "register_operand" "f")
5214                            (match_operand:SF 2 "register_operand" "f"))))
5215    (set (match_operand:SF 4 "register_operand" "=&f")
5216         (mult:SF (match_dup 1) (match_dup 2)))]
5217   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5218     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5219           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5220   "#"
5221   [(set_attr "type" "fpmuldbl")
5222    (set_attr "length" "8")])
5223
5224 (define_split
5225   [(set (match_operand:SF 0 "register_operand" "")
5226         (minus:SF (match_operand:SF 3 "register_operand" "")
5227                   (mult:SF (match_operand:SF 1 "register_operand" "")
5228                            (match_operand:SF 2 "register_operand" ""))))
5229    (set (match_operand:SF 4 "register_operand" "")
5230         (mult:SF (match_dup 1) (match_dup 2)))]
5231   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5232   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5233    (set (match_dup 0) (minus:SF (match_dup 3)
5234                                 (mult:SF (match_dup 1) (match_dup 2))))]
5235   "")
5236
5237 (define_insn ""
5238   [(set (match_operand:DF 0 "register_operand" "=f")
5239         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
5240    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
5241   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5242     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5243   "#"
5244   [(set_attr "type" "fpalu")
5245    (set_attr "length" "8")])
5246
5247 (define_split
5248   [(set (match_operand:DF 0 "register_operand" "")
5249         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
5250    (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
5251   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5252   [(set (match_dup 2) (abs:DF (match_dup 1)))
5253    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
5254   "")
5255
5256 (define_insn ""
5257   [(set (match_operand:SF 0 "register_operand" "=f")
5258         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
5259    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
5260   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5261     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
5262   "#"
5263   [(set_attr "type" "fpalu")
5264    (set_attr "length" "8")])
5265
5266 (define_split
5267   [(set (match_operand:SF 0 "register_operand" "")
5268         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
5269    (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
5270   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5271   [(set (match_dup 2) (abs:SF (match_dup 1)))
5272    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
5273   "")
5274 \f
5275 ;;- Shift instructions
5276
5277 ;; Optimized special case of shifting.
5278
5279 (define_insn ""
5280   [(set (match_operand:SI 0 "register_operand" "=r")
5281         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5282                      (const_int 24)))]
5283   ""
5284   "ldb%M1 %1,%0"
5285   [(set_attr "type" "load")
5286    (set_attr "length" "4")])
5287
5288 (define_insn ""
5289   [(set (match_operand:SI 0 "register_operand" "=r")
5290         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
5291                      (const_int 16)))]
5292   ""
5293   "ldh%M1 %1,%0"
5294   [(set_attr "type" "load")
5295    (set_attr "length" "4")])
5296
5297 (define_insn ""
5298   [(set (match_operand:SI 0 "register_operand" "=r")
5299         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
5300                           (match_operand:SI 3 "shadd_operand" ""))
5301                  (match_operand:SI 1 "register_operand" "r")))]
5302   ""
5303   "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
5304   [(set_attr "type" "binary")
5305    (set_attr "length" "4")])
5306
5307 (define_insn ""
5308   [(set (match_operand:DI 0 "register_operand" "=r")
5309         (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
5310                           (match_operand:DI 3 "shadd_operand" ""))
5311                  (match_operand:DI 1 "register_operand" "r")))]
5312   "TARGET_64BIT"
5313   "shladd,l %2,%O3,%1,%0"
5314   [(set_attr "type" "binary")
5315    (set_attr "length" "4")])
5316
5317 (define_expand "ashlsi3"
5318   [(set (match_operand:SI 0 "register_operand" "")
5319         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
5320                    (match_operand:SI 2 "arith32_operand" "")))]
5321   ""
5322   "
5323 {
5324   if (GET_CODE (operands[2]) != CONST_INT)
5325     {
5326       rtx temp = gen_reg_rtx (SImode);
5327       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5328       if (GET_CODE (operands[1]) == CONST_INT)
5329         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
5330       else
5331         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
5332       DONE;
5333     }
5334   /* Make sure both inputs are not constants,
5335      there are no patterns for that.  */
5336   operands[1] = force_reg (SImode, operands[1]);
5337 }")
5338
5339 (define_insn ""
5340   [(set (match_operand:SI 0 "register_operand" "=r")
5341         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5342                    (match_operand:SI 2 "const_int_operand" "n")))]
5343   ""
5344   "{zdep|depw,z} %1,%P2,%L2,%0"
5345   [(set_attr "type" "shift")
5346    (set_attr "length" "4")])
5347
5348 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
5349 ; Doing it like this makes slightly better code since reload can
5350 ; replace a register with a known value in range -16..15 with a
5351 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
5352 ; but since we have no more CONST_OK... characters, that is not
5353 ; possible.
5354 (define_insn "zvdep32"
5355   [(set (match_operand:SI 0 "register_operand" "=r,r")
5356         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
5357                    (minus:SI (const_int 31)
5358                              (match_operand:SI 2 "register_operand" "q,q"))))]
5359   ""
5360   "@
5361    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
5362    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
5363   [(set_attr "type" "shift,shift")
5364    (set_attr "length" "4,4")])
5365
5366 (define_insn "zvdep_imm32"
5367   [(set (match_operand:SI 0 "register_operand" "=r")
5368         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
5369                    (minus:SI (const_int 31)
5370                              (match_operand:SI 2 "register_operand" "q"))))]
5371   ""
5372   "*
5373 {
5374   int x = INTVAL (operands[1]);
5375   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5376   operands[1] = GEN_INT ((x & 0xf) - 0x10);
5377   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
5378 }"
5379   [(set_attr "type" "shift")
5380    (set_attr "length" "4")])
5381
5382 (define_insn "vdepi_ior"
5383   [(set (match_operand:SI 0 "register_operand" "=r")
5384         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
5385                            (minus:SI (const_int 31)
5386                                      (match_operand:SI 2 "register_operand" "q")))
5387                 (match_operand:SI 3 "register_operand" "0")))]
5388   ; accept ...0001...1, can this be generalized?
5389   "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5390   "*
5391 {
5392   int x = INTVAL (operands[1]);
5393   operands[2] = GEN_INT (exact_log2 (x + 1));
5394   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
5395 }"
5396   [(set_attr "type" "shift")
5397    (set_attr "length" "4")])
5398
5399 (define_insn "vdepi_and"
5400   [(set (match_operand:SI 0 "register_operand" "=r")
5401         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
5402                            (minus:SI (const_int 31)
5403                                      (match_operand:SI 2 "register_operand" "q")))
5404                 (match_operand:SI 3 "register_operand" "0")))]
5405   ; this can be generalized...!
5406   "INTVAL (operands[1]) == -2"
5407   "*
5408 {
5409   int x = INTVAL (operands[1]);
5410   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5411   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
5412 }"
5413   [(set_attr "type" "shift")
5414    (set_attr "length" "4")])
5415
5416 (define_expand "ashldi3"
5417   [(set (match_operand:DI 0 "register_operand" "")
5418         (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
5419                    (match_operand:DI 2 "arith32_operand" "")))]
5420   "TARGET_64BIT"
5421   "
5422 {
5423   if (GET_CODE (operands[2]) != CONST_INT)
5424     {
5425       rtx temp = gen_reg_rtx (DImode);
5426       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5427       if (GET_CODE (operands[1]) == CONST_INT)
5428         emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
5429       else
5430         emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
5431       DONE;
5432     }
5433   /* Make sure both inputs are not constants,
5434      there are no patterns for that.  */
5435   operands[1] = force_reg (DImode, operands[1]);
5436 }")
5437
5438 (define_insn ""
5439   [(set (match_operand:DI 0 "register_operand" "=r")
5440         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5441                    (match_operand:DI 2 "const_int_operand" "n")))]
5442   "TARGET_64BIT"
5443   "depd,z %1,%p2,%Q2,%0"
5444   [(set_attr "type" "shift")
5445    (set_attr "length" "4")])
5446
5447 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
5448 ; Doing it like this makes slightly better code since reload can
5449 ; replace a register with a known value in range -16..15 with a
5450 ; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
5451 ; but since we have no more CONST_OK... characters, that is not
5452 ; possible.
5453 (define_insn "zvdep64"
5454   [(set (match_operand:DI 0 "register_operand" "=r,r")
5455         (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
5456                    (minus:DI (const_int 63)
5457                              (match_operand:DI 2 "register_operand" "q,q"))))]
5458   "TARGET_64BIT"
5459   "@
5460    depd,z %1,%%sar,64,%0
5461    depdi,z %1,%%sar,64,%0"
5462   [(set_attr "type" "shift,shift")
5463    (set_attr "length" "4,4")])
5464
5465 (define_insn "zvdep_imm64"
5466   [(set (match_operand:DI 0 "register_operand" "=r")
5467         (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
5468                    (minus:DI (const_int 63)
5469                              (match_operand:DI 2 "register_operand" "q"))))]
5470   "TARGET_64BIT"
5471   "*
5472 {
5473   int x = INTVAL (operands[1]);
5474   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
5475   operands[1] = GEN_INT ((x & 0x1f) - 0x20);
5476   return \"depdi,z %1,%%sar,%2,%0\";
5477 }"
5478   [(set_attr "type" "shift")
5479    (set_attr "length" "4")])
5480
5481 (define_insn ""
5482   [(set (match_operand:DI 0 "register_operand" "=r")
5483         (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
5484                            (minus:DI (const_int 63)
5485                                      (match_operand:DI 2 "register_operand" "q")))
5486                 (match_operand:DI 3 "register_operand" "0")))]
5487   ; accept ...0001...1, can this be generalized?
5488   "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0"
5489   "*
5490 {
5491   int x = INTVAL (operands[1]);
5492   operands[2] = GEN_INT (exact_log2 (x + 1));
5493   return \"depdi -1,%%sar,%2,%0\";
5494 }"
5495   [(set_attr "type" "shift")
5496    (set_attr "length" "4")])
5497
5498 (define_insn ""
5499   [(set (match_operand:DI 0 "register_operand" "=r")
5500         (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
5501                            (minus:DI (const_int 63)
5502                                      (match_operand:DI 2 "register_operand" "q")))
5503                 (match_operand:DI 3 "register_operand" "0")))]
5504   ; this can be generalized...!
5505   "TARGET_64BIT && INTVAL (operands[1]) == -2"
5506   "*
5507 {
5508   int x = INTVAL (operands[1]);
5509   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
5510   return \"depdi 0,%%sar,%2,%0\";
5511 }"
5512   [(set_attr "type" "shift")
5513    (set_attr "length" "4")])
5514
5515 (define_expand "ashrsi3"
5516   [(set (match_operand:SI 0 "register_operand" "")
5517         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
5518                      (match_operand:SI 2 "arith32_operand" "")))]
5519   ""
5520   "
5521 {
5522   if (GET_CODE (operands[2]) != CONST_INT)
5523     {
5524       rtx temp = gen_reg_rtx (SImode);
5525       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
5526       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
5527       DONE;
5528     }
5529 }")
5530
5531 (define_insn ""
5532   [(set (match_operand:SI 0 "register_operand" "=r")
5533         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5534                      (match_operand:SI 2 "const_int_operand" "n")))]
5535   ""
5536   "{extrs|extrw,s} %1,%P2,%L2,%0"
5537   [(set_attr "type" "shift")
5538    (set_attr "length" "4")])
5539
5540 (define_insn "vextrs32"
5541   [(set (match_operand:SI 0 "register_operand" "=r")
5542         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5543                      (minus:SI (const_int 31)
5544                                (match_operand:SI 2 "register_operand" "q"))))]
5545   ""
5546   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
5547   [(set_attr "type" "shift")
5548    (set_attr "length" "4")])
5549
5550 (define_expand "ashrdi3"
5551   [(set (match_operand:DI 0 "register_operand" "")
5552         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5553                      (match_operand:DI 2 "arith32_operand" "")))]
5554   "TARGET_64BIT"
5555   "
5556 {
5557   if (GET_CODE (operands[2]) != CONST_INT)
5558     {
5559       rtx temp = gen_reg_rtx (DImode);
5560       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
5561       emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
5562       DONE;
5563     }
5564 }")
5565
5566 (define_insn ""
5567   [(set (match_operand:DI 0 "register_operand" "=r")
5568         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5569                      (match_operand:DI 2 "const_int_operand" "n")))]
5570   "TARGET_64BIT"
5571   "extrd,s %1,%p2,%Q2,%0"
5572   [(set_attr "type" "shift")
5573    (set_attr "length" "4")])
5574
5575 (define_insn "vextrs64"
5576   [(set (match_operand:DI 0 "register_operand" "=r")
5577         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5578                      (minus:DI (const_int 63)
5579                                (match_operand:DI 2 "register_operand" "q"))))]
5580   "TARGET_64BIT"
5581   "extrd,s %1,%%sar,64,%0"
5582   [(set_attr "type" "shift")
5583    (set_attr "length" "4")])
5584
5585 (define_insn "lshrsi3"
5586   [(set (match_operand:SI 0 "register_operand" "=r,r")
5587         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
5588                      (match_operand:SI 2 "arith32_operand" "q,n")))]
5589   ""
5590   "@
5591    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
5592    {extru|extrw,u} %1,%P2,%L2,%0"
5593   [(set_attr "type" "shift")
5594    (set_attr "length" "4")])
5595
5596 (define_insn "lshrdi3"
5597   [(set (match_operand:DI 0 "register_operand" "=r,r")
5598         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
5599                      (match_operand:DI 2 "arith32_operand" "q,n")))]
5600   "TARGET_64BIT"
5601   "@
5602    shrpd %%r0,%1,%%sar,%0
5603    extrd,u %1,%p2,%Q2,%0"
5604   [(set_attr "type" "shift")
5605    (set_attr "length" "4")])
5606
5607 (define_insn "rotrsi3"
5608   [(set (match_operand:SI 0 "register_operand" "=r,r")
5609         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
5610                      (match_operand:SI 2 "arith32_operand" "q,n")))]
5611   ""
5612   "*
5613 {
5614   if (GET_CODE (operands[2]) == CONST_INT)
5615     {
5616       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
5617       return \"{shd|shrpw} %1,%1,%2,%0\";
5618     }
5619   else
5620     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
5621 }"
5622   [(set_attr "type" "shift")
5623    (set_attr "length" "4")])
5624
5625 (define_expand "rotlsi3"
5626   [(set (match_operand:SI 0 "register_operand" "")
5627         (rotate:SI (match_operand:SI 1 "register_operand" "")
5628                    (match_operand:SI 2 "arith32_operand" "")))]
5629   ""
5630   "
5631 {
5632   if (GET_CODE (operands[2]) != CONST_INT)
5633     {
5634       rtx temp = gen_reg_rtx (SImode);
5635       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
5636       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
5637       DONE;
5638     }
5639   /* Else expand normally.  */
5640 }")
5641
5642 (define_insn ""
5643   [(set (match_operand:SI 0 "register_operand" "=r")
5644         (rotate:SI (match_operand:SI 1 "register_operand" "r")
5645                    (match_operand:SI 2 "const_int_operand" "n")))]
5646   ""
5647   "*
5648 {
5649   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
5650   return \"{shd|shrpw} %1,%1,%2,%0\";
5651 }"
5652   [(set_attr "type" "shift")
5653    (set_attr "length" "4")])
5654
5655 (define_insn ""
5656   [(set (match_operand:SI 0 "register_operand" "=r")
5657         (match_operator:SI 5 "plus_xor_ior_operator"
5658           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
5659                       (match_operand:SI 3 "const_int_operand" "n"))
5660            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5661                         (match_operand:SI 4 "const_int_operand" "n"))]))]
5662   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5663   "{shd|shrpw} %1,%2,%4,%0"
5664   [(set_attr "type" "shift")
5665    (set_attr "length" "4")])
5666
5667 (define_insn ""
5668   [(set (match_operand:SI 0 "register_operand" "=r")
5669         (match_operator:SI 5 "plus_xor_ior_operator"
5670           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
5671                         (match_operand:SI 4 "const_int_operand" "n"))
5672            (ashift:SI (match_operand:SI 1 "register_operand" "r")
5673                       (match_operand:SI 3 "const_int_operand" "n"))]))]
5674   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
5675   "{shd|shrpw} %1,%2,%4,%0"
5676   [(set_attr "type" "shift")
5677    (set_attr "length" "4")])
5678
5679 (define_insn ""
5680   [(set (match_operand:SI 0 "register_operand" "=r")
5681         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
5682                            (match_operand:SI 2 "const_int_operand" ""))
5683                 (match_operand:SI 3 "const_int_operand" "")))]
5684   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
5685   "*
5686 {
5687   int cnt = INTVAL (operands[2]) & 31;
5688   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
5689   operands[2] = GEN_INT (31 - cnt);
5690   return \"{zdep|depw,z} %1,%2,%3,%0\";
5691 }"
5692   [(set_attr "type" "shift")
5693    (set_attr "length" "4")])
5694 \f
5695 ;; Unconditional and other jump instructions.
5696
5697 ;; This can only be used in a leaf function, so we do
5698 ;; not need to use the PIC register when generating PIC code.
5699 (define_insn "return"
5700   [(return)
5701    (use (reg:SI 2))
5702    (const_int 0)]
5703   "hppa_can_use_return_insn_p ()"
5704   "*
5705 {
5706   if (TARGET_PA_20)
5707     return \"bve%* (%%r2)\";
5708   return \"bv%* %%r0(%%r2)\";
5709 }"
5710   [(set_attr "type" "branch")
5711    (set_attr "length" "4")])
5712
5713 ;; Emit a different pattern for functions which have non-trivial
5714 ;; epilogues so as not to confuse jump and reorg.
5715 (define_insn "return_internal"
5716   [(return)
5717    (use (reg:SI 2))
5718    (const_int 1)]
5719   "! flag_pic"
5720   "*
5721 {
5722   if (TARGET_PA_20)
5723     return \"bve%* (%%r2)\";
5724   return \"bv%* %%r0(%%r2)\";
5725 }"
5726   [(set_attr "type" "branch")
5727    (set_attr "length" "4")])
5728
5729 ;; Use the PIC register to ensure it's restored after a
5730 ;; call in PIC mode.
5731 (define_insn "return_internal_pic"
5732   [(return)
5733    (use (match_operand 0 "register_operand" "r"))
5734    (use (reg:SI 2))]
5735   "flag_pic && true_regnum (operands[0]) == PIC_OFFSET_TABLE_REGNUM"
5736   "*
5737 {
5738   if (TARGET_PA_20)
5739     return \"bve%* (%%r2)\";
5740   return \"bv%* %%r0(%%r2)\";
5741 }"
5742   [(set_attr "type" "branch")
5743    (set_attr "length" "4")])
5744
5745 ;; Use the PIC register to ensure it's restored after a
5746 ;; call in PIC mode.  This is used for eh returns which
5747 ;; bypass the return stub.
5748 (define_insn "return_external_pic"
5749   [(return)
5750    (use (match_operand 0 "register_operand" "r"))
5751    (use (reg:SI 2))
5752    (clobber (reg:SI 1))]
5753   "flag_pic
5754    && current_function_calls_eh_return
5755    && true_regnum (operands[0]) == PIC_OFFSET_TABLE_REGNUM"
5756   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
5757   [(set_attr "type" "branch")
5758    (set_attr "length" "12")])
5759
5760 (define_expand "prologue"
5761   [(const_int 0)]
5762   ""
5763   "hppa_expand_prologue ();DONE;")
5764
5765 (define_expand "sibcall_epilogue"
5766   [(return)]
5767   ""
5768   "
5769 {
5770   hppa_expand_epilogue ();
5771   DONE;
5772 }")
5773
5774 (define_expand "epilogue"
5775   [(return)]
5776   ""
5777   "
5778 {
5779   /* Try to use the trivial return first.  Else use the full
5780      epilogue.  */
5781   if (hppa_can_use_return_insn_p ())
5782     emit_jump_insn (gen_return ());
5783   else
5784     {
5785       rtx x;
5786
5787       hppa_expand_epilogue ();
5788       if (flag_pic)
5789         {
5790           rtx pic = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM);
5791
5792           /* EH returns bypass the normal return stub.  Thus, we must do an
5793              interspace branch to return from functions that call eh_return.
5794              This is only a problem for returns from shared code.  */
5795           if (current_function_calls_eh_return)
5796             x = gen_return_external_pic (pic);
5797           else
5798             x = gen_return_internal_pic (pic);
5799         }
5800       else
5801         x = gen_return_internal ();
5802       emit_jump_insn (x);
5803     }
5804   DONE;
5805 }")
5806
5807 ;; Special because we use the value placed in %r2 by the bl instruction
5808 ;; from within its delay slot to set the value for the 2nd parameter to
5809 ;; the call.
5810 (define_insn "call_profiler"
5811   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
5812          (match_operand 1 "" ""))
5813    (use (match_operand 2 "" ""))
5814    (use (reg:SI 25))
5815    (use (reg:SI 26))
5816    (clobber (reg:SI 2))]
5817   ""
5818   "*
5819 {
5820   rtx xoperands[3];
5821
5822   output_arg_descriptor (insn);
5823
5824   xoperands[0] = operands[0];
5825   xoperands[1] = operands[2];
5826   xoperands[2] = gen_label_rtx ();
5827   output_asm_insn (\"{bl|b,l} %0,%%r2\;ldo %1-%2(%%r2),%%r25\", xoperands);
5828
5829   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5830                              CODE_LABEL_NUMBER (xoperands[2]));
5831   return \"\";
5832 }"
5833   [(set_attr "type" "multi")
5834    (set_attr "length" "8")])
5835
5836 (define_insn "blockage"
5837   [(unspec_volatile [(const_int 2)] 0)]
5838   ""
5839   ""
5840   [(set_attr "length" "0")])
5841
5842 (define_insn "jump"
5843   [(set (pc) (label_ref (match_operand 0 "" "")))]
5844   ""
5845   "*
5846 {
5847   extern int optimize;
5848
5849   if (GET_MODE (insn) == SImode)
5850     return \"b %l0%#\";
5851
5852   /* An unconditional branch which can reach its target.  */
5853   if (get_attr_length (insn) != 24
5854       && get_attr_length (insn) != 16)
5855     return \"b%* %l0\";
5856
5857   /* An unconditional branch which can not reach its target.
5858
5859      We need to be able to use %r1 as a scratch register; however,
5860      we can never be sure whether or not it's got a live value in
5861      it.  Therefore, we must restore its original value after the
5862      jump.
5863
5864      To make matters worse, we don't have a stack slot which we
5865      can always clobber.  sp-12/sp-16 shouldn't ever have a live
5866      value during a non-optimizing compilation, so we use those
5867      slots for now.  We don't support very long branches when
5868      optimizing -- they should be quite rare when optimizing.
5869
5870      Really the way to go long term is a register scavenger; goto
5871      the target of the jump and find a register which we can use
5872      as a scratch to hold the value in %r1.  */
5873
5874   /* We don't know how to register scavenge yet.  */
5875   if (optimize)
5876     abort ();
5877
5878   /* First store %r1 into the stack.  */
5879   output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
5880
5881   /* Now load the target address into %r1 and do an indirect jump
5882      to the value specified in %r1.  Be careful to generate PIC
5883      code as needed.  */
5884   if (flag_pic)
5885     {
5886       rtx xoperands[2];
5887       xoperands[0] = operands[0];
5888       if (TARGET_SOM || ! TARGET_GAS)
5889         {
5890           xoperands[1] = gen_label_rtx ();
5891
5892           output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
5893                            xoperands);
5894           ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5895                                      CODE_LABEL_NUMBER (xoperands[1]));
5896           output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\", xoperands);
5897         }
5898       else
5899         {
5900           output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
5901           output_asm_insn (\"addil L'%l0-$PIC_pcrel$0+4,%%r1\", xoperands);
5902           output_asm_insn (\"ldo R'%l0-$PIC_pcrel$0+8(%%r1),%%r1\", xoperands);
5903         }
5904       output_asm_insn (\"bv %%r0(%%r1)\", xoperands);
5905     }
5906   else
5907     output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
5908
5909   /* And restore the value of %r1 in the delay slot.  We're not optimizing,
5910      so we know nothing else can be in the delay slot.  */
5911   return \"ldw -16(%%r30),%%r1\";
5912 }"
5913   [(set_attr "type" "uncond_branch")
5914    (set_attr "pa_combine_type" "uncond_branch")
5915    (set (attr "length")
5916     (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
5917            (if_then_else (lt (abs (minus (match_dup 0)
5918                                          (plus (pc) (const_int 8))))
5919                              (const_int 8184))
5920                          (const_int 4)
5921                          (const_int 8))
5922            (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
5923                (const_int 262100))
5924            (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
5925                          (const_int 16)
5926                          (const_int 24))]
5927           (const_int 4)))])
5928
5929 ;; Subroutines of "casesi".
5930 ;; operand 0 is index
5931 ;; operand 1 is the minimum bound
5932 ;; operand 2 is the maximum bound - minimum bound + 1
5933 ;; operand 3 is CODE_LABEL for the table;
5934 ;; operand 4 is the CODE_LABEL to go to if index out of range.
5935
5936 (define_expand "casesi"
5937   [(match_operand:SI 0 "general_operand" "")
5938    (match_operand:SI 1 "const_int_operand" "")
5939    (match_operand:SI 2 "const_int_operand" "")
5940    (match_operand 3 "" "")
5941    (match_operand 4 "" "")]
5942   ""
5943   "
5944 {
5945   if (GET_CODE (operands[0]) != REG)
5946     operands[0] = force_reg (SImode, operands[0]);
5947
5948   if (operands[1] != const0_rtx)
5949     {
5950       rtx reg = gen_reg_rtx (SImode);
5951
5952       operands[1] = GEN_INT (-INTVAL (operands[1]));
5953       if (!INT_14_BITS (operands[1]))
5954         operands[1] = force_reg (SImode, operands[1]);
5955       emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
5956
5957       operands[0] = reg;
5958     }
5959
5960   /* In 64bit mode we must make sure to wipe the upper bits of the register
5961      just in case the addition overflowed or we had random bits in the
5962      high part of the register.  */
5963   if (TARGET_64BIT)
5964     {
5965       rtx reg = gen_reg_rtx (DImode);
5966       emit_insn (gen_extendsidi2 (reg, operands[0]));
5967       operands[0] = gen_rtx_SUBREG (SImode, reg, 4);
5968     }
5969
5970   if (!INT_5_BITS (operands[2]))
5971     operands[2] = force_reg (SImode, operands[2]);
5972
5973   emit_insn (gen_cmpsi (operands[0], operands[2]));
5974   emit_jump_insn (gen_bgtu (operands[4]));
5975   if (TARGET_BIG_SWITCH)
5976     {
5977       rtx temp = gen_reg_rtx (SImode);
5978       emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
5979       operands[0] = temp;
5980     }
5981   emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
5982   DONE;
5983 }")
5984
5985 (define_insn "casesi0"
5986   [(set (pc) (plus:SI
5987                (mem:SI (plus:SI (pc)
5988                                 (match_operand:SI 0 "register_operand" "r")))
5989                (label_ref (match_operand 1 "" ""))))]
5990   ""
5991   "blr %0,%%r0\;nop"
5992   [(set_attr "type" "multi")
5993    (set_attr "length" "8")])
5994
5995 ;; Need nops for the calls because execution is supposed to continue
5996 ;; past; we don't want to nullify an instruction that we need.
5997 ;;- jump to subroutine
5998
5999 (define_expand "call"
6000   [(parallel [(call (match_operand:SI 0 "" "")
6001                     (match_operand 1 "" ""))
6002               (clobber (reg:SI 2))])]
6003   ""
6004   "
6005 {
6006   rtx op;
6007   rtx call_insn;
6008
6009   if (TARGET_PORTABLE_RUNTIME)
6010     op = force_reg (SImode, XEXP (operands[0], 0));
6011   else
6012     op = XEXP (operands[0], 0);
6013
6014   if (TARGET_64BIT)
6015     emit_move_insn (arg_pointer_rtx,
6016                     gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
6017                                   GEN_INT (64)));
6018
6019   /* Use two different patterns for calls to explicitly named functions
6020      and calls through function pointers.  This is necessary as these two
6021      types of calls use different calling conventions, and CSE might try
6022      to change the named call into an indirect call in some cases (using
6023      two patterns keeps CSE from performing this optimization).  */
6024   if (GET_CODE (op) == SYMBOL_REF)
6025     call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
6026   else if (TARGET_64BIT)
6027     {
6028       rtx tmpreg = force_reg (word_mode, op);
6029       call_insn = emit_call_insn (gen_call_internal_reg_64bit (tmpreg,
6030                                                                operands[1]));
6031     }
6032   else
6033     {
6034       rtx tmpreg = gen_rtx_REG (word_mode, 22);
6035       emit_move_insn (tmpreg, force_reg (word_mode, op));
6036       call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
6037     }
6038
6039   if (flag_pic)
6040     {
6041       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6042       if (TARGET_64BIT)
6043         use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
6044
6045       /* After each call we must restore the PIC register, even if it
6046          doesn't appear to be used.  */
6047       emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6048     }
6049   DONE;
6050 }")
6051
6052 (define_insn "call_internal_symref"
6053   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
6054          (match_operand 1 "" "i"))
6055    (clobber (reg:SI 2))
6056    (use (const_int 0))]
6057   "! TARGET_PORTABLE_RUNTIME"
6058   "*
6059 {
6060   output_arg_descriptor (insn);
6061   return output_call (insn, operands[0], 0);
6062 }"
6063   [(set_attr "type" "call")
6064    (set (attr "length")
6065 ;;       If we're sure that we can either reach the target or that the
6066 ;;       linker can use a long-branch stub, then the length is at most
6067 ;;       8 bytes.
6068 ;;
6069 ;;       For long-calls the length will be at most 68 bytes (non-pic)
6070 ;;       or 84 bytes (pic).  */
6071 ;;       Else we have to use a long-call;
6072       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6073                         (const_int 240000))
6074                     (const_int 8)
6075                     (if_then_else (eq (symbol_ref "flag_pic")
6076                                       (const_int 0))
6077                                   (const_int 68)
6078                                   (const_int 84))))])
6079
6080 (define_insn "call_internal_reg_64bit"
6081   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
6082          (match_operand 1 "" "i"))
6083    (clobber (reg:SI 2))
6084    (use (const_int 1))]
6085   "TARGET_64BIT"
6086   "*
6087 {
6088   /* ??? Needs more work.  Length computation, split into multiple insns,
6089      do not use %r22 directly, expose delay slot.  */
6090   return \"ldd 16(%0),%%r2\;ldd 24(%0),%%r27\;bve,l (%%r2),%%r2\;nop\";
6091 }"
6092   [(set_attr "type" "dyncall")
6093    (set (attr "length") (const_int 16))])
6094
6095 (define_insn "call_internal_reg"
6096   [(call (mem:SI (reg:SI 22))
6097          (match_operand 0 "" "i"))
6098    (clobber (reg:SI 2))
6099    (use (const_int 1))]
6100   ""
6101   "*
6102 {
6103   rtx xoperands[2];
6104
6105   /* First the special case for kernels, level 0 systems, etc.  */
6106   if (TARGET_FAST_INDIRECT_CALLS)
6107     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
6108
6109   /* Now the normal case -- we can reach $$dyncall directly or
6110      we're sure that we can get there via a long-branch stub. 
6111
6112      No need to check target flags as the length uniquely identifies
6113      the remaining cases.  */
6114   if (get_attr_length (insn) == 8)
6115     return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
6116
6117   /* Long millicode call, but we are not generating PIC or portable runtime
6118      code.  */
6119   if (get_attr_length (insn) == 12)
6120     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
6121
6122   /* Long millicode call for portable runtime.  */
6123   if (get_attr_length (insn) == 20)
6124     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
6125
6126   /* If we're generating PIC code.  */
6127   xoperands[0] = operands[0];
6128   if (TARGET_SOM || ! TARGET_GAS)
6129     xoperands[1] = gen_label_rtx ();
6130   output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
6131   if (TARGET_SOM || ! TARGET_GAS)
6132     {
6133       output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
6134       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6135                                  CODE_LABEL_NUMBER (xoperands[1]));
6136       output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
6137     }
6138   else
6139     {
6140       output_asm_insn (\"addil L%%$$dyncall-$PIC_pcrel$0+4,%%r1\", xoperands);
6141       output_asm_insn (\"ldo R%%$$dyncall-$PIC_pcrel$0+8(%%r1),%%r1\",
6142                        xoperands);
6143     }
6144   output_asm_insn (\"blr %%r0,%%r2\", xoperands);
6145   output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
6146   return \"\";
6147 }"
6148   [(set_attr "type" "dyncall")
6149    (set (attr "length")
6150      (cond [
6151 ;; First FAST_INDIRECT_CALLS
6152             (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
6153                 (const_int 0))
6154             (const_int 8)
6155
6156 ;; Target (or stub) within reach
6157             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
6158                      (const_int 240000))
6159                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
6160                      (const_int 0)))
6161             (const_int 8)
6162
6163 ;; Out of reach PIC
6164             (ne (symbol_ref "flag_pic")
6165                 (const_int 0))
6166             (const_int 24)
6167
6168 ;; Out of reach PORTABLE_RUNTIME
6169             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
6170                 (const_int 0))
6171             (const_int 20)]
6172
6173 ;; Out of reach, can use ble
6174           (const_int 12)))])
6175
6176 (define_expand "call_value"
6177   [(parallel [(set (match_operand 0 "" "")
6178                    (call (match_operand:SI 1 "" "")
6179                          (match_operand 2 "" "")))
6180               (clobber (reg:SI 2))])]
6181   ""
6182   "
6183 {
6184   rtx op;
6185   rtx call_insn;
6186
6187   if (TARGET_PORTABLE_RUNTIME)
6188     op = force_reg (word_mode, XEXP (operands[1], 0));
6189   else
6190     op = XEXP (operands[1], 0);
6191
6192   if (TARGET_64BIT)
6193     emit_move_insn (arg_pointer_rtx,
6194                     gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
6195                                   GEN_INT (64)));
6196
6197   /* Use two different patterns for calls to explicitly named functions
6198      and calls through function pointers.  This is necessary as these two
6199      types of calls use different calling conventions, and CSE might try
6200      to change the named call into an indirect call in some cases (using
6201      two patterns keeps CSE from performing this optimization).  */
6202   if (GET_CODE (op) == SYMBOL_REF)
6203     call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
6204                                                                 op,
6205                                                                 operands[2]));
6206   else if (TARGET_64BIT)
6207     {
6208       rtx tmpreg = force_reg (word_mode, op);
6209       call_insn
6210         = emit_call_insn (gen_call_value_internal_reg_64bit (operands[0],
6211                                                              tmpreg,
6212                                                              operands[2]));
6213     }
6214   else
6215     {
6216       rtx tmpreg = gen_rtx_REG (word_mode, 22);
6217       emit_move_insn (tmpreg, force_reg (word_mode, op));
6218       call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
6219                                                                operands[2]));
6220     }
6221   if (flag_pic)
6222     {
6223       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6224       if (TARGET_64BIT)
6225         use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
6226
6227       /* After each call we must restore the PIC register, even if it
6228          doesn't appear to be used.  */
6229       emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6230     }
6231   DONE;
6232 }")
6233
6234 (define_insn "call_value_internal_symref"
6235   [(set (match_operand 0 "" "=rf")
6236         (call (mem:SI (match_operand 1 "call_operand_address" ""))
6237               (match_operand 2 "" "i")))
6238    (clobber (reg:SI 2))
6239    (use (const_int 0))]
6240   ;;- Don't use operand 1 for most machines.
6241   "! TARGET_PORTABLE_RUNTIME"
6242   "*
6243 {
6244   output_arg_descriptor (insn);
6245   return output_call (insn, operands[1], 0);
6246 }"
6247   [(set_attr "type" "call")
6248    (set (attr "length")
6249 ;;       If we're sure that we can either reach the target or that the
6250 ;;       linker can use a long-branch stub, then the length is at most
6251 ;;       8 bytes.
6252 ;;
6253 ;;       For long-calls the length will be at most 68 bytes (non-pic)
6254 ;;       or 84 bytes (pic).  */
6255 ;;       Else we have to use a long-call;
6256       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6257                         (const_int 240000))
6258                     (const_int 8)
6259                     (if_then_else (eq (symbol_ref "flag_pic")
6260                                       (const_int 0))
6261                                   (const_int 68)
6262                                   (const_int 84))))])
6263
6264 (define_insn "call_value_internal_reg_64bit"
6265   [(set (match_operand 0 "" "=rf")
6266          (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
6267                (match_operand 2 "" "i")))
6268    (clobber (reg:SI 2))
6269    (use (const_int 1))]
6270   "TARGET_64BIT"
6271   "*
6272 {
6273   /* ??? Needs more work.  Length computation, split into multiple insns,
6274      do not use %r22 directly, expose delay slot.  */
6275   return \"ldd 16(%1),%%r2\;ldd 24(%1),%%r27\;bve,l (%%r2),%%r2\;nop\";
6276 }"
6277   [(set_attr "type" "dyncall")
6278    (set (attr "length") (const_int 16))])
6279
6280 (define_insn "call_value_internal_reg"
6281   [(set (match_operand 0 "" "=rf")
6282         (call (mem:SI (reg:SI 22))
6283               (match_operand 1 "" "i")))
6284    (clobber (reg:SI 2))
6285    (use (const_int 1))]
6286   ""
6287   "*
6288 {
6289   rtx xoperands[2];
6290
6291   /* First the special case for kernels, level 0 systems, etc.  */
6292   if (TARGET_FAST_INDIRECT_CALLS)
6293     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
6294
6295   /* Now the normal case -- we can reach $$dyncall directly or
6296      we're sure that we can get there via a long-branch stub. 
6297
6298      No need to check target flags as the length uniquely identifies
6299      the remaining cases.  */
6300   if (get_attr_length (insn) == 8)
6301     return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
6302
6303   /* Long millicode call, but we are not generating PIC or portable runtime
6304      code.  */
6305   if (get_attr_length (insn) == 12)
6306     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
6307
6308   /* Long millicode call for portable runtime.  */
6309   if (get_attr_length (insn) == 20)
6310     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
6311
6312   /* If we're generating PIC code.  */
6313   xoperands[0] = operands[1];
6314   if (TARGET_SOM || ! TARGET_GAS)
6315     xoperands[1] = gen_label_rtx ();
6316   output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
6317   if (TARGET_SOM || ! TARGET_GAS)
6318     {
6319       output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
6320       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
6321                                  CODE_LABEL_NUMBER (xoperands[1]));
6322       output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
6323     }
6324   else
6325     {
6326       output_asm_insn (\"addil L%%$$dyncall-$PIC_pcrel$0+4,%%r1\", xoperands);
6327       output_asm_insn (\"ldo R%%$$dyncall-$PIC_pcrel$0+8(%%r1),%%r1\",
6328                        xoperands);
6329     }
6330   output_asm_insn (\"blr %%r0,%%r2\", xoperands);
6331   output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
6332   return \"\";
6333 }"
6334   [(set_attr "type" "dyncall")
6335    (set (attr "length")
6336      (cond [
6337 ;; First FAST_INDIRECT_CALLS
6338             (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
6339                 (const_int 0))
6340             (const_int 8)
6341
6342 ;; Target (or stub) within reach
6343             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
6344                      (const_int 240000))
6345                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
6346                      (const_int 0)))
6347             (const_int 8)
6348
6349 ;; Out of reach PIC
6350             (ne (symbol_ref "flag_pic")
6351                 (const_int 0))
6352             (const_int 24)
6353
6354 ;; Out of reach PORTABLE_RUNTIME
6355             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
6356                 (const_int 0))
6357             (const_int 20)]
6358
6359 ;; Out of reach, can use ble
6360           (const_int 12)))])
6361
6362 ;; Call subroutine returning any type.
6363
6364 (define_expand "untyped_call"
6365   [(parallel [(call (match_operand 0 "" "")
6366                     (const_int 0))
6367               (match_operand 1 "" "")
6368               (match_operand 2 "" "")])]
6369   ""
6370   "
6371 {
6372   int i;
6373
6374   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
6375
6376   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6377     {
6378       rtx set = XVECEXP (operands[2], 0, i);
6379       emit_move_insn (SET_DEST (set), SET_SRC (set));
6380     }
6381
6382   /* The optimizer does not know that the call sets the function value
6383      registers we stored in the result block.  We avoid problems by
6384      claiming that all hard registers are used and clobbered at this
6385      point.  */
6386   emit_insn (gen_blockage ());
6387
6388   DONE;
6389 }")
6390
6391 (define_expand "sibcall"
6392   [(parallel [(call (match_operand:SI 0 "" "")
6393                     (match_operand 1 "" ""))
6394               (clobber (reg:SI 0))])]
6395   "! TARGET_PORTABLE_RUNTIME"
6396   "
6397 {
6398   rtx op;
6399   rtx call_insn;
6400
6401   op = XEXP (operands[0], 0);
6402
6403   /* We do not allow indirect sibling calls.  */
6404   call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
6405
6406   if (flag_pic)
6407     {
6408       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6409
6410       /* After each call we must restore the PIC register, even if it
6411          doesn't appear to be used.  */
6412       emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6413     }
6414   DONE;
6415 }")
6416
6417 (define_insn "sibcall_internal_symref"
6418   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
6419          (match_operand 1 "" "i"))
6420    (clobber (reg:SI 0))
6421    (use (reg:SI 2))
6422    (use (const_int 0))]
6423   "! TARGET_PORTABLE_RUNTIME"
6424   "*
6425 {
6426   output_arg_descriptor (insn);
6427   return output_call (insn, operands[0], 1);
6428 }"
6429   [(set_attr "type" "call")
6430    (set (attr "length")
6431 ;;       If we're sure that we can either reach the target or that the
6432 ;;       linker can use a long-branch stub, then the length is at most
6433 ;;       8 bytes.
6434 ;;
6435 ;;       For long-calls the length will be at most 68 bytes (non-pic)
6436 ;;       or 84 bytes (pic).  */
6437 ;;       Else we have to use a long-call;
6438       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6439                         (const_int 240000))
6440                     (const_int 8)
6441                     (if_then_else (eq (symbol_ref "flag_pic")
6442                                       (const_int 0))
6443                                   (const_int 68)
6444                                   (const_int 84))))])
6445
6446 (define_expand "sibcall_value"
6447   [(parallel [(set (match_operand 0 "" "")
6448                    (call (match_operand:SI 1 "" "")
6449                          (match_operand 2 "" "")))
6450               (clobber (reg:SI 0))])]
6451   "! TARGET_PORTABLE_RUNTIME"
6452   "
6453 {
6454   rtx op;
6455   rtx call_insn;
6456
6457   op = XEXP (operands[1], 0);
6458
6459   /* We do not allow indirect sibling calls.  */
6460   call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
6461                                                                  op,
6462                                                                  operands[2]));
6463   if (flag_pic)
6464     {
6465       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
6466
6467       /* After each call we must restore the PIC register, even if it
6468          doesn't appear to be used.  */
6469       emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
6470     }
6471   DONE;
6472 }")
6473
6474 (define_insn "sibcall_value_internal_symref"
6475   [(set (match_operand 0 "" "=rf")
6476         (call (mem:SI (match_operand 1 "call_operand_address" ""))
6477               (match_operand 2 "" "i")))
6478    (clobber (reg:SI 0))
6479    (use (reg:SI 2))
6480    (use (const_int 0))]
6481   ;;- Don't use operand 1 for most machines.
6482   "! TARGET_PORTABLE_RUNTIME"
6483   "*
6484 {
6485   output_arg_descriptor (insn);
6486   return output_call (insn, operands[1], 1);
6487 }"
6488   [(set_attr "type" "call")
6489    (set (attr "length")
6490 ;;       If we're sure that we can either reach the target or that the
6491 ;;       linker can use a long-branch stub, then the length is at most
6492 ;;       8 bytes.
6493 ;;
6494 ;;       For long-calls the length will be at most 68 bytes (non-pic)
6495 ;;       or 84 bytes (pic).  */
6496 ;;       Else we have to use a long-call;
6497       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
6498                         (const_int 240000))
6499                     (const_int 8)
6500                     (if_then_else (eq (symbol_ref "flag_pic")
6501                                       (const_int 0))
6502                                   (const_int 68)
6503                                   (const_int 84))))])
6504
6505 (define_insn "nop"
6506   [(const_int 0)]
6507   ""
6508   "nop"
6509   [(set_attr "type" "move")
6510    (set_attr "length" "4")])
6511
6512 ;; These are just placeholders so we know where branch tables
6513 ;; begin and end.
6514 (define_insn "begin_brtab"
6515   [(const_int 1)]
6516   ""
6517   "*
6518 {
6519   /* Only GAS actually supports this pseudo-op.  */
6520   if (TARGET_GAS)
6521     return \".begin_brtab\";
6522   else
6523     return \"\";
6524 }"
6525   [(set_attr "type" "move")
6526    (set_attr "length" "0")])
6527
6528 (define_insn "end_brtab"
6529   [(const_int 2)]
6530   ""
6531   "*
6532 {
6533   /* Only GAS actually supports this pseudo-op.  */
6534   if (TARGET_GAS)
6535     return \".end_brtab\";
6536   else
6537     return \"\";
6538 }"
6539   [(set_attr "type" "move")
6540    (set_attr "length" "0")])
6541
6542 ;;; EH does longjmp's from and within the data section.  Thus,
6543 ;;; an interspace branch is required for the longjmp implementation.
6544 ;;; Registers r1 and r2 are used as scratch registers for the jump.
6545 (define_expand "interspace_jump"
6546   [(parallel
6547      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6548       (clobber (match_dup 1))])]
6549   ""
6550   "
6551 {
6552   operands[1] = gen_rtx_REG (word_mode, 2);
6553 }")
6554
6555 (define_insn ""
6556   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6557   (clobber (reg:SI 2))]
6558   "!TARGET_64BIT"
6559   "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6560    [(set_attr "type" "branch")
6561     (set_attr "length" "12")])
6562
6563 (define_insn ""
6564   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
6565   (clobber (reg:DI 2))]
6566   "TARGET_64BIT"
6567   "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
6568    [(set_attr "type" "branch")
6569     (set_attr "length" "12")])
6570
6571 (define_expand "builtin_longjmp"
6572   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
6573   ""
6574   "
6575 {
6576   /* The elements of the buffer are, in order:  */
6577   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6578   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0],
6579                          POINTER_SIZE / BITS_PER_UNIT));
6580   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0],
6581                            (POINTER_SIZE * 2) / BITS_PER_UNIT));
6582   rtx pv = gen_rtx_REG (Pmode, 1);
6583
6584   /* This bit is the same as expand_builtin_longjmp.  */
6585   emit_move_insn (hard_frame_pointer_rtx, fp);
6586   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6587   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6588   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6589
6590   /* Load the label we are jumping through into r1 so that we know
6591      where to look for it when we get back to setjmp's function for
6592      restoring the gp.  */
6593   emit_move_insn (pv, lab);
6594
6595   /* Prevent the insns above from being scheduled into the delay slot
6596      of the interspace jump because the space register could change.  */
6597   emit_insn (gen_blockage ());
6598
6599   emit_jump_insn (gen_interspace_jump (pv));
6600   emit_barrier ();
6601   DONE;
6602 }")
6603
6604 ;;; Hope this is only within a function...
6605 (define_insn "indirect_jump"
6606   [(set (pc) (match_operand 0 "register_operand" "r"))]
6607   "GET_MODE (operands[0]) == word_mode"
6608   "bv%* %%r0(%0)"
6609   [(set_attr "type" "branch")
6610    (set_attr "length" "4")])
6611
6612 (define_expand "extzv"
6613   [(set (match_operand 0 "register_operand" "")
6614         (zero_extract (match_operand 1 "register_operand" "")
6615                       (match_operand 2 "uint32_operand" "")
6616                       (match_operand 3 "uint32_operand" "")))]
6617   ""
6618   "
6619 {
6620   if (TARGET_64BIT)
6621     emit_insn (gen_extzv_64 (operands[0], operands[1],
6622                              operands[2], operands[3]));
6623   else
6624     emit_insn (gen_extzv_32 (operands[0], operands[1],
6625                              operands[2], operands[3]));
6626   DONE;
6627 }")
6628
6629 (define_insn "extzv_32"
6630   [(set (match_operand:SI 0 "register_operand" "=r")
6631         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6632                          (match_operand:SI 2 "uint5_operand" "")
6633                          (match_operand:SI 3 "uint5_operand" "")))]
6634   ""
6635   "{extru|extrw,u} %1,%3+%2-1,%2,%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         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
6642                          (const_int 1)
6643                          (match_operand:SI 2 "register_operand" "q")))]
6644   ""
6645   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
6646   [(set_attr "type" "shift")
6647    (set_attr "length" "4")])
6648
6649 (define_insn "extzv_64"
6650   [(set (match_operand:DI 0 "register_operand" "=r")
6651         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6652                          (match_operand:DI 2 "uint32_operand" "")
6653                          (match_operand:DI 3 "uint32_operand" "")))]
6654   "TARGET_64BIT"
6655   "extrd,u %1,%3+%2-1,%2,%0"
6656   [(set_attr "type" "shift")
6657    (set_attr "length" "4")])
6658
6659 (define_insn ""
6660   [(set (match_operand:DI 0 "register_operand" "=r")
6661         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
6662                          (const_int 1)
6663                          (match_operand:DI 2 "register_operand" "q")))]
6664   "TARGET_64BIT"
6665   "extrd,u %1,%%sar,1,%0"
6666   [(set_attr "type" "shift")
6667    (set_attr "length" "4")])
6668
6669 (define_expand "extv"
6670   [(set (match_operand 0 "register_operand" "")
6671         (sign_extract (match_operand 1 "register_operand" "")
6672                       (match_operand 2 "uint32_operand" "")
6673                       (match_operand 3 "uint32_operand" "")))]
6674   ""
6675   "
6676 {
6677   if (TARGET_64BIT)
6678     emit_insn (gen_extv_64 (operands[0], operands[1],
6679                             operands[2], operands[3]));
6680   else
6681     {
6682       if (! uint5_operand (operands[2], SImode)
6683           || ! uint5_operand (operands[3], SImode))
6684         FAIL;
6685       emit_insn (gen_extv_32 (operands[0], operands[1],
6686                               operands[2], operands[3]));
6687     }
6688   DONE;
6689 }")
6690
6691 (define_insn "extv_32"
6692   [(set (match_operand:SI 0 "register_operand" "=r")
6693         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6694                          (match_operand:SI 2 "uint5_operand" "")
6695                          (match_operand:SI 3 "uint5_operand" "")))]
6696   ""
6697   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
6698   [(set_attr "type" "shift")
6699    (set_attr "length" "4")])
6700
6701 (define_insn ""
6702   [(set (match_operand:SI 0 "register_operand" "=r")
6703         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
6704                          (const_int 1)
6705                          (match_operand:SI 2 "register_operand" "q")))]
6706   "!TARGET_64BIT"
6707   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
6708   [(set_attr "type" "shift")
6709    (set_attr "length" "4")])
6710
6711 (define_insn "extv_64"
6712   [(set (match_operand:DI 0 "register_operand" "=r")
6713         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6714                          (match_operand:DI 2 "uint32_operand" "")
6715                          (match_operand:DI 3 "uint32_operand" "")))]
6716   "TARGET_64BIT"
6717   "extrd,s %1,%3+%2-1,%2,%0"
6718   [(set_attr "type" "shift")
6719    (set_attr "length" "4")])
6720
6721 (define_insn ""
6722   [(set (match_operand:DI 0 "register_operand" "=r")
6723         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
6724                          (const_int 1)
6725                          (match_operand:DI 2 "register_operand" "q")))]
6726   "TARGET_64BIT"
6727   "extrd,s %1,%%sar,1,%0"
6728   [(set_attr "type" "shift")
6729    (set_attr "length" "4")])
6730
6731 ;; Only specify the mode operands 0, the rest are assumed to be word_mode.
6732 (define_expand "insv"
6733   [(set (zero_extract (match_operand 0 "register_operand" "")
6734                       (match_operand 1 "uint32_operand" "")
6735                       (match_operand 2 "uint32_operand" ""))
6736         (match_operand 3 "arith5_operand" ""))]
6737   ""
6738   "
6739 {
6740   if (TARGET_64BIT)
6741     emit_insn (gen_insv_64 (operands[0], operands[1],
6742                             operands[2], operands[3]));
6743   else
6744     emit_insn (gen_insv_32 (operands[0], operands[1],
6745                             operands[2], operands[3]));
6746   DONE;
6747 }")
6748
6749 (define_insn "insv_32"
6750   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
6751                          (match_operand:SI 1 "uint5_operand" "")
6752                          (match_operand:SI 2 "uint5_operand" ""))
6753         (match_operand:SI 3 "arith5_operand" "r,L"))]
6754   ""
6755   "@
6756    {dep|depw} %3,%2+%1-1,%1,%0
6757    {depi|depwi} %3,%2+%1-1,%1,%0"
6758   [(set_attr "type" "shift,shift")
6759    (set_attr "length" "4,4")])
6760
6761 ;; Optimize insertion of const_int values of type 1...1xxxx.
6762 (define_insn ""
6763   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
6764                          (match_operand:SI 1 "uint5_operand" "")
6765                          (match_operand:SI 2 "uint5_operand" ""))
6766         (match_operand:SI 3 "const_int_operand" ""))]
6767   "(INTVAL (operands[3]) & 0x10) != 0 &&
6768    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6769   "*
6770 {
6771   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6772   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
6773 }"
6774   [(set_attr "type" "shift")
6775    (set_attr "length" "4")])
6776
6777 (define_insn "insv_64"
6778   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
6779                          (match_operand:DI 1 "uint32_operand" "")
6780                          (match_operand:DI 2 "uint32_operand" ""))
6781         (match_operand:DI 3 "arith32_operand" "r,L"))]
6782   "TARGET_64BIT"
6783   "@
6784    depd %3,%2+%1-1,%1,%0
6785    depdi %3,%2+%1-1,%1,%0"
6786   [(set_attr "type" "shift,shift")
6787    (set_attr "length" "4,4")])
6788
6789 ;; Optimize insertion of const_int values of type 1...1xxxx.
6790 (define_insn ""
6791   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
6792                          (match_operand:DI 1 "uint32_operand" "")
6793                          (match_operand:DI 2 "uint32_operand" ""))
6794         (match_operand:DI 3 "const_int_operand" ""))]
6795   "(INTVAL (operands[3]) & 0x10) != 0
6796    && TARGET_64BIT
6797    && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
6798   "*
6799 {
6800   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
6801   return \"depdi %3,%2+%1-1,%1,%0\";
6802 }"
6803   [(set_attr "type" "shift")
6804    (set_attr "length" "4")])
6805
6806 (define_insn ""
6807   [(set (match_operand:DI 0 "register_operand" "=r")
6808         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6809                    (const_int 32)))]
6810   "TARGET_64BIT"
6811   "depd,z %1,31,32,%0"
6812   [(set_attr "type" "shift")
6813    (set_attr "length" "4")])
6814
6815 ;; This insn is used for some loop tests, typically loops reversed when
6816 ;; strength reduction is used.  It is actually created when the instruction
6817 ;; combination phase combines the special loop test.  Since this insn
6818 ;; is both a jump insn and has an output, it must deal with its own
6819 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
6820 ;; to not choose the register alternatives in the event a reload is needed.
6821 (define_insn "decrement_and_branch_until_zero"
6822   [(set (pc)
6823         (if_then_else
6824           (match_operator 2 "comparison_operator"
6825            [(plus:SI
6826               (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
6827               (match_operand:SI 1 "int5_operand" "L,L,L"))
6828             (const_int 0)])
6829           (label_ref (match_operand 3 "" ""))
6830           (pc)))
6831    (set (match_dup 0)
6832         (plus:SI (match_dup 0) (match_dup 1)))
6833    (clobber (match_scratch:SI 4 "=X,r,r"))]
6834   ""
6835   "* return output_dbra (operands, insn, which_alternative); "
6836 ;; Do not expect to understand this the first time through.
6837 [(set_attr "type" "cbranch,multi,multi")
6838  (set (attr "length")
6839       (if_then_else (eq_attr "alternative" "0")
6840 ;; Loop counter in register case
6841 ;; Short branch has length of 4
6842 ;; Long branch has length of 8
6843         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6844                       (const_int 8184))
6845            (const_int 4)
6846            (const_int 8))
6847
6848 ;; Loop counter in FP reg case.
6849 ;; Extra goo to deal with additional reload insns.
6850         (if_then_else (eq_attr "alternative" "1")
6851           (if_then_else (lt (match_dup 3) (pc))
6852             (if_then_else
6853               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
6854                   (const_int 8184))
6855               (const_int 24)
6856               (const_int 28))
6857             (if_then_else
6858               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6859                   (const_int 8184))
6860               (const_int 24)
6861               (const_int 28)))
6862 ;; Loop counter in memory case.
6863 ;; Extra goo to deal with additional reload insns.
6864         (if_then_else (lt (match_dup 3) (pc))
6865           (if_then_else
6866             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6867                 (const_int 8184))
6868             (const_int 12)
6869             (const_int 16))
6870           (if_then_else
6871             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6872                 (const_int 8184))
6873             (const_int 12)
6874             (const_int 16))))))])
6875
6876 (define_insn ""
6877   [(set (pc)
6878         (if_then_else
6879           (match_operator 2 "movb_comparison_operator"
6880            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6881           (label_ref (match_operand 3 "" ""))
6882           (pc)))
6883    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
6884         (match_dup 1))]
6885   ""
6886 "* return output_movb (operands, insn, which_alternative, 0); "
6887 ;; Do not expect to understand this the first time through.
6888 [(set_attr "type" "cbranch,multi,multi,multi")
6889  (set (attr "length")
6890       (if_then_else (eq_attr "alternative" "0")
6891 ;; Loop counter in register case
6892 ;; Short branch has length of 4
6893 ;; Long branch has length of 8
6894         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6895                       (const_int 8184))
6896            (const_int 4)
6897            (const_int 8))
6898
6899 ;; Loop counter in FP reg case.
6900 ;; Extra goo to deal with additional reload insns.
6901         (if_then_else (eq_attr "alternative" "1")
6902           (if_then_else (lt (match_dup 3) (pc))
6903             (if_then_else
6904               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6905                   (const_int 8184))
6906               (const_int 12)
6907               (const_int 16))
6908             (if_then_else
6909               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6910                   (const_int 8184))
6911               (const_int 12)
6912               (const_int 16)))
6913 ;; Loop counter in memory or sar case.
6914 ;; Extra goo to deal with additional reload insns.
6915         (if_then_else
6916           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6917               (const_int 8184))
6918           (const_int 8)
6919           (const_int 12)))))])
6920
6921 ;; Handle negated branch.
6922 (define_insn ""
6923   [(set (pc)
6924         (if_then_else
6925           (match_operator 2 "movb_comparison_operator"
6926            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
6927           (pc)
6928           (label_ref (match_operand 3 "" ""))))
6929    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
6930         (match_dup 1))]
6931   ""
6932 "* return output_movb (operands, insn, which_alternative, 1); "
6933 ;; Do not expect to understand this the first time through.
6934 [(set_attr "type" "cbranch,multi,multi,multi")
6935  (set (attr "length")
6936       (if_then_else (eq_attr "alternative" "0")
6937 ;; Loop counter in register case
6938 ;; Short branch has length of 4
6939 ;; Long branch has length of 8
6940         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6941                       (const_int 8184))
6942            (const_int 4)
6943            (const_int 8))
6944
6945 ;; Loop counter in FP reg case.
6946 ;; Extra goo to deal with additional reload insns.
6947         (if_then_else (eq_attr "alternative" "1")
6948           (if_then_else (lt (match_dup 3) (pc))
6949             (if_then_else
6950               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
6951                   (const_int 8184))
6952               (const_int 12)
6953               (const_int 16))
6954             (if_then_else
6955               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6956                   (const_int 8184))
6957               (const_int 12)
6958               (const_int 16)))
6959 ;; Loop counter in memory or SAR case.
6960 ;; Extra goo to deal with additional reload insns.
6961         (if_then_else
6962           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6963               (const_int 8184))
6964           (const_int 8)
6965           (const_int 12)))))])
6966
6967 (define_insn ""
6968   [(set (pc) (label_ref (match_operand 3 "" "" )))
6969    (set (match_operand:SI 0 "ireg_operand" "=r")
6970         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
6971                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
6972   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
6973   "*
6974 {
6975   return output_parallel_addb (operands, get_attr_length (insn));
6976 }"
6977   [(set_attr "type" "parallel_branch")
6978    (set (attr "length")
6979     (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
6980                       (const_int 8184))
6981            (const_int 4)
6982            (const_int 8)))])
6983
6984 (define_insn ""
6985   [(set (pc) (label_ref (match_operand 2 "" "" )))
6986    (set (match_operand:SF 0 "ireg_operand" "=r")
6987         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
6988   "reload_completed"
6989   "*
6990 {
6991   return output_parallel_movb (operands, get_attr_length (insn));
6992 }"
6993   [(set_attr "type" "parallel_branch")
6994    (set (attr "length")
6995     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
6996                       (const_int 8184))
6997            (const_int 4)
6998            (const_int 8)))])
6999
7000 (define_insn ""
7001   [(set (pc) (label_ref (match_operand 2 "" "" )))
7002    (set (match_operand:SI 0 "ireg_operand" "=r")
7003         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
7004   "reload_completed"
7005   "*
7006 {
7007   return output_parallel_movb (operands, get_attr_length (insn));
7008 }"
7009   [(set_attr "type" "parallel_branch")
7010    (set (attr "length")
7011     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
7012                       (const_int 8184))
7013            (const_int 4)
7014            (const_int 8)))])
7015
7016 (define_insn ""
7017   [(set (pc) (label_ref (match_operand 2 "" "" )))
7018    (set (match_operand:HI 0 "ireg_operand" "=r")
7019         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
7020   "reload_completed"
7021   "*
7022 {
7023   return output_parallel_movb (operands, get_attr_length (insn));
7024 }"
7025   [(set_attr "type" "parallel_branch")
7026    (set (attr "length")
7027     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
7028                       (const_int 8184))
7029            (const_int 4)
7030            (const_int 8)))])
7031
7032 (define_insn ""
7033   [(set (pc) (label_ref (match_operand 2 "" "" )))
7034    (set (match_operand:QI 0 "ireg_operand" "=r")
7035         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
7036   "reload_completed"
7037   "*
7038 {
7039   return output_parallel_movb (operands, get_attr_length (insn));
7040 }"
7041   [(set_attr "type" "parallel_branch")
7042    (set (attr "length")
7043     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
7044                       (const_int 8184))
7045            (const_int 4)
7046            (const_int 8)))])
7047
7048 (define_insn ""
7049   [(set (match_operand 0 "register_operand" "=f")
7050         (mult (match_operand 1 "register_operand" "f")
7051               (match_operand 2 "register_operand" "f")))
7052    (set (match_operand 3 "register_operand" "+f")
7053         (plus (match_operand 4 "register_operand" "f")
7054               (match_operand 5 "register_operand" "f")))]
7055   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
7056    && reload_completed && fmpyaddoperands (operands)"
7057   "*
7058 {
7059   if (GET_MODE (operands[0]) == DFmode)
7060     {
7061       if (rtx_equal_p (operands[3], operands[5]))
7062         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
7063       else
7064         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
7065     }
7066   else
7067     {
7068       if (rtx_equal_p (operands[3], operands[5]))
7069         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
7070       else
7071         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
7072     }
7073 }"
7074   [(set_attr "type" "fpalu")
7075    (set_attr "length" "4")])
7076
7077 (define_insn ""
7078   [(set (match_operand 3 "register_operand" "+f")
7079         (plus (match_operand 4 "register_operand" "f")
7080               (match_operand 5 "register_operand" "f")))
7081    (set (match_operand 0 "register_operand" "=f")
7082         (mult (match_operand 1 "register_operand" "f")
7083               (match_operand 2 "register_operand" "f")))]
7084   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
7085    && reload_completed && fmpyaddoperands (operands)"
7086   "*
7087 {
7088   if (GET_MODE (operands[0]) == DFmode)
7089     {
7090       if (rtx_equal_p (operands[3], operands[5]))
7091         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
7092       else
7093         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
7094     }
7095   else
7096     {
7097       if (rtx_equal_p (operands[3], operands[5]))
7098         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
7099       else
7100         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
7101     }
7102 }"
7103   [(set_attr "type" "fpalu")
7104    (set_attr "length" "4")])
7105
7106 (define_insn ""
7107   [(set (match_operand 0 "register_operand" "=f")
7108         (mult (match_operand 1 "register_operand" "f")
7109               (match_operand 2 "register_operand" "f")))
7110    (set (match_operand 3 "register_operand" "+f")
7111         (minus (match_operand 4 "register_operand" "f")
7112                (match_operand 5 "register_operand" "f")))]
7113   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
7114    && reload_completed && fmpysuboperands (operands)"
7115   "*
7116 {
7117   if (GET_MODE (operands[0]) == DFmode)
7118     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
7119   else
7120     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
7121 }"
7122   [(set_attr "type" "fpalu")
7123    (set_attr "length" "4")])
7124
7125 (define_insn ""
7126   [(set (match_operand 3 "register_operand" "+f")
7127         (minus (match_operand 4 "register_operand" "f")
7128                (match_operand 5 "register_operand" "f")))
7129    (set (match_operand 0 "register_operand" "=f")
7130         (mult (match_operand 1 "register_operand" "f")
7131               (match_operand 2 "register_operand" "f")))]
7132   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
7133    && reload_completed && fmpysuboperands (operands)"
7134   "*
7135 {
7136   if (GET_MODE (operands[0]) == DFmode)
7137     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
7138   else
7139     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
7140 }"
7141   [(set_attr "type" "fpalu")
7142    (set_attr "length" "4")])
7143
7144 ;; Clean up turds left by reload.
7145 (define_peephole
7146   [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
7147         (match_operand 1 "register_operand" "fr"))
7148    (set (match_operand 2 "register_operand" "fr")
7149         (match_dup 0))]
7150   "! TARGET_SOFT_FLOAT
7151    && GET_CODE (operands[0]) == MEM
7152    && ! MEM_VOLATILE_P (operands[0])
7153    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7154    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7155    && GET_MODE (operands[0]) == DFmode
7156    && GET_CODE (operands[1]) == REG
7157    && GET_CODE (operands[2]) == REG
7158    && ! side_effects_p (XEXP (operands[0], 0))
7159    && REGNO_REG_CLASS (REGNO (operands[1]))
7160       == REGNO_REG_CLASS (REGNO (operands[2]))"
7161   "*
7162 {
7163   rtx xoperands[2];
7164
7165   if (FP_REG_P (operands[1]))
7166     output_asm_insn (output_fp_move_double (operands), operands);
7167   else
7168     output_asm_insn (output_move_double (operands), operands);
7169
7170   if (rtx_equal_p (operands[1], operands[2]))
7171     return \"\";
7172
7173   xoperands[0] = operands[2];
7174   xoperands[1] = operands[1];
7175       
7176   if (FP_REG_P (xoperands[1]))
7177     output_asm_insn (output_fp_move_double (xoperands), xoperands);
7178   else
7179     output_asm_insn (output_move_double (xoperands), xoperands);
7180
7181   return \"\";
7182 }")
7183
7184 (define_peephole
7185   [(set (match_operand 0 "register_operand" "fr")
7186         (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
7187    (set (match_operand 2 "register_operand" "fr")
7188         (match_dup 1))]
7189   "! TARGET_SOFT_FLOAT
7190    && GET_CODE (operands[1]) == MEM
7191    && ! MEM_VOLATILE_P (operands[1])
7192    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7193    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7194    && GET_MODE (operands[0]) == DFmode
7195    && GET_CODE (operands[0]) == REG
7196    && GET_CODE (operands[2]) == REG
7197    && ! side_effects_p (XEXP (operands[1], 0))
7198    && REGNO_REG_CLASS (REGNO (operands[0]))
7199       == REGNO_REG_CLASS (REGNO (operands[2]))"
7200   "*
7201 {
7202   rtx xoperands[2];
7203
7204   if (FP_REG_P (operands[0]))
7205     output_asm_insn (output_fp_move_double (operands), operands);
7206   else
7207     output_asm_insn (output_move_double (operands), operands);
7208
7209   xoperands[0] = operands[2];
7210   xoperands[1] = operands[0];
7211       
7212   if (FP_REG_P (xoperands[1]))
7213     output_asm_insn (output_fp_move_double (xoperands), xoperands);
7214   else
7215     output_asm_insn (output_move_double (xoperands), xoperands);
7216
7217   return \"\";
7218 }")
7219
7220 ;; Flush the I and D cache line found at the address in operand 0.
7221 ;; This is used by the trampoline code for nested functions.
7222 ;; So long as the trampoline itself is less than 32 bytes this
7223 ;; is sufficient.
7224
7225 (define_insn "dcacheflush"
7226   [(unspec_volatile [(const_int 1)] 0)
7227    (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
7228    (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
7229   ""
7230   "fdc 0(%0)\;fdc 0(%1)\;sync"
7231   [(set_attr "type" "multi")
7232    (set_attr "length" "12")])
7233
7234 (define_insn "icacheflush"
7235   [(unspec_volatile [(const_int 2)] 0)
7236    (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
7237    (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
7238    (use (match_operand 2 "pmode_register_operand" "r"))
7239    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
7240    (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
7241   ""
7242   "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
7243   [(set_attr "type" "multi")
7244    (set_attr "length" "52")])
7245
7246 ;; An out-of-line prologue.
7247 (define_insn "outline_prologue_call"
7248   [(unspec_volatile [(const_int 0)] 0)
7249    (clobber (reg:SI 31))
7250    (clobber (reg:SI 22))
7251    (clobber (reg:SI 21))
7252    (clobber (reg:SI 20))
7253    (clobber (reg:SI 19))
7254    (clobber (reg:SI 1))]
7255   ""
7256   "*
7257 {
7258   extern int frame_pointer_needed;
7259
7260   /* We need two different versions depending on whether or not we
7261      need a frame pointer.   Also note that we return to the instruction
7262      immediately after the branch rather than two instructions after the
7263      break as normally is the case.  */
7264   if (frame_pointer_needed)
7265     {
7266       /* Must import the magic millicode routine(s).  */
7267       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
7268
7269       if (TARGET_PORTABLE_RUNTIME)
7270         {
7271           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
7272           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
7273                            NULL);
7274         }
7275       else
7276         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
7277     }
7278   else
7279     {
7280       /* Must import the magic millicode routine(s).  */
7281       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
7282
7283       if (TARGET_PORTABLE_RUNTIME)
7284         {
7285           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
7286           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
7287         }
7288       else
7289         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
7290     }
7291   return \"\";
7292 }"
7293   [(set_attr "type" "multi")
7294    (set_attr "length" "8")])
7295
7296 ;; An out-of-line epilogue.
7297 (define_insn "outline_epilogue_call"
7298   [(unspec_volatile [(const_int 1)] 0)
7299    (use (reg:SI 29))
7300    (use (reg:SI 28))
7301    (clobber (reg:SI 31))
7302    (clobber (reg:SI 22))
7303    (clobber (reg:SI 21))
7304    (clobber (reg:SI 20))
7305    (clobber (reg:SI 19))
7306    (clobber (reg:SI 2))
7307    (clobber (reg:SI 1))]
7308   ""
7309   "*
7310 {
7311   extern int frame_pointer_needed;
7312
7313   /* We need two different versions depending on whether or not we
7314      need a frame pointer.   Also note that we return to the instruction
7315      immediately after the branch rather than two instructions after the
7316      break as normally is the case.  */
7317   if (frame_pointer_needed)
7318     {
7319       /* Must import the magic millicode routine.  */
7320       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
7321
7322       /* The out-of-line prologue will make sure we return to the right
7323          instruction.  */
7324       if (TARGET_PORTABLE_RUNTIME)
7325         {
7326           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
7327           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
7328                            NULL);
7329         }
7330       else
7331         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
7332     }
7333   else
7334     {
7335       /* Must import the magic millicode routine.  */
7336       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
7337
7338       /* The out-of-line prologue will make sure we return to the right
7339          instruction.  */
7340       if (TARGET_PORTABLE_RUNTIME)
7341         {
7342           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
7343           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
7344         }
7345       else
7346         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
7347     }
7348   return \"\";
7349 }"
7350   [(set_attr "type" "multi")
7351    (set_attr "length" "8")])
7352
7353 ;; Given a function pointer, canonicalize it so it can be 
7354 ;; reliably compared to another function pointer.  */
7355 (define_expand "canonicalize_funcptr_for_compare"
7356   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
7357    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7358               (clobber (match_dup 2))
7359               (clobber (reg:SI 26))
7360               (clobber (reg:SI 22))
7361               (clobber (reg:SI 31))])
7362    (set (match_operand:SI 0 "register_operand" "")
7363         (reg:SI 29))]
7364   "! TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && !TARGET_ELF32"
7365   "
7366 {
7367   operands[2] = gen_reg_rtx (SImode);
7368   if (GET_CODE (operands[1]) != REG)
7369     {
7370       rtx tmp = gen_reg_rtx (Pmode);
7371       emit_move_insn (tmp, operands[1]);
7372       operands[1] = tmp;
7373     }
7374 }")
7375
7376 (define_insn ""
7377   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
7378    (clobber (match_operand:SI 0 "register_operand" "=a"))
7379    (clobber (reg:SI 26))
7380    (clobber (reg:SI 22))
7381    (clobber (reg:SI 31))]
7382   "!TARGET_64BIT"
7383   "*
7384 {
7385   /* Must import the magic millicode routine.  */
7386   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
7387
7388   /* This is absolutely amazing.
7389
7390      First, copy our input parameter into %r29 just in case we don't
7391      need to call $$sh_func_adrs.  */
7392   output_asm_insn (\"copy %%r26,%%r29\", NULL);
7393
7394   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
7395      we use %r26 unchanged.  */
7396   if (get_attr_length (insn) == 32)
7397     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
7398   else if (get_attr_length (insn) == 40)
7399     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
7400   else if (get_attr_length (insn) == 44)
7401     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
7402   else
7403     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
7404
7405   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
7406      4096, then we use %r26 unchanged.  */
7407   if (get_attr_length (insn) == 32)
7408     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
7409                      NULL);
7410   else if (get_attr_length (insn) == 40)
7411     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
7412                      NULL);
7413   else if (get_attr_length (insn) == 44)
7414     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
7415                      NULL);
7416   else
7417     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
7418                      NULL);
7419
7420   /* Else call $$sh_func_adrs to extract the function's real add24.  */
7421   return output_millicode_call (insn,
7422                                 gen_rtx_SYMBOL_REF (SImode,
7423                                          \"$$sh_func_adrs\"));
7424 }"
7425   [(set_attr "type" "multi")
7426    (set (attr "length")
7427      (cond [
7428 ;; Target (or stub) within reach
7429             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
7430                      (const_int 240000))
7431                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
7432                      (const_int 0)))
7433             (const_int 28)
7434
7435 ;; Out of reach PIC
7436             (ne (symbol_ref "flag_pic")
7437                 (const_int 0))
7438             (const_int 44)
7439
7440 ;; Out of reach PORTABLE_RUNTIME
7441             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
7442                 (const_int 0))
7443             (const_int 40)]
7444
7445 ;; Out of reach, can use ble
7446           (const_int 32)))])
7447
7448 ;; On the PA, the PIC register is call clobbered, so it must
7449 ;; be saved & restored around calls by the caller.  If the call
7450 ;; doesn't return normally (nonlocal goto, or an exception is
7451 ;; thrown), then the code at the exception handler label must
7452 ;; restore the PIC register.
7453 (define_expand "exception_receiver"
7454   [(const_int 4)]
7455   "flag_pic"
7456   "
7457 {
7458   /* On the 64-bit port, we need a blockage because there is
7459      confusion regarding the dependence of the restore on the
7460      frame pointer.  As a result, the frame pointer and pic
7461      register restores sometimes are interchanged erroneously.  */
7462   if (TARGET_64BIT)
7463     emit_insn (gen_blockage ());
7464   /* Restore the PIC register using hppa_pic_save_rtx ().  The
7465      PIC register is not saved in the frame in 64-bit ABI.  */
7466   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
7467   DONE;
7468 }")
7469
7470 (define_expand "builtin_setjmp_receiver"
7471   [(label_ref (match_operand 0 "" ""))]
7472   "flag_pic"
7473   "
7474 {
7475   if (TARGET_64BIT)
7476     emit_insn (gen_blockage ());
7477   /* Restore the PIC register.  Hopefully, this will always be from
7478      a stack slot.  The only registers that are valid after a
7479      builtin_longjmp are the stack and frame pointers.  */
7480   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
7481   DONE;
7482 }")