xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/pa/pa.md (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1;;- Machine description for HP PA-RISC architecture for GCC compiler
2;;   Copyright (C) 1992-2022 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.cc
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.cc
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  if (TARGET_64BIT)
5077    operands[2] = force_reg (DImode, operands[2]);
5078}")
5079
5080(define_insn ""
5081  [(set (match_operand:DI 0 "register_operand" "=r")
5082	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5083		 (match_operand:DI 2 "register_operand" "r")))
5084   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5085			 (sign_extend:TI (match_dup 2)))
5086		(sign_extend:TI (plus:DI (match_dup 1)
5087					 (match_dup 2))))
5088	    (const_int 0))]
5089  "TARGET_64BIT"
5090  "add,tsv,* %2,%1,%0"
5091  [(set_attr "type" "binary")
5092   (set_attr "length" "4")])
5093
5094(define_insn ""
5095  [(set (match_operand:DI 0 "register_operand" "=r")
5096	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5097		 (match_operand:DI 2 "arith11_operand" "rI")))
5098   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5099			 (sign_extend:TI (match_dup 2)))
5100		(sign_extend:TI (plus:DI (match_dup 1)
5101					 (match_dup 2))))
5102	    (const_int 0))]
5103  "!TARGET_64BIT"
5104  "*
5105{
5106  if (GET_CODE (operands[2]) == CONST_INT)
5107    {
5108      if (INTVAL (operands[2]) >= 0)
5109	return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5110      else
5111	return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5112    }
5113  else
5114    return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5115}"
5116  [(set_attr "type" "binary")
5117   (set_attr "length" "8")])
5118
5119;; define_splits to optimize cases of adding a constant integer
5120;; to a register when the constant does not fit in 14 bits.  */
5121(define_split
5122  [(set (match_operand:SI 0 "register_operand" "")
5123	(plus:SI (match_operand:SI 1 "register_operand" "")
5124		 (match_operand:SI 2 "const_int_operand" "")))
5125   (clobber (match_operand:SI 4 "register_operand" ""))]
5126  "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5127   && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5128  [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5129   (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5130  "
5131{
5132  int val = INTVAL (operands[2]);
5133  int low = (val < 0) ? -0x2000 : 0x1fff;
5134  int rest = val - low;
5135
5136  operands[2] = GEN_INT (rest);
5137  operands[3] = GEN_INT (low);
5138}")
5139
5140(define_split
5141  [(set (match_operand:SI 0 "register_operand" "")
5142	(plus:SI (match_operand:SI 1 "register_operand" "")
5143		 (match_operand:SI 2 "const_int_operand" "")))
5144   (clobber (match_operand:SI 4 "register_operand" ""))]
5145  "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5146  [(set (match_dup 4) (match_dup 2))
5147   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5148			       (match_dup 1)))]
5149  "
5150{
5151  unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5152
5153  /* Try dividing the constant by 2, then 4, and finally 8 to see
5154     if we can get a constant which can be loaded into a register
5155     in a single instruction (pa_cint_ok_for_move).
5156
5157     If that fails, try to negate the constant and subtract it
5158     from our input operand.  */
5159  if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5160    {
5161      operands[2] = GEN_INT (intval / 2);
5162      operands[3] = const1_rtx;
5163    }
5164  else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5165    {
5166      operands[2] = GEN_INT (intval / 4);
5167      operands[3] = const2_rtx;
5168    }
5169  else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5170    {
5171      operands[2] = GEN_INT (intval / 8);
5172      operands[3] = GEN_INT (3);
5173    }
5174  else if (pa_cint_ok_for_move (-intval))
5175    {
5176      emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5177      emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5178      DONE;
5179    }
5180  else
5181    FAIL;
5182}")
5183
5184(define_insn "addsi3"
5185  [(set (match_operand:SI 0 "register_operand" "=r,r")
5186	(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5187		 (match_operand:SI 2 "arith14_operand" "r,J")))]
5188  ""
5189  "@
5190   {addl|add,l} %1,%2,%0
5191   ldo %2(%1),%0"
5192  [(set_attr "type" "binary,binary")
5193   (set_attr "pa_combine_type" "addmove")
5194   (set_attr "length" "4,4")])
5195
5196(define_insn "addvsi3"
5197  [(set (match_operand:SI 0 "register_operand" "=r,r")
5198	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5199		 (match_operand:SI 2 "arith11_operand" "r,I")))
5200   (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5201			 (sign_extend:DI (match_dup 2)))
5202		(sign_extend:DI (plus:SI (match_dup 1)
5203					 (match_dup 2))))
5204	    (const_int 0))]
5205  ""
5206  "@
5207  {addo|add,tsv} %2,%1,%0
5208  {addio|addi,tsv} %2,%1,%0"
5209  [(set_attr "type" "binary,binary")
5210   (set_attr "length" "4,4")])
5211
5212(define_expand "subdi3"
5213  [(set (match_operand:DI 0 "register_operand" "")
5214	(minus:DI (match_operand:DI 1 "arith11_operand" "")
5215		  (match_operand:DI 2 "reg_or_0_operand" "")))]
5216  ""
5217  "")
5218
5219(define_insn ""
5220  [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5221	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5222		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5223  "TARGET_64BIT"
5224  "@
5225   sub %1,%2,%0
5226   subi %1,%2,%0
5227   mtsarcm %2"
5228  [(set_attr "type" "binary,binary,move")
5229  (set_attr "length" "4,4,4")])
5230
5231(define_insn ""
5232  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5233	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5234		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5235  "!TARGET_64BIT"
5236  "*
5237{
5238  if (GET_CODE (operands[1]) == CONST_INT)
5239    {
5240      if (INTVAL (operands[1]) >= 0)
5241	return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5242      else
5243	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5244    }
5245  else
5246    return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5247}"
5248  [(set_attr "type" "binary")
5249   (set (attr "length")
5250	(if_then_else (eq_attr "alternative" "0")
5251	  (const_int 8)
5252	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5253			    (const_int 0))
5254	    (const_int 8)
5255	    (const_int 12))))])
5256
5257(define_expand "subvdi3"
5258  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5259		   (minus:DI (match_operand:DI 1 "arith11_operand" "")
5260			     (match_operand:DI 2 "reg_or_0_operand" "")))
5261	      (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5262				     (sign_extend:TI (match_dup 2)))
5263			   (sign_extend:TI (minus:DI (match_dup 1)
5264						     (match_dup 2))))
5265		       (const_int 0))])]
5266  ""
5267  "
5268{
5269  if (TARGET_64BIT)
5270    operands[1] = force_reg (DImode, operands[1]);
5271}")
5272
5273(define_insn ""
5274  [(set (match_operand:DI 0 "register_operand" "=r")
5275	(minus:DI (match_operand:DI 1 "register_operand" "r")
5276		  (match_operand:DI 2 "reg_or_0_operand" "rM")))
5277   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5278			  (sign_extend:TI (match_dup 2)))
5279		(sign_extend:TI (minus:DI (match_dup 1)
5280					  (match_dup 2))))
5281	    (const_int 0))]
5282  "TARGET_64BIT"
5283  "sub,tsv,* %1,%2,%0"
5284  [(set_attr "type" "binary")
5285   (set_attr "length" "4")])
5286
5287(define_insn ""
5288  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5289	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5290		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5291   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5292			  (sign_extend:TI (match_dup 2)))
5293		(sign_extend:TI (minus:DI (match_dup 1)
5294					  (match_dup 2))))
5295	    (const_int 0))]
5296  "!TARGET_64BIT"
5297  "*
5298{
5299  if (GET_CODE (operands[1]) == CONST_INT)
5300    {
5301      if (INTVAL (operands[1]) >= 0)
5302	return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5303      else
5304	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5305    }
5306  else
5307    return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5308}"
5309  [(set_attr "type" "binary,binary")
5310   (set (attr "length")
5311	(if_then_else (eq_attr "alternative" "0")
5312	  (const_int 8)
5313	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5314			    (const_int 0))
5315	    (const_int 8)
5316	    (const_int 12))))])
5317
5318(define_expand "subsi3"
5319  [(set (match_operand:SI 0 "register_operand" "")
5320	(minus:SI (match_operand:SI 1 "arith11_operand" "")
5321		  (match_operand:SI 2 "register_operand" "")))]
5322  ""
5323  "")
5324
5325(define_insn ""
5326  [(set (match_operand:SI 0 "register_operand" "=r,r")
5327	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5328		  (match_operand:SI 2 "register_operand" "r,r")))]
5329  "!TARGET_PA_20"
5330  "@
5331   sub %1,%2,%0
5332   subi %1,%2,%0"
5333  [(set_attr "type" "binary,binary")
5334   (set_attr "length" "4,4")])
5335
5336(define_insn ""
5337  [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5338	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5339		  (match_operand:SI 2 "register_operand" "r,r,!r")))]
5340  "TARGET_PA_20"
5341  "@
5342   sub %1,%2,%0
5343   subi %1,%2,%0
5344   mtsarcm %2"
5345  [(set_attr "type" "binary,binary,move")
5346   (set_attr "length" "4,4,4")])
5347
5348(define_insn "subvsi3"
5349  [(set (match_operand:SI 0 "register_operand" "=r,r")
5350	(minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5351		  (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5352   (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5353			  (sign_extend:DI (match_dup 2)))
5354		(sign_extend:DI (minus:SI (match_dup 1)
5355					  (match_dup 2))))
5356	    (const_int 0))]
5357  ""
5358  "@
5359  {subo|sub,tsv} %1,%2,%0
5360  {subio|subi,tsv} %1,%2,%0"
5361  [(set_attr "type" "binary,binary")
5362   (set_attr "length" "4,4")])
5363
5364(define_insn "addti3"
5365  [(set (match_operand:TI 0 "register_operand" "=r")
5366	(plus:TI (match_operand:TI 1 "register_operand" "r")
5367		 (match_operand:TI 2 "register_operand" "r")))]
5368  "TARGET_64BIT"
5369  "*
5370{
5371  operands[3] = gen_lowpart (DImode, operands[0]);
5372  operands[4] = gen_lowpart (DImode, operands[1]);
5373  operands[5] = gen_lowpart (DImode, operands[2]);
5374  operands[0] = gen_highpart (DImode, operands[0]);
5375  operands[1] = gen_highpart (DImode, operands[1]);
5376  operands[2] = gen_highpart (DImode, operands[2]);
5377  return \"add %4,%5,%3\;add,dc %1,%2,%0\";
5378}"
5379  [(set_attr "type" "multi")
5380   (set_attr "length" "8")])
5381
5382(define_insn "addvti3"
5383  [(set (match_operand:TI 0 "register_operand" "=r")
5384	(plus:TI (match_operand:TI 1 "register_operand" "r")
5385		 (match_operand:TI 2 "register_operand" "r")))
5386   (trap_if (ne (plus:OI (sign_extend:OI (match_dup 1))
5387			 (sign_extend:OI (match_dup 2)))
5388		(sign_extend:OI (plus:TI (match_dup 1)
5389					 (match_dup 2))))
5390	    (const_int 0))]
5391  "TARGET_64BIT"
5392  "*
5393{
5394  operands[3] = gen_lowpart (DImode, operands[0]);
5395  operands[4] = gen_lowpart (DImode, operands[1]);
5396  operands[5] = gen_lowpart (DImode, operands[2]);
5397  operands[0] = gen_highpart (DImode, operands[0]);
5398  operands[1] = gen_highpart (DImode, operands[1]);
5399  operands[2] = gen_highpart (DImode, operands[2]);
5400  return \"add %4,%5,%3\;add,dc,tsv %1,%2,%0\";
5401}"
5402  [(set_attr "type" "multi")
5403   (set_attr "length" "8")])
5404
5405(define_insn "subti3"
5406  [(set (match_operand:TI 0 "register_operand" "=r")
5407	(minus:TI (match_operand:TI 1 "register_operand" "r")
5408		  (match_operand:TI 2 "register_operand" "r")))]
5409  "TARGET_64BIT"
5410  "*
5411{
5412  operands[3] = gen_lowpart (DImode, operands[0]);
5413  operands[4] = gen_lowpart (DImode, operands[1]);
5414  operands[5] = gen_lowpart (DImode, operands[2]);
5415  operands[0] = gen_highpart (DImode, operands[0]);
5416  operands[1] = gen_highpart (DImode, operands[1]);
5417  operands[2] = gen_highpart (DImode, operands[2]);
5418  return \"sub %4,%5,%3\;sub,db %1,%2,%0\";
5419}"
5420  [(set_attr "type" "multi")
5421   (set_attr "length" "8")])
5422
5423(define_insn "subvti3"
5424  [(set (match_operand:TI 0 "register_operand" "=r")
5425	(minus:TI (match_operand:TI 1 "register_operand" "r")
5426		  (match_operand:TI 2 "register_operand" "r")))
5427   (trap_if (ne (minus:OI (sign_extend:OI (match_dup 1))
5428			  (sign_extend:OI (match_dup 2)))
5429		(sign_extend:OI (minus:TI (match_dup 1)
5430					  (match_dup 2))))
5431	    (const_int 0))]
5432  "TARGET_64BIT"
5433  "*
5434{
5435  operands[3] = gen_lowpart (DImode, operands[0]);
5436  operands[4] = gen_lowpart (DImode, operands[1]);
5437  operands[5] = gen_lowpart (DImode, operands[2]);
5438  operands[0] = gen_highpart (DImode, operands[0]);
5439  operands[1] = gen_highpart (DImode, operands[1]);
5440  operands[2] = gen_highpart (DImode, operands[2]);
5441  return \"sub %4,%5,%3\;sub,db,tsv %1,%2,%0\";
5442}"
5443  [(set_attr "type" "multi")
5444   (set_attr "length" "8")])
5445
5446;; Trap instructions.
5447
5448(define_insn "trap"
5449  [(trap_if (const_int 1) (const_int 0))]
5450  ""
5451  "{addit|addi,tc},<> 1,%%r0,%%r0"
5452  [(set_attr "type" "trap")
5453   (set_attr "length" "4")])
5454
5455;; Clobbering a "register_operand" instead of a match_scratch
5456;; in operand3 of millicode calls avoids spilling %r1 and
5457;; produces better code.
5458
5459;; The mulsi3 insns set up registers for the millicode call.
5460(define_expand "mulsi3"
5461  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5462   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5463   (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5464	      (clobber (match_dup 3))
5465	      (clobber (reg:SI 26))
5466	      (clobber (reg:SI 25))
5467	      (clobber (match_dup 4))])
5468   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5469  ""
5470  "
5471{
5472  operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5473  if (TARGET_PA_11 && !TARGET_SOFT_FLOAT && !TARGET_SOFT_MULT)
5474    {
5475      rtx scratch = gen_reg_rtx (DImode);
5476      operands[1] = force_reg (SImode, operands[1]);
5477      operands[2] = force_reg (SImode, operands[2]);
5478      emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5479      emit_insn (gen_movsi (operands[0],
5480			    gen_rtx_SUBREG (SImode, scratch,
5481					    GET_MODE_SIZE (SImode))));
5482      DONE;
5483    }
5484  operands[3] = gen_reg_rtx (SImode);
5485}")
5486
5487(define_insn "umulsidi3"
5488  [(set (match_operand:DI 0 "register_operand" "=f")
5489	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5490		 (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5491  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT"
5492  "xmpyu %1,%2,%0"
5493  [(set_attr "type" "fpmuldbl")
5494   (set_attr "length" "4")])
5495
5496(define_insn ""
5497  [(set (match_operand:DI 0 "register_operand" "=f")
5498	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5499		 (match_operand:DI 2 "uint32_operand" "f")))]
5500  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && !TARGET_64BIT"
5501  "xmpyu %1,%R2,%0"
5502  [(set_attr "type" "fpmuldbl")
5503   (set_attr "length" "4")])
5504
5505(define_insn ""
5506  [(set (match_operand:DI 0 "register_operand" "=f")
5507	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5508		 (match_operand:DI 2 "uint32_operand" "f")))]
5509  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && TARGET_64BIT"
5510  "xmpyu %1,%2R,%0"
5511  [(set_attr "type" "fpmuldbl")
5512   (set_attr "length" "4")])
5513
5514(define_insn ""
5515  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5516   (clobber (match_operand:SI 0 "register_operand" "=a"))
5517   (clobber (reg:SI 26))
5518   (clobber (reg:SI 25))
5519   (clobber (reg:SI 31))]
5520  "!TARGET_64BIT"
5521  "* return pa_output_mul_insn (0, insn);"
5522  [(set_attr "type" "milli")
5523   (set (attr "length")
5524	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5525	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5526
5527(define_insn ""
5528  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5529   (clobber (match_operand:SI 0 "register_operand" "=a"))
5530   (clobber (reg:SI 26))
5531   (clobber (reg:SI 25))
5532   (clobber (reg:SI 2))]
5533  "TARGET_64BIT"
5534  "* return pa_output_mul_insn (0, insn);"
5535  [(set_attr "type" "milli")
5536   (set (attr "length")
5537	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5538	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5539
5540(define_expand "muldi3"
5541  [(set (match_operand:DI 0 "register_operand" "")
5542        (mult:DI (match_operand:DI 1 "register_operand" "")
5543		 (match_operand:DI 2 "register_operand" "")))]
5544  "! optimize_size
5545   && TARGET_PA_11
5546   && ! TARGET_SOFT_FLOAT
5547   && ! TARGET_SOFT_MULT"
5548  "
5549{
5550  rtx low_product = gen_reg_rtx (DImode);
5551  rtx cross_product1 = gen_reg_rtx (DImode);
5552  rtx cross_product2 = gen_reg_rtx (DImode);
5553  rtx op1l, op1r, op2l, op2r;
5554
5555  if (TARGET_64BIT)
5556    {
5557      rtx op1shifted = gen_reg_rtx (DImode);
5558      rtx op2shifted = gen_reg_rtx (DImode);
5559
5560      emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5561						    GEN_INT (32)));
5562      emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5563						    GEN_INT (32)));
5564      op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5565      op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5566      op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5567      op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5568    }
5569  else
5570    {
5571      op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5572      op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5573      op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5574      op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5575    }
5576
5577  /* Emit multiplies for the cross products.  */
5578  emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5579  emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5580
5581  /* Emit a multiply for the low sub-word.  */
5582  emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5583
5584  if (TARGET_64BIT)
5585    {
5586      rtx cross_scratch = gen_reg_rtx (DImode);
5587      rtx cross_product = gen_reg_rtx (DImode);
5588
5589      /* Sum the cross products and shift them into proper position.  */
5590      emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5591      emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5592
5593      /* Add the cross product to the low product and store the result
5594	 into the output operand .  */
5595      emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5596    }
5597  else
5598    {
5599      rtx cross_scratch = gen_reg_rtx (SImode);
5600
5601      /* Sum cross products.  */
5602      emit_move_insn (cross_scratch,
5603		      gen_rtx_PLUS (SImode,
5604				    gen_lowpart (SImode, cross_product1),
5605				    gen_lowpart (SImode, cross_product2)));
5606      emit_move_insn (gen_lowpart (SImode, operands[0]),
5607		      gen_lowpart (SImode, low_product));
5608      emit_move_insn (gen_highpart (SImode, operands[0]),
5609		      gen_rtx_PLUS (SImode,
5610				    gen_highpart (SImode, low_product),
5611				    cross_scratch));
5612    }
5613  DONE;
5614}")
5615
5616;;; Division and mod.
5617(define_expand "divsi3"
5618  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5619   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5620   (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5621	      (clobber (match_dup 3))
5622	      (clobber (match_dup 4))
5623	      (clobber (reg:SI 26))
5624	      (clobber (reg:SI 25))
5625	      (clobber (match_dup 5))])
5626   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5627  ""
5628  "
5629{
5630  operands[3] = gen_reg_rtx (SImode);
5631  if (TARGET_64BIT)
5632    {
5633      operands[5] = gen_rtx_REG (SImode, 2);
5634      operands[4] = operands[5];
5635    }
5636  else
5637    {
5638      operands[5] = gen_rtx_REG (SImode, 31);
5639      operands[4] = gen_reg_rtx (SImode);
5640    }
5641  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5642    DONE;
5643}")
5644
5645(define_insn ""
5646  [(set (reg:SI 29)
5647	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5648   (clobber (match_operand:SI 1 "register_operand" "=a"))
5649   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5650   (clobber (reg:SI 26))
5651   (clobber (reg:SI 25))
5652   (clobber (reg:SI 31))]
5653  "!TARGET_64BIT"
5654  "*
5655   return pa_output_div_insn (operands, 0, insn);"
5656  [(set_attr "type" "milli")
5657   (set (attr "length")
5658	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5659	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5660
5661(define_insn ""
5662  [(set (reg:SI 29)
5663	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5664   (clobber (match_operand:SI 1 "register_operand" "=a"))
5665   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5666   (clobber (reg:SI 26))
5667   (clobber (reg:SI 25))
5668   (clobber (reg:SI 2))]
5669  "TARGET_64BIT"
5670  "*
5671   return pa_output_div_insn (operands, 0, insn);"
5672  [(set_attr "type" "milli")
5673   (set (attr "length")
5674	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5675	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5676
5677(define_expand "udivsi3"
5678  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5679   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5680   (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5681	      (clobber (match_dup 3))
5682	      (clobber (match_dup 4))
5683	      (clobber (reg:SI 26))
5684	      (clobber (reg:SI 25))
5685	      (clobber (match_dup 5))])
5686   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5687  ""
5688  "
5689{
5690  operands[3] = gen_reg_rtx (SImode);
5691
5692  if (TARGET_64BIT)
5693    {
5694      operands[5] = gen_rtx_REG (SImode, 2);
5695      operands[4] = operands[5];
5696    }
5697  else
5698    {
5699      operands[5] = gen_rtx_REG (SImode, 31);
5700      operands[4] = gen_reg_rtx (SImode);
5701    }
5702  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5703    DONE;
5704}")
5705
5706(define_insn ""
5707  [(set (reg:SI 29)
5708	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5709   (clobber (match_operand:SI 1 "register_operand" "=a"))
5710   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5711   (clobber (reg:SI 26))
5712   (clobber (reg:SI 25))
5713   (clobber (reg:SI 31))]
5714  "!TARGET_64BIT"
5715  "*
5716   return pa_output_div_insn (operands, 1, insn);"
5717  [(set_attr "type" "milli")
5718   (set (attr "length")
5719	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5720	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5721
5722(define_insn ""
5723  [(set (reg:SI 29)
5724	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5725   (clobber (match_operand:SI 1 "register_operand" "=a"))
5726   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5727   (clobber (reg:SI 26))
5728   (clobber (reg:SI 25))
5729   (clobber (reg:SI 2))]
5730  "TARGET_64BIT"
5731  "*
5732   return pa_output_div_insn (operands, 1, insn);"
5733  [(set_attr "type" "milli")
5734   (set (attr "length")
5735	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5736	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5737
5738(define_expand "modsi3"
5739  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5740   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5741   (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5742	      (clobber (match_dup 3))
5743	      (clobber (match_dup 4))
5744	      (clobber (reg:SI 26))
5745	      (clobber (reg:SI 25))
5746	      (clobber (match_dup 5))])
5747   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5748  ""
5749  "
5750{
5751  if (TARGET_64BIT)
5752    {
5753      operands[5] = gen_rtx_REG (SImode, 2);
5754      operands[4] = operands[5];
5755    }
5756  else
5757    {
5758      operands[5] = gen_rtx_REG (SImode, 31);
5759      operands[4] = gen_reg_rtx (SImode);
5760    }
5761  operands[3] = gen_reg_rtx (SImode);
5762}")
5763
5764(define_insn ""
5765  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5766   (clobber (match_operand:SI 0 "register_operand" "=a"))
5767   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5768   (clobber (reg:SI 26))
5769   (clobber (reg:SI 25))
5770   (clobber (reg:SI 31))]
5771  "!TARGET_64BIT"
5772  "*
5773  return pa_output_mod_insn (0, insn);"
5774  [(set_attr "type" "milli")
5775   (set (attr "length")
5776	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5777	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5778
5779(define_insn ""
5780  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5781   (clobber (match_operand:SI 0 "register_operand" "=a"))
5782   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5783   (clobber (reg:SI 26))
5784   (clobber (reg:SI 25))
5785   (clobber (reg:SI 2))]
5786  "TARGET_64BIT"
5787  "*
5788  return pa_output_mod_insn (0, insn);"
5789  [(set_attr "type" "milli")
5790   (set (attr "length")
5791	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5792	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5793
5794(define_expand "umodsi3"
5795  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5796   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5797   (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5798	      (clobber (match_dup 3))
5799	      (clobber (match_dup 4))
5800	      (clobber (reg:SI 26))
5801	      (clobber (reg:SI 25))
5802	      (clobber (match_dup 5))])
5803   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5804  ""
5805  "
5806{
5807  if (TARGET_64BIT)
5808    {
5809      operands[5] = gen_rtx_REG (SImode, 2);
5810      operands[4] = operands[5];
5811    }
5812  else
5813    {
5814      operands[5] = gen_rtx_REG (SImode, 31);
5815      operands[4] = gen_reg_rtx (SImode);
5816    }
5817  operands[3] = gen_reg_rtx (SImode);
5818}")
5819
5820(define_insn ""
5821  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5822   (clobber (match_operand:SI 0 "register_operand" "=a"))
5823   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5824   (clobber (reg:SI 26))
5825   (clobber (reg:SI 25))
5826   (clobber (reg:SI 31))]
5827  "!TARGET_64BIT"
5828  "*
5829  return pa_output_mod_insn (1, insn);"
5830  [(set_attr "type" "milli")
5831   (set (attr "length")
5832	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5833	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5834
5835(define_insn ""
5836  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5837   (clobber (match_operand:SI 0 "register_operand" "=a"))
5838   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5839   (clobber (reg:SI 26))
5840   (clobber (reg:SI 25))
5841   (clobber (reg:SI 2))]
5842  "TARGET_64BIT"
5843  "*
5844  return pa_output_mod_insn (1, insn);"
5845  [(set_attr "type" "milli")
5846   (set (attr "length")
5847	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5848	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5849
5850;;- and instructions
5851;; We define DImode `and` so with DImode `not` we can get
5852;; DImode `andn`.  Other combinations are possible.
5853
5854(define_expand "anddi3"
5855  [(set (match_operand:DI 0 "register_operand" "")
5856	(and:DI (match_operand:DI 1 "register_operand" "")
5857		(match_operand:DI 2 "and_operand" "")))]
5858  "TARGET_64BIT"
5859  "")
5860
5861(define_insn ""
5862  [(set (match_operand:DI 0 "register_operand" "=r,r")
5863	(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5864		(match_operand:DI 2 "and_operand" "rO,P")))]
5865  "TARGET_64BIT"
5866  "* return pa_output_64bit_and (operands); "
5867  [(set_attr "type" "binary")
5868   (set_attr "length" "4")])
5869
5870; The ? for op1 makes reload prefer zdepi instead of loading a huge
5871; constant with ldil;ldo.
5872(define_insn "andsi3"
5873  [(set (match_operand:SI 0 "register_operand" "=r,r")
5874	(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5875		(match_operand:SI 2 "and_operand" "rO,P")))]
5876  ""
5877  "* return pa_output_and (operands); "
5878  [(set_attr "type" "binary,shift")
5879   (set_attr "length" "4,4")])
5880
5881(define_insn ""
5882  [(set (match_operand:DI 0 "register_operand" "=r")
5883	(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5884		(match_operand:DI 2 "register_operand" "r")))]
5885  "TARGET_64BIT"
5886  "andcm %2,%1,%0"
5887  [(set_attr "type" "binary")
5888   (set_attr "length" "4")])
5889
5890(define_insn ""
5891  [(set (match_operand:SI 0 "register_operand" "=r")
5892	(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5893		(match_operand:SI 2 "register_operand" "r")))]
5894  ""
5895  "andcm %2,%1,%0"
5896  [(set_attr "type" "binary")
5897  (set_attr "length" "4")])
5898
5899(define_expand "iordi3"
5900  [(set (match_operand:DI 0 "register_operand" "")
5901	(ior:DI (match_operand:DI 1 "register_operand" "")
5902		(match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5903  "TARGET_64BIT"
5904  "")
5905
5906(define_insn ""
5907  [(set (match_operand:DI 0 "register_operand" "=r,r")
5908	(ior:DI (match_operand:DI 1 "register_operand" "0,0")
5909		(match_operand:DI 2 "cint_ior_operand" "M,i")))]
5910  "TARGET_64BIT"
5911  "* return pa_output_64bit_ior (operands); "
5912  [(set_attr "type" "binary,shift")
5913   (set_attr "length" "4,4")])
5914
5915(define_insn ""
5916  [(set (match_operand:DI 0 "register_operand" "=r")
5917	(ior:DI (match_operand:DI 1 "register_operand" "%r")
5918		(match_operand:DI 2 "register_operand" "r")))]
5919  "TARGET_64BIT"
5920  "or %1,%2,%0"
5921  [(set_attr "type" "binary")
5922   (set_attr "length" "4")])
5923
5924;; Need a define_expand because we've run out of CONST_OK... characters.
5925(define_expand "iorsi3"
5926  [(set (match_operand:SI 0 "register_operand" "")
5927	(ior:SI (match_operand:SI 1 "register_operand" "")
5928		(match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5929  ""
5930  "")
5931
5932(define_insn ""
5933  [(set (match_operand:SI 0 "register_operand" "=r,r")
5934	(ior:SI (match_operand:SI 1 "register_operand" "0,0")
5935		(match_operand:SI 2 "cint_ior_operand" "M,i")))]
5936  ""
5937  "* return pa_output_ior (operands); "
5938  [(set_attr "type" "binary,shift")
5939   (set_attr "length" "4,4")])
5940
5941(define_insn ""
5942  [(set (match_operand:SI 0 "register_operand" "=r")
5943	(ior:SI (match_operand:SI 1 "register_operand" "%r")
5944		(match_operand:SI 2 "register_operand" "r")))]
5945  ""
5946  "or %1,%2,%0"
5947  [(set_attr "type" "binary")
5948   (set_attr "length" "4")])
5949
5950(define_expand "xordi3"
5951  [(set (match_operand:DI 0 "register_operand" "")
5952	(xor:DI (match_operand:DI 1 "register_operand" "")
5953		(match_operand:DI 2 "register_operand" "")))]
5954  "TARGET_64BIT"
5955  "")
5956
5957(define_insn ""
5958  [(set (match_operand:DI 0 "register_operand" "=r")
5959	(xor:DI (match_operand:DI 1 "register_operand" "%r")
5960		(match_operand:DI 2 "register_operand" "r")))]
5961  "TARGET_64BIT"
5962  "xor %1,%2,%0"
5963  [(set_attr "type" "binary")
5964   (set_attr "length" "4")])
5965
5966(define_insn "xorsi3"
5967  [(set (match_operand:SI 0 "register_operand" "=r")
5968	(xor:SI (match_operand:SI 1 "register_operand" "%r")
5969		(match_operand:SI 2 "register_operand" "r")))]
5970  ""
5971  "xor %1,%2,%0"
5972  [(set_attr "type" "binary")
5973   (set_attr "length" "4")])
5974
5975(define_expand "negdi2"
5976  [(set (match_operand:DI 0 "register_operand" "")
5977	(neg:DI (match_operand:DI 1 "register_operand" "")))]
5978  ""
5979  "")
5980
5981(define_insn ""
5982  [(set (match_operand:DI 0 "register_operand" "=r")
5983	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5984  "!TARGET_64BIT"
5985  "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5986  [(set_attr "type" "multi")
5987   (set_attr "length" "8")])
5988
5989(define_insn ""
5990  [(set (match_operand:DI 0 "register_operand" "=r")
5991	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5992  "TARGET_64BIT"
5993  "sub %%r0,%1,%0"
5994  [(set_attr "type" "unary")
5995   (set_attr "length" "4")])
5996
5997(define_insn "negti2"
5998  [(set (match_operand:TI 0 "register_operand" "=r")
5999	(neg:TI (match_operand:TI 1 "register_operand" "r")))]
6000  "TARGET_64BIT"
6001  "*
6002{
6003  operands[2] = gen_lowpart (DImode, operands[0]);
6004  operands[3] = gen_lowpart (DImode, operands[1]);
6005  operands[0] = gen_highpart (DImode, operands[0]);
6006  operands[1] = gen_highpart (DImode, operands[1]);
6007  return \"sub %%r0,%3,%2\;sub,db %%r0,%1,%0\";
6008}"
6009  [(set_attr "type" "multi")
6010   (set_attr "length" "8")])
6011
6012(define_expand "negvdi2"
6013  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6014		   (neg:DI (match_operand:DI 1 "register_operand" "")))
6015	      (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6016				   (sign_extend:TI (neg:DI (match_dup 1))))
6017		       (const_int 0))])]
6018  ""
6019  "")
6020
6021(define_insn ""
6022  [(set (match_operand:DI 0 "register_operand" "=r")
6023	(neg:DI (match_operand:DI 1 "register_operand" "r")))
6024   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6025		(sign_extend:TI (neg:DI (match_dup 1))))
6026	    (const_int 0))]
6027  "!TARGET_64BIT"
6028  "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
6029  [(set_attr "type" "multi")
6030   (set_attr "length" "8")])
6031
6032(define_insn ""
6033  [(set (match_operand:DI 0 "register_operand" "=r")
6034	(neg:DI (match_operand:DI 1 "register_operand" "r")))
6035   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6036		(sign_extend:TI (neg:DI (match_dup 1))))
6037	    (const_int 0))]
6038  "TARGET_64BIT"
6039  "sub,tsv %%r0,%1,%0"
6040  [(set_attr "type" "unary")
6041   (set_attr "length" "4")])
6042
6043(define_insn "negvti2"
6044  [(set (match_operand:TI 0 "register_operand" "=r")
6045	(neg:TI (match_operand:TI 1 "register_operand" "r")))
6046   (trap_if (ne (neg:OI (sign_extend:OI (match_dup 1)))
6047		(sign_extend:OI (neg:TI (match_dup 1))))
6048	    (const_int 0))]
6049  "TARGET_64BIT"
6050  "*
6051{
6052  operands[2] = gen_lowpart (DImode, operands[0]);
6053  operands[3] = gen_lowpart (DImode, operands[1]);
6054  operands[0] = gen_highpart (DImode, operands[0]);
6055  operands[1] = gen_highpart (DImode, operands[1]);
6056  return \"sub %%r0,%3,%2\;sub,db,tsv %%r0,%1,%0\";
6057}"
6058  [(set_attr "type" "multi")
6059   (set_attr "length" "8")])
6060
6061(define_insn "negsi2"
6062  [(set (match_operand:SI 0 "register_operand" "=r")
6063	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
6064  ""
6065  "sub %%r0,%1,%0"
6066  [(set_attr "type" "unary")
6067   (set_attr "length" "4")])
6068
6069(define_insn "negvsi2"
6070  [(set (match_operand:SI 0 "register_operand" "=r")
6071        (neg:SI (match_operand:SI 1 "register_operand" "r")))
6072   (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
6073		(sign_extend:DI (neg:SI (match_dup 1))))
6074	    (const_int 0))]
6075   ""
6076   "{subo|sub,tsv} %%r0,%1,%0"
6077  [(set_attr "type" "unary")
6078   (set_attr "length" "4")])
6079
6080(define_expand "one_cmpldi2"
6081  [(set (match_operand:DI 0 "register_operand" "")
6082	(not:DI (match_operand:DI 1 "register_operand" "")))]
6083  ""
6084  "
6085{
6086}")
6087
6088(define_insn ""
6089  [(set (match_operand:DI 0 "register_operand" "=r")
6090	(not:DI (match_operand:DI 1 "register_operand" "r")))]
6091  "!TARGET_64BIT"
6092  "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
6093  [(set_attr "type" "unary")
6094   (set_attr "length" "8")])
6095
6096(define_insn ""
6097  [(set (match_operand:DI 0 "register_operand" "=r")
6098	(not:DI (match_operand:DI 1 "register_operand" "r")))]
6099  "TARGET_64BIT"
6100  "uaddcm %%r0,%1,%0"
6101  [(set_attr "type" "unary")
6102   (set_attr "length" "4")])
6103
6104(define_insn "one_cmplsi2"
6105  [(set (match_operand:SI 0 "register_operand" "=r")
6106	(not:SI (match_operand:SI 1 "register_operand" "r")))]
6107  ""
6108  "uaddcm %%r0,%1,%0"
6109  [(set_attr "type" "unary")
6110   (set_attr "length" "4")])
6111
6112;; Floating point arithmetic instructions.
6113
6114(define_insn "adddf3"
6115  [(set (match_operand:DF 0 "register_operand" "=f")
6116	(plus:DF (match_operand:DF 1 "register_operand" "f")
6117		 (match_operand:DF 2 "register_operand" "f")))]
6118  "! TARGET_SOFT_FLOAT"
6119  "fadd,dbl %1,%2,%0"
6120  [(set_attr "type" "fpalu")
6121   (set_attr "pa_combine_type" "faddsub")
6122   (set_attr "length" "4")])
6123
6124(define_insn "addsf3"
6125  [(set (match_operand:SF 0 "register_operand" "=f")
6126	(plus:SF (match_operand:SF 1 "register_operand" "f")
6127		 (match_operand:SF 2 "register_operand" "f")))]
6128  "! TARGET_SOFT_FLOAT"
6129  "fadd,sgl %1,%2,%0"
6130  [(set_attr "type" "fpalu")
6131   (set_attr "pa_combine_type" "faddsub")
6132   (set_attr "length" "4")])
6133
6134(define_insn "subdf3"
6135  [(set (match_operand:DF 0 "register_operand" "=f")
6136	(minus:DF (match_operand:DF 1 "register_operand" "f")
6137		  (match_operand:DF 2 "register_operand" "f")))]
6138  "! TARGET_SOFT_FLOAT"
6139  "fsub,dbl %1,%2,%0"
6140  [(set_attr "type" "fpalu")
6141   (set_attr "pa_combine_type" "faddsub")
6142   (set_attr "length" "4")])
6143
6144(define_insn "subsf3"
6145  [(set (match_operand:SF 0 "register_operand" "=f")
6146	(minus:SF (match_operand:SF 1 "register_operand" "f")
6147		  (match_operand:SF 2 "register_operand" "f")))]
6148  "! TARGET_SOFT_FLOAT"
6149  "fsub,sgl %1,%2,%0"
6150  [(set_attr "type" "fpalu")
6151   (set_attr "pa_combine_type" "faddsub")
6152   (set_attr "length" "4")])
6153
6154(define_insn "muldf3"
6155  [(set (match_operand:DF 0 "register_operand" "=f")
6156	(mult:DF (match_operand:DF 1 "register_operand" "f")
6157		 (match_operand:DF 2 "register_operand" "f")))]
6158  "! TARGET_SOFT_FLOAT"
6159  "fmpy,dbl %1,%2,%0"
6160  [(set_attr "type" "fpmuldbl")
6161   (set_attr "pa_combine_type" "fmpy")
6162   (set_attr "length" "4")])
6163
6164(define_insn "mulsf3"
6165  [(set (match_operand:SF 0 "register_operand" "=f")
6166	(mult:SF (match_operand:SF 1 "register_operand" "f")
6167		 (match_operand:SF 2 "register_operand" "f")))]
6168  "! TARGET_SOFT_FLOAT"
6169  "fmpy,sgl %1,%2,%0"
6170  [(set_attr "type" "fpmulsgl")
6171   (set_attr "pa_combine_type" "fmpy")
6172   (set_attr "length" "4")])
6173
6174(define_insn "divdf3"
6175  [(set (match_operand:DF 0 "register_operand" "=f")
6176	(div:DF (match_operand:DF 1 "register_operand" "f")
6177		(match_operand:DF 2 "register_operand" "f")))]
6178  "! TARGET_SOFT_FLOAT"
6179  "fdiv,dbl %1,%2,%0"
6180  [(set_attr "type" "fpdivdbl")
6181   (set_attr "length" "4")])
6182
6183(define_insn "divsf3"
6184  [(set (match_operand:SF 0 "register_operand" "=f")
6185	(div:SF (match_operand:SF 1 "register_operand" "f")
6186		(match_operand:SF 2 "register_operand" "f")))]
6187  "! TARGET_SOFT_FLOAT"
6188  "fdiv,sgl %1,%2,%0"
6189  [(set_attr "type" "fpdivsgl")
6190   (set_attr "length" "4")])
6191
6192;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6193;; negation can be done by subtracting from plus zero.  However, this
6194;; violates the IEEE standard when negating plus and minus zero.
6195;; The slow path toggles the sign bit in the general registers.
6196(define_expand "negdf2"
6197  [(set (match_operand:DF 0 "register_operand" "")
6198	(neg:DF (match_operand:DF 1 "register_operand" "")))]
6199  "!TARGET_SOFT_FLOAT"
6200{
6201  if (TARGET_PA_20 || !flag_signed_zeros)
6202    emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6203  else
6204    emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6205  DONE;
6206})
6207
6208(define_insn "negdf2_slow"
6209  [(set (match_operand:DF 0 "register_operand" "=r")
6210	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
6211  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6212  "*
6213{
6214  if (rtx_equal_p (operands[0], operands[1]))
6215    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6216  else
6217    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6218}"
6219  [(set_attr "type" "multi")
6220   (set (attr "length")
6221	(if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6222	    (const_int 12)
6223	    (const_int 16)))])
6224
6225(define_insn "negdf2_fast"
6226  [(set (match_operand:DF 0 "register_operand" "=f")
6227	(neg:DF (match_operand:DF 1 "register_operand" "f")))]
6228  "!TARGET_SOFT_FLOAT"
6229  "*
6230{
6231  if (TARGET_PA_20)
6232    return \"fneg,dbl %1,%0\";
6233  else
6234    return \"fsub,dbl %%fr0,%1,%0\";
6235}"
6236  [(set_attr "type" "fpalu")
6237   (set_attr "length" "4")])
6238
6239(define_expand "negsf2"
6240  [(set (match_operand:SF 0 "register_operand" "")
6241	(neg:SF (match_operand:SF 1 "register_operand" "")))]
6242  "!TARGET_SOFT_FLOAT"
6243{
6244  if (TARGET_PA_20 || !flag_signed_zeros)
6245    emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6246  else
6247    emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6248  DONE;
6249})
6250
6251(define_insn "negsf2_slow"
6252  [(set (match_operand:SF 0 "register_operand" "=r")
6253	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
6254  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6255  "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6256  [(set_attr "type" "multi")
6257   (set_attr "length" "12")])
6258
6259(define_insn "negsf2_fast"
6260  [(set (match_operand:SF 0 "register_operand" "=f")
6261	(neg:SF (match_operand:SF 1 "register_operand" "f")))]
6262  "!TARGET_SOFT_FLOAT"
6263  "*
6264{
6265  if (TARGET_PA_20)
6266    return \"fneg,sgl %1,%0\";
6267  else
6268    return \"fsub,sgl %%fr0,%1,%0\";
6269}"
6270  [(set_attr "type" "fpalu")
6271   (set_attr "length" "4")])
6272
6273(define_insn "absdf2"
6274  [(set (match_operand:DF 0 "register_operand" "=f")
6275	(abs:DF (match_operand:DF 1 "register_operand" "f")))]
6276  "! TARGET_SOFT_FLOAT"
6277  "fabs,dbl %1,%0"
6278  [(set_attr "type" "fpalu")
6279   (set_attr "length" "4")])
6280
6281(define_insn "abssf2"
6282  [(set (match_operand:SF 0 "register_operand" "=f")
6283	(abs:SF (match_operand:SF 1 "register_operand" "f")))]
6284  "! TARGET_SOFT_FLOAT"
6285  "fabs,sgl %1,%0"
6286  [(set_attr "type" "fpalu")
6287   (set_attr "length" "4")])
6288
6289(define_insn "sqrtdf2"
6290  [(set (match_operand:DF 0 "register_operand" "=f")
6291	(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6292  "! TARGET_SOFT_FLOAT"
6293  "fsqrt,dbl %1,%0"
6294  [(set_attr "type" "fpsqrtdbl")
6295   (set_attr "length" "4")])
6296
6297(define_insn "sqrtsf2"
6298  [(set (match_operand:SF 0 "register_operand" "=f")
6299	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6300  "! TARGET_SOFT_FLOAT"
6301  "fsqrt,sgl %1,%0"
6302  [(set_attr "type" "fpsqrtsgl")
6303   (set_attr "length" "4")])
6304
6305;; PA 2.0 floating point instructions
6306
6307; fmpyfadd patterns
6308(define_insn "fmadf4"
6309  [(set (match_operand:DF 0 "register_operand" "=f")
6310	(fma:DF (match_operand:DF 1 "register_operand" "f")
6311		(match_operand:DF 2 "register_operand" "f")
6312		(match_operand:DF 3 "register_operand" "f")))]
6313  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6314  "fmpyfadd,dbl %1,%2,%3,%0"
6315  [(set_attr "type" "fpmuldbl")
6316   (set_attr "length" "4")])
6317
6318(define_insn "fmasf4"
6319  [(set (match_operand:SF 0 "register_operand" "=f")
6320	(fma:SF (match_operand:SF 1 "register_operand" "f")
6321		(match_operand:SF 2 "register_operand" "f")
6322		(match_operand:SF 3 "register_operand" "f")))]
6323  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6324  "fmpyfadd,sgl %1,%2,%3,%0"
6325  [(set_attr "type" "fpmulsgl")
6326   (set_attr "length" "4")])
6327
6328; fmpynfadd patterns
6329(define_insn "fnmadf4"
6330  [(set (match_operand:DF 0 "register_operand" "=f")
6331	(fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6332		(match_operand:DF 2 "register_operand" "f")
6333		(match_operand:DF 3 "register_operand" "f")))]
6334  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6335  "fmpynfadd,dbl %1,%2,%3,%0"
6336  [(set_attr "type" "fpmuldbl")
6337   (set_attr "length" "4")])
6338
6339(define_insn "fnmasf4"
6340  [(set (match_operand:SF 0 "register_operand" "=f")
6341	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6342		(match_operand:SF 2 "register_operand" "f")
6343		(match_operand:SF 3 "register_operand" "f")))]
6344  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6345  "fmpynfadd,sgl %1,%2,%3,%0"
6346  [(set_attr "type" "fpmulsgl")
6347   (set_attr "length" "4")])
6348
6349; fnegabs patterns
6350(define_insn ""
6351  [(set (match_operand:DF 0 "register_operand" "=f")
6352	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6353  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6354  "fnegabs,dbl %1,%0"
6355  [(set_attr "type" "fpalu")
6356   (set_attr "length" "4")])
6357
6358(define_insn ""
6359  [(set (match_operand:SF 0 "register_operand" "=f")
6360	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6361  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6362  "fnegabs,sgl %1,%0"
6363  [(set_attr "type" "fpalu")
6364   (set_attr "length" "4")])
6365
6366(define_insn ""
6367  [(set (match_operand:DF 0 "register_operand" "=f")
6368	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6369   (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6370  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6371    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6372  "#"
6373  [(set_attr "type" "fpalu")
6374   (set_attr "length" "8")])
6375
6376(define_split
6377  [(set (match_operand:DF 0 "register_operand" "")
6378	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6379   (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6380  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6381  [(set (match_dup 2) (abs:DF (match_dup 1)))
6382   (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6383  "")
6384
6385(define_insn ""
6386  [(set (match_operand:SF 0 "register_operand" "=f")
6387	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6388   (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6389  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6390    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6391  "#"
6392  [(set_attr "type" "fpalu")
6393   (set_attr "length" "8")])
6394
6395(define_split
6396  [(set (match_operand:SF 0 "register_operand" "")
6397	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6398   (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6399  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6400  [(set (match_dup 2) (abs:SF (match_dup 1)))
6401   (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6402  "")
6403
6404;; Negating a multiply can be faked by adding zero in a fused multiply-add
6405;; instruction if we can ignore the sign of zero.
6406(define_insn ""
6407  [(set (match_operand:DF 0 "register_operand" "=f")
6408	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6409			 (match_operand:DF 2 "register_operand" "f"))))]
6410  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6411  "fmpynfadd,dbl %1,%2,%%fr0,%0"
6412  [(set_attr "type" "fpmuldbl")
6413   (set_attr "length" "4")])
6414
6415(define_insn ""
6416  [(set (match_operand:SF 0 "register_operand" "=f")
6417	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6418			 (match_operand:SF 2 "register_operand" "f"))))]
6419  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6420  "fmpynfadd,sgl %1,%2,%%fr0,%0"
6421  [(set_attr "type" "fpmuldbl")
6422   (set_attr "length" "4")])
6423
6424(define_insn ""
6425  [(set (match_operand:DF 0 "register_operand" "=f")
6426	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6427			 (match_operand:DF 2 "register_operand" "f"))))
6428   (set (match_operand:DF 3 "register_operand" "=&f")
6429	(mult:DF (match_dup 1) (match_dup 2)))]
6430  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6431    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6432          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6433  "#"
6434  [(set_attr "type" "fpmuldbl")
6435   (set_attr "length" "8")])
6436
6437(define_split
6438  [(set (match_operand:DF 0 "register_operand" "")
6439	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6440			 (match_operand:DF 2 "register_operand" ""))))
6441   (set (match_operand:DF 3 "register_operand" "")
6442	(mult:DF (match_dup 1) (match_dup 2)))]
6443  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6444  [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6445   (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6446  "")
6447
6448(define_insn ""
6449  [(set (match_operand:SF 0 "register_operand" "=f")
6450	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6451			 (match_operand:SF 2 "register_operand" "f"))))
6452   (set (match_operand:SF 3 "register_operand" "=&f")
6453	(mult:SF (match_dup 1) (match_dup 2)))]
6454  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6455    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6456          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6457  "#"
6458  [(set_attr "type" "fpmuldbl")
6459   (set_attr "length" "8")])
6460
6461(define_split
6462  [(set (match_operand:SF 0 "register_operand" "")
6463	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6464			 (match_operand:SF 2 "register_operand" ""))))
6465   (set (match_operand:SF 3 "register_operand" "")
6466	(mult:SF (match_dup 1) (match_dup 2)))]
6467  "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6468  [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6469   (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6470  "")
6471
6472;;- Shift instructions
6473
6474;; Optimized special case of shifting.
6475
6476(define_insn ""
6477  [(set (match_operand:SI 0 "register_operand" "=r")
6478	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6479		     (const_int 24)))]
6480  ""
6481  "ldb%M1 %1,%0"
6482  [(set_attr "type" "load")
6483   (set_attr "length" "4")])
6484
6485(define_insn ""
6486  [(set (match_operand:SI 0 "register_operand" "=r")
6487	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6488		     (const_int 16)))]
6489  ""
6490  "ldh%M1 %1,%0"
6491  [(set_attr "type" "load")
6492   (set_attr "length" "4")])
6493
6494(define_insn ""
6495  [(set (match_operand:SI 0 "register_operand" "=r")
6496	(plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6497			    (match_operand:SI 3 "shadd_operand" ""))
6498		 (match_operand:SI 1 "register_operand" "r")))]
6499  ""
6500  "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6501  [(set_attr "type" "binary")
6502   (set_attr "length" "4")])
6503
6504(define_insn ""
6505  [(set (match_operand:SI 0 "register_operand" "=r")
6506	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6507			  (match_operand:SI 3 "mem_shadd_operand" ""))
6508		 (match_operand:SI 1 "register_operand" "r")))]
6509  ""
6510  "*
6511{
6512  int shift_val = exact_log2 (INTVAL (operands[3]));
6513  operands[3] = GEN_INT (shift_val);
6514  return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6515}"
6516  [(set_attr "type" "binary")
6517   (set_attr "length" "4")])
6518
6519(define_insn ""
6520  [(set (match_operand:DI 0 "register_operand" "=r")
6521	(plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6522			    (match_operand:DI 3 "shadd_operand" ""))
6523		 (match_operand:DI 1 "register_operand" "r")))]
6524  "TARGET_64BIT"
6525  "shladd,l %2,%o3,%1,%0"
6526  [(set_attr "type" "binary")
6527   (set_attr "length" "4")])
6528
6529(define_insn ""
6530  [(set (match_operand:DI 0 "register_operand" "=r")
6531	(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6532			  (match_operand:DI 3 "mem_shadd_operand" ""))
6533		 (match_operand:DI 1 "register_operand" "r")))]
6534  "TARGET_64BIT"
6535  "*
6536{
6537  int shift_val = exact_log2 (INTVAL (operands[3]));
6538  operands[3] = GEN_INT (shift_val);
6539  return \"shladd,l %2,%o3,%1,%0\";
6540}"
6541  [(set_attr "type" "binary")
6542   (set_attr "length" "4")])
6543
6544(define_expand "ashlsi3"
6545  [(set (match_operand:SI 0 "register_operand" "")
6546	(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6547		   (match_operand:SI 2 "arith32_operand" "")))]
6548  ""
6549  "
6550{
6551  if (GET_CODE (operands[2]) != CONST_INT)
6552    {
6553      rtx temp = gen_reg_rtx (SImode);
6554      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6555      if (GET_CODE (operands[1]) == CONST_INT)
6556	emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6557      else
6558	emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6559      DONE;
6560    }
6561  /* Make sure both inputs are not constants,
6562     there are no patterns for that.  */
6563  operands[1] = force_reg (SImode, operands[1]);
6564}")
6565
6566(define_insn ""
6567  [(set (match_operand:SI 0 "register_operand" "=r")
6568	(ashift:SI (match_operand:SI 1 "register_operand" "r")
6569		   (match_operand:SI 2 "const_int_operand" "n")))]
6570  ""
6571  "{zdep|depw,z} %1,%P2,%L2,%0"
6572  [(set_attr "type" "shift")
6573   (set_attr "length" "4")])
6574
6575; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6576; Doing it like this makes slightly better code since reload can
6577; replace a register with a known value in range -16..15 with a
6578; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6579; but since we have no more CONST_OK... characters, that is not
6580; possible.
6581(define_insn "zvdep32"
6582  [(set (match_operand:SI 0 "register_operand" "=r,r")
6583	(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6584		   (minus:SI (const_int 31)
6585			     (match_operand:SI 2 "register_operand" "q,q"))))]
6586  ""
6587  "@
6588   {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6589   {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6590  [(set_attr "type" "shift,shift")
6591   (set_attr "length" "4,4")])
6592
6593(define_insn "zvdep_imm32"
6594  [(set (match_operand:SI 0 "register_operand" "=r")
6595	(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6596		   (minus:SI (const_int 31)
6597			     (match_operand:SI 2 "register_operand" "q"))))]
6598  ""
6599  "*
6600{
6601  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6602  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6603  operands[1] = GEN_INT ((x & 0xf) - 0x10);
6604  return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6605}"
6606  [(set_attr "type" "shift")
6607   (set_attr "length" "4")])
6608
6609(define_insn "vdepi_ior"
6610  [(set (match_operand:SI 0 "register_operand" "=r")
6611	(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6612			   (minus:SI (const_int 31)
6613				     (match_operand:SI 2 "register_operand" "q")))
6614		(match_operand:SI 3 "register_operand" "0")))]
6615  ; accept ...0001...1, can this be generalized?
6616  "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6617  "*
6618{
6619  HOST_WIDE_INT x = INTVAL (operands[1]);
6620  operands[2] = GEN_INT (exact_log2 (x + 1));
6621  return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6622}"
6623  [(set_attr "type" "shift")
6624   (set_attr "length" "4")])
6625
6626(define_insn "vdepi_and"
6627  [(set (match_operand:SI 0 "register_operand" "=r")
6628	(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6629			   (minus:SI (const_int 31)
6630				     (match_operand:SI 2 "register_operand" "q")))
6631		(match_operand:SI 3 "register_operand" "0")))]
6632  ; this can be generalized...!
6633  "INTVAL (operands[1]) == -2"
6634  "*
6635{
6636  HOST_WIDE_INT x = INTVAL (operands[1]);
6637  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6638  return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6639}"
6640  [(set_attr "type" "shift")
6641   (set_attr "length" "4")])
6642
6643(define_expand "ashldi3"
6644  [(set (match_operand:DI 0 "register_operand" "")
6645	(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6646		   (match_operand:DI 2 "arith32_operand" "")))]
6647  ""
6648  "
6649{
6650  if (!TARGET_64BIT)
6651    {
6652      if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6653	{
6654	  unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6655	  if (shift >= 1 && shift <= 31)
6656	    {
6657	      rtx dst = operands[0];
6658	      rtx src = force_reg (DImode, operands[1]);
6659	      emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6660					   gen_lowpart (SImode, src),
6661					   GEN_INT (32-shift),
6662					   gen_highpart (SImode, src),
6663					   GEN_INT (shift)));
6664	      emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6665				      gen_lowpart (SImode, src),
6666				      GEN_INT (shift)));
6667	      DONE;
6668	    }
6669	}
6670      /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6671      FAIL;
6672    }
6673  if (GET_CODE (operands[2]) != CONST_INT)
6674    {
6675      rtx temp = gen_reg_rtx (DImode);
6676      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6677      if (GET_CODE (operands[1]) == CONST_INT)
6678	emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6679      else
6680	emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6681      DONE;
6682    }
6683  /* Make sure both inputs are not constants,
6684     there are no patterns for that.  */
6685  operands[1] = force_reg (DImode, operands[1]);
6686}")
6687
6688(define_expand "ashlti3"
6689  [(set (match_operand:TI 0 "register_operand" "")
6690	(ashift:TI (match_operand:TI 1 "lhs_lshift_operand" "")
6691		   (match_operand:TI 2 "arith32_operand" "")))]
6692  "TARGET_64BIT"
6693{
6694  if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6695    {
6696      unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6697      rtx dst = operands[0];
6698      rtx src = force_reg (TImode, operands[1]);
6699      if (shift >= 1 && shift <= 63)
6700	{
6701	  emit_insn (gen_shrpd_internal (gen_highpart (DImode, dst),
6702					 gen_lowpart (DImode, src),
6703					 GEN_INT (64-shift),
6704					 gen_highpart (DImode, src),
6705					 GEN_INT (shift)));
6706	  emit_insn (gen_ashldi3 (gen_lowpart (DImode, dst),
6707				  gen_lowpart (DImode, src),
6708				  GEN_INT (shift)));
6709	  DONE;
6710	}
6711      else if (shift >= 64 && shift <= 127)
6712	{
6713	  emit_insn (gen_ashldi3 (gen_highpart (DImode, dst),
6714				  gen_lowpart (DImode, src),
6715				  GEN_INT (shift - 64)));
6716	  emit_move_insn (gen_lowpart (DImode, dst), GEN_INT (0));
6717	  DONE;
6718	}
6719    }
6720  /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6721  FAIL;
6722})
6723
6724(define_insn ""
6725  [(set (match_operand:DI 0 "register_operand" "=r")
6726	(ashift:DI (match_operand:DI 1 "register_operand" "r")
6727		   (match_operand:DI 2 "const_int_operand" "n")))]
6728  "TARGET_64BIT"
6729  "depd,z %1,%p2,%Q2,%0"
6730  [(set_attr "type" "shift")
6731   (set_attr "length" "4")])
6732
6733; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6734; Doing it like this makes slightly better code since reload can
6735; replace a register with a known value in range -16..15 with a
6736; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6737; but since we have no more CONST_OK... characters, that is not
6738; possible.
6739(define_insn "zvdep64"
6740  [(set (match_operand:DI 0 "register_operand" "=r,r")
6741	(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6742		   (minus:DI (const_int 63)
6743			     (match_operand:DI 2 "register_operand" "q,q"))))]
6744  "TARGET_64BIT"
6745  "@
6746   depd,z %1,%%sar,64,%0
6747   depdi,z %1,%%sar,64,%0"
6748  [(set_attr "type" "shift,shift")
6749   (set_attr "length" "4,4")])
6750
6751(define_insn "zvdep_imm64"
6752  [(set (match_operand:DI 0 "register_operand" "=r")
6753	(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6754		   (minus:DI (const_int 63)
6755			     (match_operand:DI 2 "register_operand" "q"))))]
6756  "TARGET_64BIT"
6757  "*
6758{
6759  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6760  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6761  operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6762  return \"depdi,z %1,%%sar,%2,%0\";
6763}"
6764  [(set_attr "type" "shift")
6765   (set_attr "length" "4")])
6766
6767(define_insn ""
6768  [(set (match_operand:DI 0 "register_operand" "=r")
6769	(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6770			   (minus:DI (const_int 63)
6771				     (match_operand:DI 2 "register_operand" "q")))
6772		(match_operand:DI 3 "register_operand" "0")))]
6773  ; accept ...0001...1, can this be generalized?
6774  "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6775  "*
6776{
6777  HOST_WIDE_INT x = INTVAL (operands[1]);
6778  operands[2] = GEN_INT (exact_log2 (x + 1));
6779  return \"depdi -1,%%sar,%2,%0\";
6780}"
6781  [(set_attr "type" "shift")
6782   (set_attr "length" "4")])
6783
6784(define_insn ""
6785  [(set (match_operand:DI 0 "register_operand" "=r")
6786	(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6787			   (minus:DI (const_int 63)
6788				     (match_operand:DI 2 "register_operand" "q")))
6789		(match_operand:DI 3 "register_operand" "0")))]
6790  ; this can be generalized...!
6791  "TARGET_64BIT && INTVAL (operands[1]) == -2"
6792  "*
6793{
6794  HOST_WIDE_INT x = INTVAL (operands[1]);
6795  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6796  return \"depdi 0,%%sar,%2,%0\";
6797}"
6798  [(set_attr "type" "shift")
6799   (set_attr "length" "4")])
6800
6801(define_expand "ashrsi3"
6802  [(set (match_operand:SI 0 "register_operand" "")
6803	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6804		     (match_operand:SI 2 "arith32_operand" "")))]
6805  ""
6806  "
6807{
6808  if (GET_CODE (operands[2]) != CONST_INT)
6809    {
6810      rtx temp = gen_reg_rtx (SImode);
6811      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6812      emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6813      DONE;
6814    }
6815}")
6816
6817(define_insn ""
6818  [(set (match_operand:SI 0 "register_operand" "=r")
6819	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6820		     (match_operand:SI 2 "const_int_operand" "n")))]
6821  ""
6822  "{extrs|extrw,s} %1,%P2,%L2,%0"
6823  [(set_attr "type" "shift")
6824   (set_attr "length" "4")])
6825
6826(define_insn "vextrs32"
6827  [(set (match_operand:SI 0 "register_operand" "=r")
6828	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6829		     (minus:SI (const_int 31)
6830			       (match_operand:SI 2 "register_operand" "q"))))]
6831  ""
6832  "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6833  [(set_attr "type" "shift")
6834   (set_attr "length" "4")])
6835
6836(define_expand "ashrdi3"
6837  [(set (match_operand:DI 0 "register_operand" "")
6838	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6839		     (match_operand:DI 2 "arith32_operand" "")))]
6840  "TARGET_64BIT"
6841  "
6842{
6843  if (GET_CODE (operands[2]) != CONST_INT)
6844    {
6845      rtx temp = gen_reg_rtx (DImode);
6846      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6847      emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6848      DONE;
6849    }
6850}")
6851
6852(define_insn ""
6853  [(set (match_operand:DI 0 "register_operand" "=r")
6854	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6855		     (match_operand:DI 2 "const_int_operand" "n")))]
6856  "TARGET_64BIT"
6857  "extrd,s %1,%p2,%Q2,%0"
6858  [(set_attr "type" "shift")
6859   (set_attr "length" "4")])
6860
6861(define_insn "vextrs64"
6862  [(set (match_operand:DI 0 "register_operand" "=r")
6863	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6864		     (minus:DI (const_int 63)
6865			       (match_operand:DI 2 "register_operand" "q"))))]
6866  "TARGET_64BIT"
6867  "extrd,s %1,%%sar,64,%0"
6868  [(set_attr "type" "shift")
6869   (set_attr "length" "4")])
6870
6871(define_insn "lshrsi3"
6872  [(set (match_operand:SI 0 "register_operand" "=r,r")
6873	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6874		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6875  ""
6876  "@
6877   {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6878   {extru|extrw,u} %1,%P2,%L2,%0"
6879  [(set_attr "type" "shift")
6880   (set_attr "length" "4")])
6881
6882(define_insn "lshrdi3"
6883  [(set (match_operand:DI 0 "register_operand" "=r,r")
6884	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6885		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6886  "TARGET_64BIT"
6887  "@
6888   shrpd %%r0,%1,%%sar,%0
6889   extrd,u %1,%p2,%Q2,%0"
6890  [(set_attr "type" "shift")
6891   (set_attr "length" "4")])
6892
6893; Shift right pair word 0 to 31 bits.
6894(define_insn "*shrpsi4_1"
6895  [(set (match_operand:SI 0 "register_operand" "=r")
6896	(match_operator:SI 4 "plus_xor_ior_operator"
6897	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6898		      (minus:SI (const_int 32)
6899				(match_operand:SI 3 "register_operand" "q")))
6900	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6901			(match_dup 3))]))]
6902  ""
6903  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6904  [(set_attr "type" "shift")
6905   (set_attr "length" "4")])
6906
6907(define_insn "*shrpsi4_2"
6908  [(set (match_operand:SI 0 "register_operand" "=r")
6909	(match_operator:SI 4 "plus_xor_ior_operator"
6910	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6911			(match_operand:SI 3 "register_operand" "q"))
6912	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6913		      (minus:SI (const_int 32)
6914				(match_dup 3)))]))]
6915  ""
6916  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6917  [(set_attr "type" "shift")
6918   (set_attr "length" "4")])
6919
6920; Shift right pair doubleword 0 to 63 bits.
6921(define_insn "*shrpdi4_1"
6922  [(set (match_operand:DI 0 "register_operand" "=r")
6923	(match_operator:DI 4 "plus_xor_ior_operator"
6924	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6925		      (minus:DI (const_int 64)
6926				(match_operand:DI 3 "register_operand" "q")))
6927	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6928			(match_dup 3))]))]
6929  "TARGET_64BIT"
6930  "shrpd %1,%2,%%sar,%0"
6931  [(set_attr "type" "shift")
6932   (set_attr "length" "4")])
6933
6934(define_insn "*shrpdi4_2"
6935  [(set (match_operand:DI 0 "register_operand" "=r")
6936	(match_operator:DI 4 "plus_xor_ior_operator"
6937	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6938			(match_operand:DI 3 "shift6_operand" "q"))
6939	   (ashift:DI (match_operand:SI 1 "register_operand" "r")
6940		      (minus:DI (const_int 64)
6941				(match_dup 3)))]))]
6942  "TARGET_64BIT"
6943  "shrpd %1,%2,%%sar,%0"
6944  [(set_attr "type" "shift")
6945   (set_attr "length" "4")])
6946
6947(define_insn "*shrpdi4_3"
6948  [(set (match_operand:DI 0 "register_operand" "=r")
6949	(match_operator:DI 5 "plus_xor_ior_operator"
6950	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6951		      (match_operand:DI 3 "const_int_operand" "n"))
6952	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6953			(match_operand:DI 4 "const_int_operand" "n"))]))]
6954  "TARGET_64BIT
6955   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6956  "shrpd %1,%2,%4,%0"
6957  [(set_attr "type" "shift")
6958   (set_attr "length" "4")])
6959
6960(define_insn "*shrpdi4_4"
6961  [(set (match_operand:DI 0 "register_operand" "=r")
6962	(match_operator:DI 5 "plus_xor_ior_operator"
6963	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6964			(match_operand:DI 4 "const_int_operand" "n"))
6965	   (ashift:DI (match_operand:DI 1 "register_operand" "r")
6966		      (match_operand:DI 3 "const_int_operand" "n"))]))]
6967  "TARGET_64BIT
6968   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6969  "shrpd %1,%2,%4,%0"
6970  [(set_attr "type" "shift")
6971   (set_attr "length" "4")])
6972
6973(define_insn "rotrsi3"
6974  [(set (match_operand:SI 0 "register_operand" "=r,r")
6975	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6976		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6977  ""
6978  "*
6979{
6980  if (GET_CODE (operands[2]) == CONST_INT)
6981    {
6982      operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6983      return \"{shd|shrpw} %1,%1,%2,%0\";
6984    }
6985  else
6986    return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6987}"
6988  [(set_attr "type" "shift")
6989   (set_attr "length" "4")])
6990
6991(define_expand "rotlsi3"
6992  [(set (match_operand:SI 0 "register_operand" "")
6993        (rotate:SI (match_operand:SI 1 "register_operand" "")
6994                   (match_operand:SI 2 "arith32_operand" "")))]
6995  ""
6996  "
6997{
6998  if (GET_CODE (operands[2]) != CONST_INT)
6999    {
7000      rtx temp = gen_reg_rtx (SImode);
7001      emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
7002      emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
7003      DONE;
7004    }
7005  /* Else expand normally.  */
7006}")
7007
7008(define_insn "*rotlsi3_internal"
7009  [(set (match_operand:SI 0 "register_operand" "=r")
7010        (rotate:SI (match_operand:SI 1 "register_operand" "r")
7011                   (match_operand:SI 2 "const_int_operand" "n")))]
7012  ""
7013  "*
7014{
7015  operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
7016  return \"{shd|shrpw} %1,%1,%2,%0\";
7017}"
7018  [(set_attr "type" "shift")
7019   (set_attr "length" "4")])
7020
7021(define_insn "rotrdi3"
7022  [(set (match_operand:DI 0 "register_operand" "=r,r")
7023	(rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
7024		     (match_operand:DI 2 "shift6_operand" "q,n")))]
7025  "TARGET_64BIT"
7026  "*
7027{
7028  if (GET_CODE (operands[2]) == CONST_INT)
7029    {
7030      operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
7031      return \"shrpd %1,%1,%2,%0\";
7032    }
7033  else
7034    return \"shrpd %1,%1,%%sar,%0\";
7035}"
7036  [(set_attr "type" "shift")
7037   (set_attr "length" "4")])
7038
7039(define_expand "rotldi3"
7040  [(set (match_operand:DI 0 "register_operand" "")
7041        (rotate:DI (match_operand:DI 1 "register_operand" "")
7042                   (match_operand:DI 2 "arith32_operand" "")))]
7043  "TARGET_64BIT"
7044  "
7045{
7046  if (GET_CODE (operands[2]) != CONST_INT)
7047    {
7048      rtx temp = gen_reg_rtx (DImode);
7049      emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
7050      emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
7051      DONE;
7052    }
7053  /* Else expand normally.  */
7054}")
7055
7056(define_insn "*rotldi3_internal"
7057  [(set (match_operand:DI 0 "register_operand" "=r")
7058        (rotate:DI (match_operand:DI 1 "register_operand" "r")
7059                   (match_operand:DI 2 "const_int_operand" "n")))]
7060  "TARGET_64BIT"
7061  "*
7062{
7063  operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
7064  return \"shrpd %1,%1,%2,%0\";
7065}"
7066  [(set_attr "type" "shift")
7067   (set_attr "length" "4")])
7068
7069(define_insn ""
7070  [(set (match_operand:SI 0 "register_operand" "=r")
7071	(match_operator:SI 5 "plus_xor_ior_operator"
7072	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
7073		      (match_operand:SI 3 "const_int_operand" "n"))
7074	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7075			(match_operand:SI 4 "const_int_operand" "n"))]))]
7076  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7077  "{shd|shrpw} %1,%2,%4,%0"
7078  [(set_attr "type" "shift")
7079   (set_attr "length" "4")])
7080
7081(define_insn ""
7082  [(set (match_operand:SI 0 "register_operand" "=r")
7083	(match_operator:SI 5 "plus_xor_ior_operator"
7084	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7085			(match_operand:SI 4 "const_int_operand" "n"))
7086	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
7087		      (match_operand:SI 3 "const_int_operand" "n"))]))]
7088  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7089  "{shd|shrpw} %1,%2,%4,%0"
7090  [(set_attr "type" "shift")
7091   (set_attr "length" "4")])
7092
7093(define_expand "shd_internal"
7094  [(set (match_operand:SI 0 "register_operand")
7095	(ior:SI
7096	  (lshiftrt:SI (match_operand:SI 1 "register_operand")
7097		       (match_operand:SI 2 "const_int_operand"))
7098	  (ashift:SI (match_operand:SI 3 "register_operand")
7099		     (match_operand:SI 4 "const_int_operand"))))]
7100  "")
7101
7102(define_expand "shrpd_internal"
7103  [(set (match_operand:DI 0 "register_operand")
7104	(ior:DI
7105	  (lshiftrt:DI (match_operand:DI 1 "register_operand")
7106		       (match_operand:DI 2 "const_int_operand"))
7107	  (ashift:DI (match_operand:DI 3 "register_operand")
7108		     (match_operand:DI 4 "const_int_operand"))))]
7109  "TARGET_64BIT")
7110
7111(define_insn ""
7112  [(set (match_operand:SI 0 "register_operand" "=r")
7113	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
7114			   (match_operand:SI 2 "const_int_operand" ""))
7115		(match_operand:SI 3 "const_int_operand" "")))]
7116  "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
7117  "*
7118{
7119  int cnt = INTVAL (operands[2]) & 31;
7120  operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
7121  operands[2] = GEN_INT (31 - cnt);
7122  return \"{zdep|depw,z} %1,%2,%3,%0\";
7123}"
7124  [(set_attr "type" "shift")
7125   (set_attr "length" "4")])
7126
7127;; Unconditional and other jump instructions.
7128
7129;; Trivial return used when no epilogue is needed.
7130(define_insn "return"
7131  [(return)
7132   (use (reg:SI 2))]
7133  "pa_can_use_return_insn ()"
7134  "*
7135{
7136  if (TARGET_PA_20)
7137    return \"bve%* (%%r2)\";
7138  return \"bv%* %%r0(%%r2)\";
7139}"
7140  [(set_attr "type" "branch")
7141   (set_attr "length" "4")])
7142
7143;; This is used for most returns.
7144(define_insn "return_internal"
7145  [(return)
7146   (use (reg:SI 2))]
7147  ""
7148  "*
7149{
7150  if (TARGET_PA_20)
7151    return \"bve%* (%%r2)\";
7152  return \"bv%* %%r0(%%r2)\";
7153}"
7154  [(set_attr "type" "branch")
7155   (set_attr "length" "4")])
7156
7157;; This is used for eh returns which bypass the return stub.
7158(define_insn "return_external_pic"
7159  [(return)
7160   (clobber (reg:SI 1))
7161   (use (reg:SI 2))]
7162  "!TARGET_NO_SPACE_REGS
7163   && !TARGET_PA_20
7164   && flag_pic && crtl->calls_eh_return"
7165  "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7166  [(set_attr "type" "branch")
7167   (set_attr "length" "12")])
7168
7169(define_expand "prologue"
7170  [(const_int 0)]
7171  ""
7172  "pa_expand_prologue ();DONE;")
7173
7174(define_expand "sibcall_epilogue"
7175  [(return)]
7176  ""
7177  "
7178{
7179  pa_expand_epilogue ();
7180  DONE;
7181}")
7182
7183(define_expand "epilogue"
7184  [(return)]
7185  ""
7186  "
7187{
7188  rtx x;
7189
7190  /* Try to use the trivial return first.  Else use the full epilogue.  */
7191  if (pa_can_use_return_insn ())
7192    x = gen_return ();
7193  else
7194    {
7195      pa_expand_epilogue ();
7196
7197      /* EH returns bypass the normal return stub.  Thus, we must do an
7198	 interspace branch to return from functions that call eh_return.
7199	 This is only a problem for returns from shared code on ports
7200	 using space registers.  */
7201      if (!TARGET_NO_SPACE_REGS
7202	  && !TARGET_PA_20
7203	  && flag_pic && crtl->calls_eh_return)
7204	x = gen_return_external_pic ();
7205      else
7206	x = gen_return_internal ();
7207    }
7208  emit_jump_insn (x);
7209  DONE;
7210}")
7211
7212; Used by hppa_profile_hook to load the starting address of the current
7213; function; operand 1 contains the address of the label in operand 3
7214(define_insn "load_offset_label_address"
7215  [(set (match_operand:SI 0 "register_operand" "=r")
7216        (plus:SI (match_operand:SI 1 "register_operand" "r")
7217		 (minus:SI (match_operand:SI 2 "" "")
7218			   (label_ref:SI (match_operand 3 "" "")))))]
7219  ""
7220  "ldo %2-%l3(%1),%0"
7221  [(set_attr "type" "multi")
7222   (set_attr "length" "4")])
7223
7224; Output a code label and load its address.
7225(define_insn "lcla1"
7226  [(set (match_operand:SI 0 "register_operand" "=r")
7227        (label_ref:SI (match_operand 1 "" "")))
7228   (const_int 0)]
7229  "!TARGET_PA_20"
7230  "*
7231{
7232  output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7233  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7234                                     CODE_LABEL_NUMBER (operands[1]));
7235  return \"\";
7236}"
7237  [(set_attr "type" "multi")
7238   (set_attr "length" "8")])
7239
7240(define_insn "lcla2"
7241  [(set (match_operand:SI 0 "register_operand" "=r")
7242        (label_ref:SI (match_operand 1 "" "")))
7243   (const_int 0)]
7244  "TARGET_PA_20"
7245  "*
7246{
7247  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7248                                     CODE_LABEL_NUMBER (operands[1]));
7249  return \"mfia %0\";
7250}"
7251  [(set_attr "type" "move")
7252   (set_attr "length" "4")])
7253
7254(define_insn "blockage"
7255  [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7256  ""
7257  ""
7258  [(set_attr "length" "0")])
7259
7260(define_insn "jump"
7261  [(set (pc) (label_ref (match_operand 0 "" "")))]
7262  ""
7263  "*
7264{
7265  /* An unconditional branch which can reach its target.  */
7266  if (get_attr_length (insn) < 16)
7267    return \"b%* %l0\";
7268
7269  return pa_output_lbranch (operands[0], insn, 1);
7270}"
7271  [(set_attr "type" "uncond_branch")
7272   (set_attr "pa_combine_type" "uncond_branch")
7273   (set (attr "length")
7274    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7275	       (const_int MAX_17BIT_OFFSET))
7276	   (const_int 4)
7277	   (match_test "TARGET_PORTABLE_RUNTIME")
7278	   (const_int 20)
7279	   (not (match_test "flag_pic"))
7280	   (const_int 16)]
7281	  (const_int 24)))])
7282
7283;;; Hope this is only within a function...
7284(define_insn "indirect_jump"
7285  [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7286  ""
7287  "bv%* %%r0(%0)"
7288  [(set_attr "type" "branch")
7289   (set_attr "length" "4")])
7290
7291;;; An indirect jump can be optimized to a direct jump.  GAS for the
7292;;; SOM target doesn't allow branching to a label inside a function.
7293;;; We also don't correctly compute branch distances for labels
7294;;; outside the current function.  Thus, we use an indirect jump can't
7295;;; be optimized to a direct jump for all targets.  We assume that
7296;;; the branch target is in the same space (i.e., nested function
7297;;; jumping to a label in an outer function in the same translation
7298;;; unit).
7299(define_expand "nonlocal_goto"
7300  [(use (match_operand 0 "general_operand" ""))
7301   (use (match_operand 1 "general_operand" ""))
7302   (use (match_operand 2 "general_operand" ""))
7303   (use (match_operand 3 "general_operand" ""))]
7304  ""
7305{
7306  rtx lab = operands[1];
7307  rtx stack = operands[2];
7308  rtx fp = operands[3];
7309
7310  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7311  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7312
7313  lab = copy_to_reg (lab);
7314
7315  /* Restore the stack and frame pointers.  */
7316  fp = copy_to_reg (fp);
7317  emit_stack_restore (SAVE_NONLOCAL, stack);
7318
7319  /* Ensure the frame pointer move is not optimized.  */
7320  emit_insn (gen_blockage ());
7321  emit_clobber (hard_frame_pointer_rtx);
7322  emit_clobber (frame_pointer_rtx);
7323  emit_move_insn (hard_frame_pointer_rtx, fp);
7324
7325  emit_use (hard_frame_pointer_rtx);
7326  emit_use (stack_pointer_rtx);
7327
7328  /* Nonlocal goto jumps are only used between functions in the same
7329     translation unit.  Thus, we can avoid the extra overhead of an
7330     interspace jump.  */
7331  emit_jump_insn (gen_indirect_goto (lab));
7332  emit_barrier ();
7333  DONE;
7334})
7335
7336(define_insn "indirect_goto"
7337  [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7338  "GET_MODE (operands[0]) == word_mode"
7339  "bv%* %%r0(%0)"
7340  [(set_attr "type" "branch")
7341   (set_attr "length" "4")])
7342
7343;; Subroutines of "casesi".
7344;; operand 0 is index
7345;; operand 1 is the minimum bound
7346;; operand 2 is the maximum bound - minimum bound + 1
7347;; operand 3 is CODE_LABEL for the table;
7348;; operand 4 is the CODE_LABEL to go to if index out of range.
7349
7350(define_expand "casesi"
7351  [(match_operand:SI 0 "general_operand" "")
7352   (match_operand:SI 1 "const_int_operand" "")
7353   (match_operand:SI 2 "const_int_operand" "")
7354   (match_operand 3 "" "")
7355   (match_operand 4 "" "")]
7356  ""
7357  "
7358{
7359  if (GET_CODE (operands[0]) != REG)
7360    operands[0] = force_reg (SImode, operands[0]);
7361
7362  if (operands[1] != const0_rtx)
7363    {
7364      rtx index = gen_reg_rtx (SImode);
7365
7366      operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7367      if (!INT_14_BITS (operands[1]))
7368	operands[1] = force_reg (SImode, operands[1]);
7369      emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7370      operands[0] = index;
7371    }
7372
7373  if (!INT_5_BITS (operands[2]))
7374    operands[2] = force_reg (SImode, operands[2]);
7375
7376  /* This branch prevents us finding an insn for the delay slot of the
7377     following vectored branch.  It might be possible to use the delay
7378     slot if an index value of -1 was used to transfer to the out-of-range
7379     label.  In order to do this, we would have to output the -1 vector
7380     element after the delay insn.  The casesi output code would have to
7381     check if the casesi insn is in a delay branch sequence and output
7382     the delay insn if one is found.  If this was done, then it might
7383     then be worthwhile to split the casesi patterns to improve scheduling.
7384     However, it's not clear that all this extra complexity is worth
7385     the effort.  */
7386  {
7387    rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7388    emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7389  }
7390
7391  /* In 64bit mode we must make sure to wipe the upper bits of the register
7392     just in case the addition overflowed or we had random bits in the
7393     high part of the register.  */
7394  if (TARGET_64BIT)
7395    {
7396      rtx index = gen_reg_rtx (DImode);
7397
7398      emit_insn (gen_extendsidi2 (index, operands[0]));
7399      operands[0] = index;
7400    }
7401
7402  if (TARGET_64BIT)
7403    emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7404  else if (flag_pic)
7405    emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7406  else
7407    emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7408  DONE;
7409}")
7410
7411;;; 32-bit code, absolute branch table.
7412(define_insn "casesi32"
7413  [(set (pc) (mem:SI (plus:SI
7414		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7415				(const_int 4))
7416		       (label_ref (match_operand 1 "" "")))))
7417   (clobber (match_scratch:SI 2 "=&r"))]
7418  "!flag_pic"
7419  "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7420  [(set_attr "type" "multi")
7421   (set_attr "length" "16")])
7422
7423;;; 32-bit code, relative branch table.
7424(define_insn "casesi32p"
7425  [(set (pc) (mem:SI (plus:SI
7426		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7427				(const_int 4))
7428		       (label_ref (match_operand 1 "" "")))))
7429   (clobber (match_scratch:SI 2 "=&r"))
7430   (clobber (match_scratch:SI 3 "=&r"))]
7431  "flag_pic"
7432  "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7433{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7434  [(set_attr "type" "multi")
7435   (set (attr "length")
7436     (if_then_else (match_test "TARGET_PA_20")
7437	(const_int 20)
7438	(const_int 24)))])
7439
7440;;; 64-bit code, 32-bit relative branch table.
7441(define_insn "casesi64p"
7442  [(set (pc) (mem:DI (plus:DI
7443		       (mult:DI (match_operand:DI 0 "register_operand" "r")
7444				(const_int 8))
7445		       (label_ref (match_operand 1 "" "")))))
7446   (clobber (match_scratch:DI 2 "=&r"))
7447   (clobber (match_scratch:DI 3 "=&r"))]
7448  ""
7449  "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7450add,l %2,%3,%3\;bv,n %%r0(%3)"
7451  [(set_attr "type" "multi")
7452   (set_attr "length" "24")])
7453
7454
7455;; Call patterns.
7456;;- jump to subroutine
7457
7458(define_expand "call"
7459  [(parallel [(call (match_operand:SI 0 "" "")
7460		    (match_operand 1 "" ""))
7461	      (clobber (reg:SI 2))])]
7462  ""
7463  "
7464{
7465  rtx op;
7466  rtx nb = operands[1];
7467
7468  if (TARGET_PORTABLE_RUNTIME)
7469    op = force_reg (SImode, XEXP (operands[0], 0));
7470  else
7471    {
7472      op = XEXP (operands[0], 0);
7473
7474      /* Generate indirect long calls to non-local functions. */
7475      if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7476	{
7477	  tree call_decl = SYMBOL_REF_DECL (op);
7478	  if (!(call_decl && targetm.binds_local_p (call_decl)))
7479	    op = force_reg (word_mode, op);
7480	}
7481    }
7482
7483  if (TARGET_64BIT)
7484    {
7485      if (!virtuals_instantiated)
7486	emit_move_insn (arg_pointer_rtx,
7487			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7488				      GEN_INT (64)));
7489      else
7490	{
7491	  /* The loop pass can generate new libcalls after the virtual
7492	     registers are instantiated when fpregs are disabled because
7493	     the only method that we have for doing DImode multiplication
7494	     is with a libcall.  This could be trouble if we haven't
7495	     allocated enough space for the outgoing arguments.  */
7496	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7497
7498	  emit_move_insn (arg_pointer_rtx,
7499			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7500					GEN_INT (STACK_POINTER_OFFSET + 64)));
7501	}
7502    }
7503
7504  /* Use two different patterns for calls to explicitly named functions
7505     and calls through function pointers.  This is necessary as these two
7506     types of calls use different calling conventions, and CSE might try
7507     to change the named call into an indirect call in some cases (using
7508     two patterns keeps CSE from performing this optimization).
7509
7510     We now use even more call patterns as there was a subtle bug in
7511     attempting to restore the pic register after a call using a simple
7512     move insn.  During reload, a instruction involving a pseudo register
7513     with no explicit dependence on the PIC register can be converted
7514     to an equivalent load from memory using the PIC register.  If we
7515     emit a simple move to restore the PIC register in the initial rtl
7516     generation, then it can potentially be repositioned during scheduling.
7517     and an instruction that eventually uses the PIC register may end up
7518     between the call and the PIC register restore.
7519
7520     This only worked because there is a post call group of instructions
7521     that are scheduled with the call.  These instructions are included
7522     in the same basic block as the call.  However, calls can throw in
7523     C++ code and a basic block has to terminate at the call if the call
7524     can throw.  This results in the PIC register restore being scheduled
7525     independently from the call.  So, we now hide the save and restore
7526     of the PIC register in the call pattern until after reload.  Then,
7527     we split the moves out.  A small side benefit is that we now don't
7528     need to have a use of the PIC register in the return pattern and
7529     the final save/restore operation is not needed.
7530
7531     I elected to just use register %r4 in the PIC patterns instead
7532     of trying to force hppa_pic_save_rtx () to a callee saved register.
7533     This might have required a new register class and constraint.  It
7534     was also simpler to just handle the restore from a register than a
7535     generic pseudo.  */
7536  if (TARGET_64BIT)
7537    {
7538      rtx r4 = gen_rtx_REG (word_mode, 4);
7539      if (GET_CODE (op) == SYMBOL_REF)
7540	emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7541      else
7542	{
7543	  op = force_reg (word_mode, op);
7544	  emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7545	}
7546    }
7547  else
7548    {
7549      if (GET_CODE (op) == SYMBOL_REF)
7550	{
7551	  if (flag_pic)
7552	    {
7553	      rtx r4 = gen_rtx_REG (word_mode, 4);
7554	      emit_call_insn (gen_call_symref_pic (op, nb, r4));
7555	    }
7556	  else
7557	    emit_call_insn (gen_call_symref (op, nb));
7558	}
7559      else
7560	{
7561	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7562	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7563	  if (flag_pic)
7564	    {
7565	      rtx r4 = gen_rtx_REG (word_mode, 4);
7566	      emit_call_insn (gen_call_reg_pic (nb, r4));
7567	    }
7568	  else
7569	    emit_call_insn (gen_call_reg (nb));
7570	}
7571    }
7572
7573  DONE;
7574}")
7575
7576;; We use function calls to set the attribute length of calls and millicode
7577;; calls.  This is necessary because of the large variety of call sequences.
7578;; Implementing the calculation in rtl is difficult as well as ugly.  As
7579;; we need the same calculation in several places, maintenance becomes a
7580;; nightmare.
7581;;
7582;; However, this has a subtle impact on branch shortening.  When the
7583;; expression used to set the length attribute of an instruction depends
7584;; on a relative address (e.g., pc or a branch address), genattrtab
7585;; notes that the insn's length is variable, and attempts to determine a
7586;; worst-case default length and code to compute an insn's current length.
7587
7588;; The use of a function call hides the variable dependence of our calls
7589;; and millicode calls.  The result is genattrtab doesn't treat the operation
7590;; as variable and it only generates code for the default case using our
7591;; function call.  Because of this, calls and millicode calls have a fixed
7592;; length in the branch shortening pass, and some branches will use a longer
7593;; code sequence than necessary.  However, the length of any given call
7594;; will still reflect its final code location and it may be shorter than
7595;; the initial length estimate.
7596
7597;; It's possible to trick genattrtab by adding an expression involving `pc'
7598;; in the set.  However, when genattrtab hits a function call in its attempt
7599;; to compute the default length, it marks the result as unknown and sets
7600;; the default result to MAX_INT ;-(  One possible fix that would allow
7601;; calls to participate in branch shortening would be to make the call to
7602;; insn_default_length a target option.  Then, we could massage unknown
7603;; results.  Another fix might be to change genattrtab so that it just does
7604;; the call in the variable case as it already does for the fixed case.
7605
7606(define_insn "call_symref"
7607  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7608	 (match_operand 1 "" "i"))
7609   (clobber (reg:SI 1))
7610   (clobber (reg:SI 2))
7611   (use (const_int 0))]
7612  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7613  "*
7614{
7615  pa_output_arg_descriptor (insn);
7616  return pa_output_call (insn, operands[0], 0);
7617}"
7618  [(set_attr "type" "call")
7619   (set (attr "length")
7620	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7621	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7622
7623(define_insn "call_symref_pic"
7624  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7625	 (match_operand 1 "" "i"))
7626   (clobber (reg:SI 1))
7627   (clobber (reg:SI 2))
7628   (clobber (match_operand 2))
7629   (use (reg:SI 19))
7630   (use (const_int 0))]
7631  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7632  "#")
7633
7634;; Split out the PIC register save and restore after reload.  As the
7635;; split is done after reload, there are some situations in which we
7636;; unnecessarily save and restore %r4.  This happens when there is a
7637;; single call and the PIC register is not used after the call.
7638;;
7639;; The split has to be done since call_from_call_insn () can't handle
7640;; the pattern as is.  Noreturn calls are special because they have to
7641;; terminate the basic block.  The split has to contain more than one
7642;; insn.
7643(define_split
7644  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7645		    (match_operand 1 "" ""))
7646	      (clobber (reg:SI 1))
7647	      (clobber (reg:SI 2))
7648	      (clobber (match_operand 2))
7649	      (use (reg:SI 19))
7650	      (use (const_int 0))])]
7651  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7652   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7653  [(set (match_dup 2) (reg:SI 19))
7654   (parallel [(call (mem:SI (match_dup 0))
7655		    (match_dup 1))
7656	      (clobber (reg:SI 1))
7657	      (clobber (reg:SI 2))
7658	      (use (reg:SI 19))
7659	      (use (const_int 0))])]
7660  "")
7661
7662(define_split
7663  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7664		    (match_operand 1 "" ""))
7665	      (clobber (reg:SI 1))
7666	      (clobber (reg:SI 2))
7667	      (clobber (match_operand 2))
7668	      (use (reg:SI 19))
7669	      (use (const_int 0))])]
7670  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7671  [(set (match_dup 2) (reg:SI 19))
7672   (parallel [(call (mem:SI (match_dup 0))
7673		    (match_dup 1))
7674	      (clobber (reg:SI 1))
7675	      (clobber (reg:SI 2))
7676	      (use (reg:SI 19))
7677	      (use (const_int 0))])
7678   (set (reg:SI 19) (match_dup 2))]
7679  "")
7680
7681(define_insn "*call_symref_pic_post_reload"
7682  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7683	 (match_operand 1 "" "i"))
7684   (clobber (reg:SI 1))
7685   (clobber (reg:SI 2))
7686   (use (reg:SI 19))
7687   (use (const_int 0))]
7688  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7689  "*
7690{
7691  pa_output_arg_descriptor (insn);
7692  return pa_output_call (insn, operands[0], 0);
7693}"
7694  [(set_attr "type" "call")
7695   (set (attr "length")
7696	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7697	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7698
7699;; This pattern is split if it is necessary to save and restore the
7700;; PIC register.
7701(define_insn "call_symref_64bit"
7702  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7703	 (match_operand 1 "" "i"))
7704   (clobber (reg:DI 1))
7705   (clobber (reg:DI 2))
7706   (clobber (match_operand 2))
7707   (use (reg:DI 27))
7708   (use (reg:DI 29))
7709   (use (const_int 0))]
7710  "TARGET_64BIT"
7711  "#")
7712
7713;; Split out the PIC register save and restore after reload.  As the
7714;; split is done after reload, there are some situations in which we
7715;; unnecessarily save and restore %r4.  This happens when there is a
7716;; single call and the PIC register is not used after the call.
7717;;
7718;; The split has to be done since call_from_call_insn () can't handle
7719;; the pattern as is.  Noreturn calls are special because they have to
7720;; terminate the basic block.  The split has to contain more than one
7721;; insn.
7722(define_split
7723  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7724		    (match_operand 1 "" ""))
7725	      (clobber (reg:DI 1))
7726	      (clobber (reg:DI 2))
7727	      (clobber (match_operand 2))
7728	      (use (reg:DI 27))
7729	      (use (reg:DI 29))
7730	      (use (const_int 0))])]
7731  "TARGET_64BIT && reload_completed
7732   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7733  [(set (match_dup 2) (reg:DI 27))
7734   (parallel [(call (mem:SI (match_dup 0))
7735		    (match_dup 1))
7736	      (clobber (reg:DI 1))
7737	      (clobber (reg:DI 2))
7738	      (use (reg:DI 27))
7739	      (use (reg:DI 29))
7740	      (use (const_int 0))])]
7741  "")
7742
7743(define_split
7744  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7745		    (match_operand 1 "" ""))
7746	      (clobber (reg:DI 1))
7747	      (clobber (reg:DI 2))
7748	      (clobber (match_operand 2))
7749	      (use (reg:DI 27))
7750	      (use (reg:DI 29))
7751	      (use (const_int 0))])]
7752  "TARGET_64BIT && reload_completed"
7753  [(set (match_dup 2) (reg:DI 27))
7754   (parallel [(call (mem:SI (match_dup 0))
7755		    (match_dup 1))
7756	      (clobber (reg:DI 1))
7757	      (clobber (reg:DI 2))
7758	      (use (reg:DI 27))
7759	      (use (reg:DI 29))
7760	      (use (const_int 0))])
7761   (set (reg:DI 27) (match_dup 2))]
7762  "")
7763
7764(define_insn "*call_symref_64bit_post_reload"
7765  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7766	 (match_operand 1 "" "i"))
7767   (clobber (reg:DI 1))
7768   (clobber (reg:DI 2))
7769   (use (reg:DI 27))
7770   (use (reg:DI 29))
7771   (use (const_int 0))]
7772  "TARGET_64BIT"
7773  "*
7774{
7775  return pa_output_call (insn, operands[0], 0);
7776}"
7777  [(set_attr "type" "call")
7778   (set (attr "length")
7779	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7780	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7781
7782(define_insn "call_reg"
7783  [(call (mem:SI (reg:SI 22))
7784	 (match_operand 0 "" "i"))
7785   (clobber (reg:SI 1))
7786   (clobber (reg:SI 2))
7787   (use (const_int 1))]
7788  "!TARGET_64BIT"
7789  "*
7790{
7791  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7792}"
7793  [(set_attr "type" "dyncall")
7794   (set (attr "length")
7795	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7796	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7797
7798;; This pattern is split if it is necessary to save and restore the
7799;; PIC register.
7800(define_insn "call_reg_pic"
7801  [(call (mem:SI (reg:SI 22))
7802	 (match_operand 0 "" "i"))
7803   (clobber (reg:SI 1))
7804   (clobber (reg:SI 2))
7805   (clobber (match_operand 1))
7806   (use (reg:SI 19))
7807   (use (const_int 1))]
7808  "!TARGET_64BIT"
7809  "#")
7810
7811;; Split out the PIC register save and restore after reload.  As the
7812;; split is done after reload, there are some situations in which we
7813;; unnecessarily save and restore %r4.  This happens when there is a
7814;; single call and the PIC register is not used after the call.
7815;;
7816;; The split has to be done since call_from_call_insn () can't handle
7817;; the pattern as is.  Noreturn calls are special because they have to
7818;; terminate the basic block.  The split has to contain more than one
7819;; insn.
7820(define_split
7821  [(parallel [(call (mem:SI (reg:SI 22))
7822		    (match_operand 0 "" ""))
7823	      (clobber (reg:SI 1))
7824	      (clobber (reg:SI 2))
7825	      (clobber (match_operand 1))
7826	      (use (reg:SI 19))
7827	      (use (const_int 1))])]
7828  "!TARGET_64BIT && reload_completed
7829   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7830  [(set (match_dup 1) (reg:SI 19))
7831   (parallel [(call (mem:SI (reg:SI 22))
7832		    (match_dup 0))
7833	      (clobber (reg:SI 1))
7834	      (clobber (reg:SI 2))
7835	      (use (reg:SI 19))
7836	      (use (const_int 1))])]
7837  "")
7838
7839(define_split
7840  [(parallel [(call (mem:SI (reg:SI 22))
7841		    (match_operand 0 "" ""))
7842	      (clobber (reg:SI 1))
7843	      (clobber (reg:SI 2))
7844	      (clobber (match_operand 1))
7845	      (use (reg:SI 19))
7846	      (use (const_int 1))])]
7847  "!TARGET_64BIT && reload_completed"
7848  [(set (match_dup 1) (reg:SI 19))
7849   (parallel [(call (mem:SI (reg:SI 22))
7850		    (match_dup 0))
7851	      (clobber (reg:SI 1))
7852	      (clobber (reg:SI 2))
7853	      (use (reg:SI 19))
7854	      (use (const_int 1))])
7855   (set (reg:SI 19) (match_dup 1))]
7856  "")
7857
7858(define_insn "*call_reg_pic_post_reload"
7859  [(call (mem:SI (reg:SI 22))
7860	 (match_operand 0 "" "i"))
7861   (clobber (reg:SI 1))
7862   (clobber (reg:SI 2))
7863   (use (reg:SI 19))
7864   (use (const_int 1))]
7865  "!TARGET_64BIT"
7866  "*
7867{
7868  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7869}"
7870  [(set_attr "type" "dyncall")
7871   (set (attr "length")
7872	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7873	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7874
7875;; This pattern is split if it is necessary to save and restore the
7876;; PIC register.
7877(define_insn "call_reg_64bit"
7878  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7879	 (match_operand 1 "" "i"))
7880   (clobber (reg:DI 2))
7881   (clobber (match_operand 2))
7882   (use (reg:DI 27))
7883   (use (reg:DI 29))
7884   (use (const_int 1))]
7885  "TARGET_64BIT"
7886  "#")
7887
7888;; Split out the PIC register save and restore after reload.  As the
7889;; split is done after reload, there are some situations in which we
7890;; unnecessarily save and restore %r4.  This happens when there is a
7891;; single call and the PIC register is not used after the call.
7892;;
7893;; The split has to be done since call_from_call_insn () can't handle
7894;; the pattern as is.  Noreturn calls are special because they have to
7895;; terminate the basic block.  The split has to contain more than one
7896;; insn.
7897(define_split
7898  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7899		    (match_operand 1 "" ""))
7900	      (clobber (reg:DI 2))
7901	      (clobber (match_operand 2))
7902	      (use (reg:DI 27))
7903	      (use (reg:DI 29))
7904	      (use (const_int 1))])]
7905  "TARGET_64BIT && reload_completed
7906   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7907  [(set (match_dup 2) (reg:DI 27))
7908   (parallel [(call (mem:SI (match_dup 0))
7909		    (match_dup 1))
7910	      (clobber (reg:DI 2))
7911	      (use (reg:DI 27))
7912	      (use (reg:DI 29))
7913	      (use (const_int 1))])]
7914  "")
7915
7916(define_split
7917  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7918		    (match_operand 1 "" ""))
7919	      (clobber (reg:DI 2))
7920	      (clobber (match_operand 2))
7921	      (use (reg:DI 27))
7922	      (use (reg:DI 29))
7923	      (use (const_int 1))])]
7924  "TARGET_64BIT && reload_completed"
7925  [(set (match_dup 2) (reg:DI 27))
7926   (parallel [(call (mem:SI (match_dup 0))
7927		    (match_dup 1))
7928	      (clobber (reg:DI 2))
7929	      (use (reg:DI 27))
7930	      (use (reg:DI 29))
7931	      (use (const_int 1))])
7932   (set (reg:DI 27) (match_dup 2))]
7933  "")
7934
7935(define_insn "*call_reg_64bit_post_reload"
7936  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7937	 (match_operand 1 "" "i"))
7938   (clobber (reg:DI 2))
7939   (use (reg:DI 27))
7940   (use (reg:DI 29))
7941   (use (const_int 1))]
7942  "TARGET_64BIT"
7943  "*
7944{
7945  return pa_output_indirect_call (insn, operands[0]);
7946}"
7947  [(set_attr "type" "dyncall")
7948   (set (attr "length")
7949	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7950	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7951
7952(define_expand "call_value"
7953  [(parallel [(set (match_operand 0 "" "")
7954		   (call (match_operand:SI 1 "" "")
7955			 (match_operand 2 "" "")))
7956	      (clobber (reg:SI 2))])]
7957  ""
7958{
7959  rtx op;
7960  rtx dst = operands[0];
7961  rtx nb = operands[2];
7962  bool call_powf = false;
7963
7964  if (TARGET_PORTABLE_RUNTIME)
7965    op = force_reg (SImode, XEXP (operands[1], 0));
7966  else
7967    {
7968      op = XEXP (operands[1], 0);
7969      if (GET_CODE (op) == SYMBOL_REF)
7970	{
7971	  /* Handle special call to buggy powf function.  */
7972	  if (TARGET_HPUX && !TARGET_SOFT_FLOAT
7973	      && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7974	    call_powf = true;
7975
7976	  /* Generate indirect long calls to non-local functions. */
7977	  else if (TARGET_LONG_CALLS)
7978	    {
7979	      tree call_decl = SYMBOL_REF_DECL (op);
7980	      if (!(call_decl && targetm.binds_local_p (call_decl)))
7981		op = force_reg (word_mode, op);
7982	    }
7983	}
7984    }
7985
7986  if (TARGET_64BIT)
7987    {
7988      if (!virtuals_instantiated)
7989	emit_move_insn (arg_pointer_rtx,
7990			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7991				      GEN_INT (64)));
7992      else
7993	{
7994	  /* The loop pass can generate new libcalls after the virtual
7995	     registers are instantiated when fpregs are disabled because
7996	     the only method that we have for doing DImode multiplication
7997	     is with a libcall.  This could be trouble if we haven't
7998	     allocated enough space for the outgoing arguments.  */
7999	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8000
8001	  emit_move_insn (arg_pointer_rtx,
8002			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8003					GEN_INT (STACK_POINTER_OFFSET + 64)));
8004	}
8005    }
8006
8007  /* Use two different patterns for calls to explicitly named functions
8008     and calls through function pointers.  This is necessary as these two
8009     types of calls use different calling conventions, and CSE might try
8010     to change the named call into an indirect call in some cases (using
8011     two patterns keeps CSE from performing this optimization).
8012
8013     We now use even more call patterns as there was a subtle bug in
8014     attempting to restore the pic register after a call using a simple
8015     move insn.  During reload, a instruction involving a pseudo register
8016     with no explicit dependence on the PIC register can be converted
8017     to an equivalent load from memory using the PIC register.  If we
8018     emit a simple move to restore the PIC register in the initial rtl
8019     generation, then it can potentially be repositioned during scheduling.
8020     and an instruction that eventually uses the PIC register may end up
8021     between the call and the PIC register restore.
8022
8023     This only worked because there is a post call group of instructions
8024     that are scheduled with the call.  These instructions are included
8025     in the same basic block as the call.  However, calls can throw in
8026     C++ code and a basic block has to terminate at the call if the call
8027     can throw.  This results in the PIC register restore being scheduled
8028     independently from the call.  So, we now hide the save and restore
8029     of the PIC register in the call pattern until after reload.  Then,
8030     we split the moves out.  A small side benefit is that we now don't
8031     need to have a use of the PIC register in the return pattern and
8032     the final save/restore operation is not needed.
8033
8034     I elected to just use register %r4 in the PIC patterns instead
8035     of trying to force hppa_pic_save_rtx () to a callee saved register.
8036     This might have required a new register class and constraint.  It
8037     was also simpler to just handle the restore from a register than a
8038     generic pseudo.  */
8039  if (TARGET_64BIT)
8040    {
8041      rtx r4 = gen_rtx_REG (word_mode, 4);
8042      if (GET_CODE (op) == SYMBOL_REF)
8043	{
8044	  if (call_powf)
8045	    emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
8046	  else
8047	    emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
8048	}
8049      else
8050	{
8051	  op = force_reg (word_mode, op);
8052	  emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
8053	}
8054    }
8055  else
8056    {
8057      if (GET_CODE (op) == SYMBOL_REF)
8058	{
8059	  if (flag_pic)
8060	    {
8061	      rtx r4 = gen_rtx_REG (word_mode, 4);
8062
8063	      if (call_powf)
8064		emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
8065	      else
8066		emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
8067	    }
8068	  else
8069	    {
8070	      if (call_powf)
8071		emit_call_insn (gen_call_val_powf (dst, op, nb));
8072	      else
8073		emit_call_insn (gen_call_val_symref (dst, op, nb));
8074	    }
8075	}
8076      else
8077	{
8078	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
8079	  emit_move_insn (tmpreg, force_reg (word_mode, op));
8080	  if (flag_pic)
8081	    {
8082	      rtx r4 = gen_rtx_REG (word_mode, 4);
8083	      emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
8084	    }
8085	  else
8086	    emit_call_insn (gen_call_val_reg (dst, nb));
8087	}
8088    }
8089
8090  DONE;
8091})
8092
8093(define_insn "call_val_symref"
8094  [(set (match_operand 0 "" "")
8095	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8096	      (match_operand 2 "" "i")))
8097   (clobber (reg:SI 1))
8098   (clobber (reg:SI 2))
8099   (use (const_int 0))]
8100  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8101  "*
8102{
8103  pa_output_arg_descriptor (insn);
8104  return pa_output_call (insn, operands[1], 0);
8105}"
8106  [(set_attr "type" "call")
8107   (set (attr "length")
8108	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8109	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8110
8111;; powf function clobbers %fr12
8112(define_insn "call_val_powf"
8113  [(set (match_operand 0 "" "")
8114	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8115	      (match_operand 2 "" "i")))
8116   (clobber (reg:SI 1))
8117   (clobber (reg:SI 2))
8118   (clobber (reg:DF 48))
8119   (use (const_int 1))]
8120  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8121  "*
8122{
8123  pa_output_arg_descriptor (insn);
8124  return pa_output_call (insn, operands[1], 0);
8125}"
8126  [(set_attr "type" "call")
8127   (set (attr "length")
8128	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8129	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8130
8131(define_insn "call_val_symref_pic"
8132  [(set (match_operand 0 "" "")
8133	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8134	      (match_operand 2 "" "i")))
8135   (clobber (reg:SI 1))
8136   (clobber (reg:SI 2))
8137   (clobber (match_operand 3))
8138   (use (reg:SI 19))
8139   (use (const_int 0))]
8140  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8141  "#")
8142
8143;; Split out the PIC register save and restore after reload.  As the
8144;; split is done after reload, there are some situations in which we
8145;; unnecessarily save and restore %r4.  This happens when there is a
8146;; single call and the PIC register is not used after the call.
8147;;
8148;; The split has to be done since call_from_call_insn () can't handle
8149;; the pattern as is.  Noreturn calls are special because they have to
8150;; terminate the basic block.  The split has to contain more than one
8151;; insn.
8152(define_split
8153  [(parallel [(set (match_operand 0 "" "")
8154	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8155		    (match_operand 2 "" "")))
8156	      (clobber (reg:SI 1))
8157	      (clobber (reg:SI 2))
8158	      (clobber (match_operand 3))
8159	      (use (reg:SI 19))
8160	      (use (const_int 0))])]
8161  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8162   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8163  [(set (match_dup 3) (reg:SI 19))
8164   (parallel [(set (match_dup 0)
8165	      (call (mem:SI (match_dup 1))
8166		    (match_dup 2)))
8167	      (clobber (reg:SI 1))
8168	      (clobber (reg:SI 2))
8169	      (use (reg:SI 19))
8170	      (use (const_int 0))])]
8171  "")
8172
8173(define_split
8174  [(parallel [(set (match_operand 0 "" "")
8175	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8176		    (match_operand 2 "" "")))
8177	      (clobber (reg:SI 1))
8178	      (clobber (reg:SI 2))
8179	      (clobber (match_operand 3))
8180	      (use (reg:SI 19))
8181	      (use (const_int 0))])]
8182  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8183  [(set (match_dup 3) (reg:SI 19))
8184   (parallel [(set (match_dup 0)
8185	      (call (mem:SI (match_dup 1))
8186		    (match_dup 2)))
8187	      (clobber (reg:SI 1))
8188	      (clobber (reg:SI 2))
8189	      (use (reg:SI 19))
8190	      (use (const_int 0))])
8191   (set (reg:SI 19) (match_dup 3))]
8192  "")
8193
8194(define_insn "*call_val_symref_pic_post_reload"
8195  [(set (match_operand 0 "" "")
8196	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8197	      (match_operand 2 "" "i")))
8198   (clobber (reg:SI 1))
8199   (clobber (reg:SI 2))
8200   (use (reg:SI 19))
8201   (use (const_int 0))]
8202  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8203  "*
8204{
8205  pa_output_arg_descriptor (insn);
8206  return pa_output_call (insn, operands[1], 0);
8207}"
8208  [(set_attr "type" "call")
8209   (set (attr "length")
8210	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8211	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8212
8213;; powf function clobbers %fr12
8214(define_insn "call_val_powf_pic"
8215  [(set (match_operand 0 "" "")
8216	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8217	      (match_operand 2 "" "i")))
8218   (clobber (reg:SI 1))
8219   (clobber (reg:SI 2))
8220   (clobber (reg:DF 48))
8221   (clobber (match_operand 3))
8222   (use (reg:SI 19))
8223   (use (const_int 1))]
8224  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8225  "#")
8226
8227;; Split out the PIC register save and restore after reload.  As the
8228;; split is done after reload, there are some situations in which we
8229;; unnecessarily save and restore %r4.  This happens when there is a
8230;; single call and the PIC register is not used after the call.
8231;;
8232;; The split has to be done since call_from_call_insn () can't handle
8233;; the pattern as is.  Noreturn calls are special because they have to
8234;; terminate the basic block.  The split has to contain more than one
8235;; insn.
8236(define_split
8237  [(parallel [(set (match_operand 0 "" "")
8238	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8239		    (match_operand 2 "" "")))
8240	      (clobber (reg:SI 1))
8241	      (clobber (reg:SI 2))
8242	      (clobber (reg:DF 48))
8243	      (clobber (match_operand 3))
8244	      (use (reg:SI 19))
8245	      (use (const_int 1))])]
8246  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8247   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8248  [(set (match_dup 3) (reg:SI 19))
8249   (parallel [(set (match_dup 0)
8250	      (call (mem:SI (match_dup 1))
8251		    (match_dup 2)))
8252	      (clobber (reg:SI 1))
8253	      (clobber (reg:SI 2))
8254	      (clobber (reg:DF 48))
8255	      (use (reg:SI 19))
8256	      (use (const_int 1))])]
8257  "")
8258
8259(define_split
8260  [(parallel [(set (match_operand 0 "" "")
8261	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8262		    (match_operand 2 "" "")))
8263	      (clobber (reg:SI 1))
8264	      (clobber (reg:SI 2))
8265	      (clobber (reg:DF 48))
8266	      (clobber (match_operand 3))
8267	      (use (reg:SI 19))
8268	      (use (const_int 1))])]
8269  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8270  [(set (match_dup 3) (reg:SI 19))
8271   (parallel [(set (match_dup 0)
8272	      (call (mem:SI (match_dup 1))
8273		    (match_dup 2)))
8274	      (clobber (reg:SI 1))
8275	      (clobber (reg:SI 2))
8276	      (clobber (reg:DF 48))
8277	      (use (reg:SI 19))
8278	      (use (const_int 1))])
8279   (set (reg:SI 19) (match_dup 3))]
8280  "")
8281
8282(define_insn "*call_val_powf_pic_post_reload"
8283  [(set (match_operand 0 "" "")
8284	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8285	      (match_operand 2 "" "i")))
8286   (clobber (reg:SI 1))
8287   (clobber (reg:SI 2))
8288   (clobber (reg:DF 48))
8289   (use (reg:SI 19))
8290   (use (const_int 1))]
8291  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8292  "*
8293{
8294  pa_output_arg_descriptor (insn);
8295  return pa_output_call (insn, operands[1], 0);
8296}"
8297  [(set_attr "type" "call")
8298   (set (attr "length")
8299	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8300	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8301
8302;; This pattern is split if it is necessary to save and restore the
8303;; PIC register.
8304(define_insn "call_val_symref_64bit"
8305  [(set (match_operand 0 "" "")
8306	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8307	      (match_operand 2 "" "i")))
8308   (clobber (reg:DI 1))
8309   (clobber (reg:DI 2))
8310   (clobber (match_operand 3))
8311   (use (reg:DI 27))
8312   (use (reg:DI 29))
8313   (use (const_int 0))]
8314  "TARGET_64BIT"
8315  "#")
8316
8317;; Split out the PIC register save and restore after reload.  As the
8318;; split is done after reload, there are some situations in which we
8319;; unnecessarily save and restore %r4.  This happens when there is a
8320;; single call and the PIC register is not used after the call.
8321;;
8322;; The split has to be done since call_from_call_insn () can't handle
8323;; the pattern as is.  Noreturn calls are special because they have to
8324;; terminate the basic block.  The split has to contain more than one
8325;; insn.
8326(define_split
8327  [(parallel [(set (match_operand 0 "" "")
8328	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8329		    (match_operand 2 "" "")))
8330	      (clobber (reg:DI 1))
8331	      (clobber (reg:DI 2))
8332	      (clobber (match_operand 3))
8333	      (use (reg:DI 27))
8334	      (use (reg:DI 29))
8335	      (use (const_int 0))])]
8336  "TARGET_64BIT && reload_completed
8337   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8338  [(set (match_dup 3) (reg:DI 27))
8339   (parallel [(set (match_dup 0)
8340	      (call (mem:SI (match_dup 1))
8341		    (match_dup 2)))
8342	      (clobber (reg:DI 1))
8343	      (clobber (reg:DI 2))
8344	      (use (reg:DI 27))
8345	      (use (reg:DI 29))
8346	      (use (const_int 0))])]
8347  "")
8348
8349(define_split
8350  [(parallel [(set (match_operand 0 "" "")
8351	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8352		    (match_operand 2 "" "")))
8353	      (clobber (reg:DI 1))
8354	      (clobber (reg:DI 2))
8355	      (clobber (match_operand 3))
8356	      (use (reg:DI 27))
8357	      (use (reg:DI 29))
8358	      (use (const_int 0))])]
8359  "TARGET_64BIT && reload_completed"
8360  [(set (match_dup 3) (reg:DI 27))
8361   (parallel [(set (match_dup 0)
8362	      (call (mem:SI (match_dup 1))
8363		    (match_dup 2)))
8364	      (clobber (reg:DI 1))
8365	      (clobber (reg:DI 2))
8366	      (use (reg:DI 27))
8367	      (use (reg:DI 29))
8368	      (use (const_int 0))])
8369   (set (reg:DI 27) (match_dup 3))]
8370  "")
8371
8372(define_insn "*call_val_symref_64bit_post_reload"
8373  [(set (match_operand 0 "" "")
8374	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8375	      (match_operand 2 "" "i")))
8376   (clobber (reg:DI 1))
8377   (clobber (reg:DI 2))
8378   (use (reg:DI 27))
8379   (use (reg:DI 29))
8380   (use (const_int 0))]
8381  "TARGET_64BIT"
8382  "*
8383{
8384  return pa_output_call (insn, operands[1], 0);
8385}"
8386  [(set_attr "type" "call")
8387   (set (attr "length")
8388	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8389	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8390
8391;; powf function clobbers %fr12
8392(define_insn "call_val_powf_64bit"
8393  [(set (match_operand 0 "" "")
8394	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8395	      (match_operand 2 "" "i")))
8396   (clobber (reg:DI 1))
8397   (clobber (reg:DI 2))
8398   (clobber (reg:DF 40))
8399   (clobber (match_operand 3))
8400   (use (reg:DI 27))
8401   (use (reg:DI 29))
8402   (use (const_int 1))]
8403  "TARGET_64BIT && TARGET_HPUX"
8404  "#")
8405
8406;; Split out the PIC register save and restore after reload.  As the
8407;; split is done after reload, there are some situations in which we
8408;; unnecessarily save and restore %r4.  This happens when there is a
8409;; single call and the PIC register is not used after the call.
8410;;
8411;; The split has to be done since call_from_call_insn () can't handle
8412;; the pattern as is.  Noreturn calls are special because they have to
8413;; terminate the basic block.  The split has to contain more than one
8414;; insn.
8415(define_split
8416  [(parallel [(set (match_operand 0 "" "")
8417	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8418		    (match_operand 2 "" "")))
8419	      (clobber (reg:DI 1))
8420	      (clobber (reg:DI 2))
8421	      (clobber (reg:DF 40))
8422	      (clobber (match_operand 3))
8423	      (use (reg:DI 27))
8424	      (use (reg:DI 29))
8425	      (use (const_int 1))])]
8426  "TARGET_64BIT && TARGET_HPUX && reload_completed
8427   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8428  [(set (match_dup 3) (reg:DI 27))
8429   (parallel [(set (match_dup 0)
8430	      (call (mem:SI (match_dup 1))
8431		    (match_dup 2)))
8432	      (clobber (reg:DI 1))
8433	      (clobber (reg:DI 2))
8434	      (clobber (reg:DF 40))
8435	      (use (reg:DI 27))
8436	      (use (reg:DI 29))
8437	      (use (const_int 1))])]
8438  "")
8439
8440(define_split
8441  [(parallel [(set (match_operand 0 "" "")
8442	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8443		    (match_operand 2 "" "")))
8444	      (clobber (reg:DI 1))
8445	      (clobber (reg:DI 2))
8446	      (clobber (reg:DF 40))
8447	      (clobber (match_operand 3))
8448	      (use (reg:DI 27))
8449	      (use (reg:DI 29))
8450	      (use (const_int 1))])]
8451  "TARGET_64BIT && TARGET_HPUX && reload_completed"
8452  [(set (match_dup 3) (reg:DI 27))
8453   (parallel [(set (match_dup 0)
8454	      (call (mem:SI (match_dup 1))
8455		    (match_dup 2)))
8456	      (clobber (reg:DI 1))
8457	      (clobber (reg:DI 2))
8458	      (clobber (reg:DF 40))
8459	      (use (reg:DI 27))
8460	      (use (reg:DI 29))
8461	      (use (const_int 1))])
8462   (set (reg:DI 27) (match_dup 3))]
8463  "")
8464
8465(define_insn "*call_val_powf_64bit_post_reload"
8466  [(set (match_operand 0 "" "")
8467	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8468	      (match_operand 2 "" "i")))
8469   (clobber (reg:DI 1))
8470   (clobber (reg:DI 2))
8471   (clobber (reg:DF 40))
8472   (use (reg:DI 27))
8473   (use (reg:DI 29))
8474   (use (const_int 1))]
8475  "TARGET_64BIT && TARGET_HPUX"
8476  "*
8477{
8478  return pa_output_call (insn, operands[1], 0);
8479}"
8480  [(set_attr "type" "call")
8481   (set (attr "length")
8482	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8483	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8484
8485(define_insn "call_val_reg"
8486  [(set (match_operand 0 "" "")
8487	(call (mem:SI (reg:SI 22))
8488	      (match_operand 1 "" "i")))
8489   (clobber (reg:SI 1))
8490   (clobber (reg:SI 2))
8491   (use (const_int 1))]
8492  "!TARGET_64BIT"
8493  "*
8494{
8495  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8496}"
8497  [(set_attr "type" "dyncall")
8498   (set (attr "length")
8499	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8500	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8501
8502;; This pattern is split if it is necessary to save and restore the
8503;; PIC register.
8504(define_insn "call_val_reg_pic"
8505  [(set (match_operand 0 "" "")
8506	(call (mem:SI (reg:SI 22))
8507	      (match_operand 1 "" "i")))
8508   (clobber (reg:SI 1))
8509   (clobber (reg:SI 2))
8510   (clobber (match_operand 2))
8511   (use (reg:SI 19))
8512   (use (const_int 1))]
8513  "!TARGET_64BIT"
8514  "#")
8515
8516;; Split out the PIC register save and restore after reload.  As the
8517;; split is done after reload, there are some situations in which we
8518;; unnecessarily save and restore %r4.  This happens when there is a
8519;; single call and the PIC register is not used after the call.
8520;;
8521;; The split has to be done since call_from_call_insn () can't handle
8522;; the pattern as is.  Noreturn calls are special because they have to
8523;; terminate the basic block.  The split has to contain more than one
8524;; insn.
8525(define_split
8526  [(parallel [(set (match_operand 0 "" "")
8527		   (call (mem:SI (reg:SI 22))
8528			 (match_operand 1 "" "")))
8529	      (clobber (reg:SI 1))
8530	      (clobber (reg:SI 2))
8531	      (clobber (match_operand 2))
8532	      (use (reg:SI 19))
8533	      (use (const_int 1))])]
8534  "!TARGET_64BIT && reload_completed
8535   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8536  [(set (match_dup 2) (reg:SI 19))
8537   (parallel [(set (match_dup 0)
8538		   (call (mem:SI (reg:SI 22))
8539			 (match_dup 1)))
8540	      (clobber (reg:SI 1))
8541	      (clobber (reg:SI 2))
8542	      (use (reg:SI 19))
8543	      (use (const_int 1))])]
8544  "")
8545
8546(define_split
8547  [(parallel [(set (match_operand 0 "" "")
8548		   (call (mem:SI (reg:SI 22))
8549			 (match_operand 1 "" "")))
8550	      (clobber (reg:SI 1))
8551	      (clobber (reg:SI 2))
8552	      (clobber (match_operand 2))
8553	      (use (reg:SI 19))
8554	      (use (const_int 1))])]
8555  "!TARGET_64BIT && reload_completed"
8556  [(set (match_dup 2) (reg:SI 19))
8557   (parallel [(set (match_dup 0)
8558		   (call (mem:SI (reg:SI 22))
8559			 (match_dup 1)))
8560	      (clobber (reg:SI 1))
8561	      (clobber (reg:SI 2))
8562	      (use (reg:SI 19))
8563	      (use (const_int 1))])
8564   (set (reg:SI 19) (match_dup 2))]
8565  "")
8566
8567(define_insn "*call_val_reg_pic_post_reload"
8568  [(set (match_operand 0 "" "")
8569	(call (mem:SI (reg:SI 22))
8570	      (match_operand 1 "" "i")))
8571   (clobber (reg:SI 1))
8572   (clobber (reg:SI 2))
8573   (use (reg:SI 19))
8574   (use (const_int 1))]
8575  "!TARGET_64BIT"
8576  "*
8577{
8578  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8579}"
8580  [(set_attr "type" "dyncall")
8581   (set (attr "length")
8582	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8583	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8584
8585;; This pattern is split if it is necessary to save and restore the
8586;; PIC register.
8587(define_insn "call_val_reg_64bit"
8588  [(set (match_operand 0 "" "")
8589	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8590	      (match_operand 2 "" "i")))
8591   (clobber (reg:DI 2))
8592   (clobber (match_operand 3))
8593   (use (reg:DI 27))
8594   (use (reg:DI 29))
8595   (use (const_int 1))]
8596  "TARGET_64BIT"
8597  "#")
8598
8599;; Split out the PIC register save and restore after reload.  As the
8600;; split is done after reload, there are some situations in which we
8601;; unnecessarily save and restore %r4.  This happens when there is a
8602;; single call and the PIC register is not used after the call.
8603;;
8604;; The split has to be done since call_from_call_insn () can't handle
8605;; the pattern as is.  Noreturn calls are special because they have to
8606;; terminate the basic block.  The split has to contain more than one
8607;; insn.
8608(define_split
8609  [(parallel [(set (match_operand 0 "" "")
8610		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8611			 (match_operand 2 "" "")))
8612	      (clobber (reg:DI 2))
8613	      (clobber (match_operand 3))
8614	      (use (reg:DI 27))
8615	      (use (reg:DI 29))
8616	      (use (const_int 1))])]
8617  "TARGET_64BIT && reload_completed
8618   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8619  [(set (match_dup 3) (reg:DI 27))
8620   (parallel [(set (match_dup 0)
8621		   (call (mem:SI (match_dup 1))
8622			 (match_dup 2)))
8623	      (clobber (reg:DI 2))
8624	      (use (reg:DI 27))
8625	      (use (reg:DI 29))
8626	      (use (const_int 1))])]
8627  "")
8628
8629(define_split
8630  [(parallel [(set (match_operand 0 "" "")
8631		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8632			 (match_operand 2 "" "")))
8633	      (clobber (reg:DI 2))
8634	      (clobber (match_operand 3))
8635	      (use (reg:DI 27))
8636	      (use (reg:DI 29))
8637	      (use (const_int 1))])]
8638  "TARGET_64BIT && reload_completed"
8639  [(set (match_dup 3) (reg:DI 27))
8640   (parallel [(set (match_dup 0)
8641		   (call (mem:SI (match_dup 1))
8642			 (match_dup 2)))
8643	      (clobber (reg:DI 2))
8644	      (use (reg:DI 27))
8645	      (use (reg:DI 29))
8646	      (use (const_int 1))])
8647   (set (reg:DI 27) (match_dup 3))]
8648  "")
8649
8650(define_insn "*call_val_reg_64bit_post_reload"
8651  [(set (match_operand 0 "" "")
8652	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8653	      (match_operand 2 "" "i")))
8654   (clobber (reg:DI 2))
8655   (use (reg:DI 27))
8656   (use (reg:DI 29))
8657   (use (const_int 1))]
8658  "TARGET_64BIT"
8659  "*
8660{
8661  return pa_output_indirect_call (insn, operands[1]);
8662}"
8663  [(set_attr "type" "dyncall")
8664   (set (attr "length")
8665	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8666	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8667
8668/* Expand special pc-relative call to _mcount.  */
8669
8670(define_expand "call_mcount"
8671  [(parallel [(call (match_operand:SI 0 "" "")
8672		    (match_operand 1 "" ""))
8673	      (set (reg:SI 25)
8674		   (plus:SI (reg:SI 2)
8675			    (minus:SI (match_operand 2 "" "")
8676				      (plus:SI (pc) (const_int 4)))))
8677	      (clobber (reg:SI 2))])]
8678  "!TARGET_PORTABLE_RUNTIME"
8679  "
8680{
8681  rtx op = XEXP (operands[0], 0);
8682  rtx nb = operands[1];
8683  rtx lab = operands[2];
8684
8685  if (TARGET_64BIT)
8686    {
8687      rtx r4 = gen_rtx_REG (word_mode, 4);
8688      emit_move_insn (arg_pointer_rtx,
8689		      gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8690				    GEN_INT (64)));
8691      emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8692    }
8693  else
8694    {
8695      if (flag_pic)
8696	{
8697	  rtx r4 = gen_rtx_REG (word_mode, 4);
8698	  emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8699	}
8700      else
8701	emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8702    }
8703
8704  DONE;
8705}")
8706
8707(define_insn "call_mcount_nonpic"
8708  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8709	 (match_operand 1 "" "i"))
8710   (set (reg:SI 25)
8711	(plus:SI (reg:SI 2)
8712		 (minus:SI (match_operand 2 "" "")
8713			   (plus:SI (pc) (const_int 4)))))
8714   (clobber (reg:SI 2))]
8715  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8716  "*
8717{
8718  pa_output_arg_descriptor (insn);
8719  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8720}"
8721  [(set_attr "type" "multi")
8722   (set_attr "length" "8")])
8723
8724(define_insn "call_mcount_pic"
8725  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8726	 (match_operand 1 "" "i"))
8727   (set (reg:SI 25)
8728	(plus:SI (reg:SI 2)
8729		 (minus:SI (match_operand 2 "" "")
8730			   (plus:SI (pc) (const_int 4)))))
8731   (clobber (reg:SI 2))
8732   (clobber (match_operand 3))
8733   (use (reg:SI 19))]
8734  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8735  "#")
8736
8737(define_split
8738  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8739		    (match_operand 1 "" ""))
8740	      (set (reg:SI 25)
8741		   (plus:SI (reg:SI 2)
8742			    (minus:SI (match_operand 2 "" "")
8743				      (plus:SI (pc) (const_int 4)))))
8744	      (clobber (reg:SI 2))
8745	      (clobber (match_operand 3))
8746	      (use (reg:SI 19))])]
8747  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8748  [(set (match_dup 3) (reg:SI 19))
8749   (parallel [(call (mem:SI (match_dup 0))
8750		    (match_dup 1))
8751	      (set (reg:SI 25)
8752		   (plus:SI (reg:SI 2)
8753			    (minus:SI (match_dup 2)
8754				      (plus:SI (pc) (const_int 4)))))
8755	      (clobber (reg:SI 2))
8756	      (use (reg:SI 19))])
8757   (set (reg:SI 19) (match_dup 3))]
8758  "")
8759
8760(define_insn "*call_mcount_pic_post_reload"
8761  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8762	 (match_operand 1 "" "i"))
8763   (set (reg:SI 25)
8764	(plus:SI (reg:SI 2)
8765		 (minus:SI (match_operand 2 "" "")
8766			   (plus:SI (pc) (const_int 4)))))
8767   (clobber (reg:SI 2))
8768   (use (reg:SI 19))]
8769  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8770  "*
8771{
8772  pa_output_arg_descriptor (insn);
8773  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8774}"
8775  [(set_attr "type" "multi")
8776   (set_attr "length" "8")])
8777
8778(define_insn "call_mcount_64bit"
8779  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8780	 (match_operand 1 "" "i"))
8781   (set (reg:SI 25)
8782	(plus:SI (reg:SI 2)
8783		 (minus:SI (match_operand 2 "" "")
8784			   (plus:SI (pc) (const_int 4)))))
8785   (clobber (reg:DI 2))
8786   (clobber (match_operand 3))
8787   (use (reg:DI 27))
8788   (use (reg:DI 29))]
8789  "TARGET_64BIT"
8790  "#")
8791
8792(define_split
8793  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8794		    (match_operand 1 "" ""))
8795	      (set (reg:SI 25)
8796		   (plus:SI (reg:SI 2)
8797			    (minus:SI (match_operand 2 "" "")
8798				      (plus:SI (pc) (const_int 4)))))
8799	      (clobber (reg:DI 2))
8800	      (clobber (match_operand 3))
8801	      (use (reg:DI 27))
8802	      (use (reg:DI 29))])]
8803  "TARGET_64BIT && reload_completed"
8804  [(set (match_dup 3) (reg:DI 27))
8805   (parallel [(call (mem:SI (match_dup 0))
8806		    (match_dup 1))
8807	      (set (reg:SI 25)
8808		   (plus:SI (reg:SI 2)
8809			    (minus:SI (match_dup 2)
8810				      (plus:SI (pc) (const_int 4)))))
8811	      (clobber (reg:DI 2))
8812	      (use (reg:DI 27))
8813	      (use (reg:DI 29))])
8814   (set (reg:DI 27) (match_dup 3))]
8815  "")
8816
8817(define_insn "*call_mcount_64bit_post_reload"
8818  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8819	 (match_operand 1 "" "i"))
8820   (set (reg:SI 25)
8821	(plus:SI (reg:SI 2)
8822		 (minus:SI (match_operand 2 "" "")
8823			   (plus:SI (pc) (const_int 4)))))
8824   (clobber (reg:DI 2))
8825   (use (reg:DI 27))
8826   (use (reg:DI 29))]
8827  "TARGET_64BIT"
8828  "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8829  [(set_attr "type" "multi")
8830   (set_attr "length" "8")])
8831
8832;; Call subroutine returning any type.
8833
8834(define_expand "untyped_call"
8835  [(parallel [(call (match_operand 0 "" "")
8836		    (const_int 0))
8837	      (match_operand 1 "" "")
8838	      (match_operand 2 "" "")])]
8839  ""
8840  "
8841{
8842  int i;
8843
8844  emit_call_insn (gen_call (operands[0], const0_rtx));
8845
8846  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8847    {
8848      rtx set = XVECEXP (operands[2], 0, i);
8849      emit_move_insn (SET_DEST (set), SET_SRC (set));
8850    }
8851
8852  /* The optimizer does not know that the call sets the function value
8853     registers we stored in the result block.  We avoid problems by
8854     claiming that all hard registers are used and clobbered at this
8855     point.  */
8856  emit_insn (gen_blockage ());
8857
8858  DONE;
8859}")
8860
8861(define_expand "sibcall"
8862  [(call (match_operand:SI 0 "" "")
8863	 (match_operand 1 "" ""))]
8864  "!TARGET_PORTABLE_RUNTIME"
8865  "
8866{
8867  rtx op, call_insn;
8868  rtx nb = operands[1];
8869
8870  op = XEXP (operands[0], 0);
8871
8872  if (TARGET_64BIT)
8873    {
8874      if (!virtuals_instantiated)
8875	emit_move_insn (arg_pointer_rtx,
8876			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8877				      GEN_INT (64)));
8878      else
8879	{
8880	  /* The loop pass can generate new libcalls after the virtual
8881	     registers are instantiated when fpregs are disabled because
8882	     the only method that we have for doing DImode multiplication
8883	     is with a libcall.  This could be trouble if we haven't
8884	     allocated enough space for the outgoing arguments.  */
8885	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8886
8887	  emit_move_insn (arg_pointer_rtx,
8888			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8889					GEN_INT (STACK_POINTER_OFFSET + 64)));
8890	}
8891    }
8892
8893  /* Indirect sibling calls are not allowed.  */
8894  if (TARGET_64BIT)
8895    call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8896  else
8897    call_insn = gen_sibcall_internal_symref (op, operands[1]);
8898
8899  call_insn = emit_call_insn (call_insn);
8900
8901  if (TARGET_64BIT)
8902    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8903
8904  /* We don't have to restore the PIC register.  */
8905  if (flag_pic)
8906    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8907
8908  DONE;
8909}")
8910
8911(define_insn "sibcall_internal_symref"
8912  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8913	 (match_operand 1 "" "i"))
8914   (clobber (reg:SI 1))
8915   (use (reg:SI 2))
8916   (use (const_int 0))]
8917  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8918  "*
8919{
8920  pa_output_arg_descriptor (insn);
8921  return pa_output_call (insn, operands[0], 1);
8922}"
8923  [(set_attr "type" "sibcall")
8924   (set (attr "length")
8925	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8926	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8927
8928(define_insn "sibcall_internal_symref_64bit"
8929  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8930	 (match_operand 1 "" "i"))
8931   (clobber (reg:DI 1))
8932   (use (reg:DI 2))
8933   (use (const_int 0))]
8934  "TARGET_64BIT"
8935  "*
8936{
8937  return pa_output_call (insn, operands[0], 1);
8938}"
8939  [(set_attr "type" "sibcall")
8940   (set (attr "length")
8941	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8942	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8943
8944(define_expand "sibcall_value"
8945  [(set (match_operand 0 "" "")
8946		   (call (match_operand:SI 1 "" "")
8947			 (match_operand 2 "" "")))]
8948  "!TARGET_PORTABLE_RUNTIME"
8949  "
8950{
8951  rtx op, call_insn;
8952  rtx nb = operands[1];
8953
8954  op = XEXP (operands[1], 0);
8955
8956  if (TARGET_64BIT)
8957    {
8958      if (!virtuals_instantiated)
8959	emit_move_insn (arg_pointer_rtx,
8960			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8961				      GEN_INT (64)));
8962      else
8963	{
8964	  /* The loop pass can generate new libcalls after the virtual
8965	     registers are instantiated when fpregs are disabled because
8966	     the only method that we have for doing DImode multiplication
8967	     is with a libcall.  This could be trouble if we haven't
8968	     allocated enough space for the outgoing arguments.  */
8969	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8970
8971	  emit_move_insn (arg_pointer_rtx,
8972			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8973					GEN_INT (STACK_POINTER_OFFSET + 64)));
8974	}
8975    }
8976
8977  /* Indirect sibling calls are not allowed.  */
8978  if (TARGET_64BIT)
8979    call_insn
8980      = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8981  else
8982    call_insn
8983      = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8984
8985  call_insn = emit_call_insn (call_insn);
8986
8987  if (TARGET_64BIT)
8988    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8989
8990  /* We don't have to restore the PIC register.  */
8991  if (flag_pic)
8992    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8993
8994  DONE;
8995}")
8996
8997(define_insn "sibcall_value_internal_symref"
8998  [(set (match_operand 0 "" "")
8999	(call (mem:SI (match_operand 1 "call_operand_address" ""))
9000	      (match_operand 2 "" "i")))
9001   (clobber (reg:SI 1))
9002   (use (reg:SI 2))
9003   (use (const_int 0))]
9004  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9005  "*
9006{
9007  pa_output_arg_descriptor (insn);
9008  return pa_output_call (insn, operands[1], 1);
9009}"
9010  [(set_attr "type" "sibcall")
9011   (set (attr "length")
9012	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9013	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
9014
9015(define_insn "sibcall_value_internal_symref_64bit"
9016  [(set (match_operand 0 "" "")
9017	(call (mem:SI (match_operand 1 "call_operand_address" ""))
9018	      (match_operand 2 "" "i")))
9019   (clobber (reg:DI 1))
9020   (use (reg:DI 2))
9021   (use (const_int 0))]
9022  "TARGET_64BIT"
9023  "*
9024{
9025  return pa_output_call (insn, operands[1], 1);
9026}"
9027  [(set_attr "type" "sibcall")
9028   (set (attr "length")
9029	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9030	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
9031
9032(define_insn "nop"
9033  [(const_int 0)]
9034  ""
9035  "nop"
9036  [(set_attr "type" "move")
9037   (set_attr "length" "4")])
9038
9039;;; EH does longjmp's from and within the data section.  Thus,
9040;;; an interspace branch is required for the longjmp implementation.
9041;;; Registers r1 and r2 are used as scratch registers for the jump
9042;;; when necessary.
9043(define_expand "interspace_jump"
9044  [(parallel
9045     [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9046      (clobber (match_dup 1))])]
9047  ""
9048  "
9049{
9050  operands[1] = gen_rtx_REG (word_mode, 2);
9051}")
9052
9053(define_insn ""
9054  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9055  (clobber (reg:SI 2))]
9056  "TARGET_PA_20 && !TARGET_64BIT"
9057  "bve%* (%0)"
9058   [(set_attr "type" "branch")
9059    (set_attr "length" "4")])
9060
9061(define_insn ""
9062  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9063  (clobber (reg:SI 2))]
9064  "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
9065  "be%* 0(%%sr4,%0)"
9066   [(set_attr "type" "branch")
9067    (set_attr "length" "4")])
9068
9069(define_insn ""
9070  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9071  (clobber (reg:SI 2))]
9072  "!TARGET_64BIT"
9073  "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
9074   [(set_attr "type" "branch")
9075    (set_attr "length" "12")])
9076
9077(define_insn ""
9078  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9079  (clobber (reg:DI 2))]
9080  "TARGET_64BIT"
9081  "bve%* (%0)"
9082   [(set_attr "type" "branch")
9083    (set_attr "length" "4")])
9084
9085(define_expand "builtin_longjmp"
9086  [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
9087  ""
9088  "
9089{
9090  /* The elements of the buffer are, in order:  */
9091  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9092  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9093			 POINTER_SIZE / BITS_PER_UNIT));
9094  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9095			   (POINTER_SIZE * 2) / BITS_PER_UNIT));
9096  rtx pv = gen_rtx_REG (Pmode, 1);
9097
9098  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
9099  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
9100
9101  /* Load the label we are jumping through into r1 so that we know
9102     where to look for it when we get back to setjmp's function for
9103     restoring the gp.  */
9104  emit_move_insn (pv, lab);
9105
9106  /* Restore the stack and frame pointers.  */
9107  fp = copy_to_reg (fp);
9108  emit_stack_restore (SAVE_NONLOCAL, stack);
9109
9110  /* Ensure the frame pointer move is not optimized.  */
9111  emit_insn (gen_blockage ());
9112  emit_clobber (hard_frame_pointer_rtx);
9113  emit_clobber (frame_pointer_rtx);
9114  emit_move_insn (hard_frame_pointer_rtx, fp);
9115
9116  emit_use (hard_frame_pointer_rtx);
9117  emit_use (stack_pointer_rtx);
9118
9119  /* Prevent the insns above from being scheduled into the delay slot
9120     of the interspace jump because the space register could change.  */
9121  emit_insn (gen_blockage ());
9122
9123  emit_jump_insn (gen_interspace_jump (pv));
9124  emit_barrier ();
9125  DONE;
9126}")
9127
9128;;; Operands 2 and 3 are assumed to be CONST_INTs.
9129(define_expand "extzvsi"
9130  [(set (match_operand:SI 0 "register_operand" "")
9131	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
9132			 (match_operand:SI 2 "uint5_operand" "")
9133			 (match_operand:SI 3 "uint5_operand" "")))]
9134  ""
9135  "
9136{
9137  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9138  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9139
9140  /* PA extraction insns don't support zero length bitfields or fields
9141     extending beyond the left or right-most bits.  Also, the predicate
9142     rejects lengths equal to a word as they are better handled by
9143     the move patterns.  */
9144  if (len == 0 || pos + len > 32)
9145    FAIL;
9146
9147  /* From mips.md: extract_bit_field doesn't verify that our source
9148     matches the predicate, so check it again here.  */
9149  if (!register_operand (operands[1], VOIDmode))
9150    FAIL;
9151
9152  emit_insn (gen_extzv_32 (operands[0], operands[1],
9153			   operands[2], operands[3]));
9154  DONE;
9155}")
9156
9157(define_insn "extzv_32"
9158  [(set (match_operand:SI 0 "register_operand" "=r")
9159	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9160			 (match_operand:SI 2 "uint5_operand" "")
9161			 (match_operand:SI 3 "uint5_operand" "")))]
9162  "UINTVAL (operands[2]) > 0
9163   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9164  "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9165  [(set_attr "type" "shift")
9166   (set_attr "length" "4")])
9167
9168(define_insn ""
9169  [(set (match_operand:SI 0 "register_operand" "=r")
9170	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9171			 (const_int 1)
9172			 (match_operand:SI 2 "register_operand" "q")))]
9173  ""
9174  "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9175  [(set_attr "type" "shift")
9176   (set_attr "length" "4")])
9177
9178(define_expand "extzvdi"
9179  [(set (match_operand:DI 0 "register_operand" "")
9180	(zero_extract:DI (match_operand:DI 1 "register_operand" "")
9181			 (match_operand:DI 2 "uint6_operand" "")
9182			 (match_operand:DI 3 "uint6_operand" "")))]
9183  "TARGET_64BIT"
9184  "
9185{
9186  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9187  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9188
9189  /* PA extraction insns don't support zero length bitfields or fields
9190     extending beyond the left or right-most bits.  Also, the predicate
9191     rejects lengths equal to a doubleword as they are better handled by
9192     the move patterns.  */
9193  if (len == 0 || pos + len > 64)
9194    FAIL;
9195
9196  /* From mips.md: extract_bit_field doesn't verify that our source
9197     matches the predicate, so check it again here.  */
9198  if (!register_operand (operands[1], VOIDmode))
9199    FAIL;
9200
9201  emit_insn (gen_extzv_64 (operands[0], operands[1],
9202			   operands[2], operands[3]));
9203  DONE;
9204}")
9205
9206(define_insn "extzv_64"
9207  [(set (match_operand:DI 0 "register_operand" "=r")
9208	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9209			 (match_operand:DI 2 "uint6_operand" "")
9210			 (match_operand:DI 3 "uint6_operand" "")))]
9211  "TARGET_64BIT
9212   && UINTVAL (operands[2]) > 0
9213   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9214  "extrd,u %1,%3+%2-1,%2,%0"
9215  [(set_attr "type" "shift")
9216   (set_attr "length" "4")])
9217
9218(define_insn ""
9219  [(set (match_operand:DI 0 "register_operand" "=r")
9220	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9221			 (const_int 1)
9222			 (match_operand:DI 2 "register_operand" "q")))]
9223  "TARGET_64BIT"
9224  "extrd,u %1,%%sar,1,%0"
9225  [(set_attr "type" "shift")
9226   (set_attr "length" "4")])
9227
9228;;; Operands 2 and 3 are assumed to be CONST_INTs.
9229(define_expand "extvsi"
9230  [(set (match_operand:SI 0 "register_operand" "")
9231	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
9232			 (match_operand:SI 2 "uint5_operand" "")
9233			 (match_operand:SI 3 "uint5_operand" "")))]
9234  ""
9235  "
9236{
9237  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9238  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9239
9240  /* PA extraction insns don't support zero length bitfields or fields
9241     extending beyond the left or right-most bits.  Also, the predicate
9242     rejects lengths equal to a word as they are better handled by
9243     the move patterns.  */
9244  if (len == 0 || pos + len > 32)
9245    FAIL;
9246
9247  /* From mips.md: extract_bit_field doesn't verify that our source
9248     matches the predicate, so check it again here.  */
9249  if (!register_operand (operands[1], VOIDmode))
9250    FAIL;
9251
9252  emit_insn (gen_extv_32 (operands[0], operands[1],
9253			  operands[2], operands[3]));
9254  DONE;
9255}")
9256
9257(define_insn "extv_32"
9258  [(set (match_operand:SI 0 "register_operand" "=r")
9259	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9260			 (match_operand:SI 2 "uint5_operand" "")
9261			 (match_operand:SI 3 "uint5_operand" "")))]
9262  "UINTVAL (operands[2]) > 0
9263   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9264  "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9265  [(set_attr "type" "shift")
9266   (set_attr "length" "4")])
9267
9268(define_insn ""
9269  [(set (match_operand:SI 0 "register_operand" "=r")
9270	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9271			 (const_int 1)
9272			 (match_operand:SI 2 "register_operand" "q")))]
9273  "!TARGET_64BIT"
9274  "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9275  [(set_attr "type" "shift")
9276   (set_attr "length" "4")])
9277
9278(define_expand "extvdi"
9279  [(set (match_operand:DI 0 "register_operand" "")
9280	(sign_extract:DI (match_operand:DI 1 "register_operand" "")
9281			 (match_operand:DI 2 "uint6_operand" "")
9282			 (match_operand:DI 3 "uint6_operand" "")))]
9283  "TARGET_64BIT"
9284  "
9285{
9286  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9287  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9288
9289  /* PA extraction insns don't support zero length bitfields or fields
9290     extending beyond the left or right-most bits.  Also, the predicate
9291     rejects lengths equal to a doubleword as they are better handled by
9292     the move patterns.  */
9293  if (len == 0 || pos + len > 64)
9294    FAIL;
9295
9296  /* From mips.md: extract_bit_field doesn't verify that our source
9297     matches the predicate, so check it again here.  */
9298  if (!register_operand (operands[1], VOIDmode))
9299    FAIL;
9300
9301  emit_insn (gen_extv_64 (operands[0], operands[1],
9302			  operands[2], operands[3]));
9303  DONE;
9304}")
9305
9306(define_insn "extv_64"
9307  [(set (match_operand:DI 0 "register_operand" "=r")
9308	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9309			 (match_operand:DI 2 "uint6_operand" "")
9310			 (match_operand:DI 3 "uint6_operand" "")))]
9311  "TARGET_64BIT
9312   && UINTVAL (operands[2]) > 0
9313   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9314  "extrd,s %1,%3+%2-1,%2,%0"
9315  [(set_attr "type" "shift")
9316   (set_attr "length" "4")])
9317
9318(define_insn ""
9319  [(set (match_operand:DI 0 "register_operand" "=r")
9320	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9321			 (const_int 1)
9322			 (match_operand:DI 2 "register_operand" "q")))]
9323  "TARGET_64BIT"
9324  "extrd,s %1,%%sar,1,%0"
9325  [(set_attr "type" "shift")
9326   (set_attr "length" "4")])
9327
9328;;; Operands 1 and 2 are assumed to be CONST_INTs.
9329(define_expand "insvsi"
9330  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9331			 (match_operand:SI 1 "uint5_operand" "")
9332			 (match_operand:SI 2 "uint5_operand" ""))
9333	(match_operand:SI 3 "arith5_operand" ""))]
9334  ""
9335  "
9336{
9337  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9338  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9339
9340  /* PA insertion insns don't support zero length bitfields or fields
9341     extending beyond the left or right-most bits.  Also, the predicate
9342     rejects lengths equal to a word as they are better handled by
9343     the move patterns.  */
9344  if (len <= 0 || pos + len > 32)
9345    FAIL;
9346
9347  /* From mips.md: insert_bit_field doesn't verify that our destination
9348     matches the predicate, so check it again here.  */
9349  if (!register_operand (operands[0], VOIDmode))
9350    FAIL;
9351
9352  emit_insn (gen_insv_32 (operands[0], operands[1],
9353			  operands[2], operands[3]));
9354  DONE;
9355}")
9356
9357(define_insn "insv_32"
9358  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9359			 (match_operand:SI 1 "uint5_operand" "")
9360			 (match_operand:SI 2 "uint5_operand" ""))
9361	(match_operand:SI 3 "arith5_operand" "r,L"))]
9362  "UINTVAL (operands[1]) > 0
9363   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9364  "@
9365   {dep|depw} %3,%2+%1-1,%1,%0
9366   {depi|depwi} %3,%2+%1-1,%1,%0"
9367  [(set_attr "type" "shift,shift")
9368   (set_attr "length" "4,4")])
9369
9370;; Optimize insertion of const_int values of type 1...1xxxx.
9371(define_insn ""
9372  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9373			 (match_operand:SI 1 "uint5_operand" "")
9374			 (match_operand:SI 2 "uint5_operand" ""))
9375	(match_operand:SI 3 "const_int_operand" ""))]
9376  "(INTVAL (operands[3]) & 0x10) != 0 &&
9377   (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9378  "*
9379{
9380  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9381  return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9382}"
9383  [(set_attr "type" "shift")
9384   (set_attr "length" "4")])
9385
9386(define_expand "insvdi"
9387  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9388			 (match_operand:DI 1 "uint6_operand" "")
9389			 (match_operand:DI 2 "uint6_operand" ""))
9390	(match_operand:DI 3 "arith5_operand" ""))]
9391  "TARGET_64BIT"
9392  "
9393{
9394  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9395  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9396
9397  /* PA insertion insns don't support zero length bitfields or fields
9398     extending beyond the left or right-most bits.  Also, the predicate
9399     rejects lengths equal to a doubleword as they are better handled by
9400     the move patterns.  */
9401  if (len <= 0 || pos + len > 64)
9402    FAIL;
9403
9404  /* From mips.md: insert_bit_field doesn't verify that our destination
9405     matches the predicate, so check it again here.  */
9406  if (!register_operand (operands[0], VOIDmode))
9407    FAIL;
9408
9409  emit_insn (gen_insv_64 (operands[0], operands[1],
9410			  operands[2], operands[3]));
9411  DONE;
9412}")
9413
9414(define_insn "insv_64"
9415  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9416			 (match_operand:DI 1 "uint6_operand" "")
9417			 (match_operand:DI 2 "uint6_operand" ""))
9418	(match_operand:DI 3 "arith5_operand" "r,L"))]
9419  "TARGET_64BIT
9420   && UINTVAL (operands[1]) > 0
9421   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9422  "@
9423   depd %3,%2+%1-1,%1,%0
9424   depdi %3,%2+%1-1,%1,%0"
9425  [(set_attr "type" "shift,shift")
9426   (set_attr "length" "4,4")])
9427
9428;; Optimize insertion of const_int values of type 1...1xxxx.
9429(define_insn ""
9430  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9431			 (match_operand:DI 1 "uint6_operand" "")
9432			 (match_operand:DI 2 "uint6_operand" ""))
9433	(match_operand:DI 3 "const_int_operand" ""))]
9434  "(INTVAL (operands[3]) & 0x10) != 0
9435   && TARGET_64BIT
9436   && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9437  "*
9438{
9439  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9440  return \"depdi %3,%2+%1-1,%1,%0\";
9441}"
9442  [(set_attr "type" "shift")
9443   (set_attr "length" "4")])
9444
9445(define_insn ""
9446  [(set (match_operand:DI 0 "register_operand" "=r")
9447	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9448		   (const_int 32)))]
9449  "TARGET_64BIT"
9450  "depd,z %1,31,32,%0"
9451  [(set_attr "type" "shift")
9452   (set_attr "length" "4")])
9453
9454;; This insn is used for some loop tests, typically loops reversed when
9455;; strength reduction is used.  It is actually created when the instruction
9456;; combination phase combines the special loop test.  Since this insn
9457;; is both a jump insn and has an output, it must deal with its own
9458;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9459;; to not choose the register alternatives in the event a reload is needed.
9460(define_insn "decrement_and_branch_until_zero"
9461  [(set (pc)
9462	(if_then_else
9463	  (match_operator 2 "ordered_comparison_operator"
9464	   [(plus:SI
9465	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9466	      (match_operand:SI 1 "int5_operand" "L,L,L"))
9467	    (const_int 0)])
9468	  (label_ref (match_operand 3 "" ""))
9469	  (pc)))
9470   (set (match_dup 0)
9471	(plus:SI (match_dup 0) (match_dup 1)))
9472   (clobber (match_scratch:SI 4 "=X,r,r"))]
9473  ""
9474  "* return pa_output_dbra (operands, insn, which_alternative); "
9475;; Do not expect to understand this the first time through.
9476[(set_attr "type" "cbranch,multi,multi")
9477 (set (attr "length")
9478      (if_then_else (eq_attr "alternative" "0")
9479;; Loop counter in register case
9480;; Short branch has length of 4
9481;; Long branch has length of 8, 20, 24 or 28
9482	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9483	       (const_int MAX_12BIT_OFFSET))
9484	   (const_int 4)
9485	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9486	       (const_int MAX_17BIT_OFFSET))
9487	   (const_int 8)
9488	   (match_test "TARGET_PORTABLE_RUNTIME")
9489	   (const_int 24)
9490	   (not (match_test "flag_pic"))
9491	   (const_int 20)]
9492	  (const_int 28))
9493
9494;; Loop counter in FP reg case.
9495;; Extra goo to deal with additional reload insns.
9496	(if_then_else (eq_attr "alternative" "1")
9497	  (if_then_else (lt (match_dup 3) (pc))
9498	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9499		      (const_int MAX_12BIT_OFFSET))
9500		    (const_int 24)
9501		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9502		      (const_int MAX_17BIT_OFFSET))
9503		    (const_int 28)
9504		    (match_test "TARGET_PORTABLE_RUNTIME")
9505		    (const_int 44)
9506		    (not (match_test "flag_pic"))
9507		    (const_int 40)]
9508		  (const_int 48))
9509	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9510		      (const_int MAX_12BIT_OFFSET))
9511		    (const_int 24)
9512		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9513		      (const_int MAX_17BIT_OFFSET))
9514		    (const_int 28)
9515		    (match_test "TARGET_PORTABLE_RUNTIME")
9516		    (const_int 44)
9517		    (not (match_test "flag_pic"))
9518		    (const_int 40)]
9519		  (const_int 48)))
9520
9521;; Loop counter in memory case.
9522;; Extra goo to deal with additional reload insns.
9523	(if_then_else (lt (match_dup 3) (pc))
9524	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9525		      (const_int MAX_12BIT_OFFSET))
9526		    (const_int 12)
9527		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9528		      (const_int MAX_17BIT_OFFSET))
9529		    (const_int 16)
9530		    (match_test "TARGET_PORTABLE_RUNTIME")
9531		    (const_int 32)
9532		    (not (match_test "flag_pic"))
9533		    (const_int 28)]
9534		  (const_int 36))
9535	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9536		      (const_int MAX_12BIT_OFFSET))
9537		    (const_int 12)
9538		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9539		      (const_int MAX_17BIT_OFFSET))
9540		    (const_int 16)
9541		    (match_test "TARGET_PORTABLE_RUNTIME")
9542		    (const_int 32)
9543		    (not (match_test "flag_pic"))
9544		    (const_int 28)]
9545		  (const_int 36))))))])
9546
9547(define_insn ""
9548  [(set (pc)
9549	(if_then_else
9550	  (match_operator 2 "movb_comparison_operator"
9551	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9552	  (label_ref (match_operand 3 "" ""))
9553	  (pc)))
9554   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9555	(match_dup 1))]
9556  ""
9557"* return pa_output_movb (operands, insn, which_alternative, 0); "
9558;; Do not expect to understand this the first time through.
9559[(set_attr "type" "cbranch,multi,multi,multi")
9560 (set (attr "length")
9561      (if_then_else (eq_attr "alternative" "0")
9562;; Loop counter in register case
9563;; Short branch has length of 4
9564;; Long branch has length of 8, 20, 24 or 28
9565        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9566	       (const_int MAX_12BIT_OFFSET))
9567	   (const_int 4)
9568	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9569	       (const_int MAX_17BIT_OFFSET))
9570	   (const_int 8)
9571	   (match_test "TARGET_PORTABLE_RUNTIME")
9572	   (const_int 24)
9573	   (not (match_test "flag_pic"))
9574	   (const_int 20)]
9575	  (const_int 28))
9576
9577;; Loop counter in FP reg case.
9578;; Extra goo to deal with additional reload insns.
9579	(if_then_else (eq_attr "alternative" "1")
9580	  (if_then_else (lt (match_dup 3) (pc))
9581	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9582		      (const_int MAX_12BIT_OFFSET))
9583		    (const_int 12)
9584		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9585		      (const_int MAX_17BIT_OFFSET))
9586		    (const_int 16)
9587		    (match_test "TARGET_PORTABLE_RUNTIME")
9588		    (const_int 32)
9589		    (not (match_test "flag_pic"))
9590		    (const_int 28)]
9591		  (const_int 36))
9592	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9593		      (const_int MAX_12BIT_OFFSET))
9594		    (const_int 12)
9595		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9596		      (const_int MAX_17BIT_OFFSET))
9597		    (const_int 16)
9598		    (match_test "TARGET_PORTABLE_RUNTIME")
9599		    (const_int 32)
9600		    (not (match_test "flag_pic"))
9601		    (const_int 28)]
9602		  (const_int 36)))
9603
9604;; Loop counter in memory or sar case.
9605;; Extra goo to deal with additional reload insns.
9606	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9607		   (const_int MAX_12BIT_OFFSET))
9608		(const_int 8)
9609		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9610		  (const_int MAX_17BIT_OFFSET))
9611		(const_int 12)
9612		(match_test "TARGET_PORTABLE_RUNTIME")
9613		(const_int 28)
9614		(not (match_test "flag_pic"))
9615		(const_int 24)]
9616	      (const_int 32)))))])
9617
9618;; Handle negated branch.
9619(define_insn ""
9620  [(set (pc)
9621	(if_then_else
9622	  (match_operator 2 "movb_comparison_operator"
9623	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9624	  (pc)
9625	  (label_ref (match_operand 3 "" ""))))
9626   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9627	(match_dup 1))]
9628  ""
9629"* return pa_output_movb (operands, insn, which_alternative, 1); "
9630;; Do not expect to understand this the first time through.
9631[(set_attr "type" "cbranch,multi,multi,multi")
9632 (set (attr "length")
9633      (if_then_else (eq_attr "alternative" "0")
9634;; Loop counter in register case
9635;; Short branch has length of 4
9636;; Long branch has length of 8
9637        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9638	       (const_int MAX_12BIT_OFFSET))
9639	   (const_int 4)
9640	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9641	       (const_int MAX_17BIT_OFFSET))
9642	   (const_int 8)
9643	   (match_test "TARGET_PORTABLE_RUNTIME")
9644	   (const_int 24)
9645	   (not (match_test "flag_pic"))
9646	   (const_int 20)]
9647	  (const_int 28))
9648
9649;; Loop counter in FP reg case.
9650;; Extra goo to deal with additional reload insns.
9651	(if_then_else (eq_attr "alternative" "1")
9652	  (if_then_else (lt (match_dup 3) (pc))
9653	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9654		      (const_int MAX_12BIT_OFFSET))
9655		    (const_int 12)
9656		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9657		      (const_int MAX_17BIT_OFFSET))
9658		    (const_int 16)
9659		    (match_test "TARGET_PORTABLE_RUNTIME")
9660		    (const_int 32)
9661		    (not (match_test "flag_pic"))
9662		    (const_int 28)]
9663		  (const_int 36))
9664	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9665		      (const_int MAX_12BIT_OFFSET))
9666		    (const_int 12)
9667		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9668		      (const_int MAX_17BIT_OFFSET))
9669		    (const_int 16)
9670		    (match_test "TARGET_PORTABLE_RUNTIME")
9671		    (const_int 32)
9672		    (not (match_test "flag_pic"))
9673		    (const_int 28)]
9674		  (const_int 36)))
9675
9676;; Loop counter in memory or SAR case.
9677;; Extra goo to deal with additional reload insns.
9678	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9679		   (const_int MAX_12BIT_OFFSET))
9680		(const_int 8)
9681		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9682		  (const_int MAX_17BIT_OFFSET))
9683		(const_int 12)
9684		(match_test "TARGET_PORTABLE_RUNTIME")
9685		(const_int 28)
9686		(not (match_test "flag_pic"))
9687		(const_int 24)]
9688	      (const_int 32)))))])
9689
9690(define_insn ""
9691  [(set (pc) (label_ref (match_operand 3 "" "" )))
9692   (set (match_operand:SI 0 "ireg_operand" "=r")
9693	(plus:SI (match_operand:SI 1 "ireg_operand" "r")
9694		 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9695  "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9696  "*
9697{
9698  return pa_output_parallel_addb (operands, insn);
9699}"
9700[(set_attr "type" "parallel_branch")
9701 (set (attr "length")
9702    (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9703	       (const_int MAX_12BIT_OFFSET))
9704	   (const_int 4)
9705	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9706	       (const_int MAX_17BIT_OFFSET))
9707	   (const_int 8)
9708	   (match_test "TARGET_PORTABLE_RUNTIME")
9709	   (const_int 24)
9710	   (not (match_test "flag_pic"))
9711	   (const_int 20)]
9712	  (const_int 28)))])
9713
9714(define_insn ""
9715  [(set (pc) (label_ref (match_operand 2 "" "" )))
9716   (set (match_operand:SF 0 "ireg_operand" "=r")
9717	(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9718  "reload_completed"
9719  "*
9720{
9721  return pa_output_parallel_movb (operands, insn);
9722}"
9723[(set_attr "type" "parallel_branch")
9724 (set (attr "length")
9725    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9726	       (const_int MAX_12BIT_OFFSET))
9727	   (const_int 4)
9728	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9729	       (const_int MAX_17BIT_OFFSET))
9730	   (const_int 8)
9731	   (match_test "TARGET_PORTABLE_RUNTIME")
9732	   (const_int 24)
9733	   (not (match_test "flag_pic"))
9734	   (const_int 20)]
9735	  (const_int 28)))])
9736
9737(define_insn ""
9738  [(set (pc) (label_ref (match_operand 2 "" "" )))
9739   (set (match_operand:SI 0 "ireg_operand" "=r")
9740	(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9741  "reload_completed"
9742  "*
9743{
9744  return pa_output_parallel_movb (operands, insn);
9745}"
9746[(set_attr "type" "parallel_branch")
9747 (set (attr "length")
9748    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9749	       (const_int MAX_12BIT_OFFSET))
9750	   (const_int 4)
9751	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9752	       (const_int MAX_17BIT_OFFSET))
9753	   (const_int 8)
9754	   (match_test "TARGET_PORTABLE_RUNTIME")
9755	   (const_int 24)
9756	   (not (match_test "flag_pic"))
9757	   (const_int 20)]
9758	  (const_int 28)))])
9759
9760(define_insn ""
9761  [(set (pc) (label_ref (match_operand 2 "" "" )))
9762   (set (match_operand:HI 0 "ireg_operand" "=r")
9763	(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9764  "reload_completed"
9765  "*
9766{
9767  return pa_output_parallel_movb (operands, insn);
9768}"
9769[(set_attr "type" "parallel_branch")
9770 (set (attr "length")
9771    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9772	       (const_int MAX_12BIT_OFFSET))
9773	   (const_int 4)
9774	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9775	       (const_int MAX_17BIT_OFFSET))
9776	   (const_int 8)
9777	   (match_test "TARGET_PORTABLE_RUNTIME")
9778	   (const_int 24)
9779	   (not (match_test "flag_pic"))
9780	   (const_int 20)]
9781	  (const_int 28)))])
9782
9783(define_insn ""
9784  [(set (pc) (label_ref (match_operand 2 "" "" )))
9785   (set (match_operand:QI 0 "ireg_operand" "=r")
9786	(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9787  "reload_completed"
9788  "*
9789{
9790  return pa_output_parallel_movb (operands, insn);
9791}"
9792[(set_attr "type" "parallel_branch")
9793 (set (attr "length")
9794    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9795	       (const_int MAX_12BIT_OFFSET))
9796	   (const_int 4)
9797	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9798	       (const_int MAX_17BIT_OFFSET))
9799	   (const_int 8)
9800	   (match_test "TARGET_PORTABLE_RUNTIME")
9801	   (const_int 24)
9802	   (not (match_test "flag_pic"))
9803	   (const_int 20)]
9804	  (const_int 28)))])
9805
9806(define_insn ""
9807  [(set (match_operand 0 "register_operand" "=f")
9808	(mult (match_operand 1 "register_operand" "f")
9809	      (match_operand 2 "register_operand" "f")))
9810   (set (match_operand 3 "register_operand" "+f")
9811	(plus (match_operand 4 "register_operand" "f")
9812	      (match_operand 5 "register_operand" "f")))]
9813  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9814   && reload_completed && pa_fmpyaddoperands (operands)"
9815  "*
9816{
9817  if (GET_MODE (operands[0]) == DFmode)
9818    {
9819      if (rtx_equal_p (operands[3], operands[5]))
9820	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9821      else
9822	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9823    }
9824  else
9825    {
9826      if (rtx_equal_p (operands[3], operands[5]))
9827	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9828      else
9829	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9830    }
9831}"
9832  [(set_attr "type" "fpalu")
9833   (set_attr "length" "4")])
9834
9835(define_insn ""
9836  [(set (match_operand 3 "register_operand" "+f")
9837	(plus (match_operand 4 "register_operand" "f")
9838	      (match_operand 5 "register_operand" "f")))
9839   (set (match_operand 0 "register_operand" "=f")
9840	(mult (match_operand 1 "register_operand" "f")
9841	      (match_operand 2 "register_operand" "f")))]
9842  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9843   && reload_completed && pa_fmpyaddoperands (operands)"
9844  "*
9845{
9846  if (GET_MODE (operands[0]) == DFmode)
9847    {
9848      if (rtx_equal_p (operands[3], operands[5]))
9849	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9850      else
9851	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9852    }
9853  else
9854    {
9855      if (rtx_equal_p (operands[3], operands[5]))
9856	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9857      else
9858	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9859    }
9860}"
9861  [(set_attr "type" "fpalu")
9862   (set_attr "length" "4")])
9863
9864(define_insn ""
9865  [(set (match_operand 0 "register_operand" "=f")
9866	(mult (match_operand 1 "register_operand" "f")
9867	      (match_operand 2 "register_operand" "f")))
9868   (set (match_operand 3 "register_operand" "+f")
9869	(minus (match_operand 4 "register_operand" "f")
9870	       (match_operand 5 "register_operand" "f")))]
9871  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9872   && reload_completed && pa_fmpysuboperands (operands)"
9873  "*
9874{
9875  if (GET_MODE (operands[0]) == DFmode)
9876    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9877  else
9878    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9879}"
9880  [(set_attr "type" "fpalu")
9881   (set_attr "length" "4")])
9882
9883(define_insn ""
9884  [(set (match_operand 3 "register_operand" "+f")
9885	(minus (match_operand 4 "register_operand" "f")
9886	       (match_operand 5 "register_operand" "f")))
9887   (set (match_operand 0 "register_operand" "=f")
9888	(mult (match_operand 1 "register_operand" "f")
9889	      (match_operand 2 "register_operand" "f")))]
9890  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9891   && reload_completed && pa_fmpysuboperands (operands)"
9892  "*
9893{
9894  if (GET_MODE (operands[0]) == DFmode)
9895    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9896  else
9897    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9898}"
9899  [(set_attr "type" "fpalu")
9900   (set_attr "length" "4")])
9901
9902;; The following two patterns are used by the trampoline code for nested
9903;; functions.  They flush the I and D cache lines from the start address
9904;; (operand0) to the end address (operand1).  No lines are flushed if the
9905;; end address is less than the start address (unsigned).
9906;;
9907;; Because the range of memory flushed is variable and the size of a MEM
9908;; can only be a CONST_INT, the patterns specify that they perform an
9909;; unspecified volatile operation on all memory.
9910;;
9911;; The address range for an icache flush must lie within a single
9912;; space on targets with non-equivalent space registers.
9913;;
9914;; Operand 0 contains the start address.
9915;; Operand 1 contains the end address.
9916;; Operand 2 contains the line length to use.
9917(define_insn "dcacheflush<P:mode>"
9918  [(const_int 1)
9919   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9920   (use (match_operand 0 "pmode_register_operand" "r"))
9921   (use (match_operand 1 "pmode_register_operand" "r"))
9922   (use (match_operand 2 "pmode_register_operand" "r"))
9923   (clobber (match_scratch:P 3 "=&0"))]
9924  ""
9925  "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9926  [(set_attr "type" "multi")
9927   (set_attr "length" "12")])
9928
9929(define_insn "icacheflush<P:mode>"
9930  [(const_int 2)
9931   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9932   (use (match_operand 0 "pmode_register_operand" "r"))
9933   (use (match_operand 1 "pmode_register_operand" "r"))
9934   (use (match_operand 2 "pmode_register_operand" "r"))
9935   (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9936   (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9937   (clobber (match_scratch:P 5 "=&0"))]
9938  ""
9939  "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"
9940  [(set_attr "type" "multi")
9941   (set_attr "length" "52")])
9942
9943;; An out-of-line prologue.
9944(define_insn "outline_prologue_call"
9945  [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9946   (clobber (reg:SI 31))
9947   (clobber (reg:SI 22))
9948   (clobber (reg:SI 21))
9949   (clobber (reg:SI 20))
9950   (clobber (reg:SI 19))
9951   (clobber (reg:SI 1))]
9952  ""
9953  "*
9954{
9955
9956  /* We need two different versions depending on whether or not we
9957     need a frame pointer.   Also note that we return to the instruction
9958     immediately after the branch rather than two instructions after the
9959     break as normally is the case.  */
9960  if (frame_pointer_needed)
9961    {
9962      /* Must import the magic millicode routine(s).  */
9963      output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9964
9965      if (TARGET_PORTABLE_RUNTIME)
9966	{
9967	  output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9968	  output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9969			   NULL);
9970	}
9971      else
9972	output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9973    }
9974  else
9975    {
9976      /* Must import the magic millicode routine(s).  */
9977      output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9978
9979      if (TARGET_PORTABLE_RUNTIME)
9980	{
9981	  output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9982	  output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9983	}
9984      else
9985	output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9986    }
9987  return \"\";
9988}"
9989  [(set_attr "type" "multi")
9990   (set_attr "length" "8")])
9991
9992;; An out-of-line epilogue.
9993(define_insn "outline_epilogue_call"
9994  [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9995   (use (reg:SI 29))
9996   (use (reg:SI 28))
9997   (clobber (reg:SI 31))
9998   (clobber (reg:SI 22))
9999   (clobber (reg:SI 21))
10000   (clobber (reg:SI 20))
10001   (clobber (reg:SI 19))
10002   (clobber (reg:SI 2))
10003   (clobber (reg:SI 1))]
10004  ""
10005  "*
10006{
10007
10008  /* We need two different versions depending on whether or not we
10009     need a frame pointer.   Also note that we return to the instruction
10010     immediately after the branch rather than two instructions after the
10011     break as normally is the case.  */
10012  if (frame_pointer_needed)
10013    {
10014      /* Must import the magic millicode routine.  */
10015      output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
10016
10017      /* The out-of-line prologue will make sure we return to the right
10018	 instruction.  */
10019      if (TARGET_PORTABLE_RUNTIME)
10020	{
10021	  output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
10022	  output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
10023			   NULL);
10024	}
10025      else
10026	output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
10027    }
10028  else
10029    {
10030      /* Must import the magic millicode routine.  */
10031      output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
10032
10033      /* The out-of-line prologue will make sure we return to the right
10034	 instruction.  */
10035      if (TARGET_PORTABLE_RUNTIME)
10036	{
10037	  output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
10038	  output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
10039	}
10040      else
10041	output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
10042    }
10043  return \"\";
10044}"
10045  [(set_attr "type" "multi")
10046   (set_attr "length" "8")])
10047
10048;; Given a function pointer, canonicalize it so it can be
10049;; reliably compared to another function pointer.  */
10050(define_expand "canonicalize_funcptr_for_compare"
10051  [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
10052   (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10053	      (clobber (match_dup 2))
10054	      (clobber (reg:SI 26))
10055	      (clobber (reg:SI 22))
10056	      (clobber (reg:SI 31))])
10057   (set (match_operand:SI 0 "register_operand" "")
10058	(reg:SI 29))]
10059  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
10060  "
10061{
10062  if (TARGET_ELF32)
10063    {
10064      rtx canonicalize_funcptr_for_compare_libfunc
10065        = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
10066
10067      emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
10068      			       operands[0], LCT_NORMAL, Pmode,
10069			       operands[1], Pmode);
10070      DONE;
10071    }
10072
10073  operands[2] = gen_reg_rtx (SImode);
10074  if (GET_CODE (operands[1]) != REG)
10075    {
10076      rtx tmp = gen_reg_rtx (Pmode);
10077      emit_move_insn (tmp, operands[1]);
10078      operands[1] = tmp;
10079    }
10080}")
10081
10082(define_insn "*$$sh_func_adrs"
10083  [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10084   (clobber (match_operand:SI 0 "register_operand" "=a"))
10085   (clobber (reg:SI 26))
10086   (clobber (reg:SI 22))
10087   (clobber (reg:SI 31))]
10088  "!TARGET_64BIT"
10089  "*
10090{
10091  int length = get_attr_length (insn);
10092  rtx xoperands[2];
10093
10094  xoperands[0] = GEN_INT (length - 8);
10095  xoperands[1] = GEN_INT (length - 16);
10096
10097  /* Must import the magic millicode routine.  */
10098  output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
10099
10100  /* This is absolutely amazing.
10101
10102     First, copy our input parameter into %r29 just in case we don't
10103     need to call $$sh_func_adrs.  */
10104  output_asm_insn (\"copy %%r26,%%r29\", NULL);
10105  output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
10106
10107  /* Next, examine the low two bits in %r26, if they aren't 0x2, then
10108     we use %r26 unchanged.  */
10109  output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
10110  output_asm_insn (\"ldi 4096,%%r31\", NULL);
10111
10112  /* Next, compare %r26 with 4096, if %r26 is less than or equal to
10113     4096, then again we use %r26 unchanged.  */
10114  output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
10115
10116  /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
10117  return pa_output_millicode_call (insn,
10118				   gen_rtx_SYMBOL_REF (SImode,
10119						       \"$$sh_func_adrs\"));
10120}"
10121  [(set_attr "type" "sh_func_adrs")
10122   (set (attr "length")
10123	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
10124	      (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
10125		    (const_int 20))))])
10126
10127;; On the PA, the PIC register is call clobbered, so it must
10128;; be saved & restored around calls by the caller.  If the call
10129;; doesn't return normally (nonlocal goto, or an exception is
10130;; thrown), then the code at the exception handler label must
10131;; restore the PIC register.
10132(define_expand "exception_receiver"
10133  [(const_int 4)]
10134  "flag_pic"
10135  "
10136{
10137  /* On the 64-bit port, we need a blockage because there is
10138     confusion regarding the dependence of the restore on the
10139     frame pointer.  As a result, the frame pointer and pic
10140     register restores sometimes are interchanged erroneously.  */
10141  if (TARGET_64BIT)
10142    emit_insn (gen_blockage ());
10143  /* Restore the PIC register using hppa_pic_save_rtx ().  The
10144     PIC register is not saved in the frame in 64-bit ABI.  */
10145  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10146  emit_insn (gen_blockage ());
10147  DONE;
10148}")
10149
10150(define_expand "builtin_setjmp_receiver"
10151  [(label_ref (match_operand 0 "" ""))]
10152  "flag_pic"
10153  "
10154{
10155  if (TARGET_64BIT)
10156    emit_insn (gen_blockage ());
10157  /* Restore the PIC register.  Hopefully, this will always be from
10158     a stack slot.  The only registers that are valid after a
10159     builtin_longjmp are the stack and frame pointers.  */
10160  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10161  emit_insn (gen_blockage ());
10162  DONE;
10163}")
10164
10165;; Allocate new stack space and update the saved stack pointer in the
10166;; frame marker.  The HP C compilers also copy additional words in the
10167;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10168;; The 32-bit compiler copies the word at -16 (Static Link).  We
10169;; currently don't copy these values.
10170;;
10171;; Since the copy of the frame marker can't be done atomically, I
10172;; suspect that using it for unwind purposes may be somewhat unreliable.
10173;; The HP compilers appear to raise the stack and copy the frame
10174;; marker in a strict instruction sequence.  This suggests that the
10175;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10176;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10177;; as GAS doesn't support it, or try to keep the instructions emitted
10178;; here in strict sequence.
10179(define_expand "allocate_stack"
10180  [(match_operand 0 "" "")
10181   (match_operand 1 "" "")]
10182  ""
10183  "
10184{
10185  rtx addr;
10186
10187  /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10188     in operand 0 before adjusting the stack.  */
10189  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10190  anti_adjust_stack (operands[1]);
10191  if (TARGET_HPUX_UNWIND_LIBRARY)
10192    {
10193      addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10194			   GEN_INT (TARGET_64BIT ? -8 : -4));
10195      emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10196    }
10197  if (!TARGET_64BIT && flag_pic)
10198    {
10199      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10200      emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10201    }
10202  DONE;
10203}")
10204
10205(define_expand "prefetch"
10206  [(match_operand 0 "address_operand" "")
10207   (match_operand 1 "const_int_operand" "")
10208   (match_operand 2 "const_int_operand" "")]
10209  "TARGET_PA_20"
10210{
10211  operands[0] = copy_addr_to_reg (operands[0]);
10212  emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10213  DONE;
10214})
10215
10216(define_insn "prefetch_20"
10217  [(prefetch (match_operand 0 "pmode_register_operand" "r")
10218	     (match_operand:SI 1 "const_int_operand" "n")
10219	     (match_operand:SI 2 "const_int_operand" "n"))]
10220  "TARGET_PA_20"
10221{
10222  /* The SL cache-control completer indicates good spatial locality but
10223     poor temporal locality.  The ldw instruction with a target of general
10224     register 0 prefetches a cache line for a read.  The ldd instruction
10225     prefetches a cache line for a write.  */
10226  static const char * const instr[2][2] = {
10227    {
10228      "ldw,sl 0(%0),%%r0",
10229      "ldd,sl 0(%0),%%r0"
10230    },
10231    {
10232      "ldw 0(%0),%%r0",
10233      "ldd 0(%0),%%r0"
10234    }
10235  };
10236  int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10237  int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10238
10239  return instr [locality][read_or_write];
10240}
10241  [(set_attr "type" "load")
10242   (set_attr "length" "4")])
10243
10244;; TLS Support
10245(define_insn "tgd_load"
10246 [(set (match_operand:SI 0 "register_operand" "=r")
10247       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10248  (clobber (reg:SI 1))
10249  (use (reg:SI 27))]
10250  ""
10251  "*
10252{
10253  return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10254}"
10255  [(set_attr "type" "multi")
10256   (set_attr "length" "8")])
10257
10258(define_insn "tgd_load_pic"
10259 [(set (match_operand:SI 0 "register_operand" "=r")
10260       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10261  (clobber (reg:SI 1))
10262  (use (reg:SI 19))]
10263  ""
10264  "*
10265{
10266  return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10267}"
10268  [(set_attr "type" "multi")
10269   (set_attr "length" "8")])
10270
10271(define_insn "tld_load"
10272 [(set (match_operand:SI 0 "register_operand" "=r")
10273       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10274  (clobber (reg:SI 1))
10275  (use (reg:SI 27))]
10276  ""
10277  "*
10278{
10279  return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10280}"
10281  [(set_attr "type" "multi")
10282   (set_attr "length" "8")])
10283
10284(define_insn "tld_load_pic"
10285 [(set (match_operand:SI 0 "register_operand" "=r")
10286       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10287  (clobber (reg:SI 1))
10288  (use (reg:SI 19))]
10289  ""
10290  "*
10291{
10292  return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10293}"
10294  [(set_attr "type" "multi")
10295   (set_attr "length" "8")])
10296
10297(define_insn "tld_offset_load"
10298  [(set (match_operand:SI 0 "register_operand" "=r")
10299        (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
10300		 	    UNSPEC_TLSLDO)
10301		 (match_operand:SI 2 "register_operand" "r")))
10302   (clobber (reg:SI 1))]
10303  ""
10304  "*
10305{
10306  return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
10307}"
10308  [(set_attr "type" "multi")
10309   (set_attr "length" "8")])
10310
10311(define_insn "tp_load"
10312  [(set (match_operand:SI 0 "register_operand" "=r")
10313	(unspec:SI [(const_int 0)] UNSPEC_TP))]
10314  ""
10315  "mfctl %%cr27,%0"
10316  [(set_attr "type" "multi")
10317   (set_attr "length" "4")])
10318
10319(define_insn "tie_load"
10320  [(set (match_operand:SI 0 "register_operand" "=r")
10321        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10322   (clobber (reg:SI 1))
10323   (use (reg:SI 27))]
10324  ""
10325  "*
10326{
10327  return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10328}"
10329  [(set_attr "type" "multi")
10330   (set_attr "length" "8")])
10331
10332(define_insn "tie_load_pic"
10333  [(set (match_operand:SI 0 "register_operand" "=r")
10334        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10335   (clobber (reg:SI 1))
10336   (use (reg:SI 19))]
10337  ""
10338  "*
10339{
10340  return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10341}"
10342  [(set_attr "type" "multi")
10343   (set_attr "length" "8")])
10344
10345(define_insn "tle_load"
10346  [(set (match_operand:SI 0 "register_operand" "=r")
10347        (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
10348		 	    UNSPEC_TLSLE)
10349		 (match_operand:SI 2 "register_operand" "r")))
10350   (clobber (reg:SI 1))]
10351  ""
10352  "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10353  [(set_attr "type" "multi")
10354   (set_attr "length" "8")])
10355
10356;; Atomic instructions
10357
10358;; All memory loads and stores access storage atomically except
10359;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10360;; doubleword loads and stores are not guaranteed to be atomic
10361;; when referencing the I/O address space.
10362
10363;; These patterns are at the bottom so the non atomic versions are preferred.
10364
10365(define_expand "atomic_storeqi"
10366  [(match_operand:QI 0 "memory_operand")                ;; memory
10367   (match_operand:QI 1 "register_operand")              ;; val out
10368   (match_operand:SI 2 "const_int_operand")]            ;; model
10369  ""
10370{
10371  if (TARGET_SYNC_LIBCALL)
10372    {
10373      rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, QImode);
10374      rtx addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10375
10376      emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10377			 operands[1], QImode);
10378      DONE;
10379    }
10380  FAIL;
10381})
10382
10383;; Implement atomic HImode stores using exchange.
10384
10385(define_expand "atomic_storehi"
10386  [(match_operand:HI 0 "memory_operand")                ;; memory
10387   (match_operand:HI 1 "register_operand")              ;; val out
10388   (match_operand:SI 2 "const_int_operand")]            ;; model
10389  ""
10390{
10391  if (TARGET_SYNC_LIBCALL)
10392    {
10393      rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, HImode);
10394      rtx addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10395
10396      emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10397			 operands[1], HImode);
10398      DONE;
10399    }
10400  FAIL;
10401})
10402
10403;; Implement atomic SImode store using exchange.
10404
10405(define_expand "atomic_storesi"
10406  [(match_operand:SI 0 "memory_operand")                ;; memory
10407   (match_operand:SI 1 "register_operand")              ;; val out
10408   (match_operand:SI 2 "const_int_operand")]            ;; model
10409  ""
10410{
10411  if (TARGET_SYNC_LIBCALL)
10412    {
10413      rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, SImode);
10414      rtx addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10415
10416      emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10417			 operands[1], SImode);
10418      DONE;
10419    }
10420  FAIL;
10421})
10422
10423;; Implement atomic DImode load.
10424
10425(define_expand "atomic_loaddi"
10426  [(match_operand:DI 0 "register_operand")              ;; val out
10427   (match_operand:DI 1 "memory_operand")                ;; memory
10428   (match_operand:SI 2 "const_int_operand")]            ;; model
10429  ""
10430{
10431  enum memmodel model;
10432
10433  if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10434    FAIL;
10435
10436  model = memmodel_from_int (INTVAL (operands[2]));
10437  operands[1] = force_reg (SImode, XEXP (operands[1], 0));
10438  if (is_mm_seq_cst (model))
10439    expand_mem_thread_fence (model);
10440  emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10441  expand_mem_thread_fence (model);
10442  DONE;
10443})
10444
10445(define_insn "atomic_loaddi_1"
10446  [(set (match_operand:DI 0 "register_operand" "=r")
10447        (mem:DI (match_operand:SI 1 "register_operand" "r")))
10448   (clobber (match_scratch:DI 2 "=f"))]
10449  "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10450  "{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"
10451  [(set_attr "type" "move")
10452   (set_attr "length" "16")])
10453
10454;; Implement atomic DImode store.
10455
10456(define_expand "atomic_storedi"
10457  [(match_operand:DI 0 "memory_operand")                ;; memory
10458   (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10459   (match_operand:SI 2 "const_int_operand")]            ;; model
10460  ""
10461{
10462  enum memmodel model;
10463
10464  if (TARGET_SYNC_LIBCALL)
10465    {
10466      rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, DImode);
10467      rtx addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10468
10469      emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10470			 operands[1], DImode);
10471      DONE;
10472    }
10473
10474  if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10475    FAIL;
10476
10477  model = memmodel_from_int (INTVAL (operands[2]));
10478  operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10479  if (operands[1] != CONST0_RTX (DImode))
10480    operands[1] = force_reg (DImode, operands[1]);
10481  expand_mem_thread_fence (model);
10482  emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10483  if (is_mm_seq_cst (model))
10484    expand_mem_thread_fence (model);
10485  DONE;
10486})
10487
10488(define_insn "atomic_storedi_1"
10489  [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10490        (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10491   (clobber (match_scratch:DI 2 "=f,f"))]
10492  "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10493  "@
10494   fcpy,dbl %%fr0,%2\n\t{fstds|fstd} %2,0(%0)
10495   {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)"
10496  [(set_attr "type" "move,move")
10497   (set_attr "length" "8,16")])
10498
10499;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10500;; we need memory barriers to enforce program order for memory references
10501;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10502;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10503;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10504;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10505
10506;; When barriers are needed, we use a strongly ordered ldcw instruction as
10507;; the barrier.  Most PA 2.0 targets are cache coherent.  In that case, we
10508;; can use the coherent cache control hint and avoid aligning the ldcw
10509;; address.  In spite of its description, it is not clear that the sync
10510;; instruction works as a barrier.
10511
10512(define_expand "memory_barrier"
10513  [(parallel
10514     [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10515      (clobber (match_dup 1))])]
10516  ""
10517{
10518  /* We don't need a barrier if the target uses ordered memory references.  */
10519  if (TARGET_ORDERED)
10520    FAIL;
10521  operands[1] = gen_reg_rtx (Pmode);
10522  operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10523  MEM_VOLATILE_P (operands[0]) = 1;
10524})
10525
10526(define_insn "*memory_barrier_coherent"
10527  [(set (match_operand:BLK 0 "" "")
10528        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10529   (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10530  "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10531  "ldcw,co 0(%%sp),%1"
10532  [(set_attr "type" "binary")
10533   (set_attr "length" "4")])
10534
10535(define_insn "*memory_barrier_64"
10536  [(set (match_operand:BLK 0 "" "")
10537        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10538    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10539  "TARGET_64BIT"
10540  "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw 0(%1),%1"
10541  [(set_attr "type" "binary")
10542   (set_attr "length" "12")])
10543
10544(define_insn "*memory_barrier_32"
10545  [(set (match_operand:BLK 0 "" "")
10546        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10547    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10548  ""
10549  "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\tldcw 0(%1),%1"
10550  [(set_attr "type" "binary")
10551   (set_attr "length" "12")])
10552