pa.md revision 1.1.1.16
1;;- Machine description for HP PA-RISC architecture for GCC compiler
2;;   Copyright (C) 1992-2020 Free Software Foundation, Inc.
3;;   Contributed by the Center for Software Science at the University
4;;   of Utah.
5
6;; This file is part of GCC.
7
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 3, or (at your option)
11;; any later version.
12
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.
21
22;; This machine description is inspired by sparc.md and to a lesser
23;; extent mips.md.
24
25;; Possible improvements:
26;;
27;; * With PA1.1, most computational instructions can conditionally nullify
28;;   the execution of the following instruction.  A nullified instruction
29;;   does not cause the instruction pipeline to stall, making it a very
30;;   efficient alternative to e.g. branching or conditional moves.
31;;
32;;   Nullification is performed conditionally based on the outcome of a
33;;   test specified in the opcode.  The test result is stored in PSW[N]
34;;   and can only be used to nullify the instruction following immediately
35;;   after the test.  For example:
36;;
37;;	ldi 10,%r26
38;;	ldi 5,%r25
39;;	sub,< %r26,%r25,%r28
40;;	sub   %r28,%r25,%r28	; %r28 == 0
41;;	sub,> %r26,%r25,%r29
42;;	sub   %r29,%r25,%r29	; %r29 == 5
43;;
44;;   This could be tricky to implement because the result of the test has
45;;   to be propagated one instruction forward, which, in the worst case,
46;;   would involve (1) adding a fake register for PSW[N]; (2) adding the
47;;   variants of the computational instructions that set or consume this
48;;   fake register.  The cond_exec infrastructure is probably not helpful
49;;   for this.
50;;
51;; * PA-RISC includes a set of conventions for branch instruction usage
52;;   to indicate whether a particular branch is more likely to be taken
53;;   or not taken.  For example, the prediction for CMPB instructions
54;;   (CMPB,cond,n r1,r2,target) depends on the direction of the branch
55;;   (forward or backward) and on the order of the operands:
56;;
57;;     | branch    | operand  | branch     |
58;;     | direction | compare  | prediction |
59;;     +-----------+----------+------------+
60;;     | backward  | r1 < r2  | taken      |
61;;     | backward  | r1 >= r2 | not taken  |
62;;     | forward   | r1 < r2  | not taken  |
63;;     | forward   | r1 >= r2 | taken      |
64;;    
65;;   By choosing instructions and operand order carefully, the compiler
66;;   could give the CPU branch predictor some help.
67;;   
68
69;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
70
71;; Uses of UNSPEC in this file:
72
73(define_c_enum "unspec"
74  [UNSPEC_CFFC		; canonicalize_funcptr_for_compare
75   UNSPEC_GOTO		; indirect_goto
76   UNSPEC_DLTIND14R
77   UNSPEC_TP
78   UNSPEC_TLSGD
79   UNSPEC_TLSLDM
80   UNSPEC_TLSLDO
81   UNSPEC_TLSLDBASE
82   UNSPEC_TLSIE
83   UNSPEC_TLSLE 
84   UNSPEC_TLSGD_PIC
85   UNSPEC_TLSLDM_PIC
86   UNSPEC_TLSIE_PIC
87   UNSPEC_MEMORY_BARRIER
88  ])
89
90;; UNSPEC_VOLATILE:
91
92(define_c_enum "unspecv"
93  [UNSPECV_BLOCKAGE	; blockage
94   UNSPECV_DCACHE	; dcacheflush
95   UNSPECV_ICACHE	; icacheflush
96   UNSPECV_OPC		; outline_prologue_call
97   UNSPECV_OEC		; outline_epilogue_call
98   UNSPECV_LONGJMP	; builtin_longjmp
99  ])
100
101;; Maximum pc-relative branch offsets.
102
103;; These numbers are a bit smaller than the maximum allowable offsets
104;; so that a few instructions may be inserted before the actual branch.
105
106(define_constants
107  [(MAX_12BIT_OFFSET     8184)	; 12-bit branch
108   (MAX_17BIT_OFFSET   262100)	; 17-bit branch
109  ])
110
111;; Mode and code iterators
112
113;; This mode iterator allows :P to be used for patterns that operate on
114;; pointer-sized quantities.  Exactly one of the two alternatives will match.
115(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
116
117;; This attribute defines the condition prefix for word and double word
118;; add, compare, subtract and logical instructions.
119(define_mode_attr dwc [(SI "") (DI "*")])
120
121;; Insn type.  Used to default other attribute values.
122
123;; type "unary" insns have one input operand (1) and one output operand (0)
124;; type "binary" insns have two input operands (1,2) and one output (0)
125
126(define_attr "type"
127  "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload,trap"
128  (const_string "binary"))
129
130(define_attr "pa_combine_type"
131  "fmpy,faddsub,uncond_branch,addmove,none"
132  (const_string "none"))
133
134;; Processor type (for scheduling, not code generation) -- this attribute
135;; must exactly match the processor_type enumeration in pa.h.
136;;
137;; FIXME: Add 800 scheduling for completeness?
138
139(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
140
141;; Length (in # of bytes).
142(define_attr "length" ""
143  (cond [(eq_attr "type" "load,fpload")
144	 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
145		       (const_int 8) (const_int 4))
146
147	 (eq_attr "type" "store,fpstore")
148	 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
149		       (const_int 8) (const_int 4))
150
151	 (eq_attr "type" "binary,shift,nullshift")
152	 (if_then_else (match_operand 2 "arith14_operand" "")
153		       (const_int 4) (const_int 12))
154
155	 (eq_attr "type" "move,unary,shift,nullshift")
156	 (if_then_else (match_operand 1 "arith14_operand" "")
157		       (const_int 4) (const_int 8))]
158
159	(const_int 4)))
160
161(define_asm_attributes
162  [(set_attr "length" "4")
163   (set_attr "type" "multi")])
164
165;; Attributes for instruction and branch scheduling
166
167;; For conditional branches. Frame related instructions are not allowed
168;; because they confuse the unwind support.
169(define_attr "in_branch_delay" "false,true"
170  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
171		     (eq_attr "length" "4")
172		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
173		(const_string "true")
174		(const_string "false")))
175
176;; Disallow instructions which use the FPU since they will tie up the FPU
177;; even if the instruction is nullified.
178(define_attr "in_nullified_branch_delay" "false,true"
179  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch,trap")
180		     (eq_attr "length" "4")
181		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
182		(const_string "true")
183		(const_string "false")))
184
185;; For calls and millicode calls.
186(define_attr "in_call_delay" "false,true"
187  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
188		     (eq_attr "length" "4")
189		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
190		(const_string "true")
191		(const_string "false")))
192
193;; Call delay slot description.
194(define_delay (eq_attr "type" "call")
195  [(eq_attr "in_call_delay" "true") (nil) (nil)])
196
197;; Sibcall delay slot description.
198(define_delay (eq_attr "type" "sibcall")
199  [(eq_attr "in_call_delay" "true") (nil) (nil)])
200
201;; Millicode call delay slot description.
202(define_delay (eq_attr "type" "milli")
203  [(eq_attr "in_call_delay" "true") (nil) (nil)])
204
205;; Return and other similar instructions.
206(define_delay (eq_attr "type" "branch,parallel_branch")
207  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
208
209;; Floating point conditional branch delay slot description.
210(define_delay (eq_attr "type" "fbranch")
211  [(eq_attr "in_branch_delay" "true")
212   (eq_attr "in_nullified_branch_delay" "true")
213   (nil)])
214
215;; Integer conditional branch delay slot description.
216;; Nullification of conditional branches on the PA is dependent on the
217;; direction of the branch.  Forward branches nullify true and
218;; backward branches nullify false.  If the direction is unknown
219;; then nullification is not allowed.
220(define_delay (eq_attr "type" "cbranch")
221  [(eq_attr "in_branch_delay" "true")
222   (and (eq_attr "in_nullified_branch_delay" "true")
223	(attr_flag "forward"))
224   (and (eq_attr "in_nullified_branch_delay" "true")
225	(attr_flag "backward"))])
226
227(define_delay (eq_attr "type" "uncond_branch")
228  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
229
230;; Memory. Disregarding Cache misses, the Mustang memory times are:
231;; load: 2, fpload: 3
232;; store, fpstore: 3, no D-cache operations should be scheduled.
233
234;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
235;; Timings:
236;; Instruction	Time	Unit	Minimum Distance (unit contention)
237;; fcpy		3	ALU	2
238;; fabs		3	ALU	2
239;; fadd		3	ALU	2
240;; fsub		3	ALU	2
241;; fcmp		3	ALU	2
242;; fcnv		3	ALU	2
243;; fmpyadd	3	ALU,MPY	2
244;; fmpysub	3	ALU,MPY 2
245;; fmpycfxt	3	ALU,MPY 2
246;; fmpy		3	MPY	2
247;; fmpyi	3	MPY	2
248;; fdiv,sgl	10	MPY	10
249;; fdiv,dbl	12	MPY	12
250;; fsqrt,sgl	14	MPY	14
251;; fsqrt,dbl	18	MPY	18
252;;
253;; We don't model fmpyadd/fmpysub properly as those instructions
254;; keep both the FP ALU and MPY units busy.  Given that these
255;; processors are obsolete, I'm not going to spend the time to
256;; model those instructions correctly.
257
258(define_automaton "pa700")
259(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
260
261(define_insn_reservation "W0" 4
262  (and (eq_attr "type" "fpcc")
263       (eq_attr "cpu" "700"))
264  "fpalu_700*2")
265
266(define_insn_reservation "W1" 3
267  (and (eq_attr "type" "fpalu")
268       (eq_attr "cpu" "700"))
269  "fpalu_700*2")
270
271(define_insn_reservation "W2" 3
272  (and (eq_attr "type" "fpmulsgl,fpmuldbl")
273       (eq_attr "cpu" "700"))
274  "fpmpy_700*2")
275
276(define_insn_reservation "W3" 10
277  (and (eq_attr "type" "fpdivsgl")
278       (eq_attr "cpu" "700"))
279  "fpmpy_700*10")
280
281(define_insn_reservation "W4" 12
282  (and (eq_attr "type" "fpdivdbl")
283       (eq_attr "cpu" "700"))
284  "fpmpy_700*12")
285
286(define_insn_reservation "W5" 14
287  (and (eq_attr "type" "fpsqrtsgl")
288       (eq_attr "cpu" "700"))
289  "fpmpy_700*14")
290
291(define_insn_reservation "W6" 18
292  (and (eq_attr "type" "fpsqrtdbl")
293       (eq_attr "cpu" "700"))
294  "fpmpy_700*18")
295
296(define_insn_reservation "W7" 2
297  (and (eq_attr "type" "load")
298       (eq_attr "cpu" "700"))
299  "mem_700")
300
301(define_insn_reservation "W8" 2
302  (and (eq_attr "type" "fpload")
303       (eq_attr "cpu" "700"))
304  "mem_700")
305
306(define_insn_reservation "W9" 3
307  (and (eq_attr "type" "store")
308       (eq_attr "cpu" "700"))
309  "mem_700*3")
310
311(define_insn_reservation "W10" 3
312  (and (eq_attr "type" "fpstore")
313       (eq_attr "cpu" "700"))
314  "mem_700*3")
315
316(define_insn_reservation "W11" 5
317  (and (eq_attr "type" "fpstore_load")
318       (eq_attr "cpu" "700"))
319  "mem_700*5")
320
321(define_insn_reservation "W12" 6
322  (and (eq_attr "type" "store_fpload")
323       (eq_attr "cpu" "700"))
324  "mem_700*6")
325
326(define_insn_reservation "W13" 1
327  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
328       (eq_attr "cpu" "700"))
329  "dummy_700")
330
331;; We have a bypass for all computations in the FP unit which feed an
332;; FP store as long as the sizes are the same.
333(define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
334(define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
335(define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
336(define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
337(define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
338
339;; We have an "anti-bypass" for FP loads which feed an FP store.
340(define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
341
342;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
343;; floating point computations with non-floating point computations (fp loads
344;; and stores are not fp computations).
345;;
346;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
347;; take two cycles, during which no Dcache operations should be scheduled.
348;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
349;; all have the same memory characteristics if one disregards cache misses.
350;;
351;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
352;; There's no value in modeling the ALU and MUL separately though
353;; since there can never be a functional unit conflict given the
354;; latency and issue rates for those units.
355;;
356;; Timings:
357;; Instruction	Time	Unit	Minimum Distance (unit contention)
358;; fcpy		2	ALU	1
359;; fabs		2	ALU	1
360;; fadd		2	ALU	1
361;; fsub		2	ALU	1
362;; fcmp		2	ALU	1
363;; fcnv		2	ALU	1
364;; fmpyadd	2	ALU,MPY	1
365;; fmpysub	2	ALU,MPY 1
366;; fmpycfxt	2	ALU,MPY 1
367;; fmpy		2	MPY	1
368;; fmpyi	2	MPY	1
369;; fdiv,sgl	8	DIV	8
370;; fdiv,dbl	15	DIV	15
371;; fsqrt,sgl	8	DIV	8
372;; fsqrt,dbl	15	DIV	15
373
374(define_automaton "pa7100")
375(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
376
377(define_insn_reservation "X0" 2
378  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
379       (eq_attr "cpu" "7100"))
380  "f_7100,fpmac_7100")
381
382(define_insn_reservation "X1" 8
383  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
384       (eq_attr "cpu" "7100"))
385  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
386
387(define_insn_reservation "X2" 15
388  (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
389       (eq_attr "cpu" "7100"))
390  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
391
392(define_insn_reservation "X3" 2
393  (and (eq_attr "type" "load")
394       (eq_attr "cpu" "7100"))
395  "i_7100+mem_7100")
396
397(define_insn_reservation "X4" 2
398  (and (eq_attr "type" "fpload")
399       (eq_attr "cpu" "7100"))
400  "i_7100+mem_7100")
401
402(define_insn_reservation "X5" 2
403  (and (eq_attr "type" "store")
404       (eq_attr "cpu" "7100"))
405  "i_7100+mem_7100,mem_7100")
406
407(define_insn_reservation "X6" 2
408  (and (eq_attr "type" "fpstore")
409       (eq_attr "cpu" "7100"))
410  "i_7100+mem_7100,mem_7100")
411
412(define_insn_reservation "X7" 4
413  (and (eq_attr "type" "fpstore_load")
414       (eq_attr "cpu" "7100"))
415  "i_7100+mem_7100,mem_7100*3")
416
417(define_insn_reservation "X8" 4
418  (and (eq_attr "type" "store_fpload")
419       (eq_attr "cpu" "7100"))
420  "i_7100+mem_7100,mem_7100*3")
421
422(define_insn_reservation "X9" 1
423  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
424       (eq_attr "cpu" "7100"))
425  "i_7100")
426
427;; We have a bypass for all computations in the FP unit which feed an
428;; FP store as long as the sizes are the same.
429(define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
430(define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
431(define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
432
433;; We have an "anti-bypass" for FP loads which feed an FP store.
434(define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
435
436;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
437;; There's no value in modeling the ALU and MUL separately though
438;; since there can never be a functional unit conflict that
439;; can be avoided given the latency, issue rates and mandatory
440;; one cycle cpu-wide lock for a double precision fp multiply.
441;;
442;; Timings:
443;; Instruction	Time	Unit	Minimum Distance (unit contention)
444;; fcpy		2	ALU	1
445;; fabs		2	ALU	1
446;; fadd		2	ALU	1
447;; fsub		2	ALU	1
448;; fcmp		2	ALU	1
449;; fcnv		2	ALU	1
450;; fmpyadd,sgl	2	ALU,MPY	1
451;; fmpyadd,dbl	3	ALU,MPY	2
452;; fmpysub,sgl	2	ALU,MPY 1
453;; fmpysub,dbl	3	ALU,MPY 2
454;; fmpycfxt,sgl	2	ALU,MPY 1
455;; fmpycfxt,dbl	3	ALU,MPY 2
456;; fmpy,sgl	2	MPY	1
457;; fmpy,dbl	3	MPY	2
458;; fmpyi	3	MPY	2
459;; fdiv,sgl	8	DIV	8
460;; fdiv,dbl	15	DIV	15
461;; fsqrt,sgl	8	DIV	8
462;; fsqrt,dbl	15	DIV	15
463;;
464;; The PA7200 is just like the PA7100LC except that there is
465;; no store-store penalty.
466;;
467;; The PA7300 is just like the PA7200 except that there is
468;; no store-load penalty.
469;;
470;; Note there are some aspects of the 7100LC we are not modeling
471;; at the moment.  I'll be reviewing the 7100LC scheduling info
472;; shortly and updating this description.
473;;
474;;   load-load pairs
475;;   store-store pairs
476;;   other issue modeling
477
478(define_automaton "pa7100lc")
479(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
480(define_cpu_unit "fpmac_7100lc" "pa7100lc")
481(define_cpu_unit "mem_7100lc" "pa7100lc")
482
483;; Double precision multiplies lock the entire CPU for one
484;; cycle.  There is no way to avoid this lock and trying to
485;; schedule around the lock is pointless and thus there is no
486;; value in trying to model this lock.
487;;
488;; Not modeling the lock allows us to treat fp multiplies just
489;; like any other FP alu instruction.  It allows for a smaller
490;; DFA and may reduce register pressure.
491(define_insn_reservation "Y0" 2
492  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
493       (eq_attr "cpu" "7100LC,7200,7300"))
494  "f_7100lc,fpmac_7100lc")
495
496;; fp division and sqrt instructions lock the entire CPU for
497;; 7 cycles (single precision) or 14 cycles (double precision).
498;; There is no way to avoid this lock and trying to schedule
499;; around the lock is pointless and thus there is no value in
500;; trying to model this lock.  Not modeling the lock allows
501;; for a smaller DFA and may reduce register pressure.
502(define_insn_reservation "Y1" 1
503  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
504       (eq_attr "cpu" "7100LC,7200,7300"))
505  "f_7100lc")
506
507(define_insn_reservation "Y2" 2
508  (and (eq_attr "type" "load")
509       (eq_attr "cpu" "7100LC,7200,7300"))
510  "i1_7100lc+mem_7100lc")
511
512(define_insn_reservation "Y3" 2
513  (and (eq_attr "type" "fpload")
514       (eq_attr "cpu" "7100LC,7200,7300"))
515  "i1_7100lc+mem_7100lc")
516
517(define_insn_reservation "Y4" 2
518  (and (eq_attr "type" "store")
519       (eq_attr "cpu" "7100LC"))
520  "i1_7100lc+mem_7100lc,mem_7100lc")
521
522(define_insn_reservation "Y5" 2
523  (and (eq_attr "type" "fpstore")
524       (eq_attr "cpu" "7100LC"))
525  "i1_7100lc+mem_7100lc,mem_7100lc")
526
527(define_insn_reservation "Y6" 4
528  (and (eq_attr "type" "fpstore_load")
529       (eq_attr "cpu" "7100LC"))
530  "i1_7100lc+mem_7100lc,mem_7100lc*3")
531
532(define_insn_reservation "Y7" 4
533  (and (eq_attr "type" "store_fpload")
534       (eq_attr "cpu" "7100LC"))
535  "i1_7100lc+mem_7100lc,mem_7100lc*3")
536
537(define_insn_reservation "Y8" 1
538  (and (eq_attr "type" "shift,nullshift")
539       (eq_attr "cpu" "7100LC,7200,7300"))
540  "i1_7100lc")
541
542(define_insn_reservation "Y9" 1
543  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
544       (eq_attr "cpu" "7100LC,7200,7300"))
545  "(i0_7100lc|i1_7100lc)")
546
547;; The 7200 has a store-load penalty
548(define_insn_reservation "Y10" 2
549  (and (eq_attr "type" "store")
550       (eq_attr "cpu" "7200"))
551  "i1_7100lc,mem_7100lc")
552
553(define_insn_reservation "Y11" 2
554  (and (eq_attr "type" "fpstore")
555       (eq_attr "cpu" "7200"))
556  "i1_7100lc,mem_7100lc")
557
558(define_insn_reservation "Y12" 4
559  (and (eq_attr "type" "fpstore_load")
560       (eq_attr "cpu" "7200"))
561  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
562
563(define_insn_reservation "Y13" 4
564  (and (eq_attr "type" "store_fpload")
565       (eq_attr "cpu" "7200"))
566  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
567
568;; The 7300 has no penalty for store-store or store-load
569(define_insn_reservation "Y14" 2
570  (and (eq_attr "type" "store")
571       (eq_attr "cpu" "7300"))
572  "i1_7100lc")
573
574(define_insn_reservation "Y15" 2
575  (and (eq_attr "type" "fpstore")
576       (eq_attr "cpu" "7300"))
577  "i1_7100lc")
578
579(define_insn_reservation "Y16" 4
580  (and (eq_attr "type" "fpstore_load")
581       (eq_attr "cpu" "7300"))
582  "i1_7100lc,i1_7100lc+mem_7100lc")
583
584(define_insn_reservation "Y17" 4
585  (and (eq_attr "type" "store_fpload")
586       (eq_attr "cpu" "7300"))
587  "i1_7100lc,i1_7100lc+mem_7100lc")
588
589;; We have an "anti-bypass" for FP loads which feed an FP store.
590(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
591
592;; Scheduling for the PA8000 is somewhat different than scheduling for a
593;; traditional architecture.
594;;
595;; The PA8000 has a large (56) entry reorder buffer that is split between
596;; memory and non-memory operations.
597;;
598;; The PA8000 can issue two memory and two non-memory operations per cycle to
599;; the function units, with the exception of branches and multi-output
600;; instructions.  The PA8000 can retire two non-memory operations per cycle
601;; and two memory operations per cycle, only one of which may be a store.
602;;
603;; Given the large reorder buffer, the processor can hide most latencies.
604;; According to HP, they've got the best results by scheduling for retirement
605;; bandwidth with limited latency scheduling for floating point operations.
606;; Latency for integer operations and memory references is ignored.
607;;
608;;
609;; We claim floating point operations have a 2 cycle latency and are
610;; fully pipelined, except for div and sqrt which are not pipelined and
611;; take from 17 to 31 cycles to complete.
612;;
613;; It's worth noting that there is no way to saturate all the functional
614;; units on the PA8000 as there is not enough issue bandwidth.
615
616(define_automaton "pa8000")
617(define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
618(define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
619(define_cpu_unit "store_8000" "pa8000")
620(define_cpu_unit "f0_8000, f1_8000" "pa8000")
621(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
622(define_reservation "inm_8000" "inm0_8000 | inm1_8000")
623(define_reservation "im_8000" "im0_8000 | im1_8000")
624(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
625(define_reservation "rm_8000" "rm0_8000 | rm1_8000")
626(define_reservation "f_8000" "f0_8000 | f1_8000")
627(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
628
629;; We can issue any two memops per cycle, but we can only retire
630;; one memory store per cycle.  We assume that the reorder buffer
631;; will hide any memory latencies per HP's recommendation.
632(define_insn_reservation "Z0" 0
633  (and
634    (eq_attr "type" "load,fpload")
635    (eq_attr "cpu" "8000"))
636  "im_8000,rm_8000")
637
638(define_insn_reservation "Z1" 0
639  (and
640    (eq_attr "type" "store,fpstore")
641    (eq_attr "cpu" "8000"))
642  "im_8000,rm_8000+store_8000")
643
644(define_insn_reservation "Z2" 0
645  (and (eq_attr "type" "fpstore_load,store_fpload")
646       (eq_attr "cpu" "8000"))
647  "im_8000,rm_8000+store_8000,im_8000,rm_8000")
648
649;; We can issue and retire two non-memory operations per cycle with
650;; a few exceptions (branches).  This group catches those we want
651;; to assume have zero latency.
652(define_insn_reservation "Z3" 0
653  (and
654    (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload")
655    (eq_attr "cpu" "8000"))
656  "inm_8000,rnm_8000")
657
658;; Branches use both slots in the non-memory issue and
659;; retirement unit.
660(define_insn_reservation "Z4" 0
661  (and
662    (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
663    (eq_attr "cpu" "8000"))
664  "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
665
666;; We partial latency schedule the floating point units.
667;; They can issue/retire two at a time in the non-memory
668;; units.  We fix their latency at 2 cycles and they
669;; are fully pipelined.
670(define_insn_reservation "Z5" 1
671 (and
672   (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
673   (eq_attr "cpu" "8000"))
674 "inm_8000,f_8000,rnm_8000")
675
676;; The fdivsqrt units are not pipelined and have a very long latency.  
677;; To keep the DFA from exploding, we do not show all the
678;; reservations for the divsqrt unit.
679(define_insn_reservation "Z6" 17
680 (and
681   (eq_attr "type" "fpdivsgl,fpsqrtsgl")
682   (eq_attr "cpu" "8000"))
683 "inm_8000,fdivsqrt_8000*6,rnm_8000")
684
685(define_insn_reservation "Z7" 31
686 (and
687   (eq_attr "type" "fpdivdbl,fpsqrtdbl")
688   (eq_attr "cpu" "8000"))
689 "inm_8000,fdivsqrt_8000*6,rnm_8000")
690
691;; Operand and operator predicates and constraints
692
693(include "predicates.md")
694(include "constraints.md")
695
696;; Compare instructions.
697;; This controls RTL generation and register allocation.
698
699(define_insn ""
700  [(set (reg:CCFP 0)
701	(match_operator:CCFP 2 "comparison_operator"
702			     [(match_operand:SF 0 "reg_or_0_operand" "fG")
703			      (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
704  "! TARGET_SOFT_FLOAT"
705  "fcmp,sgl,%Y2 %f0,%f1"
706  [(set_attr "length" "4")
707   (set_attr "type" "fpcc")])
708
709(define_insn ""
710  [(set (reg:CCFP 0)
711	(match_operator:CCFP 2 "comparison_operator"
712			     [(match_operand:DF 0 "reg_or_0_operand" "fG")
713			      (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
714  "! TARGET_SOFT_FLOAT"
715  "fcmp,dbl,%Y2 %f0,%f1"
716  [(set_attr "length" "4")
717   (set_attr "type" "fpcc")])
718
719;; Provide a means to emit the movccfp0 and movccfp1 optimization
720;; placeholders.  This is necessary in rare situations when a
721;; placeholder is re-emitted (see PR 8705).
722
723(define_expand "movccfp"
724  [(set (reg:CCFP 0)
725	(match_operand 0 "const_int_operand" ""))]
726  "! TARGET_SOFT_FLOAT"
727  "
728{
729  if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
730    FAIL;
731}")
732
733;; The following patterns are optimization placeholders.  In almost
734;; all cases, the user of the condition code will be simplified and the
735;; original condition code setting insn should be eliminated.
736
737(define_insn "*movccfp0"
738  [(set (reg:CCFP 0)
739	(const_int 0))]
740  "! TARGET_SOFT_FLOAT"
741  "fcmp,dbl,= %%fr0,%%fr0"
742  [(set_attr "length" "4")
743   (set_attr "type" "fpcc")])
744
745(define_insn "*movccfp1"
746  [(set (reg:CCFP 0)
747	(const_int 1))]
748  "! TARGET_SOFT_FLOAT"
749  "fcmp,dbl,!= %%fr0,%%fr0"
750  [(set_attr "length" "4")
751   (set_attr "type" "fpcc")])
752
753;; scc insns.
754
755(define_expand "cstoresi4"
756  [(set (match_operand:SI 0 "register_operand")
757	(match_operator:SI 1 "ordered_comparison_operator"
758	 [(match_operand:SI 2 "reg_or_0_operand" "")
759	  (match_operand:SI 3 "arith5_operand" "")]))]
760  "!TARGET_64BIT"
761  "")
762
763;; Instruction canonicalization puts immediate operands second, which
764;; is the reverse of what we want.
765
766(define_insn "scc"
767  [(set (match_operand:SI 0 "register_operand" "=r")
768	(match_operator:SI 3 "ordered_comparison_operator"
769			   [(match_operand:SI 1 "reg_or_0_operand" "rM")
770			    (match_operand:SI 2 "arith11_operand" "rI")]))]
771  ""
772  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
773  [(set_attr "type" "binary")
774   (set_attr "length" "8")])
775
776(define_insn ""
777  [(set (match_operand:DI 0 "register_operand" "=r")
778	(match_operator:DI 3 "ordered_comparison_operator"
779			   [(match_operand:DI 1 "reg_or_0_operand" "rM")
780			    (match_operand:DI 2 "arith11_operand" "rI")]))]
781  "TARGET_64BIT"
782  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
783  [(set_attr "type" "binary")
784   (set_attr "length" "8")])
785
786(define_insn "iorscc"
787  [(set (match_operand:SI 0 "register_operand" "=r")
788	(ior:SI (match_operator:SI 3 "ordered_comparison_operator"
789				   [(match_operand:SI 1 "reg_or_0_operand" "rM")
790				    (match_operand:SI 2 "arith11_operand" "rI")])
791		(match_operator:SI 6 "ordered_comparison_operator"
792				   [(match_operand:SI 4 "reg_or_0_operand" "rM")
793				    (match_operand:SI 5 "arith11_operand" "rI")])))]
794  ""
795  "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
796  [(set_attr "type" "binary")
797   (set_attr "length" "12")])
798
799(define_insn ""
800  [(set (match_operand:DI 0 "register_operand" "=r")
801	(ior:DI (match_operator:DI 3 "ordered_comparison_operator"
802				   [(match_operand:DI 1 "reg_or_0_operand" "rM")
803				    (match_operand:DI 2 "arith11_operand" "rI")])
804		(match_operator:DI 6 "ordered_comparison_operator"
805				   [(match_operand:DI 4 "reg_or_0_operand" "rM")
806				    (match_operand:DI 5 "arith11_operand" "rI")])))]
807  "TARGET_64BIT"
808  "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
809  [(set_attr "type" "binary")
810   (set_attr "length" "12")])
811
812;; Combiner patterns for common operations performed with the output
813;; from an scc insn (negscc and incscc).
814(define_insn "negscc"
815  [(set (match_operand:SI 0 "register_operand" "=r")
816	(neg:SI (match_operator:SI 3 "ordered_comparison_operator"
817	       [(match_operand:SI 1 "reg_or_0_operand" "rM")
818		(match_operand:SI 2 "arith11_operand" "rI")])))]
819  ""
820  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
821  [(set_attr "type" "binary")
822   (set_attr "length" "8")])
823
824(define_insn ""
825  [(set (match_operand:DI 0 "register_operand" "=r")
826	(neg:DI (match_operator:DI 3 "ordered_comparison_operator"
827	       [(match_operand:DI 1 "reg_or_0_operand" "rM")
828		(match_operand:DI 2 "arith11_operand" "rI")])))]
829  "TARGET_64BIT"
830  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
831  [(set_attr "type" "binary")
832   (set_attr "length" "8")])
833
834;; Patterns for adding/subtracting the result of a boolean expression from
835;; a register.  First we have special patterns that make use of the carry
836;; bit, and output only two instructions.  For the cases we can't in
837;; general do in two instructions, the incscc pattern at the end outputs
838;; two or three instructions.
839
840(define_insn ""
841  [(set (match_operand:SI 0 "register_operand" "=r")
842	(plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
843			 (match_operand:SI 3 "arith11_operand" "rI"))
844		 (match_operand:SI 1 "register_operand" "r")))]
845  ""
846  "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
847  [(set_attr "type" "binary")
848   (set_attr "length" "8")])
849
850(define_insn ""
851  [(set (match_operand:DI 0 "register_operand" "=r")
852	(plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
853			 (match_operand:DI 3 "arith11_operand" "rI"))
854		 (match_operand:DI 1 "register_operand" "r")))]
855  "TARGET_64BIT"
856  "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
857  [(set_attr "type" "binary")
858   (set_attr "length" "8")])
859
860; This need only accept registers for op3, since canonicalization
861; replaces geu with gtu when op3 is an integer.
862(define_insn ""
863  [(set (match_operand:SI 0 "register_operand" "=r")
864	(plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
865			 (match_operand:SI 3 "register_operand" "r"))
866		 (match_operand:SI 1 "register_operand" "r")))]
867  ""
868  "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
869  [(set_attr "type" "binary")
870   (set_attr "length" "8")])
871
872(define_insn ""
873  [(set (match_operand:DI 0 "register_operand" "=r")
874	(plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
875			 (match_operand:DI 3 "register_operand" "r"))
876		 (match_operand:DI 1 "register_operand" "r")))]
877  "TARGET_64BIT"
878  "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
879  [(set_attr "type" "binary")
880   (set_attr "length" "8")])
881
882; Match only integers for op3 here.  This is used as canonical form of the
883; geu pattern when op3 is an integer.  Don't match registers since we can't
884; make better code than the general incscc pattern.
885(define_insn ""
886  [(set (match_operand:SI 0 "register_operand" "=r")
887	(plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
888			 (match_operand:SI 3 "int11_operand" "I"))
889		 (match_operand:SI 1 "register_operand" "r")))]
890  ""
891  "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
892  [(set_attr "type" "binary")
893   (set_attr "length" "8")])
894
895(define_insn ""
896  [(set (match_operand:DI 0 "register_operand" "=r")
897	(plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
898			 (match_operand:DI 3 "int11_operand" "I"))
899		 (match_operand:DI 1 "register_operand" "r")))]
900  "TARGET_64BIT"
901  "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
902  [(set_attr "type" "binary")
903   (set_attr "length" "8")])
904
905(define_insn "incscc"
906  [(set (match_operand:SI 0 "register_operand" "=r,r")
907 	(plus:SI (match_operator:SI 4 "ordered_comparison_operator"
908		    [(match_operand:SI 2 "register_operand" "r,r")
909		     (match_operand:SI 3 "arith11_operand" "rI,rI")])
910		 (match_operand:SI 1 "register_operand" "0,?r")))]
911  ""
912  "@
913   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
914   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
915  [(set_attr "type" "binary,binary")
916   (set_attr "length" "8,12")])
917
918(define_insn ""
919  [(set (match_operand:DI 0 "register_operand" "=r,r")
920 	(plus:DI (match_operator:DI 4 "ordered_comparison_operator"
921		    [(match_operand:DI 2 "register_operand" "r,r")
922		     (match_operand:DI 3 "arith11_operand" "rI,rI")])
923		 (match_operand:DI 1 "register_operand" "0,?r")))]
924  "TARGET_64BIT"
925  "@
926   cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
927   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
928  [(set_attr "type" "binary,binary")
929   (set_attr "length" "8,12")])
930
931(define_insn ""
932  [(set (match_operand:SI 0 "register_operand" "=r")
933	(minus:SI (match_operand:SI 1 "register_operand" "r")
934		  (gtu:SI (match_operand:SI 2 "register_operand" "r")
935			  (match_operand:SI 3 "arith11_operand" "rI"))))]
936  ""
937  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
938  [(set_attr "type" "binary")
939   (set_attr "length" "8")])
940
941(define_insn ""
942  [(set (match_operand:DI 0 "register_operand" "=r")
943	(minus:DI (match_operand:DI 1 "register_operand" "r")
944		  (gtu:DI (match_operand:DI 2 "register_operand" "r")
945			  (match_operand:DI 3 "arith11_operand" "rI"))))]
946  "TARGET_64BIT"
947  "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
948  [(set_attr "type" "binary")
949   (set_attr "length" "8")])
950
951(define_insn ""
952  [(set (match_operand:SI 0 "register_operand" "=r")
953	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
954			    (gtu:SI (match_operand:SI 2 "register_operand" "r")
955				    (match_operand:SI 3 "arith11_operand" "rI")))
956		  (match_operand:SI 4 "register_operand" "r")))]
957  ""
958  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
959  [(set_attr "type" "binary")
960   (set_attr "length" "8")])
961
962(define_insn ""
963  [(set (match_operand:DI 0 "register_operand" "=r")
964	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
965			    (gtu:DI (match_operand:DI 2 "register_operand" "r")
966				    (match_operand:DI 3 "arith11_operand" "rI")))
967		  (match_operand:DI 4 "register_operand" "r")))]
968  "TARGET_64BIT"
969  "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
970  [(set_attr "type" "binary")
971   (set_attr "length" "8")])
972
973; This need only accept registers for op3, since canonicalization
974; replaces ltu with leu when op3 is an integer.
975(define_insn ""
976  [(set (match_operand:SI 0 "register_operand" "=r")
977	(minus:SI (match_operand:SI 1 "register_operand" "r")
978		  (ltu:SI (match_operand:SI 2 "register_operand" "r")
979			  (match_operand:SI 3 "register_operand" "r"))))]
980  ""
981  "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
982  [(set_attr "type" "binary")
983   (set_attr "length" "8")])
984
985(define_insn ""
986  [(set (match_operand:DI 0 "register_operand" "=r")
987	(minus:DI (match_operand:DI 1 "register_operand" "r")
988		  (ltu:DI (match_operand:DI 2 "register_operand" "r")
989			  (match_operand:DI 3 "register_operand" "r"))))]
990  "TARGET_64BIT"
991  "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
992  [(set_attr "type" "binary")
993   (set_attr "length" "8")])
994
995(define_insn ""
996  [(set (match_operand:SI 0 "register_operand" "=r")
997	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
998			    (ltu:SI (match_operand:SI 2 "register_operand" "r")
999				    (match_operand:SI 3 "register_operand" "r")))
1000		  (match_operand:SI 4 "register_operand" "r")))]
1001  ""
1002  "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1003  [(set_attr "type" "binary")
1004   (set_attr "length" "8")])
1005
1006(define_insn ""
1007  [(set (match_operand:DI 0 "register_operand" "=r")
1008	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1009			    (ltu:DI (match_operand:DI 2 "register_operand" "r")
1010				    (match_operand:DI 3 "register_operand" "r")))
1011		  (match_operand:DI 4 "register_operand" "r")))]
1012  "TARGET_64BIT"
1013  "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1014  [(set_attr "type" "binary")
1015   (set_attr "length" "8")])
1016
1017; Match only integers for op3 here.  This is used as canonical form of the
1018; ltu pattern when op3 is an integer.  Don't match registers since we can't
1019; make better code than the general incscc pattern.
1020(define_insn ""
1021  [(set (match_operand:SI 0 "register_operand" "=r")
1022	(minus:SI (match_operand:SI 1 "register_operand" "r")
1023		  (leu:SI (match_operand:SI 2 "register_operand" "r")
1024			  (match_operand:SI 3 "int11_operand" "I"))))]
1025  ""
1026  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1027  [(set_attr "type" "binary")
1028   (set_attr "length" "8")])
1029
1030(define_insn ""
1031  [(set (match_operand:DI 0 "register_operand" "=r")
1032	(minus:DI (match_operand:DI 1 "register_operand" "r")
1033		  (leu:DI (match_operand:DI 2 "register_operand" "r")
1034			  (match_operand:DI 3 "int11_operand" "I"))))]
1035  "TARGET_64BIT"
1036  "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1037  [(set_attr "type" "binary")
1038   (set_attr "length" "8")])
1039
1040(define_insn ""
1041  [(set (match_operand:SI 0 "register_operand" "=r")
1042	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1043			    (leu:SI (match_operand:SI 2 "register_operand" "r")
1044				    (match_operand:SI 3 "int11_operand" "I")))
1045		  (match_operand:SI 4 "register_operand" "r")))]
1046  ""
1047  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1048  [(set_attr "type" "binary")
1049   (set_attr "length" "8")])
1050
1051(define_insn ""
1052  [(set (match_operand:DI 0 "register_operand" "=r")
1053	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1054			    (leu:DI (match_operand:DI 2 "register_operand" "r")
1055				    (match_operand:DI 3 "int11_operand" "I")))
1056		  (match_operand:DI 4 "register_operand" "r")))]
1057  "TARGET_64BIT"
1058  "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1059  [(set_attr "type" "binary")
1060   (set_attr "length" "8")])
1061
1062(define_insn "decscc"
1063  [(set (match_operand:SI 0 "register_operand" "=r,r")
1064	(minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1065		  (match_operator:SI 4 "ordered_comparison_operator"
1066		     [(match_operand:SI 2 "register_operand" "r,r")
1067		      (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1068  ""
1069  "@
1070   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1071   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1072  [(set_attr "type" "binary,binary")
1073   (set_attr "length" "8,12")])
1074
1075(define_insn ""
1076  [(set (match_operand:DI 0 "register_operand" "=r,r")
1077	(minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1078		  (match_operator:DI 4 "ordered_comparison_operator"
1079		     [(match_operand:DI 2 "register_operand" "r,r")
1080		      (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1081  "TARGET_64BIT"
1082  "@
1083   cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1084   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1085  [(set_attr "type" "binary,binary")
1086   (set_attr "length" "8,12")])
1087
1088; Patterns for max and min.  (There is no need for an earlyclobber in the
1089; last alternative since the middle alternative will match if op0 == op1.)
1090
1091(define_insn "sminsi3"
1092  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1093	(smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1094		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1095  ""
1096  "@
1097  {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1098  {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1099  {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1100[(set_attr "type" "multi,multi,multi")
1101 (set_attr "length" "8,8,8")])
1102
1103(define_insn "smindi3"
1104  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1105	(smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1106		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1107  "TARGET_64BIT"
1108  "@
1109  cmpclr,*> %2,%0,%%r0\;copy %2,%0
1110  cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1111  cmpclr,*> %1,%r2,%0\;copy %1,%0"
1112[(set_attr "type" "multi,multi,multi")
1113 (set_attr "length" "8,8,8")])
1114
1115(define_insn "uminsi3"
1116  [(set (match_operand:SI 0 "register_operand" "=r,r")
1117	(umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1118		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1119  ""
1120  "@
1121  {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1122  {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1123[(set_attr "type" "multi,multi")
1124 (set_attr "length" "8,8")])
1125
1126(define_insn "umindi3"
1127  [(set (match_operand:DI 0 "register_operand" "=r,r")
1128	(umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1129		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1130  "TARGET_64BIT"
1131  "@
1132  cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1133  cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1134[(set_attr "type" "multi,multi")
1135 (set_attr "length" "8,8")])
1136
1137(define_insn "smaxsi3"
1138  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1139	(smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1140		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1141  ""
1142  "@
1143  {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1144  {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1145  {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1146[(set_attr "type" "multi,multi,multi")
1147 (set_attr "length" "8,8,8")])
1148
1149(define_insn "smaxdi3"
1150  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1151	(smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1152		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1153  "TARGET_64BIT"
1154  "@
1155  cmpclr,*< %2,%0,%%r0\;copy %2,%0
1156  cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1157  cmpclr,*< %1,%r2,%0\;copy %1,%0"
1158[(set_attr "type" "multi,multi,multi")
1159 (set_attr "length" "8,8,8")])
1160
1161(define_insn "umaxsi3"
1162  [(set (match_operand:SI 0 "register_operand" "=r,r")
1163	(umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1164		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1165  ""
1166  "@
1167  {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1168  {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1169[(set_attr "type" "multi,multi")
1170 (set_attr "length" "8,8")])
1171
1172(define_insn "umaxdi3"
1173  [(set (match_operand:DI 0 "register_operand" "=r,r")
1174	(umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1175		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1176  "TARGET_64BIT"
1177  "@
1178  cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1179  cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1180[(set_attr "type" "multi,multi")
1181 (set_attr "length" "8,8")])
1182
1183(define_insn "absqi2"
1184  [(set (match_operand:QI 0 "register_operand" "=r")
1185	(abs:QI (match_operand:QI 1 "register_operand" "r")))]
1186  ""
1187  "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1188  [(set_attr "type" "multi")
1189   (set_attr "length" "8")])
1190
1191(define_insn "abshi2"
1192  [(set (match_operand:HI 0 "register_operand" "=r")
1193	(abs:HI (match_operand:HI 1 "register_operand" "r")))]
1194  ""
1195  "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1196  [(set_attr "type" "multi")
1197   (set_attr "length" "8")])
1198
1199(define_insn "abssi2"
1200  [(set (match_operand:SI 0 "register_operand" "=r")
1201	(abs:SI (match_operand:SI 1 "register_operand" "r")))]
1202  ""
1203  "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1204  [(set_attr "type" "multi")
1205   (set_attr "length" "8")])
1206
1207(define_insn "absdi2"
1208  [(set (match_operand:DI 0 "register_operand" "=r")
1209	(abs:DI (match_operand:DI 1 "register_operand" "r")))]
1210  "TARGET_64BIT"
1211  "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1212  [(set_attr "type" "multi")
1213   (set_attr "length" "8")])
1214
1215(define_insn "bswaphi2"
1216  [(set (match_operand:HI 0 "register_operand" "=&r")
1217	(bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1218  ""
1219  "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1220  [(set_attr "type" "multi")
1221   (set_attr "length" "8")])
1222
1223(define_insn "bswapsi2"
1224  [(set (match_operand:SI 0 "register_operand" "=&r")
1225	(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1226  ""
1227  "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1228  [(set_attr "type" "multi")
1229   (set_attr "length" "12")])
1230
1231(define_insn "bswapdi2"
1232  [(set (match_operand:DI 0 "register_operand" "=&r")
1233	(bswap:DI (match_operand:DI 1 "register_operand" "r")))
1234   (clobber (match_scratch:DI 2 "=r"))]
1235  "TARGET_64BIT"
1236  "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1237  [(set_attr "type" "multi")
1238   (set_attr "length" "16")])
1239
1240;;; Experimental conditional move patterns
1241
1242(define_expand "movsicc"
1243  [(set (match_operand:SI 0 "register_operand" "")
1244	(if_then_else:SI
1245	 (match_operand 1 "ordered_comparison_operator" "")
1246	 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1247	 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1248  ""
1249  "
1250{
1251  if (GET_MODE (XEXP (operands[1], 0)) != SImode
1252      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1253    FAIL;
1254}")
1255
1256;; We used to accept any register for op1.
1257;;
1258;; However, it loses sometimes because the compiler will end up using
1259;; different registers for op0 and op1 in some critical cases.  local-alloc
1260;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1261;;
1262;; If/when global register allocation supports tying we should allow any
1263;; register for op1 again.
1264(define_insn ""
1265  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1266	(if_then_else:SI
1267	 (match_operator 2 "ordered_comparison_operator"
1268	    [(match_operand:SI 3 "register_operand" "r,r,r,r")
1269	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1270	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1271	 (const_int 0)))]
1272  ""
1273  "@
1274   {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1275   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1276   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1277   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1278  [(set_attr "type" "multi,multi,multi,nullshift")
1279   (set_attr "length" "8,8,8,8")])
1280
1281(define_insn ""
1282  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1283	(if_then_else:SI
1284	 (match_operator 5 "ordered_comparison_operator"
1285	    [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1286	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1287	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1288	 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1289  ""
1290  "@
1291   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1292   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1293   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1294   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1295   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1296   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1297   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1298   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1299  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1300   (set_attr "length" "8,8,8,8,8,8,8,8")])
1301
1302(define_expand "movdicc"
1303  [(set (match_operand:DI 0 "register_operand" "")
1304	(if_then_else:DI
1305	 (match_operand 1 "ordered_comparison_operator" "")
1306	 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1307	 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1308  "TARGET_64BIT"
1309  "
1310{
1311  if (GET_MODE (XEXP (operands[1], 0)) != DImode
1312      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1313    FAIL;
1314}")
1315
1316; We need the first constraint alternative in order to avoid
1317; earlyclobbers on all other alternatives.
1318(define_insn ""
1319  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1320	(if_then_else:DI
1321	 (match_operator 2 "ordered_comparison_operator"
1322	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1323	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1324	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1325	 (const_int 0)))]
1326  "TARGET_64BIT"
1327  "@
1328   cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1329   cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1330   cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1331   cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1332   cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1333  [(set_attr "type" "multi,multi,multi,multi,nullshift")
1334   (set_attr "length" "8,8,8,8,8")])
1335
1336(define_insn ""
1337  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1338	(if_then_else:DI
1339	 (match_operator 5 "ordered_comparison_operator"
1340	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1341	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1342	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1343	 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1344  "TARGET_64BIT"
1345  "@
1346   cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1347   cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1348   cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1349   cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1350   cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1351   cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1352   cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1353   cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1354  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1355   (set_attr "length" "8,8,8,8,8,8,8,8")])
1356
1357;; Conditional Branches
1358
1359(define_expand "cbranchdi4"
1360  [(set (pc)
1361        (if_then_else (match_operator 0 "ordered_comparison_operator"
1362		       [(match_operand:DI 1 "reg_or_0_operand" "")
1363                        (match_operand:DI 2 "register_operand" "")])
1364		      (label_ref (match_operand 3 "" ""))
1365		      (pc)))]
1366  "TARGET_64BIT"
1367  "")
1368
1369(define_expand "cbranchsi4"
1370  [(set (pc)
1371        (if_then_else (match_operator 0 "ordered_comparison_operator"
1372		       [(match_operand:SI 1 "reg_or_0_operand" "")
1373                        (match_operand:SI 2 "arith5_operand" "")])
1374		      (label_ref (match_operand 3 "" ""))
1375		      (pc)))]
1376  ""
1377  "")
1378
1379(define_expand "cbranchsf4"
1380  [(set (pc)
1381        (if_then_else (match_operator 0 "comparison_operator"
1382		       [(match_operand:SF 1 "reg_or_0_operand" "")
1383                        (match_operand:SF 2 "reg_or_0_operand" "")])
1384		      (label_ref (match_operand 3 "" ""))
1385		      (pc)))]
1386  "! TARGET_SOFT_FLOAT"
1387  "
1388{
1389  pa_emit_bcond_fp (operands);
1390  DONE;
1391}")
1392
1393
1394(define_expand "cbranchdf4"
1395  [(set (pc)
1396        (if_then_else (match_operator 0 "comparison_operator"
1397		       [(match_operand:DF 1 "reg_or_0_operand" "")
1398                        (match_operand:DF 2 "reg_or_0_operand" "")])
1399		      (label_ref (match_operand 3 "" ""))
1400		      (pc)))]
1401  "! TARGET_SOFT_FLOAT"
1402  "
1403{
1404  pa_emit_bcond_fp (operands);
1405  DONE;
1406}")
1407
1408;; Match the branch patterns.
1409
1410
1411;; Note a long backward conditional branch with an annulled delay slot
1412;; has a length of 12.
1413(define_insn ""
1414  [(set (pc)
1415	(if_then_else
1416	 (match_operator 3 "ordered_comparison_operator"
1417			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1418			  (match_operand:SI 2 "arith5_operand" "rL")])
1419	 (label_ref (match_operand 0 "" ""))
1420	 (pc)))]
1421  ""
1422  "*
1423{
1424  return pa_output_cbranch (operands, 0, insn);
1425}"
1426[(set_attr "type" "cbranch")
1427 (set (attr "length")
1428    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1429	       (const_int MAX_12BIT_OFFSET))
1430	   (const_int 4)
1431	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1432	       (const_int MAX_17BIT_OFFSET))
1433	   (const_int 8)
1434	   (match_test "TARGET_PORTABLE_RUNTIME")
1435	   (const_int 24)
1436	   (not (match_test "flag_pic"))
1437	   (const_int 20)]
1438	  (const_int 28)))])
1439
1440;; Match the negated branch.
1441
1442(define_insn ""
1443  [(set (pc)
1444	(if_then_else
1445	 (match_operator 3 "ordered_comparison_operator"
1446			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1447			  (match_operand:SI 2 "arith5_operand" "rL")])
1448	 (pc)
1449	 (label_ref (match_operand 0 "" ""))))]
1450  ""
1451  "*
1452{
1453  return pa_output_cbranch (operands, 1, insn);
1454}"
1455[(set_attr "type" "cbranch")
1456 (set (attr "length")
1457    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1458	       (const_int MAX_12BIT_OFFSET))
1459	   (const_int 4)
1460	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1461	       (const_int MAX_17BIT_OFFSET))
1462	   (const_int 8)
1463	   (match_test "TARGET_PORTABLE_RUNTIME")
1464	   (const_int 24)
1465	   (not (match_test "flag_pic"))
1466	   (const_int 20)]
1467	  (const_int 28)))])
1468
1469(define_insn ""
1470  [(set (pc)
1471	(if_then_else
1472	 (match_operator 3 "ordered_comparison_operator"
1473			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1474			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1475	 (label_ref (match_operand 0 "" ""))
1476	 (pc)))]
1477  "TARGET_64BIT"
1478  "*
1479{
1480  return pa_output_cbranch (operands, 0, insn);
1481}"
1482[(set_attr "type" "cbranch")
1483 (set (attr "length")
1484    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1485	       (const_int MAX_12BIT_OFFSET))
1486	   (const_int 4)
1487	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1488	       (const_int MAX_17BIT_OFFSET))
1489	   (const_int 8)
1490	   (match_test "TARGET_PORTABLE_RUNTIME")
1491	   (const_int 24)
1492	   (not (match_test "flag_pic"))
1493	   (const_int 20)]
1494	  (const_int 28)))])
1495
1496;; Match the negated branch.
1497
1498(define_insn ""
1499  [(set (pc)
1500	(if_then_else
1501	 (match_operator 3 "ordered_comparison_operator"
1502			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1503			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1504	 (pc)
1505	 (label_ref (match_operand 0 "" ""))))]
1506  "TARGET_64BIT"
1507  "*
1508{
1509  return pa_output_cbranch (operands, 1, insn);
1510}"
1511[(set_attr "type" "cbranch")
1512 (set (attr "length")
1513    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1514	       (const_int MAX_12BIT_OFFSET))
1515	   (const_int 4)
1516	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1517	       (const_int MAX_17BIT_OFFSET))
1518	   (const_int 8)
1519	   (match_test "TARGET_PORTABLE_RUNTIME")
1520	   (const_int 24)
1521	   (not (match_test "flag_pic"))
1522	   (const_int 20)]
1523	  (const_int 28)))])
1524(define_insn ""
1525  [(set (pc)
1526	(if_then_else
1527	 (match_operator 3 "cmpib_comparison_operator"
1528			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1529			  (match_operand:DI 2 "arith5_operand" "rL")])
1530	 (label_ref (match_operand 0 "" ""))
1531	 (pc)))]
1532  "TARGET_64BIT"
1533  "*
1534{
1535  return pa_output_cbranch (operands, 0, insn);
1536}"
1537[(set_attr "type" "cbranch")
1538 (set (attr "length")
1539    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1540	       (const_int MAX_12BIT_OFFSET))
1541	   (const_int 4)
1542	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1543	       (const_int MAX_17BIT_OFFSET))
1544	   (const_int 8)
1545	   (match_test "TARGET_PORTABLE_RUNTIME")
1546	   (const_int 24)
1547	   (not (match_test "flag_pic"))
1548	   (const_int 20)]
1549	  (const_int 28)))])
1550
1551;; Match the negated branch.
1552
1553(define_insn ""
1554  [(set (pc)
1555	(if_then_else
1556	 (match_operator 3 "cmpib_comparison_operator"
1557			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1558			  (match_operand:DI 2 "arith5_operand" "rL")])
1559	 (pc)
1560	 (label_ref (match_operand 0 "" ""))))]
1561  "TARGET_64BIT"
1562  "*
1563{
1564  return pa_output_cbranch (operands, 1, insn);
1565}"
1566[(set_attr "type" "cbranch")
1567 (set (attr "length")
1568    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1569	       (const_int MAX_12BIT_OFFSET))
1570	   (const_int 4)
1571	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1572	       (const_int MAX_17BIT_OFFSET))
1573	   (const_int 8)
1574	   (match_test "TARGET_PORTABLE_RUNTIME")
1575	   (const_int 24)
1576	   (not (match_test "flag_pic"))
1577	   (const_int 20)]
1578	  (const_int 28)))])
1579
1580;; Branch on Bit patterns.
1581(define_insn ""
1582  [(set (pc)
1583	(if_then_else
1584	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1585			      (const_int 1)
1586			      (match_operand:SI 1 "uint5_operand" ""))
1587	     (const_int 0))
1588	 (label_ref (match_operand 2 "" ""))
1589	 (pc)))]
1590  ""
1591  "*
1592{
1593  return pa_output_bb (operands, 0, insn, 0);
1594}"
1595[(set_attr "type" "cbranch")
1596 (set (attr "length")
1597    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1598	       (const_int MAX_12BIT_OFFSET))
1599	   (const_int 4)
1600	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1601	       (const_int MAX_17BIT_OFFSET))
1602	   (const_int 8)
1603	   (match_test "TARGET_PORTABLE_RUNTIME")
1604	   (const_int 24)
1605	   (not (match_test "flag_pic"))
1606	   (const_int 20)]
1607	  (const_int 28)))])
1608
1609(define_insn ""
1610  [(set (pc)
1611	(if_then_else
1612	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1613			      (const_int 1)
1614			      (match_operand:DI 1 "uint32_operand" ""))
1615	     (const_int 0))
1616	 (label_ref (match_operand 2 "" ""))
1617	 (pc)))]
1618  "TARGET_64BIT"
1619  "*
1620{
1621  return pa_output_bb (operands, 0, insn, 0);
1622}"
1623[(set_attr "type" "cbranch")
1624 (set (attr "length")
1625    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1626	       (const_int MAX_12BIT_OFFSET))
1627	   (const_int 4)
1628	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1629	       (const_int MAX_17BIT_OFFSET))
1630	   (const_int 8)
1631	   (match_test "TARGET_PORTABLE_RUNTIME")
1632	   (const_int 24)
1633	   (not (match_test "flag_pic"))
1634	   (const_int 20)]
1635	  (const_int 28)))])
1636
1637(define_insn ""
1638  [(set (pc)
1639	(if_then_else
1640	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1641			      (const_int 1)
1642			      (match_operand:SI 1 "uint5_operand" ""))
1643	     (const_int 0))
1644	 (pc)
1645	 (label_ref (match_operand 2 "" ""))))]
1646  ""
1647  "*
1648{
1649  return pa_output_bb (operands, 1, insn, 0);
1650}"
1651[(set_attr "type" "cbranch")
1652 (set (attr "length")
1653    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1654	       (const_int MAX_12BIT_OFFSET))
1655	   (const_int 4)
1656	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1657	       (const_int MAX_17BIT_OFFSET))
1658	   (const_int 8)
1659	   (match_test "TARGET_PORTABLE_RUNTIME")
1660	   (const_int 24)
1661	   (not (match_test "flag_pic"))
1662	   (const_int 20)]
1663	  (const_int 28)))])
1664
1665(define_insn ""
1666  [(set (pc)
1667	(if_then_else
1668	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1669			      (const_int 1)
1670			      (match_operand:DI 1 "uint32_operand" ""))
1671	     (const_int 0))
1672	 (pc)
1673	 (label_ref (match_operand 2 "" ""))))]
1674  "TARGET_64BIT"
1675  "*
1676{
1677  return pa_output_bb (operands, 1, insn, 0);
1678}"
1679[(set_attr "type" "cbranch")
1680 (set (attr "length")
1681    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1682	       (const_int MAX_12BIT_OFFSET))
1683	   (const_int 4)
1684	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1685	       (const_int MAX_17BIT_OFFSET))
1686	   (const_int 8)
1687	   (match_test "TARGET_PORTABLE_RUNTIME")
1688	   (const_int 24)
1689	   (not (match_test "flag_pic"))
1690	   (const_int 20)]
1691	  (const_int 28)))])
1692
1693(define_insn ""
1694  [(set (pc)
1695	(if_then_else
1696	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1697			      (const_int 1)
1698			      (match_operand:SI 1 "uint5_operand" ""))
1699	     (const_int 0))
1700	 (label_ref (match_operand 2 "" ""))
1701	 (pc)))]
1702  ""
1703  "*
1704{
1705  return pa_output_bb (operands, 0, insn, 1);
1706}"
1707[(set_attr "type" "cbranch")
1708 (set (attr "length")
1709    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1710	       (const_int MAX_12BIT_OFFSET))
1711	   (const_int 4)
1712	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1713	       (const_int MAX_17BIT_OFFSET))
1714	   (const_int 8)
1715	   (match_test "TARGET_PORTABLE_RUNTIME")
1716	   (const_int 24)
1717	   (not (match_test "flag_pic"))
1718	   (const_int 20)]
1719	  (const_int 28)))])
1720
1721(define_insn ""
1722  [(set (pc)
1723	(if_then_else
1724	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1725			      (const_int 1)
1726			      (match_operand:DI 1 "uint32_operand" ""))
1727	     (const_int 0))
1728	 (label_ref (match_operand 2 "" ""))
1729	 (pc)))]
1730  "TARGET_64BIT"
1731  "*
1732{
1733  return pa_output_bb (operands, 0, insn, 1);
1734}"
1735[(set_attr "type" "cbranch")
1736 (set (attr "length")
1737    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1738	       (const_int MAX_12BIT_OFFSET))
1739	   (const_int 4)
1740	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1741	       (const_int MAX_17BIT_OFFSET))
1742	   (const_int 8)
1743	   (match_test "TARGET_PORTABLE_RUNTIME")
1744	   (const_int 24)
1745	   (not (match_test "flag_pic"))
1746	   (const_int 20)]
1747	  (const_int 28)))])
1748
1749(define_insn ""
1750  [(set (pc)
1751	(if_then_else
1752	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1753			      (const_int 1)
1754			      (match_operand:SI 1 "uint5_operand" ""))
1755	     (const_int 0))
1756	 (pc)
1757	 (label_ref (match_operand 2 "" ""))))]
1758  ""
1759  "*
1760{
1761  return pa_output_bb (operands, 1, insn, 1);
1762}"
1763[(set_attr "type" "cbranch")
1764 (set (attr "length")
1765    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1766	       (const_int MAX_12BIT_OFFSET))
1767	   (const_int 4)
1768	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1769	       (const_int MAX_17BIT_OFFSET))
1770	   (const_int 8)
1771	   (match_test "TARGET_PORTABLE_RUNTIME")
1772	   (const_int 24)
1773	   (not (match_test "flag_pic"))
1774	   (const_int 20)]
1775	  (const_int 28)))])
1776
1777(define_insn ""
1778  [(set (pc)
1779	(if_then_else
1780	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1781			      (const_int 1)
1782			      (match_operand:DI 1 "uint32_operand" ""))
1783	     (const_int 0))
1784	 (pc)
1785	 (label_ref (match_operand 2 "" ""))))]
1786  "TARGET_64BIT"
1787  "*
1788{
1789  return pa_output_bb (operands, 1, insn, 1);
1790}"
1791[(set_attr "type" "cbranch")
1792 (set (attr "length")
1793    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1794	       (const_int MAX_12BIT_OFFSET))
1795	   (const_int 4)
1796	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1797	       (const_int MAX_17BIT_OFFSET))
1798	   (const_int 8)
1799	   (match_test "TARGET_PORTABLE_RUNTIME")
1800	   (const_int 24)
1801	   (not (match_test "flag_pic"))
1802	   (const_int 20)]
1803	  (const_int 28)))])
1804
1805;; Branch on Variable Bit patterns.
1806(define_insn ""
1807  [(set (pc)
1808	(if_then_else
1809	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1810			      (const_int 1)
1811			      (match_operand:SI 1 "register_operand" "q"))
1812	     (const_int 0))
1813	 (label_ref (match_operand 2 "" ""))
1814	 (pc)))]
1815  ""
1816  "*
1817{
1818  return pa_output_bvb (operands, 0, insn, 0);
1819}"
1820[(set_attr "type" "cbranch")
1821 (set (attr "length")
1822    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1823	       (const_int MAX_12BIT_OFFSET))
1824	   (const_int 4)
1825	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1826	       (const_int MAX_17BIT_OFFSET))
1827	   (const_int 8)
1828	   (match_test "TARGET_PORTABLE_RUNTIME")
1829	   (const_int 24)
1830	   (not (match_test "flag_pic"))
1831	   (const_int 20)]
1832	  (const_int 28)))])
1833
1834(define_insn ""
1835  [(set (pc)
1836	(if_then_else
1837	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1838			      (const_int 1)
1839			      (match_operand:DI 1 "register_operand" "q"))
1840	     (const_int 0))
1841	 (label_ref (match_operand 2 "" ""))
1842	 (pc)))]
1843  "TARGET_64BIT"
1844  "*
1845{
1846  return pa_output_bvb (operands, 0, insn, 0);
1847}"
1848[(set_attr "type" "cbranch")
1849 (set (attr "length")
1850    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1851	       (const_int MAX_12BIT_OFFSET))
1852	   (const_int 4)
1853	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1854	       (const_int MAX_17BIT_OFFSET))
1855	   (const_int 8)
1856	   (match_test "TARGET_PORTABLE_RUNTIME")
1857	   (const_int 24)
1858	   (not (match_test "flag_pic"))
1859	   (const_int 20)]
1860	  (const_int 28)))])
1861
1862(define_insn ""
1863  [(set (pc)
1864	(if_then_else
1865	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1866			      (const_int 1)
1867			      (match_operand:SI 1 "register_operand" "q"))
1868	     (const_int 0))
1869	 (pc)
1870	 (label_ref (match_operand 2 "" ""))))]
1871  ""
1872  "*
1873{
1874  return pa_output_bvb (operands, 1, insn, 0);
1875}"
1876[(set_attr "type" "cbranch")
1877 (set (attr "length")
1878    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1879	       (const_int MAX_12BIT_OFFSET))
1880	   (const_int 4)
1881	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1882	       (const_int MAX_17BIT_OFFSET))
1883	   (const_int 8)
1884	   (match_test "TARGET_PORTABLE_RUNTIME")
1885	   (const_int 24)
1886	   (not (match_test "flag_pic"))
1887	   (const_int 20)]
1888	  (const_int 28)))])
1889
1890(define_insn ""
1891  [(set (pc)
1892	(if_then_else
1893	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1894			      (const_int 1)
1895			      (match_operand:DI 1 "register_operand" "q"))
1896	     (const_int 0))
1897	 (pc)
1898	 (label_ref (match_operand 2 "" ""))))]
1899  "TARGET_64BIT"
1900  "*
1901{
1902  return pa_output_bvb (operands, 1, insn, 0);
1903}"
1904[(set_attr "type" "cbranch")
1905 (set (attr "length")
1906    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1907	       (const_int MAX_12BIT_OFFSET))
1908	   (const_int 4)
1909	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1910	       (const_int MAX_17BIT_OFFSET))
1911	   (const_int 8)
1912	   (match_test "TARGET_PORTABLE_RUNTIME")
1913	   (const_int 24)
1914	   (not (match_test "flag_pic"))
1915	   (const_int 20)]
1916	  (const_int 28)))])
1917
1918(define_insn ""
1919  [(set (pc)
1920	(if_then_else
1921	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1922			      (const_int 1)
1923			      (match_operand:SI 1 "register_operand" "q"))
1924	     (const_int 0))
1925	 (label_ref (match_operand 2 "" ""))
1926	 (pc)))]
1927  ""
1928  "*
1929{
1930  return pa_output_bvb (operands, 0, insn, 1);
1931}"
1932[(set_attr "type" "cbranch")
1933 (set (attr "length")
1934    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1935	       (const_int MAX_12BIT_OFFSET))
1936	   (const_int 4)
1937	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1938	       (const_int MAX_17BIT_OFFSET))
1939	   (const_int 8)
1940	   (match_test "TARGET_PORTABLE_RUNTIME")
1941	   (const_int 24)
1942	   (not (match_test "flag_pic"))
1943	   (const_int 20)]
1944	  (const_int 28)))])
1945
1946(define_insn ""
1947  [(set (pc)
1948	(if_then_else
1949	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1950			      (const_int 1)
1951			      (match_operand:DI 1 "register_operand" "q"))
1952	     (const_int 0))
1953	 (label_ref (match_operand 2 "" ""))
1954	 (pc)))]
1955  "TARGET_64BIT"
1956  "*
1957{
1958  return pa_output_bvb (operands, 0, insn, 1);
1959}"
1960[(set_attr "type" "cbranch")
1961 (set (attr "length")
1962    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1963	       (const_int MAX_12BIT_OFFSET))
1964	   (const_int 4)
1965	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1966	       (const_int MAX_17BIT_OFFSET))
1967	   (const_int 8)
1968	   (match_test "TARGET_PORTABLE_RUNTIME")
1969	   (const_int 24)
1970	   (not (match_test "flag_pic"))
1971	   (const_int 20)]
1972	  (const_int 28)))])
1973
1974(define_insn ""
1975  [(set (pc)
1976	(if_then_else
1977	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1978			      (const_int 1)
1979			      (match_operand:SI 1 "register_operand" "q"))
1980	     (const_int 0))
1981	 (pc)
1982	 (label_ref (match_operand 2 "" ""))))]
1983  ""
1984  "*
1985{
1986  return pa_output_bvb (operands, 1, insn, 1);
1987}"
1988[(set_attr "type" "cbranch")
1989 (set (attr "length")
1990    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1991	       (const_int MAX_12BIT_OFFSET))
1992	   (const_int 4)
1993	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1994	       (const_int MAX_17BIT_OFFSET))
1995	   (const_int 8)
1996	   (match_test "TARGET_PORTABLE_RUNTIME")
1997	   (const_int 24)
1998	   (not (match_test "flag_pic"))
1999	   (const_int 20)]
2000	  (const_int 28)))])
2001
2002(define_insn ""
2003  [(set (pc)
2004	(if_then_else
2005	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2006			      (const_int 1)
2007			      (match_operand:DI 1 "register_operand" "q"))
2008	     (const_int 0))
2009	 (pc)
2010	 (label_ref (match_operand 2 "" ""))))]
2011  "TARGET_64BIT"
2012  "*
2013{
2014  return pa_output_bvb (operands, 1, insn, 1);
2015}"
2016[(set_attr "type" "cbranch")
2017 (set (attr "length")
2018    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2019	       (const_int MAX_12BIT_OFFSET))
2020	   (const_int 4)
2021	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2022	       (const_int MAX_17BIT_OFFSET))
2023	   (const_int 8)
2024	   (match_test "TARGET_PORTABLE_RUNTIME")
2025	   (const_int 24)
2026	   (not (match_test "flag_pic"))
2027	   (const_int 20)]
2028	  (const_int 28)))])
2029
2030;; Floating point branches
2031
2032;; ??? Nullification is handled differently from other branches.
2033;; If nullification is specified, the delay slot is nullified on any
2034;; taken branch regardless of branch direction.
2035(define_insn ""
2036  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2037			   (label_ref (match_operand 0 "" ""))
2038			   (pc)))]
2039  "!TARGET_SOFT_FLOAT"
2040  "*
2041{
2042  int length = get_attr_length (insn);
2043  rtx xoperands[1];
2044  int nullify, xdelay;
2045
2046  if (length < 16)
2047    return \"ftest\;b%* %l0\";
2048
2049  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2050    {
2051      nullify = 1;
2052      xdelay = 0;
2053      xoperands[0] = GEN_INT (length - 8);
2054    }
2055  else
2056    {
2057      nullify = 0;
2058      xdelay = 1;
2059      xoperands[0] = GEN_INT (length - 4);
2060    }
2061
2062  if (nullify)
2063    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2064  else
2065    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2066  return pa_output_lbranch (operands[0], insn, xdelay);
2067}"
2068[(set_attr "type" "fbranch")
2069 (set (attr "length")
2070    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2071	       (const_int MAX_17BIT_OFFSET))
2072	   (const_int 8)
2073	   (match_test "TARGET_PORTABLE_RUNTIME")
2074	   (const_int 32)
2075	   (not (match_test "flag_pic"))
2076	   (const_int 28)]
2077	  (const_int 36)))])
2078
2079(define_insn ""
2080  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2081			   (pc)
2082			   (label_ref (match_operand 0 "" ""))))]
2083  "!TARGET_SOFT_FLOAT"
2084  "*
2085{
2086  int length = get_attr_length (insn);
2087  rtx xoperands[1];
2088  int nullify, xdelay;
2089
2090  if (length < 16)
2091    return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2092
2093  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2094    {
2095      nullify = 1;
2096      xdelay = 0;
2097      xoperands[0] = GEN_INT (length - 4);
2098    }
2099  else
2100    {
2101      nullify = 0;
2102      xdelay = 1;
2103      xoperands[0] = GEN_INT (length);
2104    }
2105
2106  if (nullify)
2107    output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2108  else
2109    output_asm_insn (\"ftest\;b .+%0\", xoperands);
2110  return pa_output_lbranch (operands[0], insn, xdelay);
2111}"
2112[(set_attr "type" "fbranch")
2113 (set (attr "length")
2114    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2115	       (const_int MAX_17BIT_OFFSET))
2116	   (const_int 12)
2117	   (match_test "TARGET_PORTABLE_RUNTIME")
2118	   (const_int 28)
2119	   (not (match_test "flag_pic"))
2120	   (const_int 24)]
2121	  (const_int 32)))])
2122
2123;; Move instructions
2124
2125(define_expand "movsi"
2126  [(set (match_operand:SI 0 "general_operand" "")
2127	(match_operand:SI 1 "general_operand" ""))]
2128  ""
2129  "
2130{
2131  if (pa_emit_move_sequence (operands, SImode, 0))
2132    DONE;
2133}")
2134
2135;; Handle SImode input reloads requiring %r1 as a scratch register.
2136(define_expand "reload_insi_r1"
2137  [(set (match_operand:SI 0 "register_operand" "=Z")
2138	(match_operand:SI 1 "non_hard_reg_operand" ""))
2139   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2140  ""
2141  "
2142{
2143  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2144    DONE;
2145
2146  /* We don't want the clobber emitted, so handle this ourselves.  */
2147  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2148  DONE;
2149}")
2150
2151;; Handle SImode input reloads requiring a general register as a
2152;; scratch register.
2153(define_expand "reload_insi"
2154  [(set (match_operand:SI 0 "register_operand" "=Z")
2155	(match_operand:SI 1 "non_hard_reg_operand" ""))
2156   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2157  ""
2158  "
2159{
2160  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2161    DONE;
2162
2163  /* We don't want the clobber emitted, so handle this ourselves.  */
2164  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2165  DONE;
2166}")
2167
2168;; Handle SImode output reloads requiring a general register as a
2169;; scratch register.
2170(define_expand "reload_outsi"
2171  [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2172	(match_operand:SI 1  "register_operand" "Z"))
2173   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2174  ""
2175  "
2176{
2177  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2178    DONE;
2179
2180  /* We don't want the clobber emitted, so handle this ourselves.  */
2181  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2182  DONE;
2183}")
2184
2185(define_insn ""
2186  [(set (match_operand:SI 0 "move_dest_operand"
2187			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2188	(match_operand:SI 1 "move_src_operand"
2189			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2190  "(register_operand (operands[0], SImode)
2191    || reg_or_0_operand (operands[1], SImode))
2192   && !TARGET_SOFT_FLOAT
2193   && !TARGET_64BIT"
2194  "@
2195   ldw RT'%A1,%0
2196   copy %1,%0
2197   ldi %1,%0
2198   ldil L'%1,%0
2199   {zdepi|depwi,z} %Z1,%0
2200   ldw%M1 %1,%0
2201   stw%M0 %r1,%0
2202   mtsar %r1
2203   {mfctl|mfctl,w} %%sar,%0
2204   fcpy,sgl %f1,%0
2205   fldw%F1 %1,%0
2206   fstw%F0 %1,%0
2207   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2208   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2209  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2210   (set_attr "pa_combine_type" "addmove")
2211   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2212
2213(define_insn ""
2214  [(set (match_operand:SI 0 "move_dest_operand"
2215			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2216	(match_operand:SI 1 "move_src_operand"
2217			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2218  "(register_operand (operands[0], SImode)
2219    || reg_or_0_operand (operands[1], SImode))
2220   && !TARGET_SOFT_FLOAT
2221   && TARGET_64BIT"
2222  "@
2223   ldw RT'%A1,%0
2224   copy %1,%0
2225   ldi %1,%0
2226   ldil L'%1,%0
2227   {zdepi|depwi,z} %Z1,%0
2228   ldw%M1 %1,%0
2229   stw%M0 %r1,%0
2230   mtsar %r1
2231   {mfctl|mfctl,w} %%sar,%0
2232   fcpy,sgl %f1,%0
2233   fldw%F1 %1,%0
2234   fstw%F0 %1,%0"
2235  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2236   (set_attr "pa_combine_type" "addmove")
2237   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2238
2239(define_insn ""
2240  [(set (match_operand:SI 0 "move_dest_operand"
2241			  "=r,r,r,r,r,r,Q,!*q,!r")
2242	(match_operand:SI 1 "move_src_operand"
2243			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2244  "(register_operand (operands[0], SImode)
2245    || reg_or_0_operand (operands[1], SImode))
2246   && TARGET_SOFT_FLOAT
2247   && TARGET_64BIT"
2248  "@
2249   ldw RT'%A1,%0
2250   copy %1,%0
2251   ldi %1,%0
2252   ldil L'%1,%0
2253   {zdepi|depwi,z} %Z1,%0
2254   ldw%M1 %1,%0
2255   stw%M0 %r1,%0
2256   mtsar %r1
2257   {mfctl|mfctl,w} %%sar,%0"
2258  [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
2259   (set_attr "pa_combine_type" "addmove")
2260   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2261
2262(define_insn ""
2263  [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2264	(match_operand:SI 1 "register_operand" "f"))]
2265  "!TARGET_SOFT_FLOAT
2266   && !TARGET_DISABLE_INDEXING
2267   && reload_completed"
2268  "fstw%F0 %1,%0"
2269  [(set_attr "type" "fpstore")
2270   (set_attr "pa_combine_type" "addmove")
2271   (set_attr "length" "4")])
2272
2273; Rewrite RTL using an indexed store.  This will allow the insn that
2274; computes the address to be deleted if the register it sets is dead.
2275(define_peephole2
2276  [(set (match_operand:SI 0 "register_operand" "")
2277	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2278			    (const_int 2))
2279		 (match_operand:SI 2 "register_operand" "")))
2280   (set (mem:SI (match_dup 0))
2281        (match_operand:SI 3 "register_operand" ""))]
2282  "!TARGET_SOFT_FLOAT
2283   && !TARGET_DISABLE_INDEXING
2284   && REG_OK_FOR_BASE_P (operands[2])
2285   && FP_REGNO_P (REGNO (operands[3]))"
2286  [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2287	(match_dup 3))
2288   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2289			       (match_dup 2)))]
2290  "")
2291
2292(define_peephole2
2293  [(set (match_operand:DI 0 "register_operand" "")
2294	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2295			    (const_int 2))
2296		 (match_operand:DI 2 "register_operand" "")))
2297   (set (mem:SI (match_dup 0))
2298        (match_operand:SI 3 "register_operand" ""))]
2299  "!TARGET_SOFT_FLOAT
2300   && !TARGET_DISABLE_INDEXING
2301   && TARGET_64BIT
2302   && REG_OK_FOR_BASE_P (operands[2])
2303   && FP_REGNO_P (REGNO (operands[3]))"
2304  [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2305	(match_dup 3))
2306   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2307			       (match_dup 2)))]
2308  "")
2309
2310(define_peephole2
2311  [(set (match_operand:SI 0 "register_operand" "")
2312	(plus:SI (match_operand:SI 1 "register_operand" "")
2313		 (match_operand:SI 2 "register_operand" "")))
2314   (set (mem:SI (match_dup 0))
2315        (match_operand:SI 3 "register_operand" ""))]
2316  "!TARGET_SOFT_FLOAT
2317   && !TARGET_DISABLE_INDEXING
2318   && TARGET_NO_SPACE_REGS
2319   && REG_OK_FOR_INDEX_P (operands[1])
2320   && REG_OK_FOR_BASE_P (operands[2])
2321   && FP_REGNO_P (REGNO (operands[3]))"
2322  [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2323	(match_dup 3))
2324   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2325  "")
2326
2327(define_peephole2
2328  [(set (match_operand:SI 0 "register_operand" "")
2329	(plus:SI (match_operand:SI 1 "register_operand" "")
2330		 (match_operand:SI 2 "register_operand" "")))
2331   (set (mem:SI (match_dup 0))
2332        (match_operand:SI 3 "register_operand" ""))]
2333  "!TARGET_SOFT_FLOAT
2334   && !TARGET_DISABLE_INDEXING
2335   && TARGET_NO_SPACE_REGS
2336   && REG_OK_FOR_BASE_P (operands[1])
2337   && REG_OK_FOR_INDEX_P (operands[2])
2338   && FP_REGNO_P (REGNO (operands[3]))"
2339  [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2340	(match_dup 3))
2341   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2342  "")
2343
2344(define_peephole2
2345  [(set (match_operand:DI 0 "register_operand" "")
2346	(plus:DI (match_operand:DI 1 "register_operand" "")
2347		 (match_operand:DI 2 "register_operand" "")))
2348   (set (mem:SI (match_dup 0))
2349        (match_operand:SI 3 "register_operand" ""))]
2350  "!TARGET_SOFT_FLOAT
2351   && !TARGET_DISABLE_INDEXING
2352   && TARGET_64BIT
2353   && TARGET_NO_SPACE_REGS
2354   && REG_OK_FOR_INDEX_P (operands[1])
2355   && REG_OK_FOR_BASE_P (operands[2])
2356   && FP_REGNO_P (REGNO (operands[3]))"
2357  [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2358	(match_dup 3))
2359   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2360  "")
2361
2362(define_peephole2
2363  [(set (match_operand:DI 0 "register_operand" "")
2364	(plus:DI (match_operand:DI 1 "register_operand" "")
2365		 (match_operand:DI 2 "register_operand" "")))
2366   (set (mem:SI (match_dup 0))
2367        (match_operand:SI 3 "register_operand" ""))]
2368  "!TARGET_SOFT_FLOAT
2369   && !TARGET_DISABLE_INDEXING
2370   && TARGET_64BIT
2371   && TARGET_NO_SPACE_REGS
2372   && REG_OK_FOR_BASE_P (operands[1])
2373   && REG_OK_FOR_INDEX_P (operands[2])
2374   && FP_REGNO_P (REGNO (operands[3]))"
2375  [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2376	(match_dup 3))
2377   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2378  "")
2379
2380(define_insn ""
2381  [(set (match_operand:SI 0 "move_dest_operand"
2382			  "=r,r,r,r,r,r,Q,!*q,!r")
2383	(match_operand:SI 1 "move_src_operand"
2384			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2385  "(register_operand (operands[0], SImode)
2386    || reg_or_0_operand (operands[1], SImode))
2387   && TARGET_SOFT_FLOAT"
2388  "@
2389   ldw RT'%A1,%0
2390   copy %1,%0
2391   ldi %1,%0
2392   ldil L'%1,%0
2393   {zdepi|depwi,z} %Z1,%0
2394   ldw%M1 %1,%0
2395   stw%M0 %r1,%0
2396   mtsar %r1
2397   {mfctl|mfctl,w} %%sar,%0"
2398  [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2399   (set_attr "pa_combine_type" "addmove")
2400   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2401
2402;; Load or store with base-register modification.
2403(define_insn ""
2404  [(set (match_operand:SI 0 "register_operand" "=r")
2405	(mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2406			 (match_operand:DI 2 "int5_operand" "L"))))
2407   (set (match_dup 1)
2408	(plus:DI (match_dup 1) (match_dup 2)))]
2409  "TARGET_64BIT"
2410  "ldw,mb %2(%1),%0"
2411  [(set_attr "type" "load")
2412   (set_attr "length" "4")])
2413
2414; And a zero extended variant.
2415(define_insn ""
2416  [(set (match_operand:DI 0 "register_operand" "=r")
2417	(zero_extend:DI (mem:SI
2418			  (plus:DI
2419			    (match_operand:DI 1 "register_operand" "+r")
2420			    (match_operand:DI 2 "int5_operand" "L")))))
2421   (set (match_dup 1)
2422	(plus:DI (match_dup 1) (match_dup 2)))]
2423  "TARGET_64BIT"
2424  "ldw,mb %2(%1),%0"
2425  [(set_attr "type" "load")
2426   (set_attr "length" "4")])
2427
2428(define_expand "pre_load"
2429  [(parallel [(set (match_operand:SI 0 "register_operand" "")
2430	      (mem (plus (match_operand 1 "register_operand" "")
2431			       (match_operand 2 "pre_cint_operand" ""))))
2432	      (set (match_dup 1)
2433		   (plus (match_dup 1) (match_dup 2)))])]
2434  ""
2435  "
2436{
2437  if (TARGET_64BIT)
2438    {
2439      emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2440      DONE;
2441    }
2442  emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2443  DONE;
2444}")
2445
2446(define_insn "pre_ldw"
2447  [(set (match_operand:SI 0 "register_operand" "=r")
2448	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2449			 (match_operand:SI 2 "pre_cint_operand" ""))))
2450   (set (match_dup 1)
2451	(plus:SI (match_dup 1) (match_dup 2)))]
2452  ""
2453  "*
2454{
2455  if (INTVAL (operands[2]) < 0)
2456    return \"{ldwm|ldw,mb} %2(%1),%0\";
2457  return \"{ldws|ldw},mb %2(%1),%0\";
2458}"
2459  [(set_attr "type" "load")
2460   (set_attr "length" "4")])
2461
2462(define_insn "pre_ldd"
2463  [(set (match_operand:DI 0 "register_operand" "=r")
2464	(mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2465			 (match_operand:DI 2 "pre_cint_operand" ""))))
2466   (set (match_dup 1)
2467	(plus:DI (match_dup 1) (match_dup 2)))]
2468  "TARGET_64BIT"
2469  "ldd,mb %2(%1),%0"
2470  [(set_attr "type" "load")
2471   (set_attr "length" "4")])
2472
2473(define_insn ""
2474  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2475			 (match_operand:SI 1 "pre_cint_operand" "")))
2476	(match_operand:SI 2 "reg_or_0_operand" "rM"))
2477   (set (match_dup 0)
2478	(plus:SI (match_dup 0) (match_dup 1)))]
2479  ""
2480  "*
2481{
2482  if (INTVAL (operands[1]) < 0)
2483    return \"{stwm|stw,mb} %r2,%1(%0)\";
2484  return \"{stws|stw},mb %r2,%1(%0)\";
2485}"
2486  [(set_attr "type" "store")
2487   (set_attr "length" "4")])
2488
2489(define_insn ""
2490  [(set (match_operand:SI 0 "register_operand" "=r")
2491	(mem:SI (match_operand:SI 1 "register_operand" "+r")))
2492   (set (match_dup 1)
2493	(plus:SI (match_dup 1)
2494		 (match_operand:SI 2 "post_cint_operand" "")))]
2495  ""
2496  "*
2497{
2498  if (INTVAL (operands[2]) > 0)
2499    return \"{ldwm|ldw,ma} %2(%1),%0\";
2500  return \"{ldws|ldw},ma %2(%1),%0\";
2501}"
2502  [(set_attr "type" "load")
2503   (set_attr "length" "4")])
2504
2505(define_expand "post_store"
2506  [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2507		   (match_operand 1 "reg_or_0_operand" ""))
2508	      (set (match_dup 0)
2509		   (plus (match_dup 0)
2510			 (match_operand 2 "post_cint_operand" "")))])]
2511  ""
2512  "
2513{
2514  if (TARGET_64BIT)
2515    {
2516      emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2517      DONE;
2518    }
2519  emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2520  DONE;
2521}")
2522
2523(define_insn "post_stw"
2524  [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2525	(match_operand:SI 1 "reg_or_0_operand" "rM"))
2526   (set (match_dup 0)
2527	(plus:SI (match_dup 0)
2528		 (match_operand:SI 2 "post_cint_operand" "")))]
2529  ""
2530  "*
2531{
2532  if (INTVAL (operands[2]) > 0)
2533    return \"{stwm|stw,ma} %r1,%2(%0)\";
2534  return \"{stws|stw},ma %r1,%2(%0)\";
2535}"
2536  [(set_attr "type" "store")
2537   (set_attr "length" "4")])
2538
2539(define_insn "post_std"
2540  [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2541	(match_operand:DI 1 "reg_or_0_operand" "rM"))
2542   (set (match_dup 0)
2543	(plus:DI (match_dup 0)
2544		 (match_operand:DI 2 "post_cint_operand" "")))]
2545  "TARGET_64BIT"
2546  "std,ma %r1,%2(%0)"
2547  [(set_attr "type" "store")
2548   (set_attr "length" "4")])
2549
2550;; For loading the address of a label while generating PIC code.
2551;; Note since this pattern can be created at reload time (via movsi), all
2552;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2553(define_insn ""
2554  [(set (match_operand 0 "pmode_register_operand" "=a")
2555	(match_operand 1 "pic_label_operand" ""))]
2556  "TARGET_PA_20"
2557  "*
2558{
2559  rtx xoperands[3];
2560
2561  xoperands[0] = operands[0];
2562  xoperands[1] = operands[1];
2563
2564  if (GET_CODE (operands[1]) == LABEL_REF
2565      && !LABEL_REF_NONLOCAL_P (operands[1]))
2566    {
2567      xoperands[2] = gen_label_rtx ();
2568      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2569					 CODE_LABEL_NUMBER (xoperands[2]));
2570      output_asm_insn (\"mfia %0\", xoperands);
2571
2572      /* If we're trying to load the address of a label that happens to be
2573	 close, then we can use a shorter sequence.  */
2574      if (INSN_ADDRESSES_SET_P ()
2575	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2576		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2577	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2578      else
2579	{
2580	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2581	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2582	}
2583    }
2584  else
2585    {
2586      /* Load using linkage table.  */
2587      if (TARGET_64BIT)
2588	{
2589	  output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
2590	  output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
2591	}
2592      else
2593	{
2594	  output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2595	  output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2596	}
2597    }
2598  return \"\";
2599}"
2600  [(set_attr "type" "multi")
2601   (set_attr "length" "12")])		; 8 or 12
2602
2603(define_insn ""
2604  [(set (match_operand 0 "pmode_register_operand" "=a")
2605	(match_operand 1 "pic_label_operand" ""))]
2606  "!TARGET_PA_20"
2607  "*
2608{
2609  rtx xoperands[3];
2610
2611  xoperands[0] = operands[0];
2612  xoperands[1] = operands[1];
2613
2614  if (GET_CODE (operands[1]) == LABEL_REF
2615      && !LABEL_REF_NONLOCAL_P (operands[1]))
2616    {
2617      xoperands[2] = gen_label_rtx ();
2618      output_asm_insn (\"bl .+8,%0\", xoperands);
2619      output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2620      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2621					 CODE_LABEL_NUMBER (xoperands[2]));
2622
2623      /* If we're trying to load the address of a label that happens to be
2624	 close, then we can use a shorter sequence.  */
2625      if (INSN_ADDRESSES_SET_P ()
2626	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2627		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2628	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2629      else
2630	{
2631	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2632	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2633	}
2634    }
2635  else
2636    {
2637      /* Load using linkage table.  */
2638      output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2639      output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2640    }
2641  return \"\";
2642}"
2643  [(set_attr "type" "multi")
2644   (set_attr "length" "16")])		; 12 or 16
2645
2646(define_insn ""
2647  [(set (match_operand:SI 0 "register_operand" "=a")
2648	(plus:SI (match_operand:SI 1 "register_operand" "r")
2649		 (high:SI (match_operand 2 "" ""))))]
2650  "symbolic_operand (operands[2], Pmode)
2651   && ! function_label_operand (operands[2], Pmode)
2652   && flag_pic"
2653  "addil LT'%G2,%1"
2654  [(set_attr "type" "binary")
2655   (set_attr "length" "4")])
2656
2657(define_insn ""
2658  [(set (match_operand:DI 0 "register_operand" "=a")
2659	(plus:DI (match_operand:DI 1 "register_operand" "r")
2660	         (high:DI (match_operand 2 "" ""))))]
2661  "symbolic_operand (operands[2], Pmode)
2662   && ! function_label_operand (operands[2], Pmode)
2663   && TARGET_64BIT
2664   && flag_pic"
2665  "addil LT'%G2,%1"
2666  [(set_attr "type" "binary")
2667   (set_attr "length" "4")])
2668
2669(define_insn ""
2670 [(set (match_operand:SI 0 "register_operand" "=r")
2671       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2672		  (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2673  "symbolic_operand (operands[2], Pmode)
2674   && ! function_label_operand (operands[2], Pmode)
2675   && flag_pic"
2676  "ldo RT'%G2(%1),%0"
2677  [(set_attr "type" "binary")
2678   (set_attr "length" "4")])
2679
2680(define_insn ""
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2683		  (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2684  "symbolic_operand (operands[2], Pmode)
2685   && ! function_label_operand (operands[2], Pmode)
2686   && TARGET_64BIT
2687   && flag_pic"
2688  "ldo RT'%G2(%1),%0"
2689  [(set_attr "type" "binary")
2690   (set_attr "length" "4")])
2691
2692;; Always use addil rather than ldil;add sequences.  This allows the
2693;; HP linker to eliminate the dp relocation if the symbolic operand
2694;; lives in the TEXT space.
2695(define_insn ""
2696  [(set (match_operand:SI 0 "register_operand" "=a")
2697	(high:SI (match_operand 1 "" "")))]
2698  "symbolic_operand (operands[1], Pmode)
2699   && ! function_label_operand (operands[1], Pmode)
2700   && ! read_only_operand (operands[1], Pmode)
2701   && ! flag_pic"
2702  "*
2703{
2704  if (TARGET_LONG_LOAD_STORE)
2705    return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2706  else
2707    return \"addil LR'%H1,%%r27\";
2708}"
2709  [(set_attr "type" "binary")
2710   (set (attr "length")
2711      (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2712		    (const_int 4)
2713		    (const_int 8)))])
2714
2715
2716;; This is for use in the prologue/epilogue code.  We need it
2717;; to add large constants to a stack pointer or frame pointer.
2718;; Because of the additional %r1 pressure, we probably do not
2719;; want to use this in general code, so make it available
2720;; only after reload.
2721(define_insn ""
2722  [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2723	(plus:SI (match_operand:SI 1 "register_operand" "r,r")
2724		 (high:SI (match_operand 2 "const_int_operand" ""))))]
2725  "reload_completed"
2726  "@
2727   addil L'%G2,%1
2728   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2729  [(set_attr "type" "binary,binary")
2730   (set_attr "length" "4,8")])
2731
2732(define_insn ""
2733  [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2734	(plus:DI (match_operand:DI 1 "register_operand" "r,r")
2735		 (high:DI (match_operand 2 "const_int_operand" ""))))]
2736  "reload_completed && TARGET_64BIT"
2737  "@
2738   addil L'%G2,%1
2739   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2740  [(set_attr "type" "binary,binary")
2741   (set_attr "length" "4,8")])
2742
2743(define_insn ""
2744  [(set (match_operand:SI 0 "register_operand" "=r")
2745	(high:SI (match_operand 1 "" "")))]
2746  "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2747    && !pa_is_function_label_plus_const (operands[1])"
2748  "*
2749{
2750  if (symbolic_operand (operands[1], Pmode))
2751    return \"ldil LR'%H1,%0\";
2752  else
2753    return \"ldil L'%G1,%0\";
2754}"
2755  [(set_attr "type" "move")
2756   (set_attr "length" "4")])
2757
2758(define_insn ""
2759  [(set (match_operand:DI 0 "register_operand" "=r")
2760	(high:DI (match_operand 1 "const_int_operand" "")))]
2761  "TARGET_64BIT"
2762  "ldil L'%G1,%0";
2763  [(set_attr "type" "move")
2764   (set_attr "length" "4")])
2765
2766(define_insn ""
2767  [(set (match_operand:DI 0 "register_operand" "=r")
2768	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2769		   (match_operand:DI 2 "const_int_operand" "i")))]
2770  "TARGET_64BIT"
2771  "ldo R'%G2(%1),%0";
2772  [(set_attr "type" "move")
2773   (set_attr "length" "4")])
2774
2775(define_insn ""
2776  [(set (match_operand:SI 0 "register_operand" "=r")
2777	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2778		   (match_operand:SI 2 "immediate_operand" "i")))]
2779  "!pa_is_function_label_plus_const (operands[2])"
2780  "*
2781{
2782  gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2783  
2784  if (symbolic_operand (operands[2], Pmode))
2785    return \"ldo RR'%G2(%1),%0\";
2786  else
2787    return \"ldo R'%G2(%1),%0\";
2788}"
2789  [(set_attr "type" "move")
2790   (set_attr "length" "4")])
2791
2792;; Now that a symbolic_address plus a constant is broken up early
2793;; in the compilation phase (for better CSE) we need a special
2794;; combiner pattern to load the symbolic address plus the constant
2795;; in only 2 instructions. (For cases where the symbolic address
2796;; was not a common subexpression.)
2797(define_split
2798  [(set (match_operand:SI 0 "register_operand" "")
2799	(match_operand:SI 1 "symbolic_operand" ""))
2800   (clobber (match_operand:SI 2 "register_operand" ""))]
2801  "! (flag_pic && pic_label_operand (operands[1], SImode))"
2802  [(set (match_dup 2) (high:SI (match_dup 1)))
2803   (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2804  "")
2805
2806;; hppa_legitimize_address goes to a great deal of trouble to
2807;; create addresses which use indexing.  In some cases, this
2808;; is a lose because there isn't any store instructions which
2809;; allow indexed addresses (with integer register source).
2810;;
2811;; These define_splits try to turn a 3 insn store into
2812;; a 2 insn store with some creative RTL rewriting.
2813(define_split
2814  [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2815			       (match_operand:SI 1 "mem_shadd_operand" ""))
2816		   (plus:SI (match_operand:SI 2 "register_operand" "")
2817			    (match_operand:SI 3 "const_int_operand" ""))))
2818	(match_operand:SI 4 "register_operand" ""))
2819   (clobber (match_operand:SI 5 "register_operand" ""))]
2820  ""
2821  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2822			       (match_dup 2)))
2823   (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2824  "
2825{
2826  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2827
2828}")
2829
2830(define_split
2831  [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2832			       (match_operand:SI 1 "mem_shadd_operand" ""))
2833		   (plus:SI (match_operand:SI 2 "register_operand" "")
2834			    (match_operand:SI 3 "const_int_operand" ""))))
2835	(match_operand:HI 4 "register_operand" ""))
2836   (clobber (match_operand:SI 5 "register_operand" ""))]
2837  ""
2838  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2839			       (match_dup 2)))
2840   (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2841  "
2842{
2843  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2844
2845}")
2846
2847(define_split
2848  [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2849			       (match_operand:SI 1 "mem_shadd_operand" ""))
2850		   (plus:SI (match_operand:SI 2 "register_operand" "")
2851			    (match_operand:SI 3 "const_int_operand" ""))))
2852	(match_operand:QI 4 "register_operand" ""))
2853   (clobber (match_operand:SI 5 "register_operand" ""))]
2854  ""
2855  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2856			       (match_dup 2)))
2857   (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2858  "
2859{
2860  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2861
2862}")
2863
2864(define_expand "movhi"
2865  [(set (match_operand:HI 0 "general_operand" "")
2866	(match_operand:HI 1 "general_operand" ""))]
2867  ""
2868  "
2869{
2870  if (pa_emit_move_sequence (operands, HImode, 0))
2871    DONE;
2872}")
2873
2874;; Handle HImode input reloads requiring a general register as a
2875;; scratch register.
2876(define_expand "reload_inhi"
2877  [(set (match_operand:HI 0 "register_operand" "=Z")
2878	(match_operand:HI 1 "non_hard_reg_operand" ""))
2879   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2880  ""
2881  "
2882{
2883  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2884    DONE;
2885
2886  /* We don't want the clobber emitted, so handle this ourselves.  */
2887  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2888  DONE;
2889}")
2890
2891;; Handle HImode output reloads requiring a general register as a
2892;; scratch register.
2893(define_expand "reload_outhi"
2894  [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2895	(match_operand:HI 1  "register_operand" "Z"))
2896   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2897  ""
2898  "
2899{
2900  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2901    DONE;
2902
2903  /* We don't want the clobber emitted, so handle this ourselves.  */
2904  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2905  DONE;
2906}")
2907
2908(define_insn ""
2909  [(set (match_operand:HI 0 "move_dest_operand"
2910	 		  "=r,r,r,r,r,Q,!*q,!r")
2911	(match_operand:HI 1 "move_src_operand"
2912			  "r,J,N,K,RQ,rM,!rM,!*q"))]
2913  "(register_operand (operands[0], HImode)
2914    || reg_or_0_operand (operands[1], HImode))"
2915  "@
2916   copy %1,%0
2917   ldi %1,%0
2918   ldil L'%1,%0
2919   {zdepi|depwi,z} %Z1,%0
2920   ldh%M1 %1,%0
2921   sth%M0 %r1,%0
2922   mtsar %r1
2923   {mfctl|mfctl,w} %sar,%0"
2924  [(set_attr "type" "move,move,move,shift,load,store,move,move")
2925   (set_attr "pa_combine_type" "addmove")
2926   (set_attr "length" "4,4,4,4,4,4,4,4")])
2927
2928(define_insn ""
2929  [(set (match_operand:HI 0 "register_operand" "=r")
2930	(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2931			 (match_operand:SI 2 "int5_operand" "L"))))
2932   (set (match_dup 1)
2933	(plus:SI (match_dup 1) (match_dup 2)))]
2934  ""
2935  "{ldhs|ldh},mb %2(%1),%0"
2936  [(set_attr "type" "load")
2937   (set_attr "length" "4")])
2938
2939(define_insn ""
2940  [(set (match_operand:HI 0 "register_operand" "=r")
2941	(mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2942			 (match_operand:DI 2 "int5_operand" "L"))))
2943   (set (match_dup 1)
2944	(plus:DI (match_dup 1) (match_dup 2)))]
2945  "TARGET_64BIT"
2946  "ldh,mb %2(%1),%0"
2947  [(set_attr "type" "load")
2948   (set_attr "length" "4")])
2949
2950; And a zero extended variant.
2951(define_insn ""
2952  [(set (match_operand:DI 0 "register_operand" "=r")
2953	(zero_extend:DI (mem:HI
2954			  (plus:DI
2955			    (match_operand:DI 1 "register_operand" "+r")
2956			    (match_operand:DI 2 "int5_operand" "L")))))
2957   (set (match_dup 1)
2958	(plus:DI (match_dup 1) (match_dup 2)))]
2959  "TARGET_64BIT"
2960  "ldh,mb %2(%1),%0"
2961  [(set_attr "type" "load")
2962   (set_attr "length" "4")])
2963
2964(define_insn ""
2965  [(set (match_operand:SI 0 "register_operand" "=r")
2966	(zero_extend:SI (mem:HI
2967			  (plus:SI
2968			    (match_operand:SI 1 "register_operand" "+r")
2969			    (match_operand:SI 2 "int5_operand" "L")))))
2970   (set (match_dup 1)
2971	(plus:SI (match_dup 1) (match_dup 2)))]
2972  ""
2973  "{ldhs|ldh},mb %2(%1),%0"
2974  [(set_attr "type" "load")
2975   (set_attr "length" "4")])
2976
2977(define_insn ""
2978  [(set (match_operand:SI 0 "register_operand" "=r")
2979	(zero_extend:SI (mem:HI
2980			  (plus:DI
2981			    (match_operand:DI 1 "register_operand" "+r")
2982			    (match_operand:DI 2 "int5_operand" "L")))))
2983   (set (match_dup 1)
2984	(plus:DI (match_dup 1) (match_dup 2)))]
2985  "TARGET_64BIT"
2986  "ldh,mb %2(%1),%0"
2987  [(set_attr "type" "load")
2988   (set_attr "length" "4")])
2989
2990(define_insn ""
2991  [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2992			 (match_operand:SI 1 "int5_operand" "L")))
2993	(match_operand:HI 2 "reg_or_0_operand" "rM"))
2994   (set (match_dup 0)
2995	(plus:SI (match_dup 0) (match_dup 1)))]
2996  ""
2997  "{sths|sth},mb %r2,%1(%0)"
2998  [(set_attr "type" "store")
2999   (set_attr "length" "4")])
3000
3001(define_insn ""
3002  [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3003			 (match_operand:DI 1 "int5_operand" "L")))
3004	(match_operand:HI 2 "reg_or_0_operand" "rM"))
3005   (set (match_dup 0)
3006	(plus:DI (match_dup 0) (match_dup 1)))]
3007  "TARGET_64BIT"
3008  "sth,mb %r2,%1(%0)"
3009  [(set_attr "type" "store")
3010   (set_attr "length" "4")])
3011
3012(define_insn "addhi3"
3013  [(set (match_operand:HI 0 "register_operand" "=r,r")
3014	(plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3015		 (match_operand:HI 2 "arith14_operand" "r,J")))]
3016  ""
3017  "@
3018   {addl|add,l} %1,%2,%0
3019   ldo %2(%1),%0"
3020  [(set_attr "type" "binary,binary")
3021   (set_attr "pa_combine_type" "addmove")
3022   (set_attr "length" "4,4")])
3023
3024(define_expand "movqi"
3025  [(set (match_operand:QI 0 "general_operand" "")
3026	(match_operand:QI 1 "general_operand" ""))]
3027  ""
3028  "
3029{
3030  if (pa_emit_move_sequence (operands, QImode, 0))
3031    DONE;
3032}")
3033
3034;; Handle QImode input reloads requiring a general register as a
3035;; scratch register.
3036(define_expand "reload_inqi"
3037  [(set (match_operand:QI 0 "register_operand" "=Z")
3038	(match_operand:QI 1 "non_hard_reg_operand" ""))
3039   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3040  ""
3041  "
3042{
3043  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3044    DONE;
3045
3046  /* We don't want the clobber emitted, so handle this ourselves.  */
3047  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3048  DONE;
3049}")
3050
3051;; Handle QImode output reloads requiring a general register as a
3052;; scratch register.
3053(define_expand "reload_outqi"
3054  [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3055	(match_operand:QI 1  "register_operand" "Z"))
3056   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3057  ""
3058  "
3059{
3060  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3061    DONE;
3062
3063  /* We don't want the clobber emitted, so handle this ourselves.  */
3064  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3065  DONE;
3066}")
3067
3068(define_insn ""
3069  [(set (match_operand:QI 0 "move_dest_operand"
3070			  "=r,r,r,r,r,Q,!*q,!r")
3071	(match_operand:QI 1 "move_src_operand"
3072			  "r,J,N,K,RQ,rM,!rM,!*q"))]
3073  "(register_operand (operands[0], QImode)
3074    || reg_or_0_operand (operands[1], QImode))"
3075  "@
3076   copy %1,%0
3077   ldi %1,%0
3078   ldil L'%1,%0
3079   {zdepi|depwi,z} %Z1,%0
3080   ldb%M1 %1,%0
3081   stb%M0 %r1,%0
3082   mtsar %r1
3083   {mfctl|mfctl,w} %%sar,%0"
3084  [(set_attr "type" "move,move,move,shift,load,store,move,move")
3085   (set_attr "pa_combine_type" "addmove")
3086   (set_attr "length" "4,4,4,4,4,4,4,4")])
3087
3088(define_insn ""
3089  [(set (match_operand:QI 0 "register_operand" "=r")
3090	(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3091			 (match_operand:SI 2 "int5_operand" "L"))))
3092   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3093  ""
3094  "{ldbs|ldb},mb %2(%1),%0"
3095  [(set_attr "type" "load")
3096   (set_attr "length" "4")])
3097
3098(define_insn ""
3099  [(set (match_operand:QI 0 "register_operand" "=r")
3100	(mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3101			 (match_operand:DI 2 "int5_operand" "L"))))
3102   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3103  "TARGET_64BIT"
3104  "ldb,mb %2(%1),%0"
3105  [(set_attr "type" "load")
3106   (set_attr "length" "4")])
3107
3108; Now the same thing with zero extensions.
3109(define_insn ""
3110  [(set (match_operand:DI 0 "register_operand" "=r")
3111	(zero_extend:DI (mem:QI (plus:DI
3112				  (match_operand:DI 1 "register_operand" "+r")
3113				  (match_operand:DI 2 "int5_operand" "L")))))
3114   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3115  "TARGET_64BIT"
3116  "ldb,mb %2(%1),%0"
3117  [(set_attr "type" "load")
3118   (set_attr "length" "4")])
3119
3120(define_insn ""
3121  [(set (match_operand:SI 0 "register_operand" "=r")
3122	(zero_extend:SI (mem:QI (plus:SI
3123				  (match_operand:SI 1 "register_operand" "+r")
3124				  (match_operand:SI 2 "int5_operand" "L")))))
3125   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3126  ""
3127  "{ldbs|ldb},mb %2(%1),%0"
3128  [(set_attr "type" "load")
3129   (set_attr "length" "4")])
3130
3131(define_insn ""
3132  [(set (match_operand:SI 0 "register_operand" "=r")
3133	(zero_extend:SI (mem:QI (plus:DI
3134				  (match_operand:DI 1 "register_operand" "+r")
3135				  (match_operand:DI 2 "int5_operand" "L")))))
3136   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3137  "TARGET_64BIT"
3138  "ldb,mb %2(%1),%0"
3139  [(set_attr "type" "load")
3140   (set_attr "length" "4")])
3141
3142(define_insn ""
3143  [(set (match_operand:HI 0 "register_operand" "=r")
3144	(zero_extend:HI (mem:QI (plus:SI
3145				  (match_operand:SI 1 "register_operand" "+r")
3146				  (match_operand:SI 2 "int5_operand" "L")))))
3147   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3148  ""
3149  "{ldbs|ldb},mb %2(%1),%0"
3150  [(set_attr "type" "load")
3151   (set_attr "length" "4")])
3152
3153(define_insn ""
3154  [(set (match_operand:HI 0 "register_operand" "=r")
3155	(zero_extend:HI (mem:QI (plus:DI
3156				  (match_operand:DI 1 "register_operand" "+r")
3157				  (match_operand:DI 2 "int5_operand" "L")))))
3158   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3159  "TARGET_64BIT"
3160  "ldb,mb %2(%1),%0"
3161  [(set_attr "type" "load")
3162   (set_attr "length" "4")])
3163
3164(define_insn ""
3165  [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3166			 (match_operand:SI 1 "int5_operand" "L")))
3167	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3168   (set (match_dup 0)
3169	(plus:SI (match_dup 0) (match_dup 1)))]
3170  ""
3171  "{stbs|stb},mb %r2,%1(%0)"
3172  [(set_attr "type" "store")
3173   (set_attr "length" "4")])
3174
3175(define_insn ""
3176  [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3177			 (match_operand:DI 1 "int5_operand" "L")))
3178	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3179   (set (match_dup 0)
3180	(plus:DI (match_dup 0) (match_dup 1)))]
3181  "TARGET_64BIT"
3182  "stb,mb %r2,%1(%0)"
3183  [(set_attr "type" "store")
3184   (set_attr "length" "4")])
3185
3186;; The definition of this insn does not really explain what it does,
3187;; but it should suffice that anything generated as this insn will be
3188;; recognized as a cpymemsi operation, and that it will not successfully
3189;; combine with anything.
3190(define_expand "cpymemsi"
3191  [(parallel [(set (match_operand:BLK 0 "" "")
3192		   (match_operand:BLK 1 "" ""))
3193	      (clobber (match_dup 4))
3194	      (clobber (match_dup 5))
3195	      (clobber (match_dup 6))
3196	      (clobber (match_dup 7))
3197	      (clobber (match_dup 8))
3198	      (use (match_operand:SI 2 "arith14_operand" ""))
3199	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3200  "!TARGET_64BIT && optimize > 0"
3201  "
3202{
3203  int size, align;
3204
3205  /* HP provides very fast block move library routine for the PA;
3206     this routine includes:
3207
3208	4x4 byte at a time block moves,
3209	1x4 byte at a time with alignment checked at runtime with
3210	    attempts to align the source and destination as needed
3211	1x1 byte loop
3212
3213     With that in mind, here's the heuristics to try and guess when
3214     the inlined block move will be better than the library block
3215     move:
3216
3217	If the size isn't constant, then always use the library routines.
3218
3219	If the size is large in respect to the known alignment, then use
3220	the library routines.
3221
3222	If the size is small in respect to the known alignment, then open
3223	code the copy (since that will lead to better scheduling).
3224
3225        Else use the block move pattern.   */
3226
3227  /* Undetermined size, use the library routine.  */
3228  if (GET_CODE (operands[2]) != CONST_INT)
3229    FAIL;
3230
3231  size = INTVAL (operands[2]);
3232  align = INTVAL (operands[3]);
3233  align = align > 4 ? 4 : (align ? align : 1);
3234
3235  /* If size/alignment is large, then use the library routines.  */
3236  if (size / align > 16)
3237    FAIL;
3238
3239  /* This does happen, but not often enough to worry much about.  */
3240  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3241    FAIL;
3242  
3243  /* Fall through means we're going to use our block move pattern.  */
3244  operands[0]
3245    = replace_equiv_address (operands[0],
3246			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3247  operands[1]
3248    = replace_equiv_address (operands[1],
3249			     copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3250  operands[4] = gen_reg_rtx (SImode);
3251  operands[5] = gen_reg_rtx (SImode);
3252  operands[6] = gen_reg_rtx (SImode);
3253  operands[7] = gen_reg_rtx (SImode);
3254  operands[8] = gen_reg_rtx (SImode);
3255}")
3256
3257;; The operand constraints are written like this to support both compile-time
3258;; and run-time determined byte counts.  The expander and pa_output_block_move
3259;; only support compile-time determined counts at this time.
3260;;
3261;; If the count is run-time determined, the register with the byte count
3262;; is clobbered by the copying code, and therefore it is forced to operand 2.
3263;;
3264;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3265;; broke this semantic for pseudo registers.  We can't use match_scratch
3266;; as this requires two registers in the class R1_REGS when the MEMs for
3267;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3268;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3269;; respectively.  We then split or peephole optimize after reload.
3270(define_insn "cpymemsi_prereload"
3271  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3272	(mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3273   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3274   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3275   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3276   (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))	;item tmp3
3277   (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))	;item tmp4
3278   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3279   (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3280  "!TARGET_64BIT"
3281  "#"
3282  [(set_attr "type" "multi,multi")])
3283
3284(define_split
3285  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3286		   (match_operand:BLK 1 "memory_operand" ""))
3287	      (clobber (match_operand:SI 2 "register_operand" ""))
3288	      (clobber (match_operand:SI 3 "register_operand" ""))
3289	      (clobber (match_operand:SI 6 "register_operand" ""))
3290	      (clobber (match_operand:SI 7 "register_operand" ""))
3291	      (clobber (match_operand:SI 8 "register_operand" ""))
3292	      (use (match_operand:SI 4 "arith14_operand" ""))
3293	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3294  "!TARGET_64BIT && reload_completed && !flag_peephole2
3295   && GET_CODE (operands[0]) == MEM
3296   && register_operand (XEXP (operands[0], 0), SImode)
3297   && GET_CODE (operands[1]) == MEM
3298   && register_operand (XEXP (operands[1], 0), SImode)"
3299  [(set (match_dup 7) (match_dup 9))
3300   (set (match_dup 8) (match_dup 10))
3301   (parallel [(set (match_dup 0) (match_dup 1))
3302   	      (clobber (match_dup 2))
3303   	      (clobber (match_dup 3))
3304   	      (clobber (match_dup 6))
3305   	      (clobber (match_dup 7))
3306   	      (clobber (match_dup 8))
3307   	      (use (match_dup 4))
3308   	      (use (match_dup 5))
3309	      (const_int 0)])]
3310  "
3311{
3312  operands[9] = XEXP (operands[0], 0);
3313  operands[10] = XEXP (operands[1], 0);
3314  operands[0] = replace_equiv_address (operands[0], operands[7]);
3315  operands[1] = replace_equiv_address (operands[1], operands[8]);
3316}")
3317
3318(define_peephole2
3319  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3320		   (match_operand:BLK 1 "memory_operand" ""))
3321	      (clobber (match_operand:SI 2 "register_operand" ""))
3322	      (clobber (match_operand:SI 3 "register_operand" ""))
3323	      (clobber (match_operand:SI 6 "register_operand" ""))
3324	      (clobber (match_operand:SI 7 "register_operand" ""))
3325	      (clobber (match_operand:SI 8 "register_operand" ""))
3326	      (use (match_operand:SI 4 "arith14_operand" ""))
3327	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3328  "!TARGET_64BIT
3329   && GET_CODE (operands[0]) == MEM
3330   && register_operand (XEXP (operands[0], 0), SImode)
3331   && GET_CODE (operands[1]) == MEM
3332   && register_operand (XEXP (operands[1], 0), SImode)"
3333  [(parallel [(set (match_dup 0) (match_dup 1))
3334   	      (clobber (match_dup 2))
3335   	      (clobber (match_dup 3))
3336   	      (clobber (match_dup 6))
3337   	      (clobber (match_dup 7))
3338   	      (clobber (match_dup 8))
3339   	      (use (match_dup 4))
3340   	      (use (match_dup 5))
3341	      (const_int 0)])]
3342  "
3343{
3344  rtx addr = XEXP (operands[0], 0);
3345  if (dead_or_set_p (curr_insn, addr))
3346    operands[7] = addr;
3347  else
3348    {
3349      emit_insn (gen_rtx_SET (operands[7], addr));
3350      operands[0] = replace_equiv_address (operands[0], operands[7]);
3351    }
3352
3353  addr = XEXP (operands[1], 0);
3354  if (dead_or_set_p (curr_insn, addr))
3355    operands[8] = addr;
3356  else
3357    {
3358      emit_insn (gen_rtx_SET (operands[8], addr));
3359      operands[1] = replace_equiv_address (operands[1], operands[8]);
3360    }
3361}")
3362
3363(define_insn "cpymemsi_postreload"
3364  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3365	(mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3366   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3367   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3368   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3369   (clobber (match_dup 0))
3370   (clobber (match_dup 1))
3371   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3372   (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3373   (const_int 0)]
3374  "!TARGET_64BIT && reload_completed"
3375  "* return pa_output_block_move (operands, !which_alternative);"
3376  [(set_attr "type" "multi,multi")])
3377
3378(define_expand "cpymemdi"
3379  [(parallel [(set (match_operand:BLK 0 "" "")
3380		   (match_operand:BLK 1 "" ""))
3381	      (clobber (match_dup 4))
3382	      (clobber (match_dup 5))
3383	      (clobber (match_dup 6))
3384	      (clobber (match_dup 7))
3385	      (clobber (match_dup 8))
3386	      (use (match_operand:DI 2 "arith14_operand" ""))
3387	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3388  "TARGET_64BIT && optimize > 0"
3389  "
3390{
3391  int size, align;
3392
3393  /* HP provides very fast block move library routine for the PA;
3394     this routine includes:
3395
3396	4x4 byte at a time block moves,
3397	1x4 byte at a time with alignment checked at runtime with
3398	    attempts to align the source and destination as needed
3399	1x1 byte loop
3400
3401     With that in mind, here's the heuristics to try and guess when
3402     the inlined block move will be better than the library block
3403     move:
3404
3405	If the size isn't constant, then always use the library routines.
3406
3407	If the size is large in respect to the known alignment, then use
3408	the library routines.
3409
3410	If the size is small in respect to the known alignment, then open
3411	code the copy (since that will lead to better scheduling).
3412
3413        Else use the block move pattern.   */
3414
3415  /* Undetermined size, use the library routine.  */
3416  if (GET_CODE (operands[2]) != CONST_INT)
3417    FAIL;
3418
3419  size = INTVAL (operands[2]);
3420  align = INTVAL (operands[3]);
3421  align = align > 8 ? 8 : (align ? align : 1);
3422
3423  /* If size/alignment is large, then use the library routines.  */
3424  if (size / align > 16)
3425    FAIL;
3426
3427  /* This does happen, but not often enough to worry much about.  */
3428  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3429    FAIL;
3430  
3431  /* Fall through means we're going to use our block move pattern.  */
3432  operands[0]
3433    = replace_equiv_address (operands[0],
3434			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3435  operands[1]
3436    = replace_equiv_address (operands[1],
3437			     copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3438  operands[4] = gen_reg_rtx (DImode);
3439  operands[5] = gen_reg_rtx (DImode);
3440  operands[6] = gen_reg_rtx (DImode);
3441  operands[7] = gen_reg_rtx (DImode);
3442  operands[8] = gen_reg_rtx (DImode);
3443}")
3444
3445;; The operand constraints are written like this to support both compile-time
3446;; and run-time determined byte counts.  The expander and pa_output_block_move
3447;; only support compile-time determined counts at this time.
3448;;
3449;; If the count is run-time determined, the register with the byte count
3450;; is clobbered by the copying code, and therefore it is forced to operand 2.
3451;;
3452;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3453;; broke this semantic for pseudo registers.  We can't use match_scratch
3454;; as this requires two registers in the class R1_REGS when the MEMs for
3455;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3456;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3457;; respectively.  We then split or peephole optimize after reload.
3458(define_insn "cpymemdi_prereload"
3459  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3460	(mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3461   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3462   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3463   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3464   (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))	;item tmp3
3465   (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))	;item tmp4
3466   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3467   (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3468  "TARGET_64BIT"
3469  "#"
3470  [(set_attr "type" "multi,multi")])
3471
3472(define_split
3473  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3474		   (match_operand:BLK 1 "memory_operand" ""))
3475	      (clobber (match_operand:DI 2 "register_operand" ""))
3476	      (clobber (match_operand:DI 3 "register_operand" ""))
3477	      (clobber (match_operand:DI 6 "register_operand" ""))
3478	      (clobber (match_operand:DI 7 "register_operand" ""))
3479	      (clobber (match_operand:DI 8 "register_operand" ""))
3480	      (use (match_operand:DI 4 "arith14_operand" ""))
3481	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3482  "TARGET_64BIT && reload_completed && !flag_peephole2
3483   && GET_CODE (operands[0]) == MEM
3484   && register_operand (XEXP (operands[0], 0), DImode)
3485   && GET_CODE (operands[1]) == MEM
3486   && register_operand (XEXP (operands[1], 0), DImode)"
3487  [(set (match_dup 7) (match_dup 9))
3488   (set (match_dup 8) (match_dup 10))
3489   (parallel [(set (match_dup 0) (match_dup 1))
3490   	      (clobber (match_dup 2))
3491   	      (clobber (match_dup 3))
3492   	      (clobber (match_dup 6))
3493   	      (clobber (match_dup 7))
3494   	      (clobber (match_dup 8))
3495   	      (use (match_dup 4))
3496   	      (use (match_dup 5))
3497	      (const_int 0)])]
3498  "
3499{
3500  operands[9] = XEXP (operands[0], 0);
3501  operands[10] = XEXP (operands[1], 0);
3502  operands[0] = replace_equiv_address (operands[0], operands[7]);
3503  operands[1] = replace_equiv_address (operands[1], operands[8]);
3504}")
3505
3506(define_peephole2
3507  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3508		   (match_operand:BLK 1 "memory_operand" ""))
3509	      (clobber (match_operand:DI 2 "register_operand" ""))
3510	      (clobber (match_operand:DI 3 "register_operand" ""))
3511	      (clobber (match_operand:DI 6 "register_operand" ""))
3512	      (clobber (match_operand:DI 7 "register_operand" ""))
3513	      (clobber (match_operand:DI 8 "register_operand" ""))
3514	      (use (match_operand:DI 4 "arith14_operand" ""))
3515	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3516  "TARGET_64BIT
3517   && GET_CODE (operands[0]) == MEM
3518   && register_operand (XEXP (operands[0], 0), DImode)
3519   && GET_CODE (operands[1]) == MEM
3520   && register_operand (XEXP (operands[1], 0), DImode)"
3521  [(parallel [(set (match_dup 0) (match_dup 1))
3522   	      (clobber (match_dup 2))
3523   	      (clobber (match_dup 3))
3524   	      (clobber (match_dup 6))
3525   	      (clobber (match_dup 7))
3526   	      (clobber (match_dup 8))
3527   	      (use (match_dup 4))
3528   	      (use (match_dup 5))
3529	      (const_int 0)])]
3530  "
3531{
3532  rtx addr = XEXP (operands[0], 0);
3533  if (dead_or_set_p (curr_insn, addr))
3534    operands[7] = addr;
3535  else
3536    {
3537      emit_insn (gen_rtx_SET (operands[7], addr));
3538      operands[0] = replace_equiv_address (operands[0], operands[7]);
3539    }
3540
3541  addr = XEXP (operands[1], 0);
3542  if (dead_or_set_p (curr_insn, addr))
3543    operands[8] = addr;
3544  else
3545    {
3546      emit_insn (gen_rtx_SET (operands[8], addr));
3547      operands[1] = replace_equiv_address (operands[1], operands[8]);
3548    }
3549}")
3550
3551(define_insn "cpymemdi_postreload"
3552  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3553	(mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3554   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3555   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3556   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3557   (clobber (match_dup 0))
3558   (clobber (match_dup 1))
3559   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3560   (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3561   (const_int 0)]
3562  "TARGET_64BIT && reload_completed"
3563  "* return pa_output_block_move (operands, !which_alternative);"
3564  [(set_attr "type" "multi,multi")])
3565
3566(define_expand "setmemsi"
3567  [(parallel [(set (match_operand:BLK 0 "" "")
3568		   (match_operand 2 "const_int_operand" ""))
3569	      (clobber (match_dup 4))
3570	      (clobber (match_dup 5))
3571	      (use (match_operand:SI 1 "arith14_operand" ""))
3572	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3573  "!TARGET_64BIT && optimize > 0"
3574  "
3575{
3576  int size, align;
3577
3578  /* If value to set is not zero, use the library routine.  */
3579  if (operands[2] != const0_rtx)
3580    FAIL;
3581
3582  /* Undetermined size, use the library routine.  */
3583  if (GET_CODE (operands[1]) != CONST_INT)
3584    FAIL;
3585
3586  size = INTVAL (operands[1]);
3587  align = INTVAL (operands[3]);
3588  align = align > 4 ? 4 : align;
3589
3590  /* If size/alignment is large, then use the library routines.  */
3591  if (size / align > 16)
3592    FAIL;
3593
3594  /* This does happen, but not often enough to worry much about.  */
3595  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3596    FAIL;
3597  
3598  /* Fall through means we're going to use our block clear pattern.  */
3599  operands[0]
3600    = replace_equiv_address (operands[0],
3601			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3602  operands[4] = gen_reg_rtx (SImode);
3603  operands[5] = gen_reg_rtx (SImode);
3604}")
3605
3606(define_insn "clrmemsi_prereload"
3607  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3608	(const_int 0))
3609   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3610   (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))	;tmp1
3611   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3612   (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3613  "!TARGET_64BIT"
3614  "#"
3615  [(set_attr "type" "multi,multi")])
3616
3617(define_split
3618  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3619		   (const_int 0))
3620	      (clobber (match_operand:SI 1 "register_operand" ""))
3621	      (clobber (match_operand:SI 4 "register_operand" ""))
3622	      (use (match_operand:SI 2 "arith14_operand" ""))
3623	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3624  "!TARGET_64BIT && reload_completed && !flag_peephole2
3625   && GET_CODE (operands[0]) == MEM
3626   && register_operand (XEXP (operands[0], 0), SImode)"
3627  [(set (match_dup 4) (match_dup 5))
3628   (parallel [(set (match_dup 0) (const_int 0))
3629   	      (clobber (match_dup 1))
3630   	      (clobber (match_dup 4))
3631   	      (use (match_dup 2))
3632   	      (use (match_dup 3))
3633	      (const_int 0)])]
3634  "
3635{
3636  operands[5] = XEXP (operands[0], 0);
3637  operands[0] = replace_equiv_address (operands[0], operands[4]);
3638}")
3639
3640(define_peephole2
3641  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3642		   (const_int 0))
3643	      (clobber (match_operand:SI 1 "register_operand" ""))
3644	      (clobber (match_operand:SI 4 "register_operand" ""))
3645	      (use (match_operand:SI 2 "arith14_operand" ""))
3646	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3647  "!TARGET_64BIT
3648   && GET_CODE (operands[0]) == MEM
3649   && register_operand (XEXP (operands[0], 0), SImode)"
3650  [(parallel [(set (match_dup 0) (const_int 0))
3651   	      (clobber (match_dup 1))
3652   	      (clobber (match_dup 4))
3653   	      (use (match_dup 2))
3654   	      (use (match_dup 3))
3655	      (const_int 0)])]
3656  "
3657{
3658  rtx addr = XEXP (operands[0], 0);
3659  if (dead_or_set_p (curr_insn, addr))
3660    operands[4] = addr;
3661  else
3662    {
3663      emit_insn (gen_rtx_SET (operands[4], addr));
3664      operands[0] = replace_equiv_address (operands[0], operands[4]);
3665    }
3666}")
3667
3668(define_insn "clrmemsi_postreload"
3669  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3670	(const_int 0))
3671   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3672   (clobber (match_dup 0))
3673   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3674   (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3675   (const_int 0)]
3676  "!TARGET_64BIT && reload_completed"
3677  "* return pa_output_block_clear (operands, !which_alternative);"
3678  [(set_attr "type" "multi,multi")])
3679
3680(define_expand "setmemdi"
3681  [(parallel [(set (match_operand:BLK 0 "" "")
3682		   (match_operand 2 "const_int_operand" ""))
3683	      (clobber (match_dup 4))
3684	      (clobber (match_dup 5))
3685	      (use (match_operand:DI 1 "arith14_operand" ""))
3686	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3687  "TARGET_64BIT && optimize > 0"
3688  "
3689{
3690  int size, align;
3691
3692  /* If value to set is not zero, use the library routine.  */
3693  if (operands[2] != const0_rtx)
3694    FAIL;
3695
3696  /* Undetermined size, use the library routine.  */
3697  if (GET_CODE (operands[1]) != CONST_INT)
3698    FAIL;
3699
3700  size = INTVAL (operands[1]);
3701  align = INTVAL (operands[3]);
3702  align = align > 8 ? 8 : align;
3703
3704  /* If size/alignment is large, then use the library routines.  */
3705  if (size / align > 16)
3706    FAIL;
3707
3708  /* This does happen, but not often enough to worry much about.  */
3709  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3710    FAIL;
3711  
3712  /* Fall through means we're going to use our block clear pattern.  */
3713  operands[0]
3714    = replace_equiv_address (operands[0],
3715			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3716  operands[4] = gen_reg_rtx (DImode);
3717  operands[5] = gen_reg_rtx (DImode);
3718}")
3719
3720(define_insn "clrmemdi_prereload"
3721  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3722	(const_int 0))
3723   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3724   (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))	;item tmp1
3725   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3726   (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3727  "TARGET_64BIT"
3728  "#"
3729  [(set_attr "type" "multi,multi")])
3730
3731(define_split
3732  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3733		   (const_int 0))
3734	      (clobber (match_operand:DI 1 "register_operand" ""))
3735	      (clobber (match_operand:DI 4 "register_operand" ""))
3736	      (use (match_operand:DI 2 "arith14_operand" ""))
3737	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3738  "TARGET_64BIT && reload_completed && !flag_peephole2
3739   && GET_CODE (operands[0]) == MEM
3740   && register_operand (XEXP (operands[0], 0), DImode)"
3741  [(set (match_dup 4) (match_dup 5))
3742   (parallel [(set (match_dup 0) (const_int 0))
3743   	      (clobber (match_dup 1))
3744   	      (clobber (match_dup 4))
3745   	      (use (match_dup 2))
3746   	      (use (match_dup 3))
3747	      (const_int 0)])]
3748  "
3749{
3750  operands[5] = XEXP (operands[0], 0);
3751  operands[0] = replace_equiv_address (operands[0], operands[4]);
3752}")
3753
3754(define_peephole2
3755  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3756		   (const_int 0))
3757	      (clobber (match_operand:DI 1 "register_operand" ""))
3758	      (clobber (match_operand:DI 4 "register_operand" ""))
3759	      (use (match_operand:DI 2 "arith14_operand" ""))
3760	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3761  "TARGET_64BIT
3762   && GET_CODE (operands[0]) == MEM
3763   && register_operand (XEXP (operands[0], 0), DImode)"
3764  [(parallel [(set (match_dup 0) (const_int 0))
3765   	      (clobber (match_dup 1))
3766   	      (clobber (match_dup 4))
3767   	      (use (match_dup 2))
3768   	      (use (match_dup 3))
3769	      (const_int 0)])]
3770  "
3771{  
3772  rtx addr = XEXP (operands[0], 0);
3773  if (dead_or_set_p (curr_insn, addr))
3774    operands[4] = addr;
3775  else
3776    {
3777      emit_insn (gen_rtx_SET (operands[4], addr));
3778      operands[0] = replace_equiv_address (operands[0], operands[4]);
3779    }
3780}")
3781
3782(define_insn "clrmemdi_postreload"
3783  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3784	(const_int 0))
3785   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3786   (clobber (match_dup 0))
3787   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3788   (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3789   (const_int 0)]
3790  "TARGET_64BIT && reload_completed"
3791  "* return pa_output_block_clear (operands, !which_alternative);"
3792  [(set_attr "type" "multi,multi")])
3793
3794;; Floating point move insns
3795
3796(define_expand "movdf"
3797  [(set (match_operand:DF 0 "general_operand" "")
3798	(match_operand:DF 1 "general_operand" ""))]
3799  ""
3800  "
3801{
3802  if (pa_emit_move_sequence (operands, DFmode, 0))
3803    DONE;
3804}")
3805
3806;; Handle DFmode input reloads requiring %r1 as a scratch register.
3807(define_expand "reload_indf_r1"
3808  [(set (match_operand:DF 0 "register_operand" "=Z")
3809	(match_operand:DF 1 "non_hard_reg_operand" ""))
3810   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3811  ""
3812  "
3813{
3814  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3815    DONE;
3816
3817  /* We don't want the clobber emitted, so handle this ourselves.  */
3818  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3819  DONE;
3820}")
3821
3822;; Handle DFmode input reloads requiring a general register as a
3823;; scratch register.
3824(define_expand "reload_indf"
3825  [(set (match_operand:DF 0 "register_operand" "=Z")
3826	(match_operand:DF 1 "non_hard_reg_operand" ""))
3827   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3828  ""
3829  "
3830{
3831  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3832    DONE;
3833
3834  /* We don't want the clobber emitted, so handle this ourselves.  */
3835  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3836  DONE;
3837}")
3838
3839;; Handle DFmode output reloads requiring a general register as a
3840;; scratch register.
3841(define_expand "reload_outdf" 
3842 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3843	(match_operand:DF 1  "register_operand" "Z"))
3844   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3845  ""
3846  "
3847{
3848  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3849    DONE;
3850
3851  /* We don't want the clobber emitted, so handle this ourselves.  */
3852  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3853  DONE;
3854}")
3855
3856(define_insn ""
3857  [(set (match_operand:DF 0 "move_dest_operand"
3858			  "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3859	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3860			  "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3861  "(register_operand (operands[0], DFmode)
3862    || reg_or_0_operand (operands[1], DFmode))
3863   && !(GET_CODE (operands[1]) == CONST_DOUBLE
3864	&& GET_CODE (operands[0]) == MEM)
3865   && !TARGET_64BIT
3866   && !TARGET_SOFT_FLOAT"
3867  "*
3868{
3869  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3870       || operands[1] == CONST0_RTX (DFmode))
3871      && !(REG_P (operands[0]) && REG_P (operands[1])
3872	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3873    return pa_output_fp_move_double (operands);
3874  return pa_output_move_double (operands);
3875}"
3876  [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3877   (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3878
3879(define_insn ""
3880  [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3881	(match_operand:DF 1 "reg_or_0_operand" "f"))]
3882  "!TARGET_SOFT_FLOAT
3883   && !TARGET_DISABLE_INDEXING
3884   && reload_completed"
3885  "fstd%F0 %1,%0"
3886  [(set_attr "type" "fpstore")
3887   (set_attr "pa_combine_type" "addmove")
3888   (set_attr "length" "4")])
3889
3890(define_peephole2
3891  [(set (match_operand:SI 0 "register_operand" "")
3892	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3893			    (const_int 3))
3894		 (match_operand:SI 2 "register_operand" "")))
3895   (set (mem:DF (match_dup 0))
3896        (match_operand:DF 3 "register_operand" ""))]
3897  "!TARGET_SOFT_FLOAT
3898   && !TARGET_DISABLE_INDEXING
3899   && REG_OK_FOR_BASE_P (operands[2])
3900   && FP_REGNO_P (REGNO (operands[3]))"
3901  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3902	(match_dup 3))
3903   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3904			       (match_dup 2)))]
3905  "")
3906
3907(define_peephole2
3908  [(set (match_operand:SI 0 "register_operand" "")
3909	(plus:SI (match_operand:SI 2 "register_operand" "")
3910		 (ashift:SI (match_operand:SI 1 "register_operand" "")
3911			    (const_int 3))))
3912   (set (mem:DF (match_dup 0))
3913        (match_operand:DF 3 "register_operand" ""))]
3914  "!TARGET_SOFT_FLOAT
3915   && !TARGET_DISABLE_INDEXING
3916   && REG_OK_FOR_BASE_P (operands[2])
3917   && FP_REGNO_P (REGNO (operands[3]))"
3918  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3919	(match_dup 3))
3920   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3921			       (match_dup 2)))]
3922  "")
3923
3924(define_peephole2
3925  [(set (match_operand:DI 0 "register_operand" "")
3926	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
3927			    (const_int 3))
3928		 (match_operand:DI 2 "register_operand" "")))
3929   (set (mem:DF (match_dup 0))
3930        (match_operand:DF 3 "register_operand" ""))]
3931  "!TARGET_SOFT_FLOAT
3932   && !TARGET_DISABLE_INDEXING
3933   && TARGET_64BIT
3934   && REG_OK_FOR_BASE_P (operands[2])
3935   && FP_REGNO_P (REGNO (operands[3]))"
3936  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3937	(match_dup 3))
3938   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3939			       (match_dup 2)))]
3940  "")
3941
3942(define_peephole2
3943  [(set (match_operand:DI 0 "register_operand" "")
3944	(plus:DI (match_operand:DI 2 "register_operand" "")
3945		 (ashift:DI (match_operand:DI 1 "register_operand" "")
3946			    (const_int 3))))
3947   (set (mem:DF (match_dup 0))
3948        (match_operand:DF 3 "register_operand" ""))]
3949  "!TARGET_SOFT_FLOAT
3950   && !TARGET_DISABLE_INDEXING
3951   && TARGET_64BIT
3952   && REG_OK_FOR_BASE_P (operands[2])
3953   && FP_REGNO_P (REGNO (operands[3]))"
3954  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3955	(match_dup 3))
3956   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3957			       (match_dup 2)))]
3958  "")
3959
3960(define_peephole2
3961  [(set (match_operand:SI 0 "register_operand" "")
3962	(plus:SI (match_operand:SI 1 "register_operand" "")
3963		 (match_operand:SI 2 "register_operand" "")))
3964   (set (mem:DF (match_dup 0))
3965        (match_operand:DF 3 "register_operand" ""))]
3966  "!TARGET_SOFT_FLOAT
3967   && !TARGET_DISABLE_INDEXING
3968   && TARGET_NO_SPACE_REGS
3969   && REG_OK_FOR_INDEX_P (operands[1])
3970   && REG_OK_FOR_BASE_P (operands[2])
3971   && FP_REGNO_P (REGNO (operands[3]))"
3972  [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3973	(match_dup 3))
3974   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3975  "")
3976
3977(define_peephole2
3978  [(set (match_operand:SI 0 "register_operand" "")
3979	(plus:SI (match_operand:SI 1 "register_operand" "")
3980		 (match_operand:SI 2 "register_operand" "")))
3981   (set (mem:DF (match_dup 0))
3982        (match_operand:DF 3 "register_operand" ""))]
3983  "!TARGET_SOFT_FLOAT
3984   && !TARGET_DISABLE_INDEXING
3985   && TARGET_NO_SPACE_REGS
3986   && REG_OK_FOR_BASE_P (operands[1])
3987   && REG_OK_FOR_INDEX_P (operands[2])
3988   && FP_REGNO_P (REGNO (operands[3]))"
3989  [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3990	(match_dup 3))
3991   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3992  "")
3993
3994(define_peephole2
3995  [(set (match_operand:DI 0 "register_operand" "")
3996	(plus:DI (match_operand:DI 1 "register_operand" "")
3997		 (match_operand:DI 2 "register_operand" "")))
3998   (set (mem:DF (match_dup 0))
3999        (match_operand:DF 3 "register_operand" ""))]
4000  "!TARGET_SOFT_FLOAT
4001   && !TARGET_DISABLE_INDEXING
4002   && TARGET_64BIT
4003   && TARGET_NO_SPACE_REGS
4004   && REG_OK_FOR_INDEX_P (operands[1])
4005   && REG_OK_FOR_BASE_P (operands[2])
4006   && FP_REGNO_P (REGNO (operands[3]))"
4007  [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4008	(match_dup 3))
4009   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4010  "")
4011
4012(define_peephole2
4013  [(set (match_operand:DI 0 "register_operand" "")
4014	(plus:DI (match_operand:DI 1 "register_operand" "")
4015		 (match_operand:DI 2 "register_operand" "")))
4016   (set (mem:DF (match_dup 0))
4017        (match_operand:DF 3 "register_operand" ""))]
4018  "!TARGET_SOFT_FLOAT
4019   && !TARGET_DISABLE_INDEXING
4020   && TARGET_64BIT
4021   && TARGET_NO_SPACE_REGS
4022   && REG_OK_FOR_BASE_P (operands[1])
4023   && REG_OK_FOR_INDEX_P (operands[2])
4024   && FP_REGNO_P (REGNO (operands[3]))"
4025  [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4026	(match_dup 3))
4027   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4028  "")
4029
4030(define_insn ""
4031  [(set (match_operand:DF 0 "move_dest_operand"
4032			  "=r,?o,?Q,r,r")
4033	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4034			  "rG,r,r,o,RQ"))]
4035  "(register_operand (operands[0], DFmode)
4036    || reg_or_0_operand (operands[1], DFmode))
4037   && !TARGET_64BIT
4038   && TARGET_SOFT_FLOAT"
4039  "*
4040{
4041  return pa_output_move_double (operands);
4042}"
4043  [(set_attr "type" "move,store,store,load,load")
4044   (set_attr "length" "8,8,16,8,16")])
4045
4046(define_insn ""
4047  [(set (match_operand:DF 0 "move_dest_operand"
4048			  "=!*r,*r,*r,*r,*r,Q,f,f,T")
4049	(match_operand:DF 1 "move_src_operand"
4050			  "!*rG,J,N,K,RQ,*rG,fG,RT,f"))]
4051  "(register_operand (operands[0], DFmode)
4052    || reg_or_0_operand (operands[1], DFmode))
4053   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4054  "@
4055   copy %r1,%0
4056   ldi %1,%0
4057   ldil L'%1,%0
4058   depdi,z %z1,%0
4059   ldd%M1 %1,%0
4060   std%M0 %r1,%0
4061   fcpy,dbl %f1,%0
4062   fldd%F1 %1,%0
4063   fstd%F0 %1,%0"
4064  [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4065   (set_attr "pa_combine_type" "addmove")
4066   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4067
4068(define_insn ""
4069  [(set (match_operand:DF 0 "move_dest_operand"
4070			  "=!*r,*r,*r,*r,*r,Q")
4071	(match_operand:DF 1 "move_src_operand"
4072			  "!*rG,J,N,K,RQ,*rG"))]
4073  "(register_operand (operands[0], DFmode)
4074    || reg_or_0_operand (operands[1], DFmode))
4075   && TARGET_SOFT_FLOAT && TARGET_64BIT"
4076  "@
4077   copy %r1,%0
4078   ldi %1,%0
4079   ldil L'%1,%0
4080   depdi,z %z1,%0
4081   ldd%M1 %1,%0
4082   std%M0 %r1,%0"
4083  [(set_attr "type" "move,move,move,shift,load,store")
4084   (set_attr "pa_combine_type" "addmove")
4085   (set_attr "length" "4,4,4,4,4,4")])
4086
4087
4088(define_expand "movdi"
4089  [(set (match_operand:DI 0 "general_operand" "")
4090	(match_operand:DI 1 "general_operand" ""))]
4091  ""
4092  "
4093{
4094  if (pa_emit_move_sequence (operands, DImode, 0))
4095    DONE;
4096}")
4097
4098;; Handle DImode input reloads requiring %r1 as a scratch register.
4099(define_expand "reload_indi_r1"
4100  [(set (match_operand:DI 0 "register_operand" "=Z")
4101	(match_operand:DI 1 "non_hard_reg_operand" ""))
4102   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4103  ""
4104  "
4105{
4106  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4107    DONE;
4108
4109  /* We don't want the clobber emitted, so handle this ourselves.  */
4110  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4111  DONE;
4112}")
4113
4114;; Handle DImode input reloads requiring a general register as a
4115;; scratch register.
4116(define_expand "reload_indi"
4117  [(set (match_operand:DI 0 "register_operand" "=Z")
4118	(match_operand:DI 1 "non_hard_reg_operand" ""))
4119   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4120  ""
4121  "
4122{
4123  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4124    DONE;
4125
4126  /* We don't want the clobber emitted, so handle this ourselves.  */
4127  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4128  DONE;
4129}")
4130
4131;; Handle DImode output reloads requiring a general register as a
4132;; scratch register.
4133(define_expand "reload_outdi"
4134  [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4135	(match_operand:DI 1 "register_operand" "Z"))
4136   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4137  ""
4138  "
4139{
4140  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4141    DONE;
4142
4143  /* We don't want the clobber emitted, so handle this ourselves.  */
4144  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4145  DONE;
4146}")
4147
4148(define_insn ""
4149  [(set (match_operand:DI 0 "register_operand" "=r")
4150	(high:DI (match_operand 1 "" "")))]
4151  "!TARGET_64BIT"
4152  "*
4153{
4154  rtx op0 = operands[0];
4155  rtx op1 = operands[1];
4156
4157  switch (GET_CODE (op1))
4158    {
4159    case CONST_INT:
4160#if HOST_BITS_PER_WIDE_INT <= 32
4161      operands[0] = operand_subword (op0, 1, 0, DImode);
4162      output_asm_insn (\"ldil L'%1,%0\", operands);
4163
4164      operands[0] = operand_subword (op0, 0, 0, DImode);
4165      if (INTVAL (op1) < 0)
4166	output_asm_insn (\"ldi -1,%0\", operands);
4167      else
4168	output_asm_insn (\"ldi 0,%0\", operands);
4169#else
4170      operands[0] = operand_subword (op0, 1, 0, DImode);
4171      operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4172      output_asm_insn (\"ldil L'%1,%0\", operands);
4173
4174      operands[0] = operand_subword (op0, 0, 0, DImode);
4175      operands[1] = GEN_INT (INTVAL (op1) >> 32);
4176      output_asm_insn (pa_singlemove_string (operands), operands);
4177#endif
4178      break;
4179
4180    case CONST_DOUBLE:
4181      operands[0] = operand_subword (op0, 1, 0, DImode);
4182      operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4183      output_asm_insn (\"ldil L'%1,%0\", operands);
4184
4185      operands[0] = operand_subword (op0, 0, 0, DImode);
4186      operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4187      output_asm_insn (pa_singlemove_string (operands), operands);
4188      break;
4189
4190    default:
4191      gcc_unreachable ();
4192    }
4193  return \"\";
4194}"
4195  [(set_attr "type" "move")
4196   (set_attr "length" "12")])
4197
4198(define_insn ""
4199  [(set (match_operand:DI 0 "move_dest_operand"
4200			  "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4201	(match_operand:DI 1 "move_src_operand"
4202			  "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4203  "(register_operand (operands[0], DImode)
4204    || reg_or_0_operand (operands[1], DImode))
4205   && !TARGET_64BIT
4206   && !TARGET_SOFT_FLOAT"
4207  "*
4208{
4209  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4210       || operands[1] == CONST0_RTX (DFmode))
4211      && !(REG_P (operands[0]) && REG_P (operands[1])
4212	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4213    return pa_output_fp_move_double (operands);
4214  return pa_output_move_double (operands);
4215}"
4216  [(set_attr "type"
4217    "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4218   (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4219
4220(define_insn ""
4221  [(set (match_operand:DI 0 "move_dest_operand"
4222			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4223	(match_operand:DI 1 "move_src_operand"
4224			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4225  "(register_operand (operands[0], DImode)
4226    || reg_or_0_operand (operands[1], DImode))
4227   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4228  "@
4229   ldd RT'%A1,%0
4230   copy %1,%0
4231   ldi %1,%0
4232   ldil L'%1,%0
4233   depdi,z %z1,%0
4234   ldd%M1 %1,%0
4235   std%M0 %r1,%0
4236   mtsar %r1
4237   {mfctl|mfctl,w} %%sar,%0
4238   fcpy,dbl %f1,%0
4239   fldd%F1 %1,%0
4240   fstd%F0 %1,%0"
4241  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4242   (set_attr "pa_combine_type" "addmove")
4243   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4244
4245(define_insn ""
4246  [(set (match_operand:DI 0 "move_dest_operand"
4247			  "=r,r,r,r,r,r,Q,!*q,!r")
4248	(match_operand:DI 1 "move_src_operand"
4249			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
4250  "(register_operand (operands[0], DImode)
4251    || reg_or_0_operand (operands[1], DImode))
4252   && TARGET_SOFT_FLOAT && TARGET_64BIT"
4253  "@
4254   ldd RT'%A1,%0
4255   copy %1,%0
4256   ldi %1,%0
4257   ldil L'%1,%0
4258   depdi,z %z1,%0
4259   ldd%M1 %1,%0
4260   std%M0 %r1,%0
4261   mtsar %r1
4262   {mfctl|mfctl,w} %%sar,%0"
4263  [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
4264   (set_attr "pa_combine_type" "addmove")
4265   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4266
4267(define_insn ""
4268  [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4269	(match_operand:DI 1 "register_operand" "f"))]
4270  "!TARGET_SOFT_FLOAT
4271   && TARGET_64BIT
4272   && !TARGET_DISABLE_INDEXING
4273   && reload_completed"
4274  "fstd%F0 %1,%0"
4275  [(set_attr "type" "fpstore")
4276   (set_attr "pa_combine_type" "addmove")
4277   (set_attr "length" "4")])
4278
4279(define_peephole2
4280  [(set (match_operand:DI 0 "register_operand" "")
4281	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4282			    (const_int 3))
4283		 (match_operand:DI 2 "register_operand" "")))
4284   (set (mem:DI (match_dup 0))
4285        (match_operand:DI 3 "register_operand" ""))]
4286  "!TARGET_SOFT_FLOAT
4287   && !TARGET_DISABLE_INDEXING
4288   && TARGET_64BIT
4289   && REG_OK_FOR_BASE_P (operands[2])
4290   && FP_REGNO_P (REGNO (operands[3]))"
4291  [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4292	(match_dup 3))
4293   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4294			       (match_dup 2)))]
4295  "")
4296
4297(define_peephole2
4298  [(set (match_operand:DI 0 "register_operand" "")
4299	(plus:DI (match_operand:DI 1 "register_operand" "")
4300		 (match_operand:DI 2 "register_operand" "")))
4301   (set (mem:DI (match_dup 0))
4302        (match_operand:DI 3 "register_operand" ""))]
4303  "!TARGET_SOFT_FLOAT
4304   && !TARGET_DISABLE_INDEXING
4305   && TARGET_64BIT
4306   && TARGET_NO_SPACE_REGS
4307   && REG_OK_FOR_INDEX_P (operands[1])
4308   && REG_OK_FOR_BASE_P (operands[2])
4309   && FP_REGNO_P (REGNO (operands[3]))"
4310  [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4311	(match_dup 3))
4312   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4313  "")
4314
4315(define_peephole2
4316  [(set (match_operand:DI 0 "register_operand" "")
4317	(plus:DI (match_operand:DI 1 "register_operand" "")
4318		 (match_operand:DI 2 "register_operand" "")))
4319   (set (mem:DI (match_dup 0))
4320        (match_operand:DI 3 "register_operand" ""))]
4321  "!TARGET_SOFT_FLOAT
4322   && !TARGET_DISABLE_INDEXING
4323   && TARGET_64BIT
4324   && TARGET_NO_SPACE_REGS
4325   && REG_OK_FOR_BASE_P (operands[1])
4326   && REG_OK_FOR_INDEX_P (operands[2])
4327   && FP_REGNO_P (REGNO (operands[3]))"
4328  [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4329	(match_dup 3))
4330   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4331  "")
4332
4333(define_insn ""
4334  [(set (match_operand:DI 0 "move_dest_operand"
4335			  "=r,o,Q,r,r,r")
4336	(match_operand:DI 1 "general_operand"
4337			  "rM,r,r,o,Q,i"))]
4338  "(register_operand (operands[0], DImode)
4339    || reg_or_0_operand (operands[1], DImode))
4340   && !TARGET_64BIT
4341   && TARGET_SOFT_FLOAT"
4342  "*
4343{
4344  return pa_output_move_double (operands);
4345}"
4346  [(set_attr "type" "move,store,store,load,load,multi")
4347   (set_attr "length" "8,8,16,8,16,16")])
4348
4349(define_insn ""
4350  [(set (match_operand:DI 0 "register_operand" "=r,&r")
4351	(lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4352		   (match_operand:DI 2 "immediate_operand" "i,i")))]
4353  "!TARGET_64BIT"
4354  "*
4355{
4356  /* Don't output a 64-bit constant, since we can't trust the assembler to
4357     handle it correctly.  */
4358  if (GET_CODE (operands[2]) == CONST_DOUBLE)
4359    operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4360  else if (HOST_BITS_PER_WIDE_INT > 32
4361	   && GET_CODE (operands[2]) == CONST_INT)
4362    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4363  if (which_alternative == 1)
4364    output_asm_insn (\"copy %1,%0\", operands);
4365  return \"ldo R'%G2(%R1),%R0\";
4366}"
4367  [(set_attr "type" "move,move")
4368   (set_attr "length" "4,8")])
4369
4370(define_expand "movsf"
4371  [(set (match_operand:SF 0 "general_operand" "")
4372	(match_operand:SF 1 "general_operand" ""))]
4373  ""
4374  "
4375{
4376  if (pa_emit_move_sequence (operands, SFmode, 0))
4377    DONE;
4378}")
4379
4380;; Handle SFmode input reloads requiring %r1 as a scratch register.
4381(define_expand "reload_insf_r1"
4382  [(set (match_operand:SF 0 "register_operand" "=Z")
4383	(match_operand:SF 1 "non_hard_reg_operand" ""))
4384   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4385  ""
4386  "
4387{
4388  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4389    DONE;
4390
4391  /* We don't want the clobber emitted, so handle this ourselves.  */
4392  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4393  DONE;
4394}")
4395
4396;; Handle SFmode input reloads requiring a general register as a
4397;; scratch register.
4398(define_expand "reload_insf"
4399  [(set (match_operand:SF 0 "register_operand" "=Z")
4400	(match_operand:SF 1 "non_hard_reg_operand" ""))
4401   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4402  ""
4403  "
4404{
4405  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4406    DONE;
4407
4408  /* We don't want the clobber emitted, so handle this ourselves.  */
4409  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4410  DONE;
4411}")
4412
4413;; Handle SFmode output reloads requiring a general register as a
4414;; scratch register.
4415(define_expand "reload_outsf"
4416  [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4417	(match_operand:SF 1  "register_operand" "Z"))
4418   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4419  ""
4420  "
4421{
4422  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4423    DONE;
4424
4425  /* We don't want the clobber emitted, so handle this ourselves.  */
4426  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4427  DONE;
4428}")
4429
4430(define_insn ""
4431  [(set (match_operand:SF 0 "move_dest_operand"
4432			  "=f,!*r,f,*r,T,Q,?*r,?f")
4433	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4434			  "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4435  "(register_operand (operands[0], SFmode)
4436    || reg_or_0_operand (operands[1], SFmode))
4437   && !TARGET_SOFT_FLOAT
4438   && !TARGET_64BIT"
4439  "@
4440   fcpy,sgl %f1,%0
4441   copy %r1,%0
4442   fldw%F1 %1,%0
4443   ldw%M1 %1,%0
4444   fstw%F0 %1,%0
4445   stw%M0 %r1,%0
4446   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4447   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4448  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4449   (set_attr "pa_combine_type" "addmove")
4450   (set_attr "length" "4,4,4,4,4,4,8,8")])
4451
4452(define_insn ""
4453  [(set (match_operand:SF 0 "move_dest_operand"
4454			  "=f,!*r,f,*r,T,Q")
4455	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4456			  "fG,!*rG,RT,RQ,f,*rG"))]
4457  "(register_operand (operands[0], SFmode)
4458    || reg_or_0_operand (operands[1], SFmode))
4459   && !TARGET_SOFT_FLOAT
4460   && TARGET_64BIT"
4461  "@
4462   fcpy,sgl %f1,%0
4463   copy %r1,%0
4464   fldw%F1 %1,%0
4465   ldw%M1 %1,%0
4466   fstw%F0 %1,%0
4467   stw%M0 %r1,%0"
4468  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4469   (set_attr "pa_combine_type" "addmove")
4470   (set_attr "length" "4,4,4,4,4,4")])
4471
4472(define_insn ""
4473  [(set (match_operand:SF 0 "move_dest_operand"
4474			  "=!*r,*r,Q")
4475	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4476			  "!*rG,RQ,*rG"))]
4477  "(register_operand (operands[0], SFmode)
4478    || reg_or_0_operand (operands[1], SFmode))
4479   && TARGET_SOFT_FLOAT
4480   && TARGET_64BIT"
4481  "@
4482   copy %r1,%0
4483   ldw%M1 %1,%0
4484   stw%M0 %r1,%0"
4485  [(set_attr "type" "move,load,store")
4486   (set_attr "pa_combine_type" "addmove")
4487   (set_attr "length" "4,4,4")])
4488
4489(define_insn ""
4490  [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4491	(match_operand:SF 1 "register_operand" "f"))]
4492  "!TARGET_SOFT_FLOAT
4493   && !TARGET_DISABLE_INDEXING
4494   && reload_completed"
4495  "fstw%F0 %1,%0"
4496  [(set_attr "type" "fpstore")
4497   (set_attr "pa_combine_type" "addmove")
4498   (set_attr "length" "4")])
4499
4500(define_peephole2
4501  [(set (match_operand:SI 0 "register_operand" "")
4502	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4503			    (const_int 2))
4504		 (match_operand:SI 2 "register_operand" "")))
4505   (set (mem:SF (match_dup 0))
4506        (match_operand:SF 3 "register_operand" ""))]
4507  "!TARGET_SOFT_FLOAT
4508   && !TARGET_DISABLE_INDEXING
4509   && REG_OK_FOR_BASE_P (operands[2])
4510   && FP_REGNO_P (REGNO (operands[3]))"
4511  [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4512	(match_dup 3))
4513   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4514			       (match_dup 2)))]
4515  "")
4516
4517(define_peephole2
4518  [(set (match_operand:DI 0 "register_operand" "")
4519	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4520			    (const_int 2))
4521		 (match_operand:DI 2 "register_operand" "")))
4522   (set (mem:SF (match_dup 0))
4523        (match_operand:SF 3 "register_operand" ""))]
4524  "!TARGET_SOFT_FLOAT
4525   && !TARGET_DISABLE_INDEXING
4526   && TARGET_64BIT
4527   && REG_OK_FOR_BASE_P (operands[2])
4528   && FP_REGNO_P (REGNO (operands[3]))"
4529  [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4530	(match_dup 3))
4531   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4532			       (match_dup 2)))]
4533  "")
4534
4535(define_peephole2
4536  [(set (match_operand:SI 0 "register_operand" "")
4537	(plus:SI (match_operand:SI 1 "register_operand" "")
4538		 (match_operand:SI 2 "register_operand" "")))
4539   (set (mem:SF (match_dup 0))
4540        (match_operand:SF 3 "register_operand" ""))]
4541  "!TARGET_SOFT_FLOAT
4542   && !TARGET_DISABLE_INDEXING
4543   && TARGET_NO_SPACE_REGS
4544   && REG_OK_FOR_INDEX_P (operands[1])
4545   && REG_OK_FOR_BASE_P (operands[2])
4546   && FP_REGNO_P (REGNO (operands[3]))"
4547  [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4548	(match_dup 3))
4549   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4550  "")
4551
4552(define_peephole2
4553  [(set (match_operand:SI 0 "register_operand" "")
4554	(plus:SI (match_operand:SI 1 "register_operand" "")
4555		 (match_operand:SI 2 "register_operand" "")))
4556   (set (mem:SF (match_dup 0))
4557        (match_operand:SF 3 "register_operand" ""))]
4558  "!TARGET_SOFT_FLOAT
4559   && !TARGET_DISABLE_INDEXING
4560   && TARGET_NO_SPACE_REGS
4561   && REG_OK_FOR_BASE_P (operands[1])
4562   && REG_OK_FOR_INDEX_P (operands[2])
4563   && FP_REGNO_P (REGNO (operands[3]))"
4564  [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4565	(match_dup 3))
4566   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4567  "")
4568
4569(define_peephole2
4570  [(set (match_operand:DI 0 "register_operand" "")
4571	(plus:DI (match_operand:DI 1 "register_operand" "")
4572		 (match_operand:DI 2 "register_operand" "")))
4573   (set (mem:SF (match_dup 0))
4574        (match_operand:SF 3 "register_operand" ""))]
4575  "!TARGET_SOFT_FLOAT
4576   && !TARGET_DISABLE_INDEXING
4577   && TARGET_64BIT
4578   && TARGET_NO_SPACE_REGS
4579   && REG_OK_FOR_INDEX_P (operands[1])
4580   && REG_OK_FOR_BASE_P (operands[2])
4581   && FP_REGNO_P (REGNO (operands[3]))"
4582  [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4583	(match_dup 3))
4584   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4585  "")
4586
4587(define_peephole2
4588  [(set (match_operand:DI 0 "register_operand" "")
4589	(plus:DI (match_operand:DI 1 "register_operand" "")
4590		 (match_operand:DI 2 "register_operand" "")))
4591   (set (mem:SF (match_dup 0))
4592        (match_operand:SF 3 "register_operand" ""))]
4593  "!TARGET_SOFT_FLOAT
4594   && !TARGET_DISABLE_INDEXING
4595   && TARGET_64BIT
4596   && TARGET_NO_SPACE_REGS
4597   && REG_OK_FOR_BASE_P (operands[1])
4598   && REG_OK_FOR_INDEX_P (operands[2])
4599   && FP_REGNO_P (REGNO (operands[3]))"
4600  [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4601	(match_dup 3))
4602   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4603  "")
4604
4605(define_insn ""
4606  [(set (match_operand:SF 0 "move_dest_operand"
4607			  "=r,r,Q")
4608	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4609			  "rG,RQ,rG"))]
4610  "(register_operand (operands[0], SFmode)
4611    || reg_or_0_operand (operands[1], SFmode))
4612   && TARGET_SOFT_FLOAT"
4613  "@
4614   copy %r1,%0
4615   ldw%M1 %1,%0
4616   stw%M0 %r1,%0"
4617  [(set_attr "type" "move,load,store")
4618   (set_attr "pa_combine_type" "addmove")
4619   (set_attr "length" "4,4,4")])
4620
4621
4622
4623;;- zero extension instructions
4624;; We have define_expand for zero extension patterns to make sure the
4625;; operands get loaded into registers.  The define_insns accept
4626;; memory operands.  This gives us better overall code than just
4627;; having a pattern that does or does not accept memory operands.
4628
4629(define_expand "zero_extendqihi2"
4630  [(set (match_operand:HI 0 "register_operand" "")
4631	(zero_extend:HI
4632	 (match_operand:QI 1 "register_operand" "")))]
4633  ""
4634  "")
4635
4636(define_insn ""
4637  [(set (match_operand:HI 0 "register_operand" "=r,r")
4638	(zero_extend:HI
4639	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4640  "GET_CODE (operands[1]) != CONST_INT"
4641  "@
4642   {extru|extrw,u} %1,31,8,%0
4643   ldb%M1 %1,%0"
4644  [(set_attr "type" "shift,load")
4645   (set_attr "length" "4,4")])
4646
4647(define_expand "zero_extendqisi2"
4648  [(set (match_operand:SI 0 "register_operand" "")
4649	(zero_extend:SI
4650	 (match_operand:QI 1 "register_operand" "")))]
4651  ""
4652  "")
4653
4654(define_insn ""
4655  [(set (match_operand:SI 0 "register_operand" "=r,r")
4656	(zero_extend:SI
4657	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4658  "GET_CODE (operands[1]) != CONST_INT"
4659  "@
4660   {extru|extrw,u} %1,31,8,%0
4661   ldb%M1 %1,%0"
4662  [(set_attr "type" "shift,load")
4663   (set_attr "length" "4,4")])
4664
4665(define_expand "zero_extendhisi2"
4666  [(set (match_operand:SI 0 "register_operand" "")
4667	(zero_extend:SI
4668	 (match_operand:HI 1 "register_operand" "")))]
4669  ""
4670  "")
4671
4672(define_insn ""
4673  [(set (match_operand:SI 0 "register_operand" "=r,r")
4674	(zero_extend:SI
4675	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4676  "GET_CODE (operands[1]) != CONST_INT"
4677  "@
4678   {extru|extrw,u} %1,31,16,%0
4679   ldh%M1 %1,%0"
4680  [(set_attr "type" "shift,load")
4681   (set_attr "length" "4,4")])
4682
4683(define_expand "zero_extendqidi2"
4684  [(set (match_operand:DI 0 "register_operand" "")
4685	(zero_extend:DI
4686	 (match_operand:QI 1 "register_operand" "")))]
4687  "TARGET_64BIT"
4688  "")
4689
4690(define_insn ""
4691  [(set (match_operand:DI 0 "register_operand" "=r,r")
4692	(zero_extend:DI
4693	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4694  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4695  "@
4696   extrd,u %1,63,8,%0
4697   ldb%M1 %1,%0"
4698  [(set_attr "type" "shift,load")
4699   (set_attr "length" "4,4")])
4700
4701(define_expand "zero_extendhidi2"
4702  [(set (match_operand:DI 0 "register_operand" "")
4703	(zero_extend:DI
4704	 (match_operand:HI 1 "register_operand" "")))]
4705  "TARGET_64BIT"
4706  "")
4707
4708(define_insn ""
4709  [(set (match_operand:DI 0 "register_operand" "=r,r")
4710	(zero_extend:DI
4711	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4712  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4713  "@
4714   extrd,u %1,63,16,%0
4715   ldh%M1 %1,%0"
4716  [(set_attr "type" "shift,load")
4717   (set_attr "length" "4,4")])
4718
4719(define_expand "zero_extendsidi2"
4720  [(set (match_operand:DI 0 "register_operand" "")
4721	(zero_extend:DI
4722	 (match_operand:SI 1 "register_operand" "")))]
4723  "TARGET_64BIT"
4724  "")
4725
4726(define_insn ""
4727  [(set (match_operand:DI 0 "register_operand" "=r,r")
4728	(zero_extend:DI
4729	 (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4730  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4731  "@
4732   extrd,u %1,63,32,%0
4733   ldw%M1 %1,%0"
4734  [(set_attr "type" "shift,load")
4735   (set_attr "length" "4,4")])
4736
4737;;- sign extension instructions
4738
4739(define_insn "extendhisi2"
4740  [(set (match_operand:SI 0 "register_operand" "=r")
4741	(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4742  ""
4743  "{extrs|extrw,s} %1,31,16,%0"
4744  [(set_attr "type" "shift")
4745   (set_attr "length" "4")])
4746
4747(define_insn "extendqihi2"
4748  [(set (match_operand:HI 0 "register_operand" "=r")
4749	(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4750  ""
4751  "{extrs|extrw,s} %1,31,8,%0"
4752  [(set_attr "type" "shift") 
4753  (set_attr "length" "4")])
4754
4755(define_insn "extendqisi2"
4756  [(set (match_operand:SI 0 "register_operand" "=r")
4757	(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4758  ""
4759  "{extrs|extrw,s} %1,31,8,%0"
4760  [(set_attr "type" "shift")
4761   (set_attr "length" "4")])
4762
4763(define_insn "extendqidi2"
4764  [(set (match_operand:DI 0 "register_operand" "=r")
4765	(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4766  "TARGET_64BIT"
4767  "extrd,s %1,63,8,%0"
4768  [(set_attr "type" "shift") 
4769  (set_attr "length" "4")])
4770
4771(define_insn "extendhidi2"
4772  [(set (match_operand:DI 0 "register_operand" "=r")
4773	(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4774  "TARGET_64BIT"
4775  "extrd,s %1,63,16,%0"
4776  [(set_attr "type" "shift") 
4777  (set_attr "length" "4")])
4778
4779(define_insn "extendsidi2"
4780  [(set (match_operand:DI 0 "register_operand" "=r")
4781	(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4782  "TARGET_64BIT"
4783  "extrd,s %1,63,32,%0"
4784  [(set_attr "type" "shift") 
4785  (set_attr "length" "4")])
4786
4787
4788;; Conversions between float and double.
4789
4790(define_insn "extendsfdf2"
4791  [(set (match_operand:DF 0 "register_operand" "=f")
4792	(float_extend:DF
4793	 (match_operand:SF 1 "register_operand" "f")))]
4794  "! TARGET_SOFT_FLOAT"
4795  "{fcnvff|fcnv},sgl,dbl %1,%0"
4796  [(set_attr "type" "fpalu")
4797   (set_attr "length" "4")])
4798
4799(define_insn "truncdfsf2"
4800  [(set (match_operand:SF 0 "register_operand" "=f")
4801	(float_truncate:SF
4802	 (match_operand:DF 1 "register_operand" "f")))]
4803  "! TARGET_SOFT_FLOAT"
4804  "{fcnvff|fcnv},dbl,sgl %1,%0"
4805  [(set_attr "type" "fpalu")
4806   (set_attr "length" "4")])
4807
4808;; Conversion between fixed point and floating point.
4809;; Note that among the fix-to-float insns
4810;; the ones that start with SImode come first.
4811;; That is so that an operand that is a CONST_INT
4812;; (and therefore lacks a specific machine mode).
4813;; will be recognized as SImode (which is always valid)
4814;; rather than as QImode or HImode.
4815
4816;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4817;; to be reloaded by putting the constant into memory.
4818;; It must come before the more general floatsisf2 pattern.
4819(define_insn ""
4820  [(set (match_operand:SF 0 "register_operand" "=f")
4821	(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4822  "! TARGET_SOFT_FLOAT"
4823  "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4824  [(set_attr "type" "fpalu")
4825   (set_attr "length" "8")])
4826
4827(define_insn "floatsisf2"
4828  [(set (match_operand:SF 0 "register_operand" "=f")
4829	(float:SF (match_operand:SI 1 "register_operand" "f")))]
4830  "! TARGET_SOFT_FLOAT"
4831  "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4832  [(set_attr "type" "fpalu")
4833   (set_attr "length" "4")])
4834
4835;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4836;; to be reloaded by putting the constant into memory.
4837;; It must come before the more general floatsidf2 pattern.
4838(define_insn ""
4839  [(set (match_operand:DF 0 "register_operand" "=f")
4840	(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4841  "! TARGET_SOFT_FLOAT"
4842  "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4843  [(set_attr "type" "fpalu")
4844   (set_attr "length" "8")])
4845
4846(define_insn "floatsidf2"
4847  [(set (match_operand:DF 0 "register_operand" "=f")
4848	(float:DF (match_operand:SI 1 "register_operand" "f")))]
4849  "! TARGET_SOFT_FLOAT"
4850  "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4851  [(set_attr "type" "fpalu")
4852   (set_attr "length" "4")])
4853
4854(define_expand "floatunssisf2"
4855  [(set (subreg:SI (match_dup 2) 4)
4856	(match_operand:SI 1 "register_operand" ""))
4857   (set (subreg:SI (match_dup 2) 0)
4858	(const_int 0))
4859   (set (match_operand:SF 0 "register_operand" "")
4860	(float:SF (match_dup 2)))]
4861  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4862  "
4863{
4864  if (TARGET_PA_20)
4865    {
4866      emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4867      DONE;
4868    }
4869  operands[2] = gen_reg_rtx (DImode);
4870}")
4871
4872(define_expand "floatunssidf2"
4873  [(set (subreg:SI (match_dup 2) 4)
4874	(match_operand:SI 1 "register_operand" ""))
4875   (set (subreg:SI (match_dup 2) 0)
4876	(const_int 0))
4877   (set (match_operand:DF 0 "register_operand" "")
4878	(float:DF (match_dup 2)))]
4879  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4880  "
4881{
4882  if (TARGET_PA_20)
4883    {
4884      emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4885      DONE;
4886    }
4887  operands[2] = gen_reg_rtx (DImode);
4888}")
4889
4890(define_insn "floatdisf2"
4891  [(set (match_operand:SF 0 "register_operand" "=f")
4892	(float:SF (match_operand:DI 1 "register_operand" "f")))]
4893  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4894  "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4895  [(set_attr "type" "fpalu")
4896   (set_attr "length" "4")])
4897
4898(define_insn "floatdidf2"
4899  [(set (match_operand:DF 0 "register_operand" "=f")
4900	(float:DF (match_operand:DI 1 "register_operand" "f")))]
4901  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4902  "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4903  [(set_attr "type" "fpalu")
4904   (set_attr "length" "4")])
4905
4906;; Convert a float to an actual integer.
4907;; Truncation is performed as part of the conversion.
4908
4909(define_insn "fix_truncsfsi2"
4910  [(set (match_operand:SI 0 "register_operand" "=f")
4911	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4912  "! TARGET_SOFT_FLOAT"
4913  "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4914  [(set_attr "type" "fpalu")
4915   (set_attr "length" "4")])
4916
4917(define_insn "fix_truncdfsi2"
4918  [(set (match_operand:SI 0 "register_operand" "=f")
4919	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4920  "! TARGET_SOFT_FLOAT"
4921  "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4922  [(set_attr "type" "fpalu")
4923   (set_attr "length" "4")])
4924
4925(define_insn "fix_truncsfdi2"
4926  [(set (match_operand:DI 0 "register_operand" "=f")
4927	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4928  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4929  "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4930  [(set_attr "type" "fpalu")
4931   (set_attr "length" "4")])
4932
4933(define_insn "fix_truncdfdi2"
4934  [(set (match_operand:DI 0 "register_operand" "=f")
4935	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4936  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4937  "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4938  [(set_attr "type" "fpalu")
4939   (set_attr "length" "4")])
4940
4941(define_insn "floatunssidf2_pa20"
4942  [(set (match_operand:DF 0 "register_operand" "=f")
4943	(unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4944  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4945  "fcnv,uw,dbl %1,%0"
4946  [(set_attr "type" "fpalu")
4947   (set_attr "length" "4")])
4948
4949(define_insn "floatunssisf2_pa20"
4950  [(set (match_operand:SF 0 "register_operand" "=f")
4951	(unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4952  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4953  "fcnv,uw,sgl %1,%0"
4954  [(set_attr "type" "fpalu")
4955   (set_attr "length" "4")])
4956
4957(define_insn "floatunsdisf2"
4958  [(set (match_operand:SF 0 "register_operand" "=f")
4959	(unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4960  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4961  "fcnv,udw,sgl %1,%0"
4962  [(set_attr "type" "fpalu")
4963   (set_attr "length" "4")])
4964
4965(define_insn "floatunsdidf2"
4966  [(set (match_operand:DF 0 "register_operand" "=f")
4967	(unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4968  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4969  "fcnv,udw,dbl %1,%0"
4970  [(set_attr "type" "fpalu")
4971   (set_attr "length" "4")])
4972
4973(define_insn "fixuns_truncsfsi2"
4974  [(set (match_operand:SI 0 "register_operand" "=f")
4975	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4976  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4977  "fcnv,t,sgl,uw %1,%0"
4978  [(set_attr "type" "fpalu")
4979   (set_attr "length" "4")])
4980
4981(define_insn "fixuns_truncdfsi2"
4982  [(set (match_operand:SI 0 "register_operand" "=f")
4983	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4984  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4985  "fcnv,t,dbl,uw %1,%0"
4986  [(set_attr "type" "fpalu")
4987   (set_attr "length" "4")])
4988
4989(define_insn "fixuns_truncsfdi2"
4990  [(set (match_operand:DI 0 "register_operand" "=f")
4991	(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4992  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4993  "fcnv,t,sgl,udw %1,%0"
4994  [(set_attr "type" "fpalu")
4995   (set_attr "length" "4")])
4996
4997(define_insn "fixuns_truncdfdi2"
4998  [(set (match_operand:DI 0 "register_operand" "=f")
4999	(unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5000  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5001  "fcnv,t,dbl,udw %1,%0"
5002  [(set_attr "type" "fpalu")
5003   (set_attr "length" "4")])
5004
5005;;- arithmetic instructions
5006
5007(define_expand "adddi3"
5008  [(set (match_operand:DI 0 "register_operand" "")
5009	(plus:DI (match_operand:DI 1 "register_operand" "")
5010		 (match_operand:DI 2 "adddi3_operand" "")))]
5011  ""
5012  "")
5013
5014(define_insn ""
5015  [(set (match_operand:DI 0 "register_operand" "=r")
5016	(plus:DI (match_operand:DI 1 "register_operand" "%r")
5017		 (match_operand:DI 2 "arith11_operand" "rI")))]
5018  "!TARGET_64BIT"
5019  "*
5020{
5021  if (GET_CODE (operands[2]) == CONST_INT)
5022    {
5023      if (INTVAL (operands[2]) >= 0)
5024	return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5025      else
5026	return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5027    }
5028  else
5029    return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5030}"
5031  [(set_attr "type" "binary")
5032   (set_attr "length" "8")])
5033
5034(define_insn ""
5035  [(set (match_operand:DI 0 "register_operand" "=r,r")
5036	(plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5037		 (match_operand:DI 2 "arith14_operand" "r,J")))]
5038  "TARGET_64BIT"
5039  "@
5040   add,l %1,%2,%0
5041   ldo %2(%1),%0"
5042  [(set_attr "type" "binary,binary")
5043   (set_attr "pa_combine_type" "addmove")
5044   (set_attr "length" "4,4")])
5045
5046(define_insn ""
5047  [(set (match_operand:DI 0 "register_operand" "=r")
5048	(plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5049		 (match_operand:DI 2 "register_operand" "r")))]
5050  "TARGET_64BIT"
5051  "uaddcm %2,%1,%0"
5052  [(set_attr "type" "binary")
5053   (set_attr "length" "4")])
5054
5055(define_insn ""
5056  [(set (match_operand:SI 0 "register_operand" "=r")
5057	(plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5058		 (match_operand:SI 2 "register_operand" "r")))]
5059  ""
5060  "uaddcm %2,%1,%0"
5061  [(set_attr "type" "binary")
5062   (set_attr "length" "4")])
5063
5064(define_expand "addvdi3"
5065  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5066		   (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5067			    (match_operand:DI 2 "arith11_operand" "")))
5068	      (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5069				    (sign_extend:TI (match_dup 2)))
5070			   (sign_extend:TI (plus:DI (match_dup 1)
5071						    (match_dup 2))))
5072		       (const_int 0))])]
5073  ""
5074  "")
5075
5076(define_insn ""
5077  [(set (match_operand:DI 0 "register_operand" "=r,r")
5078	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
5079		 (match_operand:DI 2 "arith11_operand" "r,I")))
5080   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5081			 (sign_extend:TI (match_dup 2)))
5082		(sign_extend:TI (plus:DI (match_dup 1)
5083					 (match_dup 2))))
5084	    (const_int 0))]
5085  "TARGET_64BIT"
5086  "@
5087  add,tsv,* %2,%1,%0
5088  addi,tsv,* %2,%1,%0"
5089  [(set_attr "type" "binary,binary")
5090   (set_attr "length" "4,4")])
5091
5092(define_insn ""
5093  [(set (match_operand:DI 0 "register_operand" "=r")
5094	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5095		 (match_operand:DI 2 "arith11_operand" "rI")))
5096   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5097			 (sign_extend:TI (match_dup 2)))
5098		(sign_extend:TI (plus:DI (match_dup 1)
5099					 (match_dup 2))))
5100	    (const_int 0))]
5101  "!TARGET_64BIT"
5102  "*
5103{
5104  if (GET_CODE (operands[2]) == CONST_INT)
5105    {
5106      if (INTVAL (operands[2]) >= 0)
5107	return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5108      else
5109	return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5110    }
5111  else
5112    return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5113}"
5114  [(set_attr "type" "binary")
5115   (set_attr "length" "8")])
5116
5117;; define_splits to optimize cases of adding a constant integer
5118;; to a register when the constant does not fit in 14 bits.  */
5119(define_split
5120  [(set (match_operand:SI 0 "register_operand" "")
5121	(plus:SI (match_operand:SI 1 "register_operand" "")
5122		 (match_operand:SI 2 "const_int_operand" "")))
5123   (clobber (match_operand:SI 4 "register_operand" ""))]
5124  "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5125   && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5126  [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5127   (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5128  "
5129{
5130  int val = INTVAL (operands[2]);
5131  int low = (val < 0) ? -0x2000 : 0x1fff;
5132  int rest = val - low;
5133
5134  operands[2] = GEN_INT (rest);
5135  operands[3] = GEN_INT (low);
5136}")
5137
5138(define_split
5139  [(set (match_operand:SI 0 "register_operand" "")
5140	(plus:SI (match_operand:SI 1 "register_operand" "")
5141		 (match_operand:SI 2 "const_int_operand" "")))
5142   (clobber (match_operand:SI 4 "register_operand" ""))]
5143  "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5144  [(set (match_dup 4) (match_dup 2))
5145   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5146			       (match_dup 1)))]
5147  "
5148{
5149  unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5150
5151  /* Try dividing the constant by 2, then 4, and finally 8 to see
5152     if we can get a constant which can be loaded into a register
5153     in a single instruction (pa_cint_ok_for_move). 
5154
5155     If that fails, try to negate the constant and subtract it
5156     from our input operand.  */
5157  if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5158    {
5159      operands[2] = GEN_INT (intval / 2);
5160      operands[3] = const1_rtx;
5161    }
5162  else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5163    {
5164      operands[2] = GEN_INT (intval / 4);
5165      operands[3] = const2_rtx;
5166    }
5167  else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5168    {
5169      operands[2] = GEN_INT (intval / 8);
5170      operands[3] = GEN_INT (3);
5171    }
5172  else if (pa_cint_ok_for_move (-intval))
5173    {
5174      emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5175      emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5176      DONE;
5177    }
5178  else
5179    FAIL;
5180}")
5181
5182(define_insn "addsi3"
5183  [(set (match_operand:SI 0 "register_operand" "=r,r")
5184	(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5185		 (match_operand:SI 2 "arith14_operand" "r,J")))]
5186  ""
5187  "@
5188   {addl|add,l} %1,%2,%0
5189   ldo %2(%1),%0"
5190  [(set_attr "type" "binary,binary")
5191   (set_attr "pa_combine_type" "addmove")
5192   (set_attr "length" "4,4")])
5193
5194(define_insn "addvsi3"
5195  [(set (match_operand:SI 0 "register_operand" "=r,r")
5196	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5197		 (match_operand:SI 2 "arith11_operand" "r,I")))
5198   (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5199			 (sign_extend:DI (match_dup 2)))
5200		(sign_extend:DI (plus:SI (match_dup 1)
5201					 (match_dup 2))))
5202	    (const_int 0))]
5203  ""
5204  "@
5205  {addo|add,tsv} %2,%1,%0
5206  {addio|addi,tsv} %2,%1,%0"
5207  [(set_attr "type" "binary,binary")
5208   (set_attr "length" "4,4")])
5209
5210(define_expand "subdi3"
5211  [(set (match_operand:DI 0 "register_operand" "")
5212	(minus:DI (match_operand:DI 1 "arith11_operand" "")
5213		  (match_operand:DI 2 "reg_or_0_operand" "")))]
5214  ""
5215  "")
5216
5217(define_insn ""
5218  [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5219	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5220		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5221  "TARGET_64BIT"
5222  "@
5223   sub %1,%2,%0
5224   subi %1,%2,%0
5225   mtsarcm %2"
5226  [(set_attr "type" "binary,binary,move")
5227  (set_attr "length" "4,4,4")])
5228
5229(define_insn ""
5230  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5231	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5232		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5233  "!TARGET_64BIT"
5234  "*
5235{
5236  if (GET_CODE (operands[1]) == CONST_INT)
5237    {
5238      if (INTVAL (operands[1]) >= 0)
5239	return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5240      else
5241	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5242    }
5243  else
5244    return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5245}"
5246  [(set_attr "type" "binary")
5247   (set (attr "length")
5248	(if_then_else (eq_attr "alternative" "0")
5249	  (const_int 8)
5250	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5251			    (const_int 0))
5252	    (const_int 8)
5253	    (const_int 12))))])
5254
5255(define_expand "subvdi3"
5256  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5257		   (minus:DI (match_operand:DI 1 "arith11_operand" "")
5258			     (match_operand:DI 2 "reg_or_0_operand" "")))
5259	      (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5260				     (sign_extend:TI (match_dup 2)))
5261			   (sign_extend:TI (minus:DI (match_dup 1)
5262						     (match_dup 2))))
5263		       (const_int 0))])]
5264  ""
5265  "")
5266
5267(define_insn ""
5268  [(set (match_operand:DI 0 "register_operand" "=r,r")
5269	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5270		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5271   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5272			  (sign_extend:TI (match_dup 2)))
5273		(sign_extend:TI (minus:DI (match_dup 1)
5274					  (match_dup 2))))
5275	    (const_int 0))]
5276  "TARGET_64BIT"
5277  "@
5278  {subo|sub,tsv} %1,%2,%0
5279  {subio|subi,tsv} %1,%2,%0"
5280  [(set_attr "type" "binary,binary")
5281   (set_attr "length" "4,4")])
5282
5283(define_insn ""
5284  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5285	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5286		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5287   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5288			  (sign_extend:TI (match_dup 2)))
5289		(sign_extend:TI (minus:DI (match_dup 1)
5290					  (match_dup 2))))
5291	    (const_int 0))]
5292  "!TARGET_64BIT"
5293  "*
5294{
5295  if (GET_CODE (operands[1]) == CONST_INT)
5296    {
5297      if (INTVAL (operands[1]) >= 0)
5298	return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5299      else
5300	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5301    }
5302  else
5303    return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5304}"
5305  [(set_attr "type" "binary,binary")
5306   (set (attr "length")
5307	(if_then_else (eq_attr "alternative" "0")
5308	  (const_int 8)
5309	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5310			    (const_int 0))
5311	    (const_int 8)
5312	    (const_int 12))))])
5313
5314(define_expand "subsi3"
5315  [(set (match_operand:SI 0 "register_operand" "")
5316	(minus:SI (match_operand:SI 1 "arith11_operand" "")
5317		  (match_operand:SI 2 "register_operand" "")))]
5318  ""
5319  "")
5320
5321(define_insn ""
5322  [(set (match_operand:SI 0 "register_operand" "=r,r")
5323	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5324		  (match_operand:SI 2 "register_operand" "r,r")))]
5325  "!TARGET_PA_20"
5326  "@
5327   sub %1,%2,%0
5328   subi %1,%2,%0"
5329  [(set_attr "type" "binary,binary")
5330   (set_attr "length" "4,4")])
5331
5332(define_insn ""
5333  [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5334	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5335		  (match_operand:SI 2 "register_operand" "r,r,!r")))]
5336  "TARGET_PA_20"
5337  "@
5338   sub %1,%2,%0
5339   subi %1,%2,%0
5340   mtsarcm %2"
5341  [(set_attr "type" "binary,binary,move")
5342   (set_attr "length" "4,4,4")])
5343
5344(define_insn "subvsi3"
5345  [(set (match_operand:SI 0 "register_operand" "=r,r")
5346	(minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5347		  (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5348   (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5349			  (sign_extend:DI (match_dup 2)))
5350		(sign_extend:DI (minus:SI (match_dup 1)
5351					  (match_dup 2))))
5352	    (const_int 0))]
5353  ""
5354  "@
5355  {subo|sub,tsv} %1,%2,%0
5356  {subio|subi,tsv} %1,%2,%0"
5357  [(set_attr "type" "binary,binary")
5358   (set_attr "length" "4,4")])
5359
5360;; Trap instructions.
5361
5362(define_insn "trap"
5363  [(trap_if (const_int 1) (const_int 0))]
5364  ""
5365  "{addit|addi,tc},<> 1,%%r0,%%r0"
5366  [(set_attr "type" "trap")
5367   (set_attr "length" "4")])
5368
5369;; Clobbering a "register_operand" instead of a match_scratch
5370;; in operand3 of millicode calls avoids spilling %r1 and
5371;; produces better code.
5372
5373;; The mulsi3 insns set up registers for the millicode call.
5374(define_expand "mulsi3"
5375  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5376   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5377   (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5378	      (clobber (match_dup 3))
5379	      (clobber (reg:SI 26))
5380	      (clobber (reg:SI 25))
5381	      (clobber (match_dup 4))])
5382   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5383  ""
5384  "
5385{
5386  operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5387  if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5388    {
5389      rtx scratch = gen_reg_rtx (DImode);
5390      operands[1] = force_reg (SImode, operands[1]);
5391      operands[2] = force_reg (SImode, operands[2]);
5392      emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5393      emit_insn (gen_movsi (operands[0],
5394			    gen_rtx_SUBREG (SImode, scratch,
5395					    GET_MODE_SIZE (SImode))));
5396      DONE;
5397    }
5398  operands[3] = gen_reg_rtx (SImode);
5399}")
5400
5401(define_insn "umulsidi3"
5402  [(set (match_operand:DI 0 "register_operand" "=f")
5403	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5404		 (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5405  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5406  "xmpyu %1,%2,%0"
5407  [(set_attr "type" "fpmuldbl")
5408   (set_attr "length" "4")])
5409
5410(define_insn ""
5411  [(set (match_operand:DI 0 "register_operand" "=f")
5412	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5413		 (match_operand:DI 2 "uint32_operand" "f")))]
5414  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5415  "xmpyu %1,%R2,%0"
5416  [(set_attr "type" "fpmuldbl")
5417   (set_attr "length" "4")])
5418
5419(define_insn ""
5420  [(set (match_operand:DI 0 "register_operand" "=f")
5421	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5422		 (match_operand:DI 2 "uint32_operand" "f")))]
5423  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5424  "xmpyu %1,%2R,%0"
5425  [(set_attr "type" "fpmuldbl")
5426   (set_attr "length" "4")])
5427
5428(define_insn ""
5429  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5430   (clobber (match_operand:SI 0 "register_operand" "=a"))
5431   (clobber (reg:SI 26))
5432   (clobber (reg:SI 25))
5433   (clobber (reg:SI 31))]
5434  "!TARGET_64BIT"
5435  "* return pa_output_mul_insn (0, insn);"
5436  [(set_attr "type" "milli")
5437   (set (attr "length")
5438	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5439	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5440
5441(define_insn ""
5442  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5443   (clobber (match_operand:SI 0 "register_operand" "=a"))
5444   (clobber (reg:SI 26))
5445   (clobber (reg:SI 25))
5446   (clobber (reg:SI 2))]
5447  "TARGET_64BIT"
5448  "* return pa_output_mul_insn (0, insn);"
5449  [(set_attr "type" "milli")
5450   (set (attr "length")
5451	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5452	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5453
5454(define_expand "muldi3"
5455  [(set (match_operand:DI 0 "register_operand" "")
5456        (mult:DI (match_operand:DI 1 "register_operand" "")
5457		 (match_operand:DI 2 "register_operand" "")))]
5458  "! optimize_size
5459   && TARGET_PA_11
5460   && ! TARGET_DISABLE_FPREGS
5461   && ! TARGET_SOFT_FLOAT"
5462  "
5463{
5464  rtx low_product = gen_reg_rtx (DImode);
5465  rtx cross_product1 = gen_reg_rtx (DImode);
5466  rtx cross_product2 = gen_reg_rtx (DImode);
5467  rtx op1l, op1r, op2l, op2r;
5468
5469  if (TARGET_64BIT)
5470    {
5471      rtx op1shifted = gen_reg_rtx (DImode);
5472      rtx op2shifted = gen_reg_rtx (DImode);
5473
5474      emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5475						    GEN_INT (32)));
5476      emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5477						    GEN_INT (32)));
5478      op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5479      op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5480      op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5481      op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5482    }
5483  else
5484    {
5485      op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5486      op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5487      op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5488      op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5489    }
5490
5491  /* Emit multiplies for the cross products.  */
5492  emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5493  emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5494
5495  /* Emit a multiply for the low sub-word.  */
5496  emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5497
5498  if (TARGET_64BIT)
5499    {
5500      rtx cross_scratch = gen_reg_rtx (DImode);
5501      rtx cross_product = gen_reg_rtx (DImode);
5502
5503      /* Sum the cross products and shift them into proper position.  */
5504      emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5505      emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5506
5507      /* Add the cross product to the low product and store the result
5508	 into the output operand .  */
5509      emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5510    }
5511  else
5512    {
5513      rtx cross_scratch = gen_reg_rtx (SImode);
5514
5515      /* Sum cross products.  */
5516      emit_move_insn (cross_scratch,
5517		      gen_rtx_PLUS (SImode,
5518				    gen_lowpart (SImode, cross_product1),
5519				    gen_lowpart (SImode, cross_product2)));
5520      emit_move_insn (gen_lowpart (SImode, operands[0]),
5521		      gen_lowpart (SImode, low_product));
5522      emit_move_insn (gen_highpart (SImode, operands[0]),
5523		      gen_rtx_PLUS (SImode,
5524				    gen_highpart (SImode, low_product),
5525				    cross_scratch));
5526    }
5527  DONE;
5528}")
5529
5530;;; Division and mod.
5531(define_expand "divsi3"
5532  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5533   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5534   (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5535	      (clobber (match_dup 3))
5536	      (clobber (match_dup 4))
5537	      (clobber (reg:SI 26))
5538	      (clobber (reg:SI 25))
5539	      (clobber (match_dup 5))])
5540   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5541  ""
5542  "
5543{
5544  operands[3] = gen_reg_rtx (SImode);
5545  if (TARGET_64BIT)
5546    {
5547      operands[5] = gen_rtx_REG (SImode, 2);
5548      operands[4] = operands[5];
5549    }
5550  else
5551    {
5552      operands[5] = gen_rtx_REG (SImode, 31);
5553      operands[4] = gen_reg_rtx (SImode);
5554    }
5555  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5556    DONE;
5557}")
5558
5559(define_insn ""
5560  [(set (reg:SI 29)
5561	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5562   (clobber (match_operand:SI 1 "register_operand" "=a"))
5563   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5564   (clobber (reg:SI 26))
5565   (clobber (reg:SI 25))
5566   (clobber (reg:SI 31))]
5567  "!TARGET_64BIT"
5568  "*
5569   return pa_output_div_insn (operands, 0, insn);"
5570  [(set_attr "type" "milli")
5571   (set (attr "length")
5572	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5573	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5574
5575(define_insn ""
5576  [(set (reg:SI 29)
5577	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5578   (clobber (match_operand:SI 1 "register_operand" "=a"))
5579   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5580   (clobber (reg:SI 26))
5581   (clobber (reg:SI 25))
5582   (clobber (reg:SI 2))]
5583  "TARGET_64BIT"
5584  "*
5585   return pa_output_div_insn (operands, 0, insn);"
5586  [(set_attr "type" "milli")
5587   (set (attr "length")
5588	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5589	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5590
5591(define_expand "udivsi3"
5592  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5593   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5594   (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5595	      (clobber (match_dup 3))
5596	      (clobber (match_dup 4))
5597	      (clobber (reg:SI 26))
5598	      (clobber (reg:SI 25))
5599	      (clobber (match_dup 5))])
5600   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5601  ""
5602  "
5603{
5604  operands[3] = gen_reg_rtx (SImode);
5605
5606  if (TARGET_64BIT)
5607    {
5608      operands[5] = gen_rtx_REG (SImode, 2);
5609      operands[4] = operands[5];
5610    }
5611  else
5612    {
5613      operands[5] = gen_rtx_REG (SImode, 31);
5614      operands[4] = gen_reg_rtx (SImode);
5615    }
5616  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5617    DONE;
5618}")
5619
5620(define_insn ""
5621  [(set (reg:SI 29)
5622	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5623   (clobber (match_operand:SI 1 "register_operand" "=a"))
5624   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5625   (clobber (reg:SI 26))
5626   (clobber (reg:SI 25))
5627   (clobber (reg:SI 31))]
5628  "!TARGET_64BIT"
5629  "*
5630   return pa_output_div_insn (operands, 1, insn);"
5631  [(set_attr "type" "milli")
5632   (set (attr "length")
5633	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5634	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5635
5636(define_insn ""
5637  [(set (reg:SI 29)
5638	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5639   (clobber (match_operand:SI 1 "register_operand" "=a"))
5640   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5641   (clobber (reg:SI 26))
5642   (clobber (reg:SI 25))
5643   (clobber (reg:SI 2))]
5644  "TARGET_64BIT"
5645  "*
5646   return pa_output_div_insn (operands, 1, insn);"
5647  [(set_attr "type" "milli")
5648   (set (attr "length")
5649	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5650	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5651
5652(define_expand "modsi3"
5653  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5654   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5655   (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5656	      (clobber (match_dup 3))
5657	      (clobber (match_dup 4))
5658	      (clobber (reg:SI 26))
5659	      (clobber (reg:SI 25))
5660	      (clobber (match_dup 5))])
5661   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5662  ""
5663  "
5664{
5665  if (TARGET_64BIT)
5666    {
5667      operands[5] = gen_rtx_REG (SImode, 2);
5668      operands[4] = operands[5];
5669    }
5670  else
5671    {
5672      operands[5] = gen_rtx_REG (SImode, 31);
5673      operands[4] = gen_reg_rtx (SImode);
5674    }
5675  operands[3] = gen_reg_rtx (SImode);
5676}")
5677
5678(define_insn ""
5679  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5680   (clobber (match_operand:SI 0 "register_operand" "=a"))
5681   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5682   (clobber (reg:SI 26))
5683   (clobber (reg:SI 25))
5684   (clobber (reg:SI 31))]
5685  "!TARGET_64BIT"
5686  "*
5687  return pa_output_mod_insn (0, insn);"
5688  [(set_attr "type" "milli")
5689   (set (attr "length")
5690	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5691	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5692
5693(define_insn ""
5694  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5695   (clobber (match_operand:SI 0 "register_operand" "=a"))
5696   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5697   (clobber (reg:SI 26))
5698   (clobber (reg:SI 25))
5699   (clobber (reg:SI 2))]
5700  "TARGET_64BIT"
5701  "*
5702  return pa_output_mod_insn (0, insn);"
5703  [(set_attr "type" "milli")
5704   (set (attr "length")
5705	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5706	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5707
5708(define_expand "umodsi3"
5709  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5710   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5711   (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5712	      (clobber (match_dup 3))
5713	      (clobber (match_dup 4))
5714	      (clobber (reg:SI 26))
5715	      (clobber (reg:SI 25))
5716	      (clobber (match_dup 5))])
5717   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5718  ""
5719  "
5720{
5721  if (TARGET_64BIT)
5722    {
5723      operands[5] = gen_rtx_REG (SImode, 2);
5724      operands[4] = operands[5];
5725    }
5726  else
5727    {
5728      operands[5] = gen_rtx_REG (SImode, 31);
5729      operands[4] = gen_reg_rtx (SImode);
5730    }
5731  operands[3] = gen_reg_rtx (SImode);
5732}")
5733
5734(define_insn ""
5735  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5736   (clobber (match_operand:SI 0 "register_operand" "=a"))
5737   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5738   (clobber (reg:SI 26))
5739   (clobber (reg:SI 25))
5740   (clobber (reg:SI 31))]
5741  "!TARGET_64BIT"
5742  "*
5743  return pa_output_mod_insn (1, insn);"
5744  [(set_attr "type" "milli")
5745   (set (attr "length")
5746	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5747	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5748
5749(define_insn ""
5750  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5751   (clobber (match_operand:SI 0 "register_operand" "=a"))
5752   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5753   (clobber (reg:SI 26))
5754   (clobber (reg:SI 25))
5755   (clobber (reg:SI 2))]
5756  "TARGET_64BIT"
5757  "*
5758  return pa_output_mod_insn (1, insn);"
5759  [(set_attr "type" "milli")
5760   (set (attr "length")
5761	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5762	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5763
5764;;- and instructions
5765;; We define DImode `and` so with DImode `not` we can get
5766;; DImode `andn`.  Other combinations are possible.
5767
5768(define_expand "anddi3"
5769  [(set (match_operand:DI 0 "register_operand" "")
5770	(and:DI (match_operand:DI 1 "register_operand" "")
5771		(match_operand:DI 2 "and_operand" "")))]
5772  "TARGET_64BIT"
5773  "")
5774
5775(define_insn ""
5776  [(set (match_operand:DI 0 "register_operand" "=r,r")
5777	(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5778		(match_operand:DI 2 "and_operand" "rO,P")))]
5779  "TARGET_64BIT"
5780  "* return pa_output_64bit_and (operands); "
5781  [(set_attr "type" "binary")
5782   (set_attr "length" "4")])
5783
5784; The ? for op1 makes reload prefer zdepi instead of loading a huge
5785; constant with ldil;ldo.
5786(define_insn "andsi3"
5787  [(set (match_operand:SI 0 "register_operand" "=r,r")
5788	(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5789		(match_operand:SI 2 "and_operand" "rO,P")))]
5790  ""
5791  "* return pa_output_and (operands); "
5792  [(set_attr "type" "binary,shift")
5793   (set_attr "length" "4,4")])
5794
5795(define_insn ""
5796  [(set (match_operand:DI 0 "register_operand" "=r")
5797	(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5798		(match_operand:DI 2 "register_operand" "r")))]
5799  "TARGET_64BIT"
5800  "andcm %2,%1,%0"
5801  [(set_attr "type" "binary")
5802   (set_attr "length" "4")])
5803
5804(define_insn ""
5805  [(set (match_operand:SI 0 "register_operand" "=r")
5806	(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5807		(match_operand:SI 2 "register_operand" "r")))]
5808  ""
5809  "andcm %2,%1,%0"
5810  [(set_attr "type" "binary")
5811  (set_attr "length" "4")])
5812
5813(define_expand "iordi3"
5814  [(set (match_operand:DI 0 "register_operand" "")
5815	(ior:DI (match_operand:DI 1 "register_operand" "")
5816		(match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5817  "TARGET_64BIT"
5818  "")
5819
5820(define_insn ""
5821  [(set (match_operand:DI 0 "register_operand" "=r,r")
5822	(ior:DI (match_operand:DI 1 "register_operand" "0,0")
5823		(match_operand:DI 2 "cint_ior_operand" "M,i")))]
5824  "TARGET_64BIT"
5825  "* return pa_output_64bit_ior (operands); "
5826  [(set_attr "type" "binary,shift")
5827   (set_attr "length" "4,4")])
5828
5829(define_insn ""
5830  [(set (match_operand:DI 0 "register_operand" "=r")
5831	(ior:DI (match_operand:DI 1 "register_operand" "%r")
5832		(match_operand:DI 2 "register_operand" "r")))]
5833  "TARGET_64BIT"
5834  "or %1,%2,%0"
5835  [(set_attr "type" "binary")
5836   (set_attr "length" "4")])
5837
5838;; Need a define_expand because we've run out of CONST_OK... characters.
5839(define_expand "iorsi3"
5840  [(set (match_operand:SI 0 "register_operand" "")
5841	(ior:SI (match_operand:SI 1 "register_operand" "")
5842		(match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5843  ""
5844  "")
5845
5846(define_insn ""
5847  [(set (match_operand:SI 0 "register_operand" "=r,r")
5848	(ior:SI (match_operand:SI 1 "register_operand" "0,0")
5849		(match_operand:SI 2 "cint_ior_operand" "M,i")))]
5850  ""
5851  "* return pa_output_ior (operands); "
5852  [(set_attr "type" "binary,shift")
5853   (set_attr "length" "4,4")])
5854
5855(define_insn ""
5856  [(set (match_operand:SI 0 "register_operand" "=r")
5857	(ior:SI (match_operand:SI 1 "register_operand" "%r")
5858		(match_operand:SI 2 "register_operand" "r")))]
5859  ""
5860  "or %1,%2,%0"
5861  [(set_attr "type" "binary")
5862   (set_attr "length" "4")])
5863
5864(define_expand "xordi3"
5865  [(set (match_operand:DI 0 "register_operand" "")
5866	(xor:DI (match_operand:DI 1 "register_operand" "")
5867		(match_operand:DI 2 "register_operand" "")))]
5868  "TARGET_64BIT"
5869  "")
5870
5871(define_insn ""
5872  [(set (match_operand:DI 0 "register_operand" "=r")
5873	(xor:DI (match_operand:DI 1 "register_operand" "%r")
5874		(match_operand:DI 2 "register_operand" "r")))]
5875  "TARGET_64BIT"
5876  "xor %1,%2,%0"
5877  [(set_attr "type" "binary")
5878   (set_attr "length" "4")])
5879
5880(define_insn "xorsi3"
5881  [(set (match_operand:SI 0 "register_operand" "=r")
5882	(xor:SI (match_operand:SI 1 "register_operand" "%r")
5883		(match_operand:SI 2 "register_operand" "r")))]
5884  ""
5885  "xor %1,%2,%0"
5886  [(set_attr "type" "binary")
5887   (set_attr "length" "4")])
5888
5889(define_expand "negdi2"
5890  [(set (match_operand:DI 0 "register_operand" "")
5891	(neg:DI (match_operand:DI 1 "register_operand" "")))]
5892  ""
5893  "")
5894
5895(define_insn ""
5896  [(set (match_operand:DI 0 "register_operand" "=r")
5897	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5898  "!TARGET_64BIT"
5899  "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5900  [(set_attr "type" "unary")
5901   (set_attr "length" "8")])
5902
5903(define_insn ""
5904  [(set (match_operand:DI 0 "register_operand" "=r")
5905	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5906  "TARGET_64BIT"
5907  "sub %%r0,%1,%0"
5908  [(set_attr "type" "unary")
5909   (set_attr "length" "4")])
5910
5911(define_expand "negvdi2"
5912  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5913		   (neg:DI (match_operand:DI 1 "register_operand" "")))
5914	      (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5915				   (sign_extend:TI (neg:DI (match_dup 1))))
5916		       (const_int 0))])]
5917  ""
5918  "")
5919
5920(define_insn ""
5921  [(set (match_operand:DI 0 "register_operand" "=r")
5922	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5923   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5924		(sign_extend:TI (neg:DI (match_dup 1))))
5925	    (const_int 0))]
5926  "!TARGET_64BIT"
5927  "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5928  [(set_attr "type" "unary")
5929   (set_attr "length" "8")])
5930
5931(define_insn ""
5932  [(set (match_operand:DI 0 "register_operand" "=r")
5933	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5934   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5935		(sign_extend:TI (neg:DI (match_dup 1))))
5936	    (const_int 0))]
5937  "TARGET_64BIT"
5938  "sub,tsv %%r0,%1,%0"
5939  [(set_attr "type" "unary")
5940   (set_attr "length" "4")])
5941
5942(define_insn "negsi2"
5943  [(set (match_operand:SI 0 "register_operand" "=r")
5944	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
5945  ""
5946  "sub %%r0,%1,%0"
5947  [(set_attr "type" "unary")
5948   (set_attr "length" "4")])
5949
5950(define_insn "negvsi2"
5951  [(set (match_operand:SI 0 "register_operand" "=r")
5952        (neg:SI (match_operand:SI 1 "register_operand" "r")))
5953   (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
5954		(sign_extend:DI (neg:SI (match_dup 1))))
5955	    (const_int 0))]
5956   ""
5957   "{subo|sub,tsv} %%r0,%1,%0"
5958  [(set_attr "type" "unary")
5959   (set_attr "length" "4")])
5960
5961(define_expand "one_cmpldi2"
5962  [(set (match_operand:DI 0 "register_operand" "")
5963	(not:DI (match_operand:DI 1 "register_operand" "")))]
5964  ""
5965  "
5966{
5967}")
5968
5969(define_insn ""
5970  [(set (match_operand:DI 0 "register_operand" "=r")
5971	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5972  "!TARGET_64BIT"
5973  "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5974  [(set_attr "type" "unary")
5975   (set_attr "length" "8")])
5976
5977(define_insn ""
5978  [(set (match_operand:DI 0 "register_operand" "=r")
5979	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5980  "TARGET_64BIT"
5981  "uaddcm %%r0,%1,%0"
5982  [(set_attr "type" "unary")
5983   (set_attr "length" "4")])
5984
5985(define_insn "one_cmplsi2"
5986  [(set (match_operand:SI 0 "register_operand" "=r")
5987	(not:SI (match_operand:SI 1 "register_operand" "r")))]
5988  ""
5989  "uaddcm %%r0,%1,%0"
5990  [(set_attr "type" "unary")
5991   (set_attr "length" "4")])
5992
5993;; Floating point arithmetic instructions.
5994
5995(define_insn "adddf3"
5996  [(set (match_operand:DF 0 "register_operand" "=f")
5997	(plus:DF (match_operand:DF 1 "register_operand" "f")
5998		 (match_operand:DF 2 "register_operand" "f")))]
5999  "! TARGET_SOFT_FLOAT"
6000  "fadd,dbl %1,%2,%0"
6001  [(set_attr "type" "fpalu")
6002   (set_attr "pa_combine_type" "faddsub")
6003   (set_attr "length" "4")])
6004
6005(define_insn "addsf3"
6006  [(set (match_operand:SF 0 "register_operand" "=f")
6007	(plus:SF (match_operand:SF 1 "register_operand" "f")
6008		 (match_operand:SF 2 "register_operand" "f")))]
6009  "! TARGET_SOFT_FLOAT"
6010  "fadd,sgl %1,%2,%0"
6011  [(set_attr "type" "fpalu")
6012   (set_attr "pa_combine_type" "faddsub")
6013   (set_attr "length" "4")])
6014
6015(define_insn "subdf3"
6016  [(set (match_operand:DF 0 "register_operand" "=f")
6017	(minus:DF (match_operand:DF 1 "register_operand" "f")
6018		  (match_operand:DF 2 "register_operand" "f")))]
6019  "! TARGET_SOFT_FLOAT"
6020  "fsub,dbl %1,%2,%0"
6021  [(set_attr "type" "fpalu")
6022   (set_attr "pa_combine_type" "faddsub")
6023   (set_attr "length" "4")])
6024
6025(define_insn "subsf3"
6026  [(set (match_operand:SF 0 "register_operand" "=f")
6027	(minus:SF (match_operand:SF 1 "register_operand" "f")
6028		  (match_operand:SF 2 "register_operand" "f")))]
6029  "! TARGET_SOFT_FLOAT"
6030  "fsub,sgl %1,%2,%0"
6031  [(set_attr "type" "fpalu")
6032   (set_attr "pa_combine_type" "faddsub")
6033   (set_attr "length" "4")])
6034
6035(define_insn "muldf3"
6036  [(set (match_operand:DF 0 "register_operand" "=f")
6037	(mult:DF (match_operand:DF 1 "register_operand" "f")
6038		 (match_operand:DF 2 "register_operand" "f")))]
6039  "! TARGET_SOFT_FLOAT"
6040  "fmpy,dbl %1,%2,%0"
6041  [(set_attr "type" "fpmuldbl")
6042   (set_attr "pa_combine_type" "fmpy")
6043   (set_attr "length" "4")])
6044
6045(define_insn "mulsf3"
6046  [(set (match_operand:SF 0 "register_operand" "=f")
6047	(mult:SF (match_operand:SF 1 "register_operand" "f")
6048		 (match_operand:SF 2 "register_operand" "f")))]
6049  "! TARGET_SOFT_FLOAT"
6050  "fmpy,sgl %1,%2,%0"
6051  [(set_attr "type" "fpmulsgl")
6052   (set_attr "pa_combine_type" "fmpy")
6053   (set_attr "length" "4")])
6054
6055(define_insn "divdf3"
6056  [(set (match_operand:DF 0 "register_operand" "=f")
6057	(div:DF (match_operand:DF 1 "register_operand" "f")
6058		(match_operand:DF 2 "register_operand" "f")))]
6059  "! TARGET_SOFT_FLOAT"
6060  "fdiv,dbl %1,%2,%0"
6061  [(set_attr "type" "fpdivdbl")
6062   (set_attr "length" "4")])
6063
6064(define_insn "divsf3"
6065  [(set (match_operand:SF 0 "register_operand" "=f")
6066	(div:SF (match_operand:SF 1 "register_operand" "f")
6067		(match_operand:SF 2 "register_operand" "f")))]
6068  "! TARGET_SOFT_FLOAT"
6069  "fdiv,sgl %1,%2,%0"
6070  [(set_attr "type" "fpdivsgl")
6071   (set_attr "length" "4")])
6072
6073;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6074;; negation can be done by subtracting from plus zero.  However, this
6075;; violates the IEEE standard when negating plus and minus zero.
6076;; The slow path toggles the sign bit in the general registers.
6077(define_expand "negdf2"
6078  [(set (match_operand:DF 0 "register_operand" "")
6079	(neg:DF (match_operand:DF 1 "register_operand" "")))]
6080  "!TARGET_SOFT_FLOAT"
6081{
6082  if (TARGET_PA_20 || !flag_signed_zeros)
6083    emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6084  else
6085    emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6086  DONE;
6087})
6088
6089(define_insn "negdf2_slow"
6090  [(set (match_operand:DF 0 "register_operand" "=r")
6091	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
6092  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6093  "*
6094{
6095  if (rtx_equal_p (operands[0], operands[1]))
6096    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6097  else
6098    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6099}"
6100  [(set_attr "type" "multi")
6101   (set (attr "length")
6102	(if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6103	    (const_int 12)
6104	    (const_int 16)))])
6105
6106(define_insn "negdf2_fast"
6107  [(set (match_operand:DF 0 "register_operand" "=f")
6108	(neg:DF (match_operand:DF 1 "register_operand" "f")))]
6109  "!TARGET_SOFT_FLOAT"
6110  "*
6111{
6112  if (TARGET_PA_20)
6113    return \"fneg,dbl %1,%0\";
6114  else
6115    return \"fsub,dbl %%fr0,%1,%0\";
6116}"
6117  [(set_attr "type" "fpalu")
6118   (set_attr "length" "4")])
6119
6120(define_expand "negsf2"
6121  [(set (match_operand:SF 0 "register_operand" "")
6122	(neg:SF (match_operand:SF 1 "register_operand" "")))]
6123  "!TARGET_SOFT_FLOAT"
6124{
6125  if (TARGET_PA_20 || !flag_signed_zeros)
6126    emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6127  else
6128    emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6129  DONE;
6130})
6131
6132(define_insn "negsf2_slow"
6133  [(set (match_operand:SF 0 "register_operand" "=r")
6134	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
6135  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6136  "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6137  [(set_attr "type" "multi")
6138   (set_attr "length" "12")])
6139
6140(define_insn "negsf2_fast"
6141  [(set (match_operand:SF 0 "register_operand" "=f")
6142	(neg:SF (match_operand:SF 1 "register_operand" "f")))]
6143  "!TARGET_SOFT_FLOAT"
6144  "*
6145{
6146  if (TARGET_PA_20)
6147    return \"fneg,sgl %1,%0\";
6148  else
6149    return \"fsub,sgl %%fr0,%1,%0\";
6150}"
6151  [(set_attr "type" "fpalu")
6152   (set_attr "length" "4")])
6153
6154(define_insn "absdf2"
6155  [(set (match_operand:DF 0 "register_operand" "=f")
6156	(abs:DF (match_operand:DF 1 "register_operand" "f")))]
6157  "! TARGET_SOFT_FLOAT"
6158  "fabs,dbl %1,%0"
6159  [(set_attr "type" "fpalu")
6160   (set_attr "length" "4")])
6161
6162(define_insn "abssf2"
6163  [(set (match_operand:SF 0 "register_operand" "=f")
6164	(abs:SF (match_operand:SF 1 "register_operand" "f")))]
6165  "! TARGET_SOFT_FLOAT"
6166  "fabs,sgl %1,%0"
6167  [(set_attr "type" "fpalu")
6168   (set_attr "length" "4")])
6169
6170(define_insn "sqrtdf2"
6171  [(set (match_operand:DF 0 "register_operand" "=f")
6172	(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6173  "! TARGET_SOFT_FLOAT"
6174  "fsqrt,dbl %1,%0"
6175  [(set_attr "type" "fpsqrtdbl")
6176   (set_attr "length" "4")])
6177
6178(define_insn "sqrtsf2"
6179  [(set (match_operand:SF 0 "register_operand" "=f")
6180	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6181  "! TARGET_SOFT_FLOAT"
6182  "fsqrt,sgl %1,%0"
6183  [(set_attr "type" "fpsqrtsgl")
6184   (set_attr "length" "4")])
6185
6186;; PA 2.0 floating point instructions
6187
6188; fmpyfadd patterns
6189(define_insn "fmadf4"
6190  [(set (match_operand:DF 0 "register_operand" "=f")
6191	(fma:DF (match_operand:DF 1 "register_operand" "f")
6192		(match_operand:DF 2 "register_operand" "f")
6193		(match_operand:DF 3 "register_operand" "f")))]
6194  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6195  "fmpyfadd,dbl %1,%2,%3,%0"
6196  [(set_attr "type" "fpmuldbl")
6197   (set_attr "length" "4")])
6198
6199(define_insn "fmasf4"
6200  [(set (match_operand:SF 0 "register_operand" "=f")
6201	(fma:SF (match_operand:SF 1 "register_operand" "f")
6202		(match_operand:SF 2 "register_operand" "f")
6203		(match_operand:SF 3 "register_operand" "f")))]
6204  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6205  "fmpyfadd,sgl %1,%2,%3,%0"
6206  [(set_attr "type" "fpmulsgl")
6207   (set_attr "length" "4")])
6208
6209; fmpynfadd patterns
6210(define_insn "fnmadf4"
6211  [(set (match_operand:DF 0 "register_operand" "=f")
6212	(fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6213		(match_operand:DF 2 "register_operand" "f")
6214		(match_operand:DF 3 "register_operand" "f")))]
6215  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6216  "fmpynfadd,dbl %1,%2,%3,%0"
6217  [(set_attr "type" "fpmuldbl")
6218   (set_attr "length" "4")])
6219
6220(define_insn "fnmasf4"
6221  [(set (match_operand:SF 0 "register_operand" "=f")
6222	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6223		(match_operand:SF 2 "register_operand" "f")
6224		(match_operand:SF 3 "register_operand" "f")))]
6225  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6226  "fmpynfadd,sgl %1,%2,%3,%0"
6227  [(set_attr "type" "fpmulsgl")
6228   (set_attr "length" "4")])
6229
6230; fnegabs patterns
6231(define_insn ""
6232  [(set (match_operand:DF 0 "register_operand" "=f")
6233	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6234  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6235  "fnegabs,dbl %1,%0"
6236  [(set_attr "type" "fpalu")
6237   (set_attr "length" "4")])
6238
6239(define_insn ""
6240  [(set (match_operand:SF 0 "register_operand" "=f")
6241	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6242  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6243  "fnegabs,sgl %1,%0"
6244  [(set_attr "type" "fpalu")
6245   (set_attr "length" "4")])
6246
6247(define_insn ""
6248  [(set (match_operand:DF 0 "register_operand" "=f")
6249	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6250   (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6251  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6252    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6253  "#"
6254  [(set_attr "type" "fpalu")
6255   (set_attr "length" "8")])
6256
6257(define_split
6258  [(set (match_operand:DF 0 "register_operand" "")
6259	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6260   (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6261  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6262  [(set (match_dup 2) (abs:DF (match_dup 1)))
6263   (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6264  "")
6265
6266(define_insn ""
6267  [(set (match_operand:SF 0 "register_operand" "=f")
6268	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6269   (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6270  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6271    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6272  "#"
6273  [(set_attr "type" "fpalu")
6274   (set_attr "length" "8")])
6275
6276(define_split
6277  [(set (match_operand:SF 0 "register_operand" "")
6278	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6279   (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6280  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6281  [(set (match_dup 2) (abs:SF (match_dup 1)))
6282   (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6283  "")
6284
6285;; Negating a multiply can be faked by adding zero in a fused multiply-add
6286;; instruction if we can ignore the sign of zero.
6287(define_insn ""
6288  [(set (match_operand:DF 0 "register_operand" "=f")
6289	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6290			 (match_operand:DF 2 "register_operand" "f"))))]
6291  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6292  "fmpynfadd,dbl %1,%2,%%fr0,%0"
6293  [(set_attr "type" "fpmuldbl")
6294   (set_attr "length" "4")])
6295
6296(define_insn ""
6297  [(set (match_operand:SF 0 "register_operand" "=f")
6298	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6299			 (match_operand:SF 2 "register_operand" "f"))))]
6300  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6301  "fmpynfadd,sgl %1,%2,%%fr0,%0"
6302  [(set_attr "type" "fpmuldbl")
6303   (set_attr "length" "4")])
6304
6305(define_insn ""
6306  [(set (match_operand:DF 0 "register_operand" "=f")
6307	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6308			 (match_operand:DF 2 "register_operand" "f"))))
6309   (set (match_operand:DF 3 "register_operand" "=&f")
6310	(mult:DF (match_dup 1) (match_dup 2)))]
6311  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6312    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6313          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6314  "#"
6315  [(set_attr "type" "fpmuldbl")
6316   (set_attr "length" "8")])
6317
6318(define_split
6319  [(set (match_operand:DF 0 "register_operand" "")
6320	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6321			 (match_operand:DF 2 "register_operand" ""))))
6322   (set (match_operand:DF 3 "register_operand" "")
6323	(mult:DF (match_dup 1) (match_dup 2)))]
6324  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6325  [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6326   (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6327  "")
6328
6329(define_insn ""
6330  [(set (match_operand:SF 0 "register_operand" "=f")
6331	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6332			 (match_operand:SF 2 "register_operand" "f"))))
6333   (set (match_operand:SF 3 "register_operand" "=&f")
6334	(mult:SF (match_dup 1) (match_dup 2)))]
6335  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6336    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6337          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6338  "#"
6339  [(set_attr "type" "fpmuldbl")
6340   (set_attr "length" "8")])
6341
6342(define_split
6343  [(set (match_operand:SF 0 "register_operand" "")
6344	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6345			 (match_operand:SF 2 "register_operand" ""))))
6346   (set (match_operand:SF 3 "register_operand" "")
6347	(mult:SF (match_dup 1) (match_dup 2)))]
6348  "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6349  [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6350   (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6351  "")
6352
6353;;- Shift instructions
6354
6355;; Optimized special case of shifting.
6356
6357(define_insn ""
6358  [(set (match_operand:SI 0 "register_operand" "=r")
6359	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6360		     (const_int 24)))]
6361  ""
6362  "ldb%M1 %1,%0"
6363  [(set_attr "type" "load")
6364   (set_attr "length" "4")])
6365
6366(define_insn ""
6367  [(set (match_operand:SI 0 "register_operand" "=r")
6368	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6369		     (const_int 16)))]
6370  ""
6371  "ldh%M1 %1,%0"
6372  [(set_attr "type" "load")
6373   (set_attr "length" "4")])
6374
6375(define_insn ""
6376  [(set (match_operand:SI 0 "register_operand" "=r")
6377	(plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6378			    (match_operand:SI 3 "shadd_operand" ""))
6379		 (match_operand:SI 1 "register_operand" "r")))]
6380  ""
6381  "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6382  [(set_attr "type" "binary")
6383   (set_attr "length" "4")])
6384
6385(define_insn ""
6386  [(set (match_operand:SI 0 "register_operand" "=r")
6387	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6388			  (match_operand:SI 3 "mem_shadd_operand" ""))
6389		 (match_operand:SI 1 "register_operand" "r")))]
6390  ""
6391  "*
6392{
6393  int shift_val = exact_log2 (INTVAL (operands[3]));
6394  operands[3] = GEN_INT (shift_val);
6395  return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6396}"
6397  [(set_attr "type" "binary")
6398   (set_attr "length" "4")])
6399
6400(define_insn ""
6401  [(set (match_operand:DI 0 "register_operand" "=r")
6402	(plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6403			    (match_operand:DI 3 "shadd_operand" ""))
6404		 (match_operand:DI 1 "register_operand" "r")))]
6405  "TARGET_64BIT"
6406  "shladd,l %2,%o3,%1,%0"
6407  [(set_attr "type" "binary")
6408   (set_attr "length" "4")])
6409
6410(define_insn ""
6411  [(set (match_operand:DI 0 "register_operand" "=r")
6412	(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6413			  (match_operand:DI 3 "mem_shadd_operand" ""))
6414		 (match_operand:DI 1 "register_operand" "r")))]
6415  "TARGET_64BIT"
6416  "*
6417{
6418  int shift_val = exact_log2 (INTVAL (operands[3]));
6419  operands[3] = GEN_INT (shift_val);
6420  return \"shladd,l %2,%o3,%1,%0\";
6421}"
6422  [(set_attr "type" "binary")
6423   (set_attr "length" "4")])
6424
6425(define_expand "ashlsi3"
6426  [(set (match_operand:SI 0 "register_operand" "")
6427	(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6428		   (match_operand:SI 2 "arith32_operand" "")))]
6429  ""
6430  "
6431{
6432  if (GET_CODE (operands[2]) != CONST_INT)
6433    {
6434      rtx temp = gen_reg_rtx (SImode);
6435      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6436      if (GET_CODE (operands[1]) == CONST_INT)
6437	emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6438      else
6439	emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6440      DONE;
6441    }
6442  /* Make sure both inputs are not constants,
6443     there are no patterns for that.  */
6444  operands[1] = force_reg (SImode, operands[1]);
6445}")
6446
6447(define_insn ""
6448  [(set (match_operand:SI 0 "register_operand" "=r")
6449	(ashift:SI (match_operand:SI 1 "register_operand" "r")
6450		   (match_operand:SI 2 "const_int_operand" "n")))]
6451  ""
6452  "{zdep|depw,z} %1,%P2,%L2,%0"
6453  [(set_attr "type" "shift")
6454   (set_attr "length" "4")])
6455
6456; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6457; Doing it like this makes slightly better code since reload can
6458; replace a register with a known value in range -16..15 with a
6459; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6460; but since we have no more CONST_OK... characters, that is not
6461; possible.
6462(define_insn "zvdep32"
6463  [(set (match_operand:SI 0 "register_operand" "=r,r")
6464	(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6465		   (minus:SI (const_int 31)
6466			     (match_operand:SI 2 "register_operand" "q,q"))))]
6467  ""
6468  "@
6469   {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6470   {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6471  [(set_attr "type" "shift,shift")
6472   (set_attr "length" "4,4")])
6473
6474(define_insn "zvdep_imm32"
6475  [(set (match_operand:SI 0 "register_operand" "=r")
6476	(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6477		   (minus:SI (const_int 31)
6478			     (match_operand:SI 2 "register_operand" "q"))))]
6479  ""
6480  "*
6481{
6482  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6483  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6484  operands[1] = GEN_INT ((x & 0xf) - 0x10);
6485  return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6486}"
6487  [(set_attr "type" "shift")
6488   (set_attr "length" "4")])
6489
6490(define_insn "vdepi_ior"
6491  [(set (match_operand:SI 0 "register_operand" "=r")
6492	(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6493			   (minus:SI (const_int 31)
6494				     (match_operand:SI 2 "register_operand" "q")))
6495		(match_operand:SI 3 "register_operand" "0")))]
6496  ; accept ...0001...1, can this be generalized?
6497  "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6498  "*
6499{
6500  HOST_WIDE_INT x = INTVAL (operands[1]);
6501  operands[2] = GEN_INT (exact_log2 (x + 1));
6502  return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6503}"
6504  [(set_attr "type" "shift")
6505   (set_attr "length" "4")])
6506
6507(define_insn "vdepi_and"
6508  [(set (match_operand:SI 0 "register_operand" "=r")
6509	(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6510			   (minus:SI (const_int 31)
6511				     (match_operand:SI 2 "register_operand" "q")))
6512		(match_operand:SI 3 "register_operand" "0")))]
6513  ; this can be generalized...!
6514  "INTVAL (operands[1]) == -2"
6515  "*
6516{
6517  HOST_WIDE_INT x = INTVAL (operands[1]);
6518  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6519  return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6520}"
6521  [(set_attr "type" "shift")
6522   (set_attr "length" "4")])
6523
6524(define_expand "ashldi3"
6525  [(set (match_operand:DI 0 "register_operand" "")
6526	(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6527		   (match_operand:DI 2 "arith32_operand" "")))]
6528  ""
6529  "
6530{
6531  if (!TARGET_64BIT)
6532    {
6533      if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6534	{
6535	  unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6536	  if (shift >= 1 && shift <= 31)
6537	    {
6538	      rtx dst = operands[0];
6539	      rtx src = force_reg (DImode, operands[1]);
6540	      emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6541					   gen_lowpart (SImode, src),
6542					   GEN_INT (32-shift),
6543					   gen_highpart (SImode, src),
6544					   GEN_INT (shift)));
6545	      emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6546				      gen_lowpart (SImode, src),
6547				      GEN_INT (shift)));
6548	      DONE;
6549	    }
6550	}
6551      /* Fallback to using optabs.c's expand_doubleword_shift.  */
6552      FAIL;
6553    }
6554  if (GET_CODE (operands[2]) != CONST_INT)
6555    {
6556      rtx temp = gen_reg_rtx (DImode);
6557      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6558      if (GET_CODE (operands[1]) == CONST_INT)
6559	emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6560      else
6561	emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6562      DONE;
6563    }
6564  /* Make sure both inputs are not constants,
6565     there are no patterns for that.  */
6566  operands[1] = force_reg (DImode, operands[1]);
6567}")
6568
6569(define_insn ""
6570  [(set (match_operand:DI 0 "register_operand" "=r")
6571	(ashift:DI (match_operand:DI 1 "register_operand" "r")
6572		   (match_operand:DI 2 "const_int_operand" "n")))]
6573  "TARGET_64BIT"
6574  "depd,z %1,%p2,%Q2,%0"
6575  [(set_attr "type" "shift")
6576   (set_attr "length" "4")])
6577
6578; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6579; Doing it like this makes slightly better code since reload can
6580; replace a register with a known value in range -16..15 with a
6581; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6582; but since we have no more CONST_OK... characters, that is not
6583; possible.
6584(define_insn "zvdep64"
6585  [(set (match_operand:DI 0 "register_operand" "=r,r")
6586	(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6587		   (minus:DI (const_int 63)
6588			     (match_operand:DI 2 "register_operand" "q,q"))))]
6589  "TARGET_64BIT"
6590  "@
6591   depd,z %1,%%sar,64,%0
6592   depdi,z %1,%%sar,64,%0"
6593  [(set_attr "type" "shift,shift")
6594   (set_attr "length" "4,4")])
6595
6596(define_insn "zvdep_imm64"
6597  [(set (match_operand:DI 0 "register_operand" "=r")
6598	(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6599		   (minus:DI (const_int 63)
6600			     (match_operand:DI 2 "register_operand" "q"))))]
6601  "TARGET_64BIT"
6602  "*
6603{
6604  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6605  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6606  operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6607  return \"depdi,z %1,%%sar,%2,%0\";
6608}"
6609  [(set_attr "type" "shift")
6610   (set_attr "length" "4")])
6611
6612(define_insn ""
6613  [(set (match_operand:DI 0 "register_operand" "=r")
6614	(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6615			   (minus:DI (const_int 63)
6616				     (match_operand:DI 2 "register_operand" "q")))
6617		(match_operand:DI 3 "register_operand" "0")))]
6618  ; accept ...0001...1, can this be generalized?
6619  "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6620  "*
6621{
6622  HOST_WIDE_INT x = INTVAL (operands[1]);
6623  operands[2] = GEN_INT (exact_log2 (x + 1));
6624  return \"depdi -1,%%sar,%2,%0\";
6625}"
6626  [(set_attr "type" "shift")
6627   (set_attr "length" "4")])
6628
6629(define_insn ""
6630  [(set (match_operand:DI 0 "register_operand" "=r")
6631	(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6632			   (minus:DI (const_int 63)
6633				     (match_operand:DI 2 "register_operand" "q")))
6634		(match_operand:DI 3 "register_operand" "0")))]
6635  ; this can be generalized...!
6636  "TARGET_64BIT && INTVAL (operands[1]) == -2"
6637  "*
6638{
6639  HOST_WIDE_INT x = INTVAL (operands[1]);
6640  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6641  return \"depdi 0,%%sar,%2,%0\";
6642}"
6643  [(set_attr "type" "shift")
6644   (set_attr "length" "4")])
6645
6646(define_expand "ashrsi3"
6647  [(set (match_operand:SI 0 "register_operand" "")
6648	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6649		     (match_operand:SI 2 "arith32_operand" "")))]
6650  ""
6651  "
6652{
6653  if (GET_CODE (operands[2]) != CONST_INT)
6654    {
6655      rtx temp = gen_reg_rtx (SImode);
6656      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6657      emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6658      DONE;
6659    }
6660}")
6661
6662(define_insn ""
6663  [(set (match_operand:SI 0 "register_operand" "=r")
6664	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6665		     (match_operand:SI 2 "const_int_operand" "n")))]
6666  ""
6667  "{extrs|extrw,s} %1,%P2,%L2,%0"
6668  [(set_attr "type" "shift")
6669   (set_attr "length" "4")])
6670
6671(define_insn "vextrs32"
6672  [(set (match_operand:SI 0 "register_operand" "=r")
6673	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6674		     (minus:SI (const_int 31)
6675			       (match_operand:SI 2 "register_operand" "q"))))]
6676  ""
6677  "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6678  [(set_attr "type" "shift")
6679   (set_attr "length" "4")])
6680
6681(define_expand "ashrdi3"
6682  [(set (match_operand:DI 0 "register_operand" "")
6683	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6684		     (match_operand:DI 2 "arith32_operand" "")))]
6685  "TARGET_64BIT"
6686  "
6687{
6688  if (GET_CODE (operands[2]) != CONST_INT)
6689    {
6690      rtx temp = gen_reg_rtx (DImode);
6691      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6692      emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6693      DONE;
6694    }
6695}")
6696
6697(define_insn ""
6698  [(set (match_operand:DI 0 "register_operand" "=r")
6699	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6700		     (match_operand:DI 2 "const_int_operand" "n")))]
6701  "TARGET_64BIT"
6702  "extrd,s %1,%p2,%Q2,%0"
6703  [(set_attr "type" "shift")
6704   (set_attr "length" "4")])
6705
6706(define_insn "vextrs64"
6707  [(set (match_operand:DI 0 "register_operand" "=r")
6708	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6709		     (minus:DI (const_int 63)
6710			       (match_operand:DI 2 "register_operand" "q"))))]
6711  "TARGET_64BIT"
6712  "extrd,s %1,%%sar,64,%0"
6713  [(set_attr "type" "shift")
6714   (set_attr "length" "4")])
6715
6716(define_insn "lshrsi3"
6717  [(set (match_operand:SI 0 "register_operand" "=r,r")
6718	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6719		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6720  ""
6721  "@
6722   {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6723   {extru|extrw,u} %1,%P2,%L2,%0"
6724  [(set_attr "type" "shift")
6725   (set_attr "length" "4")])
6726
6727(define_insn "lshrdi3"
6728  [(set (match_operand:DI 0 "register_operand" "=r,r")
6729	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6730		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6731  "TARGET_64BIT"
6732  "@
6733   shrpd %%r0,%1,%%sar,%0
6734   extrd,u %1,%p2,%Q2,%0"
6735  [(set_attr "type" "shift")
6736   (set_attr "length" "4")])
6737
6738; Shift right pair word 0 to 31 bits.
6739(define_insn "*shrpsi4_1"
6740  [(set (match_operand:SI 0 "register_operand" "=r")
6741	(match_operator:SI 4 "plus_xor_ior_operator"
6742	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6743		      (minus:SI (const_int 32)
6744				(match_operand:SI 3 "register_operand" "q")))
6745	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6746			(match_dup 3))]))]
6747  ""
6748  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6749  [(set_attr "type" "shift")
6750   (set_attr "length" "4")])
6751
6752(define_insn "*shrpsi4_2"
6753  [(set (match_operand:SI 0 "register_operand" "=r")
6754	(match_operator:SI 4 "plus_xor_ior_operator"
6755	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6756			(match_operand:SI 3 "register_operand" "q"))
6757	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6758		      (minus:SI (const_int 32)
6759				(match_dup 3)))]))]
6760  ""
6761  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6762  [(set_attr "type" "shift")
6763   (set_attr "length" "4")])
6764
6765; Shift right pair doubleword 0 to 63 bits.
6766(define_insn "*shrpdi4_1"
6767  [(set (match_operand:DI 0 "register_operand" "=r")
6768	(match_operator:DI 4 "plus_xor_ior_operator"
6769	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6770		      (minus:DI (const_int 64)
6771				(match_operand:DI 3 "register_operand" "q")))
6772	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6773			(match_dup 3))]))]
6774  "TARGET_64BIT"
6775  "shrpd %1,%2,%%sar,%0"
6776  [(set_attr "type" "shift")
6777   (set_attr "length" "4")])
6778
6779(define_insn "*shrpdi4_2"
6780  [(set (match_operand:DI 0 "register_operand" "=r")
6781	(match_operator:DI 4 "plus_xor_ior_operator"
6782	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6783			(match_operand:DI 3 "shift6_operand" "q"))
6784	   (ashift:DI (match_operand:SI 1 "register_operand" "r")
6785		      (minus:DI (const_int 64)
6786				(match_dup 3)))]))]
6787  "TARGET_64BIT"
6788  "shrpd %1,%2,%%sar,%0"
6789  [(set_attr "type" "shift")
6790   (set_attr "length" "4")])
6791
6792(define_insn "*shrpdi4_3"
6793  [(set (match_operand:DI 0 "register_operand" "=r")
6794	(match_operator:DI 5 "plus_xor_ior_operator"
6795	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6796		      (match_operand:DI 3 "const_int_operand" "n"))
6797	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6798			(match_operand:DI 4 "const_int_operand" "n"))]))]
6799  "TARGET_64BIT
6800   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6801  "shrpd %1,%2,%4,%0"
6802  [(set_attr "type" "shift")
6803   (set_attr "length" "4")])
6804
6805(define_insn "*shrpdi4_4"
6806  [(set (match_operand:DI 0 "register_operand" "=r")
6807	(match_operator:DI 5 "plus_xor_ior_operator"
6808	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6809			(match_operand:DI 4 "const_int_operand" "n"))
6810	   (ashift:DI (match_operand:DI 1 "register_operand" "r")
6811		      (match_operand:DI 3 "const_int_operand" "n"))]))]
6812  "TARGET_64BIT
6813   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6814  "shrpd %1,%2,%4,%0"
6815  [(set_attr "type" "shift")
6816   (set_attr "length" "4")])
6817
6818(define_insn "rotrsi3"
6819  [(set (match_operand:SI 0 "register_operand" "=r,r")
6820	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6821		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6822  ""
6823  "*
6824{
6825  if (GET_CODE (operands[2]) == CONST_INT)
6826    {
6827      operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6828      return \"{shd|shrpw} %1,%1,%2,%0\";
6829    }
6830  else
6831    return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6832}"
6833  [(set_attr "type" "shift")
6834   (set_attr "length" "4")])
6835
6836(define_expand "rotlsi3"
6837  [(set (match_operand:SI 0 "register_operand" "")
6838        (rotate:SI (match_operand:SI 1 "register_operand" "")
6839                   (match_operand:SI 2 "arith32_operand" "")))]
6840  ""
6841  "
6842{
6843  if (GET_CODE (operands[2]) != CONST_INT)
6844    {
6845      rtx temp = gen_reg_rtx (SImode);
6846      emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6847      emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6848      DONE;
6849    }
6850  /* Else expand normally.  */
6851}")
6852
6853(define_insn "*rotlsi3_internal"
6854  [(set (match_operand:SI 0 "register_operand" "=r")
6855        (rotate:SI (match_operand:SI 1 "register_operand" "r")
6856                   (match_operand:SI 2 "const_int_operand" "n")))]
6857  ""
6858  "*
6859{
6860  operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6861  return \"{shd|shrpw} %1,%1,%2,%0\";
6862}"
6863  [(set_attr "type" "shift")
6864   (set_attr "length" "4")])
6865
6866(define_insn "rotrdi3"
6867  [(set (match_operand:DI 0 "register_operand" "=r,r")
6868	(rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
6869		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6870  "TARGET_64BIT"
6871  "*
6872{
6873  if (GET_CODE (operands[2]) == CONST_INT)
6874    {
6875      operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
6876      return \"shrpd %1,%1,%2,%0\";
6877    }
6878  else
6879    return \"shrpd %1,%1,%%sar,%0\";
6880}"
6881  [(set_attr "type" "shift")
6882   (set_attr "length" "4")])
6883
6884(define_expand "rotldi3"
6885  [(set (match_operand:DI 0 "register_operand" "")
6886        (rotate:DI (match_operand:DI 1 "register_operand" "")
6887                   (match_operand:DI 2 "arith32_operand" "")))]
6888  "TARGET_64BIT"
6889  "
6890{
6891  if (GET_CODE (operands[2]) != CONST_INT)
6892    {
6893      rtx temp = gen_reg_rtx (DImode);
6894      emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
6895      emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
6896      DONE;
6897    }
6898  /* Else expand normally.  */
6899}")
6900
6901(define_insn "*rotldi3_internal"
6902  [(set (match_operand:DI 0 "register_operand" "=r")
6903        (rotate:DI (match_operand:DI 1 "register_operand" "r")
6904                   (match_operand:DI 2 "const_int_operand" "n")))]
6905  "TARGET_64BIT"
6906  "*
6907{
6908  operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
6909  return \"shrpd %1,%1,%2,%0\";
6910}"
6911  [(set_attr "type" "shift")
6912   (set_attr "length" "4")])
6913
6914(define_insn ""
6915  [(set (match_operand:SI 0 "register_operand" "=r")
6916	(match_operator:SI 5 "plus_xor_ior_operator"
6917	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6918		      (match_operand:SI 3 "const_int_operand" "n"))
6919	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6920			(match_operand:SI 4 "const_int_operand" "n"))]))]
6921  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6922  "{shd|shrpw} %1,%2,%4,%0"
6923  [(set_attr "type" "shift")
6924   (set_attr "length" "4")])
6925
6926(define_insn ""
6927  [(set (match_operand:SI 0 "register_operand" "=r")
6928	(match_operator:SI 5 "plus_xor_ior_operator"
6929	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6930			(match_operand:SI 4 "const_int_operand" "n"))
6931	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6932		      (match_operand:SI 3 "const_int_operand" "n"))]))]
6933  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6934  "{shd|shrpw} %1,%2,%4,%0"
6935  [(set_attr "type" "shift")
6936   (set_attr "length" "4")])
6937
6938(define_expand "shd_internal"
6939  [(set (match_operand:SI 0 "register_operand")
6940	(ior:SI
6941	  (lshiftrt:SI (match_operand:SI 1 "register_operand")
6942		       (match_operand:SI 2 "const_int_operand"))
6943	  (ashift:SI (match_operand:SI 3 "register_operand")
6944		     (match_operand:SI 4 "const_int_operand"))))]
6945  "")
6946
6947(define_insn ""
6948  [(set (match_operand:SI 0 "register_operand" "=r")
6949	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6950			   (match_operand:SI 2 "const_int_operand" ""))
6951		(match_operand:SI 3 "const_int_operand" "")))]
6952  "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6953  "*
6954{
6955  int cnt = INTVAL (operands[2]) & 31;
6956  operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6957  operands[2] = GEN_INT (31 - cnt);
6958  return \"{zdep|depw,z} %1,%2,%3,%0\";
6959}"
6960  [(set_attr "type" "shift")
6961   (set_attr "length" "4")])
6962
6963;; Unconditional and other jump instructions.
6964
6965;; Trivial return used when no epilogue is needed.
6966(define_insn "return"
6967  [(return)
6968   (use (reg:SI 2))]
6969  "pa_can_use_return_insn ()"
6970  "*
6971{
6972  if (TARGET_PA_20)
6973    return \"bve%* (%%r2)\";
6974  return \"bv%* %%r0(%%r2)\";
6975}"
6976  [(set_attr "type" "branch")
6977   (set_attr "length" "4")])
6978
6979;; This is used for most returns.
6980(define_insn "return_internal"
6981  [(return)
6982   (use (reg:SI 2))]
6983  ""
6984  "*
6985{
6986  if (TARGET_PA_20)
6987    return \"bve%* (%%r2)\";
6988  return \"bv%* %%r0(%%r2)\";
6989}"
6990  [(set_attr "type" "branch")
6991   (set_attr "length" "4")])
6992
6993;; This is used for eh returns which bypass the return stub.
6994(define_insn "return_external_pic"
6995  [(return)
6996   (clobber (reg:SI 1))
6997   (use (reg:SI 2))]
6998  "!TARGET_NO_SPACE_REGS
6999   && !TARGET_PA_20
7000   && flag_pic && crtl->calls_eh_return"
7001  "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7002  [(set_attr "type" "branch")
7003   (set_attr "length" "12")])
7004
7005(define_expand "prologue"
7006  [(const_int 0)]
7007  ""
7008  "pa_expand_prologue ();DONE;")
7009
7010(define_expand "sibcall_epilogue"
7011  [(return)]
7012  ""
7013  "
7014{
7015  pa_expand_epilogue ();
7016  DONE;
7017}")
7018
7019(define_expand "epilogue"
7020  [(return)]
7021  ""
7022  "
7023{
7024  rtx x;
7025
7026  /* Try to use the trivial return first.  Else use the full epilogue.  */
7027  if (pa_can_use_return_insn ())
7028    x = gen_return ();
7029  else
7030    {
7031      pa_expand_epilogue ();
7032
7033      /* EH returns bypass the normal return stub.  Thus, we must do an
7034	 interspace branch to return from functions that call eh_return.
7035	 This is only a problem for returns from shared code on ports
7036	 using space registers.  */
7037      if (!TARGET_NO_SPACE_REGS
7038	  && !TARGET_PA_20
7039	  && flag_pic && crtl->calls_eh_return)
7040	x = gen_return_external_pic ();
7041      else
7042	x = gen_return_internal ();
7043    }
7044  emit_jump_insn (x);
7045  DONE;
7046}")
7047
7048; Used by hppa_profile_hook to load the starting address of the current
7049; function; operand 1 contains the address of the label in operand 3
7050(define_insn "load_offset_label_address"
7051  [(set (match_operand:SI 0 "register_operand" "=r")
7052        (plus:SI (match_operand:SI 1 "register_operand" "r")
7053		 (minus:SI (match_operand:SI 2 "" "")
7054			   (label_ref:SI (match_operand 3 "" "")))))]
7055  ""
7056  "ldo %2-%l3(%1),%0"
7057  [(set_attr "type" "multi")
7058   (set_attr "length" "4")])
7059
7060; Output a code label and load its address.
7061(define_insn "lcla1"
7062  [(set (match_operand:SI 0 "register_operand" "=r")
7063        (label_ref:SI (match_operand 1 "" "")))
7064   (const_int 0)]
7065  "!TARGET_PA_20"
7066  "*
7067{
7068  output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7069  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7070                                     CODE_LABEL_NUMBER (operands[1]));
7071  return \"\";
7072}"
7073  [(set_attr "type" "multi")
7074   (set_attr "length" "8")])
7075
7076(define_insn "lcla2"
7077  [(set (match_operand:SI 0 "register_operand" "=r")
7078        (label_ref:SI (match_operand 1 "" "")))
7079   (const_int 0)]
7080  "TARGET_PA_20"
7081  "*
7082{
7083  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7084                                     CODE_LABEL_NUMBER (operands[1]));
7085  return \"mfia %0\";
7086}"
7087  [(set_attr "type" "move")
7088   (set_attr "length" "4")])
7089
7090(define_insn "blockage"
7091  [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7092  ""
7093  ""
7094  [(set_attr "length" "0")])
7095
7096(define_insn "jump"
7097  [(set (pc) (label_ref (match_operand 0 "" "")))]
7098  ""
7099  "*
7100{
7101  /* An unconditional branch which can reach its target.  */
7102  if (get_attr_length (insn) < 16)
7103    return \"b%* %l0\";
7104
7105  return pa_output_lbranch (operands[0], insn, 1);
7106}"
7107  [(set_attr "type" "uncond_branch")
7108   (set_attr "pa_combine_type" "uncond_branch")
7109   (set (attr "length")
7110    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7111	       (const_int MAX_17BIT_OFFSET))
7112	   (const_int 4)
7113	   (match_test "TARGET_PORTABLE_RUNTIME")
7114	   (const_int 20)
7115	   (not (match_test "flag_pic"))
7116	   (const_int 16)]
7117	  (const_int 24)))])
7118
7119;;; Hope this is only within a function...
7120(define_insn "indirect_jump"
7121  [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7122  ""
7123  "bv%* %%r0(%0)"
7124  [(set_attr "type" "branch")
7125   (set_attr "length" "4")])
7126
7127;;; An indirect jump can be optimized to a direct jump.  GAS for the
7128;;; SOM target doesn't allow branching to a label inside a function.
7129;;; We also don't correctly compute branch distances for labels
7130;;; outside the current function.  Thus, we use an indirect jump can't
7131;;; be optimized to a direct jump for all targets.  We assume that
7132;;; the branch target is in the same space (i.e., nested function
7133;;; jumping to a label in an outer function in the same translation
7134;;; unit).
7135(define_expand "nonlocal_goto"
7136  [(use (match_operand 0 "general_operand" ""))
7137   (use (match_operand 1 "general_operand" ""))
7138   (use (match_operand 2 "general_operand" ""))
7139   (use (match_operand 3 "general_operand" ""))]
7140  ""
7141{
7142  rtx lab = operands[1];
7143  rtx stack = operands[2];
7144  rtx fp = operands[3];
7145
7146  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7147  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7148
7149  lab = copy_to_reg (lab);
7150
7151  /* Restore the stack and frame pointers.  */
7152  fp = copy_to_reg (fp);
7153  emit_stack_restore (SAVE_NONLOCAL, stack);
7154
7155  /* Ensure the frame pointer move is not optimized.  */
7156  emit_insn (gen_blockage ());
7157  emit_clobber (hard_frame_pointer_rtx);
7158  emit_clobber (frame_pointer_rtx);
7159  emit_move_insn (hard_frame_pointer_rtx, fp);
7160
7161  emit_use (hard_frame_pointer_rtx);
7162  emit_use (stack_pointer_rtx);
7163
7164  /* Nonlocal goto jumps are only used between functions in the same
7165     translation unit.  Thus, we can avoid the extra overhead of an
7166     interspace jump.  */
7167  emit_jump_insn (gen_indirect_goto (lab));
7168  emit_barrier ();
7169  DONE;
7170})
7171
7172(define_insn "indirect_goto"
7173  [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7174  "GET_MODE (operands[0]) == word_mode"
7175  "bv%* %%r0(%0)"
7176  [(set_attr "type" "branch")
7177   (set_attr "length" "4")])
7178
7179;; Subroutines of "casesi".
7180;; operand 0 is index
7181;; operand 1 is the minimum bound
7182;; operand 2 is the maximum bound - minimum bound + 1
7183;; operand 3 is CODE_LABEL for the table;
7184;; operand 4 is the CODE_LABEL to go to if index out of range.
7185
7186(define_expand "casesi"
7187  [(match_operand:SI 0 "general_operand" "")
7188   (match_operand:SI 1 "const_int_operand" "")
7189   (match_operand:SI 2 "const_int_operand" "")
7190   (match_operand 3 "" "")
7191   (match_operand 4 "" "")]
7192  ""
7193  "
7194{
7195  if (GET_CODE (operands[0]) != REG)
7196    operands[0] = force_reg (SImode, operands[0]);
7197
7198  if (operands[1] != const0_rtx)
7199    {
7200      rtx index = gen_reg_rtx (SImode);
7201
7202      operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7203      if (!INT_14_BITS (operands[1]))
7204	operands[1] = force_reg (SImode, operands[1]);
7205      emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7206      operands[0] = index;
7207    }
7208
7209  if (!INT_5_BITS (operands[2]))
7210    operands[2] = force_reg (SImode, operands[2]);
7211
7212  /* This branch prevents us finding an insn for the delay slot of the
7213     following vectored branch.  It might be possible to use the delay
7214     slot if an index value of -1 was used to transfer to the out-of-range
7215     label.  In order to do this, we would have to output the -1 vector
7216     element after the delay insn.  The casesi output code would have to
7217     check if the casesi insn is in a delay branch sequence and output
7218     the delay insn if one is found.  If this was done, then it might
7219     then be worthwhile to split the casesi patterns to improve scheduling.
7220     However, it's not clear that all this extra complexity is worth
7221     the effort.  */
7222  {
7223    rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7224    emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7225  }
7226
7227  /* In 64bit mode we must make sure to wipe the upper bits of the register
7228     just in case the addition overflowed or we had random bits in the
7229     high part of the register.  */
7230  if (TARGET_64BIT)
7231    {
7232      rtx index = gen_reg_rtx (DImode);
7233
7234      emit_insn (gen_extendsidi2 (index, operands[0]));
7235      operands[0] = index;
7236    }
7237
7238  if (TARGET_64BIT)
7239    emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7240  else if (flag_pic)
7241    emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7242  else
7243    emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7244  DONE;
7245}")
7246
7247;;; 32-bit code, absolute branch table.
7248(define_insn "casesi32"
7249  [(set (pc) (mem:SI (plus:SI
7250		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7251				(const_int 4))
7252		       (label_ref (match_operand 1 "" "")))))
7253   (clobber (match_scratch:SI 2 "=&r"))]
7254  "!flag_pic"
7255  "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7256  [(set_attr "type" "multi")
7257   (set_attr "length" "16")])
7258
7259;;; 32-bit code, relative branch table.
7260(define_insn "casesi32p"
7261  [(set (pc) (mem:SI (plus:SI
7262		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7263				(const_int 4))
7264		       (label_ref (match_operand 1 "" "")))))
7265   (clobber (match_scratch:SI 2 "=&r"))
7266   (clobber (match_scratch:SI 3 "=&r"))]
7267  "flag_pic"
7268  "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7269{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7270  [(set_attr "type" "multi")
7271   (set (attr "length")
7272     (if_then_else (match_test "TARGET_PA_20")
7273	(const_int 20)
7274	(const_int 24)))])
7275
7276;;; 64-bit code, 32-bit relative branch table.
7277(define_insn "casesi64p"
7278  [(set (pc) (mem:DI (plus:DI
7279		       (mult:DI (match_operand:DI 0 "register_operand" "r")
7280				(const_int 8))
7281		       (label_ref (match_operand 1 "" "")))))
7282   (clobber (match_scratch:DI 2 "=&r"))
7283   (clobber (match_scratch:DI 3 "=&r"))]
7284  ""
7285  "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7286add,l %2,%3,%3\;bv,n %%r0(%3)"
7287  [(set_attr "type" "multi")
7288   (set_attr "length" "24")])
7289
7290
7291;; Call patterns.
7292;;- jump to subroutine
7293
7294(define_expand "call"
7295  [(parallel [(call (match_operand:SI 0 "" "")
7296		    (match_operand 1 "" ""))
7297	      (clobber (reg:SI 2))])]
7298  ""
7299  "
7300{
7301  rtx op;
7302  rtx nb = operands[1];
7303
7304  if (TARGET_PORTABLE_RUNTIME)
7305    op = force_reg (SImode, XEXP (operands[0], 0));
7306  else
7307    {
7308      op = XEXP (operands[0], 0);
7309
7310      /* Generate indirect long calls to non-local functions. */
7311      if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7312	{
7313	  tree call_decl = SYMBOL_REF_DECL (op);
7314	  if (!(call_decl && targetm.binds_local_p (call_decl)))
7315	    op = force_reg (word_mode, op);
7316	}
7317    }
7318
7319  if (TARGET_64BIT)
7320    {
7321      if (!virtuals_instantiated)
7322	emit_move_insn (arg_pointer_rtx,
7323			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7324				      GEN_INT (64)));
7325      else
7326	{
7327	  /* The loop pass can generate new libcalls after the virtual
7328	     registers are instantiated when fpregs are disabled because
7329	     the only method that we have for doing DImode multiplication
7330	     is with a libcall.  This could be trouble if we haven't
7331	     allocated enough space for the outgoing arguments.  */
7332	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7333
7334	  emit_move_insn (arg_pointer_rtx,
7335			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7336					GEN_INT (STACK_POINTER_OFFSET + 64)));
7337	}
7338    }
7339
7340  /* Use two different patterns for calls to explicitly named functions
7341     and calls through function pointers.  This is necessary as these two
7342     types of calls use different calling conventions, and CSE might try
7343     to change the named call into an indirect call in some cases (using
7344     two patterns keeps CSE from performing this optimization).
7345     
7346     We now use even more call patterns as there was a subtle bug in
7347     attempting to restore the pic register after a call using a simple
7348     move insn.  During reload, a instruction involving a pseudo register
7349     with no explicit dependence on the PIC register can be converted
7350     to an equivalent load from memory using the PIC register.  If we
7351     emit a simple move to restore the PIC register in the initial rtl
7352     generation, then it can potentially be repositioned during scheduling.
7353     and an instruction that eventually uses the PIC register may end up
7354     between the call and the PIC register restore.
7355     
7356     This only worked because there is a post call group of instructions
7357     that are scheduled with the call.  These instructions are included
7358     in the same basic block as the call.  However, calls can throw in
7359     C++ code and a basic block has to terminate at the call if the call
7360     can throw.  This results in the PIC register restore being scheduled
7361     independently from the call.  So, we now hide the save and restore
7362     of the PIC register in the call pattern until after reload.  Then,
7363     we split the moves out.  A small side benefit is that we now don't
7364     need to have a use of the PIC register in the return pattern and
7365     the final save/restore operation is not needed.
7366     
7367     I elected to just use register %r4 in the PIC patterns instead
7368     of trying to force hppa_pic_save_rtx () to a callee saved register.
7369     This might have required a new register class and constraint.  It
7370     was also simpler to just handle the restore from a register than a
7371     generic pseudo.  */
7372  if (TARGET_64BIT)
7373    {
7374      rtx r4 = gen_rtx_REG (word_mode, 4);
7375      if (GET_CODE (op) == SYMBOL_REF)
7376	emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7377      else
7378	{
7379	  op = force_reg (word_mode, op);
7380	  emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7381	}
7382    }
7383  else
7384    {
7385      if (GET_CODE (op) == SYMBOL_REF)
7386	{
7387	  if (flag_pic)
7388	    {
7389	      rtx r4 = gen_rtx_REG (word_mode, 4);
7390	      emit_call_insn (gen_call_symref_pic (op, nb, r4));
7391	    }
7392	  else
7393	    emit_call_insn (gen_call_symref (op, nb));
7394	}
7395      else
7396	{
7397	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7398	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7399	  if (flag_pic)
7400	    {
7401	      rtx r4 = gen_rtx_REG (word_mode, 4);
7402	      emit_call_insn (gen_call_reg_pic (nb, r4));
7403	    }
7404	  else
7405	    emit_call_insn (gen_call_reg (nb));
7406	}
7407    }
7408
7409  DONE;
7410}")
7411
7412;; We use function calls to set the attribute length of calls and millicode
7413;; calls.  This is necessary because of the large variety of call sequences.
7414;; Implementing the calculation in rtl is difficult as well as ugly.  As
7415;; we need the same calculation in several places, maintenance becomes a
7416;; nightmare.
7417;;
7418;; However, this has a subtle impact on branch shortening.  When the
7419;; expression used to set the length attribute of an instruction depends
7420;; on a relative address (e.g., pc or a branch address), genattrtab
7421;; notes that the insn's length is variable, and attempts to determine a
7422;; worst-case default length and code to compute an insn's current length.
7423
7424;; The use of a function call hides the variable dependence of our calls
7425;; and millicode calls.  The result is genattrtab doesn't treat the operation
7426;; as variable and it only generates code for the default case using our
7427;; function call.  Because of this, calls and millicode calls have a fixed
7428;; length in the branch shortening pass, and some branches will use a longer
7429;; code sequence than necessary.  However, the length of any given call
7430;; will still reflect its final code location and it may be shorter than
7431;; the initial length estimate.
7432
7433;; It's possible to trick genattrtab by adding an expression involving `pc'
7434;; in the set.  However, when genattrtab hits a function call in its attempt
7435;; to compute the default length, it marks the result as unknown and sets
7436;; the default result to MAX_INT ;-(  One possible fix that would allow
7437;; calls to participate in branch shortening would be to make the call to
7438;; insn_default_length a target option.  Then, we could massage unknown
7439;; results.  Another fix might be to change genattrtab so that it just does
7440;; the call in the variable case as it already does for the fixed case.
7441
7442(define_insn "call_symref"
7443  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7444	 (match_operand 1 "" "i"))
7445   (clobber (reg:SI 1))
7446   (clobber (reg:SI 2))
7447   (use (const_int 0))]
7448  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7449  "*
7450{
7451  pa_output_arg_descriptor (insn);
7452  return pa_output_call (insn, operands[0], 0);
7453}"
7454  [(set_attr "type" "call")
7455   (set (attr "length")
7456	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7457	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7458
7459(define_insn "call_symref_pic"
7460  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7461	 (match_operand 1 "" "i"))
7462   (clobber (reg:SI 1))
7463   (clobber (reg:SI 2))
7464   (clobber (match_operand 2))
7465   (use (reg:SI 19))
7466   (use (const_int 0))]
7467  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7468  "#")
7469
7470;; Split out the PIC register save and restore after reload.  As the
7471;; split is done after reload, there are some situations in which we
7472;; unnecessarily save and restore %r4.  This happens when there is a
7473;; single call and the PIC register is not used after the call.
7474;;
7475;; The split has to be done since call_from_call_insn () can't handle
7476;; the pattern as is.  Noreturn calls are special because they have to
7477;; terminate the basic block.  The split has to contain more than one
7478;; insn.
7479(define_split
7480  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7481		    (match_operand 1 "" ""))
7482	      (clobber (reg:SI 1))
7483	      (clobber (reg:SI 2))
7484	      (clobber (match_operand 2))
7485	      (use (reg:SI 19))
7486	      (use (const_int 0))])]
7487  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7488   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7489  [(set (match_dup 2) (reg:SI 19))
7490   (parallel [(call (mem:SI (match_dup 0))
7491		    (match_dup 1))
7492	      (clobber (reg:SI 1))
7493	      (clobber (reg:SI 2))
7494	      (use (reg:SI 19))
7495	      (use (const_int 0))])]
7496  "")
7497
7498(define_split
7499  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7500		    (match_operand 1 "" ""))
7501	      (clobber (reg:SI 1))
7502	      (clobber (reg:SI 2))
7503	      (clobber (match_operand 2))
7504	      (use (reg:SI 19))
7505	      (use (const_int 0))])]
7506  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7507  [(set (match_dup 2) (reg:SI 19))
7508   (parallel [(call (mem:SI (match_dup 0))
7509		    (match_dup 1))
7510	      (clobber (reg:SI 1))
7511	      (clobber (reg:SI 2))
7512	      (use (reg:SI 19))
7513	      (use (const_int 0))])
7514   (set (reg:SI 19) (match_dup 2))]
7515  "")
7516
7517(define_insn "*call_symref_pic_post_reload"
7518  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7519	 (match_operand 1 "" "i"))
7520   (clobber (reg:SI 1))
7521   (clobber (reg:SI 2))
7522   (use (reg:SI 19))
7523   (use (const_int 0))]
7524  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7525  "*
7526{
7527  pa_output_arg_descriptor (insn);
7528  return pa_output_call (insn, operands[0], 0);
7529}"
7530  [(set_attr "type" "call")
7531   (set (attr "length")
7532	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7533	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7534
7535;; This pattern is split if it is necessary to save and restore the
7536;; PIC register.
7537(define_insn "call_symref_64bit"
7538  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7539	 (match_operand 1 "" "i"))
7540   (clobber (reg:DI 1))
7541   (clobber (reg:DI 2))
7542   (clobber (match_operand 2))
7543   (use (reg:DI 27))
7544   (use (reg:DI 29))
7545   (use (const_int 0))]
7546  "TARGET_64BIT"
7547  "#")
7548
7549;; Split out the PIC register save and restore after reload.  As the
7550;; split is done after reload, there are some situations in which we
7551;; unnecessarily save and restore %r4.  This happens when there is a
7552;; single call and the PIC register is not used after the call.
7553;;
7554;; The split has to be done since call_from_call_insn () can't handle
7555;; the pattern as is.  Noreturn calls are special because they have to
7556;; terminate the basic block.  The split has to contain more than one
7557;; insn.
7558(define_split
7559  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7560		    (match_operand 1 "" ""))
7561	      (clobber (reg:DI 1))
7562	      (clobber (reg:DI 2))
7563	      (clobber (match_operand 2))
7564	      (use (reg:DI 27))
7565	      (use (reg:DI 29))
7566	      (use (const_int 0))])]
7567  "TARGET_64BIT && reload_completed
7568   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7569  [(set (match_dup 2) (reg:DI 27))
7570   (parallel [(call (mem:SI (match_dup 0))
7571		    (match_dup 1))
7572	      (clobber (reg:DI 1))
7573	      (clobber (reg:DI 2))
7574	      (use (reg:DI 27))
7575	      (use (reg:DI 29))
7576	      (use (const_int 0))])]
7577  "")
7578
7579(define_split
7580  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7581		    (match_operand 1 "" ""))
7582	      (clobber (reg:DI 1))
7583	      (clobber (reg:DI 2))
7584	      (clobber (match_operand 2))
7585	      (use (reg:DI 27))
7586	      (use (reg:DI 29))
7587	      (use (const_int 0))])]
7588  "TARGET_64BIT && reload_completed"
7589  [(set (match_dup 2) (reg:DI 27))
7590   (parallel [(call (mem:SI (match_dup 0))
7591		    (match_dup 1))
7592	      (clobber (reg:DI 1))
7593	      (clobber (reg:DI 2))
7594	      (use (reg:DI 27))
7595	      (use (reg:DI 29))
7596	      (use (const_int 0))])
7597   (set (reg:DI 27) (match_dup 2))]
7598  "")
7599
7600(define_insn "*call_symref_64bit_post_reload"
7601  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7602	 (match_operand 1 "" "i"))
7603   (clobber (reg:DI 1))
7604   (clobber (reg:DI 2))
7605   (use (reg:DI 27))
7606   (use (reg:DI 29))
7607   (use (const_int 0))]
7608  "TARGET_64BIT"
7609  "*
7610{
7611  return pa_output_call (insn, operands[0], 0);
7612}"
7613  [(set_attr "type" "call")
7614   (set (attr "length")
7615	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7616	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7617
7618(define_insn "call_reg"
7619  [(call (mem:SI (reg:SI 22))
7620	 (match_operand 0 "" "i"))
7621   (clobber (reg:SI 1))
7622   (clobber (reg:SI 2))
7623   (use (const_int 1))]
7624  "!TARGET_64BIT"
7625  "*
7626{
7627  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7628}"
7629  [(set_attr "type" "dyncall")
7630   (set (attr "length")
7631	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7632	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7633
7634;; This pattern is split if it is necessary to save and restore the
7635;; PIC register.
7636(define_insn "call_reg_pic"
7637  [(call (mem:SI (reg:SI 22))
7638	 (match_operand 0 "" "i"))
7639   (clobber (reg:SI 1))
7640   (clobber (reg:SI 2))
7641   (clobber (match_operand 1))
7642   (use (reg:SI 19))
7643   (use (const_int 1))]
7644  "!TARGET_64BIT"
7645  "#")
7646
7647;; Split out the PIC register save and restore after reload.  As the
7648;; split is done after reload, there are some situations in which we
7649;; unnecessarily save and restore %r4.  This happens when there is a
7650;; single call and the PIC register is not used after the call.
7651;;
7652;; The split has to be done since call_from_call_insn () can't handle
7653;; the pattern as is.  Noreturn calls are special because they have to
7654;; terminate the basic block.  The split has to contain more than one
7655;; insn.
7656(define_split
7657  [(parallel [(call (mem:SI (reg:SI 22))
7658		    (match_operand 0 "" ""))
7659	      (clobber (reg:SI 1))
7660	      (clobber (reg:SI 2))
7661	      (clobber (match_operand 1))
7662	      (use (reg:SI 19))
7663	      (use (const_int 1))])]
7664  "!TARGET_64BIT && reload_completed
7665   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7666  [(set (match_dup 1) (reg:SI 19))
7667   (parallel [(call (mem:SI (reg:SI 22))
7668		    (match_dup 0))
7669	      (clobber (reg:SI 1))
7670	      (clobber (reg:SI 2))
7671	      (use (reg:SI 19))
7672	      (use (const_int 1))])]
7673  "")
7674
7675(define_split
7676  [(parallel [(call (mem:SI (reg:SI 22))
7677		    (match_operand 0 "" ""))
7678	      (clobber (reg:SI 1))
7679	      (clobber (reg:SI 2))
7680	      (clobber (match_operand 1))
7681	      (use (reg:SI 19))
7682	      (use (const_int 1))])]
7683  "!TARGET_64BIT && reload_completed"
7684  [(set (match_dup 1) (reg:SI 19))
7685   (parallel [(call (mem:SI (reg:SI 22))
7686		    (match_dup 0))
7687	      (clobber (reg:SI 1))
7688	      (clobber (reg:SI 2))
7689	      (use (reg:SI 19))
7690	      (use (const_int 1))])
7691   (set (reg:SI 19) (match_dup 1))]
7692  "")
7693
7694(define_insn "*call_reg_pic_post_reload"
7695  [(call (mem:SI (reg:SI 22))
7696	 (match_operand 0 "" "i"))
7697   (clobber (reg:SI 1))
7698   (clobber (reg:SI 2))
7699   (use (reg:SI 19))
7700   (use (const_int 1))]
7701  "!TARGET_64BIT"
7702  "*
7703{
7704  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7705}"
7706  [(set_attr "type" "dyncall")
7707   (set (attr "length")
7708	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7709	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7710
7711;; This pattern is split if it is necessary to save and restore the
7712;; PIC register.
7713(define_insn "call_reg_64bit"
7714  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7715	 (match_operand 1 "" "i"))
7716   (clobber (reg:DI 2))
7717   (clobber (match_operand 2))
7718   (use (reg:DI 27))
7719   (use (reg:DI 29))
7720   (use (const_int 1))]
7721  "TARGET_64BIT"
7722  "#")
7723
7724;; Split out the PIC register save and restore after reload.  As the
7725;; split is done after reload, there are some situations in which we
7726;; unnecessarily save and restore %r4.  This happens when there is a
7727;; single call and the PIC register is not used after the call.
7728;;
7729;; The split has to be done since call_from_call_insn () can't handle
7730;; the pattern as is.  Noreturn calls are special because they have to
7731;; terminate the basic block.  The split has to contain more than one
7732;; insn.
7733(define_split
7734  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7735		    (match_operand 1 "" ""))
7736	      (clobber (reg:DI 2))
7737	      (clobber (match_operand 2))
7738	      (use (reg:DI 27))
7739	      (use (reg:DI 29))
7740	      (use (const_int 1))])]
7741  "TARGET_64BIT && reload_completed
7742   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7743  [(set (match_dup 2) (reg:DI 27))
7744   (parallel [(call (mem:SI (match_dup 0))
7745		    (match_dup 1))
7746	      (clobber (reg:DI 2))
7747	      (use (reg:DI 27))
7748	      (use (reg:DI 29))
7749	      (use (const_int 1))])]
7750  "")
7751
7752(define_split
7753  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7754		    (match_operand 1 "" ""))
7755	      (clobber (reg:DI 2))
7756	      (clobber (match_operand 2))
7757	      (use (reg:DI 27))
7758	      (use (reg:DI 29))
7759	      (use (const_int 1))])]
7760  "TARGET_64BIT && reload_completed"
7761  [(set (match_dup 2) (reg:DI 27))
7762   (parallel [(call (mem:SI (match_dup 0))
7763		    (match_dup 1))
7764	      (clobber (reg:DI 2))
7765	      (use (reg:DI 27))
7766	      (use (reg:DI 29))
7767	      (use (const_int 1))])
7768   (set (reg:DI 27) (match_dup 2))]
7769  "")
7770
7771(define_insn "*call_reg_64bit_post_reload"
7772  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7773	 (match_operand 1 "" "i"))
7774   (clobber (reg:DI 2))
7775   (use (reg:DI 27))
7776   (use (reg:DI 29))
7777   (use (const_int 1))]
7778  "TARGET_64BIT"
7779  "*
7780{
7781  return pa_output_indirect_call (insn, operands[0]);
7782}"
7783  [(set_attr "type" "dyncall")
7784   (set (attr "length")
7785	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7786	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7787
7788(define_expand "call_value"
7789  [(parallel [(set (match_operand 0 "" "")
7790		   (call (match_operand:SI 1 "" "")
7791			 (match_operand 2 "" "")))
7792	      (clobber (reg:SI 2))])]
7793  ""
7794{
7795  rtx op;
7796  rtx dst = operands[0];
7797  rtx nb = operands[2];
7798  bool call_powf = false;
7799
7800  if (TARGET_PORTABLE_RUNTIME)
7801    op = force_reg (SImode, XEXP (operands[1], 0));
7802  else
7803    {
7804      op = XEXP (operands[1], 0);
7805      if (GET_CODE (op) == SYMBOL_REF)
7806	{
7807	  /* Handle special call to buggy powf function.  */
7808	  if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
7809	      && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7810	    call_powf = true;
7811
7812	  /* Generate indirect long calls to non-local functions. */
7813	  else if (TARGET_LONG_CALLS)
7814	    {
7815	      tree call_decl = SYMBOL_REF_DECL (op);
7816	      if (!(call_decl && targetm.binds_local_p (call_decl)))
7817		op = force_reg (word_mode, op);
7818	    }
7819	}
7820    }
7821
7822  if (TARGET_64BIT)
7823    {
7824      if (!virtuals_instantiated)
7825	emit_move_insn (arg_pointer_rtx,
7826			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7827				      GEN_INT (64)));
7828      else
7829	{
7830	  /* The loop pass can generate new libcalls after the virtual
7831	     registers are instantiated when fpregs are disabled because
7832	     the only method that we have for doing DImode multiplication
7833	     is with a libcall.  This could be trouble if we haven't
7834	     allocated enough space for the outgoing arguments.  */
7835	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7836
7837	  emit_move_insn (arg_pointer_rtx,
7838			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7839					GEN_INT (STACK_POINTER_OFFSET + 64)));
7840	}
7841    }
7842
7843  /* Use two different patterns for calls to explicitly named functions
7844     and calls through function pointers.  This is necessary as these two
7845     types of calls use different calling conventions, and CSE might try
7846     to change the named call into an indirect call in some cases (using
7847     two patterns keeps CSE from performing this optimization).
7848
7849     We now use even more call patterns as there was a subtle bug in
7850     attempting to restore the pic register after a call using a simple
7851     move insn.  During reload, a instruction involving a pseudo register
7852     with no explicit dependence on the PIC register can be converted
7853     to an equivalent load from memory using the PIC register.  If we
7854     emit a simple move to restore the PIC register in the initial rtl
7855     generation, then it can potentially be repositioned during scheduling.
7856     and an instruction that eventually uses the PIC register may end up
7857     between the call and the PIC register restore.
7858     
7859     This only worked because there is a post call group of instructions
7860     that are scheduled with the call.  These instructions are included
7861     in the same basic block as the call.  However, calls can throw in
7862     C++ code and a basic block has to terminate at the call if the call
7863     can throw.  This results in the PIC register restore being scheduled
7864     independently from the call.  So, we now hide the save and restore
7865     of the PIC register in the call pattern until after reload.  Then,
7866     we split the moves out.  A small side benefit is that we now don't
7867     need to have a use of the PIC register in the return pattern and
7868     the final save/restore operation is not needed.
7869     
7870     I elected to just use register %r4 in the PIC patterns instead
7871     of trying to force hppa_pic_save_rtx () to a callee saved register.
7872     This might have required a new register class and constraint.  It
7873     was also simpler to just handle the restore from a register than a
7874     generic pseudo.  */
7875  if (TARGET_64BIT)
7876    {
7877      rtx r4 = gen_rtx_REG (word_mode, 4);
7878      if (GET_CODE (op) == SYMBOL_REF)
7879	{
7880	  if (call_powf)
7881	    emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
7882	  else
7883	    emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7884	}
7885      else
7886	{
7887	  op = force_reg (word_mode, op);
7888	  emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7889	}
7890    }
7891  else
7892    {
7893      if (GET_CODE (op) == SYMBOL_REF)
7894	{
7895	  if (flag_pic)
7896	    {
7897	      rtx r4 = gen_rtx_REG (word_mode, 4);
7898
7899	      if (call_powf)
7900		emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
7901	      else
7902		emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7903	    }
7904	  else
7905	    {
7906	      if (call_powf)
7907		emit_call_insn (gen_call_val_powf (dst, op, nb));
7908	      else
7909		emit_call_insn (gen_call_val_symref (dst, op, nb));
7910	    }
7911	}
7912      else
7913	{
7914	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7915	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7916	  if (flag_pic)
7917	    {
7918	      rtx r4 = gen_rtx_REG (word_mode, 4);
7919	      emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7920	    }
7921	  else
7922	    emit_call_insn (gen_call_val_reg (dst, nb));
7923	}
7924    }
7925
7926  DONE;
7927})
7928
7929(define_insn "call_val_symref"
7930  [(set (match_operand 0 "" "")
7931	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7932	      (match_operand 2 "" "i")))
7933   (clobber (reg:SI 1))
7934   (clobber (reg:SI 2))
7935   (use (const_int 0))]
7936  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7937  "*
7938{
7939  pa_output_arg_descriptor (insn);
7940  return pa_output_call (insn, operands[1], 0);
7941}"
7942  [(set_attr "type" "call")
7943   (set (attr "length")
7944	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7945	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7946
7947;; powf function clobbers %fr12
7948(define_insn "call_val_powf"
7949  [(set (match_operand 0 "" "")
7950	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7951	      (match_operand 2 "" "i")))
7952   (clobber (reg:SI 1))
7953   (clobber (reg:SI 2))
7954   (clobber (reg:DF 48))
7955   (use (const_int 1))]
7956  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7957  "*
7958{
7959  pa_output_arg_descriptor (insn);
7960  return pa_output_call (insn, operands[1], 0);
7961}"
7962  [(set_attr "type" "call")
7963   (set (attr "length")
7964	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7965	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7966
7967(define_insn "call_val_symref_pic"
7968  [(set (match_operand 0 "" "")
7969	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7970	      (match_operand 2 "" "i")))
7971   (clobber (reg:SI 1))
7972   (clobber (reg:SI 2))
7973   (clobber (match_operand 3))
7974   (use (reg:SI 19))
7975   (use (const_int 0))]
7976  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7977  "#")
7978
7979;; Split out the PIC register save and restore after reload.  As the
7980;; split is done after reload, there are some situations in which we
7981;; unnecessarily save and restore %r4.  This happens when there is a
7982;; single call and the PIC register is not used after the call.
7983;;
7984;; The split has to be done since call_from_call_insn () can't handle
7985;; the pattern as is.  Noreturn calls are special because they have to
7986;; terminate the basic block.  The split has to contain more than one
7987;; insn.
7988(define_split
7989  [(parallel [(set (match_operand 0 "" "")
7990	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7991		    (match_operand 2 "" "")))
7992	      (clobber (reg:SI 1))
7993	      (clobber (reg:SI 2))
7994	      (clobber (match_operand 3))
7995	      (use (reg:SI 19))
7996	      (use (const_int 0))])]
7997  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7998   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7999  [(set (match_dup 3) (reg:SI 19))
8000   (parallel [(set (match_dup 0)
8001	      (call (mem:SI (match_dup 1))
8002		    (match_dup 2)))
8003	      (clobber (reg:SI 1))
8004	      (clobber (reg:SI 2))
8005	      (use (reg:SI 19))
8006	      (use (const_int 0))])]
8007  "")
8008
8009(define_split
8010  [(parallel [(set (match_operand 0 "" "")
8011	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8012		    (match_operand 2 "" "")))
8013	      (clobber (reg:SI 1))
8014	      (clobber (reg:SI 2))
8015	      (clobber (match_operand 3))
8016	      (use (reg:SI 19))
8017	      (use (const_int 0))])]
8018  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8019  [(set (match_dup 3) (reg:SI 19))
8020   (parallel [(set (match_dup 0)
8021	      (call (mem:SI (match_dup 1))
8022		    (match_dup 2)))
8023	      (clobber (reg:SI 1))
8024	      (clobber (reg:SI 2))
8025	      (use (reg:SI 19))
8026	      (use (const_int 0))])
8027   (set (reg:SI 19) (match_dup 3))]
8028  "")
8029
8030(define_insn "*call_val_symref_pic_post_reload"
8031  [(set (match_operand 0 "" "")
8032	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8033	      (match_operand 2 "" "i")))
8034   (clobber (reg:SI 1))
8035   (clobber (reg:SI 2))
8036   (use (reg:SI 19))
8037   (use (const_int 0))]
8038  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8039  "*
8040{
8041  pa_output_arg_descriptor (insn);
8042  return pa_output_call (insn, operands[1], 0);
8043}"
8044  [(set_attr "type" "call")
8045   (set (attr "length")
8046	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8047	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8048
8049;; powf function clobbers %fr12
8050(define_insn "call_val_powf_pic"
8051  [(set (match_operand 0 "" "")
8052	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8053	      (match_operand 2 "" "i")))
8054   (clobber (reg:SI 1))
8055   (clobber (reg:SI 2))
8056   (clobber (reg:DF 48))
8057   (clobber (match_operand 3))
8058   (use (reg:SI 19))
8059   (use (const_int 1))]
8060  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8061  "#")
8062
8063;; Split out the PIC register save and restore after reload.  As the
8064;; split is done after reload, there are some situations in which we
8065;; unnecessarily save and restore %r4.  This happens when there is a
8066;; single call and the PIC register is not used after the call.
8067;;
8068;; The split has to be done since call_from_call_insn () can't handle
8069;; the pattern as is.  Noreturn calls are special because they have to
8070;; terminate the basic block.  The split has to contain more than one
8071;; insn.
8072(define_split
8073  [(parallel [(set (match_operand 0 "" "")
8074	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8075		    (match_operand 2 "" "")))
8076	      (clobber (reg:SI 1))
8077	      (clobber (reg:SI 2))
8078	      (clobber (reg:DF 48))
8079	      (clobber (match_operand 3))
8080	      (use (reg:SI 19))
8081	      (use (const_int 1))])]
8082  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8083   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8084  [(set (match_dup 3) (reg:SI 19))
8085   (parallel [(set (match_dup 0)
8086	      (call (mem:SI (match_dup 1))
8087		    (match_dup 2)))
8088	      (clobber (reg:SI 1))
8089	      (clobber (reg:SI 2))
8090	      (clobber (reg:DF 48))
8091	      (use (reg:SI 19))
8092	      (use (const_int 1))])]
8093  "")
8094
8095(define_split
8096  [(parallel [(set (match_operand 0 "" "")
8097	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8098		    (match_operand 2 "" "")))
8099	      (clobber (reg:SI 1))
8100	      (clobber (reg:SI 2))
8101	      (clobber (reg:DF 48))
8102	      (clobber (match_operand 3))
8103	      (use (reg:SI 19))
8104	      (use (const_int 1))])]
8105  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8106  [(set (match_dup 3) (reg:SI 19))
8107   (parallel [(set (match_dup 0)
8108	      (call (mem:SI (match_dup 1))
8109		    (match_dup 2)))
8110	      (clobber (reg:SI 1))
8111	      (clobber (reg:SI 2))
8112	      (clobber (reg:DF 48))
8113	      (use (reg:SI 19))
8114	      (use (const_int 1))])
8115   (set (reg:SI 19) (match_dup 3))]
8116  "")
8117
8118(define_insn "*call_val_powf_pic_post_reload"
8119  [(set (match_operand 0 "" "")
8120	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8121	      (match_operand 2 "" "i")))
8122   (clobber (reg:SI 1))
8123   (clobber (reg:SI 2))
8124   (clobber (reg:DF 48))
8125   (use (reg:SI 19))
8126   (use (const_int 1))]
8127  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8128  "*
8129{
8130  pa_output_arg_descriptor (insn);
8131  return pa_output_call (insn, operands[1], 0);
8132}"
8133  [(set_attr "type" "call")
8134   (set (attr "length")
8135	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8136	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8137
8138;; This pattern is split if it is necessary to save and restore the
8139;; PIC register.
8140(define_insn "call_val_symref_64bit"
8141  [(set (match_operand 0 "" "")
8142	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8143	      (match_operand 2 "" "i")))
8144   (clobber (reg:DI 1))
8145   (clobber (reg:DI 2))
8146   (clobber (match_operand 3))
8147   (use (reg:DI 27))
8148   (use (reg:DI 29))
8149   (use (const_int 0))]
8150  "TARGET_64BIT"
8151  "#")
8152
8153;; Split out the PIC register save and restore after reload.  As the
8154;; split is done after reload, there are some situations in which we
8155;; unnecessarily save and restore %r4.  This happens when there is a
8156;; single call and the PIC register is not used after the call.
8157;;
8158;; The split has to be done since call_from_call_insn () can't handle
8159;; the pattern as is.  Noreturn calls are special because they have to
8160;; terminate the basic block.  The split has to contain more than one
8161;; insn.
8162(define_split
8163  [(parallel [(set (match_operand 0 "" "")
8164	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8165		    (match_operand 2 "" "")))
8166	      (clobber (reg:DI 1))
8167	      (clobber (reg:DI 2))
8168	      (clobber (match_operand 3))
8169	      (use (reg:DI 27))
8170	      (use (reg:DI 29))
8171	      (use (const_int 0))])]
8172  "TARGET_64BIT && reload_completed
8173   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8174  [(set (match_dup 3) (reg:DI 27))
8175   (parallel [(set (match_dup 0)
8176	      (call (mem:SI (match_dup 1))
8177		    (match_dup 2)))
8178	      (clobber (reg:DI 1))
8179	      (clobber (reg:DI 2))
8180	      (use (reg:DI 27))
8181	      (use (reg:DI 29))
8182	      (use (const_int 0))])]
8183  "")
8184
8185(define_split
8186  [(parallel [(set (match_operand 0 "" "")
8187	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8188		    (match_operand 2 "" "")))
8189	      (clobber (reg:DI 1))
8190	      (clobber (reg:DI 2))
8191	      (clobber (match_operand 3))
8192	      (use (reg:DI 27))
8193	      (use (reg:DI 29))
8194	      (use (const_int 0))])]
8195  "TARGET_64BIT && reload_completed"
8196  [(set (match_dup 3) (reg:DI 27))
8197   (parallel [(set (match_dup 0)
8198	      (call (mem:SI (match_dup 1))
8199		    (match_dup 2)))
8200	      (clobber (reg:DI 1))
8201	      (clobber (reg:DI 2))
8202	      (use (reg:DI 27))
8203	      (use (reg:DI 29))
8204	      (use (const_int 0))])
8205   (set (reg:DI 27) (match_dup 3))]
8206  "")
8207
8208(define_insn "*call_val_symref_64bit_post_reload"
8209  [(set (match_operand 0 "" "")
8210	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8211	      (match_operand 2 "" "i")))
8212   (clobber (reg:DI 1))
8213   (clobber (reg:DI 2))
8214   (use (reg:DI 27))
8215   (use (reg:DI 29))
8216   (use (const_int 0))]
8217  "TARGET_64BIT"
8218  "*
8219{
8220  return pa_output_call (insn, operands[1], 0);
8221}"
8222  [(set_attr "type" "call")
8223   (set (attr "length")
8224	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8225	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8226
8227;; powf function clobbers %fr12
8228(define_insn "call_val_powf_64bit"
8229  [(set (match_operand 0 "" "")
8230	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8231	      (match_operand 2 "" "i")))
8232   (clobber (reg:DI 1))
8233   (clobber (reg:DI 2))
8234   (clobber (reg:DF 40))
8235   (clobber (match_operand 3))
8236   (use (reg:DI 27))
8237   (use (reg:DI 29))
8238   (use (const_int 1))]
8239  "TARGET_64BIT && TARGET_HPUX"
8240  "#")
8241
8242;; Split out the PIC register save and restore after reload.  As the
8243;; split is done after reload, there are some situations in which we
8244;; unnecessarily save and restore %r4.  This happens when there is a
8245;; single call and the PIC register is not used after the call.
8246;;
8247;; The split has to be done since call_from_call_insn () can't handle
8248;; the pattern as is.  Noreturn calls are special because they have to
8249;; terminate the basic block.  The split has to contain more than one
8250;; insn.
8251(define_split
8252  [(parallel [(set (match_operand 0 "" "")
8253	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8254		    (match_operand 2 "" "")))
8255	      (clobber (reg:DI 1))
8256	      (clobber (reg:DI 2))
8257	      (clobber (reg:DF 40))
8258	      (clobber (match_operand 3))
8259	      (use (reg:DI 27))
8260	      (use (reg:DI 29))
8261	      (use (const_int 1))])]
8262  "TARGET_64BIT && TARGET_HPUX && reload_completed
8263   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8264  [(set (match_dup 3) (reg:DI 27))
8265   (parallel [(set (match_dup 0)
8266	      (call (mem:SI (match_dup 1))
8267		    (match_dup 2)))
8268	      (clobber (reg:DI 1))
8269	      (clobber (reg:DI 2))
8270	      (clobber (reg:DF 40))
8271	      (use (reg:DI 27))
8272	      (use (reg:DI 29))
8273	      (use (const_int 1))])]
8274  "")
8275
8276(define_split
8277  [(parallel [(set (match_operand 0 "" "")
8278	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8279		    (match_operand 2 "" "")))
8280	      (clobber (reg:DI 1))
8281	      (clobber (reg:DI 2))
8282	      (clobber (reg:DF 40))
8283	      (clobber (match_operand 3))
8284	      (use (reg:DI 27))
8285	      (use (reg:DI 29))
8286	      (use (const_int 1))])]
8287  "TARGET_64BIT && TARGET_HPUX && reload_completed"
8288  [(set (match_dup 3) (reg:DI 27))
8289   (parallel [(set (match_dup 0)
8290	      (call (mem:SI (match_dup 1))
8291		    (match_dup 2)))
8292	      (clobber (reg:DI 1))
8293	      (clobber (reg:DI 2))
8294	      (clobber (reg:DF 40))
8295	      (use (reg:DI 27))
8296	      (use (reg:DI 29))
8297	      (use (const_int 1))])
8298   (set (reg:DI 27) (match_dup 3))]
8299  "")
8300
8301(define_insn "*call_val_powf_64bit_post_reload"
8302  [(set (match_operand 0 "" "")
8303	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8304	      (match_operand 2 "" "i")))
8305   (clobber (reg:DI 1))
8306   (clobber (reg:DI 2))
8307   (clobber (reg:DF 40))
8308   (use (reg:DI 27))
8309   (use (reg:DI 29))
8310   (use (const_int 1))]
8311  "TARGET_64BIT && TARGET_HPUX"
8312  "*
8313{
8314  return pa_output_call (insn, operands[1], 0);
8315}"
8316  [(set_attr "type" "call")
8317   (set (attr "length")
8318	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8319	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8320
8321(define_insn "call_val_reg"
8322  [(set (match_operand 0 "" "")
8323	(call (mem:SI (reg:SI 22))
8324	      (match_operand 1 "" "i")))
8325   (clobber (reg:SI 1))
8326   (clobber (reg:SI 2))
8327   (use (const_int 1))]
8328  "!TARGET_64BIT"
8329  "*
8330{
8331  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8332}"
8333  [(set_attr "type" "dyncall")
8334   (set (attr "length")
8335	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8336	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8337
8338;; This pattern is split if it is necessary to save and restore the
8339;; PIC register.
8340(define_insn "call_val_reg_pic"
8341  [(set (match_operand 0 "" "")
8342	(call (mem:SI (reg:SI 22))
8343	      (match_operand 1 "" "i")))
8344   (clobber (reg:SI 1))
8345   (clobber (reg:SI 2))
8346   (clobber (match_operand 2))
8347   (use (reg:SI 19))
8348   (use (const_int 1))]
8349  "!TARGET_64BIT"
8350  "#")
8351
8352;; Split out the PIC register save and restore after reload.  As the
8353;; split is done after reload, there are some situations in which we
8354;; unnecessarily save and restore %r4.  This happens when there is a
8355;; single call and the PIC register is not used after the call.
8356;;
8357;; The split has to be done since call_from_call_insn () can't handle
8358;; the pattern as is.  Noreturn calls are special because they have to
8359;; terminate the basic block.  The split has to contain more than one
8360;; insn.
8361(define_split
8362  [(parallel [(set (match_operand 0 "" "")
8363		   (call (mem:SI (reg:SI 22))
8364			 (match_operand 1 "" "")))
8365	      (clobber (reg:SI 1))
8366	      (clobber (reg:SI 2))
8367	      (clobber (match_operand 2))
8368	      (use (reg:SI 19))
8369	      (use (const_int 1))])]
8370  "!TARGET_64BIT && reload_completed
8371   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8372  [(set (match_dup 2) (reg:SI 19))
8373   (parallel [(set (match_dup 0)
8374		   (call (mem:SI (reg:SI 22))
8375			 (match_dup 1)))
8376	      (clobber (reg:SI 1))
8377	      (clobber (reg:SI 2))
8378	      (use (reg:SI 19))
8379	      (use (const_int 1))])]
8380  "")
8381
8382(define_split
8383  [(parallel [(set (match_operand 0 "" "")
8384		   (call (mem:SI (reg:SI 22))
8385			 (match_operand 1 "" "")))
8386	      (clobber (reg:SI 1))
8387	      (clobber (reg:SI 2))
8388	      (clobber (match_operand 2))
8389	      (use (reg:SI 19))
8390	      (use (const_int 1))])]
8391  "!TARGET_64BIT && reload_completed"
8392  [(set (match_dup 2) (reg:SI 19))
8393   (parallel [(set (match_dup 0)
8394		   (call (mem:SI (reg:SI 22))
8395			 (match_dup 1)))
8396	      (clobber (reg:SI 1))
8397	      (clobber (reg:SI 2))
8398	      (use (reg:SI 19))
8399	      (use (const_int 1))])
8400   (set (reg:SI 19) (match_dup 2))]
8401  "")
8402
8403(define_insn "*call_val_reg_pic_post_reload"
8404  [(set (match_operand 0 "" "")
8405	(call (mem:SI (reg:SI 22))
8406	      (match_operand 1 "" "i")))
8407   (clobber (reg:SI 1))
8408   (clobber (reg:SI 2))
8409   (use (reg:SI 19))
8410   (use (const_int 1))]
8411  "!TARGET_64BIT"
8412  "*
8413{
8414  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8415}"
8416  [(set_attr "type" "dyncall")
8417   (set (attr "length")
8418	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8419	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8420
8421;; This pattern is split if it is necessary to save and restore the
8422;; PIC register.
8423(define_insn "call_val_reg_64bit"
8424  [(set (match_operand 0 "" "")
8425	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8426	      (match_operand 2 "" "i")))
8427   (clobber (reg:DI 2))
8428   (clobber (match_operand 3))
8429   (use (reg:DI 27))
8430   (use (reg:DI 29))
8431   (use (const_int 1))]
8432  "TARGET_64BIT"
8433  "#")
8434
8435;; Split out the PIC register save and restore after reload.  As the
8436;; split is done after reload, there are some situations in which we
8437;; unnecessarily save and restore %r4.  This happens when there is a
8438;; single call and the PIC register is not used after the call.
8439;;
8440;; The split has to be done since call_from_call_insn () can't handle
8441;; the pattern as is.  Noreturn calls are special because they have to
8442;; terminate the basic block.  The split has to contain more than one
8443;; insn.
8444(define_split
8445  [(parallel [(set (match_operand 0 "" "")
8446		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8447			 (match_operand 2 "" "")))
8448	      (clobber (reg:DI 2))
8449	      (clobber (match_operand 3))
8450	      (use (reg:DI 27))
8451	      (use (reg:DI 29))
8452	      (use (const_int 1))])]
8453  "TARGET_64BIT && reload_completed
8454   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8455  [(set (match_dup 3) (reg:DI 27))
8456   (parallel [(set (match_dup 0)
8457		   (call (mem:SI (match_dup 1))
8458			 (match_dup 2)))
8459	      (clobber (reg:DI 2))
8460	      (use (reg:DI 27))
8461	      (use (reg:DI 29))
8462	      (use (const_int 1))])]
8463  "")
8464
8465(define_split
8466  [(parallel [(set (match_operand 0 "" "")
8467		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8468			 (match_operand 2 "" "")))
8469	      (clobber (reg:DI 2))
8470	      (clobber (match_operand 3))
8471	      (use (reg:DI 27))
8472	      (use (reg:DI 29))
8473	      (use (const_int 1))])]
8474  "TARGET_64BIT && reload_completed"
8475  [(set (match_dup 3) (reg:DI 27))
8476   (parallel [(set (match_dup 0)
8477		   (call (mem:SI (match_dup 1))
8478			 (match_dup 2)))
8479	      (clobber (reg:DI 2))
8480	      (use (reg:DI 27))
8481	      (use (reg:DI 29))
8482	      (use (const_int 1))])
8483   (set (reg:DI 27) (match_dup 3))]
8484  "")
8485
8486(define_insn "*call_val_reg_64bit_post_reload"
8487  [(set (match_operand 0 "" "")
8488	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8489	      (match_operand 2 "" "i")))
8490   (clobber (reg:DI 2))
8491   (use (reg:DI 27))
8492   (use (reg:DI 29))
8493   (use (const_int 1))]
8494  "TARGET_64BIT"
8495  "*
8496{
8497  return pa_output_indirect_call (insn, operands[1]);
8498}"
8499  [(set_attr "type" "dyncall")
8500   (set (attr "length")
8501	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8502	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8503
8504/* Expand special pc-relative call to _mcount.  */
8505
8506(define_expand "call_mcount"
8507  [(parallel [(call (match_operand:SI 0 "" "")
8508		    (match_operand 1 "" ""))
8509	      (set (reg:SI 25)
8510		   (plus:SI (reg:SI 2)
8511			    (minus:SI (match_operand 2 "" "")
8512				      (plus:SI (pc) (const_int 4)))))
8513	      (clobber (reg:SI 2))])]
8514  "!TARGET_PORTABLE_RUNTIME"
8515  "
8516{
8517  rtx op = XEXP (operands[0], 0);
8518  rtx nb = operands[1];
8519  rtx lab = operands[2];
8520
8521  if (TARGET_64BIT)
8522    {
8523      rtx r4 = gen_rtx_REG (word_mode, 4);
8524      emit_move_insn (arg_pointer_rtx,
8525		      gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8526				    GEN_INT (64)));
8527      emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8528    }
8529  else
8530    {
8531      if (flag_pic)
8532	{
8533	  rtx r4 = gen_rtx_REG (word_mode, 4);
8534	  emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8535	}
8536      else
8537	emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8538    }
8539
8540  DONE;
8541}")
8542
8543(define_insn "call_mcount_nonpic"
8544  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8545	 (match_operand 1 "" "i"))
8546   (set (reg:SI 25)
8547	(plus:SI (reg:SI 2)
8548		 (minus:SI (match_operand 2 "" "")
8549			   (plus:SI (pc) (const_int 4)))))
8550   (clobber (reg:SI 2))]
8551  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8552  "*
8553{
8554  pa_output_arg_descriptor (insn);
8555  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8556}"
8557  [(set_attr "type" "multi")
8558   (set_attr "length" "8")])
8559
8560(define_insn "call_mcount_pic"
8561  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8562	 (match_operand 1 "" "i"))
8563   (set (reg:SI 25)
8564	(plus:SI (reg:SI 2)
8565		 (minus:SI (match_operand 2 "" "")
8566			   (plus:SI (pc) (const_int 4)))))
8567   (clobber (reg:SI 2))
8568   (clobber (match_operand 3))
8569   (use (reg:SI 19))]
8570  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8571  "#")
8572
8573(define_split
8574  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8575		    (match_operand 1 "" ""))
8576	      (set (reg:SI 25)
8577		   (plus:SI (reg:SI 2)
8578			    (minus:SI (match_operand 2 "" "")
8579				      (plus:SI (pc) (const_int 4)))))
8580	      (clobber (reg:SI 2))
8581	      (clobber (match_operand 3))
8582	      (use (reg:SI 19))])]
8583  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8584  [(set (match_dup 3) (reg:SI 19))
8585   (parallel [(call (mem:SI (match_dup 0))
8586		    (match_dup 1))
8587	      (set (reg:SI 25)
8588		   (plus:SI (reg:SI 2)
8589			    (minus:SI (match_dup 2)
8590				      (plus:SI (pc) (const_int 4)))))
8591	      (clobber (reg:SI 2))
8592	      (use (reg:SI 19))])
8593   (set (reg:SI 19) (match_dup 3))]
8594  "")
8595
8596(define_insn "*call_mcount_pic_post_reload"
8597  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8598	 (match_operand 1 "" "i"))
8599   (set (reg:SI 25)
8600	(plus:SI (reg:SI 2)
8601		 (minus:SI (match_operand 2 "" "")
8602			   (plus:SI (pc) (const_int 4)))))
8603   (clobber (reg:SI 2))
8604   (use (reg:SI 19))]
8605  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8606  "*
8607{
8608  pa_output_arg_descriptor (insn);
8609  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8610}"
8611  [(set_attr "type" "multi")
8612   (set_attr "length" "8")])
8613
8614(define_insn "call_mcount_64bit"
8615  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8616	 (match_operand 1 "" "i"))
8617   (set (reg:SI 25)
8618	(plus:SI (reg:SI 2)
8619		 (minus:SI (match_operand 2 "" "")
8620			   (plus:SI (pc) (const_int 4)))))
8621   (clobber (reg:DI 2))
8622   (clobber (match_operand 3))
8623   (use (reg:DI 27))
8624   (use (reg:DI 29))]
8625  "TARGET_64BIT"
8626  "#")
8627
8628(define_split
8629  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8630		    (match_operand 1 "" ""))
8631	      (set (reg:SI 25)
8632		   (plus:SI (reg:SI 2)
8633			    (minus:SI (match_operand 2 "" "")
8634				      (plus:SI (pc) (const_int 4)))))
8635	      (clobber (reg:DI 2))
8636	      (clobber (match_operand 3))
8637	      (use (reg:DI 27))
8638	      (use (reg:DI 29))])]
8639  "TARGET_64BIT && reload_completed"
8640  [(set (match_dup 3) (reg:DI 27))
8641   (parallel [(call (mem:SI (match_dup 0))
8642		    (match_dup 1))
8643	      (set (reg:SI 25)
8644		   (plus:SI (reg:SI 2)
8645			    (minus:SI (match_dup 2)
8646				      (plus:SI (pc) (const_int 4)))))
8647	      (clobber (reg:DI 2))
8648	      (use (reg:DI 27))
8649	      (use (reg:DI 29))])
8650   (set (reg:DI 27) (match_dup 3))]
8651  "")
8652
8653(define_insn "*call_mcount_64bit_post_reload"
8654  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8655	 (match_operand 1 "" "i"))
8656   (set (reg:SI 25)
8657	(plus:SI (reg:SI 2)
8658		 (minus:SI (match_operand 2 "" "")
8659			   (plus:SI (pc) (const_int 4)))))
8660   (clobber (reg:DI 2))
8661   (use (reg:DI 27))
8662   (use (reg:DI 29))]
8663  "TARGET_64BIT"
8664  "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8665  [(set_attr "type" "multi")
8666   (set_attr "length" "8")])
8667
8668;; Call subroutine returning any type.
8669
8670(define_expand "untyped_call"
8671  [(parallel [(call (match_operand 0 "" "")
8672		    (const_int 0))
8673	      (match_operand 1 "" "")
8674	      (match_operand 2 "" "")])]
8675  ""
8676  "
8677{
8678  int i;
8679
8680  emit_call_insn (gen_call (operands[0], const0_rtx));
8681
8682  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8683    {
8684      rtx set = XVECEXP (operands[2], 0, i);
8685      emit_move_insn (SET_DEST (set), SET_SRC (set));
8686    }
8687
8688  /* The optimizer does not know that the call sets the function value
8689     registers we stored in the result block.  We avoid problems by
8690     claiming that all hard registers are used and clobbered at this
8691     point.  */
8692  emit_insn (gen_blockage ());
8693
8694  DONE;
8695}")
8696
8697(define_expand "sibcall"
8698  [(call (match_operand:SI 0 "" "")
8699	 (match_operand 1 "" ""))]
8700  "!TARGET_PORTABLE_RUNTIME"
8701  "
8702{
8703  rtx op, call_insn;
8704  rtx nb = operands[1];
8705
8706  op = XEXP (operands[0], 0);
8707
8708  if (TARGET_64BIT)
8709    {
8710      if (!virtuals_instantiated)
8711	emit_move_insn (arg_pointer_rtx,
8712			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8713				      GEN_INT (64)));
8714      else
8715	{
8716	  /* The loop pass can generate new libcalls after the virtual
8717	     registers are instantiated when fpregs are disabled because
8718	     the only method that we have for doing DImode multiplication
8719	     is with a libcall.  This could be trouble if we haven't
8720	     allocated enough space for the outgoing arguments.  */
8721	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8722
8723	  emit_move_insn (arg_pointer_rtx,
8724			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8725					GEN_INT (STACK_POINTER_OFFSET + 64)));
8726	}
8727    }
8728
8729  /* Indirect sibling calls are not allowed.  */
8730  if (TARGET_64BIT)
8731    call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8732  else
8733    call_insn = gen_sibcall_internal_symref (op, operands[1]);
8734
8735  call_insn = emit_call_insn (call_insn);
8736
8737  if (TARGET_64BIT)
8738    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8739
8740  /* We don't have to restore the PIC register.  */
8741  if (flag_pic)
8742    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8743
8744  DONE;
8745}")
8746
8747(define_insn "sibcall_internal_symref"
8748  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8749	 (match_operand 1 "" "i"))
8750   (clobber (reg:SI 1))
8751   (use (reg:SI 2))
8752   (use (const_int 0))]
8753  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8754  "*
8755{
8756  pa_output_arg_descriptor (insn);
8757  return pa_output_call (insn, operands[0], 1);
8758}"
8759  [(set_attr "type" "sibcall")
8760   (set (attr "length")
8761	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8762	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8763
8764(define_insn "sibcall_internal_symref_64bit"
8765  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8766	 (match_operand 1 "" "i"))
8767   (clobber (reg:DI 1))
8768   (use (reg:DI 2))
8769   (use (const_int 0))]
8770  "TARGET_64BIT"
8771  "*
8772{
8773  return pa_output_call (insn, operands[0], 1);
8774}"
8775  [(set_attr "type" "sibcall")
8776   (set (attr "length")
8777	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8778	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8779
8780(define_expand "sibcall_value"
8781  [(set (match_operand 0 "" "")
8782		   (call (match_operand:SI 1 "" "")
8783			 (match_operand 2 "" "")))]
8784  "!TARGET_PORTABLE_RUNTIME"
8785  "
8786{
8787  rtx op, call_insn;
8788  rtx nb = operands[1];
8789
8790  op = XEXP (operands[1], 0);
8791
8792  if (TARGET_64BIT)
8793    {
8794      if (!virtuals_instantiated)
8795	emit_move_insn (arg_pointer_rtx,
8796			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8797				      GEN_INT (64)));
8798      else
8799	{
8800	  /* The loop pass can generate new libcalls after the virtual
8801	     registers are instantiated when fpregs are disabled because
8802	     the only method that we have for doing DImode multiplication
8803	     is with a libcall.  This could be trouble if we haven't
8804	     allocated enough space for the outgoing arguments.  */
8805	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8806
8807	  emit_move_insn (arg_pointer_rtx,
8808			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8809					GEN_INT (STACK_POINTER_OFFSET + 64)));
8810	}
8811    }
8812
8813  /* Indirect sibling calls are not allowed.  */
8814  if (TARGET_64BIT)
8815    call_insn
8816      = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8817  else
8818    call_insn
8819      = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8820
8821  call_insn = emit_call_insn (call_insn);
8822
8823  if (TARGET_64BIT)
8824    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8825
8826  /* We don't have to restore the PIC register.  */
8827  if (flag_pic)
8828    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8829
8830  DONE;
8831}")
8832
8833(define_insn "sibcall_value_internal_symref"
8834  [(set (match_operand 0 "" "")
8835	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8836	      (match_operand 2 "" "i")))
8837   (clobber (reg:SI 1))
8838   (use (reg:SI 2))
8839   (use (const_int 0))]
8840  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8841  "*
8842{
8843  pa_output_arg_descriptor (insn);
8844  return pa_output_call (insn, operands[1], 1);
8845}"
8846  [(set_attr "type" "sibcall")
8847   (set (attr "length")
8848	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8849	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8850
8851(define_insn "sibcall_value_internal_symref_64bit"
8852  [(set (match_operand 0 "" "")
8853	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8854	      (match_operand 2 "" "i")))
8855   (clobber (reg:DI 1))
8856   (use (reg:DI 2))
8857   (use (const_int 0))]
8858  "TARGET_64BIT"
8859  "*
8860{
8861  return pa_output_call (insn, operands[1], 1);
8862}"
8863  [(set_attr "type" "sibcall")
8864   (set (attr "length")
8865	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8866	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8867
8868(define_insn "nop"
8869  [(const_int 0)]
8870  ""
8871  "nop"
8872  [(set_attr "type" "move")
8873   (set_attr "length" "4")])
8874
8875;;; EH does longjmp's from and within the data section.  Thus,
8876;;; an interspace branch is required for the longjmp implementation.
8877;;; Registers r1 and r2 are used as scratch registers for the jump
8878;;; when necessary.
8879(define_expand "interspace_jump"
8880  [(parallel
8881     [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8882      (clobber (match_dup 1))])]
8883  ""
8884  "
8885{
8886  operands[1] = gen_rtx_REG (word_mode, 2);
8887}")
8888
8889(define_insn ""
8890  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8891  (clobber (reg:SI 2))]
8892  "TARGET_PA_20 && !TARGET_64BIT"
8893  "bve%* (%0)"
8894   [(set_attr "type" "branch")
8895    (set_attr "length" "4")])
8896
8897(define_insn ""
8898  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8899  (clobber (reg:SI 2))]
8900  "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8901  "be%* 0(%%sr4,%0)"
8902   [(set_attr "type" "branch")
8903    (set_attr "length" "4")])
8904
8905(define_insn ""
8906  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8907  (clobber (reg:SI 2))]
8908  "!TARGET_64BIT"
8909  "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8910   [(set_attr "type" "branch")
8911    (set_attr "length" "12")])
8912
8913(define_insn ""
8914  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8915  (clobber (reg:DI 2))]
8916  "TARGET_64BIT"
8917  "bve%* (%0)"
8918   [(set_attr "type" "branch")
8919    (set_attr "length" "4")])
8920
8921(define_expand "builtin_longjmp"
8922  [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8923  ""
8924  "
8925{
8926  /* The elements of the buffer are, in order:  */
8927  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8928  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8929			 POINTER_SIZE / BITS_PER_UNIT));
8930  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8931			   (POINTER_SIZE * 2) / BITS_PER_UNIT));
8932  rtx pv = gen_rtx_REG (Pmode, 1);
8933
8934  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8935  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8936
8937  /* Load the label we are jumping through into r1 so that we know
8938     where to look for it when we get back to setjmp's function for
8939     restoring the gp.  */
8940  emit_move_insn (pv, lab);
8941
8942  /* Restore the stack and frame pointers.  */
8943  fp = copy_to_reg (fp);
8944  emit_stack_restore (SAVE_NONLOCAL, stack);
8945
8946  /* Ensure the frame pointer move is not optimized.  */
8947  emit_insn (gen_blockage ());
8948  emit_clobber (hard_frame_pointer_rtx);
8949  emit_clobber (frame_pointer_rtx);
8950  emit_move_insn (hard_frame_pointer_rtx, fp);
8951
8952  emit_use (hard_frame_pointer_rtx);
8953  emit_use (stack_pointer_rtx);
8954
8955  /* Prevent the insns above from being scheduled into the delay slot
8956     of the interspace jump because the space register could change.  */
8957  emit_insn (gen_blockage ());
8958
8959  emit_jump_insn (gen_interspace_jump (pv));
8960  emit_barrier ();
8961  DONE;
8962}")
8963
8964;;; Operands 2 and 3 are assumed to be CONST_INTs.
8965(define_expand "extzvsi"
8966  [(set (match_operand:SI 0 "register_operand" "")
8967	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
8968			 (match_operand:SI 2 "uint5_operand" "")
8969			 (match_operand:SI 3 "uint5_operand" "")))]
8970  ""
8971  "
8972{
8973  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8974  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8975
8976  /* PA extraction insns don't support zero length bitfields or fields
8977     extending beyond the left or right-most bits.  Also, the predicate
8978     rejects lengths equal to a word as they are better handled by
8979     the move patterns.  */
8980  if (len == 0 || pos + len > 32)
8981    FAIL;
8982
8983  /* From mips.md: extract_bit_field doesn't verify that our source
8984     matches the predicate, so check it again here.  */
8985  if (!register_operand (operands[1], VOIDmode))
8986    FAIL;
8987
8988  emit_insn (gen_extzv_32 (operands[0], operands[1],
8989			   operands[2], operands[3]));
8990  DONE;
8991}")
8992
8993(define_insn "extzv_32"
8994  [(set (match_operand:SI 0 "register_operand" "=r")
8995	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8996			 (match_operand:SI 2 "uint5_operand" "")
8997			 (match_operand:SI 3 "uint5_operand" "")))]
8998  "UINTVAL (operands[2]) > 0
8999   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9000  "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9001  [(set_attr "type" "shift")
9002   (set_attr "length" "4")])
9003
9004(define_insn ""
9005  [(set (match_operand:SI 0 "register_operand" "=r")
9006	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9007			 (const_int 1)
9008			 (match_operand:SI 2 "register_operand" "q")))]
9009  ""
9010  "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9011  [(set_attr "type" "shift")
9012   (set_attr "length" "4")])
9013
9014(define_expand "extzvdi"
9015  [(set (match_operand:DI 0 "register_operand" "")
9016	(zero_extract:DI (match_operand:DI 1 "register_operand" "")
9017			 (match_operand:DI 2 "uint6_operand" "")
9018			 (match_operand:DI 3 "uint6_operand" "")))]
9019  "TARGET_64BIT"
9020  "
9021{
9022  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9023  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9024
9025  /* PA extraction insns don't support zero length bitfields or fields
9026     extending beyond the left or right-most bits.  Also, the predicate
9027     rejects lengths equal to a doubleword as they are better handled by
9028     the move patterns.  */
9029  if (len == 0 || pos + len > 64)
9030    FAIL;
9031
9032  /* From mips.md: extract_bit_field doesn't verify that our source
9033     matches the predicate, so check it again here.  */
9034  if (!register_operand (operands[1], VOIDmode))
9035    FAIL;
9036
9037  emit_insn (gen_extzv_64 (operands[0], operands[1],
9038			   operands[2], operands[3]));
9039  DONE;
9040}")
9041
9042(define_insn "extzv_64"
9043  [(set (match_operand:DI 0 "register_operand" "=r")
9044	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9045			 (match_operand:DI 2 "uint6_operand" "")
9046			 (match_operand:DI 3 "uint6_operand" "")))]
9047  "TARGET_64BIT
9048   && UINTVAL (operands[2]) > 0
9049   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9050  "extrd,u %1,%3+%2-1,%2,%0"
9051  [(set_attr "type" "shift")
9052   (set_attr "length" "4")])
9053
9054(define_insn ""
9055  [(set (match_operand:DI 0 "register_operand" "=r")
9056	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9057			 (const_int 1)
9058			 (match_operand:DI 2 "register_operand" "q")))]
9059  "TARGET_64BIT"
9060  "extrd,u %1,%%sar,1,%0"
9061  [(set_attr "type" "shift")
9062   (set_attr "length" "4")])
9063
9064;;; Operands 2 and 3 are assumed to be CONST_INTs.
9065(define_expand "extvsi"
9066  [(set (match_operand:SI 0 "register_operand" "")
9067	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
9068			 (match_operand:SI 2 "uint5_operand" "")
9069			 (match_operand:SI 3 "uint5_operand" "")))]
9070  ""
9071  "
9072{
9073  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9074  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9075
9076  /* PA extraction insns don't support zero length bitfields or fields
9077     extending beyond the left or right-most bits.  Also, the predicate
9078     rejects lengths equal to a word as they are better handled by
9079     the move patterns.  */
9080  if (len == 0 || pos + len > 32)
9081    FAIL;
9082
9083  /* From mips.md: extract_bit_field doesn't verify that our source
9084     matches the predicate, so check it again here.  */
9085  if (!register_operand (operands[1], VOIDmode))
9086    FAIL;
9087
9088  emit_insn (gen_extv_32 (operands[0], operands[1],
9089			  operands[2], operands[3]));
9090  DONE;
9091}")
9092
9093(define_insn "extv_32"
9094  [(set (match_operand:SI 0 "register_operand" "=r")
9095	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9096			 (match_operand:SI 2 "uint5_operand" "")
9097			 (match_operand:SI 3 "uint5_operand" "")))]
9098  "UINTVAL (operands[2]) > 0
9099   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9100  "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9101  [(set_attr "type" "shift")
9102   (set_attr "length" "4")])
9103
9104(define_insn ""
9105  [(set (match_operand:SI 0 "register_operand" "=r")
9106	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9107			 (const_int 1)
9108			 (match_operand:SI 2 "register_operand" "q")))]
9109  "!TARGET_64BIT"
9110  "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9111  [(set_attr "type" "shift")
9112   (set_attr "length" "4")])
9113
9114(define_expand "extvdi"
9115  [(set (match_operand:DI 0 "register_operand" "")
9116	(sign_extract:DI (match_operand:DI 1 "register_operand" "")
9117			 (match_operand:DI 2 "uint6_operand" "")
9118			 (match_operand:DI 3 "uint6_operand" "")))]
9119  "TARGET_64BIT"
9120  "
9121{
9122  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9123  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9124
9125  /* PA extraction insns don't support zero length bitfields or fields
9126     extending beyond the left or right-most bits.  Also, the predicate
9127     rejects lengths equal to a doubleword as they are better handled by
9128     the move patterns.  */
9129  if (len == 0 || pos + len > 64)
9130    FAIL;
9131
9132  /* From mips.md: extract_bit_field doesn't verify that our source
9133     matches the predicate, so check it again here.  */
9134  if (!register_operand (operands[1], VOIDmode))
9135    FAIL;
9136
9137  emit_insn (gen_extv_64 (operands[0], operands[1],
9138			  operands[2], operands[3]));
9139  DONE;
9140}")
9141
9142(define_insn "extv_64"
9143  [(set (match_operand:DI 0 "register_operand" "=r")
9144	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9145			 (match_operand:DI 2 "uint6_operand" "")
9146			 (match_operand:DI 3 "uint6_operand" "")))]
9147  "TARGET_64BIT
9148   && UINTVAL (operands[2]) > 0
9149   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9150  "extrd,s %1,%3+%2-1,%2,%0"
9151  [(set_attr "type" "shift")
9152   (set_attr "length" "4")])
9153
9154(define_insn ""
9155  [(set (match_operand:DI 0 "register_operand" "=r")
9156	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9157			 (const_int 1)
9158			 (match_operand:DI 2 "register_operand" "q")))]
9159  "TARGET_64BIT"
9160  "extrd,s %1,%%sar,1,%0"
9161  [(set_attr "type" "shift")
9162   (set_attr "length" "4")])
9163
9164;;; Operands 1 and 2 are assumed to be CONST_INTs.
9165(define_expand "insvsi"
9166  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9167			 (match_operand:SI 1 "uint5_operand" "")
9168			 (match_operand:SI 2 "uint5_operand" ""))
9169	(match_operand:SI 3 "arith5_operand" ""))]
9170  ""
9171  "
9172{
9173  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9174  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9175
9176  /* PA insertion insns don't support zero length bitfields or fields
9177     extending beyond the left or right-most bits.  Also, the predicate
9178     rejects lengths equal to a word as they are better handled by
9179     the move patterns.  */
9180  if (len <= 0 || pos + len > 32)
9181    FAIL;
9182
9183  /* From mips.md: insert_bit_field doesn't verify that our destination
9184     matches the predicate, so check it again here.  */
9185  if (!register_operand (operands[0], VOIDmode))
9186    FAIL;
9187
9188  emit_insn (gen_insv_32 (operands[0], operands[1],
9189			  operands[2], operands[3]));
9190  DONE;
9191}")
9192
9193(define_insn "insv_32"
9194  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9195			 (match_operand:SI 1 "uint5_operand" "")
9196			 (match_operand:SI 2 "uint5_operand" ""))
9197	(match_operand:SI 3 "arith5_operand" "r,L"))]
9198  "UINTVAL (operands[1]) > 0
9199   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9200  "@
9201   {dep|depw} %3,%2+%1-1,%1,%0
9202   {depi|depwi} %3,%2+%1-1,%1,%0"
9203  [(set_attr "type" "shift,shift")
9204   (set_attr "length" "4,4")])
9205
9206;; Optimize insertion of const_int values of type 1...1xxxx.
9207(define_insn ""
9208  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9209			 (match_operand:SI 1 "uint5_operand" "")
9210			 (match_operand:SI 2 "uint5_operand" ""))
9211	(match_operand:SI 3 "const_int_operand" ""))]
9212  "(INTVAL (operands[3]) & 0x10) != 0 &&
9213   (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9214  "*
9215{
9216  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9217  return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9218}"
9219  [(set_attr "type" "shift")
9220   (set_attr "length" "4")])
9221
9222(define_expand "insvdi"
9223  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9224			 (match_operand:DI 1 "uint6_operand" "")
9225			 (match_operand:DI 2 "uint6_operand" ""))
9226	(match_operand:DI 3 "arith5_operand" ""))]
9227  "TARGET_64BIT"
9228  "
9229{
9230  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9231  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9232
9233  /* PA insertion insns don't support zero length bitfields or fields
9234     extending beyond the left or right-most bits.  Also, the predicate
9235     rejects lengths equal to a doubleword as they are better handled by
9236     the move patterns.  */
9237  if (len <= 0 || pos + len > 64)
9238    FAIL;
9239
9240  /* From mips.md: insert_bit_field doesn't verify that our destination
9241     matches the predicate, so check it again here.  */
9242  if (!register_operand (operands[0], VOIDmode))
9243    FAIL;
9244
9245  emit_insn (gen_insv_64 (operands[0], operands[1],
9246			  operands[2], operands[3]));
9247  DONE;
9248}")
9249
9250(define_insn "insv_64"
9251  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9252			 (match_operand:DI 1 "uint6_operand" "")
9253			 (match_operand:DI 2 "uint6_operand" ""))
9254	(match_operand:DI 3 "arith5_operand" "r,L"))]
9255  "TARGET_64BIT
9256   && UINTVAL (operands[1]) > 0
9257   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9258  "@
9259   depd %3,%2+%1-1,%1,%0
9260   depdi %3,%2+%1-1,%1,%0"
9261  [(set_attr "type" "shift,shift")
9262   (set_attr "length" "4,4")])
9263
9264;; Optimize insertion of const_int values of type 1...1xxxx.
9265(define_insn ""
9266  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9267			 (match_operand:DI 1 "uint6_operand" "")
9268			 (match_operand:DI 2 "uint6_operand" ""))
9269	(match_operand:DI 3 "const_int_operand" ""))]
9270  "(INTVAL (operands[3]) & 0x10) != 0
9271   && TARGET_64BIT
9272   && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9273  "*
9274{
9275  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9276  return \"depdi %3,%2+%1-1,%1,%0\";
9277}"
9278  [(set_attr "type" "shift")
9279   (set_attr "length" "4")])
9280
9281(define_insn ""
9282  [(set (match_operand:DI 0 "register_operand" "=r")
9283	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9284		   (const_int 32)))]
9285  "TARGET_64BIT"
9286  "depd,z %1,31,32,%0"
9287  [(set_attr "type" "shift")
9288   (set_attr "length" "4")])
9289
9290;; This insn is used for some loop tests, typically loops reversed when
9291;; strength reduction is used.  It is actually created when the instruction
9292;; combination phase combines the special loop test.  Since this insn
9293;; is both a jump insn and has an output, it must deal with its own
9294;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9295;; to not choose the register alternatives in the event a reload is needed.
9296(define_insn "decrement_and_branch_until_zero"
9297  [(set (pc)
9298	(if_then_else
9299	  (match_operator 2 "ordered_comparison_operator"
9300	   [(plus:SI
9301	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9302	      (match_operand:SI 1 "int5_operand" "L,L,L"))
9303	    (const_int 0)])
9304	  (label_ref (match_operand 3 "" ""))
9305	  (pc)))
9306   (set (match_dup 0)
9307	(plus:SI (match_dup 0) (match_dup 1)))
9308   (clobber (match_scratch:SI 4 "=X,r,r"))]
9309  ""
9310  "* return pa_output_dbra (operands, insn, which_alternative); "
9311;; Do not expect to understand this the first time through.
9312[(set_attr "type" "cbranch,multi,multi")
9313 (set (attr "length")
9314      (if_then_else (eq_attr "alternative" "0")
9315;; Loop counter in register case
9316;; Short branch has length of 4
9317;; Long branch has length of 8, 20, 24 or 28
9318	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9319	       (const_int MAX_12BIT_OFFSET))
9320	   (const_int 4)
9321	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9322	       (const_int MAX_17BIT_OFFSET))
9323	   (const_int 8)
9324	   (match_test "TARGET_PORTABLE_RUNTIME")
9325	   (const_int 24)
9326	   (not (match_test "flag_pic"))
9327	   (const_int 20)]
9328	  (const_int 28))
9329
9330;; Loop counter in FP reg case.
9331;; Extra goo to deal with additional reload insns.
9332	(if_then_else (eq_attr "alternative" "1")
9333	  (if_then_else (lt (match_dup 3) (pc))
9334	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9335		      (const_int MAX_12BIT_OFFSET))
9336		    (const_int 24)
9337		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9338		      (const_int MAX_17BIT_OFFSET))
9339		    (const_int 28)
9340		    (match_test "TARGET_PORTABLE_RUNTIME")
9341		    (const_int 44)
9342		    (not (match_test "flag_pic"))
9343		    (const_int 40)]
9344		  (const_int 48))
9345	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9346		      (const_int MAX_12BIT_OFFSET))
9347		    (const_int 24)
9348		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9349		      (const_int MAX_17BIT_OFFSET))
9350		    (const_int 28)
9351		    (match_test "TARGET_PORTABLE_RUNTIME")
9352		    (const_int 44)
9353		    (not (match_test "flag_pic"))
9354		    (const_int 40)]
9355		  (const_int 48)))
9356
9357;; Loop counter in memory case.
9358;; Extra goo to deal with additional reload insns.
9359	(if_then_else (lt (match_dup 3) (pc))
9360	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9361		      (const_int MAX_12BIT_OFFSET))
9362		    (const_int 12)
9363		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9364		      (const_int MAX_17BIT_OFFSET))
9365		    (const_int 16)
9366		    (match_test "TARGET_PORTABLE_RUNTIME")
9367		    (const_int 32)
9368		    (not (match_test "flag_pic"))
9369		    (const_int 28)]
9370		  (const_int 36))
9371	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9372		      (const_int MAX_12BIT_OFFSET))
9373		    (const_int 12)
9374		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9375		      (const_int MAX_17BIT_OFFSET))
9376		    (const_int 16)
9377		    (match_test "TARGET_PORTABLE_RUNTIME")
9378		    (const_int 32)
9379		    (not (match_test "flag_pic"))
9380		    (const_int 28)]
9381		  (const_int 36))))))])
9382
9383(define_insn ""
9384  [(set (pc)
9385	(if_then_else
9386	  (match_operator 2 "movb_comparison_operator"
9387	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9388	  (label_ref (match_operand 3 "" ""))
9389	  (pc)))
9390   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9391	(match_dup 1))]
9392  ""
9393"* return pa_output_movb (operands, insn, which_alternative, 0); "
9394;; Do not expect to understand this the first time through.
9395[(set_attr "type" "cbranch,multi,multi,multi")
9396 (set (attr "length")
9397      (if_then_else (eq_attr "alternative" "0")
9398;; Loop counter in register case
9399;; Short branch has length of 4
9400;; Long branch has length of 8, 20, 24 or 28
9401        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9402	       (const_int MAX_12BIT_OFFSET))
9403	   (const_int 4)
9404	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9405	       (const_int MAX_17BIT_OFFSET))
9406	   (const_int 8)
9407	   (match_test "TARGET_PORTABLE_RUNTIME")
9408	   (const_int 24)
9409	   (not (match_test "flag_pic"))
9410	   (const_int 20)]
9411	  (const_int 28))
9412
9413;; Loop counter in FP reg case.
9414;; Extra goo to deal with additional reload insns.
9415	(if_then_else (eq_attr "alternative" "1")
9416	  (if_then_else (lt (match_dup 3) (pc))
9417	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9418		      (const_int MAX_12BIT_OFFSET))
9419		    (const_int 12)
9420		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9421		      (const_int MAX_17BIT_OFFSET))
9422		    (const_int 16)
9423		    (match_test "TARGET_PORTABLE_RUNTIME")
9424		    (const_int 32)
9425		    (not (match_test "flag_pic"))
9426		    (const_int 28)]
9427		  (const_int 36))
9428	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9429		      (const_int MAX_12BIT_OFFSET))
9430		    (const_int 12)
9431		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9432		      (const_int MAX_17BIT_OFFSET))
9433		    (const_int 16)
9434		    (match_test "TARGET_PORTABLE_RUNTIME")
9435		    (const_int 32)
9436		    (not (match_test "flag_pic"))
9437		    (const_int 28)]
9438		  (const_int 36)))
9439
9440;; Loop counter in memory or sar case.
9441;; Extra goo to deal with additional reload insns.
9442	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9443		   (const_int MAX_12BIT_OFFSET))
9444		(const_int 8)
9445		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9446		  (const_int MAX_17BIT_OFFSET))
9447		(const_int 12)
9448		(match_test "TARGET_PORTABLE_RUNTIME")
9449		(const_int 28)
9450		(not (match_test "flag_pic"))
9451		(const_int 24)]
9452	      (const_int 32)))))])
9453
9454;; Handle negated branch.
9455(define_insn ""
9456  [(set (pc)
9457	(if_then_else
9458	  (match_operator 2 "movb_comparison_operator"
9459	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9460	  (pc)
9461	  (label_ref (match_operand 3 "" ""))))
9462   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9463	(match_dup 1))]
9464  ""
9465"* return pa_output_movb (operands, insn, which_alternative, 1); "
9466;; Do not expect to understand this the first time through.
9467[(set_attr "type" "cbranch,multi,multi,multi")
9468 (set (attr "length")
9469      (if_then_else (eq_attr "alternative" "0")
9470;; Loop counter in register case
9471;; Short branch has length of 4
9472;; Long branch has length of 8
9473        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9474	       (const_int MAX_12BIT_OFFSET))
9475	   (const_int 4)
9476	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9477	       (const_int MAX_17BIT_OFFSET))
9478	   (const_int 8)
9479	   (match_test "TARGET_PORTABLE_RUNTIME")
9480	   (const_int 24)
9481	   (not (match_test "flag_pic"))
9482	   (const_int 20)]
9483	  (const_int 28))
9484
9485;; Loop counter in FP reg case.
9486;; Extra goo to deal with additional reload insns.
9487	(if_then_else (eq_attr "alternative" "1")
9488	  (if_then_else (lt (match_dup 3) (pc))
9489	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9490		      (const_int MAX_12BIT_OFFSET))
9491		    (const_int 12)
9492		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9493		      (const_int MAX_17BIT_OFFSET))
9494		    (const_int 16)
9495		    (match_test "TARGET_PORTABLE_RUNTIME")
9496		    (const_int 32)
9497		    (not (match_test "flag_pic"))
9498		    (const_int 28)]
9499		  (const_int 36))
9500	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9501		      (const_int MAX_12BIT_OFFSET))
9502		    (const_int 12)
9503		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9504		      (const_int MAX_17BIT_OFFSET))
9505		    (const_int 16)
9506		    (match_test "TARGET_PORTABLE_RUNTIME")
9507		    (const_int 32)
9508		    (not (match_test "flag_pic"))
9509		    (const_int 28)]
9510		  (const_int 36)))
9511
9512;; Loop counter in memory or SAR case.
9513;; Extra goo to deal with additional reload insns.
9514	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9515		   (const_int MAX_12BIT_OFFSET))
9516		(const_int 8)
9517		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9518		  (const_int MAX_17BIT_OFFSET))
9519		(const_int 12)
9520		(match_test "TARGET_PORTABLE_RUNTIME")
9521		(const_int 28)
9522		(not (match_test "flag_pic"))
9523		(const_int 24)]
9524	      (const_int 32)))))])
9525
9526(define_insn ""
9527  [(set (pc) (label_ref (match_operand 3 "" "" )))
9528   (set (match_operand:SI 0 "ireg_operand" "=r")
9529	(plus:SI (match_operand:SI 1 "ireg_operand" "r")
9530		 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9531  "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9532  "*
9533{
9534  return pa_output_parallel_addb (operands, insn);
9535}"
9536[(set_attr "type" "parallel_branch")
9537 (set (attr "length")
9538    (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9539	       (const_int MAX_12BIT_OFFSET))
9540	   (const_int 4)
9541	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9542	       (const_int MAX_17BIT_OFFSET))
9543	   (const_int 8)
9544	   (match_test "TARGET_PORTABLE_RUNTIME")
9545	   (const_int 24)
9546	   (not (match_test "flag_pic"))
9547	   (const_int 20)]
9548	  (const_int 28)))])
9549
9550(define_insn ""
9551  [(set (pc) (label_ref (match_operand 2 "" "" )))
9552   (set (match_operand:SF 0 "ireg_operand" "=r")
9553	(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9554  "reload_completed"
9555  "*
9556{
9557  return pa_output_parallel_movb (operands, insn);
9558}"
9559[(set_attr "type" "parallel_branch")
9560 (set (attr "length")
9561    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9562	       (const_int MAX_12BIT_OFFSET))
9563	   (const_int 4)
9564	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9565	       (const_int MAX_17BIT_OFFSET))
9566	   (const_int 8)
9567	   (match_test "TARGET_PORTABLE_RUNTIME")
9568	   (const_int 24)
9569	   (not (match_test "flag_pic"))
9570	   (const_int 20)]
9571	  (const_int 28)))])
9572
9573(define_insn ""
9574  [(set (pc) (label_ref (match_operand 2 "" "" )))
9575   (set (match_operand:SI 0 "ireg_operand" "=r")
9576	(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9577  "reload_completed"
9578  "*
9579{
9580  return pa_output_parallel_movb (operands, insn);
9581}"
9582[(set_attr "type" "parallel_branch")
9583 (set (attr "length")
9584    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9585	       (const_int MAX_12BIT_OFFSET))
9586	   (const_int 4)
9587	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9588	       (const_int MAX_17BIT_OFFSET))
9589	   (const_int 8)
9590	   (match_test "TARGET_PORTABLE_RUNTIME")
9591	   (const_int 24)
9592	   (not (match_test "flag_pic"))
9593	   (const_int 20)]
9594	  (const_int 28)))])
9595
9596(define_insn ""
9597  [(set (pc) (label_ref (match_operand 2 "" "" )))
9598   (set (match_operand:HI 0 "ireg_operand" "=r")
9599	(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9600  "reload_completed"
9601  "*
9602{
9603  return pa_output_parallel_movb (operands, insn);
9604}"
9605[(set_attr "type" "parallel_branch")
9606 (set (attr "length")
9607    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9608	       (const_int MAX_12BIT_OFFSET))
9609	   (const_int 4)
9610	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9611	       (const_int MAX_17BIT_OFFSET))
9612	   (const_int 8)
9613	   (match_test "TARGET_PORTABLE_RUNTIME")
9614	   (const_int 24)
9615	   (not (match_test "flag_pic"))
9616	   (const_int 20)]
9617	  (const_int 28)))])
9618
9619(define_insn ""
9620  [(set (pc) (label_ref (match_operand 2 "" "" )))
9621   (set (match_operand:QI 0 "ireg_operand" "=r")
9622	(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9623  "reload_completed"
9624  "*
9625{
9626  return pa_output_parallel_movb (operands, insn);
9627}"
9628[(set_attr "type" "parallel_branch")
9629 (set (attr "length")
9630    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9631	       (const_int MAX_12BIT_OFFSET))
9632	   (const_int 4)
9633	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9634	       (const_int MAX_17BIT_OFFSET))
9635	   (const_int 8)
9636	   (match_test "TARGET_PORTABLE_RUNTIME")
9637	   (const_int 24)
9638	   (not (match_test "flag_pic"))
9639	   (const_int 20)]
9640	  (const_int 28)))])
9641
9642(define_insn ""
9643  [(set (match_operand 0 "register_operand" "=f")
9644	(mult (match_operand 1 "register_operand" "f")
9645	      (match_operand 2 "register_operand" "f")))
9646   (set (match_operand 3 "register_operand" "+f")
9647	(plus (match_operand 4 "register_operand" "f")
9648	      (match_operand 5 "register_operand" "f")))]
9649  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9650   && reload_completed && pa_fmpyaddoperands (operands)"
9651  "*
9652{
9653  if (GET_MODE (operands[0]) == DFmode)
9654    {
9655      if (rtx_equal_p (operands[3], operands[5]))
9656	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9657      else
9658	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9659    }
9660  else
9661    {
9662      if (rtx_equal_p (operands[3], operands[5]))
9663	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9664      else
9665	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9666    }
9667}"
9668  [(set_attr "type" "fpalu")
9669   (set_attr "length" "4")])
9670
9671(define_insn ""
9672  [(set (match_operand 3 "register_operand" "+f")
9673	(plus (match_operand 4 "register_operand" "f")
9674	      (match_operand 5 "register_operand" "f")))
9675   (set (match_operand 0 "register_operand" "=f")
9676	(mult (match_operand 1 "register_operand" "f")
9677	      (match_operand 2 "register_operand" "f")))]
9678  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9679   && reload_completed && pa_fmpyaddoperands (operands)"
9680  "*
9681{
9682  if (GET_MODE (operands[0]) == DFmode)
9683    {
9684      if (rtx_equal_p (operands[3], operands[5]))
9685	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9686      else
9687	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9688    }
9689  else
9690    {
9691      if (rtx_equal_p (operands[3], operands[5]))
9692	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9693      else
9694	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9695    }
9696}"
9697  [(set_attr "type" "fpalu")
9698   (set_attr "length" "4")])
9699
9700(define_insn ""
9701  [(set (match_operand 0 "register_operand" "=f")
9702	(mult (match_operand 1 "register_operand" "f")
9703	      (match_operand 2 "register_operand" "f")))
9704   (set (match_operand 3 "register_operand" "+f")
9705	(minus (match_operand 4 "register_operand" "f")
9706	       (match_operand 5 "register_operand" "f")))]
9707  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9708   && reload_completed && pa_fmpysuboperands (operands)"
9709  "*
9710{
9711  if (GET_MODE (operands[0]) == DFmode)
9712    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9713  else
9714    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9715}"
9716  [(set_attr "type" "fpalu")
9717   (set_attr "length" "4")])
9718
9719(define_insn ""
9720  [(set (match_operand 3 "register_operand" "+f")
9721	(minus (match_operand 4 "register_operand" "f")
9722	       (match_operand 5 "register_operand" "f")))
9723   (set (match_operand 0 "register_operand" "=f")
9724	(mult (match_operand 1 "register_operand" "f")
9725	      (match_operand 2 "register_operand" "f")))]
9726  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9727   && reload_completed && pa_fmpysuboperands (operands)"
9728  "*
9729{
9730  if (GET_MODE (operands[0]) == DFmode)
9731    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9732  else
9733    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9734}"
9735  [(set_attr "type" "fpalu")
9736   (set_attr "length" "4")])
9737
9738;; The following two patterns are used by the trampoline code for nested
9739;; functions.  They flush the I and D cache lines from the start address
9740;; (operand0) to the end address (operand1).  No lines are flushed if the
9741;; end address is less than the start address (unsigned).
9742;;
9743;; Because the range of memory flushed is variable and the size of a MEM
9744;; can only be a CONST_INT, the patterns specify that they perform an
9745;; unspecified volatile operation on all memory.
9746;;
9747;; The address range for an icache flush must lie within a single
9748;; space on targets with non-equivalent space registers.
9749;;
9750;; Operand 0 contains the start address.
9751;; Operand 1 contains the end address.
9752;; Operand 2 contains the line length to use.
9753(define_insn "dcacheflush<P:mode>"
9754  [(const_int 1)
9755   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9756   (use (match_operand 0 "pmode_register_operand" "r"))
9757   (use (match_operand 1 "pmode_register_operand" "r"))
9758   (use (match_operand 2 "pmode_register_operand" "r"))
9759   (clobber (match_scratch:P 3 "=&0"))]
9760  ""
9761  "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9762  [(set_attr "type" "multi")
9763   (set_attr "length" "12")])
9764
9765(define_insn "icacheflush<P:mode>"
9766  [(const_int 2)
9767   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9768   (use (match_operand 0 "pmode_register_operand" "r"))
9769   (use (match_operand 1 "pmode_register_operand" "r"))
9770   (use (match_operand 2 "pmode_register_operand" "r"))
9771   (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9772   (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9773   (clobber (match_scratch:P 5 "=&0"))]
9774  ""
9775  "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"
9776  [(set_attr "type" "multi")
9777   (set_attr "length" "52")])
9778
9779;; An out-of-line prologue.
9780(define_insn "outline_prologue_call"
9781  [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9782   (clobber (reg:SI 31))
9783   (clobber (reg:SI 22))
9784   (clobber (reg:SI 21))
9785   (clobber (reg:SI 20))
9786   (clobber (reg:SI 19))
9787   (clobber (reg:SI 1))]
9788  ""
9789  "*
9790{
9791 
9792  /* We need two different versions depending on whether or not we
9793     need a frame pointer.   Also note that we return to the instruction
9794     immediately after the branch rather than two instructions after the
9795     break as normally is the case.  */
9796  if (frame_pointer_needed)
9797    {
9798      /* Must import the magic millicode routine(s).  */
9799      output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9800
9801      if (TARGET_PORTABLE_RUNTIME)
9802	{
9803	  output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9804	  output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9805			   NULL);
9806	}
9807      else
9808	output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9809    }
9810  else
9811    {
9812      /* Must import the magic millicode routine(s).  */
9813      output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9814
9815      if (TARGET_PORTABLE_RUNTIME)
9816	{
9817	  output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9818	  output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9819	}
9820      else
9821	output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9822    }
9823  return \"\";
9824}"
9825  [(set_attr "type" "multi")
9826   (set_attr "length" "8")])
9827
9828;; An out-of-line epilogue.
9829(define_insn "outline_epilogue_call"
9830  [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9831   (use (reg:SI 29))
9832   (use (reg:SI 28))
9833   (clobber (reg:SI 31))
9834   (clobber (reg:SI 22))
9835   (clobber (reg:SI 21))
9836   (clobber (reg:SI 20))
9837   (clobber (reg:SI 19))
9838   (clobber (reg:SI 2))
9839   (clobber (reg:SI 1))]
9840  ""
9841  "*
9842{
9843
9844  /* We need two different versions depending on whether or not we
9845     need a frame pointer.   Also note that we return to the instruction
9846     immediately after the branch rather than two instructions after the
9847     break as normally is the case.  */
9848  if (frame_pointer_needed)
9849    {
9850      /* Must import the magic millicode routine.  */
9851      output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9852
9853      /* The out-of-line prologue will make sure we return to the right
9854	 instruction.  */
9855      if (TARGET_PORTABLE_RUNTIME)
9856	{
9857	  output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9858	  output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9859			   NULL);
9860	}
9861      else
9862	output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9863    }
9864  else
9865    {
9866      /* Must import the magic millicode routine.  */
9867      output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9868
9869      /* The out-of-line prologue will make sure we return to the right
9870	 instruction.  */
9871      if (TARGET_PORTABLE_RUNTIME)
9872	{
9873	  output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9874	  output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9875	}
9876      else
9877	output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9878    }
9879  return \"\";
9880}"
9881  [(set_attr "type" "multi")
9882   (set_attr "length" "8")])
9883
9884;; Given a function pointer, canonicalize it so it can be 
9885;; reliably compared to another function pointer.  */
9886(define_expand "canonicalize_funcptr_for_compare"
9887  [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9888   (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9889	      (clobber (match_dup 2))
9890	      (clobber (reg:SI 26))
9891	      (clobber (reg:SI 22))
9892	      (clobber (reg:SI 31))])
9893   (set (match_operand:SI 0 "register_operand" "")
9894	(reg:SI 29))]
9895  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9896  "
9897{
9898  if (TARGET_ELF32)
9899    {
9900      rtx canonicalize_funcptr_for_compare_libfunc
9901        = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9902
9903      emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9904      			       operands[0], LCT_NORMAL, Pmode,
9905			       operands[1], Pmode);
9906      DONE;
9907    }
9908
9909  operands[2] = gen_reg_rtx (SImode);
9910  if (GET_CODE (operands[1]) != REG)
9911    {
9912      rtx tmp = gen_reg_rtx (Pmode);
9913      emit_move_insn (tmp, operands[1]);
9914      operands[1] = tmp;
9915    }
9916}")
9917
9918(define_insn "*$$sh_func_adrs"
9919  [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9920   (clobber (match_operand:SI 0 "register_operand" "=a"))
9921   (clobber (reg:SI 26))
9922   (clobber (reg:SI 22))
9923   (clobber (reg:SI 31))]
9924  "!TARGET_64BIT"
9925  "*
9926{
9927  int length = get_attr_length (insn);
9928  rtx xoperands[2];
9929
9930  xoperands[0] = GEN_INT (length - 8);
9931  xoperands[1] = GEN_INT (length - 16);
9932
9933  /* Must import the magic millicode routine.  */
9934  output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9935
9936  /* This is absolutely amazing.
9937
9938     First, copy our input parameter into %r29 just in case we don't
9939     need to call $$sh_func_adrs.  */
9940  output_asm_insn (\"copy %%r26,%%r29\", NULL);
9941  output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9942
9943  /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9944     we use %r26 unchanged.  */
9945  output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9946  output_asm_insn (\"ldi 4096,%%r31\", NULL);
9947
9948  /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9949     4096, then again we use %r26 unchanged.  */
9950  output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9951
9952  /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
9953  return pa_output_millicode_call (insn,
9954				   gen_rtx_SYMBOL_REF (SImode,
9955						       \"$$sh_func_adrs\"));
9956}"
9957  [(set_attr "type" "sh_func_adrs")
9958   (set (attr "length")
9959	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
9960	      (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9961		    (const_int 20))))])
9962
9963;; On the PA, the PIC register is call clobbered, so it must
9964;; be saved & restored around calls by the caller.  If the call
9965;; doesn't return normally (nonlocal goto, or an exception is
9966;; thrown), then the code at the exception handler label must
9967;; restore the PIC register.
9968(define_expand "exception_receiver"
9969  [(const_int 4)]
9970  "flag_pic"
9971  "
9972{
9973  /* On the 64-bit port, we need a blockage because there is
9974     confusion regarding the dependence of the restore on the
9975     frame pointer.  As a result, the frame pointer and pic
9976     register restores sometimes are interchanged erroneously.  */
9977  if (TARGET_64BIT)
9978    emit_insn (gen_blockage ());
9979  /* Restore the PIC register using hppa_pic_save_rtx ().  The
9980     PIC register is not saved in the frame in 64-bit ABI.  */
9981  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9982  emit_insn (gen_blockage ());
9983  DONE;
9984}")
9985
9986(define_expand "builtin_setjmp_receiver"
9987  [(label_ref (match_operand 0 "" ""))]
9988  "flag_pic"
9989  "
9990{
9991  if (TARGET_64BIT)
9992    emit_insn (gen_blockage ());
9993  /* Restore the PIC register.  Hopefully, this will always be from
9994     a stack slot.  The only registers that are valid after a
9995     builtin_longjmp are the stack and frame pointers.  */
9996  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9997  emit_insn (gen_blockage ());
9998  DONE;
9999}")
10000
10001;; Allocate new stack space and update the saved stack pointer in the
10002;; frame marker.  The HP C compilers also copy additional words in the
10003;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10004;; The 32-bit compiler copies the word at -16 (Static Link).  We
10005;; currently don't copy these values.
10006;;
10007;; Since the copy of the frame marker can't be done atomically, I
10008;; suspect that using it for unwind purposes may be somewhat unreliable.
10009;; The HP compilers appear to raise the stack and copy the frame
10010;; marker in a strict instruction sequence.  This suggests that the
10011;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10012;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10013;; as GAS doesn't support it, or try to keep the instructions emitted
10014;; here in strict sequence.
10015(define_expand "allocate_stack"
10016  [(match_operand 0 "" "")
10017   (match_operand 1 "" "")]
10018  ""
10019  "
10020{
10021  rtx addr;
10022
10023  /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10024     in operand 0 before adjusting the stack.  */
10025  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10026  anti_adjust_stack (operands[1]);
10027  if (TARGET_HPUX_UNWIND_LIBRARY)
10028    {
10029      addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10030			   GEN_INT (TARGET_64BIT ? -8 : -4));
10031      emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10032    }
10033  if (!TARGET_64BIT && flag_pic)
10034    {
10035      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10036      emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10037    }
10038  DONE;
10039}")
10040
10041(define_expand "prefetch"
10042  [(match_operand 0 "address_operand" "")
10043   (match_operand 1 "const_int_operand" "")
10044   (match_operand 2 "const_int_operand" "")]
10045  "TARGET_PA_20"
10046{
10047  operands[0] = copy_addr_to_reg (operands[0]);
10048  emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10049  DONE;
10050})
10051
10052(define_insn "prefetch_20"
10053  [(prefetch (match_operand 0 "pmode_register_operand" "r")
10054	     (match_operand:SI 1 "const_int_operand" "n")
10055	     (match_operand:SI 2 "const_int_operand" "n"))]
10056  "TARGET_PA_20"
10057{
10058  /* The SL cache-control completer indicates good spatial locality but
10059     poor temporal locality.  The ldw instruction with a target of general
10060     register 0 prefetches a cache line for a read.  The ldd instruction
10061     prefetches a cache line for a write.  */
10062  static const char * const instr[2][2] = {
10063    {
10064      "ldw,sl 0(%0),%%r0",
10065      "ldd,sl 0(%0),%%r0"
10066    },
10067    {
10068      "ldw 0(%0),%%r0",
10069      "ldd 0(%0),%%r0"
10070    }
10071  };
10072  int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10073  int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10074
10075  return instr [locality][read_or_write];
10076}
10077  [(set_attr "type" "load")
10078   (set_attr "length" "4")])
10079
10080;; TLS Support
10081(define_insn "tgd_load"
10082 [(set (match_operand:SI 0 "register_operand" "=r")
10083       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10084  (clobber (reg:SI 1))
10085  (use (reg:SI 27))]
10086  ""
10087  "*
10088{
10089  return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10090}"
10091  [(set_attr "type" "multi")
10092   (set_attr "length" "8")])
10093
10094(define_insn "tgd_load_pic"
10095 [(set (match_operand:SI 0 "register_operand" "=r")
10096       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10097  (clobber (reg:SI 1))
10098  (use (reg:SI 19))]
10099  ""
10100  "*
10101{
10102  return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10103}"
10104  [(set_attr "type" "multi")
10105   (set_attr "length" "8")])
10106
10107(define_insn "tld_load"
10108 [(set (match_operand:SI 0 "register_operand" "=r")
10109       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10110  (clobber (reg:SI 1))
10111  (use (reg:SI 27))]
10112  ""
10113  "*
10114{
10115  return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10116}"
10117  [(set_attr "type" "multi")
10118   (set_attr "length" "8")])
10119
10120(define_insn "tld_load_pic"
10121 [(set (match_operand:SI 0 "register_operand" "=r")
10122       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10123  (clobber (reg:SI 1))
10124  (use (reg:SI 19))]
10125  ""
10126  "*
10127{
10128  return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10129}"
10130  [(set_attr "type" "multi")
10131   (set_attr "length" "8")])
10132
10133(define_insn "tld_offset_load"
10134  [(set (match_operand:SI 0 "register_operand" "=r")
10135        (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] 
10136		 	    UNSPEC_TLSLDO)
10137		 (match_operand:SI 2 "register_operand" "r")))
10138   (clobber (reg:SI 1))]
10139  ""
10140  "*
10141{
10142  return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\"; 
10143}"
10144  [(set_attr "type" "multi")
10145   (set_attr "length" "8")])
10146
10147(define_insn "tp_load"
10148  [(set (match_operand:SI 0 "register_operand" "=r")
10149	(unspec:SI [(const_int 0)] UNSPEC_TP))]
10150  ""
10151  "mfctl %%cr27,%0"
10152  [(set_attr "type" "multi")
10153   (set_attr "length" "4")])
10154
10155(define_insn "tie_load"
10156  [(set (match_operand:SI 0 "register_operand" "=r")
10157        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10158   (clobber (reg:SI 1))
10159   (use (reg:SI 27))]
10160  ""
10161  "*
10162{
10163  return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10164}"
10165  [(set_attr "type" "multi")
10166   (set_attr "length" "8")])
10167
10168(define_insn "tie_load_pic"
10169  [(set (match_operand:SI 0 "register_operand" "=r")
10170        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10171   (clobber (reg:SI 1))
10172   (use (reg:SI 19))]
10173  ""
10174  "*
10175{
10176  return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10177}"
10178  [(set_attr "type" "multi")
10179   (set_attr "length" "8")])
10180
10181(define_insn "tle_load"
10182  [(set (match_operand:SI 0 "register_operand" "=r")
10183        (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] 
10184		 	    UNSPEC_TLSLE)
10185		 (match_operand:SI 2 "register_operand" "r")))
10186   (clobber (reg:SI 1))]
10187  ""
10188  "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10189  [(set_attr "type" "multi")
10190   (set_attr "length" "8")])
10191
10192;; Atomic instructions
10193
10194;; All memory loads and stores access storage atomically except
10195;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10196;; doubleword loads and stores are not guaranteed to be atomic
10197;; when referencing the I/O address space.
10198
10199;; These patterns are at the bottom so the non atomic versions are preferred.
10200
10201(define_expand "atomic_storeqi"
10202  [(match_operand:QI 0 "memory_operand")                ;; memory
10203   (match_operand:QI 1 "register_operand")              ;; val out
10204   (match_operand:SI 2 "const_int_operand")]            ;; model
10205  ""
10206{
10207  if (TARGET_SYNC_LIBCALL)
10208    {
10209      rtx mem = operands[0];
10210      rtx val = operands[1];
10211      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10212	DONE;
10213    }
10214  FAIL;
10215})
10216
10217;; Implement atomic HImode stores using exchange.
10218
10219(define_expand "atomic_storehi"
10220  [(match_operand:HI 0 "memory_operand")                ;; memory
10221   (match_operand:HI 1 "register_operand")              ;; val out
10222   (match_operand:SI 2 "const_int_operand")]            ;; model
10223  ""
10224{
10225  if (TARGET_SYNC_LIBCALL)
10226    {
10227      rtx mem = operands[0];
10228      rtx val = operands[1];
10229      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10230	DONE;
10231    }
10232  FAIL;
10233})
10234
10235;; Implement atomic SImode store using exchange.
10236
10237(define_expand "atomic_storesi"
10238  [(match_operand:SI 0 "memory_operand")                ;; memory
10239   (match_operand:SI 1 "register_operand")              ;; val out
10240   (match_operand:SI 2 "const_int_operand")]            ;; model
10241  ""
10242{
10243  if (TARGET_SYNC_LIBCALL)
10244    {
10245      rtx mem = operands[0];
10246      rtx val = operands[1];
10247      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10248	DONE;
10249    }
10250  FAIL;
10251})
10252
10253;; Implement atomic DImode load.
10254
10255(define_expand "atomic_loaddi"
10256  [(match_operand:DI 0 "register_operand")              ;; val out
10257   (match_operand:DI 1 "memory_operand")                ;; memory
10258   (match_operand:SI 2 "const_int_operand")]            ;; model
10259  ""
10260{
10261  enum memmodel model;
10262
10263  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
10264    FAIL;
10265
10266  model = memmodel_from_int (INTVAL (operands[2]));
10267  operands[1] = force_reg (SImode, XEXP (operands[1], 0));
10268  if (is_mm_seq_cst (model))
10269    expand_mem_thread_fence (model);
10270  emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10271  expand_mem_thread_fence (model);
10272  DONE;
10273})
10274
10275(define_insn "atomic_loaddi_1"
10276  [(set (match_operand:DI 0 "register_operand" "=r")
10277        (mem:DI (match_operand:SI 1 "register_operand" "r")))
10278   (clobber (match_scratch:DI 2 "=f"))]
10279  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
10280  "{fldds|fldd} 0(%1),%2\n\t{fstds|fstd} %2,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0\n\t{ldws|ldw} -12(%%sp),%R0"
10281  [(set_attr "type" "move")
10282   (set_attr "length" "16")])
10283
10284;; Implement atomic DImode store.
10285
10286(define_expand "atomic_storedi"
10287  [(match_operand:DI 0 "memory_operand")                ;; memory
10288   (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10289   (match_operand:SI 2 "const_int_operand")]            ;; model
10290  ""
10291{
10292  enum memmodel model;
10293
10294  if (TARGET_SYNC_LIBCALL)
10295    {
10296      rtx mem = operands[0];
10297      rtx val = operands[1];
10298      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10299	DONE;
10300    }
10301
10302  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
10303    FAIL;
10304
10305  model = memmodel_from_int (INTVAL (operands[2]));
10306  operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10307  if (operands[1] != CONST0_RTX (DImode))
10308    operands[1] = force_reg (DImode, operands[1]);
10309  expand_mem_thread_fence (model);
10310  emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10311  if (is_mm_seq_cst (model))
10312    expand_mem_thread_fence (model);
10313  DONE;
10314})
10315
10316(define_insn "atomic_storedi_1"
10317  [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10318        (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10319   (clobber (match_scratch:DI 2 "=X,f"))]
10320  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
10321  "@
10322   {fstds|fstd} %%fr0,0(%0)
10323   {stws|stw} %1,-16(%%sp)\n\t{stws|stw} %R1,-12(%%sp)\n\t{fldds|fldd} -16(%%sp),%2\n\t{fstds|fstd} %2,0(%0)"
10324  [(set_attr "type" "move,move")
10325   (set_attr "length" "4,16")])
10326
10327;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10328;; we need memory barriers to enforce program order for memory references
10329;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10330;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10331;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10332;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10333
10334;; When barriers are needed, we use a strongly ordered ldcw instruction as
10335;; the barrier.  Most PA 2.0 targets are cache coherent.  In that case, we
10336;; can use the coherent cache control hint and avoid aligning the ldcw
10337;; address.  In spite of its description, it is not clear that the sync
10338;; instruction works as a barrier.
10339
10340(define_expand "memory_barrier"
10341  [(parallel
10342     [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10343      (clobber (match_dup 1))])]
10344  ""
10345{
10346  /* We don't need a barrier if the target uses ordered memory references.  */
10347  if (TARGET_ORDERED)
10348    FAIL;
10349  operands[1] = gen_reg_rtx (Pmode);
10350  operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10351  MEM_VOLATILE_P (operands[0]) = 1;
10352})
10353
10354(define_insn "*memory_barrier_coherent"
10355  [(set (match_operand:BLK 0 "" "")
10356        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10357   (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10358  "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10359  "ldcw,co 0(%%sp),%1"
10360  [(set_attr "type" "binary")
10361   (set_attr "length" "4")])
10362
10363(define_insn "*memory_barrier_64"
10364  [(set (match_operand:BLK 0 "" "")
10365        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10366    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10367  "TARGET_64BIT"
10368  "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw 0(%1),%1"
10369  [(set_attr "type" "binary")
10370   (set_attr "length" "12")])
10371
10372(define_insn "*memory_barrier_32"
10373  [(set (match_operand:BLK 0 "" "")
10374        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10375    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10376  ""
10377  "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\tldcw 0(%1),%1"
10378  [(set_attr "type" "binary")
10379   (set_attr "length" "12")])
10380