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