xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/pa/pa.md (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
1;;- Machine description for HP PA-RISC architecture for GCC compiler
2;;   Copyright (C) 1992-2020 Free Software Foundation, Inc.
3;;   Contributed by the Center for Software Science at the University
4;;   of Utah.
5
6;; This file is part of GCC.
7
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 3, or (at your option)
11;; any later version.
12
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.
21
22;; This machine description is inspired by sparc.md and to a lesser
23;; extent mips.md.
24
25;; Possible improvements:
26;;
27;; * With PA1.1, most computational instructions can conditionally nullify
28;;   the execution of the following instruction.  A nullified instruction
29;;   does not cause the instruction pipeline to stall, making it a very
30;;   efficient alternative to e.g. branching or conditional moves.
31;;
32;;   Nullification is performed conditionally based on the outcome of a
33;;   test specified in the opcode.  The test result is stored in PSW[N]
34;;   and can only be used to nullify the instruction following immediately
35;;   after the test.  For example:
36;;
37;;	ldi 10,%r26
38;;	ldi 5,%r25
39;;	sub,< %r26,%r25,%r28
40;;	sub   %r28,%r25,%r28	; %r28 == 0
41;;	sub,> %r26,%r25,%r29
42;;	sub   %r29,%r25,%r29	; %r29 == 5
43;;
44;;   This could be tricky to implement because the result of the test has
45;;   to be propagated one instruction forward, which, in the worst case,
46;;   would involve (1) adding a fake register for PSW[N]; (2) adding the
47;;   variants of the computational instructions that set or consume this
48;;   fake register.  The cond_exec infrastructure is probably not helpful
49;;   for this.
50;;
51;; * PA-RISC includes a set of conventions for branch instruction usage
52;;   to indicate whether a particular branch is more likely to be taken
53;;   or not taken.  For example, the prediction for CMPB instructions
54;;   (CMPB,cond,n r1,r2,target) depends on the direction of the branch
55;;   (forward or backward) and on the order of the operands:
56;;
57;;     | branch    | operand  | branch     |
58;;     | direction | compare  | prediction |
59;;     +-----------+----------+------------+
60;;     | backward  | r1 < r2  | taken      |
61;;     | backward  | r1 >= r2 | not taken  |
62;;     | forward   | r1 < r2  | not taken  |
63;;     | forward   | r1 >= r2 | taken      |
64;;
65;;   By choosing instructions and operand order carefully, the compiler
66;;   could give the CPU branch predictor some help.
67;;
68
69;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
70
71;; Uses of UNSPEC in this file:
72
73(define_c_enum "unspec"
74  [UNSPEC_CFFC		; canonicalize_funcptr_for_compare
75   UNSPEC_GOTO		; indirect_goto
76   UNSPEC_DLTIND14R
77   UNSPEC_TP
78   UNSPEC_TLSGD
79   UNSPEC_TLSLDM
80   UNSPEC_TLSLDO
81   UNSPEC_TLSLDBASE
82   UNSPEC_TLSIE
83   UNSPEC_TLSLE
84   UNSPEC_TLSGD_PIC
85   UNSPEC_TLSLDM_PIC
86   UNSPEC_TLSIE_PIC
87   UNSPEC_MEMORY_BARRIER
88  ])
89
90;; UNSPEC_VOLATILE:
91
92(define_c_enum "unspecv"
93  [UNSPECV_BLOCKAGE	; blockage
94   UNSPECV_DCACHE	; dcacheflush
95   UNSPECV_ICACHE	; icacheflush
96   UNSPECV_OPC		; outline_prologue_call
97   UNSPECV_OEC		; outline_epilogue_call
98   UNSPECV_LONGJMP	; builtin_longjmp
99  ])
100
101;; Maximum pc-relative branch offsets.
102
103;; These numbers are a bit smaller than the maximum allowable offsets
104;; so that a few instructions may be inserted before the actual branch.
105
106(define_constants
107  [(MAX_12BIT_OFFSET     8184)	; 12-bit branch
108   (MAX_17BIT_OFFSET   262100)	; 17-bit branch
109  ])
110
111;; Mode and code iterators
112
113;; This mode iterator allows :P to be used for patterns that operate on
114;; pointer-sized quantities.  Exactly one of the two alternatives will match.
115(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
116
117;; This attribute defines the condition prefix for word and double word
118;; add, compare, subtract and logical instructions.
119(define_mode_attr dwc [(SI "") (DI "*")])
120
121;; Insn type.  Used to default other attribute values.
122
123;; type "unary" insns have one input operand (1) and one output operand (0)
124;; type "binary" insns have two input operands (1,2) and one output (0)
125
126(define_attr "type"
127  "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload,trap"
128  (const_string "binary"))
129
130(define_attr "pa_combine_type"
131  "fmpy,faddsub,uncond_branch,addmove,none"
132  (const_string "none"))
133
134;; Processor type (for scheduling, not code generation) -- this attribute
135;; must exactly match the processor_type enumeration in pa.h.
136;;
137;; FIXME: Add 800 scheduling for completeness?
138
139(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
140
141;; Length (in # of bytes).
142(define_attr "length" ""
143  (cond [(eq_attr "type" "load,fpload")
144	 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
145		       (const_int 8) (const_int 4))
146
147	 (eq_attr "type" "store,fpstore")
148	 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
149		       (const_int 8) (const_int 4))
150
151	 (eq_attr "type" "binary,shift,nullshift")
152	 (if_then_else (match_operand 2 "arith14_operand" "")
153		       (const_int 4) (const_int 12))
154
155	 (eq_attr "type" "move,unary,shift,nullshift")
156	 (if_then_else (match_operand 1 "arith14_operand" "")
157		       (const_int 4) (const_int 8))]
158
159	(const_int 4)))
160
161(define_asm_attributes
162  [(set_attr "length" "4")
163   (set_attr "type" "multi")])
164
165;; Attributes for instruction and branch scheduling
166
167;; For conditional branches. Frame related instructions are not allowed
168;; because they confuse the unwind support.
169(define_attr "in_branch_delay" "false,true"
170  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
171		     (eq_attr "length" "4")
172		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
173		(const_string "true")
174		(const_string "false")))
175
176;; Disallow instructions which use the FPU since they will tie up the FPU
177;; even if the instruction is nullified.
178(define_attr "in_nullified_branch_delay" "false,true"
179  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch,trap")
180		     (eq_attr "length" "4")
181		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
182		(const_string "true")
183		(const_string "false")))
184
185;; For calls and millicode calls.
186(define_attr "in_call_delay" "false,true"
187  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
188		     (eq_attr "length" "4")
189		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
190		(const_string "true")
191		(const_string "false")))
192
193;; Call delay slot description.
194(define_delay (eq_attr "type" "call")
195  [(eq_attr "in_call_delay" "true") (nil) (nil)])
196
197;; Sibcall delay slot description.
198(define_delay (eq_attr "type" "sibcall")
199  [(eq_attr "in_call_delay" "true") (nil) (nil)])
200
201;; Millicode call delay slot description.
202(define_delay (eq_attr "type" "milli")
203  [(eq_attr "in_call_delay" "true") (nil) (nil)])
204
205;; Return and other similar instructions.
206(define_delay (eq_attr "type" "branch,parallel_branch")
207  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
208
209;; Floating point conditional branch delay slot description.
210(define_delay (eq_attr "type" "fbranch")
211  [(eq_attr "in_branch_delay" "true")
212   (eq_attr "in_nullified_branch_delay" "true")
213   (nil)])
214
215;; Integer conditional branch delay slot description.
216;; Nullification of conditional branches on the PA is dependent on the
217;; direction of the branch.  Forward branches nullify true and
218;; backward branches nullify false.  If the direction is unknown
219;; then nullification is not allowed.
220(define_delay (eq_attr "type" "cbranch")
221  [(eq_attr "in_branch_delay" "true")
222   (and (eq_attr "in_nullified_branch_delay" "true")
223	(attr_flag "forward"))
224   (and (eq_attr "in_nullified_branch_delay" "true")
225	(attr_flag "backward"))])
226
227(define_delay (eq_attr "type" "uncond_branch")
228  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
229
230;; Memory. Disregarding Cache misses, the Mustang memory times are:
231;; load: 2, fpload: 3
232;; store, fpstore: 3, no D-cache operations should be scheduled.
233
234;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
235;; Timings:
236;; Instruction	Time	Unit	Minimum Distance (unit contention)
237;; fcpy		3	ALU	2
238;; fabs		3	ALU	2
239;; fadd		3	ALU	2
240;; fsub		3	ALU	2
241;; fcmp		3	ALU	2
242;; fcnv		3	ALU	2
243;; fmpyadd	3	ALU,MPY	2
244;; fmpysub	3	ALU,MPY 2
245;; fmpycfxt	3	ALU,MPY 2
246;; fmpy		3	MPY	2
247;; fmpyi	3	MPY	2
248;; fdiv,sgl	10	MPY	10
249;; fdiv,dbl	12	MPY	12
250;; fsqrt,sgl	14	MPY	14
251;; fsqrt,dbl	18	MPY	18
252;;
253;; We don't model fmpyadd/fmpysub properly as those instructions
254;; keep both the FP ALU and MPY units busy.  Given that these
255;; processors are obsolete, I'm not going to spend the time to
256;; model those instructions correctly.
257
258(define_automaton "pa700")
259(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
260
261(define_insn_reservation "W0" 4
262  (and (eq_attr "type" "fpcc")
263       (eq_attr "cpu" "700"))
264  "fpalu_700*2")
265
266(define_insn_reservation "W1" 3
267  (and (eq_attr "type" "fpalu")
268       (eq_attr "cpu" "700"))
269  "fpalu_700*2")
270
271(define_insn_reservation "W2" 3
272  (and (eq_attr "type" "fpmulsgl,fpmuldbl")
273       (eq_attr "cpu" "700"))
274  "fpmpy_700*2")
275
276(define_insn_reservation "W3" 10
277  (and (eq_attr "type" "fpdivsgl")
278       (eq_attr "cpu" "700"))
279  "fpmpy_700*10")
280
281(define_insn_reservation "W4" 12
282  (and (eq_attr "type" "fpdivdbl")
283       (eq_attr "cpu" "700"))
284  "fpmpy_700*12")
285
286(define_insn_reservation "W5" 14
287  (and (eq_attr "type" "fpsqrtsgl")
288       (eq_attr "cpu" "700"))
289  "fpmpy_700*14")
290
291(define_insn_reservation "W6" 18
292  (and (eq_attr "type" "fpsqrtdbl")
293       (eq_attr "cpu" "700"))
294  "fpmpy_700*18")
295
296(define_insn_reservation "W7" 2
297  (and (eq_attr "type" "load")
298       (eq_attr "cpu" "700"))
299  "mem_700")
300
301(define_insn_reservation "W8" 2
302  (and (eq_attr "type" "fpload")
303       (eq_attr "cpu" "700"))
304  "mem_700")
305
306(define_insn_reservation "W9" 3
307  (and (eq_attr "type" "store")
308       (eq_attr "cpu" "700"))
309  "mem_700*3")
310
311(define_insn_reservation "W10" 3
312  (and (eq_attr "type" "fpstore")
313       (eq_attr "cpu" "700"))
314  "mem_700*3")
315
316(define_insn_reservation "W11" 5
317  (and (eq_attr "type" "fpstore_load")
318       (eq_attr "cpu" "700"))
319  "mem_700*5")
320
321(define_insn_reservation "W12" 6
322  (and (eq_attr "type" "store_fpload")
323       (eq_attr "cpu" "700"))
324  "mem_700*6")
325
326(define_insn_reservation "W13" 1
327  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
328       (eq_attr "cpu" "700"))
329  "dummy_700")
330
331;; We have a bypass for all computations in the FP unit which feed an
332;; FP store as long as the sizes are the same.
333(define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
334(define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
335(define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
336(define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
337(define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
338
339;; We have an "anti-bypass" for FP loads which feed an FP store.
340(define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
341
342;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
343;; floating point computations with non-floating point computations (fp loads
344;; and stores are not fp computations).
345;;
346;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
347;; take two cycles, during which no Dcache operations should be scheduled.
348;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
349;; all have the same memory characteristics if one disregards cache misses.
350;;
351;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
352;; There's no value in modeling the ALU and MUL separately though
353;; since there can never be a functional unit conflict given the
354;; latency and issue rates for those units.
355;;
356;; Timings:
357;; Instruction	Time	Unit	Minimum Distance (unit contention)
358;; fcpy		2	ALU	1
359;; fabs		2	ALU	1
360;; fadd		2	ALU	1
361;; fsub		2	ALU	1
362;; fcmp		2	ALU	1
363;; fcnv		2	ALU	1
364;; fmpyadd	2	ALU,MPY	1
365;; fmpysub	2	ALU,MPY 1
366;; fmpycfxt	2	ALU,MPY 1
367;; fmpy		2	MPY	1
368;; fmpyi	2	MPY	1
369;; fdiv,sgl	8	DIV	8
370;; fdiv,dbl	15	DIV	15
371;; fsqrt,sgl	8	DIV	8
372;; fsqrt,dbl	15	DIV	15
373
374(define_automaton "pa7100")
375(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
376
377(define_insn_reservation "X0" 2
378  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
379       (eq_attr "cpu" "7100"))
380  "f_7100,fpmac_7100")
381
382(define_insn_reservation "X1" 8
383  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
384       (eq_attr "cpu" "7100"))
385  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
386
387(define_insn_reservation "X2" 15
388  (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
389       (eq_attr "cpu" "7100"))
390  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
391
392(define_insn_reservation "X3" 2
393  (and (eq_attr "type" "load")
394       (eq_attr "cpu" "7100"))
395  "i_7100+mem_7100")
396
397(define_insn_reservation "X4" 2
398  (and (eq_attr "type" "fpload")
399       (eq_attr "cpu" "7100"))
400  "i_7100+mem_7100")
401
402(define_insn_reservation "X5" 2
403  (and (eq_attr "type" "store")
404       (eq_attr "cpu" "7100"))
405  "i_7100+mem_7100,mem_7100")
406
407(define_insn_reservation "X6" 2
408  (and (eq_attr "type" "fpstore")
409       (eq_attr "cpu" "7100"))
410  "i_7100+mem_7100,mem_7100")
411
412(define_insn_reservation "X7" 4
413  (and (eq_attr "type" "fpstore_load")
414       (eq_attr "cpu" "7100"))
415  "i_7100+mem_7100,mem_7100*3")
416
417(define_insn_reservation "X8" 4
418  (and (eq_attr "type" "store_fpload")
419       (eq_attr "cpu" "7100"))
420  "i_7100+mem_7100,mem_7100*3")
421
422(define_insn_reservation "X9" 1
423  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
424       (eq_attr "cpu" "7100"))
425  "i_7100")
426
427;; We have a bypass for all computations in the FP unit which feed an
428;; FP store as long as the sizes are the same.
429(define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
430(define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
431(define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
432
433;; We have an "anti-bypass" for FP loads which feed an FP store.
434(define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
435
436;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
437;; There's no value in modeling the ALU and MUL separately though
438;; since there can never be a functional unit conflict that
439;; can be avoided given the latency, issue rates and mandatory
440;; one cycle cpu-wide lock for a double precision fp multiply.
441;;
442;; Timings:
443;; Instruction	Time	Unit	Minimum Distance (unit contention)
444;; fcpy		2	ALU	1
445;; fabs		2	ALU	1
446;; fadd		2	ALU	1
447;; fsub		2	ALU	1
448;; fcmp		2	ALU	1
449;; fcnv		2	ALU	1
450;; fmpyadd,sgl	2	ALU,MPY	1
451;; fmpyadd,dbl	3	ALU,MPY	2
452;; fmpysub,sgl	2	ALU,MPY 1
453;; fmpysub,dbl	3	ALU,MPY 2
454;; fmpycfxt,sgl	2	ALU,MPY 1
455;; fmpycfxt,dbl	3	ALU,MPY 2
456;; fmpy,sgl	2	MPY	1
457;; fmpy,dbl	3	MPY	2
458;; fmpyi	3	MPY	2
459;; fdiv,sgl	8	DIV	8
460;; fdiv,dbl	15	DIV	15
461;; fsqrt,sgl	8	DIV	8
462;; fsqrt,dbl	15	DIV	15
463;;
464;; The PA7200 is just like the PA7100LC except that there is
465;; no store-store penalty.
466;;
467;; The PA7300 is just like the PA7200 except that there is
468;; no store-load penalty.
469;;
470;; Note there are some aspects of the 7100LC we are not modeling
471;; at the moment.  I'll be reviewing the 7100LC scheduling info
472;; shortly and updating this description.
473;;
474;;   load-load pairs
475;;   store-store pairs
476;;   other issue modeling
477
478(define_automaton "pa7100lc")
479(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
480(define_cpu_unit "fpmac_7100lc" "pa7100lc")
481(define_cpu_unit "mem_7100lc" "pa7100lc")
482
483;; Double precision multiplies lock the entire CPU for one
484;; cycle.  There is no way to avoid this lock and trying to
485;; schedule around the lock is pointless and thus there is no
486;; value in trying to model this lock.
487;;
488;; Not modeling the lock allows us to treat fp multiplies just
489;; like any other FP alu instruction.  It allows for a smaller
490;; DFA and may reduce register pressure.
491(define_insn_reservation "Y0" 2
492  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
493       (eq_attr "cpu" "7100LC,7200,7300"))
494  "f_7100lc,fpmac_7100lc")
495
496;; fp division and sqrt instructions lock the entire CPU for
497;; 7 cycles (single precision) or 14 cycles (double precision).
498;; There is no way to avoid this lock and trying to schedule
499;; around the lock is pointless and thus there is no value in
500;; trying to model this lock.  Not modeling the lock allows
501;; for a smaller DFA and may reduce register pressure.
502(define_insn_reservation "Y1" 1
503  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
504       (eq_attr "cpu" "7100LC,7200,7300"))
505  "f_7100lc")
506
507(define_insn_reservation "Y2" 2
508  (and (eq_attr "type" "load")
509       (eq_attr "cpu" "7100LC,7200,7300"))
510  "i1_7100lc+mem_7100lc")
511
512(define_insn_reservation "Y3" 2
513  (and (eq_attr "type" "fpload")
514       (eq_attr "cpu" "7100LC,7200,7300"))
515  "i1_7100lc+mem_7100lc")
516
517(define_insn_reservation "Y4" 2
518  (and (eq_attr "type" "store")
519       (eq_attr "cpu" "7100LC"))
520  "i1_7100lc+mem_7100lc,mem_7100lc")
521
522(define_insn_reservation "Y5" 2
523  (and (eq_attr "type" "fpstore")
524       (eq_attr "cpu" "7100LC"))
525  "i1_7100lc+mem_7100lc,mem_7100lc")
526
527(define_insn_reservation "Y6" 4
528  (and (eq_attr "type" "fpstore_load")
529       (eq_attr "cpu" "7100LC"))
530  "i1_7100lc+mem_7100lc,mem_7100lc*3")
531
532(define_insn_reservation "Y7" 4
533  (and (eq_attr "type" "store_fpload")
534       (eq_attr "cpu" "7100LC"))
535  "i1_7100lc+mem_7100lc,mem_7100lc*3")
536
537(define_insn_reservation "Y8" 1
538  (and (eq_attr "type" "shift,nullshift")
539       (eq_attr "cpu" "7100LC,7200,7300"))
540  "i1_7100lc")
541
542(define_insn_reservation "Y9" 1
543  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
544       (eq_attr "cpu" "7100LC,7200,7300"))
545  "(i0_7100lc|i1_7100lc)")
546
547;; The 7200 has a store-load penalty
548(define_insn_reservation "Y10" 2
549  (and (eq_attr "type" "store")
550       (eq_attr "cpu" "7200"))
551  "i1_7100lc,mem_7100lc")
552
553(define_insn_reservation "Y11" 2
554  (and (eq_attr "type" "fpstore")
555       (eq_attr "cpu" "7200"))
556  "i1_7100lc,mem_7100lc")
557
558(define_insn_reservation "Y12" 4
559  (and (eq_attr "type" "fpstore_load")
560       (eq_attr "cpu" "7200"))
561  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
562
563(define_insn_reservation "Y13" 4
564  (and (eq_attr "type" "store_fpload")
565       (eq_attr "cpu" "7200"))
566  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
567
568;; The 7300 has no penalty for store-store or store-load
569(define_insn_reservation "Y14" 2
570  (and (eq_attr "type" "store")
571       (eq_attr "cpu" "7300"))
572  "i1_7100lc")
573
574(define_insn_reservation "Y15" 2
575  (and (eq_attr "type" "fpstore")
576       (eq_attr "cpu" "7300"))
577  "i1_7100lc")
578
579(define_insn_reservation "Y16" 4
580  (and (eq_attr "type" "fpstore_load")
581       (eq_attr "cpu" "7300"))
582  "i1_7100lc,i1_7100lc+mem_7100lc")
583
584(define_insn_reservation "Y17" 4
585  (and (eq_attr "type" "store_fpload")
586       (eq_attr "cpu" "7300"))
587  "i1_7100lc,i1_7100lc+mem_7100lc")
588
589;; We have an "anti-bypass" for FP loads which feed an FP store.
590(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
591
592;; Scheduling for the PA8000 is somewhat different than scheduling for a
593;; traditional architecture.
594;;
595;; The PA8000 has a large (56) entry reorder buffer that is split between
596;; memory and non-memory operations.
597;;
598;; The PA8000 can issue two memory and two non-memory operations per cycle to
599;; the function units, with the exception of branches and multi-output
600;; instructions.  The PA8000 can retire two non-memory operations per cycle
601;; and two memory operations per cycle, only one of which may be a store.
602;;
603;; Given the large reorder buffer, the processor can hide most latencies.
604;; According to HP, they've got the best results by scheduling for retirement
605;; bandwidth with limited latency scheduling for floating point operations.
606;; Latency for integer operations and memory references is ignored.
607;;
608;;
609;; We claim floating point operations have a 2 cycle latency and are
610;; fully pipelined, except for div and sqrt which are not pipelined and
611;; take from 17 to 31 cycles to complete.
612;;
613;; It's worth noting that there is no way to saturate all the functional
614;; units on the PA8000 as there is not enough issue bandwidth.
615
616(define_automaton "pa8000")
617(define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
618(define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
619(define_cpu_unit "store_8000" "pa8000")
620(define_cpu_unit "f0_8000, f1_8000" "pa8000")
621(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
622(define_reservation "inm_8000" "inm0_8000 | inm1_8000")
623(define_reservation "im_8000" "im0_8000 | im1_8000")
624(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
625(define_reservation "rm_8000" "rm0_8000 | rm1_8000")
626(define_reservation "f_8000" "f0_8000 | f1_8000")
627(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
628
629;; We can issue any two memops per cycle, but we can only retire
630;; one memory store per cycle.  We assume that the reorder buffer
631;; will hide any memory latencies per HP's recommendation.
632(define_insn_reservation "Z0" 0
633  (and
634    (eq_attr "type" "load,fpload")
635    (eq_attr "cpu" "8000"))
636  "im_8000,rm_8000")
637
638(define_insn_reservation "Z1" 0
639  (and
640    (eq_attr "type" "store,fpstore")
641    (eq_attr "cpu" "8000"))
642  "im_8000,rm_8000+store_8000")
643
644(define_insn_reservation "Z2" 0
645  (and (eq_attr "type" "fpstore_load,store_fpload")
646       (eq_attr "cpu" "8000"))
647  "im_8000,rm_8000+store_8000,im_8000,rm_8000")
648
649;; We can issue and retire two non-memory operations per cycle with
650;; a few exceptions (branches).  This group catches those we want
651;; to assume have zero latency.
652(define_insn_reservation "Z3" 0
653  (and
654    (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload")
655    (eq_attr "cpu" "8000"))
656  "inm_8000,rnm_8000")
657
658;; Branches use both slots in the non-memory issue and
659;; retirement unit.
660(define_insn_reservation "Z4" 0
661  (and
662    (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
663    (eq_attr "cpu" "8000"))
664  "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
665
666;; We partial latency schedule the floating point units.
667;; They can issue/retire two at a time in the non-memory
668;; units.  We fix their latency at 2 cycles and they
669;; are fully pipelined.
670(define_insn_reservation "Z5" 1
671 (and
672   (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
673   (eq_attr "cpu" "8000"))
674 "inm_8000,f_8000,rnm_8000")
675
676;; The fdivsqrt units are not pipelined and have a very long latency.
677;; To keep the DFA from exploding, we do not show all the
678;; reservations for the divsqrt unit.
679(define_insn_reservation "Z6" 17
680 (and
681   (eq_attr "type" "fpdivsgl,fpsqrtsgl")
682   (eq_attr "cpu" "8000"))
683 "inm_8000,fdivsqrt_8000*6,rnm_8000")
684
685(define_insn_reservation "Z7" 31
686 (and
687   (eq_attr "type" "fpdivdbl,fpsqrtdbl")
688   (eq_attr "cpu" "8000"))
689 "inm_8000,fdivsqrt_8000*6,rnm_8000")
690
691;; Operand and operator predicates and constraints
692
693(include "predicates.md")
694(include "constraints.md")
695
696;; Compare instructions.
697;; This controls RTL generation and register allocation.
698
699(define_insn ""
700  [(set (reg:CCFP 0)
701	(match_operator:CCFP 2 "comparison_operator"
702			     [(match_operand:SF 0 "reg_or_0_operand" "fG")
703			      (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
704  "! TARGET_SOFT_FLOAT"
705  "fcmp,sgl,%Y2 %f0,%f1"
706  [(set_attr "length" "4")
707   (set_attr "type" "fpcc")])
708
709(define_insn ""
710  [(set (reg:CCFP 0)
711	(match_operator:CCFP 2 "comparison_operator"
712			     [(match_operand:DF 0 "reg_or_0_operand" "fG")
713			      (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
714  "! TARGET_SOFT_FLOAT"
715  "fcmp,dbl,%Y2 %f0,%f1"
716  [(set_attr "length" "4")
717   (set_attr "type" "fpcc")])
718
719;; Provide a means to emit the movccfp0 and movccfp1 optimization
720;; placeholders.  This is necessary in rare situations when a
721;; placeholder is re-emitted (see PR 8705).
722
723(define_expand "movccfp"
724  [(set (reg:CCFP 0)
725	(match_operand 0 "const_int_operand" ""))]
726  "! TARGET_SOFT_FLOAT"
727  "
728{
729  if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
730    FAIL;
731}")
732
733;; The following patterns are optimization placeholders.  In almost
734;; all cases, the user of the condition code will be simplified and the
735;; original condition code setting insn should be eliminated.
736
737(define_insn "*movccfp0"
738  [(set (reg:CCFP 0)
739	(const_int 0))]
740  "! TARGET_SOFT_FLOAT"
741  "fcmp,dbl,= %%fr0,%%fr0"
742  [(set_attr "length" "4")
743   (set_attr "type" "fpcc")])
744
745(define_insn "*movccfp1"
746  [(set (reg:CCFP 0)
747	(const_int 1))]
748  "! TARGET_SOFT_FLOAT"
749  "fcmp,dbl,!= %%fr0,%%fr0"
750  [(set_attr "length" "4")
751   (set_attr "type" "fpcc")])
752
753;; scc insns.
754
755(define_expand "cstoresi4"
756  [(set (match_operand:SI 0 "register_operand")
757	(match_operator:SI 1 "ordered_comparison_operator"
758	 [(match_operand:SI 2 "reg_or_0_operand" "")
759	  (match_operand:SI 3 "arith5_operand" "")]))]
760  "!TARGET_64BIT"
761  "")
762
763;; Instruction canonicalization puts immediate operands second, which
764;; is the reverse of what we want.
765
766(define_insn "scc"
767  [(set (match_operand:SI 0 "register_operand" "=r")
768	(match_operator:SI 3 "ordered_comparison_operator"
769			   [(match_operand:SI 1 "reg_or_0_operand" "rM")
770			    (match_operand:SI 2 "arith11_operand" "rI")]))]
771  ""
772  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
773  [(set_attr "type" "binary")
774   (set_attr "length" "8")])
775
776(define_insn ""
777  [(set (match_operand:DI 0 "register_operand" "=r")
778	(match_operator:DI 3 "ordered_comparison_operator"
779			   [(match_operand:DI 1 "reg_or_0_operand" "rM")
780			    (match_operand:DI 2 "arith11_operand" "rI")]))]
781  "TARGET_64BIT"
782  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
783  [(set_attr "type" "binary")
784   (set_attr "length" "8")])
785
786(define_insn "iorscc"
787  [(set (match_operand:SI 0 "register_operand" "=r")
788	(ior:SI (match_operator:SI 3 "ordered_comparison_operator"
789				   [(match_operand:SI 1 "reg_or_0_operand" "rM")
790				    (match_operand:SI 2 "arith11_operand" "rI")])
791		(match_operator:SI 6 "ordered_comparison_operator"
792				   [(match_operand:SI 4 "reg_or_0_operand" "rM")
793				    (match_operand:SI 5 "arith11_operand" "rI")])))]
794  ""
795  "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
796  [(set_attr "type" "binary")
797   (set_attr "length" "12")])
798
799(define_insn ""
800  [(set (match_operand:DI 0 "register_operand" "=r")
801	(ior:DI (match_operator:DI 3 "ordered_comparison_operator"
802				   [(match_operand:DI 1 "reg_or_0_operand" "rM")
803				    (match_operand:DI 2 "arith11_operand" "rI")])
804		(match_operator:DI 6 "ordered_comparison_operator"
805				   [(match_operand:DI 4 "reg_or_0_operand" "rM")
806				    (match_operand:DI 5 "arith11_operand" "rI")])))]
807  "TARGET_64BIT"
808  "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
809  [(set_attr "type" "binary")
810   (set_attr "length" "12")])
811
812;; Combiner patterns for common operations performed with the output
813;; from an scc insn (negscc and incscc).
814(define_insn "negscc"
815  [(set (match_operand:SI 0 "register_operand" "=r")
816	(neg:SI (match_operator:SI 3 "ordered_comparison_operator"
817	       [(match_operand:SI 1 "reg_or_0_operand" "rM")
818		(match_operand:SI 2 "arith11_operand" "rI")])))]
819  ""
820  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
821  [(set_attr "type" "binary")
822   (set_attr "length" "8")])
823
824(define_insn ""
825  [(set (match_operand:DI 0 "register_operand" "=r")
826	(neg:DI (match_operator:DI 3 "ordered_comparison_operator"
827	       [(match_operand:DI 1 "reg_or_0_operand" "rM")
828		(match_operand:DI 2 "arith11_operand" "rI")])))]
829  "TARGET_64BIT"
830  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
831  [(set_attr "type" "binary")
832   (set_attr "length" "8")])
833
834;; Patterns for adding/subtracting the result of a boolean expression from
835;; a register.  First we have special patterns that make use of the carry
836;; bit, and output only two instructions.  For the cases we can't in
837;; general do in two instructions, the incscc pattern at the end outputs
838;; two or three instructions.
839
840(define_insn ""
841  [(set (match_operand:SI 0 "register_operand" "=r")
842	(plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
843			 (match_operand:SI 3 "arith11_operand" "rI"))
844		 (match_operand:SI 1 "register_operand" "r")))]
845  ""
846  "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
847  [(set_attr "type" "binary")
848   (set_attr "length" "8")])
849
850(define_insn ""
851  [(set (match_operand:DI 0 "register_operand" "=r")
852	(plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
853			 (match_operand:DI 3 "arith11_operand" "rI"))
854		 (match_operand:DI 1 "register_operand" "r")))]
855  "TARGET_64BIT"
856  "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
857  [(set_attr "type" "binary")
858   (set_attr "length" "8")])
859
860; This need only accept registers for op3, since canonicalization
861; replaces geu with gtu when op3 is an integer.
862(define_insn ""
863  [(set (match_operand:SI 0 "register_operand" "=r")
864	(plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
865			 (match_operand:SI 3 "register_operand" "r"))
866		 (match_operand:SI 1 "register_operand" "r")))]
867  ""
868  "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
869  [(set_attr "type" "binary")
870   (set_attr "length" "8")])
871
872(define_insn ""
873  [(set (match_operand:DI 0 "register_operand" "=r")
874	(plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
875			 (match_operand:DI 3 "register_operand" "r"))
876		 (match_operand:DI 1 "register_operand" "r")))]
877  "TARGET_64BIT"
878  "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
879  [(set_attr "type" "binary")
880   (set_attr "length" "8")])
881
882; Match only integers for op3 here.  This is used as canonical form of the
883; geu pattern when op3 is an integer.  Don't match registers since we can't
884; make better code than the general incscc pattern.
885(define_insn ""
886  [(set (match_operand:SI 0 "register_operand" "=r")
887	(plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
888			 (match_operand:SI 3 "int11_operand" "I"))
889		 (match_operand:SI 1 "register_operand" "r")))]
890  ""
891  "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
892  [(set_attr "type" "binary")
893   (set_attr "length" "8")])
894
895(define_insn ""
896  [(set (match_operand:DI 0 "register_operand" "=r")
897	(plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
898			 (match_operand:DI 3 "int11_operand" "I"))
899		 (match_operand:DI 1 "register_operand" "r")))]
900  "TARGET_64BIT"
901  "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
902  [(set_attr "type" "binary")
903   (set_attr "length" "8")])
904
905(define_insn "incscc"
906  [(set (match_operand:SI 0 "register_operand" "=r,r")
907 	(plus:SI (match_operator:SI 4 "ordered_comparison_operator"
908		    [(match_operand:SI 2 "register_operand" "r,r")
909		     (match_operand:SI 3 "arith11_operand" "rI,rI")])
910		 (match_operand:SI 1 "register_operand" "0,?r")))]
911  ""
912  "@
913   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
914   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
915  [(set_attr "type" "binary,binary")
916   (set_attr "length" "8,12")])
917
918(define_insn ""
919  [(set (match_operand:DI 0 "register_operand" "=r,r")
920 	(plus:DI (match_operator:DI 4 "ordered_comparison_operator"
921		    [(match_operand:DI 2 "register_operand" "r,r")
922		     (match_operand:DI 3 "arith11_operand" "rI,rI")])
923		 (match_operand:DI 1 "register_operand" "0,?r")))]
924  "TARGET_64BIT"
925  "@
926   cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
927   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
928  [(set_attr "type" "binary,binary")
929   (set_attr "length" "8,12")])
930
931(define_insn ""
932  [(set (match_operand:SI 0 "register_operand" "=r")
933	(minus:SI (match_operand:SI 1 "register_operand" "r")
934		  (gtu:SI (match_operand:SI 2 "register_operand" "r")
935			  (match_operand:SI 3 "arith11_operand" "rI"))))]
936  ""
937  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
938  [(set_attr "type" "binary")
939   (set_attr "length" "8")])
940
941(define_insn ""
942  [(set (match_operand:DI 0 "register_operand" "=r")
943	(minus:DI (match_operand:DI 1 "register_operand" "r")
944		  (gtu:DI (match_operand:DI 2 "register_operand" "r")
945			  (match_operand:DI 3 "arith11_operand" "rI"))))]
946  "TARGET_64BIT"
947  "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
948  [(set_attr "type" "binary")
949   (set_attr "length" "8")])
950
951(define_insn ""
952  [(set (match_operand:SI 0 "register_operand" "=r")
953	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
954			    (gtu:SI (match_operand:SI 2 "register_operand" "r")
955				    (match_operand:SI 3 "arith11_operand" "rI")))
956		  (match_operand:SI 4 "register_operand" "r")))]
957  ""
958  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
959  [(set_attr "type" "binary")
960   (set_attr "length" "8")])
961
962(define_insn ""
963  [(set (match_operand:DI 0 "register_operand" "=r")
964	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
965			    (gtu:DI (match_operand:DI 2 "register_operand" "r")
966				    (match_operand:DI 3 "arith11_operand" "rI")))
967		  (match_operand:DI 4 "register_operand" "r")))]
968  "TARGET_64BIT"
969  "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
970  [(set_attr "type" "binary")
971   (set_attr "length" "8")])
972
973; This need only accept registers for op3, since canonicalization
974; replaces ltu with leu when op3 is an integer.
975(define_insn ""
976  [(set (match_operand:SI 0 "register_operand" "=r")
977	(minus:SI (match_operand:SI 1 "register_operand" "r")
978		  (ltu:SI (match_operand:SI 2 "register_operand" "r")
979			  (match_operand:SI 3 "register_operand" "r"))))]
980  ""
981  "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
982  [(set_attr "type" "binary")
983   (set_attr "length" "8")])
984
985(define_insn ""
986  [(set (match_operand:DI 0 "register_operand" "=r")
987	(minus:DI (match_operand:DI 1 "register_operand" "r")
988		  (ltu:DI (match_operand:DI 2 "register_operand" "r")
989			  (match_operand:DI 3 "register_operand" "r"))))]
990  "TARGET_64BIT"
991  "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
992  [(set_attr "type" "binary")
993   (set_attr "length" "8")])
994
995(define_insn ""
996  [(set (match_operand:SI 0 "register_operand" "=r")
997	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
998			    (ltu:SI (match_operand:SI 2 "register_operand" "r")
999				    (match_operand:SI 3 "register_operand" "r")))
1000		  (match_operand:SI 4 "register_operand" "r")))]
1001  ""
1002  "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1003  [(set_attr "type" "binary")
1004   (set_attr "length" "8")])
1005
1006(define_insn ""
1007  [(set (match_operand:DI 0 "register_operand" "=r")
1008	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1009			    (ltu:DI (match_operand:DI 2 "register_operand" "r")
1010				    (match_operand:DI 3 "register_operand" "r")))
1011		  (match_operand:DI 4 "register_operand" "r")))]
1012  "TARGET_64BIT"
1013  "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1014  [(set_attr "type" "binary")
1015   (set_attr "length" "8")])
1016
1017; Match only integers for op3 here.  This is used as canonical form of the
1018; ltu pattern when op3 is an integer.  Don't match registers since we can't
1019; make better code than the general incscc pattern.
1020(define_insn ""
1021  [(set (match_operand:SI 0 "register_operand" "=r")
1022	(minus:SI (match_operand:SI 1 "register_operand" "r")
1023		  (leu:SI (match_operand:SI 2 "register_operand" "r")
1024			  (match_operand:SI 3 "int11_operand" "I"))))]
1025  ""
1026  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1027  [(set_attr "type" "binary")
1028   (set_attr "length" "8")])
1029
1030(define_insn ""
1031  [(set (match_operand:DI 0 "register_operand" "=r")
1032	(minus:DI (match_operand:DI 1 "register_operand" "r")
1033		  (leu:DI (match_operand:DI 2 "register_operand" "r")
1034			  (match_operand:DI 3 "int11_operand" "I"))))]
1035  "TARGET_64BIT"
1036  "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1037  [(set_attr "type" "binary")
1038   (set_attr "length" "8")])
1039
1040(define_insn ""
1041  [(set (match_operand:SI 0 "register_operand" "=r")
1042	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1043			    (leu:SI (match_operand:SI 2 "register_operand" "r")
1044				    (match_operand:SI 3 "int11_operand" "I")))
1045		  (match_operand:SI 4 "register_operand" "r")))]
1046  ""
1047  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1048  [(set_attr "type" "binary")
1049   (set_attr "length" "8")])
1050
1051(define_insn ""
1052  [(set (match_operand:DI 0 "register_operand" "=r")
1053	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1054			    (leu:DI (match_operand:DI 2 "register_operand" "r")
1055				    (match_operand:DI 3 "int11_operand" "I")))
1056		  (match_operand:DI 4 "register_operand" "r")))]
1057  "TARGET_64BIT"
1058  "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1059  [(set_attr "type" "binary")
1060   (set_attr "length" "8")])
1061
1062(define_insn "decscc"
1063  [(set (match_operand:SI 0 "register_operand" "=r,r")
1064	(minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1065		  (match_operator:SI 4 "ordered_comparison_operator"
1066		     [(match_operand:SI 2 "register_operand" "r,r")
1067		      (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1068  ""
1069  "@
1070   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1071   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1072  [(set_attr "type" "binary,binary")
1073   (set_attr "length" "8,12")])
1074
1075(define_insn ""
1076  [(set (match_operand:DI 0 "register_operand" "=r,r")
1077	(minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1078		  (match_operator:DI 4 "ordered_comparison_operator"
1079		     [(match_operand:DI 2 "register_operand" "r,r")
1080		      (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1081  "TARGET_64BIT"
1082  "@
1083   cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1084   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1085  [(set_attr "type" "binary,binary")
1086   (set_attr "length" "8,12")])
1087
1088; Patterns for max and min.  (There is no need for an earlyclobber in the
1089; last alternative since the middle alternative will match if op0 == op1.)
1090
1091(define_insn "sminsi3"
1092  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1093	(smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1094		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1095  ""
1096  "@
1097  {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1098  {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1099  {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1100[(set_attr "type" "multi,multi,multi")
1101 (set_attr "length" "8,8,8")])
1102
1103(define_insn "smindi3"
1104  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1105	(smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1106		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1107  "TARGET_64BIT"
1108  "@
1109  cmpclr,*> %2,%0,%%r0\;copy %2,%0
1110  cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1111  cmpclr,*> %1,%r2,%0\;copy %1,%0"
1112[(set_attr "type" "multi,multi,multi")
1113 (set_attr "length" "8,8,8")])
1114
1115(define_insn "uminsi3"
1116  [(set (match_operand:SI 0 "register_operand" "=r,r")
1117	(umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1118		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1119  ""
1120  "@
1121  {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1122  {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1123[(set_attr "type" "multi,multi")
1124 (set_attr "length" "8,8")])
1125
1126(define_insn "umindi3"
1127  [(set (match_operand:DI 0 "register_operand" "=r,r")
1128	(umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1129		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1130  "TARGET_64BIT"
1131  "@
1132  cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1133  cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1134[(set_attr "type" "multi,multi")
1135 (set_attr "length" "8,8")])
1136
1137(define_insn "smaxsi3"
1138  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1139	(smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1140		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1141  ""
1142  "@
1143  {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1144  {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1145  {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1146[(set_attr "type" "multi,multi,multi")
1147 (set_attr "length" "8,8,8")])
1148
1149(define_insn "smaxdi3"
1150  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1151	(smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1152		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1153  "TARGET_64BIT"
1154  "@
1155  cmpclr,*< %2,%0,%%r0\;copy %2,%0
1156  cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1157  cmpclr,*< %1,%r2,%0\;copy %1,%0"
1158[(set_attr "type" "multi,multi,multi")
1159 (set_attr "length" "8,8,8")])
1160
1161(define_insn "umaxsi3"
1162  [(set (match_operand:SI 0 "register_operand" "=r,r")
1163	(umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1164		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1165  ""
1166  "@
1167  {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1168  {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1169[(set_attr "type" "multi,multi")
1170 (set_attr "length" "8,8")])
1171
1172(define_insn "umaxdi3"
1173  [(set (match_operand:DI 0 "register_operand" "=r,r")
1174	(umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1175		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1176  "TARGET_64BIT"
1177  "@
1178  cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1179  cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1180[(set_attr "type" "multi,multi")
1181 (set_attr "length" "8,8")])
1182
1183(define_insn "absqi2"
1184  [(set (match_operand:QI 0 "register_operand" "=r")
1185	(abs:QI (match_operand:QI 1 "register_operand" "r")))]
1186  ""
1187  "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1188  [(set_attr "type" "multi")
1189   (set_attr "length" "8")])
1190
1191(define_insn "abshi2"
1192  [(set (match_operand:HI 0 "register_operand" "=r")
1193	(abs:HI (match_operand:HI 1 "register_operand" "r")))]
1194  ""
1195  "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1196  [(set_attr "type" "multi")
1197   (set_attr "length" "8")])
1198
1199(define_insn "abssi2"
1200  [(set (match_operand:SI 0 "register_operand" "=r")
1201	(abs:SI (match_operand:SI 1 "register_operand" "r")))]
1202  ""
1203  "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1204  [(set_attr "type" "multi")
1205   (set_attr "length" "8")])
1206
1207(define_insn "absdi2"
1208  [(set (match_operand:DI 0 "register_operand" "=r")
1209	(abs:DI (match_operand:DI 1 "register_operand" "r")))]
1210  "TARGET_64BIT"
1211  "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1212  [(set_attr "type" "multi")
1213   (set_attr "length" "8")])
1214
1215(define_insn "bswaphi2"
1216  [(set (match_operand:HI 0 "register_operand" "=&r")
1217	(bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1218  ""
1219  "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1220  [(set_attr "type" "multi")
1221   (set_attr "length" "8")])
1222
1223(define_insn "bswapsi2"
1224  [(set (match_operand:SI 0 "register_operand" "=&r")
1225	(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1226  ""
1227  "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1228  [(set_attr "type" "multi")
1229   (set_attr "length" "12")])
1230
1231(define_insn "bswapdi2"
1232  [(set (match_operand:DI 0 "register_operand" "=&r")
1233	(bswap:DI (match_operand:DI 1 "register_operand" "r")))
1234   (clobber (match_scratch:DI 2 "=r"))]
1235  "TARGET_64BIT"
1236  "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1237  [(set_attr "type" "multi")
1238   (set_attr "length" "16")])
1239
1240;;; Experimental conditional move patterns
1241
1242(define_expand "movsicc"
1243  [(set (match_operand:SI 0 "register_operand" "")
1244	(if_then_else:SI
1245	 (match_operand 1 "ordered_comparison_operator" "")
1246	 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1247	 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1248  ""
1249  "
1250{
1251  if (GET_MODE (XEXP (operands[1], 0)) != SImode
1252      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1253    FAIL;
1254}")
1255
1256;; We used to accept any register for op1.
1257;;
1258;; However, it loses sometimes because the compiler will end up using
1259;; different registers for op0 and op1 in some critical cases.  local-alloc
1260;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1261;;
1262;; If/when global register allocation supports tying we should allow any
1263;; register for op1 again.
1264(define_insn ""
1265  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1266	(if_then_else:SI
1267	 (match_operator 2 "ordered_comparison_operator"
1268	    [(match_operand:SI 3 "register_operand" "r,r,r,r")
1269	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1270	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1271	 (const_int 0)))]
1272  ""
1273  "@
1274   {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1275   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1276   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1277   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1278  [(set_attr "type" "multi,multi,multi,nullshift")
1279   (set_attr "length" "8,8,8,8")])
1280
1281(define_insn ""
1282  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1283	(if_then_else:SI
1284	 (match_operator 5 "ordered_comparison_operator"
1285	    [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1286	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1287	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1288	 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1289  ""
1290  "@
1291   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1292   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1293   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1294   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1295   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1296   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1297   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1298   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1299  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1300   (set_attr "length" "8,8,8,8,8,8,8,8")])
1301
1302(define_expand "movdicc"
1303  [(set (match_operand:DI 0 "register_operand" "")
1304	(if_then_else:DI
1305	 (match_operand 1 "ordered_comparison_operator" "")
1306	 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1307	 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1308  "TARGET_64BIT"
1309  "
1310{
1311  if (GET_MODE (XEXP (operands[1], 0)) != DImode
1312      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1313    FAIL;
1314}")
1315
1316; We need the first constraint alternative in order to avoid
1317; earlyclobbers on all other alternatives.
1318(define_insn ""
1319  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1320	(if_then_else:DI
1321	 (match_operator 2 "ordered_comparison_operator"
1322	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1323	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1324	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1325	 (const_int 0)))]
1326  "TARGET_64BIT"
1327  "@
1328   cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1329   cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1330   cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1331   cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1332   cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1333  [(set_attr "type" "multi,multi,multi,multi,nullshift")
1334   (set_attr "length" "8,8,8,8,8")])
1335
1336(define_insn ""
1337  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1338	(if_then_else:DI
1339	 (match_operator 5 "ordered_comparison_operator"
1340	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1341	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1342	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1343	 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1344  "TARGET_64BIT"
1345  "@
1346   cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1347   cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1348   cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1349   cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1350   cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1351   cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1352   cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1353   cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1354  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1355   (set_attr "length" "8,8,8,8,8,8,8,8")])
1356
1357;; Conditional Branches
1358
1359(define_expand "cbranchdi4"
1360  [(set (pc)
1361        (if_then_else (match_operator 0 "ordered_comparison_operator"
1362		       [(match_operand:DI 1 "reg_or_0_operand" "")
1363                        (match_operand:DI 2 "register_operand" "")])
1364		      (label_ref (match_operand 3 "" ""))
1365		      (pc)))]
1366  "TARGET_64BIT"
1367  "")
1368
1369(define_expand "cbranchsi4"
1370  [(set (pc)
1371        (if_then_else (match_operator 0 "ordered_comparison_operator"
1372		       [(match_operand:SI 1 "reg_or_0_operand" "")
1373                        (match_operand:SI 2 "arith5_operand" "")])
1374		      (label_ref (match_operand 3 "" ""))
1375		      (pc)))]
1376  ""
1377  "")
1378
1379(define_expand "cbranchsf4"
1380  [(set (pc)
1381        (if_then_else (match_operator 0 "comparison_operator"
1382		       [(match_operand:SF 1 "reg_or_0_operand" "")
1383                        (match_operand:SF 2 "reg_or_0_operand" "")])
1384		      (label_ref (match_operand 3 "" ""))
1385		      (pc)))]
1386  "! TARGET_SOFT_FLOAT"
1387  "
1388{
1389  pa_emit_bcond_fp (operands);
1390  DONE;
1391}")
1392
1393
1394(define_expand "cbranchdf4"
1395  [(set (pc)
1396        (if_then_else (match_operator 0 "comparison_operator"
1397		       [(match_operand:DF 1 "reg_or_0_operand" "")
1398                        (match_operand:DF 2 "reg_or_0_operand" "")])
1399		      (label_ref (match_operand 3 "" ""))
1400		      (pc)))]
1401  "! TARGET_SOFT_FLOAT"
1402  "
1403{
1404  pa_emit_bcond_fp (operands);
1405  DONE;
1406}")
1407
1408;; Match the branch patterns.
1409
1410
1411;; Note a long backward conditional branch with an annulled delay slot
1412;; has a length of 12.
1413(define_insn ""
1414  [(set (pc)
1415	(if_then_else
1416	 (match_operator 3 "ordered_comparison_operator"
1417			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1418			  (match_operand:SI 2 "arith5_operand" "rL")])
1419	 (label_ref (match_operand 0 "" ""))
1420	 (pc)))]
1421  ""
1422  "*
1423{
1424  return pa_output_cbranch (operands, 0, insn);
1425}"
1426[(set_attr "type" "cbranch")
1427 (set (attr "length")
1428    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1429	       (const_int MAX_12BIT_OFFSET))
1430	   (const_int 4)
1431	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1432	       (const_int MAX_17BIT_OFFSET))
1433	   (const_int 8)
1434	   (match_test "TARGET_PORTABLE_RUNTIME")
1435	   (const_int 24)
1436	   (not (match_test "flag_pic"))
1437	   (const_int 20)]
1438	  (const_int 28)))])
1439
1440;; Match the negated branch.
1441
1442(define_insn ""
1443  [(set (pc)
1444	(if_then_else
1445	 (match_operator 3 "ordered_comparison_operator"
1446			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1447			  (match_operand:SI 2 "arith5_operand" "rL")])
1448	 (pc)
1449	 (label_ref (match_operand 0 "" ""))))]
1450  ""
1451  "*
1452{
1453  return pa_output_cbranch (operands, 1, insn);
1454}"
1455[(set_attr "type" "cbranch")
1456 (set (attr "length")
1457    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1458	       (const_int MAX_12BIT_OFFSET))
1459	   (const_int 4)
1460	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1461	       (const_int MAX_17BIT_OFFSET))
1462	   (const_int 8)
1463	   (match_test "TARGET_PORTABLE_RUNTIME")
1464	   (const_int 24)
1465	   (not (match_test "flag_pic"))
1466	   (const_int 20)]
1467	  (const_int 28)))])
1468
1469(define_insn ""
1470  [(set (pc)
1471	(if_then_else
1472	 (match_operator 3 "ordered_comparison_operator"
1473			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1474			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1475	 (label_ref (match_operand 0 "" ""))
1476	 (pc)))]
1477  "TARGET_64BIT"
1478  "*
1479{
1480  return pa_output_cbranch (operands, 0, insn);
1481}"
1482[(set_attr "type" "cbranch")
1483 (set (attr "length")
1484    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1485	       (const_int MAX_12BIT_OFFSET))
1486	   (const_int 4)
1487	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1488	       (const_int MAX_17BIT_OFFSET))
1489	   (const_int 8)
1490	   (match_test "TARGET_PORTABLE_RUNTIME")
1491	   (const_int 24)
1492	   (not (match_test "flag_pic"))
1493	   (const_int 20)]
1494	  (const_int 28)))])
1495
1496;; Match the negated branch.
1497
1498(define_insn ""
1499  [(set (pc)
1500	(if_then_else
1501	 (match_operator 3 "ordered_comparison_operator"
1502			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1503			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1504	 (pc)
1505	 (label_ref (match_operand 0 "" ""))))]
1506  "TARGET_64BIT"
1507  "*
1508{
1509  return pa_output_cbranch (operands, 1, insn);
1510}"
1511[(set_attr "type" "cbranch")
1512 (set (attr "length")
1513    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1514	       (const_int MAX_12BIT_OFFSET))
1515	   (const_int 4)
1516	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1517	       (const_int MAX_17BIT_OFFSET))
1518	   (const_int 8)
1519	   (match_test "TARGET_PORTABLE_RUNTIME")
1520	   (const_int 24)
1521	   (not (match_test "flag_pic"))
1522	   (const_int 20)]
1523	  (const_int 28)))])
1524(define_insn ""
1525  [(set (pc)
1526	(if_then_else
1527	 (match_operator 3 "cmpib_comparison_operator"
1528			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1529			  (match_operand:DI 2 "arith5_operand" "rL")])
1530	 (label_ref (match_operand 0 "" ""))
1531	 (pc)))]
1532  "TARGET_64BIT"
1533  "*
1534{
1535  return pa_output_cbranch (operands, 0, insn);
1536}"
1537[(set_attr "type" "cbranch")
1538 (set (attr "length")
1539    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1540	       (const_int MAX_12BIT_OFFSET))
1541	   (const_int 4)
1542	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1543	       (const_int MAX_17BIT_OFFSET))
1544	   (const_int 8)
1545	   (match_test "TARGET_PORTABLE_RUNTIME")
1546	   (const_int 24)
1547	   (not (match_test "flag_pic"))
1548	   (const_int 20)]
1549	  (const_int 28)))])
1550
1551;; Match the negated branch.
1552
1553(define_insn ""
1554  [(set (pc)
1555	(if_then_else
1556	 (match_operator 3 "cmpib_comparison_operator"
1557			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1558			  (match_operand:DI 2 "arith5_operand" "rL")])
1559	 (pc)
1560	 (label_ref (match_operand 0 "" ""))))]
1561  "TARGET_64BIT"
1562  "*
1563{
1564  return pa_output_cbranch (operands, 1, insn);
1565}"
1566[(set_attr "type" "cbranch")
1567 (set (attr "length")
1568    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1569	       (const_int MAX_12BIT_OFFSET))
1570	   (const_int 4)
1571	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1572	       (const_int MAX_17BIT_OFFSET))
1573	   (const_int 8)
1574	   (match_test "TARGET_PORTABLE_RUNTIME")
1575	   (const_int 24)
1576	   (not (match_test "flag_pic"))
1577	   (const_int 20)]
1578	  (const_int 28)))])
1579
1580;; Branch on Bit patterns.
1581(define_insn ""
1582  [(set (pc)
1583	(if_then_else
1584	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1585			      (const_int 1)
1586			      (match_operand:SI 1 "uint5_operand" ""))
1587	     (const_int 0))
1588	 (label_ref (match_operand 2 "" ""))
1589	 (pc)))]
1590  ""
1591  "*
1592{
1593  return pa_output_bb (operands, 0, insn, 0);
1594}"
1595[(set_attr "type" "cbranch")
1596 (set (attr "length")
1597    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1598	       (const_int MAX_12BIT_OFFSET))
1599	   (const_int 4)
1600	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1601	       (const_int MAX_17BIT_OFFSET))
1602	   (const_int 8)
1603	   (match_test "TARGET_PORTABLE_RUNTIME")
1604	   (const_int 24)
1605	   (not (match_test "flag_pic"))
1606	   (const_int 20)]
1607	  (const_int 28)))])
1608
1609(define_insn ""
1610  [(set (pc)
1611	(if_then_else
1612	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1613			      (const_int 1)
1614			      (match_operand:DI 1 "uint32_operand" ""))
1615	     (const_int 0))
1616	 (label_ref (match_operand 2 "" ""))
1617	 (pc)))]
1618  "TARGET_64BIT"
1619  "*
1620{
1621  return pa_output_bb (operands, 0, insn, 0);
1622}"
1623[(set_attr "type" "cbranch")
1624 (set (attr "length")
1625    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1626	       (const_int MAX_12BIT_OFFSET))
1627	   (const_int 4)
1628	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1629	       (const_int MAX_17BIT_OFFSET))
1630	   (const_int 8)
1631	   (match_test "TARGET_PORTABLE_RUNTIME")
1632	   (const_int 24)
1633	   (not (match_test "flag_pic"))
1634	   (const_int 20)]
1635	  (const_int 28)))])
1636
1637(define_insn ""
1638  [(set (pc)
1639	(if_then_else
1640	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1641			      (const_int 1)
1642			      (match_operand:SI 1 "uint5_operand" ""))
1643	     (const_int 0))
1644	 (pc)
1645	 (label_ref (match_operand 2 "" ""))))]
1646  ""
1647  "*
1648{
1649  return pa_output_bb (operands, 1, insn, 0);
1650}"
1651[(set_attr "type" "cbranch")
1652 (set (attr "length")
1653    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1654	       (const_int MAX_12BIT_OFFSET))
1655	   (const_int 4)
1656	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1657	       (const_int MAX_17BIT_OFFSET))
1658	   (const_int 8)
1659	   (match_test "TARGET_PORTABLE_RUNTIME")
1660	   (const_int 24)
1661	   (not (match_test "flag_pic"))
1662	   (const_int 20)]
1663	  (const_int 28)))])
1664
1665(define_insn ""
1666  [(set (pc)
1667	(if_then_else
1668	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1669			      (const_int 1)
1670			      (match_operand:DI 1 "uint32_operand" ""))
1671	     (const_int 0))
1672	 (pc)
1673	 (label_ref (match_operand 2 "" ""))))]
1674  "TARGET_64BIT"
1675  "*
1676{
1677  return pa_output_bb (operands, 1, insn, 0);
1678}"
1679[(set_attr "type" "cbranch")
1680 (set (attr "length")
1681    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1682	       (const_int MAX_12BIT_OFFSET))
1683	   (const_int 4)
1684	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1685	       (const_int MAX_17BIT_OFFSET))
1686	   (const_int 8)
1687	   (match_test "TARGET_PORTABLE_RUNTIME")
1688	   (const_int 24)
1689	   (not (match_test "flag_pic"))
1690	   (const_int 20)]
1691	  (const_int 28)))])
1692
1693(define_insn ""
1694  [(set (pc)
1695	(if_then_else
1696	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1697			      (const_int 1)
1698			      (match_operand:SI 1 "uint5_operand" ""))
1699	     (const_int 0))
1700	 (label_ref (match_operand 2 "" ""))
1701	 (pc)))]
1702  ""
1703  "*
1704{
1705  return pa_output_bb (operands, 0, insn, 1);
1706}"
1707[(set_attr "type" "cbranch")
1708 (set (attr "length")
1709    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1710	       (const_int MAX_12BIT_OFFSET))
1711	   (const_int 4)
1712	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1713	       (const_int MAX_17BIT_OFFSET))
1714	   (const_int 8)
1715	   (match_test "TARGET_PORTABLE_RUNTIME")
1716	   (const_int 24)
1717	   (not (match_test "flag_pic"))
1718	   (const_int 20)]
1719	  (const_int 28)))])
1720
1721(define_insn ""
1722  [(set (pc)
1723	(if_then_else
1724	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1725			      (const_int 1)
1726			      (match_operand:DI 1 "uint32_operand" ""))
1727	     (const_int 0))
1728	 (label_ref (match_operand 2 "" ""))
1729	 (pc)))]
1730  "TARGET_64BIT"
1731  "*
1732{
1733  return pa_output_bb (operands, 0, insn, 1);
1734}"
1735[(set_attr "type" "cbranch")
1736 (set (attr "length")
1737    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1738	       (const_int MAX_12BIT_OFFSET))
1739	   (const_int 4)
1740	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1741	       (const_int MAX_17BIT_OFFSET))
1742	   (const_int 8)
1743	   (match_test "TARGET_PORTABLE_RUNTIME")
1744	   (const_int 24)
1745	   (not (match_test "flag_pic"))
1746	   (const_int 20)]
1747	  (const_int 28)))])
1748
1749(define_insn ""
1750  [(set (pc)
1751	(if_then_else
1752	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1753			      (const_int 1)
1754			      (match_operand:SI 1 "uint5_operand" ""))
1755	     (const_int 0))
1756	 (pc)
1757	 (label_ref (match_operand 2 "" ""))))]
1758  ""
1759  "*
1760{
1761  return pa_output_bb (operands, 1, insn, 1);
1762}"
1763[(set_attr "type" "cbranch")
1764 (set (attr "length")
1765    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1766	       (const_int MAX_12BIT_OFFSET))
1767	   (const_int 4)
1768	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1769	       (const_int MAX_17BIT_OFFSET))
1770	   (const_int 8)
1771	   (match_test "TARGET_PORTABLE_RUNTIME")
1772	   (const_int 24)
1773	   (not (match_test "flag_pic"))
1774	   (const_int 20)]
1775	  (const_int 28)))])
1776
1777(define_insn ""
1778  [(set (pc)
1779	(if_then_else
1780	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1781			      (const_int 1)
1782			      (match_operand:DI 1 "uint32_operand" ""))
1783	     (const_int 0))
1784	 (pc)
1785	 (label_ref (match_operand 2 "" ""))))]
1786  "TARGET_64BIT"
1787  "*
1788{
1789  return pa_output_bb (operands, 1, insn, 1);
1790}"
1791[(set_attr "type" "cbranch")
1792 (set (attr "length")
1793    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1794	       (const_int MAX_12BIT_OFFSET))
1795	   (const_int 4)
1796	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1797	       (const_int MAX_17BIT_OFFSET))
1798	   (const_int 8)
1799	   (match_test "TARGET_PORTABLE_RUNTIME")
1800	   (const_int 24)
1801	   (not (match_test "flag_pic"))
1802	   (const_int 20)]
1803	  (const_int 28)))])
1804
1805;; Branch on Variable Bit patterns.
1806(define_insn ""
1807  [(set (pc)
1808	(if_then_else
1809	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1810			      (const_int 1)
1811			      (match_operand:SI 1 "register_operand" "q"))
1812	     (const_int 0))
1813	 (label_ref (match_operand 2 "" ""))
1814	 (pc)))]
1815  ""
1816  "*
1817{
1818  return pa_output_bvb (operands, 0, insn, 0);
1819}"
1820[(set_attr "type" "cbranch")
1821 (set (attr "length")
1822    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1823	       (const_int MAX_12BIT_OFFSET))
1824	   (const_int 4)
1825	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1826	       (const_int MAX_17BIT_OFFSET))
1827	   (const_int 8)
1828	   (match_test "TARGET_PORTABLE_RUNTIME")
1829	   (const_int 24)
1830	   (not (match_test "flag_pic"))
1831	   (const_int 20)]
1832	  (const_int 28)))])
1833
1834(define_insn ""
1835  [(set (pc)
1836	(if_then_else
1837	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1838			      (const_int 1)
1839			      (match_operand:DI 1 "register_operand" "q"))
1840	     (const_int 0))
1841	 (label_ref (match_operand 2 "" ""))
1842	 (pc)))]
1843  "TARGET_64BIT"
1844  "*
1845{
1846  return pa_output_bvb (operands, 0, insn, 0);
1847}"
1848[(set_attr "type" "cbranch")
1849 (set (attr "length")
1850    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1851	       (const_int MAX_12BIT_OFFSET))
1852	   (const_int 4)
1853	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1854	       (const_int MAX_17BIT_OFFSET))
1855	   (const_int 8)
1856	   (match_test "TARGET_PORTABLE_RUNTIME")
1857	   (const_int 24)
1858	   (not (match_test "flag_pic"))
1859	   (const_int 20)]
1860	  (const_int 28)))])
1861
1862(define_insn ""
1863  [(set (pc)
1864	(if_then_else
1865	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1866			      (const_int 1)
1867			      (match_operand:SI 1 "register_operand" "q"))
1868	     (const_int 0))
1869	 (pc)
1870	 (label_ref (match_operand 2 "" ""))))]
1871  ""
1872  "*
1873{
1874  return pa_output_bvb (operands, 1, insn, 0);
1875}"
1876[(set_attr "type" "cbranch")
1877 (set (attr "length")
1878    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1879	       (const_int MAX_12BIT_OFFSET))
1880	   (const_int 4)
1881	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1882	       (const_int MAX_17BIT_OFFSET))
1883	   (const_int 8)
1884	   (match_test "TARGET_PORTABLE_RUNTIME")
1885	   (const_int 24)
1886	   (not (match_test "flag_pic"))
1887	   (const_int 20)]
1888	  (const_int 28)))])
1889
1890(define_insn ""
1891  [(set (pc)
1892	(if_then_else
1893	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1894			      (const_int 1)
1895			      (match_operand:DI 1 "register_operand" "q"))
1896	     (const_int 0))
1897	 (pc)
1898	 (label_ref (match_operand 2 "" ""))))]
1899  "TARGET_64BIT"
1900  "*
1901{
1902  return pa_output_bvb (operands, 1, insn, 0);
1903}"
1904[(set_attr "type" "cbranch")
1905 (set (attr "length")
1906    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1907	       (const_int MAX_12BIT_OFFSET))
1908	   (const_int 4)
1909	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1910	       (const_int MAX_17BIT_OFFSET))
1911	   (const_int 8)
1912	   (match_test "TARGET_PORTABLE_RUNTIME")
1913	   (const_int 24)
1914	   (not (match_test "flag_pic"))
1915	   (const_int 20)]
1916	  (const_int 28)))])
1917
1918(define_insn ""
1919  [(set (pc)
1920	(if_then_else
1921	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1922			      (const_int 1)
1923			      (match_operand:SI 1 "register_operand" "q"))
1924	     (const_int 0))
1925	 (label_ref (match_operand 2 "" ""))
1926	 (pc)))]
1927  ""
1928  "*
1929{
1930  return pa_output_bvb (operands, 0, insn, 1);
1931}"
1932[(set_attr "type" "cbranch")
1933 (set (attr "length")
1934    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1935	       (const_int MAX_12BIT_OFFSET))
1936	   (const_int 4)
1937	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1938	       (const_int MAX_17BIT_OFFSET))
1939	   (const_int 8)
1940	   (match_test "TARGET_PORTABLE_RUNTIME")
1941	   (const_int 24)
1942	   (not (match_test "flag_pic"))
1943	   (const_int 20)]
1944	  (const_int 28)))])
1945
1946(define_insn ""
1947  [(set (pc)
1948	(if_then_else
1949	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1950			      (const_int 1)
1951			      (match_operand:DI 1 "register_operand" "q"))
1952	     (const_int 0))
1953	 (label_ref (match_operand 2 "" ""))
1954	 (pc)))]
1955  "TARGET_64BIT"
1956  "*
1957{
1958  return pa_output_bvb (operands, 0, insn, 1);
1959}"
1960[(set_attr "type" "cbranch")
1961 (set (attr "length")
1962    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1963	       (const_int MAX_12BIT_OFFSET))
1964	   (const_int 4)
1965	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1966	       (const_int MAX_17BIT_OFFSET))
1967	   (const_int 8)
1968	   (match_test "TARGET_PORTABLE_RUNTIME")
1969	   (const_int 24)
1970	   (not (match_test "flag_pic"))
1971	   (const_int 20)]
1972	  (const_int 28)))])
1973
1974(define_insn ""
1975  [(set (pc)
1976	(if_then_else
1977	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1978			      (const_int 1)
1979			      (match_operand:SI 1 "register_operand" "q"))
1980	     (const_int 0))
1981	 (pc)
1982	 (label_ref (match_operand 2 "" ""))))]
1983  ""
1984  "*
1985{
1986  return pa_output_bvb (operands, 1, insn, 1);
1987}"
1988[(set_attr "type" "cbranch")
1989 (set (attr "length")
1990    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1991	       (const_int MAX_12BIT_OFFSET))
1992	   (const_int 4)
1993	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1994	       (const_int MAX_17BIT_OFFSET))
1995	   (const_int 8)
1996	   (match_test "TARGET_PORTABLE_RUNTIME")
1997	   (const_int 24)
1998	   (not (match_test "flag_pic"))
1999	   (const_int 20)]
2000	  (const_int 28)))])
2001
2002(define_insn ""
2003  [(set (pc)
2004	(if_then_else
2005	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2006			      (const_int 1)
2007			      (match_operand:DI 1 "register_operand" "q"))
2008	     (const_int 0))
2009	 (pc)
2010	 (label_ref (match_operand 2 "" ""))))]
2011  "TARGET_64BIT"
2012  "*
2013{
2014  return pa_output_bvb (operands, 1, insn, 1);
2015}"
2016[(set_attr "type" "cbranch")
2017 (set (attr "length")
2018    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2019	       (const_int MAX_12BIT_OFFSET))
2020	   (const_int 4)
2021	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2022	       (const_int MAX_17BIT_OFFSET))
2023	   (const_int 8)
2024	   (match_test "TARGET_PORTABLE_RUNTIME")
2025	   (const_int 24)
2026	   (not (match_test "flag_pic"))
2027	   (const_int 20)]
2028	  (const_int 28)))])
2029
2030;; Floating point branches
2031
2032;; ??? Nullification is handled differently from other branches.
2033;; If nullification is specified, the delay slot is nullified on any
2034;; taken branch regardless of branch direction.
2035(define_insn ""
2036  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2037			   (label_ref (match_operand 0 "" ""))
2038			   (pc)))]
2039  "!TARGET_SOFT_FLOAT"
2040  "*
2041{
2042  int length = get_attr_length (insn);
2043  rtx xoperands[1];
2044  int nullify, xdelay;
2045
2046  if (length < 16)
2047    return \"ftest\;b%* %l0\";
2048
2049  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2050    {
2051      nullify = 1;
2052      xdelay = 0;
2053      xoperands[0] = GEN_INT (length - 8);
2054    }
2055  else
2056    {
2057      nullify = 0;
2058      xdelay = 1;
2059      xoperands[0] = GEN_INT (length - 4);
2060    }
2061
2062  if (nullify)
2063    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2064  else
2065    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2066  return pa_output_lbranch (operands[0], insn, xdelay);
2067}"
2068[(set_attr "type" "fbranch")
2069 (set (attr "length")
2070    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2071	       (const_int MAX_17BIT_OFFSET))
2072	   (const_int 8)
2073	   (match_test "TARGET_PORTABLE_RUNTIME")
2074	   (const_int 32)
2075	   (not (match_test "flag_pic"))
2076	   (const_int 28)]
2077	  (const_int 36)))])
2078
2079(define_insn ""
2080  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2081			   (pc)
2082			   (label_ref (match_operand 0 "" ""))))]
2083  "!TARGET_SOFT_FLOAT"
2084  "*
2085{
2086  int length = get_attr_length (insn);
2087  rtx xoperands[1];
2088  int nullify, xdelay;
2089
2090  if (length < 16)
2091    return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2092
2093  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2094    {
2095      nullify = 1;
2096      xdelay = 0;
2097      xoperands[0] = GEN_INT (length - 4);
2098    }
2099  else
2100    {
2101      nullify = 0;
2102      xdelay = 1;
2103      xoperands[0] = GEN_INT (length);
2104    }
2105
2106  if (nullify)
2107    output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2108  else
2109    output_asm_insn (\"ftest\;b .+%0\", xoperands);
2110  return pa_output_lbranch (operands[0], insn, xdelay);
2111}"
2112[(set_attr "type" "fbranch")
2113 (set (attr "length")
2114    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2115	       (const_int MAX_17BIT_OFFSET))
2116	   (const_int 12)
2117	   (match_test "TARGET_PORTABLE_RUNTIME")
2118	   (const_int 28)
2119	   (not (match_test "flag_pic"))
2120	   (const_int 24)]
2121	  (const_int 32)))])
2122
2123;; Move instructions
2124
2125(define_expand "movsi"
2126  [(set (match_operand:SI 0 "general_operand" "")
2127	(match_operand:SI 1 "general_operand" ""))]
2128  ""
2129  "
2130{
2131  if (pa_emit_move_sequence (operands, SImode, 0))
2132    DONE;
2133}")
2134
2135;; Handle SImode input reloads requiring %r1 as a scratch register.
2136(define_expand "reload_insi_r1"
2137  [(set (match_operand:SI 0 "register_operand" "=Z")
2138	(match_operand:SI 1 "non_hard_reg_operand" ""))
2139   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2140  ""
2141  "
2142{
2143  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2144    DONE;
2145
2146  /* We don't want the clobber emitted, so handle this ourselves.  */
2147  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2148  DONE;
2149}")
2150
2151;; Handle SImode input reloads requiring a general register as a
2152;; scratch register.
2153(define_expand "reload_insi"
2154  [(set (match_operand:SI 0 "register_operand" "=Z")
2155	(match_operand:SI 1 "non_hard_reg_operand" ""))
2156   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2157  ""
2158  "
2159{
2160  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2161    DONE;
2162
2163  /* We don't want the clobber emitted, so handle this ourselves.  */
2164  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2165  DONE;
2166}")
2167
2168;; Handle SImode output reloads requiring a general register as a
2169;; scratch register.
2170(define_expand "reload_outsi"
2171  [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2172	(match_operand:SI 1  "register_operand" "Z"))
2173   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2174  ""
2175  "
2176{
2177  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2178    DONE;
2179
2180  /* We don't want the clobber emitted, so handle this ourselves.  */
2181  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2182  DONE;
2183}")
2184
2185(define_insn ""
2186  [(set (match_operand:SI 0 "move_dest_operand"
2187			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2188	(match_operand:SI 1 "move_src_operand"
2189			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2190  "(register_operand (operands[0], SImode)
2191    || reg_or_0_operand (operands[1], SImode))
2192   && !TARGET_SOFT_FLOAT
2193   && !TARGET_64BIT"
2194  "@
2195   ldw RT'%A1,%0
2196   copy %1,%0
2197   ldi %1,%0
2198   ldil L'%1,%0
2199   {zdepi|depwi,z} %Z1,%0
2200   ldw%M1 %1,%0
2201   stw%M0 %r1,%0
2202   mtsar %r1
2203   {mfctl|mfctl,w} %%sar,%0
2204   fcpy,sgl %f1,%0
2205   fldw%F1 %1,%0
2206   fstw%F0 %1,%0
2207   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2208   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2209  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2210   (set_attr "pa_combine_type" "addmove")
2211   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2212
2213(define_insn ""
2214  [(set (match_operand:SI 0 "move_dest_operand"
2215			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2216	(match_operand:SI 1 "move_src_operand"
2217			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2218  "(register_operand (operands[0], SImode)
2219    || reg_or_0_operand (operands[1], SImode))
2220   && !TARGET_SOFT_FLOAT
2221   && TARGET_64BIT"
2222  "@
2223   ldw RT'%A1,%0
2224   copy %1,%0
2225   ldi %1,%0
2226   ldil L'%1,%0
2227   {zdepi|depwi,z} %Z1,%0
2228   ldw%M1 %1,%0
2229   stw%M0 %r1,%0
2230   mtsar %r1
2231   {mfctl|mfctl,w} %%sar,%0
2232   fcpy,sgl %f1,%0
2233   fldw%F1 %1,%0
2234   fstw%F0 %1,%0"
2235  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2236   (set_attr "pa_combine_type" "addmove")
2237   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2238
2239(define_insn ""
2240  [(set (match_operand:SI 0 "move_dest_operand"
2241			  "=r,r,r,r,r,r,Q,!*q,!r")
2242	(match_operand:SI 1 "move_src_operand"
2243			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2244  "(register_operand (operands[0], SImode)
2245    || reg_or_0_operand (operands[1], SImode))
2246   && TARGET_SOFT_FLOAT
2247   && TARGET_64BIT"
2248  "@
2249   ldw RT'%A1,%0
2250   copy %1,%0
2251   ldi %1,%0
2252   ldil L'%1,%0
2253   {zdepi|depwi,z} %Z1,%0
2254   ldw%M1 %1,%0
2255   stw%M0 %r1,%0
2256   mtsar %r1
2257   {mfctl|mfctl,w} %%sar,%0"
2258  [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
2259   (set_attr "pa_combine_type" "addmove")
2260   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2261
2262(define_insn ""
2263  [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2264	(match_operand:SI 1 "register_operand" "f"))]
2265  "!TARGET_SOFT_FLOAT
2266   && !TARGET_DISABLE_INDEXING
2267   && reload_completed"
2268  "fstw%F0 %1,%0"
2269  [(set_attr "type" "fpstore")
2270   (set_attr "pa_combine_type" "addmove")
2271   (set_attr "length" "4")])
2272
2273; Rewrite RTL using an indexed store.  This will allow the insn that
2274; computes the address to be deleted if the register it sets is dead.
2275(define_peephole2
2276  [(set (match_operand:SI 0 "register_operand" "")
2277	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2278			    (const_int 2))
2279		 (match_operand:SI 2 "register_operand" "")))
2280   (set (mem:SI (match_dup 0))
2281        (match_operand:SI 3 "register_operand" ""))]
2282  "!TARGET_SOFT_FLOAT
2283   && !TARGET_DISABLE_INDEXING
2284   && REG_OK_FOR_BASE_P (operands[2])
2285   && FP_REGNO_P (REGNO (operands[3]))"
2286  [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2287	(match_dup 3))
2288   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2289			       (match_dup 2)))]
2290  "")
2291
2292(define_peephole2
2293  [(set (match_operand:DI 0 "register_operand" "")
2294	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2295			    (const_int 2))
2296		 (match_operand:DI 2 "register_operand" "")))
2297   (set (mem:SI (match_dup 0))
2298        (match_operand:SI 3 "register_operand" ""))]
2299  "!TARGET_SOFT_FLOAT
2300   && !TARGET_DISABLE_INDEXING
2301   && TARGET_64BIT
2302   && REG_OK_FOR_BASE_P (operands[2])
2303   && FP_REGNO_P (REGNO (operands[3]))"
2304  [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2305	(match_dup 3))
2306   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2307			       (match_dup 2)))]
2308  "")
2309
2310(define_peephole2
2311  [(set (match_operand:SI 0 "register_operand" "")
2312	(plus:SI (match_operand:SI 1 "register_operand" "")
2313		 (match_operand:SI 2 "register_operand" "")))
2314   (set (mem:SI (match_dup 0))
2315        (match_operand:SI 3 "register_operand" ""))]
2316  "!TARGET_SOFT_FLOAT
2317   && !TARGET_DISABLE_INDEXING
2318   && TARGET_NO_SPACE_REGS
2319   && REG_OK_FOR_INDEX_P (operands[1])
2320   && REG_OK_FOR_BASE_P (operands[2])
2321   && FP_REGNO_P (REGNO (operands[3]))"
2322  [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2323	(match_dup 3))
2324   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2325  "")
2326
2327(define_peephole2
2328  [(set (match_operand:SI 0 "register_operand" "")
2329	(plus:SI (match_operand:SI 1 "register_operand" "")
2330		 (match_operand:SI 2 "register_operand" "")))
2331   (set (mem:SI (match_dup 0))
2332        (match_operand:SI 3 "register_operand" ""))]
2333  "!TARGET_SOFT_FLOAT
2334   && !TARGET_DISABLE_INDEXING
2335   && TARGET_NO_SPACE_REGS
2336   && REG_OK_FOR_BASE_P (operands[1])
2337   && REG_OK_FOR_INDEX_P (operands[2])
2338   && FP_REGNO_P (REGNO (operands[3]))"
2339  [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2340	(match_dup 3))
2341   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2342  "")
2343
2344(define_peephole2
2345  [(set (match_operand:DI 0 "register_operand" "")
2346	(plus:DI (match_operand:DI 1 "register_operand" "")
2347		 (match_operand:DI 2 "register_operand" "")))
2348   (set (mem:SI (match_dup 0))
2349        (match_operand:SI 3 "register_operand" ""))]
2350  "!TARGET_SOFT_FLOAT
2351   && !TARGET_DISABLE_INDEXING
2352   && TARGET_64BIT
2353   && TARGET_NO_SPACE_REGS
2354   && REG_OK_FOR_INDEX_P (operands[1])
2355   && REG_OK_FOR_BASE_P (operands[2])
2356   && FP_REGNO_P (REGNO (operands[3]))"
2357  [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2358	(match_dup 3))
2359   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2360  "")
2361
2362(define_peephole2
2363  [(set (match_operand:DI 0 "register_operand" "")
2364	(plus:DI (match_operand:DI 1 "register_operand" "")
2365		 (match_operand:DI 2 "register_operand" "")))
2366   (set (mem:SI (match_dup 0))
2367        (match_operand:SI 3 "register_operand" ""))]
2368  "!TARGET_SOFT_FLOAT
2369   && !TARGET_DISABLE_INDEXING
2370   && TARGET_64BIT
2371   && TARGET_NO_SPACE_REGS
2372   && REG_OK_FOR_BASE_P (operands[1])
2373   && REG_OK_FOR_INDEX_P (operands[2])
2374   && FP_REGNO_P (REGNO (operands[3]))"
2375  [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2376	(match_dup 3))
2377   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2378  "")
2379
2380(define_insn ""
2381  [(set (match_operand:SI 0 "move_dest_operand"
2382			  "=r,r,r,r,r,r,Q,!*q,!r")
2383	(match_operand:SI 1 "move_src_operand"
2384			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2385  "(register_operand (operands[0], SImode)
2386    || reg_or_0_operand (operands[1], SImode))
2387   && TARGET_SOFT_FLOAT"
2388  "@
2389   ldw RT'%A1,%0
2390   copy %1,%0
2391   ldi %1,%0
2392   ldil L'%1,%0
2393   {zdepi|depwi,z} %Z1,%0
2394   ldw%M1 %1,%0
2395   stw%M0 %r1,%0
2396   mtsar %r1
2397   {mfctl|mfctl,w} %%sar,%0"
2398  [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2399   (set_attr "pa_combine_type" "addmove")
2400   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2401
2402;; Load or store with base-register modification.
2403(define_insn ""
2404  [(set (match_operand:SI 0 "register_operand" "=r")
2405	(mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2406			 (match_operand:DI 2 "int5_operand" "L"))))
2407   (set (match_dup 1)
2408	(plus:DI (match_dup 1) (match_dup 2)))]
2409  "TARGET_64BIT"
2410  "ldw,mb %2(%1),%0"
2411  [(set_attr "type" "load")
2412   (set_attr "length" "4")])
2413
2414; And a zero extended variant.
2415(define_insn ""
2416  [(set (match_operand:DI 0 "register_operand" "=r")
2417	(zero_extend:DI (mem:SI
2418			  (plus:DI
2419			    (match_operand:DI 1 "register_operand" "+r")
2420			    (match_operand:DI 2 "int5_operand" "L")))))
2421   (set (match_dup 1)
2422	(plus:DI (match_dup 1) (match_dup 2)))]
2423  "TARGET_64BIT"
2424  "ldw,mb %2(%1),%0"
2425  [(set_attr "type" "load")
2426   (set_attr "length" "4")])
2427
2428(define_expand "pre_load"
2429  [(parallel [(set (match_operand:SI 0 "register_operand" "")
2430	      (mem (plus (match_operand 1 "register_operand" "")
2431			       (match_operand 2 "pre_cint_operand" ""))))
2432	      (set (match_dup 1)
2433		   (plus (match_dup 1) (match_dup 2)))])]
2434  ""
2435  "
2436{
2437  if (TARGET_64BIT)
2438    {
2439      emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2440      DONE;
2441    }
2442  emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2443  DONE;
2444}")
2445
2446(define_insn "pre_ldw"
2447  [(set (match_operand:SI 0 "register_operand" "=r")
2448	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2449			 (match_operand:SI 2 "pre_cint_operand" ""))))
2450   (set (match_dup 1)
2451	(plus:SI (match_dup 1) (match_dup 2)))]
2452  ""
2453  "*
2454{
2455  if (INTVAL (operands[2]) < 0)
2456    return \"{ldwm|ldw,mb} %2(%1),%0\";
2457  return \"{ldws|ldw},mb %2(%1),%0\";
2458}"
2459  [(set_attr "type" "load")
2460   (set_attr "length" "4")])
2461
2462(define_insn "pre_ldd"
2463  [(set (match_operand:DI 0 "register_operand" "=r")
2464	(mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2465			 (match_operand:DI 2 "pre_cint_operand" ""))))
2466   (set (match_dup 1)
2467	(plus:DI (match_dup 1) (match_dup 2)))]
2468  "TARGET_64BIT"
2469  "ldd,mb %2(%1),%0"
2470  [(set_attr "type" "load")
2471   (set_attr "length" "4")])
2472
2473(define_insn ""
2474  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2475			 (match_operand:SI 1 "pre_cint_operand" "")))
2476	(match_operand:SI 2 "reg_or_0_operand" "rM"))
2477   (set (match_dup 0)
2478	(plus:SI (match_dup 0) (match_dup 1)))]
2479  ""
2480  "*
2481{
2482  if (INTVAL (operands[1]) < 0)
2483    return \"{stwm|stw,mb} %r2,%1(%0)\";
2484  return \"{stws|stw},mb %r2,%1(%0)\";
2485}"
2486  [(set_attr "type" "store")
2487   (set_attr "length" "4")])
2488
2489(define_insn ""
2490  [(set (match_operand:SI 0 "register_operand" "=r")
2491	(mem:SI (match_operand:SI 1 "register_operand" "+r")))
2492   (set (match_dup 1)
2493	(plus:SI (match_dup 1)
2494		 (match_operand:SI 2 "post_cint_operand" "")))]
2495  ""
2496  "*
2497{
2498  if (INTVAL (operands[2]) > 0)
2499    return \"{ldwm|ldw,ma} %2(%1),%0\";
2500  return \"{ldws|ldw},ma %2(%1),%0\";
2501}"
2502  [(set_attr "type" "load")
2503   (set_attr "length" "4")])
2504
2505(define_expand "post_store"
2506  [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2507		   (match_operand 1 "reg_or_0_operand" ""))
2508	      (set (match_dup 0)
2509		   (plus (match_dup 0)
2510			 (match_operand 2 "post_cint_operand" "")))])]
2511  ""
2512  "
2513{
2514  if (TARGET_64BIT)
2515    {
2516      emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2517      DONE;
2518    }
2519  emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2520  DONE;
2521}")
2522
2523(define_insn "post_stw"
2524  [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2525	(match_operand:SI 1 "reg_or_0_operand" "rM"))
2526   (set (match_dup 0)
2527	(plus:SI (match_dup 0)
2528		 (match_operand:SI 2 "post_cint_operand" "")))]
2529  ""
2530  "*
2531{
2532  if (INTVAL (operands[2]) > 0)
2533    return \"{stwm|stw,ma} %r1,%2(%0)\";
2534  return \"{stws|stw},ma %r1,%2(%0)\";
2535}"
2536  [(set_attr "type" "store")
2537   (set_attr "length" "4")])
2538
2539(define_insn "post_std"
2540  [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2541	(match_operand:DI 1 "reg_or_0_operand" "rM"))
2542   (set (match_dup 0)
2543	(plus:DI (match_dup 0)
2544		 (match_operand:DI 2 "post_cint_operand" "")))]
2545  "TARGET_64BIT"
2546  "std,ma %r1,%2(%0)"
2547  [(set_attr "type" "store")
2548   (set_attr "length" "4")])
2549
2550;; For loading the address of a label while generating PIC code.
2551;; Note since this pattern can be created at reload time (via movsi), all
2552;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2553(define_insn ""
2554  [(set (match_operand 0 "pmode_register_operand" "=a")
2555	(match_operand 1 "pic_label_operand" ""))]
2556  "TARGET_PA_20"
2557  "*
2558{
2559  rtx xoperands[3];
2560
2561  xoperands[0] = operands[0];
2562  xoperands[1] = operands[1];
2563
2564  if (GET_CODE (operands[1]) == LABEL_REF
2565      && !LABEL_REF_NONLOCAL_P (operands[1]))
2566    {
2567      xoperands[2] = gen_label_rtx ();
2568      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2569					 CODE_LABEL_NUMBER (xoperands[2]));
2570      output_asm_insn (\"mfia %0\", xoperands);
2571
2572      /* If we're trying to load the address of a label that happens to be
2573	 close, then we can use a shorter sequence.  */
2574      if (INSN_ADDRESSES_SET_P ()
2575	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2576		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2577	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2578      else
2579	{
2580	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2581	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2582	}
2583    }
2584  else
2585    {
2586      /* Load using linkage table.  */
2587      if (TARGET_64BIT)
2588	{
2589	  output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
2590	  output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
2591	}
2592      else
2593	{
2594	  output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2595	  output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2596	}
2597    }
2598  return \"\";
2599}"
2600  [(set_attr "type" "multi")
2601   (set_attr "length" "12")])		; 8 or 12
2602
2603(define_insn ""
2604  [(set (match_operand 0 "pmode_register_operand" "=a")
2605	(match_operand 1 "pic_label_operand" ""))]
2606  "!TARGET_PA_20"
2607  "*
2608{
2609  rtx xoperands[3];
2610
2611  xoperands[0] = operands[0];
2612  xoperands[1] = operands[1];
2613
2614  if (GET_CODE (operands[1]) == LABEL_REF
2615      && !LABEL_REF_NONLOCAL_P (operands[1]))
2616    {
2617      xoperands[2] = gen_label_rtx ();
2618      output_asm_insn (\"bl .+8,%0\", xoperands);
2619      output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2620      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2621					 CODE_LABEL_NUMBER (xoperands[2]));
2622
2623      /* If we're trying to load the address of a label that happens to be
2624	 close, then we can use a shorter sequence.  */
2625      if (INSN_ADDRESSES_SET_P ()
2626	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2627		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2628	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2629      else
2630	{
2631	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2632	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2633	}
2634    }
2635  else
2636    {
2637      /* Load using linkage table.  */
2638      output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2639      output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2640    }
2641  return \"\";
2642}"
2643  [(set_attr "type" "multi")
2644   (set_attr "length" "16")])		; 12 or 16
2645
2646(define_insn ""
2647  [(set (match_operand:SI 0 "register_operand" "=a")
2648	(plus:SI (match_operand:SI 1 "register_operand" "r")
2649		 (high:SI (match_operand 2 "" ""))))]
2650  "symbolic_operand (operands[2], Pmode)
2651   && ! function_label_operand (operands[2], Pmode)
2652   && flag_pic"
2653  "addil LT'%G2,%1"
2654  [(set_attr "type" "binary")
2655   (set_attr "length" "4")])
2656
2657(define_insn ""
2658  [(set (match_operand:DI 0 "register_operand" "=a")
2659	(plus:DI (match_operand:DI 1 "register_operand" "r")
2660	         (high:DI (match_operand 2 "" ""))))]
2661  "symbolic_operand (operands[2], Pmode)
2662   && ! function_label_operand (operands[2], Pmode)
2663   && TARGET_64BIT
2664   && flag_pic"
2665  "addil LT'%G2,%1"
2666  [(set_attr "type" "binary")
2667   (set_attr "length" "4")])
2668
2669(define_insn ""
2670 [(set (match_operand:SI 0 "register_operand" "=r")
2671       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2672		  (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2673  "symbolic_operand (operands[2], Pmode)
2674   && ! function_label_operand (operands[2], Pmode)
2675   && flag_pic"
2676  "ldo RT'%G2(%1),%0"
2677  [(set_attr "type" "binary")
2678   (set_attr "length" "4")])
2679
2680(define_insn ""
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2683		  (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2684  "symbolic_operand (operands[2], Pmode)
2685   && ! function_label_operand (operands[2], Pmode)
2686   && TARGET_64BIT
2687   && flag_pic"
2688  "ldo RT'%G2(%1),%0"
2689  [(set_attr "type" "binary")
2690   (set_attr "length" "4")])
2691
2692;; Always use addil rather than ldil;add sequences.  This allows the
2693;; HP linker to eliminate the dp relocation if the symbolic operand
2694;; lives in the TEXT space.
2695(define_insn ""
2696  [(set (match_operand:SI 0 "register_operand" "=a")
2697	(high:SI (match_operand 1 "" "")))]
2698  "symbolic_operand (operands[1], Pmode)
2699   && ! function_label_operand (operands[1], Pmode)
2700   && ! read_only_operand (operands[1], Pmode)
2701   && ! flag_pic"
2702  "*
2703{
2704  if (TARGET_LONG_LOAD_STORE)
2705    return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2706  else
2707    return \"addil LR'%H1,%%r27\";
2708}"
2709  [(set_attr "type" "binary")
2710   (set (attr "length")
2711      (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2712		    (const_int 4)
2713		    (const_int 8)))])
2714
2715
2716;; This is for use in the prologue/epilogue code.  We need it
2717;; to add large constants to a stack pointer or frame pointer.
2718;; Because of the additional %r1 pressure, we probably do not
2719;; want to use this in general code, so make it available
2720;; only after reload.
2721(define_insn ""
2722  [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2723	(plus:SI (match_operand:SI 1 "register_operand" "r,r")
2724		 (high:SI (match_operand 2 "const_int_operand" ""))))]
2725  "reload_completed"
2726  "@
2727   addil L'%G2,%1
2728   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2729  [(set_attr "type" "binary,binary")
2730   (set_attr "length" "4,8")])
2731
2732(define_insn ""
2733  [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2734	(plus:DI (match_operand:DI 1 "register_operand" "r,r")
2735		 (high:DI (match_operand 2 "const_int_operand" ""))))]
2736  "reload_completed && TARGET_64BIT"
2737  "@
2738   addil L'%G2,%1
2739   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2740  [(set_attr "type" "binary,binary")
2741   (set_attr "length" "4,8")])
2742
2743(define_insn ""
2744  [(set (match_operand:SI 0 "register_operand" "=r")
2745	(high:SI (match_operand 1 "" "")))]
2746  "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2747    && !pa_is_function_label_plus_const (operands[1])"
2748  "*
2749{
2750  if (symbolic_operand (operands[1], Pmode))
2751    return \"ldil LR'%H1,%0\";
2752  else
2753    return \"ldil L'%G1,%0\";
2754}"
2755  [(set_attr "type" "move")
2756   (set_attr "length" "4")])
2757
2758(define_insn ""
2759  [(set (match_operand:DI 0 "register_operand" "=r")
2760	(high:DI (match_operand 1 "const_int_operand" "")))]
2761  "TARGET_64BIT"
2762  "ldil L'%G1,%0";
2763  [(set_attr "type" "move")
2764   (set_attr "length" "4")])
2765
2766(define_insn ""
2767  [(set (match_operand:DI 0 "register_operand" "=r")
2768	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2769		   (match_operand:DI 2 "const_int_operand" "i")))]
2770  "TARGET_64BIT"
2771  "ldo R'%G2(%1),%0";
2772  [(set_attr "type" "move")
2773   (set_attr "length" "4")])
2774
2775(define_insn ""
2776  [(set (match_operand:SI 0 "register_operand" "=r")
2777	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2778		   (match_operand:SI 2 "immediate_operand" "i")))]
2779  "!pa_is_function_label_plus_const (operands[2])"
2780  "*
2781{
2782  gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2783
2784  if (symbolic_operand (operands[2], Pmode))
2785    return \"ldo RR'%G2(%1),%0\";
2786  else
2787    return \"ldo R'%G2(%1),%0\";
2788}"
2789  [(set_attr "type" "move")
2790   (set_attr "length" "4")])
2791
2792;; Now that a symbolic_address plus a constant is broken up early
2793;; in the compilation phase (for better CSE) we need a special
2794;; combiner pattern to load the symbolic address plus the constant
2795;; in only 2 instructions. (For cases where the symbolic address
2796;; was not a common subexpression.)
2797(define_split
2798  [(set (match_operand:SI 0 "register_operand" "")
2799	(match_operand:SI 1 "symbolic_operand" ""))
2800   (clobber (match_operand:SI 2 "register_operand" ""))]
2801  "! (flag_pic && pic_label_operand (operands[1], SImode))"
2802  [(set (match_dup 2) (high:SI (match_dup 1)))
2803   (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2804  "")
2805
2806;; hppa_legitimize_address goes to a great deal of trouble to
2807;; create addresses which use indexing.  In some cases, this
2808;; is a lose because there isn't any store instructions which
2809;; allow indexed addresses (with integer register source).
2810;;
2811;; These define_splits try to turn a 3 insn store into
2812;; a 2 insn store with some creative RTL rewriting.
2813(define_split
2814  [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2815			       (match_operand:SI 1 "mem_shadd_operand" ""))
2816		   (plus:SI (match_operand:SI 2 "register_operand" "")
2817			    (match_operand:SI 3 "const_int_operand" ""))))
2818	(match_operand:SI 4 "register_operand" ""))
2819   (clobber (match_operand:SI 5 "register_operand" ""))]
2820  ""
2821  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2822			       (match_dup 2)))
2823   (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2824  "
2825{
2826  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2827
2828}")
2829
2830(define_split
2831  [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2832			       (match_operand:SI 1 "mem_shadd_operand" ""))
2833		   (plus:SI (match_operand:SI 2 "register_operand" "")
2834			    (match_operand:SI 3 "const_int_operand" ""))))
2835	(match_operand:HI 4 "register_operand" ""))
2836   (clobber (match_operand:SI 5 "register_operand" ""))]
2837  ""
2838  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2839			       (match_dup 2)))
2840   (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2841  "
2842{
2843  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2844
2845}")
2846
2847(define_split
2848  [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2849			       (match_operand:SI 1 "mem_shadd_operand" ""))
2850		   (plus:SI (match_operand:SI 2 "register_operand" "")
2851			    (match_operand:SI 3 "const_int_operand" ""))))
2852	(match_operand:QI 4 "register_operand" ""))
2853   (clobber (match_operand:SI 5 "register_operand" ""))]
2854  ""
2855  [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2856			       (match_dup 2)))
2857   (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2858  "
2859{
2860  operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2861
2862}")
2863
2864(define_expand "movhi"
2865  [(set (match_operand:HI 0 "general_operand" "")
2866	(match_operand:HI 1 "general_operand" ""))]
2867  ""
2868  "
2869{
2870  if (pa_emit_move_sequence (operands, HImode, 0))
2871    DONE;
2872}")
2873
2874;; Handle HImode input reloads requiring a general register as a
2875;; scratch register.
2876(define_expand "reload_inhi"
2877  [(set (match_operand:HI 0 "register_operand" "=Z")
2878	(match_operand:HI 1 "non_hard_reg_operand" ""))
2879   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2880  ""
2881  "
2882{
2883  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2884    DONE;
2885
2886  /* We don't want the clobber emitted, so handle this ourselves.  */
2887  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2888  DONE;
2889}")
2890
2891;; Handle HImode output reloads requiring a general register as a
2892;; scratch register.
2893(define_expand "reload_outhi"
2894  [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2895	(match_operand:HI 1  "register_operand" "Z"))
2896   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2897  ""
2898  "
2899{
2900  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2901    DONE;
2902
2903  /* We don't want the clobber emitted, so handle this ourselves.  */
2904  emit_insn (gen_rtx_SET (operands[0], operands[1]));
2905  DONE;
2906}")
2907
2908(define_insn ""
2909  [(set (match_operand:HI 0 "move_dest_operand"
2910	 		  "=r,r,r,r,r,Q,!*q,!r")
2911	(match_operand:HI 1 "move_src_operand"
2912			  "r,J,N,K,RQ,rM,!rM,!*q"))]
2913  "(register_operand (operands[0], HImode)
2914    || reg_or_0_operand (operands[1], HImode))"
2915  "@
2916   copy %1,%0
2917   ldi %1,%0
2918   ldil L'%1,%0
2919   {zdepi|depwi,z} %Z1,%0
2920   ldh%M1 %1,%0
2921   sth%M0 %r1,%0
2922   mtsar %r1
2923   {mfctl|mfctl,w} %sar,%0"
2924  [(set_attr "type" "move,move,move,shift,load,store,move,move")
2925   (set_attr "pa_combine_type" "addmove")
2926   (set_attr "length" "4,4,4,4,4,4,4,4")])
2927
2928(define_insn ""
2929  [(set (match_operand:HI 0 "register_operand" "=r")
2930	(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2931			 (match_operand:SI 2 "int5_operand" "L"))))
2932   (set (match_dup 1)
2933	(plus:SI (match_dup 1) (match_dup 2)))]
2934  ""
2935  "{ldhs|ldh},mb %2(%1),%0"
2936  [(set_attr "type" "load")
2937   (set_attr "length" "4")])
2938
2939(define_insn ""
2940  [(set (match_operand:HI 0 "register_operand" "=r")
2941	(mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2942			 (match_operand:DI 2 "int5_operand" "L"))))
2943   (set (match_dup 1)
2944	(plus:DI (match_dup 1) (match_dup 2)))]
2945  "TARGET_64BIT"
2946  "ldh,mb %2(%1),%0"
2947  [(set_attr "type" "load")
2948   (set_attr "length" "4")])
2949
2950; And a zero extended variant.
2951(define_insn ""
2952  [(set (match_operand:DI 0 "register_operand" "=r")
2953	(zero_extend:DI (mem:HI
2954			  (plus:DI
2955			    (match_operand:DI 1 "register_operand" "+r")
2956			    (match_operand:DI 2 "int5_operand" "L")))))
2957   (set (match_dup 1)
2958	(plus:DI (match_dup 1) (match_dup 2)))]
2959  "TARGET_64BIT"
2960  "ldh,mb %2(%1),%0"
2961  [(set_attr "type" "load")
2962   (set_attr "length" "4")])
2963
2964(define_insn ""
2965  [(set (match_operand:SI 0 "register_operand" "=r")
2966	(zero_extend:SI (mem:HI
2967			  (plus:SI
2968			    (match_operand:SI 1 "register_operand" "+r")
2969			    (match_operand:SI 2 "int5_operand" "L")))))
2970   (set (match_dup 1)
2971	(plus:SI (match_dup 1) (match_dup 2)))]
2972  ""
2973  "{ldhs|ldh},mb %2(%1),%0"
2974  [(set_attr "type" "load")
2975   (set_attr "length" "4")])
2976
2977(define_insn ""
2978  [(set (match_operand:SI 0 "register_operand" "=r")
2979	(zero_extend:SI (mem:HI
2980			  (plus:DI
2981			    (match_operand:DI 1 "register_operand" "+r")
2982			    (match_operand:DI 2 "int5_operand" "L")))))
2983   (set (match_dup 1)
2984	(plus:DI (match_dup 1) (match_dup 2)))]
2985  "TARGET_64BIT"
2986  "ldh,mb %2(%1),%0"
2987  [(set_attr "type" "load")
2988   (set_attr "length" "4")])
2989
2990(define_insn ""
2991  [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2992			 (match_operand:SI 1 "int5_operand" "L")))
2993	(match_operand:HI 2 "reg_or_0_operand" "rM"))
2994   (set (match_dup 0)
2995	(plus:SI (match_dup 0) (match_dup 1)))]
2996  ""
2997  "{sths|sth},mb %r2,%1(%0)"
2998  [(set_attr "type" "store")
2999   (set_attr "length" "4")])
3000
3001(define_insn ""
3002  [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3003			 (match_operand:DI 1 "int5_operand" "L")))
3004	(match_operand:HI 2 "reg_or_0_operand" "rM"))
3005   (set (match_dup 0)
3006	(plus:DI (match_dup 0) (match_dup 1)))]
3007  "TARGET_64BIT"
3008  "sth,mb %r2,%1(%0)"
3009  [(set_attr "type" "store")
3010   (set_attr "length" "4")])
3011
3012(define_insn "addhi3"
3013  [(set (match_operand:HI 0 "register_operand" "=r,r")
3014	(plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3015		 (match_operand:HI 2 "arith14_operand" "r,J")))]
3016  ""
3017  "@
3018   {addl|add,l} %1,%2,%0
3019   ldo %2(%1),%0"
3020  [(set_attr "type" "binary,binary")
3021   (set_attr "pa_combine_type" "addmove")
3022   (set_attr "length" "4,4")])
3023
3024(define_expand "movqi"
3025  [(set (match_operand:QI 0 "general_operand" "")
3026	(match_operand:QI 1 "general_operand" ""))]
3027  ""
3028  "
3029{
3030  if (pa_emit_move_sequence (operands, QImode, 0))
3031    DONE;
3032}")
3033
3034;; Handle QImode input reloads requiring a general register as a
3035;; scratch register.
3036(define_expand "reload_inqi"
3037  [(set (match_operand:QI 0 "register_operand" "=Z")
3038	(match_operand:QI 1 "non_hard_reg_operand" ""))
3039   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3040  ""
3041  "
3042{
3043  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3044    DONE;
3045
3046  /* We don't want the clobber emitted, so handle this ourselves.  */
3047  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3048  DONE;
3049}")
3050
3051;; Handle QImode output reloads requiring a general register as a
3052;; scratch register.
3053(define_expand "reload_outqi"
3054  [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3055	(match_operand:QI 1  "register_operand" "Z"))
3056   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3057  ""
3058  "
3059{
3060  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3061    DONE;
3062
3063  /* We don't want the clobber emitted, so handle this ourselves.  */
3064  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3065  DONE;
3066}")
3067
3068(define_insn ""
3069  [(set (match_operand:QI 0 "move_dest_operand"
3070			  "=r,r,r,r,r,Q,!*q,!r")
3071	(match_operand:QI 1 "move_src_operand"
3072			  "r,J,N,K,RQ,rM,!rM,!*q"))]
3073  "(register_operand (operands[0], QImode)
3074    || reg_or_0_operand (operands[1], QImode))"
3075  "@
3076   copy %1,%0
3077   ldi %1,%0
3078   ldil L'%1,%0
3079   {zdepi|depwi,z} %Z1,%0
3080   ldb%M1 %1,%0
3081   stb%M0 %r1,%0
3082   mtsar %r1
3083   {mfctl|mfctl,w} %%sar,%0"
3084  [(set_attr "type" "move,move,move,shift,load,store,move,move")
3085   (set_attr "pa_combine_type" "addmove")
3086   (set_attr "length" "4,4,4,4,4,4,4,4")])
3087
3088(define_insn ""
3089  [(set (match_operand:QI 0 "register_operand" "=r")
3090	(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3091			 (match_operand:SI 2 "int5_operand" "L"))))
3092   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3093  ""
3094  "{ldbs|ldb},mb %2(%1),%0"
3095  [(set_attr "type" "load")
3096   (set_attr "length" "4")])
3097
3098(define_insn ""
3099  [(set (match_operand:QI 0 "register_operand" "=r")
3100	(mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3101			 (match_operand:DI 2 "int5_operand" "L"))))
3102   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3103  "TARGET_64BIT"
3104  "ldb,mb %2(%1),%0"
3105  [(set_attr "type" "load")
3106   (set_attr "length" "4")])
3107
3108; Now the same thing with zero extensions.
3109(define_insn ""
3110  [(set (match_operand:DI 0 "register_operand" "=r")
3111	(zero_extend:DI (mem:QI (plus:DI
3112				  (match_operand:DI 1 "register_operand" "+r")
3113				  (match_operand:DI 2 "int5_operand" "L")))))
3114   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3115  "TARGET_64BIT"
3116  "ldb,mb %2(%1),%0"
3117  [(set_attr "type" "load")
3118   (set_attr "length" "4")])
3119
3120(define_insn ""
3121  [(set (match_operand:SI 0 "register_operand" "=r")
3122	(zero_extend:SI (mem:QI (plus:SI
3123				  (match_operand:SI 1 "register_operand" "+r")
3124				  (match_operand:SI 2 "int5_operand" "L")))))
3125   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3126  ""
3127  "{ldbs|ldb},mb %2(%1),%0"
3128  [(set_attr "type" "load")
3129   (set_attr "length" "4")])
3130
3131(define_insn ""
3132  [(set (match_operand:SI 0 "register_operand" "=r")
3133	(zero_extend:SI (mem:QI (plus:DI
3134				  (match_operand:DI 1 "register_operand" "+r")
3135				  (match_operand:DI 2 "int5_operand" "L")))))
3136   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3137  "TARGET_64BIT"
3138  "ldb,mb %2(%1),%0"
3139  [(set_attr "type" "load")
3140   (set_attr "length" "4")])
3141
3142(define_insn ""
3143  [(set (match_operand:HI 0 "register_operand" "=r")
3144	(zero_extend:HI (mem:QI (plus:SI
3145				  (match_operand:SI 1 "register_operand" "+r")
3146				  (match_operand:SI 2 "int5_operand" "L")))))
3147   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3148  ""
3149  "{ldbs|ldb},mb %2(%1),%0"
3150  [(set_attr "type" "load")
3151   (set_attr "length" "4")])
3152
3153(define_insn ""
3154  [(set (match_operand:HI 0 "register_operand" "=r")
3155	(zero_extend:HI (mem:QI (plus:DI
3156				  (match_operand:DI 1 "register_operand" "+r")
3157				  (match_operand:DI 2 "int5_operand" "L")))))
3158   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3159  "TARGET_64BIT"
3160  "ldb,mb %2(%1),%0"
3161  [(set_attr "type" "load")
3162   (set_attr "length" "4")])
3163
3164(define_insn ""
3165  [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3166			 (match_operand:SI 1 "int5_operand" "L")))
3167	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3168   (set (match_dup 0)
3169	(plus:SI (match_dup 0) (match_dup 1)))]
3170  ""
3171  "{stbs|stb},mb %r2,%1(%0)"
3172  [(set_attr "type" "store")
3173   (set_attr "length" "4")])
3174
3175(define_insn ""
3176  [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3177			 (match_operand:DI 1 "int5_operand" "L")))
3178	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3179   (set (match_dup 0)
3180	(plus:DI (match_dup 0) (match_dup 1)))]
3181  "TARGET_64BIT"
3182  "stb,mb %r2,%1(%0)"
3183  [(set_attr "type" "store")
3184   (set_attr "length" "4")])
3185
3186;; The definition of this insn does not really explain what it does,
3187;; but it should suffice that anything generated as this insn will be
3188;; recognized as a cpymemsi operation, and that it will not successfully
3189;; combine with anything.
3190(define_expand "cpymemsi"
3191  [(parallel [(set (match_operand:BLK 0 "" "")
3192		   (match_operand:BLK 1 "" ""))
3193	      (clobber (match_dup 4))
3194	      (clobber (match_dup 5))
3195	      (clobber (match_dup 6))
3196	      (clobber (match_dup 7))
3197	      (clobber (match_dup 8))
3198	      (use (match_operand:SI 2 "arith14_operand" ""))
3199	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3200  "!TARGET_64BIT && optimize > 0"
3201  "
3202{
3203  int size, align;
3204
3205  /* HP provides very fast block move library routine for the PA;
3206     this routine includes:
3207
3208	4x4 byte at a time block moves,
3209	1x4 byte at a time with alignment checked at runtime with
3210	    attempts to align the source and destination as needed
3211	1x1 byte loop
3212
3213     With that in mind, here's the heuristics to try and guess when
3214     the inlined block move will be better than the library block
3215     move:
3216
3217	If the size isn't constant, then always use the library routines.
3218
3219	If the size is large in respect to the known alignment, then use
3220	the library routines.
3221
3222	If the size is small in respect to the known alignment, then open
3223	code the copy (since that will lead to better scheduling).
3224
3225        Else use the block move pattern.   */
3226
3227  /* Undetermined size, use the library routine.  */
3228  if (GET_CODE (operands[2]) != CONST_INT)
3229    FAIL;
3230
3231  size = INTVAL (operands[2]);
3232  align = INTVAL (operands[3]);
3233  align = align > 4 ? 4 : (align ? align : 1);
3234
3235  /* If size/alignment is large, then use the library routines.  */
3236  if (size / align > 16)
3237    FAIL;
3238
3239  /* This does happen, but not often enough to worry much about.  */
3240  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3241    FAIL;
3242
3243  /* Fall through means we're going to use our block move pattern.  */
3244  operands[0]
3245    = replace_equiv_address (operands[0],
3246			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3247  operands[1]
3248    = replace_equiv_address (operands[1],
3249			     copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3250  operands[4] = gen_reg_rtx (SImode);
3251  operands[5] = gen_reg_rtx (SImode);
3252  operands[6] = gen_reg_rtx (SImode);
3253  operands[7] = gen_reg_rtx (SImode);
3254  operands[8] = gen_reg_rtx (SImode);
3255}")
3256
3257;; The operand constraints are written like this to support both compile-time
3258;; and run-time determined byte counts.  The expander and pa_output_block_move
3259;; only support compile-time determined counts at this time.
3260;;
3261;; If the count is run-time determined, the register with the byte count
3262;; is clobbered by the copying code, and therefore it is forced to operand 2.
3263;;
3264;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3265;; broke this semantic for pseudo registers.  We can't use match_scratch
3266;; as this requires two registers in the class R1_REGS when the MEMs for
3267;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3268;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3269;; respectively.  We then split or peephole optimize after reload.
3270(define_insn "cpymemsi_prereload"
3271  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3272	(mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3273   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3274   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3275   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3276   (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))	;item tmp3
3277   (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))	;item tmp4
3278   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3279   (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3280  "!TARGET_64BIT"
3281  "#"
3282  [(set_attr "type" "multi,multi")])
3283
3284(define_split
3285  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3286		   (match_operand:BLK 1 "memory_operand" ""))
3287	      (clobber (match_operand:SI 2 "register_operand" ""))
3288	      (clobber (match_operand:SI 3 "register_operand" ""))
3289	      (clobber (match_operand:SI 6 "register_operand" ""))
3290	      (clobber (match_operand:SI 7 "register_operand" ""))
3291	      (clobber (match_operand:SI 8 "register_operand" ""))
3292	      (use (match_operand:SI 4 "arith14_operand" ""))
3293	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3294  "!TARGET_64BIT && reload_completed && !flag_peephole2
3295   && GET_CODE (operands[0]) == MEM
3296   && register_operand (XEXP (operands[0], 0), SImode)
3297   && GET_CODE (operands[1]) == MEM
3298   && register_operand (XEXP (operands[1], 0), SImode)"
3299  [(set (match_dup 7) (match_dup 9))
3300   (set (match_dup 8) (match_dup 10))
3301   (parallel [(set (match_dup 0) (match_dup 1))
3302   	      (clobber (match_dup 2))
3303   	      (clobber (match_dup 3))
3304   	      (clobber (match_dup 6))
3305   	      (clobber (match_dup 7))
3306   	      (clobber (match_dup 8))
3307   	      (use (match_dup 4))
3308   	      (use (match_dup 5))
3309	      (const_int 0)])]
3310  "
3311{
3312  operands[9] = XEXP (operands[0], 0);
3313  operands[10] = XEXP (operands[1], 0);
3314  operands[0] = replace_equiv_address (operands[0], operands[7]);
3315  operands[1] = replace_equiv_address (operands[1], operands[8]);
3316}")
3317
3318(define_peephole2
3319  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3320		   (match_operand:BLK 1 "memory_operand" ""))
3321	      (clobber (match_operand:SI 2 "register_operand" ""))
3322	      (clobber (match_operand:SI 3 "register_operand" ""))
3323	      (clobber (match_operand:SI 6 "register_operand" ""))
3324	      (clobber (match_operand:SI 7 "register_operand" ""))
3325	      (clobber (match_operand:SI 8 "register_operand" ""))
3326	      (use (match_operand:SI 4 "arith14_operand" ""))
3327	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3328  "!TARGET_64BIT
3329   && GET_CODE (operands[0]) == MEM
3330   && register_operand (XEXP (operands[0], 0), SImode)
3331   && GET_CODE (operands[1]) == MEM
3332   && register_operand (XEXP (operands[1], 0), SImode)"
3333  [(parallel [(set (match_dup 0) (match_dup 1))
3334   	      (clobber (match_dup 2))
3335   	      (clobber (match_dup 3))
3336   	      (clobber (match_dup 6))
3337   	      (clobber (match_dup 7))
3338   	      (clobber (match_dup 8))
3339   	      (use (match_dup 4))
3340   	      (use (match_dup 5))
3341	      (const_int 0)])]
3342  "
3343{
3344  rtx addr = XEXP (operands[0], 0);
3345  if (dead_or_set_p (curr_insn, addr))
3346    operands[7] = addr;
3347  else
3348    {
3349      emit_insn (gen_rtx_SET (operands[7], addr));
3350      operands[0] = replace_equiv_address (operands[0], operands[7]);
3351    }
3352
3353  addr = XEXP (operands[1], 0);
3354  if (dead_or_set_p (curr_insn, addr))
3355    operands[8] = addr;
3356  else
3357    {
3358      emit_insn (gen_rtx_SET (operands[8], addr));
3359      operands[1] = replace_equiv_address (operands[1], operands[8]);
3360    }
3361}")
3362
3363(define_insn "cpymemsi_postreload"
3364  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3365	(mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3366   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3367   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3368   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3369   (clobber (match_dup 0))
3370   (clobber (match_dup 1))
3371   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3372   (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3373   (const_int 0)]
3374  "!TARGET_64BIT && reload_completed"
3375  "* return pa_output_block_move (operands, !which_alternative);"
3376  [(set_attr "type" "multi,multi")])
3377
3378(define_expand "cpymemdi"
3379  [(parallel [(set (match_operand:BLK 0 "" "")
3380		   (match_operand:BLK 1 "" ""))
3381	      (clobber (match_dup 4))
3382	      (clobber (match_dup 5))
3383	      (clobber (match_dup 6))
3384	      (clobber (match_dup 7))
3385	      (clobber (match_dup 8))
3386	      (use (match_operand:DI 2 "arith14_operand" ""))
3387	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3388  "TARGET_64BIT && optimize > 0"
3389  "
3390{
3391  int size, align;
3392
3393  /* HP provides very fast block move library routine for the PA;
3394     this routine includes:
3395
3396	4x4 byte at a time block moves,
3397	1x4 byte at a time with alignment checked at runtime with
3398	    attempts to align the source and destination as needed
3399	1x1 byte loop
3400
3401     With that in mind, here's the heuristics to try and guess when
3402     the inlined block move will be better than the library block
3403     move:
3404
3405	If the size isn't constant, then always use the library routines.
3406
3407	If the size is large in respect to the known alignment, then use
3408	the library routines.
3409
3410	If the size is small in respect to the known alignment, then open
3411	code the copy (since that will lead to better scheduling).
3412
3413        Else use the block move pattern.   */
3414
3415  /* Undetermined size, use the library routine.  */
3416  if (GET_CODE (operands[2]) != CONST_INT)
3417    FAIL;
3418
3419  size = INTVAL (operands[2]);
3420  align = INTVAL (operands[3]);
3421  align = align > 8 ? 8 : (align ? align : 1);
3422
3423  /* If size/alignment is large, then use the library routines.  */
3424  if (size / align > 16)
3425    FAIL;
3426
3427  /* This does happen, but not often enough to worry much about.  */
3428  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3429    FAIL;
3430
3431  /* Fall through means we're going to use our block move pattern.  */
3432  operands[0]
3433    = replace_equiv_address (operands[0],
3434			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3435  operands[1]
3436    = replace_equiv_address (operands[1],
3437			     copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3438  operands[4] = gen_reg_rtx (DImode);
3439  operands[5] = gen_reg_rtx (DImode);
3440  operands[6] = gen_reg_rtx (DImode);
3441  operands[7] = gen_reg_rtx (DImode);
3442  operands[8] = gen_reg_rtx (DImode);
3443}")
3444
3445;; The operand constraints are written like this to support both compile-time
3446;; and run-time determined byte counts.  The expander and pa_output_block_move
3447;; only support compile-time determined counts at this time.
3448;;
3449;; If the count is run-time determined, the register with the byte count
3450;; is clobbered by the copying code, and therefore it is forced to operand 2.
3451;;
3452;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3453;; broke this semantic for pseudo registers.  We can't use match_scratch
3454;; as this requires two registers in the class R1_REGS when the MEMs for
3455;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3456;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3457;; respectively.  We then split or peephole optimize after reload.
3458(define_insn "cpymemdi_prereload"
3459  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3460	(mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3461   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3462   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3463   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3464   (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))	;item tmp3
3465   (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))	;item tmp4
3466   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3467   (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3468  "TARGET_64BIT"
3469  "#"
3470  [(set_attr "type" "multi,multi")])
3471
3472(define_split
3473  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3474		   (match_operand:BLK 1 "memory_operand" ""))
3475	      (clobber (match_operand:DI 2 "register_operand" ""))
3476	      (clobber (match_operand:DI 3 "register_operand" ""))
3477	      (clobber (match_operand:DI 6 "register_operand" ""))
3478	      (clobber (match_operand:DI 7 "register_operand" ""))
3479	      (clobber (match_operand:DI 8 "register_operand" ""))
3480	      (use (match_operand:DI 4 "arith14_operand" ""))
3481	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3482  "TARGET_64BIT && reload_completed && !flag_peephole2
3483   && GET_CODE (operands[0]) == MEM
3484   && register_operand (XEXP (operands[0], 0), DImode)
3485   && GET_CODE (operands[1]) == MEM
3486   && register_operand (XEXP (operands[1], 0), DImode)"
3487  [(set (match_dup 7) (match_dup 9))
3488   (set (match_dup 8) (match_dup 10))
3489   (parallel [(set (match_dup 0) (match_dup 1))
3490   	      (clobber (match_dup 2))
3491   	      (clobber (match_dup 3))
3492   	      (clobber (match_dup 6))
3493   	      (clobber (match_dup 7))
3494   	      (clobber (match_dup 8))
3495   	      (use (match_dup 4))
3496   	      (use (match_dup 5))
3497	      (const_int 0)])]
3498  "
3499{
3500  operands[9] = XEXP (operands[0], 0);
3501  operands[10] = XEXP (operands[1], 0);
3502  operands[0] = replace_equiv_address (operands[0], operands[7]);
3503  operands[1] = replace_equiv_address (operands[1], operands[8]);
3504}")
3505
3506(define_peephole2
3507  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3508		   (match_operand:BLK 1 "memory_operand" ""))
3509	      (clobber (match_operand:DI 2 "register_operand" ""))
3510	      (clobber (match_operand:DI 3 "register_operand" ""))
3511	      (clobber (match_operand:DI 6 "register_operand" ""))
3512	      (clobber (match_operand:DI 7 "register_operand" ""))
3513	      (clobber (match_operand:DI 8 "register_operand" ""))
3514	      (use (match_operand:DI 4 "arith14_operand" ""))
3515	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3516  "TARGET_64BIT
3517   && GET_CODE (operands[0]) == MEM
3518   && register_operand (XEXP (operands[0], 0), DImode)
3519   && GET_CODE (operands[1]) == MEM
3520   && register_operand (XEXP (operands[1], 0), DImode)"
3521  [(parallel [(set (match_dup 0) (match_dup 1))
3522   	      (clobber (match_dup 2))
3523   	      (clobber (match_dup 3))
3524   	      (clobber (match_dup 6))
3525   	      (clobber (match_dup 7))
3526   	      (clobber (match_dup 8))
3527   	      (use (match_dup 4))
3528   	      (use (match_dup 5))
3529	      (const_int 0)])]
3530  "
3531{
3532  rtx addr = XEXP (operands[0], 0);
3533  if (dead_or_set_p (curr_insn, addr))
3534    operands[7] = addr;
3535  else
3536    {
3537      emit_insn (gen_rtx_SET (operands[7], addr));
3538      operands[0] = replace_equiv_address (operands[0], operands[7]);
3539    }
3540
3541  addr = XEXP (operands[1], 0);
3542  if (dead_or_set_p (curr_insn, addr))
3543    operands[8] = addr;
3544  else
3545    {
3546      emit_insn (gen_rtx_SET (operands[8], addr));
3547      operands[1] = replace_equiv_address (operands[1], operands[8]);
3548    }
3549}")
3550
3551(define_insn "cpymemdi_postreload"
3552  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3553	(mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3554   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3555   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3556   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3557   (clobber (match_dup 0))
3558   (clobber (match_dup 1))
3559   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3560   (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3561   (const_int 0)]
3562  "TARGET_64BIT && reload_completed"
3563  "* return pa_output_block_move (operands, !which_alternative);"
3564  [(set_attr "type" "multi,multi")])
3565
3566(define_expand "setmemsi"
3567  [(parallel [(set (match_operand:BLK 0 "" "")
3568		   (match_operand 2 "const_int_operand" ""))
3569	      (clobber (match_dup 4))
3570	      (clobber (match_dup 5))
3571	      (use (match_operand:SI 1 "arith14_operand" ""))
3572	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3573  "!TARGET_64BIT && optimize > 0"
3574  "
3575{
3576  int size, align;
3577
3578  /* If value to set is not zero, use the library routine.  */
3579  if (operands[2] != const0_rtx)
3580    FAIL;
3581
3582  /* Undetermined size, use the library routine.  */
3583  if (GET_CODE (operands[1]) != CONST_INT)
3584    FAIL;
3585
3586  size = INTVAL (operands[1]);
3587  align = INTVAL (operands[3]);
3588  align = align > 4 ? 4 : align;
3589
3590  /* If size/alignment is large, then use the library routines.  */
3591  if (size / align > 16)
3592    FAIL;
3593
3594  /* This does happen, but not often enough to worry much about.  */
3595  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3596    FAIL;
3597
3598  /* Fall through means we're going to use our block clear pattern.  */
3599  operands[0]
3600    = replace_equiv_address (operands[0],
3601			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3602  operands[4] = gen_reg_rtx (SImode);
3603  operands[5] = gen_reg_rtx (SImode);
3604}")
3605
3606(define_insn "clrmemsi_prereload"
3607  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3608	(const_int 0))
3609   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3610   (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))	;tmp1
3611   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3612   (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3613  "!TARGET_64BIT"
3614  "#"
3615  [(set_attr "type" "multi,multi")])
3616
3617(define_split
3618  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3619		   (const_int 0))
3620	      (clobber (match_operand:SI 1 "register_operand" ""))
3621	      (clobber (match_operand:SI 4 "register_operand" ""))
3622	      (use (match_operand:SI 2 "arith14_operand" ""))
3623	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3624  "!TARGET_64BIT && reload_completed && !flag_peephole2
3625   && GET_CODE (operands[0]) == MEM
3626   && register_operand (XEXP (operands[0], 0), SImode)"
3627  [(set (match_dup 4) (match_dup 5))
3628   (parallel [(set (match_dup 0) (const_int 0))
3629   	      (clobber (match_dup 1))
3630   	      (clobber (match_dup 4))
3631   	      (use (match_dup 2))
3632   	      (use (match_dup 3))
3633	      (const_int 0)])]
3634  "
3635{
3636  operands[5] = XEXP (operands[0], 0);
3637  operands[0] = replace_equiv_address (operands[0], operands[4]);
3638}")
3639
3640(define_peephole2
3641  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3642		   (const_int 0))
3643	      (clobber (match_operand:SI 1 "register_operand" ""))
3644	      (clobber (match_operand:SI 4 "register_operand" ""))
3645	      (use (match_operand:SI 2 "arith14_operand" ""))
3646	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3647  "!TARGET_64BIT
3648   && GET_CODE (operands[0]) == MEM
3649   && register_operand (XEXP (operands[0], 0), SImode)"
3650  [(parallel [(set (match_dup 0) (const_int 0))
3651   	      (clobber (match_dup 1))
3652   	      (clobber (match_dup 4))
3653   	      (use (match_dup 2))
3654   	      (use (match_dup 3))
3655	      (const_int 0)])]
3656  "
3657{
3658  rtx addr = XEXP (operands[0], 0);
3659  if (dead_or_set_p (curr_insn, addr))
3660    operands[4] = addr;
3661  else
3662    {
3663      emit_insn (gen_rtx_SET (operands[4], addr));
3664      operands[0] = replace_equiv_address (operands[0], operands[4]);
3665    }
3666}")
3667
3668(define_insn "clrmemsi_postreload"
3669  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3670	(const_int 0))
3671   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3672   (clobber (match_dup 0))
3673   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3674   (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3675   (const_int 0)]
3676  "!TARGET_64BIT && reload_completed"
3677  "* return pa_output_block_clear (operands, !which_alternative);"
3678  [(set_attr "type" "multi,multi")])
3679
3680(define_expand "setmemdi"
3681  [(parallel [(set (match_operand:BLK 0 "" "")
3682		   (match_operand 2 "const_int_operand" ""))
3683	      (clobber (match_dup 4))
3684	      (clobber (match_dup 5))
3685	      (use (match_operand:DI 1 "arith14_operand" ""))
3686	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3687  "TARGET_64BIT && optimize > 0"
3688  "
3689{
3690  int size, align;
3691
3692  /* If value to set is not zero, use the library routine.  */
3693  if (operands[2] != const0_rtx)
3694    FAIL;
3695
3696  /* Undetermined size, use the library routine.  */
3697  if (GET_CODE (operands[1]) != CONST_INT)
3698    FAIL;
3699
3700  size = INTVAL (operands[1]);
3701  align = INTVAL (operands[3]);
3702  align = align > 8 ? 8 : align;
3703
3704  /* If size/alignment is large, then use the library routines.  */
3705  if (size / align > 16)
3706    FAIL;
3707
3708  /* This does happen, but not often enough to worry much about.  */
3709  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3710    FAIL;
3711
3712  /* Fall through means we're going to use our block clear pattern.  */
3713  operands[0]
3714    = replace_equiv_address (operands[0],
3715			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3716  operands[4] = gen_reg_rtx (DImode);
3717  operands[5] = gen_reg_rtx (DImode);
3718}")
3719
3720(define_insn "clrmemdi_prereload"
3721  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3722	(const_int 0))
3723   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3724   (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))	;item tmp1
3725   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3726   (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3727  "TARGET_64BIT"
3728  "#"
3729  [(set_attr "type" "multi,multi")])
3730
3731(define_split
3732  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3733		   (const_int 0))
3734	      (clobber (match_operand:DI 1 "register_operand" ""))
3735	      (clobber (match_operand:DI 4 "register_operand" ""))
3736	      (use (match_operand:DI 2 "arith14_operand" ""))
3737	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3738  "TARGET_64BIT && reload_completed && !flag_peephole2
3739   && GET_CODE (operands[0]) == MEM
3740   && register_operand (XEXP (operands[0], 0), DImode)"
3741  [(set (match_dup 4) (match_dup 5))
3742   (parallel [(set (match_dup 0) (const_int 0))
3743   	      (clobber (match_dup 1))
3744   	      (clobber (match_dup 4))
3745   	      (use (match_dup 2))
3746   	      (use (match_dup 3))
3747	      (const_int 0)])]
3748  "
3749{
3750  operands[5] = XEXP (operands[0], 0);
3751  operands[0] = replace_equiv_address (operands[0], operands[4]);
3752}")
3753
3754(define_peephole2
3755  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3756		   (const_int 0))
3757	      (clobber (match_operand:DI 1 "register_operand" ""))
3758	      (clobber (match_operand:DI 4 "register_operand" ""))
3759	      (use (match_operand:DI 2 "arith14_operand" ""))
3760	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3761  "TARGET_64BIT
3762   && GET_CODE (operands[0]) == MEM
3763   && register_operand (XEXP (operands[0], 0), DImode)"
3764  [(parallel [(set (match_dup 0) (const_int 0))
3765   	      (clobber (match_dup 1))
3766   	      (clobber (match_dup 4))
3767   	      (use (match_dup 2))
3768   	      (use (match_dup 3))
3769	      (const_int 0)])]
3770  "
3771{
3772  rtx addr = XEXP (operands[0], 0);
3773  if (dead_or_set_p (curr_insn, addr))
3774    operands[4] = addr;
3775  else
3776    {
3777      emit_insn (gen_rtx_SET (operands[4], addr));
3778      operands[0] = replace_equiv_address (operands[0], operands[4]);
3779    }
3780}")
3781
3782(define_insn "clrmemdi_postreload"
3783  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3784	(const_int 0))
3785   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3786   (clobber (match_dup 0))
3787   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3788   (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3789   (const_int 0)]
3790  "TARGET_64BIT && reload_completed"
3791  "* return pa_output_block_clear (operands, !which_alternative);"
3792  [(set_attr "type" "multi,multi")])
3793
3794;; Floating point move insns
3795
3796(define_expand "movdf"
3797  [(set (match_operand:DF 0 "general_operand" "")
3798	(match_operand:DF 1 "general_operand" ""))]
3799  ""
3800  "
3801{
3802  if (pa_emit_move_sequence (operands, DFmode, 0))
3803    DONE;
3804}")
3805
3806;; Handle DFmode input reloads requiring %r1 as a scratch register.
3807(define_expand "reload_indf_r1"
3808  [(set (match_operand:DF 0 "register_operand" "=Z")
3809	(match_operand:DF 1 "non_hard_reg_operand" ""))
3810   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3811  ""
3812  "
3813{
3814  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3815    DONE;
3816
3817  /* We don't want the clobber emitted, so handle this ourselves.  */
3818  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3819  DONE;
3820}")
3821
3822;; Handle DFmode input reloads requiring a general register as a
3823;; scratch register.
3824(define_expand "reload_indf"
3825  [(set (match_operand:DF 0 "register_operand" "=Z")
3826	(match_operand:DF 1 "non_hard_reg_operand" ""))
3827   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3828  ""
3829  "
3830{
3831  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3832    DONE;
3833
3834  /* We don't want the clobber emitted, so handle this ourselves.  */
3835  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3836  DONE;
3837}")
3838
3839;; Handle DFmode output reloads requiring a general register as a
3840;; scratch register.
3841(define_expand "reload_outdf"
3842 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3843	(match_operand:DF 1  "register_operand" "Z"))
3844   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3845  ""
3846  "
3847{
3848  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3849    DONE;
3850
3851  /* We don't want the clobber emitted, so handle this ourselves.  */
3852  emit_insn (gen_rtx_SET (operands[0], operands[1]));
3853  DONE;
3854}")
3855
3856(define_insn ""
3857  [(set (match_operand:DF 0 "move_dest_operand"
3858			  "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3859	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3860			  "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3861  "(register_operand (operands[0], DFmode)
3862    || reg_or_0_operand (operands[1], DFmode))
3863   && !(GET_CODE (operands[1]) == CONST_DOUBLE
3864	&& GET_CODE (operands[0]) == MEM)
3865   && !TARGET_64BIT
3866   && !TARGET_SOFT_FLOAT"
3867  "*
3868{
3869  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3870       || operands[1] == CONST0_RTX (DFmode))
3871      && !(REG_P (operands[0]) && REG_P (operands[1])
3872	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3873    return pa_output_fp_move_double (operands);
3874  return pa_output_move_double (operands);
3875}"
3876  [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3877   (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3878
3879(define_insn ""
3880  [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3881	(match_operand:DF 1 "reg_or_0_operand" "f"))]
3882  "!TARGET_SOFT_FLOAT
3883   && !TARGET_DISABLE_INDEXING
3884   && reload_completed"
3885  "fstd%F0 %1,%0"
3886  [(set_attr "type" "fpstore")
3887   (set_attr "pa_combine_type" "addmove")
3888   (set_attr "length" "4")])
3889
3890(define_peephole2
3891  [(set (match_operand:SI 0 "register_operand" "")
3892	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3893			    (const_int 3))
3894		 (match_operand:SI 2 "register_operand" "")))
3895   (set (mem:DF (match_dup 0))
3896        (match_operand:DF 3 "register_operand" ""))]
3897  "!TARGET_SOFT_FLOAT
3898   && !TARGET_DISABLE_INDEXING
3899   && REG_OK_FOR_BASE_P (operands[2])
3900   && FP_REGNO_P (REGNO (operands[3]))"
3901  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3902	(match_dup 3))
3903   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3904			       (match_dup 2)))]
3905  "")
3906
3907(define_peephole2
3908  [(set (match_operand:SI 0 "register_operand" "")
3909	(plus:SI (match_operand:SI 2 "register_operand" "")
3910		 (ashift:SI (match_operand:SI 1 "register_operand" "")
3911			    (const_int 3))))
3912   (set (mem:DF (match_dup 0))
3913        (match_operand:DF 3 "register_operand" ""))]
3914  "!TARGET_SOFT_FLOAT
3915   && !TARGET_DISABLE_INDEXING
3916   && REG_OK_FOR_BASE_P (operands[2])
3917   && FP_REGNO_P (REGNO (operands[3]))"
3918  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3919	(match_dup 3))
3920   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3921			       (match_dup 2)))]
3922  "")
3923
3924(define_peephole2
3925  [(set (match_operand:DI 0 "register_operand" "")
3926	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
3927			    (const_int 3))
3928		 (match_operand:DI 2 "register_operand" "")))
3929   (set (mem:DF (match_dup 0))
3930        (match_operand:DF 3 "register_operand" ""))]
3931  "!TARGET_SOFT_FLOAT
3932   && !TARGET_DISABLE_INDEXING
3933   && TARGET_64BIT
3934   && REG_OK_FOR_BASE_P (operands[2])
3935   && FP_REGNO_P (REGNO (operands[3]))"
3936  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3937	(match_dup 3))
3938   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3939			       (match_dup 2)))]
3940  "")
3941
3942(define_peephole2
3943  [(set (match_operand:DI 0 "register_operand" "")
3944	(plus:DI (match_operand:DI 2 "register_operand" "")
3945		 (ashift:DI (match_operand:DI 1 "register_operand" "")
3946			    (const_int 3))))
3947   (set (mem:DF (match_dup 0))
3948        (match_operand:DF 3 "register_operand" ""))]
3949  "!TARGET_SOFT_FLOAT
3950   && !TARGET_DISABLE_INDEXING
3951   && TARGET_64BIT
3952   && REG_OK_FOR_BASE_P (operands[2])
3953   && FP_REGNO_P (REGNO (operands[3]))"
3954  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3955	(match_dup 3))
3956   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3957			       (match_dup 2)))]
3958  "")
3959
3960(define_peephole2
3961  [(set (match_operand:SI 0 "register_operand" "")
3962	(plus:SI (match_operand:SI 1 "register_operand" "")
3963		 (match_operand:SI 2 "register_operand" "")))
3964   (set (mem:DF (match_dup 0))
3965        (match_operand:DF 3 "register_operand" ""))]
3966  "!TARGET_SOFT_FLOAT
3967   && !TARGET_DISABLE_INDEXING
3968   && TARGET_NO_SPACE_REGS
3969   && REG_OK_FOR_INDEX_P (operands[1])
3970   && REG_OK_FOR_BASE_P (operands[2])
3971   && FP_REGNO_P (REGNO (operands[3]))"
3972  [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3973	(match_dup 3))
3974   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3975  "")
3976
3977(define_peephole2
3978  [(set (match_operand:SI 0 "register_operand" "")
3979	(plus:SI (match_operand:SI 1 "register_operand" "")
3980		 (match_operand:SI 2 "register_operand" "")))
3981   (set (mem:DF (match_dup 0))
3982        (match_operand:DF 3 "register_operand" ""))]
3983  "!TARGET_SOFT_FLOAT
3984   && !TARGET_DISABLE_INDEXING
3985   && TARGET_NO_SPACE_REGS
3986   && REG_OK_FOR_BASE_P (operands[1])
3987   && REG_OK_FOR_INDEX_P (operands[2])
3988   && FP_REGNO_P (REGNO (operands[3]))"
3989  [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3990	(match_dup 3))
3991   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3992  "")
3993
3994(define_peephole2
3995  [(set (match_operand:DI 0 "register_operand" "")
3996	(plus:DI (match_operand:DI 1 "register_operand" "")
3997		 (match_operand:DI 2 "register_operand" "")))
3998   (set (mem:DF (match_dup 0))
3999        (match_operand:DF 3 "register_operand" ""))]
4000  "!TARGET_SOFT_FLOAT
4001   && !TARGET_DISABLE_INDEXING
4002   && TARGET_64BIT
4003   && TARGET_NO_SPACE_REGS
4004   && REG_OK_FOR_INDEX_P (operands[1])
4005   && REG_OK_FOR_BASE_P (operands[2])
4006   && FP_REGNO_P (REGNO (operands[3]))"
4007  [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4008	(match_dup 3))
4009   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4010  "")
4011
4012(define_peephole2
4013  [(set (match_operand:DI 0 "register_operand" "")
4014	(plus:DI (match_operand:DI 1 "register_operand" "")
4015		 (match_operand:DI 2 "register_operand" "")))
4016   (set (mem:DF (match_dup 0))
4017        (match_operand:DF 3 "register_operand" ""))]
4018  "!TARGET_SOFT_FLOAT
4019   && !TARGET_DISABLE_INDEXING
4020   && TARGET_64BIT
4021   && TARGET_NO_SPACE_REGS
4022   && REG_OK_FOR_BASE_P (operands[1])
4023   && REG_OK_FOR_INDEX_P (operands[2])
4024   && FP_REGNO_P (REGNO (operands[3]))"
4025  [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4026	(match_dup 3))
4027   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4028  "")
4029
4030(define_insn ""
4031  [(set (match_operand:DF 0 "move_dest_operand"
4032			  "=r,?o,?Q,r,r")
4033	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4034			  "rG,r,r,o,RQ"))]
4035  "(register_operand (operands[0], DFmode)
4036    || reg_or_0_operand (operands[1], DFmode))
4037   && !TARGET_64BIT
4038   && TARGET_SOFT_FLOAT"
4039  "*
4040{
4041  return pa_output_move_double (operands);
4042}"
4043  [(set_attr "type" "move,store,store,load,load")
4044   (set_attr "length" "8,8,16,8,16")])
4045
4046(define_insn ""
4047  [(set (match_operand:DF 0 "move_dest_operand"
4048			  "=!*r,*r,*r,*r,*r,Q,f,f,T")
4049	(match_operand:DF 1 "move_src_operand"
4050			  "!*rG,J,N,K,RQ,*rG,fG,RT,f"))]
4051  "(register_operand (operands[0], DFmode)
4052    || reg_or_0_operand (operands[1], DFmode))
4053   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4054  "@
4055   copy %r1,%0
4056   ldi %1,%0
4057   ldil L'%1,%0
4058   depdi,z %z1,%0
4059   ldd%M1 %1,%0
4060   std%M0 %r1,%0
4061   fcpy,dbl %f1,%0
4062   fldd%F1 %1,%0
4063   fstd%F0 %1,%0"
4064  [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4065   (set_attr "pa_combine_type" "addmove")
4066   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4067
4068(define_insn ""
4069  [(set (match_operand:DF 0 "move_dest_operand"
4070			  "=!*r,*r,*r,*r,*r,Q")
4071	(match_operand:DF 1 "move_src_operand"
4072			  "!*rG,J,N,K,RQ,*rG"))]
4073  "(register_operand (operands[0], DFmode)
4074    || reg_or_0_operand (operands[1], DFmode))
4075   && TARGET_SOFT_FLOAT && TARGET_64BIT"
4076  "@
4077   copy %r1,%0
4078   ldi %1,%0
4079   ldil L'%1,%0
4080   depdi,z %z1,%0
4081   ldd%M1 %1,%0
4082   std%M0 %r1,%0"
4083  [(set_attr "type" "move,move,move,shift,load,store")
4084   (set_attr "pa_combine_type" "addmove")
4085   (set_attr "length" "4,4,4,4,4,4")])
4086
4087
4088(define_expand "movdi"
4089  [(set (match_operand:DI 0 "general_operand" "")
4090	(match_operand:DI 1 "general_operand" ""))]
4091  ""
4092  "
4093{
4094  if (pa_emit_move_sequence (operands, DImode, 0))
4095    DONE;
4096}")
4097
4098;; Handle DImode input reloads requiring %r1 as a scratch register.
4099(define_expand "reload_indi_r1"
4100  [(set (match_operand:DI 0 "register_operand" "=Z")
4101	(match_operand:DI 1 "non_hard_reg_operand" ""))
4102   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4103  ""
4104  "
4105{
4106  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4107    DONE;
4108
4109  /* We don't want the clobber emitted, so handle this ourselves.  */
4110  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4111  DONE;
4112}")
4113
4114;; Handle DImode input reloads requiring a general register as a
4115;; scratch register.
4116(define_expand "reload_indi"
4117  [(set (match_operand:DI 0 "register_operand" "=Z")
4118	(match_operand:DI 1 "non_hard_reg_operand" ""))
4119   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4120  ""
4121  "
4122{
4123  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4124    DONE;
4125
4126  /* We don't want the clobber emitted, so handle this ourselves.  */
4127  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4128  DONE;
4129}")
4130
4131;; Handle DImode output reloads requiring a general register as a
4132;; scratch register.
4133(define_expand "reload_outdi"
4134  [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4135	(match_operand:DI 1 "register_operand" "Z"))
4136   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4137  ""
4138  "
4139{
4140  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4141    DONE;
4142
4143  /* We don't want the clobber emitted, so handle this ourselves.  */
4144  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4145  DONE;
4146}")
4147
4148(define_insn ""
4149  [(set (match_operand:DI 0 "register_operand" "=r")
4150	(high:DI (match_operand 1 "" "")))]
4151  "!TARGET_64BIT"
4152  "*
4153{
4154  rtx op0 = operands[0];
4155  rtx op1 = operands[1];
4156
4157  switch (GET_CODE (op1))
4158    {
4159    case CONST_INT:
4160#if HOST_BITS_PER_WIDE_INT <= 32
4161      operands[0] = operand_subword (op0, 1, 0, DImode);
4162      output_asm_insn (\"ldil L'%1,%0\", operands);
4163
4164      operands[0] = operand_subword (op0, 0, 0, DImode);
4165      if (INTVAL (op1) < 0)
4166	output_asm_insn (\"ldi -1,%0\", operands);
4167      else
4168	output_asm_insn (\"ldi 0,%0\", operands);
4169#else
4170      operands[0] = operand_subword (op0, 1, 0, DImode);
4171      operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4172      output_asm_insn (\"ldil L'%1,%0\", operands);
4173
4174      operands[0] = operand_subword (op0, 0, 0, DImode);
4175      operands[1] = GEN_INT (INTVAL (op1) >> 32);
4176      output_asm_insn (pa_singlemove_string (operands), operands);
4177#endif
4178      break;
4179
4180    case CONST_DOUBLE:
4181      operands[0] = operand_subword (op0, 1, 0, DImode);
4182      operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4183      output_asm_insn (\"ldil L'%1,%0\", operands);
4184
4185      operands[0] = operand_subword (op0, 0, 0, DImode);
4186      operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4187      output_asm_insn (pa_singlemove_string (operands), operands);
4188      break;
4189
4190    default:
4191      gcc_unreachable ();
4192    }
4193  return \"\";
4194}"
4195  [(set_attr "type" "move")
4196   (set_attr "length" "12")])
4197
4198(define_insn ""
4199  [(set (match_operand:DI 0 "move_dest_operand"
4200			  "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4201	(match_operand:DI 1 "move_src_operand"
4202			  "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4203  "(register_operand (operands[0], DImode)
4204    || reg_or_0_operand (operands[1], DImode))
4205   && !TARGET_64BIT
4206   && !TARGET_SOFT_FLOAT"
4207  "*
4208{
4209  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4210       || operands[1] == CONST0_RTX (DFmode))
4211      && !(REG_P (operands[0]) && REG_P (operands[1])
4212	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4213    return pa_output_fp_move_double (operands);
4214  return pa_output_move_double (operands);
4215}"
4216  [(set_attr "type"
4217    "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4218   (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4219
4220(define_insn ""
4221  [(set (match_operand:DI 0 "move_dest_operand"
4222			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4223	(match_operand:DI 1 "move_src_operand"
4224			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4225  "(register_operand (operands[0], DImode)
4226    || reg_or_0_operand (operands[1], DImode))
4227   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4228  "@
4229   ldd RT'%A1,%0
4230   copy %1,%0
4231   ldi %1,%0
4232   ldil L'%1,%0
4233   depdi,z %z1,%0
4234   ldd%M1 %1,%0
4235   std%M0 %r1,%0
4236   mtsar %r1
4237   {mfctl|mfctl,w} %%sar,%0
4238   fcpy,dbl %f1,%0
4239   fldd%F1 %1,%0
4240   fstd%F0 %1,%0"
4241  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4242   (set_attr "pa_combine_type" "addmove")
4243   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4244
4245(define_insn ""
4246  [(set (match_operand:DI 0 "move_dest_operand"
4247			  "=r,r,r,r,r,r,Q,!*q,!r")
4248	(match_operand:DI 1 "move_src_operand"
4249			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
4250  "(register_operand (operands[0], DImode)
4251    || reg_or_0_operand (operands[1], DImode))
4252   && TARGET_SOFT_FLOAT && TARGET_64BIT"
4253  "@
4254   ldd RT'%A1,%0
4255   copy %1,%0
4256   ldi %1,%0
4257   ldil L'%1,%0
4258   depdi,z %z1,%0
4259   ldd%M1 %1,%0
4260   std%M0 %r1,%0
4261   mtsar %r1
4262   {mfctl|mfctl,w} %%sar,%0"
4263  [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
4264   (set_attr "pa_combine_type" "addmove")
4265   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4266
4267(define_insn ""
4268  [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4269	(match_operand:DI 1 "register_operand" "f"))]
4270  "!TARGET_SOFT_FLOAT
4271   && TARGET_64BIT
4272   && !TARGET_DISABLE_INDEXING
4273   && reload_completed"
4274  "fstd%F0 %1,%0"
4275  [(set_attr "type" "fpstore")
4276   (set_attr "pa_combine_type" "addmove")
4277   (set_attr "length" "4")])
4278
4279(define_peephole2
4280  [(set (match_operand:DI 0 "register_operand" "")
4281	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4282			    (const_int 3))
4283		 (match_operand:DI 2 "register_operand" "")))
4284   (set (mem:DI (match_dup 0))
4285        (match_operand:DI 3 "register_operand" ""))]
4286  "!TARGET_SOFT_FLOAT
4287   && !TARGET_DISABLE_INDEXING
4288   && TARGET_64BIT
4289   && REG_OK_FOR_BASE_P (operands[2])
4290   && FP_REGNO_P (REGNO (operands[3]))"
4291  [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4292	(match_dup 3))
4293   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4294			       (match_dup 2)))]
4295  "")
4296
4297(define_peephole2
4298  [(set (match_operand:DI 0 "register_operand" "")
4299	(plus:DI (match_operand:DI 1 "register_operand" "")
4300		 (match_operand:DI 2 "register_operand" "")))
4301   (set (mem:DI (match_dup 0))
4302        (match_operand:DI 3 "register_operand" ""))]
4303  "!TARGET_SOFT_FLOAT
4304   && !TARGET_DISABLE_INDEXING
4305   && TARGET_64BIT
4306   && TARGET_NO_SPACE_REGS
4307   && REG_OK_FOR_INDEX_P (operands[1])
4308   && REG_OK_FOR_BASE_P (operands[2])
4309   && FP_REGNO_P (REGNO (operands[3]))"
4310  [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4311	(match_dup 3))
4312   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4313  "")
4314
4315(define_peephole2
4316  [(set (match_operand:DI 0 "register_operand" "")
4317	(plus:DI (match_operand:DI 1 "register_operand" "")
4318		 (match_operand:DI 2 "register_operand" "")))
4319   (set (mem:DI (match_dup 0))
4320        (match_operand:DI 3 "register_operand" ""))]
4321  "!TARGET_SOFT_FLOAT
4322   && !TARGET_DISABLE_INDEXING
4323   && TARGET_64BIT
4324   && TARGET_NO_SPACE_REGS
4325   && REG_OK_FOR_BASE_P (operands[1])
4326   && REG_OK_FOR_INDEX_P (operands[2])
4327   && FP_REGNO_P (REGNO (operands[3]))"
4328  [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4329	(match_dup 3))
4330   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4331  "")
4332
4333(define_insn ""
4334  [(set (match_operand:DI 0 "move_dest_operand"
4335			  "=r,o,Q,r,r,r")
4336	(match_operand:DI 1 "general_operand"
4337			  "rM,r,r,o,Q,i"))]
4338  "(register_operand (operands[0], DImode)
4339    || reg_or_0_operand (operands[1], DImode))
4340   && !TARGET_64BIT
4341   && TARGET_SOFT_FLOAT"
4342  "*
4343{
4344  return pa_output_move_double (operands);
4345}"
4346  [(set_attr "type" "move,store,store,load,load,multi")
4347   (set_attr "length" "8,8,16,8,16,16")])
4348
4349(define_insn ""
4350  [(set (match_operand:DI 0 "register_operand" "=r,&r")
4351	(lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4352		   (match_operand:DI 2 "immediate_operand" "i,i")))]
4353  "!TARGET_64BIT"
4354  "*
4355{
4356  /* Don't output a 64-bit constant, since we can't trust the assembler to
4357     handle it correctly.  */
4358  if (GET_CODE (operands[2]) == CONST_DOUBLE)
4359    operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4360  else if (HOST_BITS_PER_WIDE_INT > 32
4361	   && GET_CODE (operands[2]) == CONST_INT)
4362    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4363  if (which_alternative == 1)
4364    output_asm_insn (\"copy %1,%0\", operands);
4365  return \"ldo R'%G2(%R1),%R0\";
4366}"
4367  [(set_attr "type" "move,move")
4368   (set_attr "length" "4,8")])
4369
4370(define_expand "movsf"
4371  [(set (match_operand:SF 0 "general_operand" "")
4372	(match_operand:SF 1 "general_operand" ""))]
4373  ""
4374  "
4375{
4376  if (pa_emit_move_sequence (operands, SFmode, 0))
4377    DONE;
4378}")
4379
4380;; Handle SFmode input reloads requiring %r1 as a scratch register.
4381(define_expand "reload_insf_r1"
4382  [(set (match_operand:SF 0 "register_operand" "=Z")
4383	(match_operand:SF 1 "non_hard_reg_operand" ""))
4384   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4385  ""
4386  "
4387{
4388  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4389    DONE;
4390
4391  /* We don't want the clobber emitted, so handle this ourselves.  */
4392  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4393  DONE;
4394}")
4395
4396;; Handle SFmode input reloads requiring a general register as a
4397;; scratch register.
4398(define_expand "reload_insf"
4399  [(set (match_operand:SF 0 "register_operand" "=Z")
4400	(match_operand:SF 1 "non_hard_reg_operand" ""))
4401   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4402  ""
4403  "
4404{
4405  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4406    DONE;
4407
4408  /* We don't want the clobber emitted, so handle this ourselves.  */
4409  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4410  DONE;
4411}")
4412
4413;; Handle SFmode output reloads requiring a general register as a
4414;; scratch register.
4415(define_expand "reload_outsf"
4416  [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4417	(match_operand:SF 1  "register_operand" "Z"))
4418   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4419  ""
4420  "
4421{
4422  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4423    DONE;
4424
4425  /* We don't want the clobber emitted, so handle this ourselves.  */
4426  emit_insn (gen_rtx_SET (operands[0], operands[1]));
4427  DONE;
4428}")
4429
4430(define_insn ""
4431  [(set (match_operand:SF 0 "move_dest_operand"
4432			  "=f,!*r,f,*r,T,Q,?*r,?f")
4433	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4434			  "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4435  "(register_operand (operands[0], SFmode)
4436    || reg_or_0_operand (operands[1], SFmode))
4437   && !TARGET_SOFT_FLOAT
4438   && !TARGET_64BIT"
4439  "@
4440   fcpy,sgl %f1,%0
4441   copy %r1,%0
4442   fldw%F1 %1,%0
4443   ldw%M1 %1,%0
4444   fstw%F0 %1,%0
4445   stw%M0 %r1,%0
4446   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4447   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4448  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4449   (set_attr "pa_combine_type" "addmove")
4450   (set_attr "length" "4,4,4,4,4,4,8,8")])
4451
4452(define_insn ""
4453  [(set (match_operand:SF 0 "move_dest_operand"
4454			  "=f,!*r,f,*r,T,Q")
4455	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4456			  "fG,!*rG,RT,RQ,f,*rG"))]
4457  "(register_operand (operands[0], SFmode)
4458    || reg_or_0_operand (operands[1], SFmode))
4459   && !TARGET_SOFT_FLOAT
4460   && TARGET_64BIT"
4461  "@
4462   fcpy,sgl %f1,%0
4463   copy %r1,%0
4464   fldw%F1 %1,%0
4465   ldw%M1 %1,%0
4466   fstw%F0 %1,%0
4467   stw%M0 %r1,%0"
4468  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4469   (set_attr "pa_combine_type" "addmove")
4470   (set_attr "length" "4,4,4,4,4,4")])
4471
4472(define_insn ""
4473  [(set (match_operand:SF 0 "move_dest_operand"
4474			  "=!*r,*r,Q")
4475	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4476			  "!*rG,RQ,*rG"))]
4477  "(register_operand (operands[0], SFmode)
4478    || reg_or_0_operand (operands[1], SFmode))
4479   && TARGET_SOFT_FLOAT
4480   && TARGET_64BIT"
4481  "@
4482   copy %r1,%0
4483   ldw%M1 %1,%0
4484   stw%M0 %r1,%0"
4485  [(set_attr "type" "move,load,store")
4486   (set_attr "pa_combine_type" "addmove")
4487   (set_attr "length" "4,4,4")])
4488
4489(define_insn ""
4490  [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4491	(match_operand:SF 1 "register_operand" "f"))]
4492  "!TARGET_SOFT_FLOAT
4493   && !TARGET_DISABLE_INDEXING
4494   && reload_completed"
4495  "fstw%F0 %1,%0"
4496  [(set_attr "type" "fpstore")
4497   (set_attr "pa_combine_type" "addmove")
4498   (set_attr "length" "4")])
4499
4500(define_peephole2
4501  [(set (match_operand:SI 0 "register_operand" "")
4502	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4503			    (const_int 2))
4504		 (match_operand:SI 2 "register_operand" "")))
4505   (set (mem:SF (match_dup 0))
4506        (match_operand:SF 3 "register_operand" ""))]
4507  "!TARGET_SOFT_FLOAT
4508   && !TARGET_DISABLE_INDEXING
4509   && REG_OK_FOR_BASE_P (operands[2])
4510   && FP_REGNO_P (REGNO (operands[3]))"
4511  [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4512	(match_dup 3))
4513   (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4514			       (match_dup 2)))]
4515  "")
4516
4517(define_peephole2
4518  [(set (match_operand:DI 0 "register_operand" "")
4519	(plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4520			    (const_int 2))
4521		 (match_operand:DI 2 "register_operand" "")))
4522   (set (mem:SF (match_dup 0))
4523        (match_operand:SF 3 "register_operand" ""))]
4524  "!TARGET_SOFT_FLOAT
4525   && !TARGET_DISABLE_INDEXING
4526   && TARGET_64BIT
4527   && REG_OK_FOR_BASE_P (operands[2])
4528   && FP_REGNO_P (REGNO (operands[3]))"
4529  [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4530	(match_dup 3))
4531   (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4532			       (match_dup 2)))]
4533  "")
4534
4535(define_peephole2
4536  [(set (match_operand:SI 0 "register_operand" "")
4537	(plus:SI (match_operand:SI 1 "register_operand" "")
4538		 (match_operand:SI 2 "register_operand" "")))
4539   (set (mem:SF (match_dup 0))
4540        (match_operand:SF 3 "register_operand" ""))]
4541  "!TARGET_SOFT_FLOAT
4542   && !TARGET_DISABLE_INDEXING
4543   && TARGET_NO_SPACE_REGS
4544   && REG_OK_FOR_INDEX_P (operands[1])
4545   && REG_OK_FOR_BASE_P (operands[2])
4546   && FP_REGNO_P (REGNO (operands[3]))"
4547  [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4548	(match_dup 3))
4549   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4550  "")
4551
4552(define_peephole2
4553  [(set (match_operand:SI 0 "register_operand" "")
4554	(plus:SI (match_operand:SI 1 "register_operand" "")
4555		 (match_operand:SI 2 "register_operand" "")))
4556   (set (mem:SF (match_dup 0))
4557        (match_operand:SF 3 "register_operand" ""))]
4558  "!TARGET_SOFT_FLOAT
4559   && !TARGET_DISABLE_INDEXING
4560   && TARGET_NO_SPACE_REGS
4561   && REG_OK_FOR_BASE_P (operands[1])
4562   && REG_OK_FOR_INDEX_P (operands[2])
4563   && FP_REGNO_P (REGNO (operands[3]))"
4564  [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4565	(match_dup 3))
4566   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4567  "")
4568
4569(define_peephole2
4570  [(set (match_operand:DI 0 "register_operand" "")
4571	(plus:DI (match_operand:DI 1 "register_operand" "")
4572		 (match_operand:DI 2 "register_operand" "")))
4573   (set (mem:SF (match_dup 0))
4574        (match_operand:SF 3 "register_operand" ""))]
4575  "!TARGET_SOFT_FLOAT
4576   && !TARGET_DISABLE_INDEXING
4577   && TARGET_64BIT
4578   && TARGET_NO_SPACE_REGS
4579   && REG_OK_FOR_INDEX_P (operands[1])
4580   && REG_OK_FOR_BASE_P (operands[2])
4581   && FP_REGNO_P (REGNO (operands[3]))"
4582  [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4583	(match_dup 3))
4584   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4585  "")
4586
4587(define_peephole2
4588  [(set (match_operand:DI 0 "register_operand" "")
4589	(plus:DI (match_operand:DI 1 "register_operand" "")
4590		 (match_operand:DI 2 "register_operand" "")))
4591   (set (mem:SF (match_dup 0))
4592        (match_operand:SF 3 "register_operand" ""))]
4593  "!TARGET_SOFT_FLOAT
4594   && !TARGET_DISABLE_INDEXING
4595   && TARGET_64BIT
4596   && TARGET_NO_SPACE_REGS
4597   && REG_OK_FOR_BASE_P (operands[1])
4598   && REG_OK_FOR_INDEX_P (operands[2])
4599   && FP_REGNO_P (REGNO (operands[3]))"
4600  [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4601	(match_dup 3))
4602   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4603  "")
4604
4605(define_insn ""
4606  [(set (match_operand:SF 0 "move_dest_operand"
4607			  "=r,r,Q")
4608	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4609			  "rG,RQ,rG"))]
4610  "(register_operand (operands[0], SFmode)
4611    || reg_or_0_operand (operands[1], SFmode))
4612   && TARGET_SOFT_FLOAT"
4613  "@
4614   copy %r1,%0
4615   ldw%M1 %1,%0
4616   stw%M0 %r1,%0"
4617  [(set_attr "type" "move,load,store")
4618   (set_attr "pa_combine_type" "addmove")
4619   (set_attr "length" "4,4,4")])
4620
4621
4622
4623;;- zero extension instructions
4624;; We have define_expand for zero extension patterns to make sure the
4625;; operands get loaded into registers.  The define_insns accept
4626;; memory operands.  This gives us better overall code than just
4627;; having a pattern that does or does not accept memory operands.
4628
4629(define_expand "zero_extendqihi2"
4630  [(set (match_operand:HI 0 "register_operand" "")
4631	(zero_extend:HI
4632	 (match_operand:QI 1 "register_operand" "")))]
4633  ""
4634  "")
4635
4636(define_insn ""
4637  [(set (match_operand:HI 0 "register_operand" "=r,r")
4638	(zero_extend:HI
4639	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4640  "GET_CODE (operands[1]) != CONST_INT"
4641  "@
4642   {extru|extrw,u} %1,31,8,%0
4643   ldb%M1 %1,%0"
4644  [(set_attr "type" "shift,load")
4645   (set_attr "length" "4,4")])
4646
4647(define_expand "zero_extendqisi2"
4648  [(set (match_operand:SI 0 "register_operand" "")
4649	(zero_extend:SI
4650	 (match_operand:QI 1 "register_operand" "")))]
4651  ""
4652  "")
4653
4654(define_insn ""
4655  [(set (match_operand:SI 0 "register_operand" "=r,r")
4656	(zero_extend:SI
4657	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4658  "GET_CODE (operands[1]) != CONST_INT"
4659  "@
4660   {extru|extrw,u} %1,31,8,%0
4661   ldb%M1 %1,%0"
4662  [(set_attr "type" "shift,load")
4663   (set_attr "length" "4,4")])
4664
4665(define_expand "zero_extendhisi2"
4666  [(set (match_operand:SI 0 "register_operand" "")
4667	(zero_extend:SI
4668	 (match_operand:HI 1 "register_operand" "")))]
4669  ""
4670  "")
4671
4672(define_insn ""
4673  [(set (match_operand:SI 0 "register_operand" "=r,r")
4674	(zero_extend:SI
4675	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4676  "GET_CODE (operands[1]) != CONST_INT"
4677  "@
4678   {extru|extrw,u} %1,31,16,%0
4679   ldh%M1 %1,%0"
4680  [(set_attr "type" "shift,load")
4681   (set_attr "length" "4,4")])
4682
4683(define_expand "zero_extendqidi2"
4684  [(set (match_operand:DI 0 "register_operand" "")
4685	(zero_extend:DI
4686	 (match_operand:QI 1 "register_operand" "")))]
4687  "TARGET_64BIT"
4688  "")
4689
4690(define_insn ""
4691  [(set (match_operand:DI 0 "register_operand" "=r,r")
4692	(zero_extend:DI
4693	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4694  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4695  "@
4696   extrd,u %1,63,8,%0
4697   ldb%M1 %1,%0"
4698  [(set_attr "type" "shift,load")
4699   (set_attr "length" "4,4")])
4700
4701(define_expand "zero_extendhidi2"
4702  [(set (match_operand:DI 0 "register_operand" "")
4703	(zero_extend:DI
4704	 (match_operand:HI 1 "register_operand" "")))]
4705  "TARGET_64BIT"
4706  "")
4707
4708(define_insn ""
4709  [(set (match_operand:DI 0 "register_operand" "=r,r")
4710	(zero_extend:DI
4711	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4712  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4713  "@
4714   extrd,u %1,63,16,%0
4715   ldh%M1 %1,%0"
4716  [(set_attr "type" "shift,load")
4717   (set_attr "length" "4,4")])
4718
4719(define_expand "zero_extendsidi2"
4720  [(set (match_operand:DI 0 "register_operand" "")
4721	(zero_extend:DI
4722	 (match_operand:SI 1 "register_operand" "")))]
4723  "TARGET_64BIT"
4724  "")
4725
4726(define_insn ""
4727  [(set (match_operand:DI 0 "register_operand" "=r,r")
4728	(zero_extend:DI
4729	 (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4730  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4731  "@
4732   extrd,u %1,63,32,%0
4733   ldw%M1 %1,%0"
4734  [(set_attr "type" "shift,load")
4735   (set_attr "length" "4,4")])
4736
4737;;- sign extension instructions
4738
4739(define_insn "extendhisi2"
4740  [(set (match_operand:SI 0 "register_operand" "=r")
4741	(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4742  ""
4743  "{extrs|extrw,s} %1,31,16,%0"
4744  [(set_attr "type" "shift")
4745   (set_attr "length" "4")])
4746
4747(define_insn "extendqihi2"
4748  [(set (match_operand:HI 0 "register_operand" "=r")
4749	(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4750  ""
4751  "{extrs|extrw,s} %1,31,8,%0"
4752  [(set_attr "type" "shift")
4753  (set_attr "length" "4")])
4754
4755(define_insn "extendqisi2"
4756  [(set (match_operand:SI 0 "register_operand" "=r")
4757	(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4758  ""
4759  "{extrs|extrw,s} %1,31,8,%0"
4760  [(set_attr "type" "shift")
4761   (set_attr "length" "4")])
4762
4763(define_insn "extendqidi2"
4764  [(set (match_operand:DI 0 "register_operand" "=r")
4765	(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4766  "TARGET_64BIT"
4767  "extrd,s %1,63,8,%0"
4768  [(set_attr "type" "shift")
4769  (set_attr "length" "4")])
4770
4771(define_insn "extendhidi2"
4772  [(set (match_operand:DI 0 "register_operand" "=r")
4773	(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4774  "TARGET_64BIT"
4775  "extrd,s %1,63,16,%0"
4776  [(set_attr "type" "shift")
4777  (set_attr "length" "4")])
4778
4779(define_insn "extendsidi2"
4780  [(set (match_operand:DI 0 "register_operand" "=r")
4781	(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4782  "TARGET_64BIT"
4783  "extrd,s %1,63,32,%0"
4784  [(set_attr "type" "shift")
4785  (set_attr "length" "4")])
4786
4787
4788;; Conversions between float and double.
4789
4790(define_insn "extendsfdf2"
4791  [(set (match_operand:DF 0 "register_operand" "=f")
4792	(float_extend:DF
4793	 (match_operand:SF 1 "register_operand" "f")))]
4794  "! TARGET_SOFT_FLOAT"
4795  "{fcnvff|fcnv},sgl,dbl %1,%0"
4796  [(set_attr "type" "fpalu")
4797   (set_attr "length" "4")])
4798
4799(define_insn "truncdfsf2"
4800  [(set (match_operand:SF 0 "register_operand" "=f")
4801	(float_truncate:SF
4802	 (match_operand:DF 1 "register_operand" "f")))]
4803  "! TARGET_SOFT_FLOAT"
4804  "{fcnvff|fcnv},dbl,sgl %1,%0"
4805  [(set_attr "type" "fpalu")
4806   (set_attr "length" "4")])
4807
4808;; Conversion between fixed point and floating point.
4809;; Note that among the fix-to-float insns
4810;; the ones that start with SImode come first.
4811;; That is so that an operand that is a CONST_INT
4812;; (and therefore lacks a specific machine mode).
4813;; will be recognized as SImode (which is always valid)
4814;; rather than as QImode or HImode.
4815
4816;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4817;; to be reloaded by putting the constant into memory.
4818;; It must come before the more general floatsisf2 pattern.
4819(define_insn ""
4820  [(set (match_operand:SF 0 "register_operand" "=f")
4821	(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4822  "! TARGET_SOFT_FLOAT"
4823  "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4824  [(set_attr "type" "fpalu")
4825   (set_attr "length" "8")])
4826
4827(define_insn "floatsisf2"
4828  [(set (match_operand:SF 0 "register_operand" "=f")
4829	(float:SF (match_operand:SI 1 "register_operand" "f")))]
4830  "! TARGET_SOFT_FLOAT"
4831  "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4832  [(set_attr "type" "fpalu")
4833   (set_attr "length" "4")])
4834
4835;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4836;; to be reloaded by putting the constant into memory.
4837;; It must come before the more general floatsidf2 pattern.
4838(define_insn ""
4839  [(set (match_operand:DF 0 "register_operand" "=f")
4840	(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4841  "! TARGET_SOFT_FLOAT"
4842  "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4843  [(set_attr "type" "fpalu")
4844   (set_attr "length" "8")])
4845
4846(define_insn "floatsidf2"
4847  [(set (match_operand:DF 0 "register_operand" "=f")
4848	(float:DF (match_operand:SI 1 "register_operand" "f")))]
4849  "! TARGET_SOFT_FLOAT"
4850  "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4851  [(set_attr "type" "fpalu")
4852   (set_attr "length" "4")])
4853
4854(define_expand "floatunssisf2"
4855  [(set (subreg:SI (match_dup 2) 4)
4856	(match_operand:SI 1 "register_operand" ""))
4857   (set (subreg:SI (match_dup 2) 0)
4858	(const_int 0))
4859   (set (match_operand:SF 0 "register_operand" "")
4860	(float:SF (match_dup 2)))]
4861  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4862  "
4863{
4864  if (TARGET_PA_20)
4865    {
4866      emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4867      DONE;
4868    }
4869  operands[2] = gen_reg_rtx (DImode);
4870}")
4871
4872(define_expand "floatunssidf2"
4873  [(set (subreg:SI (match_dup 2) 4)
4874	(match_operand:SI 1 "register_operand" ""))
4875   (set (subreg:SI (match_dup 2) 0)
4876	(const_int 0))
4877   (set (match_operand:DF 0 "register_operand" "")
4878	(float:DF (match_dup 2)))]
4879  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4880  "
4881{
4882  if (TARGET_PA_20)
4883    {
4884      emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4885      DONE;
4886    }
4887  operands[2] = gen_reg_rtx (DImode);
4888}")
4889
4890(define_insn "floatdisf2"
4891  [(set (match_operand:SF 0 "register_operand" "=f")
4892	(float:SF (match_operand:DI 1 "register_operand" "f")))]
4893  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4894  "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4895  [(set_attr "type" "fpalu")
4896   (set_attr "length" "4")])
4897
4898(define_insn "floatdidf2"
4899  [(set (match_operand:DF 0 "register_operand" "=f")
4900	(float:DF (match_operand:DI 1 "register_operand" "f")))]
4901  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4902  "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4903  [(set_attr "type" "fpalu")
4904   (set_attr "length" "4")])
4905
4906;; Convert a float to an actual integer.
4907;; Truncation is performed as part of the conversion.
4908
4909(define_insn "fix_truncsfsi2"
4910  [(set (match_operand:SI 0 "register_operand" "=f")
4911	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4912  "! TARGET_SOFT_FLOAT"
4913  "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4914  [(set_attr "type" "fpalu")
4915   (set_attr "length" "4")])
4916
4917(define_insn "fix_truncdfsi2"
4918  [(set (match_operand:SI 0 "register_operand" "=f")
4919	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4920  "! TARGET_SOFT_FLOAT"
4921  "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4922  [(set_attr "type" "fpalu")
4923   (set_attr "length" "4")])
4924
4925(define_insn "fix_truncsfdi2"
4926  [(set (match_operand:DI 0 "register_operand" "=f")
4927	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4928  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4929  "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4930  [(set_attr "type" "fpalu")
4931   (set_attr "length" "4")])
4932
4933(define_insn "fix_truncdfdi2"
4934  [(set (match_operand:DI 0 "register_operand" "=f")
4935	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4936  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4937  "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4938  [(set_attr "type" "fpalu")
4939   (set_attr "length" "4")])
4940
4941(define_insn "floatunssidf2_pa20"
4942  [(set (match_operand:DF 0 "register_operand" "=f")
4943	(unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4944  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4945  "fcnv,uw,dbl %1,%0"
4946  [(set_attr "type" "fpalu")
4947   (set_attr "length" "4")])
4948
4949(define_insn "floatunssisf2_pa20"
4950  [(set (match_operand:SF 0 "register_operand" "=f")
4951	(unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4952  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4953  "fcnv,uw,sgl %1,%0"
4954  [(set_attr "type" "fpalu")
4955   (set_attr "length" "4")])
4956
4957(define_insn "floatunsdisf2"
4958  [(set (match_operand:SF 0 "register_operand" "=f")
4959	(unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4960  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4961  "fcnv,udw,sgl %1,%0"
4962  [(set_attr "type" "fpalu")
4963   (set_attr "length" "4")])
4964
4965(define_insn "floatunsdidf2"
4966  [(set (match_operand:DF 0 "register_operand" "=f")
4967	(unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4968  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4969  "fcnv,udw,dbl %1,%0"
4970  [(set_attr "type" "fpalu")
4971   (set_attr "length" "4")])
4972
4973(define_insn "fixuns_truncsfsi2"
4974  [(set (match_operand:SI 0 "register_operand" "=f")
4975	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4976  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4977  "fcnv,t,sgl,uw %1,%0"
4978  [(set_attr "type" "fpalu")
4979   (set_attr "length" "4")])
4980
4981(define_insn "fixuns_truncdfsi2"
4982  [(set (match_operand:SI 0 "register_operand" "=f")
4983	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4984  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4985  "fcnv,t,dbl,uw %1,%0"
4986  [(set_attr "type" "fpalu")
4987   (set_attr "length" "4")])
4988
4989(define_insn "fixuns_truncsfdi2"
4990  [(set (match_operand:DI 0 "register_operand" "=f")
4991	(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4992  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4993  "fcnv,t,sgl,udw %1,%0"
4994  [(set_attr "type" "fpalu")
4995   (set_attr "length" "4")])
4996
4997(define_insn "fixuns_truncdfdi2"
4998  [(set (match_operand:DI 0 "register_operand" "=f")
4999	(unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5000  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5001  "fcnv,t,dbl,udw %1,%0"
5002  [(set_attr "type" "fpalu")
5003   (set_attr "length" "4")])
5004
5005;;- arithmetic instructions
5006
5007(define_expand "adddi3"
5008  [(set (match_operand:DI 0 "register_operand" "")
5009	(plus:DI (match_operand:DI 1 "register_operand" "")
5010		 (match_operand:DI 2 "adddi3_operand" "")))]
5011  ""
5012  "")
5013
5014(define_insn ""
5015  [(set (match_operand:DI 0 "register_operand" "=r")
5016	(plus:DI (match_operand:DI 1 "register_operand" "%r")
5017		 (match_operand:DI 2 "arith11_operand" "rI")))]
5018  "!TARGET_64BIT"
5019  "*
5020{
5021  if (GET_CODE (operands[2]) == CONST_INT)
5022    {
5023      if (INTVAL (operands[2]) >= 0)
5024	return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5025      else
5026	return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5027    }
5028  else
5029    return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5030}"
5031  [(set_attr "type" "binary")
5032   (set_attr "length" "8")])
5033
5034(define_insn ""
5035  [(set (match_operand:DI 0 "register_operand" "=r,r")
5036	(plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5037		 (match_operand:DI 2 "arith14_operand" "r,J")))]
5038  "TARGET_64BIT"
5039  "@
5040   add,l %1,%2,%0
5041   ldo %2(%1),%0"
5042  [(set_attr "type" "binary,binary")
5043   (set_attr "pa_combine_type" "addmove")
5044   (set_attr "length" "4,4")])
5045
5046(define_insn ""
5047  [(set (match_operand:DI 0 "register_operand" "=r")
5048	(plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5049		 (match_operand:DI 2 "register_operand" "r")))]
5050  "TARGET_64BIT"
5051  "uaddcm %2,%1,%0"
5052  [(set_attr "type" "binary")
5053   (set_attr "length" "4")])
5054
5055(define_insn ""
5056  [(set (match_operand:SI 0 "register_operand" "=r")
5057	(plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5058		 (match_operand:SI 2 "register_operand" "r")))]
5059  ""
5060  "uaddcm %2,%1,%0"
5061  [(set_attr "type" "binary")
5062   (set_attr "length" "4")])
5063
5064(define_expand "addvdi3"
5065  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5066		   (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5067			    (match_operand:DI 2 "arith11_operand" "")))
5068	      (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5069				    (sign_extend:TI (match_dup 2)))
5070			   (sign_extend:TI (plus:DI (match_dup 1)
5071						    (match_dup 2))))
5072		       (const_int 0))])]
5073  ""
5074  "
5075{
5076  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;; Trap instructions.
5365
5366(define_insn "trap"
5367  [(trap_if (const_int 1) (const_int 0))]
5368  ""
5369  "{addit|addi,tc},<> 1,%%r0,%%r0"
5370  [(set_attr "type" "trap")
5371   (set_attr "length" "4")])
5372
5373;; Clobbering a "register_operand" instead of a match_scratch
5374;; in operand3 of millicode calls avoids spilling %r1 and
5375;; produces better code.
5376
5377;; The mulsi3 insns set up registers for the millicode call.
5378(define_expand "mulsi3"
5379  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5380   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5381   (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5382	      (clobber (match_dup 3))
5383	      (clobber (reg:SI 26))
5384	      (clobber (reg:SI 25))
5385	      (clobber (match_dup 4))])
5386   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5387  ""
5388  "
5389{
5390  operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5391  if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5392    {
5393      rtx scratch = gen_reg_rtx (DImode);
5394      operands[1] = force_reg (SImode, operands[1]);
5395      operands[2] = force_reg (SImode, operands[2]);
5396      emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5397      emit_insn (gen_movsi (operands[0],
5398			    gen_rtx_SUBREG (SImode, scratch,
5399					    GET_MODE_SIZE (SImode))));
5400      DONE;
5401    }
5402  operands[3] = gen_reg_rtx (SImode);
5403}")
5404
5405(define_insn "umulsidi3"
5406  [(set (match_operand:DI 0 "register_operand" "=f")
5407	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5408		 (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5409  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5410  "xmpyu %1,%2,%0"
5411  [(set_attr "type" "fpmuldbl")
5412   (set_attr "length" "4")])
5413
5414(define_insn ""
5415  [(set (match_operand:DI 0 "register_operand" "=f")
5416	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5417		 (match_operand:DI 2 "uint32_operand" "f")))]
5418  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5419  "xmpyu %1,%R2,%0"
5420  [(set_attr "type" "fpmuldbl")
5421   (set_attr "length" "4")])
5422
5423(define_insn ""
5424  [(set (match_operand:DI 0 "register_operand" "=f")
5425	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5426		 (match_operand:DI 2 "uint32_operand" "f")))]
5427  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5428  "xmpyu %1,%2R,%0"
5429  [(set_attr "type" "fpmuldbl")
5430   (set_attr "length" "4")])
5431
5432(define_insn ""
5433  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5434   (clobber (match_operand:SI 0 "register_operand" "=a"))
5435   (clobber (reg:SI 26))
5436   (clobber (reg:SI 25))
5437   (clobber (reg:SI 31))]
5438  "!TARGET_64BIT"
5439  "* return pa_output_mul_insn (0, insn);"
5440  [(set_attr "type" "milli")
5441   (set (attr "length")
5442	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5443	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5444
5445(define_insn ""
5446  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5447   (clobber (match_operand:SI 0 "register_operand" "=a"))
5448   (clobber (reg:SI 26))
5449   (clobber (reg:SI 25))
5450   (clobber (reg:SI 2))]
5451  "TARGET_64BIT"
5452  "* return pa_output_mul_insn (0, insn);"
5453  [(set_attr "type" "milli")
5454   (set (attr "length")
5455	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5456	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5457
5458(define_expand "muldi3"
5459  [(set (match_operand:DI 0 "register_operand" "")
5460        (mult:DI (match_operand:DI 1 "register_operand" "")
5461		 (match_operand:DI 2 "register_operand" "")))]
5462  "! optimize_size
5463   && TARGET_PA_11
5464   && ! TARGET_DISABLE_FPREGS
5465   && ! TARGET_SOFT_FLOAT"
5466  "
5467{
5468  rtx low_product = gen_reg_rtx (DImode);
5469  rtx cross_product1 = gen_reg_rtx (DImode);
5470  rtx cross_product2 = gen_reg_rtx (DImode);
5471  rtx op1l, op1r, op2l, op2r;
5472
5473  if (TARGET_64BIT)
5474    {
5475      rtx op1shifted = gen_reg_rtx (DImode);
5476      rtx op2shifted = gen_reg_rtx (DImode);
5477
5478      emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5479						    GEN_INT (32)));
5480      emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5481						    GEN_INT (32)));
5482      op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5483      op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5484      op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5485      op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5486    }
5487  else
5488    {
5489      op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5490      op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5491      op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5492      op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5493    }
5494
5495  /* Emit multiplies for the cross products.  */
5496  emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5497  emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5498
5499  /* Emit a multiply for the low sub-word.  */
5500  emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5501
5502  if (TARGET_64BIT)
5503    {
5504      rtx cross_scratch = gen_reg_rtx (DImode);
5505      rtx cross_product = gen_reg_rtx (DImode);
5506
5507      /* Sum the cross products and shift them into proper position.  */
5508      emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5509      emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5510
5511      /* Add the cross product to the low product and store the result
5512	 into the output operand .  */
5513      emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5514    }
5515  else
5516    {
5517      rtx cross_scratch = gen_reg_rtx (SImode);
5518
5519      /* Sum cross products.  */
5520      emit_move_insn (cross_scratch,
5521		      gen_rtx_PLUS (SImode,
5522				    gen_lowpart (SImode, cross_product1),
5523				    gen_lowpart (SImode, cross_product2)));
5524      emit_move_insn (gen_lowpart (SImode, operands[0]),
5525		      gen_lowpart (SImode, low_product));
5526      emit_move_insn (gen_highpart (SImode, operands[0]),
5527		      gen_rtx_PLUS (SImode,
5528				    gen_highpart (SImode, low_product),
5529				    cross_scratch));
5530    }
5531  DONE;
5532}")
5533
5534;;; Division and mod.
5535(define_expand "divsi3"
5536  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5537   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5538   (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5539	      (clobber (match_dup 3))
5540	      (clobber (match_dup 4))
5541	      (clobber (reg:SI 26))
5542	      (clobber (reg:SI 25))
5543	      (clobber (match_dup 5))])
5544   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5545  ""
5546  "
5547{
5548  operands[3] = gen_reg_rtx (SImode);
5549  if (TARGET_64BIT)
5550    {
5551      operands[5] = gen_rtx_REG (SImode, 2);
5552      operands[4] = operands[5];
5553    }
5554  else
5555    {
5556      operands[5] = gen_rtx_REG (SImode, 31);
5557      operands[4] = gen_reg_rtx (SImode);
5558    }
5559  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5560    DONE;
5561}")
5562
5563(define_insn ""
5564  [(set (reg:SI 29)
5565	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5566   (clobber (match_operand:SI 1 "register_operand" "=a"))
5567   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5568   (clobber (reg:SI 26))
5569   (clobber (reg:SI 25))
5570   (clobber (reg:SI 31))]
5571  "!TARGET_64BIT"
5572  "*
5573   return pa_output_div_insn (operands, 0, insn);"
5574  [(set_attr "type" "milli")
5575   (set (attr "length")
5576	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5577	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5578
5579(define_insn ""
5580  [(set (reg:SI 29)
5581	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5582   (clobber (match_operand:SI 1 "register_operand" "=a"))
5583   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5584   (clobber (reg:SI 26))
5585   (clobber (reg:SI 25))
5586   (clobber (reg:SI 2))]
5587  "TARGET_64BIT"
5588  "*
5589   return pa_output_div_insn (operands, 0, insn);"
5590  [(set_attr "type" "milli")
5591   (set (attr "length")
5592	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5593	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5594
5595(define_expand "udivsi3"
5596  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5597   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5598   (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5599	      (clobber (match_dup 3))
5600	      (clobber (match_dup 4))
5601	      (clobber (reg:SI 26))
5602	      (clobber (reg:SI 25))
5603	      (clobber (match_dup 5))])
5604   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5605  ""
5606  "
5607{
5608  operands[3] = gen_reg_rtx (SImode);
5609
5610  if (TARGET_64BIT)
5611    {
5612      operands[5] = gen_rtx_REG (SImode, 2);
5613      operands[4] = operands[5];
5614    }
5615  else
5616    {
5617      operands[5] = gen_rtx_REG (SImode, 31);
5618      operands[4] = gen_reg_rtx (SImode);
5619    }
5620  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5621    DONE;
5622}")
5623
5624(define_insn ""
5625  [(set (reg:SI 29)
5626	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5627   (clobber (match_operand:SI 1 "register_operand" "=a"))
5628   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5629   (clobber (reg:SI 26))
5630   (clobber (reg:SI 25))
5631   (clobber (reg:SI 31))]
5632  "!TARGET_64BIT"
5633  "*
5634   return pa_output_div_insn (operands, 1, insn);"
5635  [(set_attr "type" "milli")
5636   (set (attr "length")
5637	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5638	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5639
5640(define_insn ""
5641  [(set (reg:SI 29)
5642	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5643   (clobber (match_operand:SI 1 "register_operand" "=a"))
5644   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5645   (clobber (reg:SI 26))
5646   (clobber (reg:SI 25))
5647   (clobber (reg:SI 2))]
5648  "TARGET_64BIT"
5649  "*
5650   return pa_output_div_insn (operands, 1, insn);"
5651  [(set_attr "type" "milli")
5652   (set (attr "length")
5653	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5654	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5655
5656(define_expand "modsi3"
5657  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5658   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5659   (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5660	      (clobber (match_dup 3))
5661	      (clobber (match_dup 4))
5662	      (clobber (reg:SI 26))
5663	      (clobber (reg:SI 25))
5664	      (clobber (match_dup 5))])
5665   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5666  ""
5667  "
5668{
5669  if (TARGET_64BIT)
5670    {
5671      operands[5] = gen_rtx_REG (SImode, 2);
5672      operands[4] = operands[5];
5673    }
5674  else
5675    {
5676      operands[5] = gen_rtx_REG (SImode, 31);
5677      operands[4] = gen_reg_rtx (SImode);
5678    }
5679  operands[3] = gen_reg_rtx (SImode);
5680}")
5681
5682(define_insn ""
5683  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5684   (clobber (match_operand:SI 0 "register_operand" "=a"))
5685   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5686   (clobber (reg:SI 26))
5687   (clobber (reg:SI 25))
5688   (clobber (reg:SI 31))]
5689  "!TARGET_64BIT"
5690  "*
5691  return pa_output_mod_insn (0, insn);"
5692  [(set_attr "type" "milli")
5693   (set (attr "length")
5694	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5695	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5696
5697(define_insn ""
5698  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5699   (clobber (match_operand:SI 0 "register_operand" "=a"))
5700   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5701   (clobber (reg:SI 26))
5702   (clobber (reg:SI 25))
5703   (clobber (reg:SI 2))]
5704  "TARGET_64BIT"
5705  "*
5706  return pa_output_mod_insn (0, insn);"
5707  [(set_attr "type" "milli")
5708   (set (attr "length")
5709	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5710	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5711
5712(define_expand "umodsi3"
5713  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5714   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5715   (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5716	      (clobber (match_dup 3))
5717	      (clobber (match_dup 4))
5718	      (clobber (reg:SI 26))
5719	      (clobber (reg:SI 25))
5720	      (clobber (match_dup 5))])
5721   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5722  ""
5723  "
5724{
5725  if (TARGET_64BIT)
5726    {
5727      operands[5] = gen_rtx_REG (SImode, 2);
5728      operands[4] = operands[5];
5729    }
5730  else
5731    {
5732      operands[5] = gen_rtx_REG (SImode, 31);
5733      operands[4] = gen_reg_rtx (SImode);
5734    }
5735  operands[3] = gen_reg_rtx (SImode);
5736}")
5737
5738(define_insn ""
5739  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5740   (clobber (match_operand:SI 0 "register_operand" "=a"))
5741   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5742   (clobber (reg:SI 26))
5743   (clobber (reg:SI 25))
5744   (clobber (reg:SI 31))]
5745  "!TARGET_64BIT"
5746  "*
5747  return pa_output_mod_insn (1, insn);"
5748  [(set_attr "type" "milli")
5749   (set (attr "length")
5750	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5751	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5752
5753(define_insn ""
5754  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5755   (clobber (match_operand:SI 0 "register_operand" "=a"))
5756   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5757   (clobber (reg:SI 26))
5758   (clobber (reg:SI 25))
5759   (clobber (reg:SI 2))]
5760  "TARGET_64BIT"
5761  "*
5762  return pa_output_mod_insn (1, insn);"
5763  [(set_attr "type" "milli")
5764   (set (attr "length")
5765	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5766	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5767
5768;;- and instructions
5769;; We define DImode `and` so with DImode `not` we can get
5770;; DImode `andn`.  Other combinations are possible.
5771
5772(define_expand "anddi3"
5773  [(set (match_operand:DI 0 "register_operand" "")
5774	(and:DI (match_operand:DI 1 "register_operand" "")
5775		(match_operand:DI 2 "and_operand" "")))]
5776  "TARGET_64BIT"
5777  "")
5778
5779(define_insn ""
5780  [(set (match_operand:DI 0 "register_operand" "=r,r")
5781	(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5782		(match_operand:DI 2 "and_operand" "rO,P")))]
5783  "TARGET_64BIT"
5784  "* return pa_output_64bit_and (operands); "
5785  [(set_attr "type" "binary")
5786   (set_attr "length" "4")])
5787
5788; The ? for op1 makes reload prefer zdepi instead of loading a huge
5789; constant with ldil;ldo.
5790(define_insn "andsi3"
5791  [(set (match_operand:SI 0 "register_operand" "=r,r")
5792	(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5793		(match_operand:SI 2 "and_operand" "rO,P")))]
5794  ""
5795  "* return pa_output_and (operands); "
5796  [(set_attr "type" "binary,shift")
5797   (set_attr "length" "4,4")])
5798
5799(define_insn ""
5800  [(set (match_operand:DI 0 "register_operand" "=r")
5801	(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5802		(match_operand:DI 2 "register_operand" "r")))]
5803  "TARGET_64BIT"
5804  "andcm %2,%1,%0"
5805  [(set_attr "type" "binary")
5806   (set_attr "length" "4")])
5807
5808(define_insn ""
5809  [(set (match_operand:SI 0 "register_operand" "=r")
5810	(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5811		(match_operand:SI 2 "register_operand" "r")))]
5812  ""
5813  "andcm %2,%1,%0"
5814  [(set_attr "type" "binary")
5815  (set_attr "length" "4")])
5816
5817(define_expand "iordi3"
5818  [(set (match_operand:DI 0 "register_operand" "")
5819	(ior:DI (match_operand:DI 1 "register_operand" "")
5820		(match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5821  "TARGET_64BIT"
5822  "")
5823
5824(define_insn ""
5825  [(set (match_operand:DI 0 "register_operand" "=r,r")
5826	(ior:DI (match_operand:DI 1 "register_operand" "0,0")
5827		(match_operand:DI 2 "cint_ior_operand" "M,i")))]
5828  "TARGET_64BIT"
5829  "* return pa_output_64bit_ior (operands); "
5830  [(set_attr "type" "binary,shift")
5831   (set_attr "length" "4,4")])
5832
5833(define_insn ""
5834  [(set (match_operand:DI 0 "register_operand" "=r")
5835	(ior:DI (match_operand:DI 1 "register_operand" "%r")
5836		(match_operand:DI 2 "register_operand" "r")))]
5837  "TARGET_64BIT"
5838  "or %1,%2,%0"
5839  [(set_attr "type" "binary")
5840   (set_attr "length" "4")])
5841
5842;; Need a define_expand because we've run out of CONST_OK... characters.
5843(define_expand "iorsi3"
5844  [(set (match_operand:SI 0 "register_operand" "")
5845	(ior:SI (match_operand:SI 1 "register_operand" "")
5846		(match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5847  ""
5848  "")
5849
5850(define_insn ""
5851  [(set (match_operand:SI 0 "register_operand" "=r,r")
5852	(ior:SI (match_operand:SI 1 "register_operand" "0,0")
5853		(match_operand:SI 2 "cint_ior_operand" "M,i")))]
5854  ""
5855  "* return pa_output_ior (operands); "
5856  [(set_attr "type" "binary,shift")
5857   (set_attr "length" "4,4")])
5858
5859(define_insn ""
5860  [(set (match_operand:SI 0 "register_operand" "=r")
5861	(ior:SI (match_operand:SI 1 "register_operand" "%r")
5862		(match_operand:SI 2 "register_operand" "r")))]
5863  ""
5864  "or %1,%2,%0"
5865  [(set_attr "type" "binary")
5866   (set_attr "length" "4")])
5867
5868(define_expand "xordi3"
5869  [(set (match_operand:DI 0 "register_operand" "")
5870	(xor:DI (match_operand:DI 1 "register_operand" "")
5871		(match_operand:DI 2 "register_operand" "")))]
5872  "TARGET_64BIT"
5873  "")
5874
5875(define_insn ""
5876  [(set (match_operand:DI 0 "register_operand" "=r")
5877	(xor:DI (match_operand:DI 1 "register_operand" "%r")
5878		(match_operand:DI 2 "register_operand" "r")))]
5879  "TARGET_64BIT"
5880  "xor %1,%2,%0"
5881  [(set_attr "type" "binary")
5882   (set_attr "length" "4")])
5883
5884(define_insn "xorsi3"
5885  [(set (match_operand:SI 0 "register_operand" "=r")
5886	(xor:SI (match_operand:SI 1 "register_operand" "%r")
5887		(match_operand:SI 2 "register_operand" "r")))]
5888  ""
5889  "xor %1,%2,%0"
5890  [(set_attr "type" "binary")
5891   (set_attr "length" "4")])
5892
5893(define_expand "negdi2"
5894  [(set (match_operand:DI 0 "register_operand" "")
5895	(neg:DI (match_operand:DI 1 "register_operand" "")))]
5896  ""
5897  "")
5898
5899(define_insn ""
5900  [(set (match_operand:DI 0 "register_operand" "=r")
5901	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5902  "!TARGET_64BIT"
5903  "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5904  [(set_attr "type" "unary")
5905   (set_attr "length" "8")])
5906
5907(define_insn ""
5908  [(set (match_operand:DI 0 "register_operand" "=r")
5909	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5910  "TARGET_64BIT"
5911  "sub %%r0,%1,%0"
5912  [(set_attr "type" "unary")
5913   (set_attr "length" "4")])
5914
5915(define_expand "negvdi2"
5916  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5917		   (neg:DI (match_operand:DI 1 "register_operand" "")))
5918	      (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5919				   (sign_extend:TI (neg:DI (match_dup 1))))
5920		       (const_int 0))])]
5921  ""
5922  "")
5923
5924(define_insn ""
5925  [(set (match_operand:DI 0 "register_operand" "=r")
5926	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5927   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5928		(sign_extend:TI (neg:DI (match_dup 1))))
5929	    (const_int 0))]
5930  "!TARGET_64BIT"
5931  "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5932  [(set_attr "type" "unary")
5933   (set_attr "length" "8")])
5934
5935(define_insn ""
5936  [(set (match_operand:DI 0 "register_operand" "=r")
5937	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5938   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5939		(sign_extend:TI (neg:DI (match_dup 1))))
5940	    (const_int 0))]
5941  "TARGET_64BIT"
5942  "sub,tsv %%r0,%1,%0"
5943  [(set_attr "type" "unary")
5944   (set_attr "length" "4")])
5945
5946(define_insn "negsi2"
5947  [(set (match_operand:SI 0 "register_operand" "=r")
5948	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
5949  ""
5950  "sub %%r0,%1,%0"
5951  [(set_attr "type" "unary")
5952   (set_attr "length" "4")])
5953
5954(define_insn "negvsi2"
5955  [(set (match_operand:SI 0 "register_operand" "=r")
5956        (neg:SI (match_operand:SI 1 "register_operand" "r")))
5957   (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
5958		(sign_extend:DI (neg:SI (match_dup 1))))
5959	    (const_int 0))]
5960   ""
5961   "{subo|sub,tsv} %%r0,%1,%0"
5962  [(set_attr "type" "unary")
5963   (set_attr "length" "4")])
5964
5965(define_expand "one_cmpldi2"
5966  [(set (match_operand:DI 0 "register_operand" "")
5967	(not:DI (match_operand:DI 1 "register_operand" "")))]
5968  ""
5969  "
5970{
5971}")
5972
5973(define_insn ""
5974  [(set (match_operand:DI 0 "register_operand" "=r")
5975	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5976  "!TARGET_64BIT"
5977  "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5978  [(set_attr "type" "unary")
5979   (set_attr "length" "8")])
5980
5981(define_insn ""
5982  [(set (match_operand:DI 0 "register_operand" "=r")
5983	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5984  "TARGET_64BIT"
5985  "uaddcm %%r0,%1,%0"
5986  [(set_attr "type" "unary")
5987   (set_attr "length" "4")])
5988
5989(define_insn "one_cmplsi2"
5990  [(set (match_operand:SI 0 "register_operand" "=r")
5991	(not:SI (match_operand:SI 1 "register_operand" "r")))]
5992  ""
5993  "uaddcm %%r0,%1,%0"
5994  [(set_attr "type" "unary")
5995   (set_attr "length" "4")])
5996
5997;; Floating point arithmetic instructions.
5998
5999(define_insn "adddf3"
6000  [(set (match_operand:DF 0 "register_operand" "=f")
6001	(plus:DF (match_operand:DF 1 "register_operand" "f")
6002		 (match_operand:DF 2 "register_operand" "f")))]
6003  "! TARGET_SOFT_FLOAT"
6004  "fadd,dbl %1,%2,%0"
6005  [(set_attr "type" "fpalu")
6006   (set_attr "pa_combine_type" "faddsub")
6007   (set_attr "length" "4")])
6008
6009(define_insn "addsf3"
6010  [(set (match_operand:SF 0 "register_operand" "=f")
6011	(plus:SF (match_operand:SF 1 "register_operand" "f")
6012		 (match_operand:SF 2 "register_operand" "f")))]
6013  "! TARGET_SOFT_FLOAT"
6014  "fadd,sgl %1,%2,%0"
6015  [(set_attr "type" "fpalu")
6016   (set_attr "pa_combine_type" "faddsub")
6017   (set_attr "length" "4")])
6018
6019(define_insn "subdf3"
6020  [(set (match_operand:DF 0 "register_operand" "=f")
6021	(minus:DF (match_operand:DF 1 "register_operand" "f")
6022		  (match_operand:DF 2 "register_operand" "f")))]
6023  "! TARGET_SOFT_FLOAT"
6024  "fsub,dbl %1,%2,%0"
6025  [(set_attr "type" "fpalu")
6026   (set_attr "pa_combine_type" "faddsub")
6027   (set_attr "length" "4")])
6028
6029(define_insn "subsf3"
6030  [(set (match_operand:SF 0 "register_operand" "=f")
6031	(minus:SF (match_operand:SF 1 "register_operand" "f")
6032		  (match_operand:SF 2 "register_operand" "f")))]
6033  "! TARGET_SOFT_FLOAT"
6034  "fsub,sgl %1,%2,%0"
6035  [(set_attr "type" "fpalu")
6036   (set_attr "pa_combine_type" "faddsub")
6037   (set_attr "length" "4")])
6038
6039(define_insn "muldf3"
6040  [(set (match_operand:DF 0 "register_operand" "=f")
6041	(mult:DF (match_operand:DF 1 "register_operand" "f")
6042		 (match_operand:DF 2 "register_operand" "f")))]
6043  "! TARGET_SOFT_FLOAT"
6044  "fmpy,dbl %1,%2,%0"
6045  [(set_attr "type" "fpmuldbl")
6046   (set_attr "pa_combine_type" "fmpy")
6047   (set_attr "length" "4")])
6048
6049(define_insn "mulsf3"
6050  [(set (match_operand:SF 0 "register_operand" "=f")
6051	(mult:SF (match_operand:SF 1 "register_operand" "f")
6052		 (match_operand:SF 2 "register_operand" "f")))]
6053  "! TARGET_SOFT_FLOAT"
6054  "fmpy,sgl %1,%2,%0"
6055  [(set_attr "type" "fpmulsgl")
6056   (set_attr "pa_combine_type" "fmpy")
6057   (set_attr "length" "4")])
6058
6059(define_insn "divdf3"
6060  [(set (match_operand:DF 0 "register_operand" "=f")
6061	(div:DF (match_operand:DF 1 "register_operand" "f")
6062		(match_operand:DF 2 "register_operand" "f")))]
6063  "! TARGET_SOFT_FLOAT"
6064  "fdiv,dbl %1,%2,%0"
6065  [(set_attr "type" "fpdivdbl")
6066   (set_attr "length" "4")])
6067
6068(define_insn "divsf3"
6069  [(set (match_operand:SF 0 "register_operand" "=f")
6070	(div:SF (match_operand:SF 1 "register_operand" "f")
6071		(match_operand:SF 2 "register_operand" "f")))]
6072  "! TARGET_SOFT_FLOAT"
6073  "fdiv,sgl %1,%2,%0"
6074  [(set_attr "type" "fpdivsgl")
6075   (set_attr "length" "4")])
6076
6077;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6078;; negation can be done by subtracting from plus zero.  However, this
6079;; violates the IEEE standard when negating plus and minus zero.
6080;; The slow path toggles the sign bit in the general registers.
6081(define_expand "negdf2"
6082  [(set (match_operand:DF 0 "register_operand" "")
6083	(neg:DF (match_operand:DF 1 "register_operand" "")))]
6084  "!TARGET_SOFT_FLOAT"
6085{
6086  if (TARGET_PA_20 || !flag_signed_zeros)
6087    emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6088  else
6089    emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6090  DONE;
6091})
6092
6093(define_insn "negdf2_slow"
6094  [(set (match_operand:DF 0 "register_operand" "=r")
6095	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
6096  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6097  "*
6098{
6099  if (rtx_equal_p (operands[0], operands[1]))
6100    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6101  else
6102    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6103}"
6104  [(set_attr "type" "multi")
6105   (set (attr "length")
6106	(if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6107	    (const_int 12)
6108	    (const_int 16)))])
6109
6110(define_insn "negdf2_fast"
6111  [(set (match_operand:DF 0 "register_operand" "=f")
6112	(neg:DF (match_operand:DF 1 "register_operand" "f")))]
6113  "!TARGET_SOFT_FLOAT"
6114  "*
6115{
6116  if (TARGET_PA_20)
6117    return \"fneg,dbl %1,%0\";
6118  else
6119    return \"fsub,dbl %%fr0,%1,%0\";
6120}"
6121  [(set_attr "type" "fpalu")
6122   (set_attr "length" "4")])
6123
6124(define_expand "negsf2"
6125  [(set (match_operand:SF 0 "register_operand" "")
6126	(neg:SF (match_operand:SF 1 "register_operand" "")))]
6127  "!TARGET_SOFT_FLOAT"
6128{
6129  if (TARGET_PA_20 || !flag_signed_zeros)
6130    emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6131  else
6132    emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6133  DONE;
6134})
6135
6136(define_insn "negsf2_slow"
6137  [(set (match_operand:SF 0 "register_operand" "=r")
6138	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
6139  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6140  "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6141  [(set_attr "type" "multi")
6142   (set_attr "length" "12")])
6143
6144(define_insn "negsf2_fast"
6145  [(set (match_operand:SF 0 "register_operand" "=f")
6146	(neg:SF (match_operand:SF 1 "register_operand" "f")))]
6147  "!TARGET_SOFT_FLOAT"
6148  "*
6149{
6150  if (TARGET_PA_20)
6151    return \"fneg,sgl %1,%0\";
6152  else
6153    return \"fsub,sgl %%fr0,%1,%0\";
6154}"
6155  [(set_attr "type" "fpalu")
6156   (set_attr "length" "4")])
6157
6158(define_insn "absdf2"
6159  [(set (match_operand:DF 0 "register_operand" "=f")
6160	(abs:DF (match_operand:DF 1 "register_operand" "f")))]
6161  "! TARGET_SOFT_FLOAT"
6162  "fabs,dbl %1,%0"
6163  [(set_attr "type" "fpalu")
6164   (set_attr "length" "4")])
6165
6166(define_insn "abssf2"
6167  [(set (match_operand:SF 0 "register_operand" "=f")
6168	(abs:SF (match_operand:SF 1 "register_operand" "f")))]
6169  "! TARGET_SOFT_FLOAT"
6170  "fabs,sgl %1,%0"
6171  [(set_attr "type" "fpalu")
6172   (set_attr "length" "4")])
6173
6174(define_insn "sqrtdf2"
6175  [(set (match_operand:DF 0 "register_operand" "=f")
6176	(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6177  "! TARGET_SOFT_FLOAT"
6178  "fsqrt,dbl %1,%0"
6179  [(set_attr "type" "fpsqrtdbl")
6180   (set_attr "length" "4")])
6181
6182(define_insn "sqrtsf2"
6183  [(set (match_operand:SF 0 "register_operand" "=f")
6184	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6185  "! TARGET_SOFT_FLOAT"
6186  "fsqrt,sgl %1,%0"
6187  [(set_attr "type" "fpsqrtsgl")
6188   (set_attr "length" "4")])
6189
6190;; PA 2.0 floating point instructions
6191
6192; fmpyfadd patterns
6193(define_insn "fmadf4"
6194  [(set (match_operand:DF 0 "register_operand" "=f")
6195	(fma:DF (match_operand:DF 1 "register_operand" "f")
6196		(match_operand:DF 2 "register_operand" "f")
6197		(match_operand:DF 3 "register_operand" "f")))]
6198  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6199  "fmpyfadd,dbl %1,%2,%3,%0"
6200  [(set_attr "type" "fpmuldbl")
6201   (set_attr "length" "4")])
6202
6203(define_insn "fmasf4"
6204  [(set (match_operand:SF 0 "register_operand" "=f")
6205	(fma:SF (match_operand:SF 1 "register_operand" "f")
6206		(match_operand:SF 2 "register_operand" "f")
6207		(match_operand:SF 3 "register_operand" "f")))]
6208  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6209  "fmpyfadd,sgl %1,%2,%3,%0"
6210  [(set_attr "type" "fpmulsgl")
6211   (set_attr "length" "4")])
6212
6213; fmpynfadd patterns
6214(define_insn "fnmadf4"
6215  [(set (match_operand:DF 0 "register_operand" "=f")
6216	(fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6217		(match_operand:DF 2 "register_operand" "f")
6218		(match_operand:DF 3 "register_operand" "f")))]
6219  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6220  "fmpynfadd,dbl %1,%2,%3,%0"
6221  [(set_attr "type" "fpmuldbl")
6222   (set_attr "length" "4")])
6223
6224(define_insn "fnmasf4"
6225  [(set (match_operand:SF 0 "register_operand" "=f")
6226	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6227		(match_operand:SF 2 "register_operand" "f")
6228		(match_operand:SF 3 "register_operand" "f")))]
6229  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6230  "fmpynfadd,sgl %1,%2,%3,%0"
6231  [(set_attr "type" "fpmulsgl")
6232   (set_attr "length" "4")])
6233
6234; fnegabs patterns
6235(define_insn ""
6236  [(set (match_operand:DF 0 "register_operand" "=f")
6237	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6238  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6239  "fnegabs,dbl %1,%0"
6240  [(set_attr "type" "fpalu")
6241   (set_attr "length" "4")])
6242
6243(define_insn ""
6244  [(set (match_operand:SF 0 "register_operand" "=f")
6245	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6246  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6247  "fnegabs,sgl %1,%0"
6248  [(set_attr "type" "fpalu")
6249   (set_attr "length" "4")])
6250
6251(define_insn ""
6252  [(set (match_operand:DF 0 "register_operand" "=f")
6253	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6254   (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6255  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6256    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6257  "#"
6258  [(set_attr "type" "fpalu")
6259   (set_attr "length" "8")])
6260
6261(define_split
6262  [(set (match_operand:DF 0 "register_operand" "")
6263	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6264   (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6265  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6266  [(set (match_dup 2) (abs:DF (match_dup 1)))
6267   (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6268  "")
6269
6270(define_insn ""
6271  [(set (match_operand:SF 0 "register_operand" "=f")
6272	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6273   (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6274  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6275    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6276  "#"
6277  [(set_attr "type" "fpalu")
6278   (set_attr "length" "8")])
6279
6280(define_split
6281  [(set (match_operand:SF 0 "register_operand" "")
6282	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6283   (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6284  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6285  [(set (match_dup 2) (abs:SF (match_dup 1)))
6286   (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6287  "")
6288
6289;; Negating a multiply can be faked by adding zero in a fused multiply-add
6290;; instruction if we can ignore the sign of zero.
6291(define_insn ""
6292  [(set (match_operand:DF 0 "register_operand" "=f")
6293	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6294			 (match_operand:DF 2 "register_operand" "f"))))]
6295  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6296  "fmpynfadd,dbl %1,%2,%%fr0,%0"
6297  [(set_attr "type" "fpmuldbl")
6298   (set_attr "length" "4")])
6299
6300(define_insn ""
6301  [(set (match_operand:SF 0 "register_operand" "=f")
6302	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6303			 (match_operand:SF 2 "register_operand" "f"))))]
6304  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6305  "fmpynfadd,sgl %1,%2,%%fr0,%0"
6306  [(set_attr "type" "fpmuldbl")
6307   (set_attr "length" "4")])
6308
6309(define_insn ""
6310  [(set (match_operand:DF 0 "register_operand" "=f")
6311	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6312			 (match_operand:DF 2 "register_operand" "f"))))
6313   (set (match_operand:DF 3 "register_operand" "=&f")
6314	(mult:DF (match_dup 1) (match_dup 2)))]
6315  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6316    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6317          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6318  "#"
6319  [(set_attr "type" "fpmuldbl")
6320   (set_attr "length" "8")])
6321
6322(define_split
6323  [(set (match_operand:DF 0 "register_operand" "")
6324	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6325			 (match_operand:DF 2 "register_operand" ""))))
6326   (set (match_operand:DF 3 "register_operand" "")
6327	(mult:DF (match_dup 1) (match_dup 2)))]
6328  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6329  [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6330   (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6331  "")
6332
6333(define_insn ""
6334  [(set (match_operand:SF 0 "register_operand" "=f")
6335	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6336			 (match_operand:SF 2 "register_operand" "f"))))
6337   (set (match_operand:SF 3 "register_operand" "=&f")
6338	(mult:SF (match_dup 1) (match_dup 2)))]
6339  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6340    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6341          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6342  "#"
6343  [(set_attr "type" "fpmuldbl")
6344   (set_attr "length" "8")])
6345
6346(define_split
6347  [(set (match_operand:SF 0 "register_operand" "")
6348	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6349			 (match_operand:SF 2 "register_operand" ""))))
6350   (set (match_operand:SF 3 "register_operand" "")
6351	(mult:SF (match_dup 1) (match_dup 2)))]
6352  "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6353  [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6354   (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6355  "")
6356
6357;;- Shift instructions
6358
6359;; Optimized special case of shifting.
6360
6361(define_insn ""
6362  [(set (match_operand:SI 0 "register_operand" "=r")
6363	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6364		     (const_int 24)))]
6365  ""
6366  "ldb%M1 %1,%0"
6367  [(set_attr "type" "load")
6368   (set_attr "length" "4")])
6369
6370(define_insn ""
6371  [(set (match_operand:SI 0 "register_operand" "=r")
6372	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6373		     (const_int 16)))]
6374  ""
6375  "ldh%M1 %1,%0"
6376  [(set_attr "type" "load")
6377   (set_attr "length" "4")])
6378
6379(define_insn ""
6380  [(set (match_operand:SI 0 "register_operand" "=r")
6381	(plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6382			    (match_operand:SI 3 "shadd_operand" ""))
6383		 (match_operand:SI 1 "register_operand" "r")))]
6384  ""
6385  "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6386  [(set_attr "type" "binary")
6387   (set_attr "length" "4")])
6388
6389(define_insn ""
6390  [(set (match_operand:SI 0 "register_operand" "=r")
6391	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6392			  (match_operand:SI 3 "mem_shadd_operand" ""))
6393		 (match_operand:SI 1 "register_operand" "r")))]
6394  ""
6395  "*
6396{
6397  int shift_val = exact_log2 (INTVAL (operands[3]));
6398  operands[3] = GEN_INT (shift_val);
6399  return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6400}"
6401  [(set_attr "type" "binary")
6402   (set_attr "length" "4")])
6403
6404(define_insn ""
6405  [(set (match_operand:DI 0 "register_operand" "=r")
6406	(plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6407			    (match_operand:DI 3 "shadd_operand" ""))
6408		 (match_operand:DI 1 "register_operand" "r")))]
6409  "TARGET_64BIT"
6410  "shladd,l %2,%o3,%1,%0"
6411  [(set_attr "type" "binary")
6412   (set_attr "length" "4")])
6413
6414(define_insn ""
6415  [(set (match_operand:DI 0 "register_operand" "=r")
6416	(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6417			  (match_operand:DI 3 "mem_shadd_operand" ""))
6418		 (match_operand:DI 1 "register_operand" "r")))]
6419  "TARGET_64BIT"
6420  "*
6421{
6422  int shift_val = exact_log2 (INTVAL (operands[3]));
6423  operands[3] = GEN_INT (shift_val);
6424  return \"shladd,l %2,%o3,%1,%0\";
6425}"
6426  [(set_attr "type" "binary")
6427   (set_attr "length" "4")])
6428
6429(define_expand "ashlsi3"
6430  [(set (match_operand:SI 0 "register_operand" "")
6431	(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6432		   (match_operand:SI 2 "arith32_operand" "")))]
6433  ""
6434  "
6435{
6436  if (GET_CODE (operands[2]) != CONST_INT)
6437    {
6438      rtx temp = gen_reg_rtx (SImode);
6439      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6440      if (GET_CODE (operands[1]) == CONST_INT)
6441	emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6442      else
6443	emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6444      DONE;
6445    }
6446  /* Make sure both inputs are not constants,
6447     there are no patterns for that.  */
6448  operands[1] = force_reg (SImode, operands[1]);
6449}")
6450
6451(define_insn ""
6452  [(set (match_operand:SI 0 "register_operand" "=r")
6453	(ashift:SI (match_operand:SI 1 "register_operand" "r")
6454		   (match_operand:SI 2 "const_int_operand" "n")))]
6455  ""
6456  "{zdep|depw,z} %1,%P2,%L2,%0"
6457  [(set_attr "type" "shift")
6458   (set_attr "length" "4")])
6459
6460; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6461; Doing it like this makes slightly better code since reload can
6462; replace a register with a known value in range -16..15 with a
6463; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6464; but since we have no more CONST_OK... characters, that is not
6465; possible.
6466(define_insn "zvdep32"
6467  [(set (match_operand:SI 0 "register_operand" "=r,r")
6468	(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6469		   (minus:SI (const_int 31)
6470			     (match_operand:SI 2 "register_operand" "q,q"))))]
6471  ""
6472  "@
6473   {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6474   {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6475  [(set_attr "type" "shift,shift")
6476   (set_attr "length" "4,4")])
6477
6478(define_insn "zvdep_imm32"
6479  [(set (match_operand:SI 0 "register_operand" "=r")
6480	(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6481		   (minus:SI (const_int 31)
6482			     (match_operand:SI 2 "register_operand" "q"))))]
6483  ""
6484  "*
6485{
6486  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6487  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6488  operands[1] = GEN_INT ((x & 0xf) - 0x10);
6489  return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6490}"
6491  [(set_attr "type" "shift")
6492   (set_attr "length" "4")])
6493
6494(define_insn "vdepi_ior"
6495  [(set (match_operand:SI 0 "register_operand" "=r")
6496	(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6497			   (minus:SI (const_int 31)
6498				     (match_operand:SI 2 "register_operand" "q")))
6499		(match_operand:SI 3 "register_operand" "0")))]
6500  ; accept ...0001...1, can this be generalized?
6501  "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6502  "*
6503{
6504  HOST_WIDE_INT x = INTVAL (operands[1]);
6505  operands[2] = GEN_INT (exact_log2 (x + 1));
6506  return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6507}"
6508  [(set_attr "type" "shift")
6509   (set_attr "length" "4")])
6510
6511(define_insn "vdepi_and"
6512  [(set (match_operand:SI 0 "register_operand" "=r")
6513	(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6514			   (minus:SI (const_int 31)
6515				     (match_operand:SI 2 "register_operand" "q")))
6516		(match_operand:SI 3 "register_operand" "0")))]
6517  ; this can be generalized...!
6518  "INTVAL (operands[1]) == -2"
6519  "*
6520{
6521  HOST_WIDE_INT x = INTVAL (operands[1]);
6522  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6523  return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6524}"
6525  [(set_attr "type" "shift")
6526   (set_attr "length" "4")])
6527
6528(define_expand "ashldi3"
6529  [(set (match_operand:DI 0 "register_operand" "")
6530	(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6531		   (match_operand:DI 2 "arith32_operand" "")))]
6532  ""
6533  "
6534{
6535  if (!TARGET_64BIT)
6536    {
6537      if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6538	{
6539	  unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6540	  if (shift >= 1 && shift <= 31)
6541	    {
6542	      rtx dst = operands[0];
6543	      rtx src = force_reg (DImode, operands[1]);
6544	      emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6545					   gen_lowpart (SImode, src),
6546					   GEN_INT (32-shift),
6547					   gen_highpart (SImode, src),
6548					   GEN_INT (shift)));
6549	      emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6550				      gen_lowpart (SImode, src),
6551				      GEN_INT (shift)));
6552	      DONE;
6553	    }
6554	}
6555      /* Fallback to using optabs.c's expand_doubleword_shift.  */
6556      FAIL;
6557    }
6558  if (GET_CODE (operands[2]) != CONST_INT)
6559    {
6560      rtx temp = gen_reg_rtx (DImode);
6561      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6562      if (GET_CODE (operands[1]) == CONST_INT)
6563	emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6564      else
6565	emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6566      DONE;
6567    }
6568  /* Make sure both inputs are not constants,
6569     there are no patterns for that.  */
6570  operands[1] = force_reg (DImode, operands[1]);
6571}")
6572
6573(define_insn ""
6574  [(set (match_operand:DI 0 "register_operand" "=r")
6575	(ashift:DI (match_operand:DI 1 "register_operand" "r")
6576		   (match_operand:DI 2 "const_int_operand" "n")))]
6577  "TARGET_64BIT"
6578  "depd,z %1,%p2,%Q2,%0"
6579  [(set_attr "type" "shift")
6580   (set_attr "length" "4")])
6581
6582; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6583; Doing it like this makes slightly better code since reload can
6584; replace a register with a known value in range -16..15 with a
6585; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6586; but since we have no more CONST_OK... characters, that is not
6587; possible.
6588(define_insn "zvdep64"
6589  [(set (match_operand:DI 0 "register_operand" "=r,r")
6590	(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6591		   (minus:DI (const_int 63)
6592			     (match_operand:DI 2 "register_operand" "q,q"))))]
6593  "TARGET_64BIT"
6594  "@
6595   depd,z %1,%%sar,64,%0
6596   depdi,z %1,%%sar,64,%0"
6597  [(set_attr "type" "shift,shift")
6598   (set_attr "length" "4,4")])
6599
6600(define_insn "zvdep_imm64"
6601  [(set (match_operand:DI 0 "register_operand" "=r")
6602	(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6603		   (minus:DI (const_int 63)
6604			     (match_operand:DI 2 "register_operand" "q"))))]
6605  "TARGET_64BIT"
6606  "*
6607{
6608  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6609  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6610  operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6611  return \"depdi,z %1,%%sar,%2,%0\";
6612}"
6613  [(set_attr "type" "shift")
6614   (set_attr "length" "4")])
6615
6616(define_insn ""
6617  [(set (match_operand:DI 0 "register_operand" "=r")
6618	(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6619			   (minus:DI (const_int 63)
6620				     (match_operand:DI 2 "register_operand" "q")))
6621		(match_operand:DI 3 "register_operand" "0")))]
6622  ; accept ...0001...1, can this be generalized?
6623  "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6624  "*
6625{
6626  HOST_WIDE_INT x = INTVAL (operands[1]);
6627  operands[2] = GEN_INT (exact_log2 (x + 1));
6628  return \"depdi -1,%%sar,%2,%0\";
6629}"
6630  [(set_attr "type" "shift")
6631   (set_attr "length" "4")])
6632
6633(define_insn ""
6634  [(set (match_operand:DI 0 "register_operand" "=r")
6635	(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6636			   (minus:DI (const_int 63)
6637				     (match_operand:DI 2 "register_operand" "q")))
6638		(match_operand:DI 3 "register_operand" "0")))]
6639  ; this can be generalized...!
6640  "TARGET_64BIT && INTVAL (operands[1]) == -2"
6641  "*
6642{
6643  HOST_WIDE_INT x = INTVAL (operands[1]);
6644  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6645  return \"depdi 0,%%sar,%2,%0\";
6646}"
6647  [(set_attr "type" "shift")
6648   (set_attr "length" "4")])
6649
6650(define_expand "ashrsi3"
6651  [(set (match_operand:SI 0 "register_operand" "")
6652	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6653		     (match_operand:SI 2 "arith32_operand" "")))]
6654  ""
6655  "
6656{
6657  if (GET_CODE (operands[2]) != CONST_INT)
6658    {
6659      rtx temp = gen_reg_rtx (SImode);
6660      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6661      emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6662      DONE;
6663    }
6664}")
6665
6666(define_insn ""
6667  [(set (match_operand:SI 0 "register_operand" "=r")
6668	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6669		     (match_operand:SI 2 "const_int_operand" "n")))]
6670  ""
6671  "{extrs|extrw,s} %1,%P2,%L2,%0"
6672  [(set_attr "type" "shift")
6673   (set_attr "length" "4")])
6674
6675(define_insn "vextrs32"
6676  [(set (match_operand:SI 0 "register_operand" "=r")
6677	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6678		     (minus:SI (const_int 31)
6679			       (match_operand:SI 2 "register_operand" "q"))))]
6680  ""
6681  "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6682  [(set_attr "type" "shift")
6683   (set_attr "length" "4")])
6684
6685(define_expand "ashrdi3"
6686  [(set (match_operand:DI 0 "register_operand" "")
6687	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6688		     (match_operand:DI 2 "arith32_operand" "")))]
6689  "TARGET_64BIT"
6690  "
6691{
6692  if (GET_CODE (operands[2]) != CONST_INT)
6693    {
6694      rtx temp = gen_reg_rtx (DImode);
6695      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6696      emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6697      DONE;
6698    }
6699}")
6700
6701(define_insn ""
6702  [(set (match_operand:DI 0 "register_operand" "=r")
6703	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6704		     (match_operand:DI 2 "const_int_operand" "n")))]
6705  "TARGET_64BIT"
6706  "extrd,s %1,%p2,%Q2,%0"
6707  [(set_attr "type" "shift")
6708   (set_attr "length" "4")])
6709
6710(define_insn "vextrs64"
6711  [(set (match_operand:DI 0 "register_operand" "=r")
6712	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6713		     (minus:DI (const_int 63)
6714			       (match_operand:DI 2 "register_operand" "q"))))]
6715  "TARGET_64BIT"
6716  "extrd,s %1,%%sar,64,%0"
6717  [(set_attr "type" "shift")
6718   (set_attr "length" "4")])
6719
6720(define_insn "lshrsi3"
6721  [(set (match_operand:SI 0 "register_operand" "=r,r")
6722	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6723		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6724  ""
6725  "@
6726   {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6727   {extru|extrw,u} %1,%P2,%L2,%0"
6728  [(set_attr "type" "shift")
6729   (set_attr "length" "4")])
6730
6731(define_insn "lshrdi3"
6732  [(set (match_operand:DI 0 "register_operand" "=r,r")
6733	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6734		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6735  "TARGET_64BIT"
6736  "@
6737   shrpd %%r0,%1,%%sar,%0
6738   extrd,u %1,%p2,%Q2,%0"
6739  [(set_attr "type" "shift")
6740   (set_attr "length" "4")])
6741
6742; Shift right pair word 0 to 31 bits.
6743(define_insn "*shrpsi4_1"
6744  [(set (match_operand:SI 0 "register_operand" "=r")
6745	(match_operator:SI 4 "plus_xor_ior_operator"
6746	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6747		      (minus:SI (const_int 32)
6748				(match_operand:SI 3 "register_operand" "q")))
6749	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6750			(match_dup 3))]))]
6751  ""
6752  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6753  [(set_attr "type" "shift")
6754   (set_attr "length" "4")])
6755
6756(define_insn "*shrpsi4_2"
6757  [(set (match_operand:SI 0 "register_operand" "=r")
6758	(match_operator:SI 4 "plus_xor_ior_operator"
6759	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6760			(match_operand:SI 3 "register_operand" "q"))
6761	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6762		      (minus:SI (const_int 32)
6763				(match_dup 3)))]))]
6764  ""
6765  "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6766  [(set_attr "type" "shift")
6767   (set_attr "length" "4")])
6768
6769; Shift right pair doubleword 0 to 63 bits.
6770(define_insn "*shrpdi4_1"
6771  [(set (match_operand:DI 0 "register_operand" "=r")
6772	(match_operator:DI 4 "plus_xor_ior_operator"
6773	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6774		      (minus:DI (const_int 64)
6775				(match_operand:DI 3 "register_operand" "q")))
6776	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6777			(match_dup 3))]))]
6778  "TARGET_64BIT"
6779  "shrpd %1,%2,%%sar,%0"
6780  [(set_attr "type" "shift")
6781   (set_attr "length" "4")])
6782
6783(define_insn "*shrpdi4_2"
6784  [(set (match_operand:DI 0 "register_operand" "=r")
6785	(match_operator:DI 4 "plus_xor_ior_operator"
6786	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6787			(match_operand:DI 3 "shift6_operand" "q"))
6788	   (ashift:DI (match_operand:SI 1 "register_operand" "r")
6789		      (minus:DI (const_int 64)
6790				(match_dup 3)))]))]
6791  "TARGET_64BIT"
6792  "shrpd %1,%2,%%sar,%0"
6793  [(set_attr "type" "shift")
6794   (set_attr "length" "4")])
6795
6796(define_insn "*shrpdi4_3"
6797  [(set (match_operand:DI 0 "register_operand" "=r")
6798	(match_operator:DI 5 "plus_xor_ior_operator"
6799	  [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6800		      (match_operand:DI 3 "const_int_operand" "n"))
6801	   (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6802			(match_operand:DI 4 "const_int_operand" "n"))]))]
6803  "TARGET_64BIT
6804   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6805  "shrpd %1,%2,%4,%0"
6806  [(set_attr "type" "shift")
6807   (set_attr "length" "4")])
6808
6809(define_insn "*shrpdi4_4"
6810  [(set (match_operand:DI 0 "register_operand" "=r")
6811	(match_operator:DI 5 "plus_xor_ior_operator"
6812	  [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6813			(match_operand:DI 4 "const_int_operand" "n"))
6814	   (ashift:DI (match_operand:DI 1 "register_operand" "r")
6815		      (match_operand:DI 3 "const_int_operand" "n"))]))]
6816  "TARGET_64BIT
6817   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6818  "shrpd %1,%2,%4,%0"
6819  [(set_attr "type" "shift")
6820   (set_attr "length" "4")])
6821
6822(define_insn "rotrsi3"
6823  [(set (match_operand:SI 0 "register_operand" "=r,r")
6824	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6825		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6826  ""
6827  "*
6828{
6829  if (GET_CODE (operands[2]) == CONST_INT)
6830    {
6831      operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6832      return \"{shd|shrpw} %1,%1,%2,%0\";
6833    }
6834  else
6835    return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6836}"
6837  [(set_attr "type" "shift")
6838   (set_attr "length" "4")])
6839
6840(define_expand "rotlsi3"
6841  [(set (match_operand:SI 0 "register_operand" "")
6842        (rotate:SI (match_operand:SI 1 "register_operand" "")
6843                   (match_operand:SI 2 "arith32_operand" "")))]
6844  ""
6845  "
6846{
6847  if (GET_CODE (operands[2]) != CONST_INT)
6848    {
6849      rtx temp = gen_reg_rtx (SImode);
6850      emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6851      emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6852      DONE;
6853    }
6854  /* Else expand normally.  */
6855}")
6856
6857(define_insn "*rotlsi3_internal"
6858  [(set (match_operand:SI 0 "register_operand" "=r")
6859        (rotate:SI (match_operand:SI 1 "register_operand" "r")
6860                   (match_operand:SI 2 "const_int_operand" "n")))]
6861  ""
6862  "*
6863{
6864  operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6865  return \"{shd|shrpw} %1,%1,%2,%0\";
6866}"
6867  [(set_attr "type" "shift")
6868   (set_attr "length" "4")])
6869
6870(define_insn "rotrdi3"
6871  [(set (match_operand:DI 0 "register_operand" "=r,r")
6872	(rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
6873		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6874  "TARGET_64BIT"
6875  "*
6876{
6877  if (GET_CODE (operands[2]) == CONST_INT)
6878    {
6879      operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
6880      return \"shrpd %1,%1,%2,%0\";
6881    }
6882  else
6883    return \"shrpd %1,%1,%%sar,%0\";
6884}"
6885  [(set_attr "type" "shift")
6886   (set_attr "length" "4")])
6887
6888(define_expand "rotldi3"
6889  [(set (match_operand:DI 0 "register_operand" "")
6890        (rotate:DI (match_operand:DI 1 "register_operand" "")
6891                   (match_operand:DI 2 "arith32_operand" "")))]
6892  "TARGET_64BIT"
6893  "
6894{
6895  if (GET_CODE (operands[2]) != CONST_INT)
6896    {
6897      rtx temp = gen_reg_rtx (DImode);
6898      emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
6899      emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
6900      DONE;
6901    }
6902  /* Else expand normally.  */
6903}")
6904
6905(define_insn "*rotldi3_internal"
6906  [(set (match_operand:DI 0 "register_operand" "=r")
6907        (rotate:DI (match_operand:DI 1 "register_operand" "r")
6908                   (match_operand:DI 2 "const_int_operand" "n")))]
6909  "TARGET_64BIT"
6910  "*
6911{
6912  operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
6913  return \"shrpd %1,%1,%2,%0\";
6914}"
6915  [(set_attr "type" "shift")
6916   (set_attr "length" "4")])
6917
6918(define_insn ""
6919  [(set (match_operand:SI 0 "register_operand" "=r")
6920	(match_operator:SI 5 "plus_xor_ior_operator"
6921	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6922		      (match_operand:SI 3 "const_int_operand" "n"))
6923	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6924			(match_operand:SI 4 "const_int_operand" "n"))]))]
6925  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6926  "{shd|shrpw} %1,%2,%4,%0"
6927  [(set_attr "type" "shift")
6928   (set_attr "length" "4")])
6929
6930(define_insn ""
6931  [(set (match_operand:SI 0 "register_operand" "=r")
6932	(match_operator:SI 5 "plus_xor_ior_operator"
6933	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6934			(match_operand:SI 4 "const_int_operand" "n"))
6935	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6936		      (match_operand:SI 3 "const_int_operand" "n"))]))]
6937  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6938  "{shd|shrpw} %1,%2,%4,%0"
6939  [(set_attr "type" "shift")
6940   (set_attr "length" "4")])
6941
6942(define_expand "shd_internal"
6943  [(set (match_operand:SI 0 "register_operand")
6944	(ior:SI
6945	  (lshiftrt:SI (match_operand:SI 1 "register_operand")
6946		       (match_operand:SI 2 "const_int_operand"))
6947	  (ashift:SI (match_operand:SI 3 "register_operand")
6948		     (match_operand:SI 4 "const_int_operand"))))]
6949  "")
6950
6951(define_insn ""
6952  [(set (match_operand:SI 0 "register_operand" "=r")
6953	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6954			   (match_operand:SI 2 "const_int_operand" ""))
6955		(match_operand:SI 3 "const_int_operand" "")))]
6956  "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6957  "*
6958{
6959  int cnt = INTVAL (operands[2]) & 31;
6960  operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6961  operands[2] = GEN_INT (31 - cnt);
6962  return \"{zdep|depw,z} %1,%2,%3,%0\";
6963}"
6964  [(set_attr "type" "shift")
6965   (set_attr "length" "4")])
6966
6967;; Unconditional and other jump instructions.
6968
6969;; Trivial return used when no epilogue is needed.
6970(define_insn "return"
6971  [(return)
6972   (use (reg:SI 2))]
6973  "pa_can_use_return_insn ()"
6974  "*
6975{
6976  if (TARGET_PA_20)
6977    return \"bve%* (%%r2)\";
6978  return \"bv%* %%r0(%%r2)\";
6979}"
6980  [(set_attr "type" "branch")
6981   (set_attr "length" "4")])
6982
6983;; This is used for most returns.
6984(define_insn "return_internal"
6985  [(return)
6986   (use (reg:SI 2))]
6987  ""
6988  "*
6989{
6990  if (TARGET_PA_20)
6991    return \"bve%* (%%r2)\";
6992  return \"bv%* %%r0(%%r2)\";
6993}"
6994  [(set_attr "type" "branch")
6995   (set_attr "length" "4")])
6996
6997;; This is used for eh returns which bypass the return stub.
6998(define_insn "return_external_pic"
6999  [(return)
7000   (clobber (reg:SI 1))
7001   (use (reg:SI 2))]
7002  "!TARGET_NO_SPACE_REGS
7003   && !TARGET_PA_20
7004   && flag_pic && crtl->calls_eh_return"
7005  "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7006  [(set_attr "type" "branch")
7007   (set_attr "length" "12")])
7008
7009(define_expand "prologue"
7010  [(const_int 0)]
7011  ""
7012  "pa_expand_prologue ();DONE;")
7013
7014(define_expand "sibcall_epilogue"
7015  [(return)]
7016  ""
7017  "
7018{
7019  pa_expand_epilogue ();
7020  DONE;
7021}")
7022
7023(define_expand "epilogue"
7024  [(return)]
7025  ""
7026  "
7027{
7028  rtx x;
7029
7030  /* Try to use the trivial return first.  Else use the full epilogue.  */
7031  if (pa_can_use_return_insn ())
7032    x = gen_return ();
7033  else
7034    {
7035      pa_expand_epilogue ();
7036
7037      /* EH returns bypass the normal return stub.  Thus, we must do an
7038	 interspace branch to return from functions that call eh_return.
7039	 This is only a problem for returns from shared code on ports
7040	 using space registers.  */
7041      if (!TARGET_NO_SPACE_REGS
7042	  && !TARGET_PA_20
7043	  && flag_pic && crtl->calls_eh_return)
7044	x = gen_return_external_pic ();
7045      else
7046	x = gen_return_internal ();
7047    }
7048  emit_jump_insn (x);
7049  DONE;
7050}")
7051
7052; Used by hppa_profile_hook to load the starting address of the current
7053; function; operand 1 contains the address of the label in operand 3
7054(define_insn "load_offset_label_address"
7055  [(set (match_operand:SI 0 "register_operand" "=r")
7056        (plus:SI (match_operand:SI 1 "register_operand" "r")
7057		 (minus:SI (match_operand:SI 2 "" "")
7058			   (label_ref:SI (match_operand 3 "" "")))))]
7059  ""
7060  "ldo %2-%l3(%1),%0"
7061  [(set_attr "type" "multi")
7062   (set_attr "length" "4")])
7063
7064; Output a code label and load its address.
7065(define_insn "lcla1"
7066  [(set (match_operand:SI 0 "register_operand" "=r")
7067        (label_ref:SI (match_operand 1 "" "")))
7068   (const_int 0)]
7069  "!TARGET_PA_20"
7070  "*
7071{
7072  output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7073  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7074                                     CODE_LABEL_NUMBER (operands[1]));
7075  return \"\";
7076}"
7077  [(set_attr "type" "multi")
7078   (set_attr "length" "8")])
7079
7080(define_insn "lcla2"
7081  [(set (match_operand:SI 0 "register_operand" "=r")
7082        (label_ref:SI (match_operand 1 "" "")))
7083   (const_int 0)]
7084  "TARGET_PA_20"
7085  "*
7086{
7087  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7088                                     CODE_LABEL_NUMBER (operands[1]));
7089  return \"mfia %0\";
7090}"
7091  [(set_attr "type" "move")
7092   (set_attr "length" "4")])
7093
7094(define_insn "blockage"
7095  [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7096  ""
7097  ""
7098  [(set_attr "length" "0")])
7099
7100(define_insn "jump"
7101  [(set (pc) (label_ref (match_operand 0 "" "")))]
7102  ""
7103  "*
7104{
7105  /* An unconditional branch which can reach its target.  */
7106  if (get_attr_length (insn) < 16)
7107    return \"b%* %l0\";
7108
7109  return pa_output_lbranch (operands[0], insn, 1);
7110}"
7111  [(set_attr "type" "uncond_branch")
7112   (set_attr "pa_combine_type" "uncond_branch")
7113   (set (attr "length")
7114    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7115	       (const_int MAX_17BIT_OFFSET))
7116	   (const_int 4)
7117	   (match_test "TARGET_PORTABLE_RUNTIME")
7118	   (const_int 20)
7119	   (not (match_test "flag_pic"))
7120	   (const_int 16)]
7121	  (const_int 24)))])
7122
7123;;; Hope this is only within a function...
7124(define_insn "indirect_jump"
7125  [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7126  ""
7127  "bv%* %%r0(%0)"
7128  [(set_attr "type" "branch")
7129   (set_attr "length" "4")])
7130
7131;;; An indirect jump can be optimized to a direct jump.  GAS for the
7132;;; SOM target doesn't allow branching to a label inside a function.
7133;;; We also don't correctly compute branch distances for labels
7134;;; outside the current function.  Thus, we use an indirect jump can't
7135;;; be optimized to a direct jump for all targets.  We assume that
7136;;; the branch target is in the same space (i.e., nested function
7137;;; jumping to a label in an outer function in the same translation
7138;;; unit).
7139(define_expand "nonlocal_goto"
7140  [(use (match_operand 0 "general_operand" ""))
7141   (use (match_operand 1 "general_operand" ""))
7142   (use (match_operand 2 "general_operand" ""))
7143   (use (match_operand 3 "general_operand" ""))]
7144  ""
7145{
7146  rtx lab = operands[1];
7147  rtx stack = operands[2];
7148  rtx fp = operands[3];
7149
7150  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7151  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7152
7153  lab = copy_to_reg (lab);
7154
7155  /* Restore the stack and frame pointers.  */
7156  fp = copy_to_reg (fp);
7157  emit_stack_restore (SAVE_NONLOCAL, stack);
7158
7159  /* Ensure the frame pointer move is not optimized.  */
7160  emit_insn (gen_blockage ());
7161  emit_clobber (hard_frame_pointer_rtx);
7162  emit_clobber (frame_pointer_rtx);
7163  emit_move_insn (hard_frame_pointer_rtx, fp);
7164
7165  emit_use (hard_frame_pointer_rtx);
7166  emit_use (stack_pointer_rtx);
7167
7168  /* Nonlocal goto jumps are only used between functions in the same
7169     translation unit.  Thus, we can avoid the extra overhead of an
7170     interspace jump.  */
7171  emit_jump_insn (gen_indirect_goto (lab));
7172  emit_barrier ();
7173  DONE;
7174})
7175
7176(define_insn "indirect_goto"
7177  [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7178  "GET_MODE (operands[0]) == word_mode"
7179  "bv%* %%r0(%0)"
7180  [(set_attr "type" "branch")
7181   (set_attr "length" "4")])
7182
7183;; Subroutines of "casesi".
7184;; operand 0 is index
7185;; operand 1 is the minimum bound
7186;; operand 2 is the maximum bound - minimum bound + 1
7187;; operand 3 is CODE_LABEL for the table;
7188;; operand 4 is the CODE_LABEL to go to if index out of range.
7189
7190(define_expand "casesi"
7191  [(match_operand:SI 0 "general_operand" "")
7192   (match_operand:SI 1 "const_int_operand" "")
7193   (match_operand:SI 2 "const_int_operand" "")
7194   (match_operand 3 "" "")
7195   (match_operand 4 "" "")]
7196  ""
7197  "
7198{
7199  if (GET_CODE (operands[0]) != REG)
7200    operands[0] = force_reg (SImode, operands[0]);
7201
7202  if (operands[1] != const0_rtx)
7203    {
7204      rtx index = gen_reg_rtx (SImode);
7205
7206      operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7207      if (!INT_14_BITS (operands[1]))
7208	operands[1] = force_reg (SImode, operands[1]);
7209      emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7210      operands[0] = index;
7211    }
7212
7213  if (!INT_5_BITS (operands[2]))
7214    operands[2] = force_reg (SImode, operands[2]);
7215
7216  /* This branch prevents us finding an insn for the delay slot of the
7217     following vectored branch.  It might be possible to use the delay
7218     slot if an index value of -1 was used to transfer to the out-of-range
7219     label.  In order to do this, we would have to output the -1 vector
7220     element after the delay insn.  The casesi output code would have to
7221     check if the casesi insn is in a delay branch sequence and output
7222     the delay insn if one is found.  If this was done, then it might
7223     then be worthwhile to split the casesi patterns to improve scheduling.
7224     However, it's not clear that all this extra complexity is worth
7225     the effort.  */
7226  {
7227    rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7228    emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7229  }
7230
7231  /* In 64bit mode we must make sure to wipe the upper bits of the register
7232     just in case the addition overflowed or we had random bits in the
7233     high part of the register.  */
7234  if (TARGET_64BIT)
7235    {
7236      rtx index = gen_reg_rtx (DImode);
7237
7238      emit_insn (gen_extendsidi2 (index, operands[0]));
7239      operands[0] = index;
7240    }
7241
7242  if (TARGET_64BIT)
7243    emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7244  else if (flag_pic)
7245    emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7246  else
7247    emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7248  DONE;
7249}")
7250
7251;;; 32-bit code, absolute branch table.
7252(define_insn "casesi32"
7253  [(set (pc) (mem:SI (plus:SI
7254		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7255				(const_int 4))
7256		       (label_ref (match_operand 1 "" "")))))
7257   (clobber (match_scratch:SI 2 "=&r"))]
7258  "!flag_pic"
7259  "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7260  [(set_attr "type" "multi")
7261   (set_attr "length" "16")])
7262
7263;;; 32-bit code, relative branch table.
7264(define_insn "casesi32p"
7265  [(set (pc) (mem:SI (plus:SI
7266		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7267				(const_int 4))
7268		       (label_ref (match_operand 1 "" "")))))
7269   (clobber (match_scratch:SI 2 "=&r"))
7270   (clobber (match_scratch:SI 3 "=&r"))]
7271  "flag_pic"
7272  "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7273{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7274  [(set_attr "type" "multi")
7275   (set (attr "length")
7276     (if_then_else (match_test "TARGET_PA_20")
7277	(const_int 20)
7278	(const_int 24)))])
7279
7280;;; 64-bit code, 32-bit relative branch table.
7281(define_insn "casesi64p"
7282  [(set (pc) (mem:DI (plus:DI
7283		       (mult:DI (match_operand:DI 0 "register_operand" "r")
7284				(const_int 8))
7285		       (label_ref (match_operand 1 "" "")))))
7286   (clobber (match_scratch:DI 2 "=&r"))
7287   (clobber (match_scratch:DI 3 "=&r"))]
7288  ""
7289  "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7290add,l %2,%3,%3\;bv,n %%r0(%3)"
7291  [(set_attr "type" "multi")
7292   (set_attr "length" "24")])
7293
7294
7295;; Call patterns.
7296;;- jump to subroutine
7297
7298(define_expand "call"
7299  [(parallel [(call (match_operand:SI 0 "" "")
7300		    (match_operand 1 "" ""))
7301	      (clobber (reg:SI 2))])]
7302  ""
7303  "
7304{
7305  rtx op;
7306  rtx nb = operands[1];
7307
7308  if (TARGET_PORTABLE_RUNTIME)
7309    op = force_reg (SImode, XEXP (operands[0], 0));
7310  else
7311    {
7312      op = XEXP (operands[0], 0);
7313
7314      /* Generate indirect long calls to non-local functions. */
7315      if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7316	{
7317	  tree call_decl = SYMBOL_REF_DECL (op);
7318	  if (!(call_decl && targetm.binds_local_p (call_decl)))
7319	    op = force_reg (word_mode, op);
7320	}
7321    }
7322
7323  if (TARGET_64BIT)
7324    {
7325      if (!virtuals_instantiated)
7326	emit_move_insn (arg_pointer_rtx,
7327			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7328				      GEN_INT (64)));
7329      else
7330	{
7331	  /* The loop pass can generate new libcalls after the virtual
7332	     registers are instantiated when fpregs are disabled because
7333	     the only method that we have for doing DImode multiplication
7334	     is with a libcall.  This could be trouble if we haven't
7335	     allocated enough space for the outgoing arguments.  */
7336	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7337
7338	  emit_move_insn (arg_pointer_rtx,
7339			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7340					GEN_INT (STACK_POINTER_OFFSET + 64)));
7341	}
7342    }
7343
7344  /* Use two different patterns for calls to explicitly named functions
7345     and calls through function pointers.  This is necessary as these two
7346     types of calls use different calling conventions, and CSE might try
7347     to change the named call into an indirect call in some cases (using
7348     two patterns keeps CSE from performing this optimization).
7349
7350     We now use even more call patterns as there was a subtle bug in
7351     attempting to restore the pic register after a call using a simple
7352     move insn.  During reload, a instruction involving a pseudo register
7353     with no explicit dependence on the PIC register can be converted
7354     to an equivalent load from memory using the PIC register.  If we
7355     emit a simple move to restore the PIC register in the initial rtl
7356     generation, then it can potentially be repositioned during scheduling.
7357     and an instruction that eventually uses the PIC register may end up
7358     between the call and the PIC register restore.
7359
7360     This only worked because there is a post call group of instructions
7361     that are scheduled with the call.  These instructions are included
7362     in the same basic block as the call.  However, calls can throw in
7363     C++ code and a basic block has to terminate at the call if the call
7364     can throw.  This results in the PIC register restore being scheduled
7365     independently from the call.  So, we now hide the save and restore
7366     of the PIC register in the call pattern until after reload.  Then,
7367     we split the moves out.  A small side benefit is that we now don't
7368     need to have a use of the PIC register in the return pattern and
7369     the final save/restore operation is not needed.
7370
7371     I elected to just use register %r4 in the PIC patterns instead
7372     of trying to force hppa_pic_save_rtx () to a callee saved register.
7373     This might have required a new register class and constraint.  It
7374     was also simpler to just handle the restore from a register than a
7375     generic pseudo.  */
7376  if (TARGET_64BIT)
7377    {
7378      rtx r4 = gen_rtx_REG (word_mode, 4);
7379      if (GET_CODE (op) == SYMBOL_REF)
7380	emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7381      else
7382	{
7383	  op = force_reg (word_mode, op);
7384	  emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7385	}
7386    }
7387  else
7388    {
7389      if (GET_CODE (op) == SYMBOL_REF)
7390	{
7391	  if (flag_pic)
7392	    {
7393	      rtx r4 = gen_rtx_REG (word_mode, 4);
7394	      emit_call_insn (gen_call_symref_pic (op, nb, r4));
7395	    }
7396	  else
7397	    emit_call_insn (gen_call_symref (op, nb));
7398	}
7399      else
7400	{
7401	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7402	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7403	  if (flag_pic)
7404	    {
7405	      rtx r4 = gen_rtx_REG (word_mode, 4);
7406	      emit_call_insn (gen_call_reg_pic (nb, r4));
7407	    }
7408	  else
7409	    emit_call_insn (gen_call_reg (nb));
7410	}
7411    }
7412
7413  DONE;
7414}")
7415
7416;; We use function calls to set the attribute length of calls and millicode
7417;; calls.  This is necessary because of the large variety of call sequences.
7418;; Implementing the calculation in rtl is difficult as well as ugly.  As
7419;; we need the same calculation in several places, maintenance becomes a
7420;; nightmare.
7421;;
7422;; However, this has a subtle impact on branch shortening.  When the
7423;; expression used to set the length attribute of an instruction depends
7424;; on a relative address (e.g., pc or a branch address), genattrtab
7425;; notes that the insn's length is variable, and attempts to determine a
7426;; worst-case default length and code to compute an insn's current length.
7427
7428;; The use of a function call hides the variable dependence of our calls
7429;; and millicode calls.  The result is genattrtab doesn't treat the operation
7430;; as variable and it only generates code for the default case using our
7431;; function call.  Because of this, calls and millicode calls have a fixed
7432;; length in the branch shortening pass, and some branches will use a longer
7433;; code sequence than necessary.  However, the length of any given call
7434;; will still reflect its final code location and it may be shorter than
7435;; the initial length estimate.
7436
7437;; It's possible to trick genattrtab by adding an expression involving `pc'
7438;; in the set.  However, when genattrtab hits a function call in its attempt
7439;; to compute the default length, it marks the result as unknown and sets
7440;; the default result to MAX_INT ;-(  One possible fix that would allow
7441;; calls to participate in branch shortening would be to make the call to
7442;; insn_default_length a target option.  Then, we could massage unknown
7443;; results.  Another fix might be to change genattrtab so that it just does
7444;; the call in the variable case as it already does for the fixed case.
7445
7446(define_insn "call_symref"
7447  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7448	 (match_operand 1 "" "i"))
7449   (clobber (reg:SI 1))
7450   (clobber (reg:SI 2))
7451   (use (const_int 0))]
7452  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7453  "*
7454{
7455  pa_output_arg_descriptor (insn);
7456  return pa_output_call (insn, operands[0], 0);
7457}"
7458  [(set_attr "type" "call")
7459   (set (attr "length")
7460	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7461	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7462
7463(define_insn "call_symref_pic"
7464  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7465	 (match_operand 1 "" "i"))
7466   (clobber (reg:SI 1))
7467   (clobber (reg:SI 2))
7468   (clobber (match_operand 2))
7469   (use (reg:SI 19))
7470   (use (const_int 0))]
7471  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7472  "#")
7473
7474;; Split out the PIC register save and restore after reload.  As the
7475;; split is done after reload, there are some situations in which we
7476;; unnecessarily save and restore %r4.  This happens when there is a
7477;; single call and the PIC register is not used after the call.
7478;;
7479;; The split has to be done since call_from_call_insn () can't handle
7480;; the pattern as is.  Noreturn calls are special because they have to
7481;; terminate the basic block.  The split has to contain more than one
7482;; insn.
7483(define_split
7484  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7485		    (match_operand 1 "" ""))
7486	      (clobber (reg:SI 1))
7487	      (clobber (reg:SI 2))
7488	      (clobber (match_operand 2))
7489	      (use (reg:SI 19))
7490	      (use (const_int 0))])]
7491  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7492   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7493  [(set (match_dup 2) (reg:SI 19))
7494   (parallel [(call (mem:SI (match_dup 0))
7495		    (match_dup 1))
7496	      (clobber (reg:SI 1))
7497	      (clobber (reg:SI 2))
7498	      (use (reg:SI 19))
7499	      (use (const_int 0))])]
7500  "")
7501
7502(define_split
7503  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7504		    (match_operand 1 "" ""))
7505	      (clobber (reg:SI 1))
7506	      (clobber (reg:SI 2))
7507	      (clobber (match_operand 2))
7508	      (use (reg:SI 19))
7509	      (use (const_int 0))])]
7510  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7511  [(set (match_dup 2) (reg:SI 19))
7512   (parallel [(call (mem:SI (match_dup 0))
7513		    (match_dup 1))
7514	      (clobber (reg:SI 1))
7515	      (clobber (reg:SI 2))
7516	      (use (reg:SI 19))
7517	      (use (const_int 0))])
7518   (set (reg:SI 19) (match_dup 2))]
7519  "")
7520
7521(define_insn "*call_symref_pic_post_reload"
7522  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7523	 (match_operand 1 "" "i"))
7524   (clobber (reg:SI 1))
7525   (clobber (reg:SI 2))
7526   (use (reg:SI 19))
7527   (use (const_int 0))]
7528  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7529  "*
7530{
7531  pa_output_arg_descriptor (insn);
7532  return pa_output_call (insn, operands[0], 0);
7533}"
7534  [(set_attr "type" "call")
7535   (set (attr "length")
7536	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7537	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7538
7539;; This pattern is split if it is necessary to save and restore the
7540;; PIC register.
7541(define_insn "call_symref_64bit"
7542  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7543	 (match_operand 1 "" "i"))
7544   (clobber (reg:DI 1))
7545   (clobber (reg:DI 2))
7546   (clobber (match_operand 2))
7547   (use (reg:DI 27))
7548   (use (reg:DI 29))
7549   (use (const_int 0))]
7550  "TARGET_64BIT"
7551  "#")
7552
7553;; Split out the PIC register save and restore after reload.  As the
7554;; split is done after reload, there are some situations in which we
7555;; unnecessarily save and restore %r4.  This happens when there is a
7556;; single call and the PIC register is not used after the call.
7557;;
7558;; The split has to be done since call_from_call_insn () can't handle
7559;; the pattern as is.  Noreturn calls are special because they have to
7560;; terminate the basic block.  The split has to contain more than one
7561;; insn.
7562(define_split
7563  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7564		    (match_operand 1 "" ""))
7565	      (clobber (reg:DI 1))
7566	      (clobber (reg:DI 2))
7567	      (clobber (match_operand 2))
7568	      (use (reg:DI 27))
7569	      (use (reg:DI 29))
7570	      (use (const_int 0))])]
7571  "TARGET_64BIT && reload_completed
7572   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7573  [(set (match_dup 2) (reg:DI 27))
7574   (parallel [(call (mem:SI (match_dup 0))
7575		    (match_dup 1))
7576	      (clobber (reg:DI 1))
7577	      (clobber (reg:DI 2))
7578	      (use (reg:DI 27))
7579	      (use (reg:DI 29))
7580	      (use (const_int 0))])]
7581  "")
7582
7583(define_split
7584  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7585		    (match_operand 1 "" ""))
7586	      (clobber (reg:DI 1))
7587	      (clobber (reg:DI 2))
7588	      (clobber (match_operand 2))
7589	      (use (reg:DI 27))
7590	      (use (reg:DI 29))
7591	      (use (const_int 0))])]
7592  "TARGET_64BIT && reload_completed"
7593  [(set (match_dup 2) (reg:DI 27))
7594   (parallel [(call (mem:SI (match_dup 0))
7595		    (match_dup 1))
7596	      (clobber (reg:DI 1))
7597	      (clobber (reg:DI 2))
7598	      (use (reg:DI 27))
7599	      (use (reg:DI 29))
7600	      (use (const_int 0))])
7601   (set (reg:DI 27) (match_dup 2))]
7602  "")
7603
7604(define_insn "*call_symref_64bit_post_reload"
7605  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7606	 (match_operand 1 "" "i"))
7607   (clobber (reg:DI 1))
7608   (clobber (reg:DI 2))
7609   (use (reg:DI 27))
7610   (use (reg:DI 29))
7611   (use (const_int 0))]
7612  "TARGET_64BIT"
7613  "*
7614{
7615  return pa_output_call (insn, operands[0], 0);
7616}"
7617  [(set_attr "type" "call")
7618   (set (attr "length")
7619	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7620	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7621
7622(define_insn "call_reg"
7623  [(call (mem:SI (reg:SI 22))
7624	 (match_operand 0 "" "i"))
7625   (clobber (reg:SI 1))
7626   (clobber (reg:SI 2))
7627   (use (const_int 1))]
7628  "!TARGET_64BIT"
7629  "*
7630{
7631  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7632}"
7633  [(set_attr "type" "dyncall")
7634   (set (attr "length")
7635	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7636	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7637
7638;; This pattern is split if it is necessary to save and restore the
7639;; PIC register.
7640(define_insn "call_reg_pic"
7641  [(call (mem:SI (reg:SI 22))
7642	 (match_operand 0 "" "i"))
7643   (clobber (reg:SI 1))
7644   (clobber (reg:SI 2))
7645   (clobber (match_operand 1))
7646   (use (reg:SI 19))
7647   (use (const_int 1))]
7648  "!TARGET_64BIT"
7649  "#")
7650
7651;; Split out the PIC register save and restore after reload.  As the
7652;; split is done after reload, there are some situations in which we
7653;; unnecessarily save and restore %r4.  This happens when there is a
7654;; single call and the PIC register is not used after the call.
7655;;
7656;; The split has to be done since call_from_call_insn () can't handle
7657;; the pattern as is.  Noreturn calls are special because they have to
7658;; terminate the basic block.  The split has to contain more than one
7659;; insn.
7660(define_split
7661  [(parallel [(call (mem:SI (reg:SI 22))
7662		    (match_operand 0 "" ""))
7663	      (clobber (reg:SI 1))
7664	      (clobber (reg:SI 2))
7665	      (clobber (match_operand 1))
7666	      (use (reg:SI 19))
7667	      (use (const_int 1))])]
7668  "!TARGET_64BIT && reload_completed
7669   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7670  [(set (match_dup 1) (reg:SI 19))
7671   (parallel [(call (mem:SI (reg:SI 22))
7672		    (match_dup 0))
7673	      (clobber (reg:SI 1))
7674	      (clobber (reg:SI 2))
7675	      (use (reg:SI 19))
7676	      (use (const_int 1))])]
7677  "")
7678
7679(define_split
7680  [(parallel [(call (mem:SI (reg:SI 22))
7681		    (match_operand 0 "" ""))
7682	      (clobber (reg:SI 1))
7683	      (clobber (reg:SI 2))
7684	      (clobber (match_operand 1))
7685	      (use (reg:SI 19))
7686	      (use (const_int 1))])]
7687  "!TARGET_64BIT && reload_completed"
7688  [(set (match_dup 1) (reg:SI 19))
7689   (parallel [(call (mem:SI (reg:SI 22))
7690		    (match_dup 0))
7691	      (clobber (reg:SI 1))
7692	      (clobber (reg:SI 2))
7693	      (use (reg:SI 19))
7694	      (use (const_int 1))])
7695   (set (reg:SI 19) (match_dup 1))]
7696  "")
7697
7698(define_insn "*call_reg_pic_post_reload"
7699  [(call (mem:SI (reg:SI 22))
7700	 (match_operand 0 "" "i"))
7701   (clobber (reg:SI 1))
7702   (clobber (reg:SI 2))
7703   (use (reg:SI 19))
7704   (use (const_int 1))]
7705  "!TARGET_64BIT"
7706  "*
7707{
7708  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7709}"
7710  [(set_attr "type" "dyncall")
7711   (set (attr "length")
7712	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7713	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7714
7715;; This pattern is split if it is necessary to save and restore the
7716;; PIC register.
7717(define_insn "call_reg_64bit"
7718  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7719	 (match_operand 1 "" "i"))
7720   (clobber (reg:DI 2))
7721   (clobber (match_operand 2))
7722   (use (reg:DI 27))
7723   (use (reg:DI 29))
7724   (use (const_int 1))]
7725  "TARGET_64BIT"
7726  "#")
7727
7728;; Split out the PIC register save and restore after reload.  As the
7729;; split is done after reload, there are some situations in which we
7730;; unnecessarily save and restore %r4.  This happens when there is a
7731;; single call and the PIC register is not used after the call.
7732;;
7733;; The split has to be done since call_from_call_insn () can't handle
7734;; the pattern as is.  Noreturn calls are special because they have to
7735;; terminate the basic block.  The split has to contain more than one
7736;; insn.
7737(define_split
7738  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7739		    (match_operand 1 "" ""))
7740	      (clobber (reg:DI 2))
7741	      (clobber (match_operand 2))
7742	      (use (reg:DI 27))
7743	      (use (reg:DI 29))
7744	      (use (const_int 1))])]
7745  "TARGET_64BIT && reload_completed
7746   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7747  [(set (match_dup 2) (reg:DI 27))
7748   (parallel [(call (mem:SI (match_dup 0))
7749		    (match_dup 1))
7750	      (clobber (reg:DI 2))
7751	      (use (reg:DI 27))
7752	      (use (reg:DI 29))
7753	      (use (const_int 1))])]
7754  "")
7755
7756(define_split
7757  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7758		    (match_operand 1 "" ""))
7759	      (clobber (reg:DI 2))
7760	      (clobber (match_operand 2))
7761	      (use (reg:DI 27))
7762	      (use (reg:DI 29))
7763	      (use (const_int 1))])]
7764  "TARGET_64BIT && reload_completed"
7765  [(set (match_dup 2) (reg:DI 27))
7766   (parallel [(call (mem:SI (match_dup 0))
7767		    (match_dup 1))
7768	      (clobber (reg:DI 2))
7769	      (use (reg:DI 27))
7770	      (use (reg:DI 29))
7771	      (use (const_int 1))])
7772   (set (reg:DI 27) (match_dup 2))]
7773  "")
7774
7775(define_insn "*call_reg_64bit_post_reload"
7776  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7777	 (match_operand 1 "" "i"))
7778   (clobber (reg:DI 2))
7779   (use (reg:DI 27))
7780   (use (reg:DI 29))
7781   (use (const_int 1))]
7782  "TARGET_64BIT"
7783  "*
7784{
7785  return pa_output_indirect_call (insn, operands[0]);
7786}"
7787  [(set_attr "type" "dyncall")
7788   (set (attr "length")
7789	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7790	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7791
7792(define_expand "call_value"
7793  [(parallel [(set (match_operand 0 "" "")
7794		   (call (match_operand:SI 1 "" "")
7795			 (match_operand 2 "" "")))
7796	      (clobber (reg:SI 2))])]
7797  ""
7798{
7799  rtx op;
7800  rtx dst = operands[0];
7801  rtx nb = operands[2];
7802  bool call_powf = false;
7803
7804  if (TARGET_PORTABLE_RUNTIME)
7805    op = force_reg (SImode, XEXP (operands[1], 0));
7806  else
7807    {
7808      op = XEXP (operands[1], 0);
7809      if (GET_CODE (op) == SYMBOL_REF)
7810	{
7811	  /* Handle special call to buggy powf function.  */
7812	  if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
7813	      && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7814	    call_powf = true;
7815
7816	  /* Generate indirect long calls to non-local functions. */
7817	  else if (TARGET_LONG_CALLS)
7818	    {
7819	      tree call_decl = SYMBOL_REF_DECL (op);
7820	      if (!(call_decl && targetm.binds_local_p (call_decl)))
7821		op = force_reg (word_mode, op);
7822	    }
7823	}
7824    }
7825
7826  if (TARGET_64BIT)
7827    {
7828      if (!virtuals_instantiated)
7829	emit_move_insn (arg_pointer_rtx,
7830			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7831				      GEN_INT (64)));
7832      else
7833	{
7834	  /* The loop pass can generate new libcalls after the virtual
7835	     registers are instantiated when fpregs are disabled because
7836	     the only method that we have for doing DImode multiplication
7837	     is with a libcall.  This could be trouble if we haven't
7838	     allocated enough space for the outgoing arguments.  */
7839	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7840
7841	  emit_move_insn (arg_pointer_rtx,
7842			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7843					GEN_INT (STACK_POINTER_OFFSET + 64)));
7844	}
7845    }
7846
7847  /* Use two different patterns for calls to explicitly named functions
7848     and calls through function pointers.  This is necessary as these two
7849     types of calls use different calling conventions, and CSE might try
7850     to change the named call into an indirect call in some cases (using
7851     two patterns keeps CSE from performing this optimization).
7852
7853     We now use even more call patterns as there was a subtle bug in
7854     attempting to restore the pic register after a call using a simple
7855     move insn.  During reload, a instruction involving a pseudo register
7856     with no explicit dependence on the PIC register can be converted
7857     to an equivalent load from memory using the PIC register.  If we
7858     emit a simple move to restore the PIC register in the initial rtl
7859     generation, then it can potentially be repositioned during scheduling.
7860     and an instruction that eventually uses the PIC register may end up
7861     between the call and the PIC register restore.
7862
7863     This only worked because there is a post call group of instructions
7864     that are scheduled with the call.  These instructions are included
7865     in the same basic block as the call.  However, calls can throw in
7866     C++ code and a basic block has to terminate at the call if the call
7867     can throw.  This results in the PIC register restore being scheduled
7868     independently from the call.  So, we now hide the save and restore
7869     of the PIC register in the call pattern until after reload.  Then,
7870     we split the moves out.  A small side benefit is that we now don't
7871     need to have a use of the PIC register in the return pattern and
7872     the final save/restore operation is not needed.
7873
7874     I elected to just use register %r4 in the PIC patterns instead
7875     of trying to force hppa_pic_save_rtx () to a callee saved register.
7876     This might have required a new register class and constraint.  It
7877     was also simpler to just handle the restore from a register than a
7878     generic pseudo.  */
7879  if (TARGET_64BIT)
7880    {
7881      rtx r4 = gen_rtx_REG (word_mode, 4);
7882      if (GET_CODE (op) == SYMBOL_REF)
7883	{
7884	  if (call_powf)
7885	    emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
7886	  else
7887	    emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7888	}
7889      else
7890	{
7891	  op = force_reg (word_mode, op);
7892	  emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7893	}
7894    }
7895  else
7896    {
7897      if (GET_CODE (op) == SYMBOL_REF)
7898	{
7899	  if (flag_pic)
7900	    {
7901	      rtx r4 = gen_rtx_REG (word_mode, 4);
7902
7903	      if (call_powf)
7904		emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
7905	      else
7906		emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7907	    }
7908	  else
7909	    {
7910	      if (call_powf)
7911		emit_call_insn (gen_call_val_powf (dst, op, nb));
7912	      else
7913		emit_call_insn (gen_call_val_symref (dst, op, nb));
7914	    }
7915	}
7916      else
7917	{
7918	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7919	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7920	  if (flag_pic)
7921	    {
7922	      rtx r4 = gen_rtx_REG (word_mode, 4);
7923	      emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7924	    }
7925	  else
7926	    emit_call_insn (gen_call_val_reg (dst, nb));
7927	}
7928    }
7929
7930  DONE;
7931})
7932
7933(define_insn "call_val_symref"
7934  [(set (match_operand 0 "" "")
7935	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7936	      (match_operand 2 "" "i")))
7937   (clobber (reg:SI 1))
7938   (clobber (reg:SI 2))
7939   (use (const_int 0))]
7940  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7941  "*
7942{
7943  pa_output_arg_descriptor (insn);
7944  return pa_output_call (insn, operands[1], 0);
7945}"
7946  [(set_attr "type" "call")
7947   (set (attr "length")
7948	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7949	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7950
7951;; powf function clobbers %fr12
7952(define_insn "call_val_powf"
7953  [(set (match_operand 0 "" "")
7954	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7955	      (match_operand 2 "" "i")))
7956   (clobber (reg:SI 1))
7957   (clobber (reg:SI 2))
7958   (clobber (reg:DF 48))
7959   (use (const_int 1))]
7960  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7961  "*
7962{
7963  pa_output_arg_descriptor (insn);
7964  return pa_output_call (insn, operands[1], 0);
7965}"
7966  [(set_attr "type" "call")
7967   (set (attr "length")
7968	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7969	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7970
7971(define_insn "call_val_symref_pic"
7972  [(set (match_operand 0 "" "")
7973	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7974	      (match_operand 2 "" "i")))
7975   (clobber (reg:SI 1))
7976   (clobber (reg:SI 2))
7977   (clobber (match_operand 3))
7978   (use (reg:SI 19))
7979   (use (const_int 0))]
7980  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7981  "#")
7982
7983;; Split out the PIC register save and restore after reload.  As the
7984;; split is done after reload, there are some situations in which we
7985;; unnecessarily save and restore %r4.  This happens when there is a
7986;; single call and the PIC register is not used after the call.
7987;;
7988;; The split has to be done since call_from_call_insn () can't handle
7989;; the pattern as is.  Noreturn calls are special because they have to
7990;; terminate the basic block.  The split has to contain more than one
7991;; insn.
7992(define_split
7993  [(parallel [(set (match_operand 0 "" "")
7994	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7995		    (match_operand 2 "" "")))
7996	      (clobber (reg:SI 1))
7997	      (clobber (reg:SI 2))
7998	      (clobber (match_operand 3))
7999	      (use (reg:SI 19))
8000	      (use (const_int 0))])]
8001  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8002   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8003  [(set (match_dup 3) (reg:SI 19))
8004   (parallel [(set (match_dup 0)
8005	      (call (mem:SI (match_dup 1))
8006		    (match_dup 2)))
8007	      (clobber (reg:SI 1))
8008	      (clobber (reg:SI 2))
8009	      (use (reg:SI 19))
8010	      (use (const_int 0))])]
8011  "")
8012
8013(define_split
8014  [(parallel [(set (match_operand 0 "" "")
8015	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8016		    (match_operand 2 "" "")))
8017	      (clobber (reg:SI 1))
8018	      (clobber (reg:SI 2))
8019	      (clobber (match_operand 3))
8020	      (use (reg:SI 19))
8021	      (use (const_int 0))])]
8022  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8023  [(set (match_dup 3) (reg:SI 19))
8024   (parallel [(set (match_dup 0)
8025	      (call (mem:SI (match_dup 1))
8026		    (match_dup 2)))
8027	      (clobber (reg:SI 1))
8028	      (clobber (reg:SI 2))
8029	      (use (reg:SI 19))
8030	      (use (const_int 0))])
8031   (set (reg:SI 19) (match_dup 3))]
8032  "")
8033
8034(define_insn "*call_val_symref_pic_post_reload"
8035  [(set (match_operand 0 "" "")
8036	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8037	      (match_operand 2 "" "i")))
8038   (clobber (reg:SI 1))
8039   (clobber (reg:SI 2))
8040   (use (reg:SI 19))
8041   (use (const_int 0))]
8042  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8043  "*
8044{
8045  pa_output_arg_descriptor (insn);
8046  return pa_output_call (insn, operands[1], 0);
8047}"
8048  [(set_attr "type" "call")
8049   (set (attr "length")
8050	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8051	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8052
8053;; powf function clobbers %fr12
8054(define_insn "call_val_powf_pic"
8055  [(set (match_operand 0 "" "")
8056	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8057	      (match_operand 2 "" "i")))
8058   (clobber (reg:SI 1))
8059   (clobber (reg:SI 2))
8060   (clobber (reg:DF 48))
8061   (clobber (match_operand 3))
8062   (use (reg:SI 19))
8063   (use (const_int 1))]
8064  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8065  "#")
8066
8067;; Split out the PIC register save and restore after reload.  As the
8068;; split is done after reload, there are some situations in which we
8069;; unnecessarily save and restore %r4.  This happens when there is a
8070;; single call and the PIC register is not used after the call.
8071;;
8072;; The split has to be done since call_from_call_insn () can't handle
8073;; the pattern as is.  Noreturn calls are special because they have to
8074;; terminate the basic block.  The split has to contain more than one
8075;; insn.
8076(define_split
8077  [(parallel [(set (match_operand 0 "" "")
8078	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8079		    (match_operand 2 "" "")))
8080	      (clobber (reg:SI 1))
8081	      (clobber (reg:SI 2))
8082	      (clobber (reg:DF 48))
8083	      (clobber (match_operand 3))
8084	      (use (reg:SI 19))
8085	      (use (const_int 1))])]
8086  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8087   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8088  [(set (match_dup 3) (reg:SI 19))
8089   (parallel [(set (match_dup 0)
8090	      (call (mem:SI (match_dup 1))
8091		    (match_dup 2)))
8092	      (clobber (reg:SI 1))
8093	      (clobber (reg:SI 2))
8094	      (clobber (reg:DF 48))
8095	      (use (reg:SI 19))
8096	      (use (const_int 1))])]
8097  "")
8098
8099(define_split
8100  [(parallel [(set (match_operand 0 "" "")
8101	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8102		    (match_operand 2 "" "")))
8103	      (clobber (reg:SI 1))
8104	      (clobber (reg:SI 2))
8105	      (clobber (reg:DF 48))
8106	      (clobber (match_operand 3))
8107	      (use (reg:SI 19))
8108	      (use (const_int 1))])]
8109  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8110  [(set (match_dup 3) (reg:SI 19))
8111   (parallel [(set (match_dup 0)
8112	      (call (mem:SI (match_dup 1))
8113		    (match_dup 2)))
8114	      (clobber (reg:SI 1))
8115	      (clobber (reg:SI 2))
8116	      (clobber (reg:DF 48))
8117	      (use (reg:SI 19))
8118	      (use (const_int 1))])
8119   (set (reg:SI 19) (match_dup 3))]
8120  "")
8121
8122(define_insn "*call_val_powf_pic_post_reload"
8123  [(set (match_operand 0 "" "")
8124	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8125	      (match_operand 2 "" "i")))
8126   (clobber (reg:SI 1))
8127   (clobber (reg:SI 2))
8128   (clobber (reg:DF 48))
8129   (use (reg:SI 19))
8130   (use (const_int 1))]
8131  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8132  "*
8133{
8134  pa_output_arg_descriptor (insn);
8135  return pa_output_call (insn, operands[1], 0);
8136}"
8137  [(set_attr "type" "call")
8138   (set (attr "length")
8139	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8140	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8141
8142;; This pattern is split if it is necessary to save and restore the
8143;; PIC register.
8144(define_insn "call_val_symref_64bit"
8145  [(set (match_operand 0 "" "")
8146	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8147	      (match_operand 2 "" "i")))
8148   (clobber (reg:DI 1))
8149   (clobber (reg:DI 2))
8150   (clobber (match_operand 3))
8151   (use (reg:DI 27))
8152   (use (reg:DI 29))
8153   (use (const_int 0))]
8154  "TARGET_64BIT"
8155  "#")
8156
8157;; Split out the PIC register save and restore after reload.  As the
8158;; split is done after reload, there are some situations in which we
8159;; unnecessarily save and restore %r4.  This happens when there is a
8160;; single call and the PIC register is not used after the call.
8161;;
8162;; The split has to be done since call_from_call_insn () can't handle
8163;; the pattern as is.  Noreturn calls are special because they have to
8164;; terminate the basic block.  The split has to contain more than one
8165;; insn.
8166(define_split
8167  [(parallel [(set (match_operand 0 "" "")
8168	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8169		    (match_operand 2 "" "")))
8170	      (clobber (reg:DI 1))
8171	      (clobber (reg:DI 2))
8172	      (clobber (match_operand 3))
8173	      (use (reg:DI 27))
8174	      (use (reg:DI 29))
8175	      (use (const_int 0))])]
8176  "TARGET_64BIT && reload_completed
8177   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8178  [(set (match_dup 3) (reg:DI 27))
8179   (parallel [(set (match_dup 0)
8180	      (call (mem:SI (match_dup 1))
8181		    (match_dup 2)))
8182	      (clobber (reg:DI 1))
8183	      (clobber (reg:DI 2))
8184	      (use (reg:DI 27))
8185	      (use (reg:DI 29))
8186	      (use (const_int 0))])]
8187  "")
8188
8189(define_split
8190  [(parallel [(set (match_operand 0 "" "")
8191	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8192		    (match_operand 2 "" "")))
8193	      (clobber (reg:DI 1))
8194	      (clobber (reg:DI 2))
8195	      (clobber (match_operand 3))
8196	      (use (reg:DI 27))
8197	      (use (reg:DI 29))
8198	      (use (const_int 0))])]
8199  "TARGET_64BIT && reload_completed"
8200  [(set (match_dup 3) (reg:DI 27))
8201   (parallel [(set (match_dup 0)
8202	      (call (mem:SI (match_dup 1))
8203		    (match_dup 2)))
8204	      (clobber (reg:DI 1))
8205	      (clobber (reg:DI 2))
8206	      (use (reg:DI 27))
8207	      (use (reg:DI 29))
8208	      (use (const_int 0))])
8209   (set (reg:DI 27) (match_dup 3))]
8210  "")
8211
8212(define_insn "*call_val_symref_64bit_post_reload"
8213  [(set (match_operand 0 "" "")
8214	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8215	      (match_operand 2 "" "i")))
8216   (clobber (reg:DI 1))
8217   (clobber (reg:DI 2))
8218   (use (reg:DI 27))
8219   (use (reg:DI 29))
8220   (use (const_int 0))]
8221  "TARGET_64BIT"
8222  "*
8223{
8224  return pa_output_call (insn, operands[1], 0);
8225}"
8226  [(set_attr "type" "call")
8227   (set (attr "length")
8228	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8229	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8230
8231;; powf function clobbers %fr12
8232(define_insn "call_val_powf_64bit"
8233  [(set (match_operand 0 "" "")
8234	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8235	      (match_operand 2 "" "i")))
8236   (clobber (reg:DI 1))
8237   (clobber (reg:DI 2))
8238   (clobber (reg:DF 40))
8239   (clobber (match_operand 3))
8240   (use (reg:DI 27))
8241   (use (reg:DI 29))
8242   (use (const_int 1))]
8243  "TARGET_64BIT && TARGET_HPUX"
8244  "#")
8245
8246;; Split out the PIC register save and restore after reload.  As the
8247;; split is done after reload, there are some situations in which we
8248;; unnecessarily save and restore %r4.  This happens when there is a
8249;; single call and the PIC register is not used after the call.
8250;;
8251;; The split has to be done since call_from_call_insn () can't handle
8252;; the pattern as is.  Noreturn calls are special because they have to
8253;; terminate the basic block.  The split has to contain more than one
8254;; insn.
8255(define_split
8256  [(parallel [(set (match_operand 0 "" "")
8257	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8258		    (match_operand 2 "" "")))
8259	      (clobber (reg:DI 1))
8260	      (clobber (reg:DI 2))
8261	      (clobber (reg:DF 40))
8262	      (clobber (match_operand 3))
8263	      (use (reg:DI 27))
8264	      (use (reg:DI 29))
8265	      (use (const_int 1))])]
8266  "TARGET_64BIT && TARGET_HPUX && reload_completed
8267   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8268  [(set (match_dup 3) (reg:DI 27))
8269   (parallel [(set (match_dup 0)
8270	      (call (mem:SI (match_dup 1))
8271		    (match_dup 2)))
8272	      (clobber (reg:DI 1))
8273	      (clobber (reg:DI 2))
8274	      (clobber (reg:DF 40))
8275	      (use (reg:DI 27))
8276	      (use (reg:DI 29))
8277	      (use (const_int 1))])]
8278  "")
8279
8280(define_split
8281  [(parallel [(set (match_operand 0 "" "")
8282	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8283		    (match_operand 2 "" "")))
8284	      (clobber (reg:DI 1))
8285	      (clobber (reg:DI 2))
8286	      (clobber (reg:DF 40))
8287	      (clobber (match_operand 3))
8288	      (use (reg:DI 27))
8289	      (use (reg:DI 29))
8290	      (use (const_int 1))])]
8291  "TARGET_64BIT && TARGET_HPUX && reload_completed"
8292  [(set (match_dup 3) (reg:DI 27))
8293   (parallel [(set (match_dup 0)
8294	      (call (mem:SI (match_dup 1))
8295		    (match_dup 2)))
8296	      (clobber (reg:DI 1))
8297	      (clobber (reg:DI 2))
8298	      (clobber (reg:DF 40))
8299	      (use (reg:DI 27))
8300	      (use (reg:DI 29))
8301	      (use (const_int 1))])
8302   (set (reg:DI 27) (match_dup 3))]
8303  "")
8304
8305(define_insn "*call_val_powf_64bit_post_reload"
8306  [(set (match_operand 0 "" "")
8307	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8308	      (match_operand 2 "" "i")))
8309   (clobber (reg:DI 1))
8310   (clobber (reg:DI 2))
8311   (clobber (reg:DF 40))
8312   (use (reg:DI 27))
8313   (use (reg:DI 29))
8314   (use (const_int 1))]
8315  "TARGET_64BIT && TARGET_HPUX"
8316  "*
8317{
8318  return pa_output_call (insn, operands[1], 0);
8319}"
8320  [(set_attr "type" "call")
8321   (set (attr "length")
8322	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8323	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8324
8325(define_insn "call_val_reg"
8326  [(set (match_operand 0 "" "")
8327	(call (mem:SI (reg:SI 22))
8328	      (match_operand 1 "" "i")))
8329   (clobber (reg:SI 1))
8330   (clobber (reg:SI 2))
8331   (use (const_int 1))]
8332  "!TARGET_64BIT"
8333  "*
8334{
8335  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8336}"
8337  [(set_attr "type" "dyncall")
8338   (set (attr "length")
8339	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8340	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8341
8342;; This pattern is split if it is necessary to save and restore the
8343;; PIC register.
8344(define_insn "call_val_reg_pic"
8345  [(set (match_operand 0 "" "")
8346	(call (mem:SI (reg:SI 22))
8347	      (match_operand 1 "" "i")))
8348   (clobber (reg:SI 1))
8349   (clobber (reg:SI 2))
8350   (clobber (match_operand 2))
8351   (use (reg:SI 19))
8352   (use (const_int 1))]
8353  "!TARGET_64BIT"
8354  "#")
8355
8356;; Split out the PIC register save and restore after reload.  As the
8357;; split is done after reload, there are some situations in which we
8358;; unnecessarily save and restore %r4.  This happens when there is a
8359;; single call and the PIC register is not used after the call.
8360;;
8361;; The split has to be done since call_from_call_insn () can't handle
8362;; the pattern as is.  Noreturn calls are special because they have to
8363;; terminate the basic block.  The split has to contain more than one
8364;; insn.
8365(define_split
8366  [(parallel [(set (match_operand 0 "" "")
8367		   (call (mem:SI (reg:SI 22))
8368			 (match_operand 1 "" "")))
8369	      (clobber (reg:SI 1))
8370	      (clobber (reg:SI 2))
8371	      (clobber (match_operand 2))
8372	      (use (reg:SI 19))
8373	      (use (const_int 1))])]
8374  "!TARGET_64BIT && reload_completed
8375   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8376  [(set (match_dup 2) (reg:SI 19))
8377   (parallel [(set (match_dup 0)
8378		   (call (mem:SI (reg:SI 22))
8379			 (match_dup 1)))
8380	      (clobber (reg:SI 1))
8381	      (clobber (reg:SI 2))
8382	      (use (reg:SI 19))
8383	      (use (const_int 1))])]
8384  "")
8385
8386(define_split
8387  [(parallel [(set (match_operand 0 "" "")
8388		   (call (mem:SI (reg:SI 22))
8389			 (match_operand 1 "" "")))
8390	      (clobber (reg:SI 1))
8391	      (clobber (reg:SI 2))
8392	      (clobber (match_operand 2))
8393	      (use (reg:SI 19))
8394	      (use (const_int 1))])]
8395  "!TARGET_64BIT && reload_completed"
8396  [(set (match_dup 2) (reg:SI 19))
8397   (parallel [(set (match_dup 0)
8398		   (call (mem:SI (reg:SI 22))
8399			 (match_dup 1)))
8400	      (clobber (reg:SI 1))
8401	      (clobber (reg:SI 2))
8402	      (use (reg:SI 19))
8403	      (use (const_int 1))])
8404   (set (reg:SI 19) (match_dup 2))]
8405  "")
8406
8407(define_insn "*call_val_reg_pic_post_reload"
8408  [(set (match_operand 0 "" "")
8409	(call (mem:SI (reg:SI 22))
8410	      (match_operand 1 "" "i")))
8411   (clobber (reg:SI 1))
8412   (clobber (reg:SI 2))
8413   (use (reg:SI 19))
8414   (use (const_int 1))]
8415  "!TARGET_64BIT"
8416  "*
8417{
8418  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8419}"
8420  [(set_attr "type" "dyncall")
8421   (set (attr "length")
8422	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8423	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8424
8425;; This pattern is split if it is necessary to save and restore the
8426;; PIC register.
8427(define_insn "call_val_reg_64bit"
8428  [(set (match_operand 0 "" "")
8429	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8430	      (match_operand 2 "" "i")))
8431   (clobber (reg:DI 2))
8432   (clobber (match_operand 3))
8433   (use (reg:DI 27))
8434   (use (reg:DI 29))
8435   (use (const_int 1))]
8436  "TARGET_64BIT"
8437  "#")
8438
8439;; Split out the PIC register save and restore after reload.  As the
8440;; split is done after reload, there are some situations in which we
8441;; unnecessarily save and restore %r4.  This happens when there is a
8442;; single call and the PIC register is not used after the call.
8443;;
8444;; The split has to be done since call_from_call_insn () can't handle
8445;; the pattern as is.  Noreturn calls are special because they have to
8446;; terminate the basic block.  The split has to contain more than one
8447;; insn.
8448(define_split
8449  [(parallel [(set (match_operand 0 "" "")
8450		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8451			 (match_operand 2 "" "")))
8452	      (clobber (reg:DI 2))
8453	      (clobber (match_operand 3))
8454	      (use (reg:DI 27))
8455	      (use (reg:DI 29))
8456	      (use (const_int 1))])]
8457  "TARGET_64BIT && reload_completed
8458   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8459  [(set (match_dup 3) (reg:DI 27))
8460   (parallel [(set (match_dup 0)
8461		   (call (mem:SI (match_dup 1))
8462			 (match_dup 2)))
8463	      (clobber (reg:DI 2))
8464	      (use (reg:DI 27))
8465	      (use (reg:DI 29))
8466	      (use (const_int 1))])]
8467  "")
8468
8469(define_split
8470  [(parallel [(set (match_operand 0 "" "")
8471		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8472			 (match_operand 2 "" "")))
8473	      (clobber (reg:DI 2))
8474	      (clobber (match_operand 3))
8475	      (use (reg:DI 27))
8476	      (use (reg:DI 29))
8477	      (use (const_int 1))])]
8478  "TARGET_64BIT && reload_completed"
8479  [(set (match_dup 3) (reg:DI 27))
8480   (parallel [(set (match_dup 0)
8481		   (call (mem:SI (match_dup 1))
8482			 (match_dup 2)))
8483	      (clobber (reg:DI 2))
8484	      (use (reg:DI 27))
8485	      (use (reg:DI 29))
8486	      (use (const_int 1))])
8487   (set (reg:DI 27) (match_dup 3))]
8488  "")
8489
8490(define_insn "*call_val_reg_64bit_post_reload"
8491  [(set (match_operand 0 "" "")
8492	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8493	      (match_operand 2 "" "i")))
8494   (clobber (reg:DI 2))
8495   (use (reg:DI 27))
8496   (use (reg:DI 29))
8497   (use (const_int 1))]
8498  "TARGET_64BIT"
8499  "*
8500{
8501  return pa_output_indirect_call (insn, operands[1]);
8502}"
8503  [(set_attr "type" "dyncall")
8504   (set (attr "length")
8505	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8506	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8507
8508/* Expand special pc-relative call to _mcount.  */
8509
8510(define_expand "call_mcount"
8511  [(parallel [(call (match_operand:SI 0 "" "")
8512		    (match_operand 1 "" ""))
8513	      (set (reg:SI 25)
8514		   (plus:SI (reg:SI 2)
8515			    (minus:SI (match_operand 2 "" "")
8516				      (plus:SI (pc) (const_int 4)))))
8517	      (clobber (reg:SI 2))])]
8518  "!TARGET_PORTABLE_RUNTIME"
8519  "
8520{
8521  rtx op = XEXP (operands[0], 0);
8522  rtx nb = operands[1];
8523  rtx lab = operands[2];
8524
8525  if (TARGET_64BIT)
8526    {
8527      rtx r4 = gen_rtx_REG (word_mode, 4);
8528      emit_move_insn (arg_pointer_rtx,
8529		      gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8530				    GEN_INT (64)));
8531      emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8532    }
8533  else
8534    {
8535      if (flag_pic)
8536	{
8537	  rtx r4 = gen_rtx_REG (word_mode, 4);
8538	  emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8539	}
8540      else
8541	emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8542    }
8543
8544  DONE;
8545}")
8546
8547(define_insn "call_mcount_nonpic"
8548  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8549	 (match_operand 1 "" "i"))
8550   (set (reg:SI 25)
8551	(plus:SI (reg:SI 2)
8552		 (minus:SI (match_operand 2 "" "")
8553			   (plus:SI (pc) (const_int 4)))))
8554   (clobber (reg:SI 2))]
8555  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8556  "*
8557{
8558  pa_output_arg_descriptor (insn);
8559  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8560}"
8561  [(set_attr "type" "multi")
8562   (set_attr "length" "8")])
8563
8564(define_insn "call_mcount_pic"
8565  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8566	 (match_operand 1 "" "i"))
8567   (set (reg:SI 25)
8568	(plus:SI (reg:SI 2)
8569		 (minus:SI (match_operand 2 "" "")
8570			   (plus:SI (pc) (const_int 4)))))
8571   (clobber (reg:SI 2))
8572   (clobber (match_operand 3))
8573   (use (reg:SI 19))]
8574  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8575  "#")
8576
8577(define_split
8578  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8579		    (match_operand 1 "" ""))
8580	      (set (reg:SI 25)
8581		   (plus:SI (reg:SI 2)
8582			    (minus:SI (match_operand 2 "" "")
8583				      (plus:SI (pc) (const_int 4)))))
8584	      (clobber (reg:SI 2))
8585	      (clobber (match_operand 3))
8586	      (use (reg:SI 19))])]
8587  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8588  [(set (match_dup 3) (reg:SI 19))
8589   (parallel [(call (mem:SI (match_dup 0))
8590		    (match_dup 1))
8591	      (set (reg:SI 25)
8592		   (plus:SI (reg:SI 2)
8593			    (minus:SI (match_dup 2)
8594				      (plus:SI (pc) (const_int 4)))))
8595	      (clobber (reg:SI 2))
8596	      (use (reg:SI 19))])
8597   (set (reg:SI 19) (match_dup 3))]
8598  "")
8599
8600(define_insn "*call_mcount_pic_post_reload"
8601  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8602	 (match_operand 1 "" "i"))
8603   (set (reg:SI 25)
8604	(plus:SI (reg:SI 2)
8605		 (minus:SI (match_operand 2 "" "")
8606			   (plus:SI (pc) (const_int 4)))))
8607   (clobber (reg:SI 2))
8608   (use (reg:SI 19))]
8609  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8610  "*
8611{
8612  pa_output_arg_descriptor (insn);
8613  return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8614}"
8615  [(set_attr "type" "multi")
8616   (set_attr "length" "8")])
8617
8618(define_insn "call_mcount_64bit"
8619  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8620	 (match_operand 1 "" "i"))
8621   (set (reg:SI 25)
8622	(plus:SI (reg:SI 2)
8623		 (minus:SI (match_operand 2 "" "")
8624			   (plus:SI (pc) (const_int 4)))))
8625   (clobber (reg:DI 2))
8626   (clobber (match_operand 3))
8627   (use (reg:DI 27))
8628   (use (reg:DI 29))]
8629  "TARGET_64BIT"
8630  "#")
8631
8632(define_split
8633  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8634		    (match_operand 1 "" ""))
8635	      (set (reg:SI 25)
8636		   (plus:SI (reg:SI 2)
8637			    (minus:SI (match_operand 2 "" "")
8638				      (plus:SI (pc) (const_int 4)))))
8639	      (clobber (reg:DI 2))
8640	      (clobber (match_operand 3))
8641	      (use (reg:DI 27))
8642	      (use (reg:DI 29))])]
8643  "TARGET_64BIT && reload_completed"
8644  [(set (match_dup 3) (reg:DI 27))
8645   (parallel [(call (mem:SI (match_dup 0))
8646		    (match_dup 1))
8647	      (set (reg:SI 25)
8648		   (plus:SI (reg:SI 2)
8649			    (minus:SI (match_dup 2)
8650				      (plus:SI (pc) (const_int 4)))))
8651	      (clobber (reg:DI 2))
8652	      (use (reg:DI 27))
8653	      (use (reg:DI 29))])
8654   (set (reg:DI 27) (match_dup 3))]
8655  "")
8656
8657(define_insn "*call_mcount_64bit_post_reload"
8658  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8659	 (match_operand 1 "" "i"))
8660   (set (reg:SI 25)
8661	(plus:SI (reg:SI 2)
8662		 (minus:SI (match_operand 2 "" "")
8663			   (plus:SI (pc) (const_int 4)))))
8664   (clobber (reg:DI 2))
8665   (use (reg:DI 27))
8666   (use (reg:DI 29))]
8667  "TARGET_64BIT"
8668  "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8669  [(set_attr "type" "multi")
8670   (set_attr "length" "8")])
8671
8672;; Call subroutine returning any type.
8673
8674(define_expand "untyped_call"
8675  [(parallel [(call (match_operand 0 "" "")
8676		    (const_int 0))
8677	      (match_operand 1 "" "")
8678	      (match_operand 2 "" "")])]
8679  ""
8680  "
8681{
8682  int i;
8683
8684  emit_call_insn (gen_call (operands[0], const0_rtx));
8685
8686  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8687    {
8688      rtx set = XVECEXP (operands[2], 0, i);
8689      emit_move_insn (SET_DEST (set), SET_SRC (set));
8690    }
8691
8692  /* The optimizer does not know that the call sets the function value
8693     registers we stored in the result block.  We avoid problems by
8694     claiming that all hard registers are used and clobbered at this
8695     point.  */
8696  emit_insn (gen_blockage ());
8697
8698  DONE;
8699}")
8700
8701(define_expand "sibcall"
8702  [(call (match_operand:SI 0 "" "")
8703	 (match_operand 1 "" ""))]
8704  "!TARGET_PORTABLE_RUNTIME"
8705  "
8706{
8707  rtx op, call_insn;
8708  rtx nb = operands[1];
8709
8710  op = XEXP (operands[0], 0);
8711
8712  if (TARGET_64BIT)
8713    {
8714      if (!virtuals_instantiated)
8715	emit_move_insn (arg_pointer_rtx,
8716			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8717				      GEN_INT (64)));
8718      else
8719	{
8720	  /* The loop pass can generate new libcalls after the virtual
8721	     registers are instantiated when fpregs are disabled because
8722	     the only method that we have for doing DImode multiplication
8723	     is with a libcall.  This could be trouble if we haven't
8724	     allocated enough space for the outgoing arguments.  */
8725	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8726
8727	  emit_move_insn (arg_pointer_rtx,
8728			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8729					GEN_INT (STACK_POINTER_OFFSET + 64)));
8730	}
8731    }
8732
8733  /* Indirect sibling calls are not allowed.  */
8734  if (TARGET_64BIT)
8735    call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8736  else
8737    call_insn = gen_sibcall_internal_symref (op, operands[1]);
8738
8739  call_insn = emit_call_insn (call_insn);
8740
8741  if (TARGET_64BIT)
8742    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8743
8744  /* We don't have to restore the PIC register.  */
8745  if (flag_pic)
8746    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8747
8748  DONE;
8749}")
8750
8751(define_insn "sibcall_internal_symref"
8752  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8753	 (match_operand 1 "" "i"))
8754   (clobber (reg:SI 1))
8755   (use (reg:SI 2))
8756   (use (const_int 0))]
8757  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8758  "*
8759{
8760  pa_output_arg_descriptor (insn);
8761  return pa_output_call (insn, operands[0], 1);
8762}"
8763  [(set_attr "type" "sibcall")
8764   (set (attr "length")
8765	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8766	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8767
8768(define_insn "sibcall_internal_symref_64bit"
8769  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8770	 (match_operand 1 "" "i"))
8771   (clobber (reg:DI 1))
8772   (use (reg:DI 2))
8773   (use (const_int 0))]
8774  "TARGET_64BIT"
8775  "*
8776{
8777  return pa_output_call (insn, operands[0], 1);
8778}"
8779  [(set_attr "type" "sibcall")
8780   (set (attr "length")
8781	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8782	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8783
8784(define_expand "sibcall_value"
8785  [(set (match_operand 0 "" "")
8786		   (call (match_operand:SI 1 "" "")
8787			 (match_operand 2 "" "")))]
8788  "!TARGET_PORTABLE_RUNTIME"
8789  "
8790{
8791  rtx op, call_insn;
8792  rtx nb = operands[1];
8793
8794  op = XEXP (operands[1], 0);
8795
8796  if (TARGET_64BIT)
8797    {
8798      if (!virtuals_instantiated)
8799	emit_move_insn (arg_pointer_rtx,
8800			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8801				      GEN_INT (64)));
8802      else
8803	{
8804	  /* The loop pass can generate new libcalls after the virtual
8805	     registers are instantiated when fpregs are disabled because
8806	     the only method that we have for doing DImode multiplication
8807	     is with a libcall.  This could be trouble if we haven't
8808	     allocated enough space for the outgoing arguments.  */
8809	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8810
8811	  emit_move_insn (arg_pointer_rtx,
8812			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8813					GEN_INT (STACK_POINTER_OFFSET + 64)));
8814	}
8815    }
8816
8817  /* Indirect sibling calls are not allowed.  */
8818  if (TARGET_64BIT)
8819    call_insn
8820      = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8821  else
8822    call_insn
8823      = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8824
8825  call_insn = emit_call_insn (call_insn);
8826
8827  if (TARGET_64BIT)
8828    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8829
8830  /* We don't have to restore the PIC register.  */
8831  if (flag_pic)
8832    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8833
8834  DONE;
8835}")
8836
8837(define_insn "sibcall_value_internal_symref"
8838  [(set (match_operand 0 "" "")
8839	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8840	      (match_operand 2 "" "i")))
8841   (clobber (reg:SI 1))
8842   (use (reg:SI 2))
8843   (use (const_int 0))]
8844  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8845  "*
8846{
8847  pa_output_arg_descriptor (insn);
8848  return pa_output_call (insn, operands[1], 1);
8849}"
8850  [(set_attr "type" "sibcall")
8851   (set (attr "length")
8852	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8853	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8854
8855(define_insn "sibcall_value_internal_symref_64bit"
8856  [(set (match_operand 0 "" "")
8857	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8858	      (match_operand 2 "" "i")))
8859   (clobber (reg:DI 1))
8860   (use (reg:DI 2))
8861   (use (const_int 0))]
8862  "TARGET_64BIT"
8863  "*
8864{
8865  return pa_output_call (insn, operands[1], 1);
8866}"
8867  [(set_attr "type" "sibcall")
8868   (set (attr "length")
8869	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8870	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8871
8872(define_insn "nop"
8873  [(const_int 0)]
8874  ""
8875  "nop"
8876  [(set_attr "type" "move")
8877   (set_attr "length" "4")])
8878
8879;;; EH does longjmp's from and within the data section.  Thus,
8880;;; an interspace branch is required for the longjmp implementation.
8881;;; Registers r1 and r2 are used as scratch registers for the jump
8882;;; when necessary.
8883(define_expand "interspace_jump"
8884  [(parallel
8885     [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8886      (clobber (match_dup 1))])]
8887  ""
8888  "
8889{
8890  operands[1] = gen_rtx_REG (word_mode, 2);
8891}")
8892
8893(define_insn ""
8894  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8895  (clobber (reg:SI 2))]
8896  "TARGET_PA_20 && !TARGET_64BIT"
8897  "bve%* (%0)"
8898   [(set_attr "type" "branch")
8899    (set_attr "length" "4")])
8900
8901(define_insn ""
8902  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8903  (clobber (reg:SI 2))]
8904  "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8905  "be%* 0(%%sr4,%0)"
8906   [(set_attr "type" "branch")
8907    (set_attr "length" "4")])
8908
8909(define_insn ""
8910  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8911  (clobber (reg:SI 2))]
8912  "!TARGET_64BIT"
8913  "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8914   [(set_attr "type" "branch")
8915    (set_attr "length" "12")])
8916
8917(define_insn ""
8918  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8919  (clobber (reg:DI 2))]
8920  "TARGET_64BIT"
8921  "bve%* (%0)"
8922   [(set_attr "type" "branch")
8923    (set_attr "length" "4")])
8924
8925(define_expand "builtin_longjmp"
8926  [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8927  ""
8928  "
8929{
8930  /* The elements of the buffer are, in order:  */
8931  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8932  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8933			 POINTER_SIZE / BITS_PER_UNIT));
8934  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8935			   (POINTER_SIZE * 2) / BITS_PER_UNIT));
8936  rtx pv = gen_rtx_REG (Pmode, 1);
8937
8938  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8939  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8940
8941  /* Load the label we are jumping through into r1 so that we know
8942     where to look for it when we get back to setjmp's function for
8943     restoring the gp.  */
8944  emit_move_insn (pv, lab);
8945
8946  /* Restore the stack and frame pointers.  */
8947  fp = copy_to_reg (fp);
8948  emit_stack_restore (SAVE_NONLOCAL, stack);
8949
8950  /* Ensure the frame pointer move is not optimized.  */
8951  emit_insn (gen_blockage ());
8952  emit_clobber (hard_frame_pointer_rtx);
8953  emit_clobber (frame_pointer_rtx);
8954  emit_move_insn (hard_frame_pointer_rtx, fp);
8955
8956  emit_use (hard_frame_pointer_rtx);
8957  emit_use (stack_pointer_rtx);
8958
8959  /* Prevent the insns above from being scheduled into the delay slot
8960     of the interspace jump because the space register could change.  */
8961  emit_insn (gen_blockage ());
8962
8963  emit_jump_insn (gen_interspace_jump (pv));
8964  emit_barrier ();
8965  DONE;
8966}")
8967
8968;;; Operands 2 and 3 are assumed to be CONST_INTs.
8969(define_expand "extzvsi"
8970  [(set (match_operand:SI 0 "register_operand" "")
8971	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
8972			 (match_operand:SI 2 "uint5_operand" "")
8973			 (match_operand:SI 3 "uint5_operand" "")))]
8974  ""
8975  "
8976{
8977  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8978  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8979
8980  /* PA extraction insns don't support zero length bitfields or fields
8981     extending beyond the left or right-most bits.  Also, the predicate
8982     rejects lengths equal to a word as they are better handled by
8983     the move patterns.  */
8984  if (len == 0 || pos + len > 32)
8985    FAIL;
8986
8987  /* From mips.md: extract_bit_field doesn't verify that our source
8988     matches the predicate, so check it again here.  */
8989  if (!register_operand (operands[1], VOIDmode))
8990    FAIL;
8991
8992  emit_insn (gen_extzv_32 (operands[0], operands[1],
8993			   operands[2], operands[3]));
8994  DONE;
8995}")
8996
8997(define_insn "extzv_32"
8998  [(set (match_operand:SI 0 "register_operand" "=r")
8999	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9000			 (match_operand:SI 2 "uint5_operand" "")
9001			 (match_operand:SI 3 "uint5_operand" "")))]
9002  "UINTVAL (operands[2]) > 0
9003   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9004  "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9005  [(set_attr "type" "shift")
9006   (set_attr "length" "4")])
9007
9008(define_insn ""
9009  [(set (match_operand:SI 0 "register_operand" "=r")
9010	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9011			 (const_int 1)
9012			 (match_operand:SI 2 "register_operand" "q")))]
9013  ""
9014  "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9015  [(set_attr "type" "shift")
9016   (set_attr "length" "4")])
9017
9018(define_expand "extzvdi"
9019  [(set (match_operand:DI 0 "register_operand" "")
9020	(zero_extract:DI (match_operand:DI 1 "register_operand" "")
9021			 (match_operand:DI 2 "uint6_operand" "")
9022			 (match_operand:DI 3 "uint6_operand" "")))]
9023  "TARGET_64BIT"
9024  "
9025{
9026  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9027  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9028
9029  /* PA extraction insns don't support zero length bitfields or fields
9030     extending beyond the left or right-most bits.  Also, the predicate
9031     rejects lengths equal to a doubleword as they are better handled by
9032     the move patterns.  */
9033  if (len == 0 || pos + len > 64)
9034    FAIL;
9035
9036  /* From mips.md: extract_bit_field doesn't verify that our source
9037     matches the predicate, so check it again here.  */
9038  if (!register_operand (operands[1], VOIDmode))
9039    FAIL;
9040
9041  emit_insn (gen_extzv_64 (operands[0], operands[1],
9042			   operands[2], operands[3]));
9043  DONE;
9044}")
9045
9046(define_insn "extzv_64"
9047  [(set (match_operand:DI 0 "register_operand" "=r")
9048	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9049			 (match_operand:DI 2 "uint6_operand" "")
9050			 (match_operand:DI 3 "uint6_operand" "")))]
9051  "TARGET_64BIT
9052   && UINTVAL (operands[2]) > 0
9053   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9054  "extrd,u %1,%3+%2-1,%2,%0"
9055  [(set_attr "type" "shift")
9056   (set_attr "length" "4")])
9057
9058(define_insn ""
9059  [(set (match_operand:DI 0 "register_operand" "=r")
9060	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9061			 (const_int 1)
9062			 (match_operand:DI 2 "register_operand" "q")))]
9063  "TARGET_64BIT"
9064  "extrd,u %1,%%sar,1,%0"
9065  [(set_attr "type" "shift")
9066   (set_attr "length" "4")])
9067
9068;;; Operands 2 and 3 are assumed to be CONST_INTs.
9069(define_expand "extvsi"
9070  [(set (match_operand:SI 0 "register_operand" "")
9071	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
9072			 (match_operand:SI 2 "uint5_operand" "")
9073			 (match_operand:SI 3 "uint5_operand" "")))]
9074  ""
9075  "
9076{
9077  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9078  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9079
9080  /* PA extraction insns don't support zero length bitfields or fields
9081     extending beyond the left or right-most bits.  Also, the predicate
9082     rejects lengths equal to a word as they are better handled by
9083     the move patterns.  */
9084  if (len == 0 || pos + len > 32)
9085    FAIL;
9086
9087  /* From mips.md: extract_bit_field doesn't verify that our source
9088     matches the predicate, so check it again here.  */
9089  if (!register_operand (operands[1], VOIDmode))
9090    FAIL;
9091
9092  emit_insn (gen_extv_32 (operands[0], operands[1],
9093			  operands[2], operands[3]));
9094  DONE;
9095}")
9096
9097(define_insn "extv_32"
9098  [(set (match_operand:SI 0 "register_operand" "=r")
9099	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9100			 (match_operand:SI 2 "uint5_operand" "")
9101			 (match_operand:SI 3 "uint5_operand" "")))]
9102  "UINTVAL (operands[2]) > 0
9103   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9104  "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9105  [(set_attr "type" "shift")
9106   (set_attr "length" "4")])
9107
9108(define_insn ""
9109  [(set (match_operand:SI 0 "register_operand" "=r")
9110	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9111			 (const_int 1)
9112			 (match_operand:SI 2 "register_operand" "q")))]
9113  "!TARGET_64BIT"
9114  "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9115  [(set_attr "type" "shift")
9116   (set_attr "length" "4")])
9117
9118(define_expand "extvdi"
9119  [(set (match_operand:DI 0 "register_operand" "")
9120	(sign_extract:DI (match_operand:DI 1 "register_operand" "")
9121			 (match_operand:DI 2 "uint6_operand" "")
9122			 (match_operand:DI 3 "uint6_operand" "")))]
9123  "TARGET_64BIT"
9124  "
9125{
9126  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9127  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9128
9129  /* PA extraction insns don't support zero length bitfields or fields
9130     extending beyond the left or right-most bits.  Also, the predicate
9131     rejects lengths equal to a doubleword as they are better handled by
9132     the move patterns.  */
9133  if (len == 0 || pos + len > 64)
9134    FAIL;
9135
9136  /* From mips.md: extract_bit_field doesn't verify that our source
9137     matches the predicate, so check it again here.  */
9138  if (!register_operand (operands[1], VOIDmode))
9139    FAIL;
9140
9141  emit_insn (gen_extv_64 (operands[0], operands[1],
9142			  operands[2], operands[3]));
9143  DONE;
9144}")
9145
9146(define_insn "extv_64"
9147  [(set (match_operand:DI 0 "register_operand" "=r")
9148	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9149			 (match_operand:DI 2 "uint6_operand" "")
9150			 (match_operand:DI 3 "uint6_operand" "")))]
9151  "TARGET_64BIT
9152   && UINTVAL (operands[2]) > 0
9153   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9154  "extrd,s %1,%3+%2-1,%2,%0"
9155  [(set_attr "type" "shift")
9156   (set_attr "length" "4")])
9157
9158(define_insn ""
9159  [(set (match_operand:DI 0 "register_operand" "=r")
9160	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9161			 (const_int 1)
9162			 (match_operand:DI 2 "register_operand" "q")))]
9163  "TARGET_64BIT"
9164  "extrd,s %1,%%sar,1,%0"
9165  [(set_attr "type" "shift")
9166   (set_attr "length" "4")])
9167
9168;;; Operands 1 and 2 are assumed to be CONST_INTs.
9169(define_expand "insvsi"
9170  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9171			 (match_operand:SI 1 "uint5_operand" "")
9172			 (match_operand:SI 2 "uint5_operand" ""))
9173	(match_operand:SI 3 "arith5_operand" ""))]
9174  ""
9175  "
9176{
9177  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9178  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9179
9180  /* PA insertion insns don't support zero length bitfields or fields
9181     extending beyond the left or right-most bits.  Also, the predicate
9182     rejects lengths equal to a word as they are better handled by
9183     the move patterns.  */
9184  if (len <= 0 || pos + len > 32)
9185    FAIL;
9186
9187  /* From mips.md: insert_bit_field doesn't verify that our destination
9188     matches the predicate, so check it again here.  */
9189  if (!register_operand (operands[0], VOIDmode))
9190    FAIL;
9191
9192  emit_insn (gen_insv_32 (operands[0], operands[1],
9193			  operands[2], operands[3]));
9194  DONE;
9195}")
9196
9197(define_insn "insv_32"
9198  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9199			 (match_operand:SI 1 "uint5_operand" "")
9200			 (match_operand:SI 2 "uint5_operand" ""))
9201	(match_operand:SI 3 "arith5_operand" "r,L"))]
9202  "UINTVAL (operands[1]) > 0
9203   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9204  "@
9205   {dep|depw} %3,%2+%1-1,%1,%0
9206   {depi|depwi} %3,%2+%1-1,%1,%0"
9207  [(set_attr "type" "shift,shift")
9208   (set_attr "length" "4,4")])
9209
9210;; Optimize insertion of const_int values of type 1...1xxxx.
9211(define_insn ""
9212  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9213			 (match_operand:SI 1 "uint5_operand" "")
9214			 (match_operand:SI 2 "uint5_operand" ""))
9215	(match_operand:SI 3 "const_int_operand" ""))]
9216  "(INTVAL (operands[3]) & 0x10) != 0 &&
9217   (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9218  "*
9219{
9220  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9221  return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9222}"
9223  [(set_attr "type" "shift")
9224   (set_attr "length" "4")])
9225
9226(define_expand "insvdi"
9227  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9228			 (match_operand:DI 1 "uint6_operand" "")
9229			 (match_operand:DI 2 "uint6_operand" ""))
9230	(match_operand:DI 3 "arith5_operand" ""))]
9231  "TARGET_64BIT"
9232  "
9233{
9234  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9235  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9236
9237  /* PA insertion insns don't support zero length bitfields or fields
9238     extending beyond the left or right-most bits.  Also, the predicate
9239     rejects lengths equal to a doubleword as they are better handled by
9240     the move patterns.  */
9241  if (len <= 0 || pos + len > 64)
9242    FAIL;
9243
9244  /* From mips.md: insert_bit_field doesn't verify that our destination
9245     matches the predicate, so check it again here.  */
9246  if (!register_operand (operands[0], VOIDmode))
9247    FAIL;
9248
9249  emit_insn (gen_insv_64 (operands[0], operands[1],
9250			  operands[2], operands[3]));
9251  DONE;
9252}")
9253
9254(define_insn "insv_64"
9255  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9256			 (match_operand:DI 1 "uint6_operand" "")
9257			 (match_operand:DI 2 "uint6_operand" ""))
9258	(match_operand:DI 3 "arith5_operand" "r,L"))]
9259  "TARGET_64BIT
9260   && UINTVAL (operands[1]) > 0
9261   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9262  "@
9263   depd %3,%2+%1-1,%1,%0
9264   depdi %3,%2+%1-1,%1,%0"
9265  [(set_attr "type" "shift,shift")
9266   (set_attr "length" "4,4")])
9267
9268;; Optimize insertion of const_int values of type 1...1xxxx.
9269(define_insn ""
9270  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9271			 (match_operand:DI 1 "uint6_operand" "")
9272			 (match_operand:DI 2 "uint6_operand" ""))
9273	(match_operand:DI 3 "const_int_operand" ""))]
9274  "(INTVAL (operands[3]) & 0x10) != 0
9275   && TARGET_64BIT
9276   && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9277  "*
9278{
9279  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9280  return \"depdi %3,%2+%1-1,%1,%0\";
9281}"
9282  [(set_attr "type" "shift")
9283   (set_attr "length" "4")])
9284
9285(define_insn ""
9286  [(set (match_operand:DI 0 "register_operand" "=r")
9287	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9288		   (const_int 32)))]
9289  "TARGET_64BIT"
9290  "depd,z %1,31,32,%0"
9291  [(set_attr "type" "shift")
9292   (set_attr "length" "4")])
9293
9294;; This insn is used for some loop tests, typically loops reversed when
9295;; strength reduction is used.  It is actually created when the instruction
9296;; combination phase combines the special loop test.  Since this insn
9297;; is both a jump insn and has an output, it must deal with its own
9298;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9299;; to not choose the register alternatives in the event a reload is needed.
9300(define_insn "decrement_and_branch_until_zero"
9301  [(set (pc)
9302	(if_then_else
9303	  (match_operator 2 "ordered_comparison_operator"
9304	   [(plus:SI
9305	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9306	      (match_operand:SI 1 "int5_operand" "L,L,L"))
9307	    (const_int 0)])
9308	  (label_ref (match_operand 3 "" ""))
9309	  (pc)))
9310   (set (match_dup 0)
9311	(plus:SI (match_dup 0) (match_dup 1)))
9312   (clobber (match_scratch:SI 4 "=X,r,r"))]
9313  ""
9314  "* return pa_output_dbra (operands, insn, which_alternative); "
9315;; Do not expect to understand this the first time through.
9316[(set_attr "type" "cbranch,multi,multi")
9317 (set (attr "length")
9318      (if_then_else (eq_attr "alternative" "0")
9319;; Loop counter in register case
9320;; Short branch has length of 4
9321;; Long branch has length of 8, 20, 24 or 28
9322	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9323	       (const_int MAX_12BIT_OFFSET))
9324	   (const_int 4)
9325	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9326	       (const_int MAX_17BIT_OFFSET))
9327	   (const_int 8)
9328	   (match_test "TARGET_PORTABLE_RUNTIME")
9329	   (const_int 24)
9330	   (not (match_test "flag_pic"))
9331	   (const_int 20)]
9332	  (const_int 28))
9333
9334;; Loop counter in FP reg case.
9335;; Extra goo to deal with additional reload insns.
9336	(if_then_else (eq_attr "alternative" "1")
9337	  (if_then_else (lt (match_dup 3) (pc))
9338	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9339		      (const_int MAX_12BIT_OFFSET))
9340		    (const_int 24)
9341		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9342		      (const_int MAX_17BIT_OFFSET))
9343		    (const_int 28)
9344		    (match_test "TARGET_PORTABLE_RUNTIME")
9345		    (const_int 44)
9346		    (not (match_test "flag_pic"))
9347		    (const_int 40)]
9348		  (const_int 48))
9349	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9350		      (const_int MAX_12BIT_OFFSET))
9351		    (const_int 24)
9352		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9353		      (const_int MAX_17BIT_OFFSET))
9354		    (const_int 28)
9355		    (match_test "TARGET_PORTABLE_RUNTIME")
9356		    (const_int 44)
9357		    (not (match_test "flag_pic"))
9358		    (const_int 40)]
9359		  (const_int 48)))
9360
9361;; Loop counter in memory case.
9362;; Extra goo to deal with additional reload insns.
9363	(if_then_else (lt (match_dup 3) (pc))
9364	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9365		      (const_int MAX_12BIT_OFFSET))
9366		    (const_int 12)
9367		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9368		      (const_int MAX_17BIT_OFFSET))
9369		    (const_int 16)
9370		    (match_test "TARGET_PORTABLE_RUNTIME")
9371		    (const_int 32)
9372		    (not (match_test "flag_pic"))
9373		    (const_int 28)]
9374		  (const_int 36))
9375	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9376		      (const_int MAX_12BIT_OFFSET))
9377		    (const_int 12)
9378		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9379		      (const_int MAX_17BIT_OFFSET))
9380		    (const_int 16)
9381		    (match_test "TARGET_PORTABLE_RUNTIME")
9382		    (const_int 32)
9383		    (not (match_test "flag_pic"))
9384		    (const_int 28)]
9385		  (const_int 36))))))])
9386
9387(define_insn ""
9388  [(set (pc)
9389	(if_then_else
9390	  (match_operator 2 "movb_comparison_operator"
9391	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9392	  (label_ref (match_operand 3 "" ""))
9393	  (pc)))
9394   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9395	(match_dup 1))]
9396  ""
9397"* return pa_output_movb (operands, insn, which_alternative, 0); "
9398;; Do not expect to understand this the first time through.
9399[(set_attr "type" "cbranch,multi,multi,multi")
9400 (set (attr "length")
9401      (if_then_else (eq_attr "alternative" "0")
9402;; Loop counter in register case
9403;; Short branch has length of 4
9404;; Long branch has length of 8, 20, 24 or 28
9405        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9406	       (const_int MAX_12BIT_OFFSET))
9407	   (const_int 4)
9408	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9409	       (const_int MAX_17BIT_OFFSET))
9410	   (const_int 8)
9411	   (match_test "TARGET_PORTABLE_RUNTIME")
9412	   (const_int 24)
9413	   (not (match_test "flag_pic"))
9414	   (const_int 20)]
9415	  (const_int 28))
9416
9417;; Loop counter in FP reg case.
9418;; Extra goo to deal with additional reload insns.
9419	(if_then_else (eq_attr "alternative" "1")
9420	  (if_then_else (lt (match_dup 3) (pc))
9421	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9422		      (const_int MAX_12BIT_OFFSET))
9423		    (const_int 12)
9424		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9425		      (const_int MAX_17BIT_OFFSET))
9426		    (const_int 16)
9427		    (match_test "TARGET_PORTABLE_RUNTIME")
9428		    (const_int 32)
9429		    (not (match_test "flag_pic"))
9430		    (const_int 28)]
9431		  (const_int 36))
9432	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9433		      (const_int MAX_12BIT_OFFSET))
9434		    (const_int 12)
9435		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9436		      (const_int MAX_17BIT_OFFSET))
9437		    (const_int 16)
9438		    (match_test "TARGET_PORTABLE_RUNTIME")
9439		    (const_int 32)
9440		    (not (match_test "flag_pic"))
9441		    (const_int 28)]
9442		  (const_int 36)))
9443
9444;; Loop counter in memory or sar case.
9445;; Extra goo to deal with additional reload insns.
9446	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9447		   (const_int MAX_12BIT_OFFSET))
9448		(const_int 8)
9449		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9450		  (const_int MAX_17BIT_OFFSET))
9451		(const_int 12)
9452		(match_test "TARGET_PORTABLE_RUNTIME")
9453		(const_int 28)
9454		(not (match_test "flag_pic"))
9455		(const_int 24)]
9456	      (const_int 32)))))])
9457
9458;; Handle negated branch.
9459(define_insn ""
9460  [(set (pc)
9461	(if_then_else
9462	  (match_operator 2 "movb_comparison_operator"
9463	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9464	  (pc)
9465	  (label_ref (match_operand 3 "" ""))))
9466   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9467	(match_dup 1))]
9468  ""
9469"* return pa_output_movb (operands, insn, which_alternative, 1); "
9470;; Do not expect to understand this the first time through.
9471[(set_attr "type" "cbranch,multi,multi,multi")
9472 (set (attr "length")
9473      (if_then_else (eq_attr "alternative" "0")
9474;; Loop counter in register case
9475;; Short branch has length of 4
9476;; Long branch has length of 8
9477        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9478	       (const_int MAX_12BIT_OFFSET))
9479	   (const_int 4)
9480	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9481	       (const_int MAX_17BIT_OFFSET))
9482	   (const_int 8)
9483	   (match_test "TARGET_PORTABLE_RUNTIME")
9484	   (const_int 24)
9485	   (not (match_test "flag_pic"))
9486	   (const_int 20)]
9487	  (const_int 28))
9488
9489;; Loop counter in FP reg case.
9490;; Extra goo to deal with additional reload insns.
9491	(if_then_else (eq_attr "alternative" "1")
9492	  (if_then_else (lt (match_dup 3) (pc))
9493	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9494		      (const_int MAX_12BIT_OFFSET))
9495		    (const_int 12)
9496		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9497		      (const_int MAX_17BIT_OFFSET))
9498		    (const_int 16)
9499		    (match_test "TARGET_PORTABLE_RUNTIME")
9500		    (const_int 32)
9501		    (not (match_test "flag_pic"))
9502		    (const_int 28)]
9503		  (const_int 36))
9504	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9505		      (const_int MAX_12BIT_OFFSET))
9506		    (const_int 12)
9507		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9508		      (const_int MAX_17BIT_OFFSET))
9509		    (const_int 16)
9510		    (match_test "TARGET_PORTABLE_RUNTIME")
9511		    (const_int 32)
9512		    (not (match_test "flag_pic"))
9513		    (const_int 28)]
9514		  (const_int 36)))
9515
9516;; Loop counter in memory or SAR case.
9517;; Extra goo to deal with additional reload insns.
9518	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9519		   (const_int MAX_12BIT_OFFSET))
9520		(const_int 8)
9521		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9522		  (const_int MAX_17BIT_OFFSET))
9523		(const_int 12)
9524		(match_test "TARGET_PORTABLE_RUNTIME")
9525		(const_int 28)
9526		(not (match_test "flag_pic"))
9527		(const_int 24)]
9528	      (const_int 32)))))])
9529
9530(define_insn ""
9531  [(set (pc) (label_ref (match_operand 3 "" "" )))
9532   (set (match_operand:SI 0 "ireg_operand" "=r")
9533	(plus:SI (match_operand:SI 1 "ireg_operand" "r")
9534		 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9535  "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9536  "*
9537{
9538  return pa_output_parallel_addb (operands, insn);
9539}"
9540[(set_attr "type" "parallel_branch")
9541 (set (attr "length")
9542    (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9543	       (const_int MAX_12BIT_OFFSET))
9544	   (const_int 4)
9545	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9546	       (const_int MAX_17BIT_OFFSET))
9547	   (const_int 8)
9548	   (match_test "TARGET_PORTABLE_RUNTIME")
9549	   (const_int 24)
9550	   (not (match_test "flag_pic"))
9551	   (const_int 20)]
9552	  (const_int 28)))])
9553
9554(define_insn ""
9555  [(set (pc) (label_ref (match_operand 2 "" "" )))
9556   (set (match_operand:SF 0 "ireg_operand" "=r")
9557	(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9558  "reload_completed"
9559  "*
9560{
9561  return pa_output_parallel_movb (operands, insn);
9562}"
9563[(set_attr "type" "parallel_branch")
9564 (set (attr "length")
9565    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9566	       (const_int MAX_12BIT_OFFSET))
9567	   (const_int 4)
9568	   (lt (abs (minus (match_dup 2) (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(define_insn ""
9578  [(set (pc) (label_ref (match_operand 2 "" "" )))
9579   (set (match_operand:SI 0 "ireg_operand" "=r")
9580	(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9581  "reload_completed"
9582  "*
9583{
9584  return pa_output_parallel_movb (operands, insn);
9585}"
9586[(set_attr "type" "parallel_branch")
9587 (set (attr "length")
9588    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9589	       (const_int MAX_12BIT_OFFSET))
9590	   (const_int 4)
9591	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9592	       (const_int MAX_17BIT_OFFSET))
9593	   (const_int 8)
9594	   (match_test "TARGET_PORTABLE_RUNTIME")
9595	   (const_int 24)
9596	   (not (match_test "flag_pic"))
9597	   (const_int 20)]
9598	  (const_int 28)))])
9599
9600(define_insn ""
9601  [(set (pc) (label_ref (match_operand 2 "" "" )))
9602   (set (match_operand:HI 0 "ireg_operand" "=r")
9603	(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9604  "reload_completed"
9605  "*
9606{
9607  return pa_output_parallel_movb (operands, insn);
9608}"
9609[(set_attr "type" "parallel_branch")
9610 (set (attr "length")
9611    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9612	       (const_int MAX_12BIT_OFFSET))
9613	   (const_int 4)
9614	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9615	       (const_int MAX_17BIT_OFFSET))
9616	   (const_int 8)
9617	   (match_test "TARGET_PORTABLE_RUNTIME")
9618	   (const_int 24)
9619	   (not (match_test "flag_pic"))
9620	   (const_int 20)]
9621	  (const_int 28)))])
9622
9623(define_insn ""
9624  [(set (pc) (label_ref (match_operand 2 "" "" )))
9625   (set (match_operand:QI 0 "ireg_operand" "=r")
9626	(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9627  "reload_completed"
9628  "*
9629{
9630  return pa_output_parallel_movb (operands, insn);
9631}"
9632[(set_attr "type" "parallel_branch")
9633 (set (attr "length")
9634    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9635	       (const_int MAX_12BIT_OFFSET))
9636	   (const_int 4)
9637	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9638	       (const_int MAX_17BIT_OFFSET))
9639	   (const_int 8)
9640	   (match_test "TARGET_PORTABLE_RUNTIME")
9641	   (const_int 24)
9642	   (not (match_test "flag_pic"))
9643	   (const_int 20)]
9644	  (const_int 28)))])
9645
9646(define_insn ""
9647  [(set (match_operand 0 "register_operand" "=f")
9648	(mult (match_operand 1 "register_operand" "f")
9649	      (match_operand 2 "register_operand" "f")))
9650   (set (match_operand 3 "register_operand" "+f")
9651	(plus (match_operand 4 "register_operand" "f")
9652	      (match_operand 5 "register_operand" "f")))]
9653  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9654   && reload_completed && pa_fmpyaddoperands (operands)"
9655  "*
9656{
9657  if (GET_MODE (operands[0]) == DFmode)
9658    {
9659      if (rtx_equal_p (operands[3], operands[5]))
9660	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9661      else
9662	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9663    }
9664  else
9665    {
9666      if (rtx_equal_p (operands[3], operands[5]))
9667	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9668      else
9669	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9670    }
9671}"
9672  [(set_attr "type" "fpalu")
9673   (set_attr "length" "4")])
9674
9675(define_insn ""
9676  [(set (match_operand 3 "register_operand" "+f")
9677	(plus (match_operand 4 "register_operand" "f")
9678	      (match_operand 5 "register_operand" "f")))
9679   (set (match_operand 0 "register_operand" "=f")
9680	(mult (match_operand 1 "register_operand" "f")
9681	      (match_operand 2 "register_operand" "f")))]
9682  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9683   && reload_completed && pa_fmpyaddoperands (operands)"
9684  "*
9685{
9686  if (GET_MODE (operands[0]) == DFmode)
9687    {
9688      if (rtx_equal_p (operands[3], operands[5]))
9689	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9690      else
9691	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9692    }
9693  else
9694    {
9695      if (rtx_equal_p (operands[3], operands[5]))
9696	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9697      else
9698	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9699    }
9700}"
9701  [(set_attr "type" "fpalu")
9702   (set_attr "length" "4")])
9703
9704(define_insn ""
9705  [(set (match_operand 0 "register_operand" "=f")
9706	(mult (match_operand 1 "register_operand" "f")
9707	      (match_operand 2 "register_operand" "f")))
9708   (set (match_operand 3 "register_operand" "+f")
9709	(minus (match_operand 4 "register_operand" "f")
9710	       (match_operand 5 "register_operand" "f")))]
9711  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9712   && reload_completed && pa_fmpysuboperands (operands)"
9713  "*
9714{
9715  if (GET_MODE (operands[0]) == DFmode)
9716    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9717  else
9718    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9719}"
9720  [(set_attr "type" "fpalu")
9721   (set_attr "length" "4")])
9722
9723(define_insn ""
9724  [(set (match_operand 3 "register_operand" "+f")
9725	(minus (match_operand 4 "register_operand" "f")
9726	       (match_operand 5 "register_operand" "f")))
9727   (set (match_operand 0 "register_operand" "=f")
9728	(mult (match_operand 1 "register_operand" "f")
9729	      (match_operand 2 "register_operand" "f")))]
9730  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9731   && reload_completed && pa_fmpysuboperands (operands)"
9732  "*
9733{
9734  if (GET_MODE (operands[0]) == DFmode)
9735    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9736  else
9737    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9738}"
9739  [(set_attr "type" "fpalu")
9740   (set_attr "length" "4")])
9741
9742;; The following two patterns are used by the trampoline code for nested
9743;; functions.  They flush the I and D cache lines from the start address
9744;; (operand0) to the end address (operand1).  No lines are flushed if the
9745;; end address is less than the start address (unsigned).
9746;;
9747;; Because the range of memory flushed is variable and the size of a MEM
9748;; can only be a CONST_INT, the patterns specify that they perform an
9749;; unspecified volatile operation on all memory.
9750;;
9751;; The address range for an icache flush must lie within a single
9752;; space on targets with non-equivalent space registers.
9753;;
9754;; Operand 0 contains the start address.
9755;; Operand 1 contains the end address.
9756;; Operand 2 contains the line length to use.
9757(define_insn "dcacheflush<P:mode>"
9758  [(const_int 1)
9759   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9760   (use (match_operand 0 "pmode_register_operand" "r"))
9761   (use (match_operand 1 "pmode_register_operand" "r"))
9762   (use (match_operand 2 "pmode_register_operand" "r"))
9763   (clobber (match_scratch:P 3 "=&0"))]
9764  ""
9765  "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9766  [(set_attr "type" "multi")
9767   (set_attr "length" "12")])
9768
9769(define_insn "icacheflush<P:mode>"
9770  [(const_int 2)
9771   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9772   (use (match_operand 0 "pmode_register_operand" "r"))
9773   (use (match_operand 1 "pmode_register_operand" "r"))
9774   (use (match_operand 2 "pmode_register_operand" "r"))
9775   (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9776   (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9777   (clobber (match_scratch:P 5 "=&0"))]
9778  ""
9779  "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"
9780  [(set_attr "type" "multi")
9781   (set_attr "length" "52")])
9782
9783;; An out-of-line prologue.
9784(define_insn "outline_prologue_call"
9785  [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9786   (clobber (reg:SI 31))
9787   (clobber (reg:SI 22))
9788   (clobber (reg:SI 21))
9789   (clobber (reg:SI 20))
9790   (clobber (reg:SI 19))
9791   (clobber (reg:SI 1))]
9792  ""
9793  "*
9794{
9795
9796  /* We need two different versions depending on whether or not we
9797     need a frame pointer.   Also note that we return to the instruction
9798     immediately after the branch rather than two instructions after the
9799     break as normally is the case.  */
9800  if (frame_pointer_needed)
9801    {
9802      /* Must import the magic millicode routine(s).  */
9803      output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9804
9805      if (TARGET_PORTABLE_RUNTIME)
9806	{
9807	  output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9808	  output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9809			   NULL);
9810	}
9811      else
9812	output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9813    }
9814  else
9815    {
9816      /* Must import the magic millicode routine(s).  */
9817      output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9818
9819      if (TARGET_PORTABLE_RUNTIME)
9820	{
9821	  output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9822	  output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9823	}
9824      else
9825	output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9826    }
9827  return \"\";
9828}"
9829  [(set_attr "type" "multi")
9830   (set_attr "length" "8")])
9831
9832;; An out-of-line epilogue.
9833(define_insn "outline_epilogue_call"
9834  [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9835   (use (reg:SI 29))
9836   (use (reg:SI 28))
9837   (clobber (reg:SI 31))
9838   (clobber (reg:SI 22))
9839   (clobber (reg:SI 21))
9840   (clobber (reg:SI 20))
9841   (clobber (reg:SI 19))
9842   (clobber (reg:SI 2))
9843   (clobber (reg:SI 1))]
9844  ""
9845  "*
9846{
9847
9848  /* We need two different versions depending on whether or not we
9849     need a frame pointer.   Also note that we return to the instruction
9850     immediately after the branch rather than two instructions after the
9851     break as normally is the case.  */
9852  if (frame_pointer_needed)
9853    {
9854      /* Must import the magic millicode routine.  */
9855      output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9856
9857      /* The out-of-line prologue will make sure we return to the right
9858	 instruction.  */
9859      if (TARGET_PORTABLE_RUNTIME)
9860	{
9861	  output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9862	  output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9863			   NULL);
9864	}
9865      else
9866	output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9867    }
9868  else
9869    {
9870      /* Must import the magic millicode routine.  */
9871      output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9872
9873      /* The out-of-line prologue will make sure we return to the right
9874	 instruction.  */
9875      if (TARGET_PORTABLE_RUNTIME)
9876	{
9877	  output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9878	  output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9879	}
9880      else
9881	output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9882    }
9883  return \"\";
9884}"
9885  [(set_attr "type" "multi")
9886   (set_attr "length" "8")])
9887
9888;; Given a function pointer, canonicalize it so it can be
9889;; reliably compared to another function pointer.  */
9890(define_expand "canonicalize_funcptr_for_compare"
9891  [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9892   (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9893	      (clobber (match_dup 2))
9894	      (clobber (reg:SI 26))
9895	      (clobber (reg:SI 22))
9896	      (clobber (reg:SI 31))])
9897   (set (match_operand:SI 0 "register_operand" "")
9898	(reg:SI 29))]
9899  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9900  "
9901{
9902  if (TARGET_ELF32)
9903    {
9904      rtx canonicalize_funcptr_for_compare_libfunc
9905        = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9906
9907      emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9908      			       operands[0], LCT_NORMAL, Pmode,
9909			       operands[1], Pmode);
9910      DONE;
9911    }
9912
9913  operands[2] = gen_reg_rtx (SImode);
9914  if (GET_CODE (operands[1]) != REG)
9915    {
9916      rtx tmp = gen_reg_rtx (Pmode);
9917      emit_move_insn (tmp, operands[1]);
9918      operands[1] = tmp;
9919    }
9920}")
9921
9922(define_insn "*$$sh_func_adrs"
9923  [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9924   (clobber (match_operand:SI 0 "register_operand" "=a"))
9925   (clobber (reg:SI 26))
9926   (clobber (reg:SI 22))
9927   (clobber (reg:SI 31))]
9928  "!TARGET_64BIT"
9929  "*
9930{
9931  int length = get_attr_length (insn);
9932  rtx xoperands[2];
9933
9934  xoperands[0] = GEN_INT (length - 8);
9935  xoperands[1] = GEN_INT (length - 16);
9936
9937  /* Must import the magic millicode routine.  */
9938  output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9939
9940  /* This is absolutely amazing.
9941
9942     First, copy our input parameter into %r29 just in case we don't
9943     need to call $$sh_func_adrs.  */
9944  output_asm_insn (\"copy %%r26,%%r29\", NULL);
9945  output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9946
9947  /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9948     we use %r26 unchanged.  */
9949  output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9950  output_asm_insn (\"ldi 4096,%%r31\", NULL);
9951
9952  /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9953     4096, then again we use %r26 unchanged.  */
9954  output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9955
9956  /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
9957  return pa_output_millicode_call (insn,
9958				   gen_rtx_SYMBOL_REF (SImode,
9959						       \"$$sh_func_adrs\"));
9960}"
9961  [(set_attr "type" "sh_func_adrs")
9962   (set (attr "length")
9963	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
9964	      (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9965		    (const_int 20))))])
9966
9967;; On the PA, the PIC register is call clobbered, so it must
9968;; be saved & restored around calls by the caller.  If the call
9969;; doesn't return normally (nonlocal goto, or an exception is
9970;; thrown), then the code at the exception handler label must
9971;; restore the PIC register.
9972(define_expand "exception_receiver"
9973  [(const_int 4)]
9974  "flag_pic"
9975  "
9976{
9977  /* On the 64-bit port, we need a blockage because there is
9978     confusion regarding the dependence of the restore on the
9979     frame pointer.  As a result, the frame pointer and pic
9980     register restores sometimes are interchanged erroneously.  */
9981  if (TARGET_64BIT)
9982    emit_insn (gen_blockage ());
9983  /* Restore the PIC register using hppa_pic_save_rtx ().  The
9984     PIC register is not saved in the frame in 64-bit ABI.  */
9985  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9986  emit_insn (gen_blockage ());
9987  DONE;
9988}")
9989
9990(define_expand "builtin_setjmp_receiver"
9991  [(label_ref (match_operand 0 "" ""))]
9992  "flag_pic"
9993  "
9994{
9995  if (TARGET_64BIT)
9996    emit_insn (gen_blockage ());
9997  /* Restore the PIC register.  Hopefully, this will always be from
9998     a stack slot.  The only registers that are valid after a
9999     builtin_longjmp are the stack and frame pointers.  */
10000  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10001  emit_insn (gen_blockage ());
10002  DONE;
10003}")
10004
10005;; Allocate new stack space and update the saved stack pointer in the
10006;; frame marker.  The HP C compilers also copy additional words in the
10007;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10008;; The 32-bit compiler copies the word at -16 (Static Link).  We
10009;; currently don't copy these values.
10010;;
10011;; Since the copy of the frame marker can't be done atomically, I
10012;; suspect that using it for unwind purposes may be somewhat unreliable.
10013;; The HP compilers appear to raise the stack and copy the frame
10014;; marker in a strict instruction sequence.  This suggests that the
10015;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10016;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10017;; as GAS doesn't support it, or try to keep the instructions emitted
10018;; here in strict sequence.
10019(define_expand "allocate_stack"
10020  [(match_operand 0 "" "")
10021   (match_operand 1 "" "")]
10022  ""
10023  "
10024{
10025  rtx addr;
10026
10027  /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10028     in operand 0 before adjusting the stack.  */
10029  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10030  anti_adjust_stack (operands[1]);
10031  if (TARGET_HPUX_UNWIND_LIBRARY)
10032    {
10033      addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10034			   GEN_INT (TARGET_64BIT ? -8 : -4));
10035      emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10036    }
10037  if (!TARGET_64BIT && flag_pic)
10038    {
10039      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10040      emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10041    }
10042  DONE;
10043}")
10044
10045(define_expand "prefetch"
10046  [(match_operand 0 "address_operand" "")
10047   (match_operand 1 "const_int_operand" "")
10048   (match_operand 2 "const_int_operand" "")]
10049  "TARGET_PA_20"
10050{
10051  operands[0] = copy_addr_to_reg (operands[0]);
10052  emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10053  DONE;
10054})
10055
10056(define_insn "prefetch_20"
10057  [(prefetch (match_operand 0 "pmode_register_operand" "r")
10058	     (match_operand:SI 1 "const_int_operand" "n")
10059	     (match_operand:SI 2 "const_int_operand" "n"))]
10060  "TARGET_PA_20"
10061{
10062  /* The SL cache-control completer indicates good spatial locality but
10063     poor temporal locality.  The ldw instruction with a target of general
10064     register 0 prefetches a cache line for a read.  The ldd instruction
10065     prefetches a cache line for a write.  */
10066  static const char * const instr[2][2] = {
10067    {
10068      "ldw,sl 0(%0),%%r0",
10069      "ldd,sl 0(%0),%%r0"
10070    },
10071    {
10072      "ldw 0(%0),%%r0",
10073      "ldd 0(%0),%%r0"
10074    }
10075  };
10076  int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10077  int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10078
10079  return instr [locality][read_or_write];
10080}
10081  [(set_attr "type" "load")
10082   (set_attr "length" "4")])
10083
10084;; TLS Support
10085(define_insn "tgd_load"
10086 [(set (match_operand:SI 0 "register_operand" "=r")
10087       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10088  (clobber (reg:SI 1))
10089  (use (reg:SI 27))]
10090  ""
10091  "*
10092{
10093  return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10094}"
10095  [(set_attr "type" "multi")
10096   (set_attr "length" "8")])
10097
10098(define_insn "tgd_load_pic"
10099 [(set (match_operand:SI 0 "register_operand" "=r")
10100       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10101  (clobber (reg:SI 1))
10102  (use (reg:SI 19))]
10103  ""
10104  "*
10105{
10106  return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10107}"
10108  [(set_attr "type" "multi")
10109   (set_attr "length" "8")])
10110
10111(define_insn "tld_load"
10112 [(set (match_operand:SI 0 "register_operand" "=r")
10113       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10114  (clobber (reg:SI 1))
10115  (use (reg:SI 27))]
10116  ""
10117  "*
10118{
10119  return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10120}"
10121  [(set_attr "type" "multi")
10122   (set_attr "length" "8")])
10123
10124(define_insn "tld_load_pic"
10125 [(set (match_operand:SI 0 "register_operand" "=r")
10126       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10127  (clobber (reg:SI 1))
10128  (use (reg:SI 19))]
10129  ""
10130  "*
10131{
10132  return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10133}"
10134  [(set_attr "type" "multi")
10135   (set_attr "length" "8")])
10136
10137(define_insn "tld_offset_load"
10138  [(set (match_operand:SI 0 "register_operand" "=r")
10139        (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
10140		 	    UNSPEC_TLSLDO)
10141		 (match_operand:SI 2 "register_operand" "r")))
10142   (clobber (reg:SI 1))]
10143  ""
10144  "*
10145{
10146  return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
10147}"
10148  [(set_attr "type" "multi")
10149   (set_attr "length" "8")])
10150
10151(define_insn "tp_load"
10152  [(set (match_operand:SI 0 "register_operand" "=r")
10153	(unspec:SI [(const_int 0)] UNSPEC_TP))]
10154  ""
10155  "mfctl %%cr27,%0"
10156  [(set_attr "type" "multi")
10157   (set_attr "length" "4")])
10158
10159(define_insn "tie_load"
10160  [(set (match_operand:SI 0 "register_operand" "=r")
10161        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10162   (clobber (reg:SI 1))
10163   (use (reg:SI 27))]
10164  ""
10165  "*
10166{
10167  return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10168}"
10169  [(set_attr "type" "multi")
10170   (set_attr "length" "8")])
10171
10172(define_insn "tie_load_pic"
10173  [(set (match_operand:SI 0 "register_operand" "=r")
10174        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10175   (clobber (reg:SI 1))
10176   (use (reg:SI 19))]
10177  ""
10178  "*
10179{
10180  return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10181}"
10182  [(set_attr "type" "multi")
10183   (set_attr "length" "8")])
10184
10185(define_insn "tle_load"
10186  [(set (match_operand:SI 0 "register_operand" "=r")
10187        (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
10188		 	    UNSPEC_TLSLE)
10189		 (match_operand:SI 2 "register_operand" "r")))
10190   (clobber (reg:SI 1))]
10191  ""
10192  "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10193  [(set_attr "type" "multi")
10194   (set_attr "length" "8")])
10195
10196;; Atomic instructions
10197
10198;; All memory loads and stores access storage atomically except
10199;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10200;; doubleword loads and stores are not guaranteed to be atomic
10201;; when referencing the I/O address space.
10202
10203;; These patterns are at the bottom so the non atomic versions are preferred.
10204
10205(define_expand "atomic_storeqi"
10206  [(match_operand:QI 0 "memory_operand")                ;; memory
10207   (match_operand:QI 1 "register_operand")              ;; val out
10208   (match_operand:SI 2 "const_int_operand")]            ;; model
10209  ""
10210{
10211  if (TARGET_SYNC_LIBCALL)
10212    {
10213      rtx mem = operands[0];
10214      rtx val = operands[1];
10215      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10216	DONE;
10217    }
10218  FAIL;
10219})
10220
10221;; Implement atomic HImode stores using exchange.
10222
10223(define_expand "atomic_storehi"
10224  [(match_operand:HI 0 "memory_operand")                ;; memory
10225   (match_operand:HI 1 "register_operand")              ;; val out
10226   (match_operand:SI 2 "const_int_operand")]            ;; model
10227  ""
10228{
10229  if (TARGET_SYNC_LIBCALL)
10230    {
10231      rtx mem = operands[0];
10232      rtx val = operands[1];
10233      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10234	DONE;
10235    }
10236  FAIL;
10237})
10238
10239;; Implement atomic SImode store using exchange.
10240
10241(define_expand "atomic_storesi"
10242  [(match_operand:SI 0 "memory_operand")                ;; memory
10243   (match_operand:SI 1 "register_operand")              ;; val out
10244   (match_operand:SI 2 "const_int_operand")]            ;; model
10245  ""
10246{
10247  if (TARGET_SYNC_LIBCALL)
10248    {
10249      rtx mem = operands[0];
10250      rtx val = operands[1];
10251      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10252	DONE;
10253    }
10254  FAIL;
10255})
10256
10257;; Implement atomic DImode load.
10258
10259(define_expand "atomic_loaddi"
10260  [(match_operand:DI 0 "register_operand")              ;; val out
10261   (match_operand:DI 1 "memory_operand")                ;; memory
10262   (match_operand:SI 2 "const_int_operand")]            ;; model
10263  ""
10264{
10265  enum memmodel model;
10266
10267  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
10268    FAIL;
10269
10270  model = memmodel_from_int (INTVAL (operands[2]));
10271  operands[1] = force_reg (SImode, XEXP (operands[1], 0));
10272  if (is_mm_seq_cst (model))
10273    expand_mem_thread_fence (model);
10274  emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10275  expand_mem_thread_fence (model);
10276  DONE;
10277})
10278
10279(define_insn "atomic_loaddi_1"
10280  [(set (match_operand:DI 0 "register_operand" "=r")
10281        (mem:DI (match_operand:SI 1 "register_operand" "r")))
10282   (clobber (match_scratch:DI 2 "=f"))]
10283  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
10284  "{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"
10285  [(set_attr "type" "move")
10286   (set_attr "length" "16")])
10287
10288;; Implement atomic DImode store.
10289
10290(define_expand "atomic_storedi"
10291  [(match_operand:DI 0 "memory_operand")                ;; memory
10292   (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10293   (match_operand:SI 2 "const_int_operand")]            ;; model
10294  ""
10295{
10296  enum memmodel model;
10297
10298  if (TARGET_SYNC_LIBCALL)
10299    {
10300      rtx mem = operands[0];
10301      rtx val = operands[1];
10302      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10303	DONE;
10304    }
10305
10306  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
10307    FAIL;
10308
10309  model = memmodel_from_int (INTVAL (operands[2]));
10310  operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10311  if (operands[1] != CONST0_RTX (DImode))
10312    operands[1] = force_reg (DImode, operands[1]);
10313  expand_mem_thread_fence (model);
10314  emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10315  if (is_mm_seq_cst (model))
10316    expand_mem_thread_fence (model);
10317  DONE;
10318})
10319
10320(define_insn "atomic_storedi_1"
10321  [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10322        (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10323   (clobber (match_scratch:DI 2 "=X,f"))]
10324  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
10325  "@
10326   {fstds|fstd} %%fr0,0(%0)
10327   {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)"
10328  [(set_attr "type" "move,move")
10329   (set_attr "length" "4,16")])
10330
10331;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10332;; we need memory barriers to enforce program order for memory references
10333;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10334;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10335;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10336;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10337
10338;; When barriers are needed, we use a strongly ordered ldcw instruction as
10339;; the barrier.  Most PA 2.0 targets are cache coherent.  In that case, we
10340;; can use the coherent cache control hint and avoid aligning the ldcw
10341;; address.  In spite of its description, it is not clear that the sync
10342;; instruction works as a barrier.
10343
10344(define_expand "memory_barrier"
10345  [(parallel
10346     [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10347      (clobber (match_dup 1))])]
10348  ""
10349{
10350  /* We don't need a barrier if the target uses ordered memory references.  */
10351  if (TARGET_ORDERED)
10352    FAIL;
10353  operands[1] = gen_reg_rtx (Pmode);
10354  operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10355  MEM_VOLATILE_P (operands[0]) = 1;
10356})
10357
10358(define_insn "*memory_barrier_coherent"
10359  [(set (match_operand:BLK 0 "" "")
10360        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10361   (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10362  "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10363  "ldcw,co 0(%%sp),%1"
10364  [(set_attr "type" "binary")
10365   (set_attr "length" "4")])
10366
10367(define_insn "*memory_barrier_64"
10368  [(set (match_operand:BLK 0 "" "")
10369        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10370    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10371  "TARGET_64BIT"
10372  "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw 0(%1),%1"
10373  [(set_attr "type" "binary")
10374   (set_attr "length" "12")])
10375
10376(define_insn "*memory_barrier_32"
10377  [(set (match_operand:BLK 0 "" "")
10378        (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10379    (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10380  ""
10381  "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\tldcw 0(%1),%1"
10382  [(set_attr "type" "binary")
10383   (set_attr "length" "12")])
10384