OSDN Git Service

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