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