xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/pa/pa.md (revision 7c192b2a5e1093666e67801684f930ef49b3b363)
1;;- Machine description for HP PA-RISC architecture for GCC compiler
2;;   Copyright (C) 1992-2015 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  ])
88
89;; UNSPEC_VOLATILE:
90
91(define_c_enum "unspecv"
92  [UNSPECV_BLOCKAGE	; blockage
93   UNSPECV_DCACHE	; dcacheflush
94   UNSPECV_ICACHE	; icacheflush
95   UNSPECV_OPC		; outline_prologue_call
96   UNSPECV_OEC		; outline_epilogue_call
97   UNSPECV_LONGJMP	; builtin_longjmp
98  ])
99
100;; Maximum pc-relative branch offsets.
101
102;; These numbers are a bit smaller than the maximum allowable offsets
103;; so that a few instructions may be inserted before the actual branch.
104
105(define_constants
106  [(MAX_12BIT_OFFSET     8184)	; 12-bit branch
107   (MAX_17BIT_OFFSET   262100)	; 17-bit branch
108  ])
109
110;; Mode and code iterators
111
112;; This mode iterator allows :P to be used for patterns that operate on
113;; pointer-sized quantities.  Exactly one of the two alternatives will match.
114(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
115
116;; This attribute defines the condition prefix for word and double word
117;; add, compare, subtract and logical instructions.
118(define_mode_attr dwc [(SI "") (DI "*")])
119
120;; Insn type.  Used to default other attribute values.
121
122;; type "unary" insns have one input operand (1) and one output operand (0)
123;; type "binary" insns have two input operands (1,2) and one output (0)
124
125(define_attr "type"
126  "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"
127  (const_string "binary"))
128
129(define_attr "pa_combine_type"
130  "fmpy,faddsub,uncond_branch,addmove,none"
131  (const_string "none"))
132
133;; Processor type (for scheduling, not code generation) -- this attribute
134;; must exactly match the processor_type enumeration in pa.h.
135;;
136;; FIXME: Add 800 scheduling for completeness?
137
138(define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
139
140;; Length (in # of bytes).
141(define_attr "length" ""
142  (cond [(eq_attr "type" "load,fpload")
143	 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
144		       (const_int 8) (const_int 4))
145
146	 (eq_attr "type" "store,fpstore")
147	 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
148		       (const_int 8) (const_int 4))
149
150	 (eq_attr "type" "binary,shift,nullshift")
151	 (if_then_else (match_operand 2 "arith14_operand" "")
152		       (const_int 4) (const_int 12))
153
154	 (eq_attr "type" "move,unary,shift,nullshift")
155	 (if_then_else (match_operand 1 "arith14_operand" "")
156		       (const_int 4) (const_int 8))]
157
158	(const_int 4)))
159
160(define_asm_attributes
161  [(set_attr "length" "4")
162   (set_attr "type" "multi")])
163
164;; Attributes for instruction and branch scheduling
165
166;; For conditional branches. Frame related instructions are not allowed
167;; because they confuse the unwind support.
168(define_attr "in_branch_delay" "false,true"
169  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
170		     (eq_attr "length" "4")
171		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
172		(const_string "true")
173		(const_string "false")))
174
175;; Disallow instructions which use the FPU since they will tie up the FPU
176;; even if the instruction is nullified.
177(define_attr "in_nullified_branch_delay" "false,true"
178  (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")
179		     (eq_attr "length" "4")
180		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
181		(const_string "true")
182		(const_string "false")))
183
184;; For calls and millicode calls.
185(define_attr "in_call_delay" "false,true"
186  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
187		     (eq_attr "length" "4")
188		     (not (match_test "RTX_FRAME_RELATED_P (insn)")))
189		(const_string "true")
190		(const_string "false")))
191
192;; Call delay slot description.
193(define_delay (eq_attr "type" "call")
194  [(eq_attr "in_call_delay" "true") (nil) (nil)])
195
196;; Sibcall delay slot description.
197(define_delay (eq_attr "type" "sibcall")
198  [(eq_attr "in_call_delay" "true") (nil) (nil)])
199
200;; Millicode call delay slot description.
201(define_delay (eq_attr "type" "milli")
202  [(eq_attr "in_call_delay" "true") (nil) (nil)])
203
204;; Return and other similar instructions.
205(define_delay (eq_attr "type" "branch,parallel_branch")
206  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
207
208;; Floating point conditional branch delay slot description.
209(define_delay (eq_attr "type" "fbranch")
210  [(eq_attr "in_branch_delay" "true")
211   (eq_attr "in_nullified_branch_delay" "true")
212   (nil)])
213
214;; Integer conditional branch delay slot description.
215;; Nullification of conditional branches on the PA is dependent on the
216;; direction of the branch.  Forward branches nullify true and
217;; backward branches nullify false.  If the direction is unknown
218;; then nullification is not allowed.
219(define_delay (eq_attr "type" "cbranch")
220  [(eq_attr "in_branch_delay" "true")
221   (and (eq_attr "in_nullified_branch_delay" "true")
222	(attr_flag "forward"))
223   (and (eq_attr "in_nullified_branch_delay" "true")
224	(attr_flag "backward"))])
225
226(define_delay (eq_attr "type" "uncond_branch")
227  [(eq_attr "in_branch_delay" "true") (nil) (nil)])
228
229;; Memory. Disregarding Cache misses, the Mustang memory times are:
230;; load: 2, fpload: 3
231;; store, fpstore: 3, no D-cache operations should be scheduled.
232
233;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
234;; Timings:
235;; Instruction	Time	Unit	Minimum Distance (unit contention)
236;; fcpy		3	ALU	2
237;; fabs		3	ALU	2
238;; fadd		3	ALU	2
239;; fsub		3	ALU	2
240;; fcmp		3	ALU	2
241;; fcnv		3	ALU	2
242;; fmpyadd	3	ALU,MPY	2
243;; fmpysub	3	ALU,MPY 2
244;; fmpycfxt	3	ALU,MPY 2
245;; fmpy		3	MPY	2
246;; fmpyi	3	MPY	2
247;; fdiv,sgl	10	MPY	10
248;; fdiv,dbl	12	MPY	12
249;; fsqrt,sgl	14	MPY	14
250;; fsqrt,dbl	18	MPY	18
251;;
252;; We don't model fmpyadd/fmpysub properly as those instructions
253;; keep both the FP ALU and MPY units busy.  Given that these
254;; processors are obsolete, I'm not going to spend the time to
255;; model those instructions correctly.
256
257(define_automaton "pa700")
258(define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
259
260(define_insn_reservation "W0" 4
261  (and (eq_attr "type" "fpcc")
262       (eq_attr "cpu" "700"))
263  "fpalu_700*2")
264
265(define_insn_reservation "W1" 3
266  (and (eq_attr "type" "fpalu")
267       (eq_attr "cpu" "700"))
268  "fpalu_700*2")
269
270(define_insn_reservation "W2" 3
271  (and (eq_attr "type" "fpmulsgl,fpmuldbl")
272       (eq_attr "cpu" "700"))
273  "fpmpy_700*2")
274
275(define_insn_reservation "W3" 10
276  (and (eq_attr "type" "fpdivsgl")
277       (eq_attr "cpu" "700"))
278  "fpmpy_700*10")
279
280(define_insn_reservation "W4" 12
281  (and (eq_attr "type" "fpdivdbl")
282       (eq_attr "cpu" "700"))
283  "fpmpy_700*12")
284
285(define_insn_reservation "W5" 14
286  (and (eq_attr "type" "fpsqrtsgl")
287       (eq_attr "cpu" "700"))
288  "fpmpy_700*14")
289
290(define_insn_reservation "W6" 18
291  (and (eq_attr "type" "fpsqrtdbl")
292       (eq_attr "cpu" "700"))
293  "fpmpy_700*18")
294
295(define_insn_reservation "W7" 2
296  (and (eq_attr "type" "load")
297       (eq_attr "cpu" "700"))
298  "mem_700")
299
300(define_insn_reservation "W8" 2
301  (and (eq_attr "type" "fpload")
302       (eq_attr "cpu" "700"))
303  "mem_700")
304
305(define_insn_reservation "W9" 3
306  (and (eq_attr "type" "store")
307       (eq_attr "cpu" "700"))
308  "mem_700*3")
309
310(define_insn_reservation "W10" 3
311  (and (eq_attr "type" "fpstore")
312       (eq_attr "cpu" "700"))
313  "mem_700*3")
314
315(define_insn_reservation "W11" 5
316  (and (eq_attr "type" "fpstore_load")
317       (eq_attr "cpu" "700"))
318  "mem_700*5")
319
320(define_insn_reservation "W12" 6
321  (and (eq_attr "type" "store_fpload")
322       (eq_attr "cpu" "700"))
323  "mem_700*6")
324
325(define_insn_reservation "W13" 1
326  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
327       (eq_attr "cpu" "700"))
328  "dummy_700")
329
330;; We have a bypass for all computations in the FP unit which feed an
331;; FP store as long as the sizes are the same.
332(define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
333(define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
334(define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
335(define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
336(define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
337
338;; We have an "anti-bypass" for FP loads which feed an FP store.
339(define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
340
341;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
342;; floating point computations with non-floating point computations (fp loads
343;; and stores are not fp computations).
344;;
345;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
346;; take two cycles, during which no Dcache operations should be scheduled.
347;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
348;; all have the same memory characteristics if one disregards cache misses.
349;;
350;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
351;; There's no value in modeling the ALU and MUL separately though
352;; since there can never be a functional unit conflict given the
353;; latency and issue rates for those units.
354;;
355;; Timings:
356;; Instruction	Time	Unit	Minimum Distance (unit contention)
357;; fcpy		2	ALU	1
358;; fabs		2	ALU	1
359;; fadd		2	ALU	1
360;; fsub		2	ALU	1
361;; fcmp		2	ALU	1
362;; fcnv		2	ALU	1
363;; fmpyadd	2	ALU,MPY	1
364;; fmpysub	2	ALU,MPY 1
365;; fmpycfxt	2	ALU,MPY 1
366;; fmpy		2	MPY	1
367;; fmpyi	2	MPY	1
368;; fdiv,sgl	8	DIV	8
369;; fdiv,dbl	15	DIV	15
370;; fsqrt,sgl	8	DIV	8
371;; fsqrt,dbl	15	DIV	15
372
373(define_automaton "pa7100")
374(define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
375
376(define_insn_reservation "X0" 2
377  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
378       (eq_attr "cpu" "7100"))
379  "f_7100,fpmac_7100")
380
381(define_insn_reservation "X1" 8
382  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
383       (eq_attr "cpu" "7100"))
384  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
385
386(define_insn_reservation "X2" 15
387  (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
388       (eq_attr "cpu" "7100"))
389  "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
390
391(define_insn_reservation "X3" 2
392  (and (eq_attr "type" "load")
393       (eq_attr "cpu" "7100"))
394  "i_7100+mem_7100")
395
396(define_insn_reservation "X4" 2
397  (and (eq_attr "type" "fpload")
398       (eq_attr "cpu" "7100"))
399  "i_7100+mem_7100")
400
401(define_insn_reservation "X5" 2
402  (and (eq_attr "type" "store")
403       (eq_attr "cpu" "7100"))
404  "i_7100+mem_7100,mem_7100")
405
406(define_insn_reservation "X6" 2
407  (and (eq_attr "type" "fpstore")
408       (eq_attr "cpu" "7100"))
409  "i_7100+mem_7100,mem_7100")
410
411(define_insn_reservation "X7" 4
412  (and (eq_attr "type" "fpstore_load")
413       (eq_attr "cpu" "7100"))
414  "i_7100+mem_7100,mem_7100*3")
415
416(define_insn_reservation "X8" 4
417  (and (eq_attr "type" "store_fpload")
418       (eq_attr "cpu" "7100"))
419  "i_7100+mem_7100,mem_7100*3")
420
421(define_insn_reservation "X9" 1
422  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
423       (eq_attr "cpu" "7100"))
424  "i_7100")
425
426;; We have a bypass for all computations in the FP unit which feed an
427;; FP store as long as the sizes are the same.
428(define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
429(define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
430(define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
431
432;; We have an "anti-bypass" for FP loads which feed an FP store.
433(define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
434
435;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
436;; There's no value in modeling the ALU and MUL separately though
437;; since there can never be a functional unit conflict that
438;; can be avoided given the latency, issue rates and mandatory
439;; one cycle cpu-wide lock for a double precision fp multiply.
440;;
441;; Timings:
442;; Instruction	Time	Unit	Minimum Distance (unit contention)
443;; fcpy		2	ALU	1
444;; fabs		2	ALU	1
445;; fadd		2	ALU	1
446;; fsub		2	ALU	1
447;; fcmp		2	ALU	1
448;; fcnv		2	ALU	1
449;; fmpyadd,sgl	2	ALU,MPY	1
450;; fmpyadd,dbl	3	ALU,MPY	2
451;; fmpysub,sgl	2	ALU,MPY 1
452;; fmpysub,dbl	3	ALU,MPY 2
453;; fmpycfxt,sgl	2	ALU,MPY 1
454;; fmpycfxt,dbl	3	ALU,MPY 2
455;; fmpy,sgl	2	MPY	1
456;; fmpy,dbl	3	MPY	2
457;; fmpyi	3	MPY	2
458;; fdiv,sgl	8	DIV	8
459;; fdiv,dbl	15	DIV	15
460;; fsqrt,sgl	8	DIV	8
461;; fsqrt,dbl	15	DIV	15
462;;
463;; The PA7200 is just like the PA7100LC except that there is
464;; no store-store penalty.
465;;
466;; The PA7300 is just like the PA7200 except that there is
467;; no store-load penalty.
468;;
469;; Note there are some aspects of the 7100LC we are not modeling
470;; at the moment.  I'll be reviewing the 7100LC scheduling info
471;; shortly and updating this description.
472;;
473;;   load-load pairs
474;;   store-store pairs
475;;   other issue modeling
476
477(define_automaton "pa7100lc")
478(define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
479(define_cpu_unit "fpmac_7100lc" "pa7100lc")
480(define_cpu_unit "mem_7100lc" "pa7100lc")
481
482;; Double precision multiplies lock the entire CPU for one
483;; cycle.  There is no way to avoid this lock and trying to
484;; schedule around the lock is pointless and thus there is no
485;; value in trying to model this lock.
486;;
487;; Not modeling the lock allows us to treat fp multiplies just
488;; like any other FP alu instruction.  It allows for a smaller
489;; DFA and may reduce register pressure.
490(define_insn_reservation "Y0" 2
491  (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
492       (eq_attr "cpu" "7100LC,7200,7300"))
493  "f_7100lc,fpmac_7100lc")
494
495;; fp division and sqrt instructions lock the entire CPU for
496;; 7 cycles (single precision) or 14 cycles (double precision).
497;; There is no way to avoid this lock and trying to schedule
498;; around the lock is pointless and thus there is no value in
499;; trying to model this lock.  Not modeling the lock allows
500;; for a smaller DFA and may reduce register pressure.
501(define_insn_reservation "Y1" 1
502  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
503       (eq_attr "cpu" "7100LC,7200,7300"))
504  "f_7100lc")
505
506(define_insn_reservation "Y2" 2
507  (and (eq_attr "type" "load")
508       (eq_attr "cpu" "7100LC,7200,7300"))
509  "i1_7100lc+mem_7100lc")
510
511(define_insn_reservation "Y3" 2
512  (and (eq_attr "type" "fpload")
513       (eq_attr "cpu" "7100LC,7200,7300"))
514  "i1_7100lc+mem_7100lc")
515
516(define_insn_reservation "Y4" 2
517  (and (eq_attr "type" "store")
518       (eq_attr "cpu" "7100LC"))
519  "i1_7100lc+mem_7100lc,mem_7100lc")
520
521(define_insn_reservation "Y5" 2
522  (and (eq_attr "type" "fpstore")
523       (eq_attr "cpu" "7100LC"))
524  "i1_7100lc+mem_7100lc,mem_7100lc")
525
526(define_insn_reservation "Y6" 4
527  (and (eq_attr "type" "fpstore_load")
528       (eq_attr "cpu" "7100LC"))
529  "i1_7100lc+mem_7100lc,mem_7100lc*3")
530
531(define_insn_reservation "Y7" 4
532  (and (eq_attr "type" "store_fpload")
533       (eq_attr "cpu" "7100LC"))
534  "i1_7100lc+mem_7100lc,mem_7100lc*3")
535
536(define_insn_reservation "Y8" 1
537  (and (eq_attr "type" "shift,nullshift")
538       (eq_attr "cpu" "7100LC,7200,7300"))
539  "i1_7100lc")
540
541(define_insn_reservation "Y9" 1
542  (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
543       (eq_attr "cpu" "7100LC,7200,7300"))
544  "(i0_7100lc|i1_7100lc)")
545
546;; The 7200 has a store-load penalty
547(define_insn_reservation "Y10" 2
548  (and (eq_attr "type" "store")
549       (eq_attr "cpu" "7200"))
550  "i1_7100lc,mem_7100lc")
551
552(define_insn_reservation "Y11" 2
553  (and (eq_attr "type" "fpstore")
554       (eq_attr "cpu" "7200"))
555  "i1_7100lc,mem_7100lc")
556
557(define_insn_reservation "Y12" 4
558  (and (eq_attr "type" "fpstore_load")
559       (eq_attr "cpu" "7200"))
560  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
561
562(define_insn_reservation "Y13" 4
563  (and (eq_attr "type" "store_fpload")
564       (eq_attr "cpu" "7200"))
565  "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
566
567;; The 7300 has no penalty for store-store or store-load
568(define_insn_reservation "Y14" 2
569  (and (eq_attr "type" "store")
570       (eq_attr "cpu" "7300"))
571  "i1_7100lc")
572
573(define_insn_reservation "Y15" 2
574  (and (eq_attr "type" "fpstore")
575       (eq_attr "cpu" "7300"))
576  "i1_7100lc")
577
578(define_insn_reservation "Y16" 4
579  (and (eq_attr "type" "fpstore_load")
580       (eq_attr "cpu" "7300"))
581  "i1_7100lc,i1_7100lc+mem_7100lc")
582
583(define_insn_reservation "Y17" 4
584  (and (eq_attr "type" "store_fpload")
585       (eq_attr "cpu" "7300"))
586  "i1_7100lc,i1_7100lc+mem_7100lc")
587
588;; We have an "anti-bypass" for FP loads which feed an FP store.
589(define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
590
591;; Scheduling for the PA8000 is somewhat different than scheduling for a
592;; traditional architecture.
593;;
594;; The PA8000 has a large (56) entry reorder buffer that is split between
595;; memory and non-memory operations.
596;;
597;; The PA8000 can issue two memory and two non-memory operations per cycle to
598;; the function units, with the exception of branches and multi-output
599;; instructions.  The PA8000 can retire two non-memory operations per cycle
600;; and two memory operations per cycle, only one of which may be a store.
601;;
602;; Given the large reorder buffer, the processor can hide most latencies.
603;; According to HP, they've got the best results by scheduling for retirement
604;; bandwidth with limited latency scheduling for floating point operations.
605;; Latency for integer operations and memory references is ignored.
606;;
607;;
608;; We claim floating point operations have a 2 cycle latency and are
609;; fully pipelined, except for div and sqrt which are not pipelined and
610;; take from 17 to 31 cycles to complete.
611;;
612;; It's worth noting that there is no way to saturate all the functional
613;; units on the PA8000 as there is not enough issue bandwidth.
614
615(define_automaton "pa8000")
616(define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
617(define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
618(define_cpu_unit "store_8000" "pa8000")
619(define_cpu_unit "f0_8000, f1_8000" "pa8000")
620(define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
621(define_reservation "inm_8000" "inm0_8000 | inm1_8000")
622(define_reservation "im_8000" "im0_8000 | im1_8000")
623(define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
624(define_reservation "rm_8000" "rm0_8000 | rm1_8000")
625(define_reservation "f_8000" "f0_8000 | f1_8000")
626(define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
627
628;; We can issue any two memops per cycle, but we can only retire
629;; one memory store per cycle.  We assume that the reorder buffer
630;; will hide any memory latencies per HP's recommendation.
631(define_insn_reservation "Z0" 0
632  (and
633    (eq_attr "type" "load,fpload")
634    (eq_attr "cpu" "8000"))
635  "im_8000,rm_8000")
636
637(define_insn_reservation "Z1" 0
638  (and
639    (eq_attr "type" "store,fpstore")
640    (eq_attr "cpu" "8000"))
641  "im_8000,rm_8000+store_8000")
642
643(define_insn_reservation "Z2" 0
644  (and (eq_attr "type" "fpstore_load,store_fpload")
645       (eq_attr "cpu" "8000"))
646  "im_8000,rm_8000+store_8000,im_8000,rm_8000")
647
648;; We can issue and retire two non-memory operations per cycle with
649;; a few exceptions (branches).  This group catches those we want
650;; to assume have zero latency.
651(define_insn_reservation "Z3" 0
652  (and
653    (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")
654    (eq_attr "cpu" "8000"))
655  "inm_8000,rnm_8000")
656
657;; Branches use both slots in the non-memory issue and
658;; retirement unit.
659(define_insn_reservation "Z4" 0
660  (and
661    (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
662    (eq_attr "cpu" "8000"))
663  "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
664
665;; We partial latency schedule the floating point units.
666;; They can issue/retire two at a time in the non-memory
667;; units.  We fix their latency at 2 cycles and they
668;; are fully pipelined.
669(define_insn_reservation "Z5" 1
670 (and
671   (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
672   (eq_attr "cpu" "8000"))
673 "inm_8000,f_8000,rnm_8000")
674
675;; The fdivsqrt units are not pipelined and have a very long latency.
676;; To keep the DFA from exploding, we do not show all the
677;; reservations for the divsqrt unit.
678(define_insn_reservation "Z6" 17
679 (and
680   (eq_attr "type" "fpdivsgl,fpsqrtsgl")
681   (eq_attr "cpu" "8000"))
682 "inm_8000,fdivsqrt_8000*6,rnm_8000")
683
684(define_insn_reservation "Z7" 31
685 (and
686   (eq_attr "type" "fpdivdbl,fpsqrtdbl")
687   (eq_attr "cpu" "8000"))
688 "inm_8000,fdivsqrt_8000*6,rnm_8000")
689
690;; Operand and operator predicates and constraints
691
692(include "predicates.md")
693(include "constraints.md")
694
695;; Compare instructions.
696;; This controls RTL generation and register allocation.
697
698(define_insn ""
699  [(set (reg:CCFP 0)
700	(match_operator:CCFP 2 "comparison_operator"
701			     [(match_operand:SF 0 "reg_or_0_operand" "fG")
702			      (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
703  "! TARGET_SOFT_FLOAT"
704  "fcmp,sgl,%Y2 %f0,%f1"
705  [(set_attr "length" "4")
706   (set_attr "type" "fpcc")])
707
708(define_insn ""
709  [(set (reg:CCFP 0)
710	(match_operator:CCFP 2 "comparison_operator"
711			     [(match_operand:DF 0 "reg_or_0_operand" "fG")
712			      (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
713  "! TARGET_SOFT_FLOAT"
714  "fcmp,dbl,%Y2 %f0,%f1"
715  [(set_attr "length" "4")
716   (set_attr "type" "fpcc")])
717
718;; Provide a means to emit the movccfp0 and movccfp1 optimization
719;; placeholders.  This is necessary in rare situations when a
720;; placeholder is re-emitted (see PR 8705).
721
722(define_expand "movccfp"
723  [(set (reg:CCFP 0)
724	(match_operand 0 "const_int_operand" ""))]
725  "! TARGET_SOFT_FLOAT"
726  "
727{
728  if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
729    FAIL;
730}")
731
732;; The following patterns are optimization placeholders.  In almost
733;; all cases, the user of the condition code will be simplified and the
734;; original condition code setting insn should be eliminated.
735
736(define_insn "*movccfp0"
737  [(set (reg:CCFP 0)
738	(const_int 0))]
739  "! TARGET_SOFT_FLOAT"
740  "fcmp,dbl,= %%fr0,%%fr0"
741  [(set_attr "length" "4")
742   (set_attr "type" "fpcc")])
743
744(define_insn "*movccfp1"
745  [(set (reg:CCFP 0)
746	(const_int 1))]
747  "! TARGET_SOFT_FLOAT"
748  "fcmp,dbl,!= %%fr0,%%fr0"
749  [(set_attr "length" "4")
750   (set_attr "type" "fpcc")])
751
752;; scc insns.
753
754(define_expand "cstoresi4"
755  [(set (match_operand:SI 0 "register_operand")
756	(match_operator:SI 1 "ordered_comparison_operator"
757	 [(match_operand:SI 2 "reg_or_0_operand" "")
758	  (match_operand:SI 3 "arith5_operand" "")]))]
759  "!TARGET_64BIT"
760  "")
761
762;; Instruction canonicalization puts immediate operands second, which
763;; is the reverse of what we want.
764
765(define_insn "scc"
766  [(set (match_operand:SI 0 "register_operand" "=r")
767	(match_operator:SI 3 "comparison_operator"
768			   [(match_operand:SI 1 "reg_or_0_operand" "rM")
769			    (match_operand:SI 2 "arith11_operand" "rI")]))]
770  ""
771  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
772  [(set_attr "type" "binary")
773   (set_attr "length" "8")])
774
775(define_insn ""
776  [(set (match_operand:DI 0 "register_operand" "=r")
777	(match_operator:DI 3 "comparison_operator"
778			   [(match_operand:DI 1 "reg_or_0_operand" "rM")
779			    (match_operand:DI 2 "arith11_operand" "rI")]))]
780  "TARGET_64BIT"
781  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
782  [(set_attr "type" "binary")
783   (set_attr "length" "8")])
784
785(define_insn "iorscc"
786  [(set (match_operand:SI 0 "register_operand" "=r")
787	(ior:SI (match_operator:SI 3 "comparison_operator"
788				   [(match_operand:SI 1 "reg_or_0_operand" "rM")
789				    (match_operand:SI 2 "arith11_operand" "rI")])
790		(match_operator:SI 6 "comparison_operator"
791				   [(match_operand:SI 4 "reg_or_0_operand" "rM")
792				    (match_operand:SI 5 "arith11_operand" "rI")])))]
793  ""
794  "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
795  [(set_attr "type" "binary")
796   (set_attr "length" "12")])
797
798(define_insn ""
799  [(set (match_operand:DI 0 "register_operand" "=r")
800	(ior:DI (match_operator:DI 3 "comparison_operator"
801				   [(match_operand:DI 1 "reg_or_0_operand" "rM")
802				    (match_operand:DI 2 "arith11_operand" "rI")])
803		(match_operator:DI 6 "comparison_operator"
804				   [(match_operand:DI 4 "reg_or_0_operand" "rM")
805				    (match_operand:DI 5 "arith11_operand" "rI")])))]
806  "TARGET_64BIT"
807  "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
808  [(set_attr "type" "binary")
809   (set_attr "length" "12")])
810
811;; Combiner patterns for common operations performed with the output
812;; from an scc insn (negscc and incscc).
813(define_insn "negscc"
814  [(set (match_operand:SI 0 "register_operand" "=r")
815	(neg:SI (match_operator:SI 3 "comparison_operator"
816	       [(match_operand:SI 1 "reg_or_0_operand" "rM")
817		(match_operand:SI 2 "arith11_operand" "rI")])))]
818  ""
819  "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
820  [(set_attr "type" "binary")
821   (set_attr "length" "8")])
822
823(define_insn ""
824  [(set (match_operand:DI 0 "register_operand" "=r")
825	(neg:DI (match_operator:DI 3 "comparison_operator"
826	       [(match_operand:DI 1 "reg_or_0_operand" "rM")
827		(match_operand:DI 2 "arith11_operand" "rI")])))]
828  "TARGET_64BIT"
829  "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
830  [(set_attr "type" "binary")
831   (set_attr "length" "8")])
832
833;; Patterns for adding/subtracting the result of a boolean expression from
834;; a register.  First we have special patterns that make use of the carry
835;; bit, and output only two instructions.  For the cases we can't in
836;; general do in two instructions, the incscc pattern at the end outputs
837;; two or three instructions.
838
839(define_insn ""
840  [(set (match_operand:SI 0 "register_operand" "=r")
841	(plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
842			 (match_operand:SI 3 "arith11_operand" "rI"))
843		 (match_operand:SI 1 "register_operand" "r")))]
844  ""
845  "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
846  [(set_attr "type" "binary")
847   (set_attr "length" "8")])
848
849(define_insn ""
850  [(set (match_operand:DI 0 "register_operand" "=r")
851	(plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
852			 (match_operand:DI 3 "arith11_operand" "rI"))
853		 (match_operand:DI 1 "register_operand" "r")))]
854  "TARGET_64BIT"
855  "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
856  [(set_attr "type" "binary")
857   (set_attr "length" "8")])
858
859; This need only accept registers for op3, since canonicalization
860; replaces geu with gtu when op3 is an integer.
861(define_insn ""
862  [(set (match_operand:SI 0 "register_operand" "=r")
863	(plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
864			 (match_operand:SI 3 "register_operand" "r"))
865		 (match_operand:SI 1 "register_operand" "r")))]
866  ""
867  "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
868  [(set_attr "type" "binary")
869   (set_attr "length" "8")])
870
871(define_insn ""
872  [(set (match_operand:DI 0 "register_operand" "=r")
873	(plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
874			 (match_operand:DI 3 "register_operand" "r"))
875		 (match_operand:DI 1 "register_operand" "r")))]
876  "TARGET_64BIT"
877  "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
878  [(set_attr "type" "binary")
879   (set_attr "length" "8")])
880
881; Match only integers for op3 here.  This is used as canonical form of the
882; geu pattern when op3 is an integer.  Don't match registers since we can't
883; make better code than the general incscc pattern.
884(define_insn ""
885  [(set (match_operand:SI 0 "register_operand" "=r")
886	(plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
887			 (match_operand:SI 3 "int11_operand" "I"))
888		 (match_operand:SI 1 "register_operand" "r")))]
889  ""
890  "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
891  [(set_attr "type" "binary")
892   (set_attr "length" "8")])
893
894(define_insn ""
895  [(set (match_operand:DI 0 "register_operand" "=r")
896	(plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
897			 (match_operand:DI 3 "int11_operand" "I"))
898		 (match_operand:DI 1 "register_operand" "r")))]
899  "TARGET_64BIT"
900  "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
901  [(set_attr "type" "binary")
902   (set_attr "length" "8")])
903
904(define_insn "incscc"
905  [(set (match_operand:SI 0 "register_operand" "=r,r")
906 	(plus:SI (match_operator:SI 4 "comparison_operator"
907		    [(match_operand:SI 2 "register_operand" "r,r")
908		     (match_operand:SI 3 "arith11_operand" "rI,rI")])
909		 (match_operand:SI 1 "register_operand" "0,?r")))]
910  ""
911  "@
912   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
913   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
914  [(set_attr "type" "binary,binary")
915   (set_attr "length" "8,12")])
916
917(define_insn ""
918  [(set (match_operand:DI 0 "register_operand" "=r,r")
919 	(plus:DI (match_operator:DI 4 "comparison_operator"
920		    [(match_operand:DI 2 "register_operand" "r,r")
921		     (match_operand:DI 3 "arith11_operand" "rI,rI")])
922		 (match_operand:DI 1 "register_operand" "0,?r")))]
923  "TARGET_64BIT"
924  "@
925   cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
926   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
927  [(set_attr "type" "binary,binary")
928   (set_attr "length" "8,12")])
929
930(define_insn ""
931  [(set (match_operand:SI 0 "register_operand" "=r")
932	(minus:SI (match_operand:SI 1 "register_operand" "r")
933		  (gtu:SI (match_operand:SI 2 "register_operand" "r")
934			  (match_operand:SI 3 "arith11_operand" "rI"))))]
935  ""
936  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
937  [(set_attr "type" "binary")
938   (set_attr "length" "8")])
939
940(define_insn ""
941  [(set (match_operand:DI 0 "register_operand" "=r")
942	(minus:DI (match_operand:DI 1 "register_operand" "r")
943		  (gtu:DI (match_operand:DI 2 "register_operand" "r")
944			  (match_operand:DI 3 "arith11_operand" "rI"))))]
945  "TARGET_64BIT"
946  "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
947  [(set_attr "type" "binary")
948   (set_attr "length" "8")])
949
950(define_insn ""
951  [(set (match_operand:SI 0 "register_operand" "=r")
952	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
953			    (gtu:SI (match_operand:SI 2 "register_operand" "r")
954				    (match_operand:SI 3 "arith11_operand" "rI")))
955		  (match_operand:SI 4 "register_operand" "r")))]
956  ""
957  "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
958  [(set_attr "type" "binary")
959   (set_attr "length" "8")])
960
961(define_insn ""
962  [(set (match_operand:DI 0 "register_operand" "=r")
963	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
964			    (gtu:DI (match_operand:DI 2 "register_operand" "r")
965				    (match_operand:DI 3 "arith11_operand" "rI")))
966		  (match_operand:DI 4 "register_operand" "r")))]
967  "TARGET_64BIT"
968  "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
969  [(set_attr "type" "binary")
970   (set_attr "length" "8")])
971
972; This need only accept registers for op3, since canonicalization
973; replaces ltu with leu when op3 is an integer.
974(define_insn ""
975  [(set (match_operand:SI 0 "register_operand" "=r")
976	(minus:SI (match_operand:SI 1 "register_operand" "r")
977		  (ltu:SI (match_operand:SI 2 "register_operand" "r")
978			  (match_operand:SI 3 "register_operand" "r"))))]
979  ""
980  "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
981  [(set_attr "type" "binary")
982   (set_attr "length" "8")])
983
984(define_insn ""
985  [(set (match_operand:DI 0 "register_operand" "=r")
986	(minus:DI (match_operand:DI 1 "register_operand" "r")
987		  (ltu:DI (match_operand:DI 2 "register_operand" "r")
988			  (match_operand:DI 3 "register_operand" "r"))))]
989  "TARGET_64BIT"
990  "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
991  [(set_attr "type" "binary")
992   (set_attr "length" "8")])
993
994(define_insn ""
995  [(set (match_operand:SI 0 "register_operand" "=r")
996	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
997			    (ltu:SI (match_operand:SI 2 "register_operand" "r")
998				    (match_operand:SI 3 "register_operand" "r")))
999		  (match_operand:SI 4 "register_operand" "r")))]
1000  ""
1001  "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1002  [(set_attr "type" "binary")
1003   (set_attr "length" "8")])
1004
1005(define_insn ""
1006  [(set (match_operand:DI 0 "register_operand" "=r")
1007	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1008			    (ltu:DI (match_operand:DI 2 "register_operand" "r")
1009				    (match_operand:DI 3 "register_operand" "r")))
1010		  (match_operand:DI 4 "register_operand" "r")))]
1011  "TARGET_64BIT"
1012  "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1013  [(set_attr "type" "binary")
1014   (set_attr "length" "8")])
1015
1016; Match only integers for op3 here.  This is used as canonical form of the
1017; ltu pattern when op3 is an integer.  Don't match registers since we can't
1018; make better code than the general incscc pattern.
1019(define_insn ""
1020  [(set (match_operand:SI 0 "register_operand" "=r")
1021	(minus:SI (match_operand:SI 1 "register_operand" "r")
1022		  (leu:SI (match_operand:SI 2 "register_operand" "r")
1023			  (match_operand:SI 3 "int11_operand" "I"))))]
1024  ""
1025  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1026  [(set_attr "type" "binary")
1027   (set_attr "length" "8")])
1028
1029(define_insn ""
1030  [(set (match_operand:DI 0 "register_operand" "=r")
1031	(minus:DI (match_operand:DI 1 "register_operand" "r")
1032		  (leu:DI (match_operand:DI 2 "register_operand" "r")
1033			  (match_operand:DI 3 "int11_operand" "I"))))]
1034  "TARGET_64BIT"
1035  "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1036  [(set_attr "type" "binary")
1037   (set_attr "length" "8")])
1038
1039(define_insn ""
1040  [(set (match_operand:SI 0 "register_operand" "=r")
1041	(minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1042			    (leu:SI (match_operand:SI 2 "register_operand" "r")
1043				    (match_operand:SI 3 "int11_operand" "I")))
1044		  (match_operand:SI 4 "register_operand" "r")))]
1045  ""
1046  "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1047  [(set_attr "type" "binary")
1048   (set_attr "length" "8")])
1049
1050(define_insn ""
1051  [(set (match_operand:DI 0 "register_operand" "=r")
1052	(minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1053			    (leu:DI (match_operand:DI 2 "register_operand" "r")
1054				    (match_operand:DI 3 "int11_operand" "I")))
1055		  (match_operand:DI 4 "register_operand" "r")))]
1056  "TARGET_64BIT"
1057  "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1058  [(set_attr "type" "binary")
1059   (set_attr "length" "8")])
1060
1061(define_insn "decscc"
1062  [(set (match_operand:SI 0 "register_operand" "=r,r")
1063	(minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1064		  (match_operator:SI 4 "comparison_operator"
1065		     [(match_operand:SI 2 "register_operand" "r,r")
1066		      (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1067  ""
1068  "@
1069   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1070   {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1071  [(set_attr "type" "binary,binary")
1072   (set_attr "length" "8,12")])
1073
1074(define_insn ""
1075  [(set (match_operand:DI 0 "register_operand" "=r,r")
1076	(minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1077		  (match_operator:DI 4 "comparison_operator"
1078		     [(match_operand:DI 2 "register_operand" "r,r")
1079		      (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1080  "TARGET_64BIT"
1081  "@
1082   cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1083   cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1084  [(set_attr "type" "binary,binary")
1085   (set_attr "length" "8,12")])
1086
1087; Patterns for max and min.  (There is no need for an earlyclobber in the
1088; last alternative since the middle alternative will match if op0 == op1.)
1089
1090(define_insn "sminsi3"
1091  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1092	(smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1093		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1094  ""
1095  "@
1096  {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1097  {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1098  {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1099[(set_attr "type" "multi,multi,multi")
1100 (set_attr "length" "8,8,8")])
1101
1102(define_insn "smindi3"
1103  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1104	(smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1105		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1106  "TARGET_64BIT"
1107  "@
1108  cmpclr,*> %2,%0,%%r0\;copy %2,%0
1109  cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1110  cmpclr,*> %1,%r2,%0\;copy %1,%0"
1111[(set_attr "type" "multi,multi,multi")
1112 (set_attr "length" "8,8,8")])
1113
1114(define_insn "uminsi3"
1115  [(set (match_operand:SI 0 "register_operand" "=r,r")
1116	(umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1117		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1118  ""
1119  "@
1120  {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1121  {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1122[(set_attr "type" "multi,multi")
1123 (set_attr "length" "8,8")])
1124
1125(define_insn "umindi3"
1126  [(set (match_operand:DI 0 "register_operand" "=r,r")
1127	(umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1128		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1129  "TARGET_64BIT"
1130  "@
1131  cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1132  cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1133[(set_attr "type" "multi,multi")
1134 (set_attr "length" "8,8")])
1135
1136(define_insn "smaxsi3"
1137  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1138	(smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1139		 (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1140  ""
1141  "@
1142  {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1143  {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1144  {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1145[(set_attr "type" "multi,multi,multi")
1146 (set_attr "length" "8,8,8")])
1147
1148(define_insn "smaxdi3"
1149  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1150	(smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1151		 (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1152  "TARGET_64BIT"
1153  "@
1154  cmpclr,*< %2,%0,%%r0\;copy %2,%0
1155  cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1156  cmpclr,*< %1,%r2,%0\;copy %1,%0"
1157[(set_attr "type" "multi,multi,multi")
1158 (set_attr "length" "8,8,8")])
1159
1160(define_insn "umaxsi3"
1161  [(set (match_operand:SI 0 "register_operand" "=r,r")
1162	(umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1163		 (match_operand:SI 2 "arith11_operand" "r,I")))]
1164  ""
1165  "@
1166  {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1167  {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1168[(set_attr "type" "multi,multi")
1169 (set_attr "length" "8,8")])
1170
1171(define_insn "umaxdi3"
1172  [(set (match_operand:DI 0 "register_operand" "=r,r")
1173	(umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1174		 (match_operand:DI 2 "arith11_operand" "r,I")))]
1175  "TARGET_64BIT"
1176  "@
1177  cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1178  cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1179[(set_attr "type" "multi,multi")
1180 (set_attr "length" "8,8")])
1181
1182(define_insn "absqi2"
1183  [(set (match_operand:QI 0 "register_operand" "=r")
1184	(abs:QI (match_operand:QI 1 "register_operand" "r")))]
1185  ""
1186  "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1187  [(set_attr "type" "multi")
1188   (set_attr "length" "8")])
1189
1190(define_insn "abshi2"
1191  [(set (match_operand:HI 0 "register_operand" "=r")
1192	(abs:HI (match_operand:HI 1 "register_operand" "r")))]
1193  ""
1194  "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1195  [(set_attr "type" "multi")
1196   (set_attr "length" "8")])
1197
1198(define_insn "abssi2"
1199  [(set (match_operand:SI 0 "register_operand" "=r")
1200	(abs:SI (match_operand:SI 1 "register_operand" "r")))]
1201  ""
1202  "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1203  [(set_attr "type" "multi")
1204   (set_attr "length" "8")])
1205
1206(define_insn "absdi2"
1207  [(set (match_operand:DI 0 "register_operand" "=r")
1208	(abs:DI (match_operand:DI 1 "register_operand" "r")))]
1209  "TARGET_64BIT"
1210  "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1211  [(set_attr "type" "multi")
1212   (set_attr "length" "8")])
1213
1214(define_insn "bswaphi2"
1215  [(set (match_operand:HI 0 "register_operand" "=&r")
1216	(bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1217  ""
1218  "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1219  [(set_attr "type" "multi")
1220   (set_attr "length" "8")])
1221
1222(define_insn "bswapsi2"
1223  [(set (match_operand:SI 0 "register_operand" "=&r")
1224	(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1225  ""
1226  "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1227  [(set_attr "type" "multi")
1228   (set_attr "length" "12")])
1229
1230(define_insn "bswapdi2"
1231  [(set (match_operand:DI 0 "register_operand" "=&r")
1232	(bswap:DI (match_operand:DI 1 "register_operand" "r")))
1233   (clobber (match_scratch:DI 2 "=r"))]
1234  "TARGET_64BIT"
1235  "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1236  [(set_attr "type" "multi")
1237   (set_attr "length" "16")])
1238
1239;;; Experimental conditional move patterns
1240
1241(define_expand "movsicc"
1242  [(set (match_operand:SI 0 "register_operand" "")
1243	(if_then_else:SI
1244	 (match_operand 1 "comparison_operator" "")
1245	 (match_operand:SI 2 "reg_or_cint_move_operand" "")
1246	 (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1247  ""
1248  "
1249{
1250  if (GET_MODE (XEXP (operands[1], 0)) != SImode
1251      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1252    FAIL;
1253}")
1254
1255;; We used to accept any register for op1.
1256;;
1257;; However, it loses sometimes because the compiler will end up using
1258;; different registers for op0 and op1 in some critical cases.  local-alloc
1259;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1260;;
1261;; If/when global register allocation supports tying we should allow any
1262;; register for op1 again.
1263(define_insn ""
1264  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1265	(if_then_else:SI
1266	 (match_operator 2 "comparison_operator"
1267	    [(match_operand:SI 3 "register_operand" "r,r,r,r")
1268	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1269	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1270	 (const_int 0)))]
1271  ""
1272  "@
1273   {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1274   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1275   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1276   {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1277  [(set_attr "type" "multi,multi,multi,nullshift")
1278   (set_attr "length" "8,8,8,8")])
1279
1280(define_insn ""
1281  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1282	(if_then_else:SI
1283	 (match_operator 5 "comparison_operator"
1284	    [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1285	     (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1286	 (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1287	 (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1288  ""
1289  "@
1290   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1291   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1292   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1293   {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1294   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1295   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1296   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1297   {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1298  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1299   (set_attr "length" "8,8,8,8,8,8,8,8")])
1300
1301(define_expand "movdicc"
1302  [(set (match_operand:DI 0 "register_operand" "")
1303	(if_then_else:DI
1304	 (match_operand 1 "comparison_operator" "")
1305	 (match_operand:DI 2 "reg_or_cint_move_operand" "")
1306	 (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1307  "TARGET_64BIT"
1308  "
1309{
1310  if (GET_MODE (XEXP (operands[1], 0)) != DImode
1311      || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1312    FAIL;
1313}")
1314
1315; We need the first constraint alternative in order to avoid
1316; earlyclobbers on all other alternatives.
1317(define_insn ""
1318  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1319	(if_then_else:DI
1320	 (match_operator 2 "comparison_operator"
1321	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1322	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1323	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1324	 (const_int 0)))]
1325  "TARGET_64BIT"
1326  "@
1327   cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1328   cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1329   cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1330   cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1331   cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1332  [(set_attr "type" "multi,multi,multi,multi,nullshift")
1333   (set_attr "length" "8,8,8,8,8")])
1334
1335(define_insn ""
1336  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1337	(if_then_else:DI
1338	 (match_operator 5 "comparison_operator"
1339	    [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1340	     (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1341	 (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1342	 (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1343  "TARGET_64BIT"
1344  "@
1345   cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1346   cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1347   cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1348   cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1349   cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1350   cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1351   cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1352   cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1353  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1354   (set_attr "length" "8,8,8,8,8,8,8,8")])
1355
1356;; Conditional Branches
1357
1358(define_expand "cbranchdi4"
1359  [(set (pc)
1360        (if_then_else (match_operator 0 "ordered_comparison_operator"
1361		       [(match_operand:DI 1 "reg_or_0_operand" "")
1362                        (match_operand:DI 2 "register_operand" "")])
1363		      (label_ref (match_operand 3 "" ""))
1364		      (pc)))]
1365  "TARGET_64BIT"
1366  "")
1367
1368(define_expand "cbranchsi4"
1369  [(set (pc)
1370        (if_then_else (match_operator 0 "ordered_comparison_operator"
1371		       [(match_operand:SI 1 "reg_or_0_operand" "")
1372                        (match_operand:SI 2 "arith5_operand" "")])
1373		      (label_ref (match_operand 3 "" ""))
1374		      (pc)))]
1375  ""
1376  "")
1377
1378(define_expand "cbranchsf4"
1379  [(set (pc)
1380        (if_then_else (match_operator 0 "comparison_operator"
1381		       [(match_operand:SF 1 "reg_or_0_operand" "")
1382                        (match_operand:SF 2 "reg_or_0_operand" "")])
1383		      (label_ref (match_operand 3 "" ""))
1384		      (pc)))]
1385  ""
1386  "
1387{
1388  pa_emit_bcond_fp (operands);
1389  DONE;
1390}")
1391
1392
1393(define_expand "cbranchdf4"
1394  [(set (pc)
1395        (if_then_else (match_operator 0 "comparison_operator"
1396		       [(match_operand:DF 1 "reg_or_0_operand" "")
1397                        (match_operand:DF 2 "reg_or_0_operand" "")])
1398		      (label_ref (match_operand 3 "" ""))
1399		      (pc)))]
1400  ""
1401  "
1402{
1403  pa_emit_bcond_fp (operands);
1404  DONE;
1405}")
1406
1407;; Match the branch patterns.
1408
1409
1410;; Note a long backward conditional branch with an annulled delay slot
1411;; has a length of 12.
1412(define_insn ""
1413  [(set (pc)
1414	(if_then_else
1415	 (match_operator 3 "comparison_operator"
1416			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1417			  (match_operand:SI 2 "arith5_operand" "rL")])
1418	 (label_ref (match_operand 0 "" ""))
1419	 (pc)))]
1420  ""
1421  "*
1422{
1423  return pa_output_cbranch (operands, 0, insn);
1424}"
1425[(set_attr "type" "cbranch")
1426 (set (attr "length")
1427    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1428	       (const_int MAX_12BIT_OFFSET))
1429	   (const_int 4)
1430	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1431	       (const_int MAX_17BIT_OFFSET))
1432	   (const_int 8)
1433	   (match_test "TARGET_PORTABLE_RUNTIME")
1434	   (const_int 24)
1435	   (not (match_test "flag_pic"))
1436	   (const_int 20)]
1437	  (const_int 28)))])
1438
1439;; Match the negated branch.
1440
1441(define_insn ""
1442  [(set (pc)
1443	(if_then_else
1444	 (match_operator 3 "comparison_operator"
1445			 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1446			  (match_operand:SI 2 "arith5_operand" "rL")])
1447	 (pc)
1448	 (label_ref (match_operand 0 "" ""))))]
1449  ""
1450  "*
1451{
1452  return pa_output_cbranch (operands, 1, insn);
1453}"
1454[(set_attr "type" "cbranch")
1455 (set (attr "length")
1456    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1457	       (const_int MAX_12BIT_OFFSET))
1458	   (const_int 4)
1459	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1460	       (const_int MAX_17BIT_OFFSET))
1461	   (const_int 8)
1462	   (match_test "TARGET_PORTABLE_RUNTIME")
1463	   (const_int 24)
1464	   (not (match_test "flag_pic"))
1465	   (const_int 20)]
1466	  (const_int 28)))])
1467
1468(define_insn ""
1469  [(set (pc)
1470	(if_then_else
1471	 (match_operator 3 "comparison_operator"
1472			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1473			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1474	 (label_ref (match_operand 0 "" ""))
1475	 (pc)))]
1476  "TARGET_64BIT"
1477  "*
1478{
1479  return pa_output_cbranch (operands, 0, insn);
1480}"
1481[(set_attr "type" "cbranch")
1482 (set (attr "length")
1483    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1484	       (const_int MAX_12BIT_OFFSET))
1485	   (const_int 4)
1486	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1487	       (const_int MAX_17BIT_OFFSET))
1488	   (const_int 8)
1489	   (match_test "TARGET_PORTABLE_RUNTIME")
1490	   (const_int 24)
1491	   (not (match_test "flag_pic"))
1492	   (const_int 20)]
1493	  (const_int 28)))])
1494
1495;; Match the negated branch.
1496
1497(define_insn ""
1498  [(set (pc)
1499	(if_then_else
1500	 (match_operator 3 "comparison_operator"
1501			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1502			  (match_operand:DI 2 "reg_or_0_operand" "rM")])
1503	 (pc)
1504	 (label_ref (match_operand 0 "" ""))))]
1505  "TARGET_64BIT"
1506  "*
1507{
1508  return pa_output_cbranch (operands, 1, insn);
1509}"
1510[(set_attr "type" "cbranch")
1511 (set (attr "length")
1512    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1513	       (const_int MAX_12BIT_OFFSET))
1514	   (const_int 4)
1515	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1516	       (const_int MAX_17BIT_OFFSET))
1517	   (const_int 8)
1518	   (match_test "TARGET_PORTABLE_RUNTIME")
1519	   (const_int 24)
1520	   (not (match_test "flag_pic"))
1521	   (const_int 20)]
1522	  (const_int 28)))])
1523(define_insn ""
1524  [(set (pc)
1525	(if_then_else
1526	 (match_operator 3 "cmpib_comparison_operator"
1527			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1528			  (match_operand:DI 2 "arith5_operand" "rL")])
1529	 (label_ref (match_operand 0 "" ""))
1530	 (pc)))]
1531  "TARGET_64BIT"
1532  "*
1533{
1534  return pa_output_cbranch (operands, 0, insn);
1535}"
1536[(set_attr "type" "cbranch")
1537 (set (attr "length")
1538    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1539	       (const_int MAX_12BIT_OFFSET))
1540	   (const_int 4)
1541	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1542	       (const_int MAX_17BIT_OFFSET))
1543	   (const_int 8)
1544	   (match_test "TARGET_PORTABLE_RUNTIME")
1545	   (const_int 24)
1546	   (not (match_test "flag_pic"))
1547	   (const_int 20)]
1548	  (const_int 28)))])
1549
1550;; Match the negated branch.
1551
1552(define_insn ""
1553  [(set (pc)
1554	(if_then_else
1555	 (match_operator 3 "cmpib_comparison_operator"
1556			 [(match_operand:DI 1 "reg_or_0_operand" "rM")
1557			  (match_operand:DI 2 "arith5_operand" "rL")])
1558	 (pc)
1559	 (label_ref (match_operand 0 "" ""))))]
1560  "TARGET_64BIT"
1561  "*
1562{
1563  return pa_output_cbranch (operands, 1, insn);
1564}"
1565[(set_attr "type" "cbranch")
1566 (set (attr "length")
1567    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1568	       (const_int MAX_12BIT_OFFSET))
1569	   (const_int 4)
1570	   (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1571	       (const_int MAX_17BIT_OFFSET))
1572	   (const_int 8)
1573	   (match_test "TARGET_PORTABLE_RUNTIME")
1574	   (const_int 24)
1575	   (not (match_test "flag_pic"))
1576	   (const_int 20)]
1577	  (const_int 28)))])
1578
1579;; Branch on Bit patterns.
1580(define_insn ""
1581  [(set (pc)
1582	(if_then_else
1583	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1584			      (const_int 1)
1585			      (match_operand:SI 1 "uint5_operand" ""))
1586	     (const_int 0))
1587	 (label_ref (match_operand 2 "" ""))
1588	 (pc)))]
1589  ""
1590  "*
1591{
1592  return pa_output_bb (operands, 0, insn, 0);
1593}"
1594[(set_attr "type" "cbranch")
1595 (set (attr "length")
1596    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1597	       (const_int MAX_12BIT_OFFSET))
1598	   (const_int 4)
1599	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1600	       (const_int MAX_17BIT_OFFSET))
1601	   (const_int 8)
1602	   (match_test "TARGET_PORTABLE_RUNTIME")
1603	   (const_int 24)
1604	   (not (match_test "flag_pic"))
1605	   (const_int 20)]
1606	  (const_int 28)))])
1607
1608(define_insn ""
1609  [(set (pc)
1610	(if_then_else
1611	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1612			      (const_int 1)
1613			      (match_operand:DI 1 "uint32_operand" ""))
1614	     (const_int 0))
1615	 (label_ref (match_operand 2 "" ""))
1616	 (pc)))]
1617  "TARGET_64BIT"
1618  "*
1619{
1620  return pa_output_bb (operands, 0, insn, 0);
1621}"
1622[(set_attr "type" "cbranch")
1623 (set (attr "length")
1624    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1625	       (const_int MAX_12BIT_OFFSET))
1626	   (const_int 4)
1627	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1628	       (const_int MAX_17BIT_OFFSET))
1629	   (const_int 8)
1630	   (match_test "TARGET_PORTABLE_RUNTIME")
1631	   (const_int 24)
1632	   (not (match_test "flag_pic"))
1633	   (const_int 20)]
1634	  (const_int 28)))])
1635
1636(define_insn ""
1637  [(set (pc)
1638	(if_then_else
1639	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1640			      (const_int 1)
1641			      (match_operand:SI 1 "uint5_operand" ""))
1642	     (const_int 0))
1643	 (pc)
1644	 (label_ref (match_operand 2 "" ""))))]
1645  ""
1646  "*
1647{
1648  return pa_output_bb (operands, 1, insn, 0);
1649}"
1650[(set_attr "type" "cbranch")
1651 (set (attr "length")
1652    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1653	       (const_int MAX_12BIT_OFFSET))
1654	   (const_int 4)
1655	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1656	       (const_int MAX_17BIT_OFFSET))
1657	   (const_int 8)
1658	   (match_test "TARGET_PORTABLE_RUNTIME")
1659	   (const_int 24)
1660	   (not (match_test "flag_pic"))
1661	   (const_int 20)]
1662	  (const_int 28)))])
1663
1664(define_insn ""
1665  [(set (pc)
1666	(if_then_else
1667	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1668			      (const_int 1)
1669			      (match_operand:DI 1 "uint32_operand" ""))
1670	     (const_int 0))
1671	 (pc)
1672	 (label_ref (match_operand 2 "" ""))))]
1673  "TARGET_64BIT"
1674  "*
1675{
1676  return pa_output_bb (operands, 1, insn, 0);
1677}"
1678[(set_attr "type" "cbranch")
1679 (set (attr "length")
1680    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1681	       (const_int MAX_12BIT_OFFSET))
1682	   (const_int 4)
1683	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1684	       (const_int MAX_17BIT_OFFSET))
1685	   (const_int 8)
1686	   (match_test "TARGET_PORTABLE_RUNTIME")
1687	   (const_int 24)
1688	   (not (match_test "flag_pic"))
1689	   (const_int 20)]
1690	  (const_int 28)))])
1691
1692(define_insn ""
1693  [(set (pc)
1694	(if_then_else
1695	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1696			      (const_int 1)
1697			      (match_operand:SI 1 "uint5_operand" ""))
1698	     (const_int 0))
1699	 (label_ref (match_operand 2 "" ""))
1700	 (pc)))]
1701  ""
1702  "*
1703{
1704  return pa_output_bb (operands, 0, insn, 1);
1705}"
1706[(set_attr "type" "cbranch")
1707 (set (attr "length")
1708    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1709	       (const_int MAX_12BIT_OFFSET))
1710	   (const_int 4)
1711	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1712	       (const_int MAX_17BIT_OFFSET))
1713	   (const_int 8)
1714	   (match_test "TARGET_PORTABLE_RUNTIME")
1715	   (const_int 24)
1716	   (not (match_test "flag_pic"))
1717	   (const_int 20)]
1718	  (const_int 28)))])
1719
1720(define_insn ""
1721  [(set (pc)
1722	(if_then_else
1723	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1724			      (const_int 1)
1725			      (match_operand:DI 1 "uint32_operand" ""))
1726	     (const_int 0))
1727	 (label_ref (match_operand 2 "" ""))
1728	 (pc)))]
1729  "TARGET_64BIT"
1730  "*
1731{
1732  return pa_output_bb (operands, 0, insn, 1);
1733}"
1734[(set_attr "type" "cbranch")
1735 (set (attr "length")
1736    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1737	       (const_int MAX_12BIT_OFFSET))
1738	   (const_int 4)
1739	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1740	       (const_int MAX_17BIT_OFFSET))
1741	   (const_int 8)
1742	   (match_test "TARGET_PORTABLE_RUNTIME")
1743	   (const_int 24)
1744	   (not (match_test "flag_pic"))
1745	   (const_int 20)]
1746	  (const_int 28)))])
1747
1748(define_insn ""
1749  [(set (pc)
1750	(if_then_else
1751	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1752			      (const_int 1)
1753			      (match_operand:SI 1 "uint5_operand" ""))
1754	     (const_int 0))
1755	 (pc)
1756	 (label_ref (match_operand 2 "" ""))))]
1757  ""
1758  "*
1759{
1760  return pa_output_bb (operands, 1, insn, 1);
1761}"
1762[(set_attr "type" "cbranch")
1763 (set (attr "length")
1764    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1765	       (const_int MAX_12BIT_OFFSET))
1766	   (const_int 4)
1767	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1768	       (const_int MAX_17BIT_OFFSET))
1769	   (const_int 8)
1770	   (match_test "TARGET_PORTABLE_RUNTIME")
1771	   (const_int 24)
1772	   (not (match_test "flag_pic"))
1773	   (const_int 20)]
1774	  (const_int 28)))])
1775
1776(define_insn ""
1777  [(set (pc)
1778	(if_then_else
1779	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1780			      (const_int 1)
1781			      (match_operand:DI 1 "uint32_operand" ""))
1782	     (const_int 0))
1783	 (pc)
1784	 (label_ref (match_operand 2 "" ""))))]
1785  "TARGET_64BIT"
1786  "*
1787{
1788  return pa_output_bb (operands, 1, insn, 1);
1789}"
1790[(set_attr "type" "cbranch")
1791 (set (attr "length")
1792    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1793	       (const_int MAX_12BIT_OFFSET))
1794	   (const_int 4)
1795	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1796	       (const_int MAX_17BIT_OFFSET))
1797	   (const_int 8)
1798	   (match_test "TARGET_PORTABLE_RUNTIME")
1799	   (const_int 24)
1800	   (not (match_test "flag_pic"))
1801	   (const_int 20)]
1802	  (const_int 28)))])
1803
1804;; Branch on Variable Bit patterns.
1805(define_insn ""
1806  [(set (pc)
1807	(if_then_else
1808	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1809			      (const_int 1)
1810			      (match_operand:SI 1 "register_operand" "q"))
1811	     (const_int 0))
1812	 (label_ref (match_operand 2 "" ""))
1813	 (pc)))]
1814  ""
1815  "*
1816{
1817  return pa_output_bvb (operands, 0, insn, 0);
1818}"
1819[(set_attr "type" "cbranch")
1820 (set (attr "length")
1821    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1822	       (const_int MAX_12BIT_OFFSET))
1823	   (const_int 4)
1824	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1825	       (const_int MAX_17BIT_OFFSET))
1826	   (const_int 8)
1827	   (match_test "TARGET_PORTABLE_RUNTIME")
1828	   (const_int 24)
1829	   (not (match_test "flag_pic"))
1830	   (const_int 20)]
1831	  (const_int 28)))])
1832
1833(define_insn ""
1834  [(set (pc)
1835	(if_then_else
1836	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1837			      (const_int 1)
1838			      (match_operand:DI 1 "register_operand" "q"))
1839	     (const_int 0))
1840	 (label_ref (match_operand 2 "" ""))
1841	 (pc)))]
1842  "TARGET_64BIT"
1843  "*
1844{
1845  return pa_output_bvb (operands, 0, insn, 0);
1846}"
1847[(set_attr "type" "cbranch")
1848 (set (attr "length")
1849    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1850	       (const_int MAX_12BIT_OFFSET))
1851	   (const_int 4)
1852	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1853	       (const_int MAX_17BIT_OFFSET))
1854	   (const_int 8)
1855	   (match_test "TARGET_PORTABLE_RUNTIME")
1856	   (const_int 24)
1857	   (not (match_test "flag_pic"))
1858	   (const_int 20)]
1859	  (const_int 28)))])
1860
1861(define_insn ""
1862  [(set (pc)
1863	(if_then_else
1864	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1865			      (const_int 1)
1866			      (match_operand:SI 1 "register_operand" "q"))
1867	     (const_int 0))
1868	 (pc)
1869	 (label_ref (match_operand 2 "" ""))))]
1870  ""
1871  "*
1872{
1873  return pa_output_bvb (operands, 1, insn, 0);
1874}"
1875[(set_attr "type" "cbranch")
1876 (set (attr "length")
1877    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1878	       (const_int MAX_12BIT_OFFSET))
1879	   (const_int 4)
1880	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1881	       (const_int MAX_17BIT_OFFSET))
1882	   (const_int 8)
1883	   (match_test "TARGET_PORTABLE_RUNTIME")
1884	   (const_int 24)
1885	   (not (match_test "flag_pic"))
1886	   (const_int 20)]
1887	  (const_int 28)))])
1888
1889(define_insn ""
1890  [(set (pc)
1891	(if_then_else
1892	 (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1893			      (const_int 1)
1894			      (match_operand:DI 1 "register_operand" "q"))
1895	     (const_int 0))
1896	 (pc)
1897	 (label_ref (match_operand 2 "" ""))))]
1898  "TARGET_64BIT"
1899  "*
1900{
1901  return pa_output_bvb (operands, 1, insn, 0);
1902}"
1903[(set_attr "type" "cbranch")
1904 (set (attr "length")
1905    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1906	       (const_int MAX_12BIT_OFFSET))
1907	   (const_int 4)
1908	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1909	       (const_int MAX_17BIT_OFFSET))
1910	   (const_int 8)
1911	   (match_test "TARGET_PORTABLE_RUNTIME")
1912	   (const_int 24)
1913	   (not (match_test "flag_pic"))
1914	   (const_int 20)]
1915	  (const_int 28)))])
1916
1917(define_insn ""
1918  [(set (pc)
1919	(if_then_else
1920	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1921			      (const_int 1)
1922			      (match_operand:SI 1 "register_operand" "q"))
1923	     (const_int 0))
1924	 (label_ref (match_operand 2 "" ""))
1925	 (pc)))]
1926  ""
1927  "*
1928{
1929  return pa_output_bvb (operands, 0, insn, 1);
1930}"
1931[(set_attr "type" "cbranch")
1932 (set (attr "length")
1933    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1934	       (const_int MAX_12BIT_OFFSET))
1935	   (const_int 4)
1936	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1937	       (const_int MAX_17BIT_OFFSET))
1938	   (const_int 8)
1939	   (match_test "TARGET_PORTABLE_RUNTIME")
1940	   (const_int 24)
1941	   (not (match_test "flag_pic"))
1942	   (const_int 20)]
1943	  (const_int 28)))])
1944
1945(define_insn ""
1946  [(set (pc)
1947	(if_then_else
1948	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1949			      (const_int 1)
1950			      (match_operand:DI 1 "register_operand" "q"))
1951	     (const_int 0))
1952	 (label_ref (match_operand 2 "" ""))
1953	 (pc)))]
1954  "TARGET_64BIT"
1955  "*
1956{
1957  return pa_output_bvb (operands, 0, insn, 1);
1958}"
1959[(set_attr "type" "cbranch")
1960 (set (attr "length")
1961    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1962	       (const_int MAX_12BIT_OFFSET))
1963	   (const_int 4)
1964	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1965	       (const_int MAX_17BIT_OFFSET))
1966	   (const_int 8)
1967	   (match_test "TARGET_PORTABLE_RUNTIME")
1968	   (const_int 24)
1969	   (not (match_test "flag_pic"))
1970	   (const_int 20)]
1971	  (const_int 28)))])
1972
1973(define_insn ""
1974  [(set (pc)
1975	(if_then_else
1976	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1977			      (const_int 1)
1978			      (match_operand:SI 1 "register_operand" "q"))
1979	     (const_int 0))
1980	 (pc)
1981	 (label_ref (match_operand 2 "" ""))))]
1982  ""
1983  "*
1984{
1985  return pa_output_bvb (operands, 1, insn, 1);
1986}"
1987[(set_attr "type" "cbranch")
1988 (set (attr "length")
1989    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1990	       (const_int MAX_12BIT_OFFSET))
1991	   (const_int 4)
1992	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1993	       (const_int MAX_17BIT_OFFSET))
1994	   (const_int 8)
1995	   (match_test "TARGET_PORTABLE_RUNTIME")
1996	   (const_int 24)
1997	   (not (match_test "flag_pic"))
1998	   (const_int 20)]
1999	  (const_int 28)))])
2000
2001(define_insn ""
2002  [(set (pc)
2003	(if_then_else
2004	 (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2005			      (const_int 1)
2006			      (match_operand:DI 1 "register_operand" "q"))
2007	     (const_int 0))
2008	 (pc)
2009	 (label_ref (match_operand 2 "" ""))))]
2010  "TARGET_64BIT"
2011  "*
2012{
2013  return pa_output_bvb (operands, 1, insn, 1);
2014}"
2015[(set_attr "type" "cbranch")
2016 (set (attr "length")
2017    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2018	       (const_int MAX_12BIT_OFFSET))
2019	   (const_int 4)
2020	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2021	       (const_int MAX_17BIT_OFFSET))
2022	   (const_int 8)
2023	   (match_test "TARGET_PORTABLE_RUNTIME")
2024	   (const_int 24)
2025	   (not (match_test "flag_pic"))
2026	   (const_int 20)]
2027	  (const_int 28)))])
2028
2029;; Floating point branches
2030
2031;; ??? Nullification is handled differently from other branches.
2032;; If nullification is specified, the delay slot is nullified on any
2033;; taken branch regardless of branch direction.
2034(define_insn ""
2035  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2036			   (label_ref (match_operand 0 "" ""))
2037			   (pc)))]
2038  "!TARGET_SOFT_FLOAT"
2039  "*
2040{
2041  int length = get_attr_length (insn);
2042  rtx xoperands[1];
2043  int nullify, xdelay;
2044
2045  if (length < 16)
2046    return \"ftest\;b%* %l0\";
2047
2048  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2049    {
2050      nullify = 1;
2051      xdelay = 0;
2052      xoperands[0] = GEN_INT (length - 8);
2053    }
2054  else
2055    {
2056      nullify = 0;
2057      xdelay = 1;
2058      xoperands[0] = GEN_INT (length - 4);
2059    }
2060
2061  if (nullify)
2062    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2063  else
2064    output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2065  return pa_output_lbranch (operands[0], insn, xdelay);
2066}"
2067[(set_attr "type" "fbranch")
2068 (set (attr "length")
2069    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2070	       (const_int MAX_17BIT_OFFSET))
2071	   (const_int 8)
2072	   (match_test "TARGET_PORTABLE_RUNTIME")
2073	   (const_int 32)
2074	   (not (match_test "flag_pic"))
2075	   (const_int 28)]
2076	  (const_int 36)))])
2077
2078(define_insn ""
2079  [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2080			   (pc)
2081			   (label_ref (match_operand 0 "" ""))))]
2082  "!TARGET_SOFT_FLOAT"
2083  "*
2084{
2085  int length = get_attr_length (insn);
2086  rtx xoperands[1];
2087  int nullify, xdelay;
2088
2089  if (length < 16)
2090    return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2091
2092  if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2093    {
2094      nullify = 1;
2095      xdelay = 0;
2096      xoperands[0] = GEN_INT (length - 4);
2097    }
2098  else
2099    {
2100      nullify = 0;
2101      xdelay = 1;
2102      xoperands[0] = GEN_INT (length);
2103    }
2104
2105  if (nullify)
2106    output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2107  else
2108    output_asm_insn (\"ftest\;b .+%0\", xoperands);
2109  return pa_output_lbranch (operands[0], insn, xdelay);
2110}"
2111[(set_attr "type" "fbranch")
2112 (set (attr "length")
2113    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2114	       (const_int MAX_17BIT_OFFSET))
2115	   (const_int 12)
2116	   (match_test "TARGET_PORTABLE_RUNTIME")
2117	   (const_int 28)
2118	   (not (match_test "flag_pic"))
2119	   (const_int 24)]
2120	  (const_int 32)))])
2121
2122;; Move instructions
2123
2124(define_expand "movsi"
2125  [(set (match_operand:SI 0 "general_operand" "")
2126	(match_operand:SI 1 "general_operand" ""))]
2127  ""
2128  "
2129{
2130  if (pa_emit_move_sequence (operands, SImode, 0))
2131    DONE;
2132}")
2133
2134;; Handle SImode input reloads requiring %r1 as a scratch register.
2135(define_expand "reload_insi_r1"
2136  [(set (match_operand:SI 0 "register_operand" "=Z")
2137	(match_operand:SI 1 "non_hard_reg_operand" ""))
2138   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2139  ""
2140  "
2141{
2142  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2143    DONE;
2144
2145  /* We don't want the clobber emitted, so handle this ourselves.  */
2146  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2147  DONE;
2148}")
2149
2150;; Handle SImode input reloads requiring a general register as a
2151;; scratch register.
2152(define_expand "reload_insi"
2153  [(set (match_operand:SI 0 "register_operand" "=Z")
2154	(match_operand:SI 1 "non_hard_reg_operand" ""))
2155   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2156  ""
2157  "
2158{
2159  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2160    DONE;
2161
2162  /* We don't want the clobber emitted, so handle this ourselves.  */
2163  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2164  DONE;
2165}")
2166
2167;; Handle SImode output reloads requiring a general register as a
2168;; scratch register.
2169(define_expand "reload_outsi"
2170  [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2171	(match_operand:SI 1  "register_operand" "Z"))
2172   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2173  ""
2174  "
2175{
2176  if (pa_emit_move_sequence (operands, SImode, operands[2]))
2177    DONE;
2178
2179  /* We don't want the clobber emitted, so handle this ourselves.  */
2180  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2181  DONE;
2182}")
2183
2184(define_insn ""
2185  [(set (match_operand:SI 0 "move_dest_operand"
2186			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2187	(match_operand:SI 1 "move_src_operand"
2188			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2189  "(register_operand (operands[0], SImode)
2190    || reg_or_0_operand (operands[1], SImode))
2191   && !TARGET_SOFT_FLOAT
2192   && !TARGET_64BIT"
2193  "@
2194   ldw RT'%A1,%0
2195   copy %1,%0
2196   ldi %1,%0
2197   ldil L'%1,%0
2198   {zdepi|depwi,z} %Z1,%0
2199   ldw%M1 %1,%0
2200   stw%M0 %r1,%0
2201   mtsar %r1
2202   {mfctl|mfctl,w} %%sar,%0
2203   fcpy,sgl %f1,%0
2204   fldw%F1 %1,%0
2205   fstw%F0 %1,%0
2206   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2207   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2208  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2209   (set_attr "pa_combine_type" "addmove")
2210   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2211
2212(define_insn ""
2213  [(set (match_operand:SI 0 "move_dest_operand"
2214			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2215	(match_operand:SI 1 "move_src_operand"
2216			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2217  "(register_operand (operands[0], SImode)
2218    || reg_or_0_operand (operands[1], SImode))
2219   && !TARGET_SOFT_FLOAT
2220   && TARGET_64BIT"
2221  "@
2222   ldw RT'%A1,%0
2223   copy %1,%0
2224   ldi %1,%0
2225   ldil L'%1,%0
2226   {zdepi|depwi,z} %Z1,%0
2227   ldw%M1 %1,%0
2228   stw%M0 %r1,%0
2229   mtsar %r1
2230   {mfctl|mfctl,w} %%sar,%0
2231   fcpy,sgl %f1,%0
2232   fldw%F1 %1,%0
2233   fstw%F0 %1,%0"
2234  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2235   (set_attr "pa_combine_type" "addmove")
2236   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2237
2238(define_insn ""
2239  [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2240	(match_operand:SI 1 "register_operand" "f"))]
2241  "!TARGET_SOFT_FLOAT
2242   && !TARGET_DISABLE_INDEXING
2243   && reload_completed"
2244  "fstw%F0 %1,%0"
2245  [(set_attr "type" "fpstore")
2246   (set_attr "pa_combine_type" "addmove")
2247   (set_attr "length" "4")])
2248
2249; Rewrite RTL using an indexed store.  This will allow the insn that
2250; computes the address to be deleted if the register it sets is dead.
2251(define_peephole2
2252  [(set (match_operand:SI 0 "register_operand" "")
2253	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2254			  (const_int 4))
2255		 (match_operand:SI 2 "register_operand" "")))
2256   (set (mem:SI (match_dup 0))
2257        (match_operand:SI 3 "register_operand" ""))]
2258  "!TARGET_SOFT_FLOAT
2259   && !TARGET_DISABLE_INDEXING
2260   && REG_OK_FOR_BASE_P (operands[2])
2261   && FP_REGNO_P (REGNO (operands[3]))"
2262  [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2263	(match_dup 3))
2264   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2265			       (match_dup 2)))]
2266  "")
2267
2268(define_peephole2
2269  [(set (match_operand:SI 0 "register_operand" "")
2270	(plus:SI (match_operand:SI 2 "register_operand" "")
2271		 (mult:SI (match_operand:SI 1 "register_operand" "")
2272			  (const_int 4))))
2273   (set (mem:SI (match_dup 0))
2274        (match_operand:SI 3 "register_operand" ""))]
2275  "!TARGET_SOFT_FLOAT
2276   && !TARGET_DISABLE_INDEXING
2277   && REG_OK_FOR_BASE_P (operands[2])
2278   && FP_REGNO_P (REGNO (operands[3]))"
2279  [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2280	(match_dup 3))
2281   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2282			       (match_dup 2)))]
2283  "")
2284
2285(define_peephole2
2286  [(set (match_operand:DI 0 "register_operand" "")
2287	(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2288			  (const_int 4))
2289		 (match_operand:DI 2 "register_operand" "")))
2290   (set (mem:SI (match_dup 0))
2291        (match_operand:SI 3 "register_operand" ""))]
2292  "!TARGET_SOFT_FLOAT
2293   && !TARGET_DISABLE_INDEXING
2294   && TARGET_64BIT
2295   && REG_OK_FOR_BASE_P (operands[2])
2296   && FP_REGNO_P (REGNO (operands[3]))"
2297  [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2298	(match_dup 3))
2299   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2300			       (match_dup 2)))]
2301  "")
2302
2303(define_peephole2
2304  [(set (match_operand:DI 0 "register_operand" "")
2305	(plus:DI (match_operand:DI 2 "register_operand" "")
2306		 (mult:DI (match_operand:DI 1 "register_operand" "")
2307			  (const_int 4))))
2308   (set (mem:SI (match_dup 0))
2309        (match_operand:SI 3 "register_operand" ""))]
2310  "!TARGET_SOFT_FLOAT
2311   && !TARGET_DISABLE_INDEXING
2312   && TARGET_64BIT
2313   && REG_OK_FOR_BASE_P (operands[2])
2314   && FP_REGNO_P (REGNO (operands[3]))"
2315  [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2316	(match_dup 3))
2317   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2318			       (match_dup 2)))]
2319  "")
2320
2321(define_peephole2
2322  [(set (match_operand:SI 0 "register_operand" "")
2323	(plus:SI (match_operand:SI 1 "register_operand" "")
2324		 (match_operand:SI 2 "register_operand" "")))
2325   (set (mem:SI (match_dup 0))
2326        (match_operand:SI 3 "register_operand" ""))]
2327  "!TARGET_SOFT_FLOAT
2328   && !TARGET_DISABLE_INDEXING
2329   && TARGET_NO_SPACE_REGS
2330   && REG_OK_FOR_INDEX_P (operands[1])
2331   && REG_OK_FOR_BASE_P (operands[2])
2332   && FP_REGNO_P (REGNO (operands[3]))"
2333  [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2334	(match_dup 3))
2335   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2336  "")
2337
2338(define_peephole2
2339  [(set (match_operand:SI 0 "register_operand" "")
2340	(plus:SI (match_operand:SI 1 "register_operand" "")
2341		 (match_operand:SI 2 "register_operand" "")))
2342   (set (mem:SI (match_dup 0))
2343        (match_operand:SI 3 "register_operand" ""))]
2344  "!TARGET_SOFT_FLOAT
2345   && !TARGET_DISABLE_INDEXING
2346   && TARGET_NO_SPACE_REGS
2347   && REG_OK_FOR_BASE_P (operands[1])
2348   && REG_OK_FOR_INDEX_P (operands[2])
2349   && FP_REGNO_P (REGNO (operands[3]))"
2350  [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2351	(match_dup 3))
2352   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2353  "")
2354
2355(define_peephole2
2356  [(set (match_operand:DI 0 "register_operand" "")
2357	(plus:DI (match_operand:DI 1 "register_operand" "")
2358		 (match_operand:DI 2 "register_operand" "")))
2359   (set (mem:SI (match_dup 0))
2360        (match_operand:SI 3 "register_operand" ""))]
2361  "!TARGET_SOFT_FLOAT
2362   && !TARGET_DISABLE_INDEXING
2363   && TARGET_64BIT
2364   && TARGET_NO_SPACE_REGS
2365   && REG_OK_FOR_INDEX_P (operands[1])
2366   && REG_OK_FOR_BASE_P (operands[2])
2367   && FP_REGNO_P (REGNO (operands[3]))"
2368  [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2369	(match_dup 3))
2370   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2371  "")
2372
2373(define_peephole2
2374  [(set (match_operand:DI 0 "register_operand" "")
2375	(plus:DI (match_operand:DI 1 "register_operand" "")
2376		 (match_operand:DI 2 "register_operand" "")))
2377   (set (mem:SI (match_dup 0))
2378        (match_operand:SI 3 "register_operand" ""))]
2379  "!TARGET_SOFT_FLOAT
2380   && !TARGET_DISABLE_INDEXING
2381   && TARGET_64BIT
2382   && TARGET_NO_SPACE_REGS
2383   && REG_OK_FOR_BASE_P (operands[1])
2384   && REG_OK_FOR_INDEX_P (operands[2])
2385   && FP_REGNO_P (REGNO (operands[3]))"
2386  [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2387	(match_dup 3))
2388   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2389  "")
2390
2391(define_insn ""
2392  [(set (match_operand:SI 0 "move_dest_operand"
2393			  "=r,r,r,r,r,r,Q,!*q,!r")
2394	(match_operand:SI 1 "move_src_operand"
2395			  "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2396  "(register_operand (operands[0], SImode)
2397    || reg_or_0_operand (operands[1], SImode))
2398   && TARGET_SOFT_FLOAT"
2399  "@
2400   ldw RT'%A1,%0
2401   copy %1,%0
2402   ldi %1,%0
2403   ldil L'%1,%0
2404   {zdepi|depwi,z} %Z1,%0
2405   ldw%M1 %1,%0
2406   stw%M0 %r1,%0
2407   mtsar %r1
2408   {mfctl|mfctl,w} %%sar,%0"
2409  [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2410   (set_attr "pa_combine_type" "addmove")
2411   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2412
2413;; Load or store with base-register modification.
2414(define_insn ""
2415  [(set (match_operand:SI 0 "register_operand" "=r")
2416	(mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2417			 (match_operand:DI 2 "int5_operand" "L"))))
2418   (set (match_dup 1)
2419	(plus:DI (match_dup 1) (match_dup 2)))]
2420  "TARGET_64BIT"
2421  "ldw,mb %2(%1),%0"
2422  [(set_attr "type" "load")
2423   (set_attr "length" "4")])
2424
2425; And a zero extended variant.
2426(define_insn ""
2427  [(set (match_operand:DI 0 "register_operand" "=r")
2428	(zero_extend:DI (mem:SI
2429			  (plus:DI
2430			    (match_operand:DI 1 "register_operand" "+r")
2431			    (match_operand:DI 2 "int5_operand" "L")))))
2432   (set (match_dup 1)
2433	(plus:DI (match_dup 1) (match_dup 2)))]
2434  "TARGET_64BIT"
2435  "ldw,mb %2(%1),%0"
2436  [(set_attr "type" "load")
2437   (set_attr "length" "4")])
2438
2439(define_expand "pre_load"
2440  [(parallel [(set (match_operand:SI 0 "register_operand" "")
2441	      (mem (plus (match_operand 1 "register_operand" "")
2442			       (match_operand 2 "pre_cint_operand" ""))))
2443	      (set (match_dup 1)
2444		   (plus (match_dup 1) (match_dup 2)))])]
2445  ""
2446  "
2447{
2448  if (TARGET_64BIT)
2449    {
2450      emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2451      DONE;
2452    }
2453  emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2454  DONE;
2455}")
2456
2457(define_insn "pre_ldw"
2458  [(set (match_operand:SI 0 "register_operand" "=r")
2459	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2460			 (match_operand:SI 2 "pre_cint_operand" ""))))
2461   (set (match_dup 1)
2462	(plus:SI (match_dup 1) (match_dup 2)))]
2463  ""
2464  "*
2465{
2466  if (INTVAL (operands[2]) < 0)
2467    return \"{ldwm|ldw,mb} %2(%1),%0\";
2468  return \"{ldws|ldw},mb %2(%1),%0\";
2469}"
2470  [(set_attr "type" "load")
2471   (set_attr "length" "4")])
2472
2473(define_insn "pre_ldd"
2474  [(set (match_operand:DI 0 "register_operand" "=r")
2475	(mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2476			 (match_operand:DI 2 "pre_cint_operand" ""))))
2477   (set (match_dup 1)
2478	(plus:DI (match_dup 1) (match_dup 2)))]
2479  "TARGET_64BIT"
2480  "ldd,mb %2(%1),%0"
2481  [(set_attr "type" "load")
2482   (set_attr "length" "4")])
2483
2484(define_insn ""
2485  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2486			 (match_operand:SI 1 "pre_cint_operand" "")))
2487	(match_operand:SI 2 "reg_or_0_operand" "rM"))
2488   (set (match_dup 0)
2489	(plus:SI (match_dup 0) (match_dup 1)))]
2490  ""
2491  "*
2492{
2493  if (INTVAL (operands[1]) < 0)
2494    return \"{stwm|stw,mb} %r2,%1(%0)\";
2495  return \"{stws|stw},mb %r2,%1(%0)\";
2496}"
2497  [(set_attr "type" "store")
2498   (set_attr "length" "4")])
2499
2500(define_insn ""
2501  [(set (match_operand:SI 0 "register_operand" "=r")
2502	(mem:SI (match_operand:SI 1 "register_operand" "+r")))
2503   (set (match_dup 1)
2504	(plus:SI (match_dup 1)
2505		 (match_operand:SI 2 "post_cint_operand" "")))]
2506  ""
2507  "*
2508{
2509  if (INTVAL (operands[2]) > 0)
2510    return \"{ldwm|ldw,ma} %2(%1),%0\";
2511  return \"{ldws|ldw},ma %2(%1),%0\";
2512}"
2513  [(set_attr "type" "load")
2514   (set_attr "length" "4")])
2515
2516(define_expand "post_store"
2517  [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2518		   (match_operand 1 "reg_or_0_operand" ""))
2519	      (set (match_dup 0)
2520		   (plus (match_dup 0)
2521			 (match_operand 2 "post_cint_operand" "")))])]
2522  ""
2523  "
2524{
2525  if (TARGET_64BIT)
2526    {
2527      emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2528      DONE;
2529    }
2530  emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2531  DONE;
2532}")
2533
2534(define_insn "post_stw"
2535  [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2536	(match_operand:SI 1 "reg_or_0_operand" "rM"))
2537   (set (match_dup 0)
2538	(plus:SI (match_dup 0)
2539		 (match_operand:SI 2 "post_cint_operand" "")))]
2540  ""
2541  "*
2542{
2543  if (INTVAL (operands[2]) > 0)
2544    return \"{stwm|stw,ma} %r1,%2(%0)\";
2545  return \"{stws|stw},ma %r1,%2(%0)\";
2546}"
2547  [(set_attr "type" "store")
2548   (set_attr "length" "4")])
2549
2550(define_insn "post_std"
2551  [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2552	(match_operand:DI 1 "reg_or_0_operand" "rM"))
2553   (set (match_dup 0)
2554	(plus:DI (match_dup 0)
2555		 (match_operand:DI 2 "post_cint_operand" "")))]
2556  "TARGET_64BIT"
2557  "std,ma %r1,%2(%0)"
2558  [(set_attr "type" "store")
2559   (set_attr "length" "4")])
2560
2561;; For loading the address of a label while generating PIC code.
2562;; Note since this pattern can be created at reload time (via movsi), all
2563;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2564(define_insn ""
2565  [(set (match_operand 0 "pmode_register_operand" "=a")
2566	(match_operand 1 "pic_label_operand" ""))]
2567  "TARGET_PA_20"
2568  "*
2569{
2570  rtx xoperands[3];
2571
2572  xoperands[0] = operands[0];
2573  xoperands[1] = operands[1];
2574  xoperands[2] = gen_label_rtx ();
2575
2576  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2577				     CODE_LABEL_NUMBER (xoperands[2]));
2578  output_asm_insn (\"mfia %0\", xoperands);
2579
2580  /* If we're trying to load the address of a label that happens to be
2581     close, then we can use a shorter sequence.  */
2582  if (GET_CODE (operands[1]) == LABEL_REF
2583      && !LABEL_REF_NONLOCAL_P (operands[1])
2584      && INSN_ADDRESSES_SET_P ()
2585      && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2586	        - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2587    output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2588  else
2589    {
2590      output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2591      output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2592    }
2593  return \"\";
2594}"
2595  [(set_attr "type" "multi")
2596   (set_attr "length" "12")])		; 8 or 12
2597
2598(define_insn ""
2599  [(set (match_operand 0 "pmode_register_operand" "=a")
2600	(match_operand 1 "pic_label_operand" ""))]
2601  "!TARGET_PA_20"
2602  "*
2603{
2604  rtx xoperands[3];
2605
2606  xoperands[0] = operands[0];
2607  xoperands[1] = operands[1];
2608  xoperands[2] = gen_label_rtx ();
2609
2610  output_asm_insn (\"bl .+8,%0\", xoperands);
2611  output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2612  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2613				     CODE_LABEL_NUMBER (xoperands[2]));
2614
2615  /* If we're trying to load the address of a label that happens to be
2616     close, then we can use a shorter sequence.  */
2617  if (GET_CODE (operands[1]) == LABEL_REF
2618      && !LABEL_REF_NONLOCAL_P (operands[1])
2619      && INSN_ADDRESSES_SET_P ()
2620      && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2621	        - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2622    output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2623  else
2624    {
2625      output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2626      output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2627    }
2628  return \"\";
2629}"
2630  [(set_attr "type" "multi")
2631   (set_attr "length" "16")])		; 12 or 16
2632
2633(define_insn ""
2634  [(set (match_operand:SI 0 "register_operand" "=a")
2635	(plus:SI (match_operand:SI 1 "register_operand" "r")
2636		 (high:SI (match_operand 2 "" ""))))]
2637  "symbolic_operand (operands[2], Pmode)
2638   && ! function_label_operand (operands[2], Pmode)
2639   && flag_pic"
2640  "addil LT'%G2,%1"
2641  [(set_attr "type" "binary")
2642   (set_attr "length" "4")])
2643
2644(define_insn ""
2645  [(set (match_operand:DI 0 "register_operand" "=a")
2646	(plus:DI (match_operand:DI 1 "register_operand" "r")
2647	         (high:DI (match_operand 2 "" ""))))]
2648  "symbolic_operand (operands[2], Pmode)
2649   && ! function_label_operand (operands[2], Pmode)
2650   && TARGET_64BIT
2651   && flag_pic"
2652  "addil LT'%G2,%1"
2653  [(set_attr "type" "binary")
2654   (set_attr "length" "4")])
2655
2656(define_insn ""
2657 [(set (match_operand:SI 0 "register_operand" "=r")
2658       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2659		  (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2660  "symbolic_operand (operands[2], Pmode)
2661   && ! function_label_operand (operands[2], Pmode)
2662   && flag_pic"
2663  "ldo RT'%G2(%1),%0"
2664  [(set_attr "type" "binary")
2665   (set_attr "length" "4")])
2666
2667(define_insn ""
2668 [(set (match_operand:DI 0 "register_operand" "=r")
2669       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2670		  (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2671  "symbolic_operand (operands[2], Pmode)
2672   && ! function_label_operand (operands[2], Pmode)
2673   && TARGET_64BIT
2674   && flag_pic"
2675  "ldo RT'%G2(%1),%0"
2676  [(set_attr "type" "binary")
2677   (set_attr "length" "4")])
2678
2679;; Always use addil rather than ldil;add sequences.  This allows the
2680;; HP linker to eliminate the dp relocation if the symbolic operand
2681;; lives in the TEXT space.
2682(define_insn ""
2683  [(set (match_operand:SI 0 "register_operand" "=a")
2684	(high:SI (match_operand 1 "" "")))]
2685  "symbolic_operand (operands[1], Pmode)
2686   && ! function_label_operand (operands[1], Pmode)
2687   && ! read_only_operand (operands[1], Pmode)
2688   && ! flag_pic"
2689  "*
2690{
2691  if (TARGET_LONG_LOAD_STORE)
2692    return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2693  else
2694    return \"addil LR'%H1,%%r27\";
2695}"
2696  [(set_attr "type" "binary")
2697   (set (attr "length")
2698      (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2699		    (const_int 4)
2700		    (const_int 8)))])
2701
2702
2703;; This is for use in the prologue/epilogue code.  We need it
2704;; to add large constants to a stack pointer or frame pointer.
2705;; Because of the additional %r1 pressure, we probably do not
2706;; want to use this in general code, so make it available
2707;; only after reload.
2708(define_insn ""
2709  [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2710	(plus:SI (match_operand:SI 1 "register_operand" "r,r")
2711		 (high:SI (match_operand 2 "const_int_operand" ""))))]
2712  "reload_completed"
2713  "@
2714   addil L'%G2,%1
2715   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2716  [(set_attr "type" "binary,binary")
2717   (set_attr "length" "4,8")])
2718
2719(define_insn ""
2720  [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2721	(plus:DI (match_operand:DI 1 "register_operand" "r,r")
2722		 (high:DI (match_operand 2 "const_int_operand" ""))))]
2723  "reload_completed && TARGET_64BIT"
2724  "@
2725   addil L'%G2,%1
2726   ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2727  [(set_attr "type" "binary,binary")
2728   (set_attr "length" "4,8")])
2729
2730(define_insn ""
2731  [(set (match_operand:SI 0 "register_operand" "=r")
2732	(high:SI (match_operand 1 "" "")))]
2733  "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2734    && !pa_is_function_label_plus_const (operands[1])"
2735  "*
2736{
2737  if (symbolic_operand (operands[1], Pmode))
2738    return \"ldil LR'%H1,%0\";
2739  else
2740    return \"ldil L'%G1,%0\";
2741}"
2742  [(set_attr "type" "move")
2743   (set_attr "length" "4")])
2744
2745(define_insn ""
2746  [(set (match_operand:DI 0 "register_operand" "=r")
2747	(high:DI (match_operand 1 "const_int_operand" "")))]
2748  "TARGET_64BIT"
2749  "ldil L'%G1,%0";
2750  [(set_attr "type" "move")
2751   (set_attr "length" "4")])
2752
2753(define_insn ""
2754  [(set (match_operand:DI 0 "register_operand" "=r")
2755	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2756		   (match_operand:DI 2 "const_int_operand" "i")))]
2757  "TARGET_64BIT"
2758  "ldo R'%G2(%1),%0";
2759  [(set_attr "type" "move")
2760   (set_attr "length" "4")])
2761
2762(define_insn ""
2763  [(set (match_operand:SI 0 "register_operand" "=r")
2764	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2765		   (match_operand:SI 2 "immediate_operand" "i")))]
2766  "!pa_is_function_label_plus_const (operands[2])"
2767  "*
2768{
2769  gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2770
2771  if (symbolic_operand (operands[2], Pmode))
2772    return \"ldo RR'%G2(%1),%0\";
2773  else
2774    return \"ldo R'%G2(%1),%0\";
2775}"
2776  [(set_attr "type" "move")
2777   (set_attr "length" "4")])
2778
2779;; Now that a symbolic_address plus a constant is broken up early
2780;; in the compilation phase (for better CSE) we need a special
2781;; combiner pattern to load the symbolic address plus the constant
2782;; in only 2 instructions. (For cases where the symbolic address
2783;; was not a common subexpression.)
2784(define_split
2785  [(set (match_operand:SI 0 "register_operand" "")
2786	(match_operand:SI 1 "symbolic_operand" ""))
2787   (clobber (match_operand:SI 2 "register_operand" ""))]
2788  "! (flag_pic && pic_label_operand (operands[1], SImode))"
2789  [(set (match_dup 2) (high:SI (match_dup 1)))
2790   (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2791  "")
2792
2793;; hppa_legitimize_address goes to a great deal of trouble to
2794;; create addresses which use indexing.  In some cases, this
2795;; is a lose because there isn't any store instructions which
2796;; allow indexed addresses (with integer register source).
2797;;
2798;; These define_splits try to turn a 3 insn store into
2799;; a 2 insn store with some creative RTL rewriting.
2800(define_split
2801  [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2802			       (match_operand:SI 1 "shadd_operand" ""))
2803		   (plus:SI (match_operand:SI 2 "register_operand" "")
2804			    (match_operand:SI 3 "const_int_operand" ""))))
2805	(match_operand:SI 4 "register_operand" ""))
2806   (clobber (match_operand:SI 5 "register_operand" ""))]
2807  ""
2808  [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2809			       (match_dup 2)))
2810   (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2811  "")
2812
2813(define_split
2814  [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2815			       (match_operand:SI 1 "shadd_operand" ""))
2816		   (plus:SI (match_operand:SI 2 "register_operand" "")
2817			    (match_operand:SI 3 "const_int_operand" ""))))
2818	(match_operand:HI 4 "register_operand" ""))
2819   (clobber (match_operand:SI 5 "register_operand" ""))]
2820  ""
2821  [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2822			       (match_dup 2)))
2823   (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2824  "")
2825
2826(define_split
2827  [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2828			       (match_operand:SI 1 "shadd_operand" ""))
2829		   (plus:SI (match_operand:SI 2 "register_operand" "")
2830			    (match_operand:SI 3 "const_int_operand" ""))))
2831	(match_operand:QI 4 "register_operand" ""))
2832   (clobber (match_operand:SI 5 "register_operand" ""))]
2833  ""
2834  [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2835			       (match_dup 2)))
2836   (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2837  "")
2838
2839(define_expand "movhi"
2840  [(set (match_operand:HI 0 "general_operand" "")
2841	(match_operand:HI 1 "general_operand" ""))]
2842  ""
2843  "
2844{
2845  if (pa_emit_move_sequence (operands, HImode, 0))
2846    DONE;
2847}")
2848
2849;; Handle HImode input reloads requiring a general register as a
2850;; scratch register.
2851(define_expand "reload_inhi"
2852  [(set (match_operand:HI 0 "register_operand" "=Z")
2853	(match_operand:HI 1 "non_hard_reg_operand" ""))
2854   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2855  ""
2856  "
2857{
2858  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2859    DONE;
2860
2861  /* We don't want the clobber emitted, so handle this ourselves.  */
2862  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2863  DONE;
2864}")
2865
2866;; Handle HImode output reloads requiring a general register as a
2867;; scratch register.
2868(define_expand "reload_outhi"
2869  [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2870	(match_operand:HI 1  "register_operand" "Z"))
2871   (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2872  ""
2873  "
2874{
2875  if (pa_emit_move_sequence (operands, HImode, operands[2]))
2876    DONE;
2877
2878  /* We don't want the clobber emitted, so handle this ourselves.  */
2879  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2880  DONE;
2881}")
2882
2883(define_insn ""
2884  [(set (match_operand:HI 0 "move_dest_operand"
2885	 		  "=r,r,r,r,r,Q,!*q,!r")
2886	(match_operand:HI 1 "move_src_operand"
2887			  "r,J,N,K,RQ,rM,!rM,!*q"))]
2888  "(register_operand (operands[0], HImode)
2889    || reg_or_0_operand (operands[1], HImode))"
2890  "@
2891   copy %1,%0
2892   ldi %1,%0
2893   ldil L'%1,%0
2894   {zdepi|depwi,z} %Z1,%0
2895   ldh%M1 %1,%0
2896   sth%M0 %r1,%0
2897   mtsar %r1
2898   {mfctl|mfctl,w} %sar,%0"
2899  [(set_attr "type" "move,move,move,shift,load,store,move,move")
2900   (set_attr "pa_combine_type" "addmove")
2901   (set_attr "length" "4,4,4,4,4,4,4,4")])
2902
2903(define_insn ""
2904  [(set (match_operand:HI 0 "register_operand" "=r")
2905	(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2906			 (match_operand:SI 2 "int5_operand" "L"))))
2907   (set (match_dup 1)
2908	(plus:SI (match_dup 1) (match_dup 2)))]
2909  ""
2910  "{ldhs|ldh},mb %2(%1),%0"
2911  [(set_attr "type" "load")
2912   (set_attr "length" "4")])
2913
2914(define_insn ""
2915  [(set (match_operand:HI 0 "register_operand" "=r")
2916	(mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2917			 (match_operand:DI 2 "int5_operand" "L"))))
2918   (set (match_dup 1)
2919	(plus:DI (match_dup 1) (match_dup 2)))]
2920  "TARGET_64BIT"
2921  "ldh,mb %2(%1),%0"
2922  [(set_attr "type" "load")
2923   (set_attr "length" "4")])
2924
2925; And a zero extended variant.
2926(define_insn ""
2927  [(set (match_operand:DI 0 "register_operand" "=r")
2928	(zero_extend:DI (mem:HI
2929			  (plus:DI
2930			    (match_operand:DI 1 "register_operand" "+r")
2931			    (match_operand:DI 2 "int5_operand" "L")))))
2932   (set (match_dup 1)
2933	(plus:DI (match_dup 1) (match_dup 2)))]
2934  "TARGET_64BIT"
2935  "ldh,mb %2(%1),%0"
2936  [(set_attr "type" "load")
2937   (set_attr "length" "4")])
2938
2939(define_insn ""
2940  [(set (match_operand:SI 0 "register_operand" "=r")
2941	(zero_extend:SI (mem:HI
2942			  (plus:SI
2943			    (match_operand:SI 1 "register_operand" "+r")
2944			    (match_operand:SI 2 "int5_operand" "L")))))
2945   (set (match_dup 1)
2946	(plus:SI (match_dup 1) (match_dup 2)))]
2947  ""
2948  "{ldhs|ldh},mb %2(%1),%0"
2949  [(set_attr "type" "load")
2950   (set_attr "length" "4")])
2951
2952(define_insn ""
2953  [(set (match_operand:SI 0 "register_operand" "=r")
2954	(zero_extend:SI (mem:HI
2955			  (plus:DI
2956			    (match_operand:DI 1 "register_operand" "+r")
2957			    (match_operand:DI 2 "int5_operand" "L")))))
2958   (set (match_dup 1)
2959	(plus:DI (match_dup 1) (match_dup 2)))]
2960  "TARGET_64BIT"
2961  "ldh,mb %2(%1),%0"
2962  [(set_attr "type" "load")
2963   (set_attr "length" "4")])
2964
2965(define_insn ""
2966  [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2967			 (match_operand:SI 1 "int5_operand" "L")))
2968	(match_operand:HI 2 "reg_or_0_operand" "rM"))
2969   (set (match_dup 0)
2970	(plus:SI (match_dup 0) (match_dup 1)))]
2971  ""
2972  "{sths|sth},mb %r2,%1(%0)"
2973  [(set_attr "type" "store")
2974   (set_attr "length" "4")])
2975
2976(define_insn ""
2977  [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
2978			 (match_operand:DI 1 "int5_operand" "L")))
2979	(match_operand:HI 2 "reg_or_0_operand" "rM"))
2980   (set (match_dup 0)
2981	(plus:DI (match_dup 0) (match_dup 1)))]
2982  "TARGET_64BIT"
2983  "sth,mb %r2,%1(%0)"
2984  [(set_attr "type" "store")
2985   (set_attr "length" "4")])
2986
2987(define_insn "addhi3"
2988  [(set (match_operand:HI 0 "register_operand" "=r,r")
2989	(plus:HI (match_operand:HI 1 "register_operand" "%r,r")
2990		 (match_operand:HI 2 "arith14_operand" "r,J")))]
2991  ""
2992  "@
2993   {addl|add,l} %1,%2,%0
2994   ldo %2(%1),%0"
2995  [(set_attr "type" "binary,binary")
2996   (set_attr "pa_combine_type" "addmove")
2997   (set_attr "length" "4,4")])
2998
2999(define_expand "movqi"
3000  [(set (match_operand:QI 0 "general_operand" "")
3001	(match_operand:QI 1 "general_operand" ""))]
3002  ""
3003  "
3004{
3005  if (pa_emit_move_sequence (operands, QImode, 0))
3006    DONE;
3007}")
3008
3009;; Handle QImode input reloads requiring a general register as a
3010;; scratch register.
3011(define_expand "reload_inqi"
3012  [(set (match_operand:QI 0 "register_operand" "=Z")
3013	(match_operand:QI 1 "non_hard_reg_operand" ""))
3014   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3015  ""
3016  "
3017{
3018  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3019    DONE;
3020
3021  /* We don't want the clobber emitted, so handle this ourselves.  */
3022  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3023  DONE;
3024}")
3025
3026;; Handle QImode output reloads requiring a general register as a
3027;; scratch register.
3028(define_expand "reload_outqi"
3029  [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3030	(match_operand:QI 1  "register_operand" "Z"))
3031   (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3032  ""
3033  "
3034{
3035  if (pa_emit_move_sequence (operands, QImode, operands[2]))
3036    DONE;
3037
3038  /* We don't want the clobber emitted, so handle this ourselves.  */
3039  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3040  DONE;
3041}")
3042
3043(define_insn ""
3044  [(set (match_operand:QI 0 "move_dest_operand"
3045			  "=r,r,r,r,r,Q,!*q,!r")
3046	(match_operand:QI 1 "move_src_operand"
3047			  "r,J,N,K,RQ,rM,!rM,!*q"))]
3048  "(register_operand (operands[0], QImode)
3049    || reg_or_0_operand (operands[1], QImode))"
3050  "@
3051   copy %1,%0
3052   ldi %1,%0
3053   ldil L'%1,%0
3054   {zdepi|depwi,z} %Z1,%0
3055   ldb%M1 %1,%0
3056   stb%M0 %r1,%0
3057   mtsar %r1
3058   {mfctl|mfctl,w} %%sar,%0"
3059  [(set_attr "type" "move,move,move,shift,load,store,move,move")
3060   (set_attr "pa_combine_type" "addmove")
3061   (set_attr "length" "4,4,4,4,4,4,4,4")])
3062
3063(define_insn ""
3064  [(set (match_operand:QI 0 "register_operand" "=r")
3065	(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3066			 (match_operand:SI 2 "int5_operand" "L"))))
3067   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3068  ""
3069  "{ldbs|ldb},mb %2(%1),%0"
3070  [(set_attr "type" "load")
3071   (set_attr "length" "4")])
3072
3073(define_insn ""
3074  [(set (match_operand:QI 0 "register_operand" "=r")
3075	(mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3076			 (match_operand:DI 2 "int5_operand" "L"))))
3077   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3078  "TARGET_64BIT"
3079  "ldb,mb %2(%1),%0"
3080  [(set_attr "type" "load")
3081   (set_attr "length" "4")])
3082
3083; Now the same thing with zero extensions.
3084(define_insn ""
3085  [(set (match_operand:DI 0 "register_operand" "=r")
3086	(zero_extend:DI (mem:QI (plus:DI
3087				  (match_operand:DI 1 "register_operand" "+r")
3088				  (match_operand:DI 2 "int5_operand" "L")))))
3089   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3090  "TARGET_64BIT"
3091  "ldb,mb %2(%1),%0"
3092  [(set_attr "type" "load")
3093   (set_attr "length" "4")])
3094
3095(define_insn ""
3096  [(set (match_operand:SI 0 "register_operand" "=r")
3097	(zero_extend:SI (mem:QI (plus:SI
3098				  (match_operand:SI 1 "register_operand" "+r")
3099				  (match_operand:SI 2 "int5_operand" "L")))))
3100   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3101  ""
3102  "{ldbs|ldb},mb %2(%1),%0"
3103  [(set_attr "type" "load")
3104   (set_attr "length" "4")])
3105
3106(define_insn ""
3107  [(set (match_operand:SI 0 "register_operand" "=r")
3108	(zero_extend:SI (mem:QI (plus:DI
3109				  (match_operand:DI 1 "register_operand" "+r")
3110				  (match_operand:DI 2 "int5_operand" "L")))))
3111   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3112  "TARGET_64BIT"
3113  "ldb,mb %2(%1),%0"
3114  [(set_attr "type" "load")
3115   (set_attr "length" "4")])
3116
3117(define_insn ""
3118  [(set (match_operand:HI 0 "register_operand" "=r")
3119	(zero_extend:HI (mem:QI (plus:SI
3120				  (match_operand:SI 1 "register_operand" "+r")
3121				  (match_operand:SI 2 "int5_operand" "L")))))
3122   (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3123  ""
3124  "{ldbs|ldb},mb %2(%1),%0"
3125  [(set_attr "type" "load")
3126   (set_attr "length" "4")])
3127
3128(define_insn ""
3129  [(set (match_operand:HI 0 "register_operand" "=r")
3130	(zero_extend:HI (mem:QI (plus:DI
3131				  (match_operand:DI 1 "register_operand" "+r")
3132				  (match_operand:DI 2 "int5_operand" "L")))))
3133   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3134  "TARGET_64BIT"
3135  "ldb,mb %2(%1),%0"
3136  [(set_attr "type" "load")
3137   (set_attr "length" "4")])
3138
3139(define_insn ""
3140  [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3141			 (match_operand:SI 1 "int5_operand" "L")))
3142	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3143   (set (match_dup 0)
3144	(plus:SI (match_dup 0) (match_dup 1)))]
3145  ""
3146  "{stbs|stb},mb %r2,%1(%0)"
3147  [(set_attr "type" "store")
3148   (set_attr "length" "4")])
3149
3150(define_insn ""
3151  [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3152			 (match_operand:DI 1 "int5_operand" "L")))
3153	(match_operand:QI 2 "reg_or_0_operand" "rM"))
3154   (set (match_dup 0)
3155	(plus:DI (match_dup 0) (match_dup 1)))]
3156  "TARGET_64BIT"
3157  "stb,mb %r2,%1(%0)"
3158  [(set_attr "type" "store")
3159   (set_attr "length" "4")])
3160
3161;; The definition of this insn does not really explain what it does,
3162;; but it should suffice that anything generated as this insn will be
3163;; recognized as a movmemsi operation, and that it will not successfully
3164;; combine with anything.
3165(define_expand "movmemsi"
3166  [(parallel [(set (match_operand:BLK 0 "" "")
3167		   (match_operand:BLK 1 "" ""))
3168	      (clobber (match_dup 4))
3169	      (clobber (match_dup 5))
3170	      (clobber (match_dup 6))
3171	      (clobber (match_dup 7))
3172	      (clobber (match_dup 8))
3173	      (use (match_operand:SI 2 "arith14_operand" ""))
3174	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3175  "!TARGET_64BIT && optimize > 0"
3176  "
3177{
3178  int size, align;
3179
3180  /* HP provides very fast block move library routine for the PA;
3181     this routine includes:
3182
3183	4x4 byte at a time block moves,
3184	1x4 byte at a time with alignment checked at runtime with
3185	    attempts to align the source and destination as needed
3186	1x1 byte loop
3187
3188     With that in mind, here's the heuristics to try and guess when
3189     the inlined block move will be better than the library block
3190     move:
3191
3192	If the size isn't constant, then always use the library routines.
3193
3194	If the size is large in respect to the known alignment, then use
3195	the library routines.
3196
3197	If the size is small in respect to the known alignment, then open
3198	code the copy (since that will lead to better scheduling).
3199
3200        Else use the block move pattern.   */
3201
3202  /* Undetermined size, use the library routine.  */
3203  if (GET_CODE (operands[2]) != CONST_INT)
3204    FAIL;
3205
3206  size = INTVAL (operands[2]);
3207  align = INTVAL (operands[3]);
3208  align = align > 4 ? 4 : (align ? align : 1);
3209
3210  /* If size/alignment is large, then use the library routines.  */
3211  if (size / align > 16)
3212    FAIL;
3213
3214  /* This does happen, but not often enough to worry much about.  */
3215  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3216    FAIL;
3217
3218  /* Fall through means we're going to use our block move pattern.  */
3219  operands[0]
3220    = replace_equiv_address (operands[0],
3221			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3222  operands[1]
3223    = replace_equiv_address (operands[1],
3224			     copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3225  operands[4] = gen_reg_rtx (SImode);
3226  operands[5] = gen_reg_rtx (SImode);
3227  operands[6] = gen_reg_rtx (SImode);
3228  operands[7] = gen_reg_rtx (SImode);
3229  operands[8] = gen_reg_rtx (SImode);
3230}")
3231
3232;; The operand constraints are written like this to support both compile-time
3233;; and run-time determined byte counts.  The expander and pa_output_block_move
3234;; only support compile-time determined counts at this time.
3235;;
3236;; If the count is run-time determined, the register with the byte count
3237;; is clobbered by the copying code, and therefore it is forced to operand 2.
3238;;
3239;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3240;; broke this semantic for pseudo registers.  We can't use match_scratch
3241;; as this requires two registers in the class R1_REGS when the MEMs for
3242;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3243;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3244;; respectively.  We then split or peephole optimize after reload.
3245(define_insn "movmemsi_prereload"
3246  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3247	(mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3248   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3249   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3250   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3251   (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))	;item tmp3
3252   (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))	;item tmp4
3253   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3254   (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3255  "!TARGET_64BIT"
3256  "#"
3257  [(set_attr "type" "multi,multi")])
3258
3259(define_split
3260  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3261		   (match_operand:BLK 1 "memory_operand" ""))
3262	      (clobber (match_operand:SI 2 "register_operand" ""))
3263	      (clobber (match_operand:SI 3 "register_operand" ""))
3264	      (clobber (match_operand:SI 6 "register_operand" ""))
3265	      (clobber (match_operand:SI 7 "register_operand" ""))
3266	      (clobber (match_operand:SI 8 "register_operand" ""))
3267	      (use (match_operand:SI 4 "arith14_operand" ""))
3268	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3269  "!TARGET_64BIT && reload_completed && !flag_peephole2
3270   && GET_CODE (operands[0]) == MEM
3271   && register_operand (XEXP (operands[0], 0), SImode)
3272   && GET_CODE (operands[1]) == MEM
3273   && register_operand (XEXP (operands[1], 0), SImode)"
3274  [(set (match_dup 7) (match_dup 9))
3275   (set (match_dup 8) (match_dup 10))
3276   (parallel [(set (match_dup 0) (match_dup 1))
3277   	      (clobber (match_dup 2))
3278   	      (clobber (match_dup 3))
3279   	      (clobber (match_dup 6))
3280   	      (clobber (match_dup 7))
3281   	      (clobber (match_dup 8))
3282   	      (use (match_dup 4))
3283   	      (use (match_dup 5))
3284	      (const_int 0)])]
3285  "
3286{
3287  operands[9] = XEXP (operands[0], 0);
3288  operands[10] = XEXP (operands[1], 0);
3289  operands[0] = replace_equiv_address (operands[0], operands[7]);
3290  operands[1] = replace_equiv_address (operands[1], operands[8]);
3291}")
3292
3293(define_peephole2
3294  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3295		   (match_operand:BLK 1 "memory_operand" ""))
3296	      (clobber (match_operand:SI 2 "register_operand" ""))
3297	      (clobber (match_operand:SI 3 "register_operand" ""))
3298	      (clobber (match_operand:SI 6 "register_operand" ""))
3299	      (clobber (match_operand:SI 7 "register_operand" ""))
3300	      (clobber (match_operand:SI 8 "register_operand" ""))
3301	      (use (match_operand:SI 4 "arith14_operand" ""))
3302	      (use (match_operand:SI 5 "const_int_operand" ""))])]
3303  "!TARGET_64BIT
3304   && GET_CODE (operands[0]) == MEM
3305   && register_operand (XEXP (operands[0], 0), SImode)
3306   && GET_CODE (operands[1]) == MEM
3307   && register_operand (XEXP (operands[1], 0), SImode)"
3308  [(parallel [(set (match_dup 0) (match_dup 1))
3309   	      (clobber (match_dup 2))
3310   	      (clobber (match_dup 3))
3311   	      (clobber (match_dup 6))
3312   	      (clobber (match_dup 7))
3313   	      (clobber (match_dup 8))
3314   	      (use (match_dup 4))
3315   	      (use (match_dup 5))
3316	      (const_int 0)])]
3317  "
3318{
3319  rtx addr = XEXP (operands[0], 0);
3320  if (dead_or_set_p (curr_insn, addr))
3321    operands[7] = addr;
3322  else
3323    {
3324      emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3325      operands[0] = replace_equiv_address (operands[0], operands[7]);
3326    }
3327
3328  addr = XEXP (operands[1], 0);
3329  if (dead_or_set_p (curr_insn, addr))
3330    operands[8] = addr;
3331  else
3332    {
3333      emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3334      operands[1] = replace_equiv_address (operands[1], operands[8]);
3335    }
3336}")
3337
3338(define_insn "movmemsi_postreload"
3339  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3340	(mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3341   (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3342   (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))	;item tmp1
3343   (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))	;item tmp2
3344   (clobber (match_dup 0))
3345   (clobber (match_dup 1))
3346   (use (match_operand:SI 4 "arith14_operand" "J,2"))	 ;byte count
3347   (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3348   (const_int 0)]
3349  "!TARGET_64BIT && reload_completed"
3350  "* return pa_output_block_move (operands, !which_alternative);"
3351  [(set_attr "type" "multi,multi")])
3352
3353(define_expand "movmemdi"
3354  [(parallel [(set (match_operand:BLK 0 "" "")
3355		   (match_operand:BLK 1 "" ""))
3356	      (clobber (match_dup 4))
3357	      (clobber (match_dup 5))
3358	      (clobber (match_dup 6))
3359	      (clobber (match_dup 7))
3360	      (clobber (match_dup 8))
3361	      (use (match_operand:DI 2 "arith14_operand" ""))
3362	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3363  "TARGET_64BIT && optimize > 0"
3364  "
3365{
3366  int size, align;
3367
3368  /* HP provides very fast block move library routine for the PA;
3369     this routine includes:
3370
3371	4x4 byte at a time block moves,
3372	1x4 byte at a time with alignment checked at runtime with
3373	    attempts to align the source and destination as needed
3374	1x1 byte loop
3375
3376     With that in mind, here's the heuristics to try and guess when
3377     the inlined block move will be better than the library block
3378     move:
3379
3380	If the size isn't constant, then always use the library routines.
3381
3382	If the size is large in respect to the known alignment, then use
3383	the library routines.
3384
3385	If the size is small in respect to the known alignment, then open
3386	code the copy (since that will lead to better scheduling).
3387
3388        Else use the block move pattern.   */
3389
3390  /* Undetermined size, use the library routine.  */
3391  if (GET_CODE (operands[2]) != CONST_INT)
3392    FAIL;
3393
3394  size = INTVAL (operands[2]);
3395  align = INTVAL (operands[3]);
3396  align = align > 8 ? 8 : (align ? align : 1);
3397
3398  /* If size/alignment is large, then use the library routines.  */
3399  if (size / align > 16)
3400    FAIL;
3401
3402  /* This does happen, but not often enough to worry much about.  */
3403  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3404    FAIL;
3405
3406  /* Fall through means we're going to use our block move pattern.  */
3407  operands[0]
3408    = replace_equiv_address (operands[0],
3409			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3410  operands[1]
3411    = replace_equiv_address (operands[1],
3412			     copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3413  operands[4] = gen_reg_rtx (DImode);
3414  operands[5] = gen_reg_rtx (DImode);
3415  operands[6] = gen_reg_rtx (DImode);
3416  operands[7] = gen_reg_rtx (DImode);
3417  operands[8] = gen_reg_rtx (DImode);
3418}")
3419
3420;; The operand constraints are written like this to support both compile-time
3421;; and run-time determined byte counts.  The expander and pa_output_block_move
3422;; only support compile-time determined counts at this time.
3423;;
3424;; If the count is run-time determined, the register with the byte count
3425;; is clobbered by the copying code, and therefore it is forced to operand 2.
3426;;
3427;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3428;; broke this semantic for pseudo registers.  We can't use match_scratch
3429;; as this requires two registers in the class R1_REGS when the MEMs for
3430;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3431;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3432;; respectively.  We then split or peephole optimize after reload.
3433(define_insn "movmemdi_prereload"
3434  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3435	(mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3436   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3437   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3438   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3439   (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))	;item tmp3
3440   (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))	;item tmp4
3441   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3442   (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3443  "TARGET_64BIT"
3444  "#"
3445  [(set_attr "type" "multi,multi")])
3446
3447(define_split
3448  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3449		   (match_operand:BLK 1 "memory_operand" ""))
3450	      (clobber (match_operand:DI 2 "register_operand" ""))
3451	      (clobber (match_operand:DI 3 "register_operand" ""))
3452	      (clobber (match_operand:DI 6 "register_operand" ""))
3453	      (clobber (match_operand:DI 7 "register_operand" ""))
3454	      (clobber (match_operand:DI 8 "register_operand" ""))
3455	      (use (match_operand:DI 4 "arith14_operand" ""))
3456	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3457  "TARGET_64BIT && reload_completed && !flag_peephole2
3458   && GET_CODE (operands[0]) == MEM
3459   && register_operand (XEXP (operands[0], 0), DImode)
3460   && GET_CODE (operands[1]) == MEM
3461   && register_operand (XEXP (operands[1], 0), DImode)"
3462  [(set (match_dup 7) (match_dup 9))
3463   (set (match_dup 8) (match_dup 10))
3464   (parallel [(set (match_dup 0) (match_dup 1))
3465   	      (clobber (match_dup 2))
3466   	      (clobber (match_dup 3))
3467   	      (clobber (match_dup 6))
3468   	      (clobber (match_dup 7))
3469   	      (clobber (match_dup 8))
3470   	      (use (match_dup 4))
3471   	      (use (match_dup 5))
3472	      (const_int 0)])]
3473  "
3474{
3475  operands[9] = XEXP (operands[0], 0);
3476  operands[10] = XEXP (operands[1], 0);
3477  operands[0] = replace_equiv_address (operands[0], operands[7]);
3478  operands[1] = replace_equiv_address (operands[1], operands[8]);
3479}")
3480
3481(define_peephole2
3482  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3483		   (match_operand:BLK 1 "memory_operand" ""))
3484	      (clobber (match_operand:DI 2 "register_operand" ""))
3485	      (clobber (match_operand:DI 3 "register_operand" ""))
3486	      (clobber (match_operand:DI 6 "register_operand" ""))
3487	      (clobber (match_operand:DI 7 "register_operand" ""))
3488	      (clobber (match_operand:DI 8 "register_operand" ""))
3489	      (use (match_operand:DI 4 "arith14_operand" ""))
3490	      (use (match_operand:DI 5 "const_int_operand" ""))])]
3491  "TARGET_64BIT
3492   && GET_CODE (operands[0]) == MEM
3493   && register_operand (XEXP (operands[0], 0), DImode)
3494   && GET_CODE (operands[1]) == MEM
3495   && register_operand (XEXP (operands[1], 0), DImode)"
3496  [(parallel [(set (match_dup 0) (match_dup 1))
3497   	      (clobber (match_dup 2))
3498   	      (clobber (match_dup 3))
3499   	      (clobber (match_dup 6))
3500   	      (clobber (match_dup 7))
3501   	      (clobber (match_dup 8))
3502   	      (use (match_dup 4))
3503   	      (use (match_dup 5))
3504	      (const_int 0)])]
3505  "
3506{
3507  rtx addr = XEXP (operands[0], 0);
3508  if (dead_or_set_p (curr_insn, addr))
3509    operands[7] = addr;
3510  else
3511    {
3512      emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3513      operands[0] = replace_equiv_address (operands[0], operands[7]);
3514    }
3515
3516  addr = XEXP (operands[1], 0);
3517  if (dead_or_set_p (curr_insn, addr))
3518    operands[8] = addr;
3519  else
3520    {
3521      emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3522      operands[1] = replace_equiv_address (operands[1], operands[8]);
3523    }
3524}")
3525
3526(define_insn "movmemdi_postreload"
3527  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3528	(mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3529   (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))	;loop cnt/tmp
3530   (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))	;item tmp1
3531   (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))	;item tmp2
3532   (clobber (match_dup 0))
3533   (clobber (match_dup 1))
3534   (use (match_operand:DI 4 "arith14_operand" "J,2"))	 ;byte count
3535   (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3536   (const_int 0)]
3537  "TARGET_64BIT && reload_completed"
3538  "* return pa_output_block_move (operands, !which_alternative);"
3539  [(set_attr "type" "multi,multi")])
3540
3541(define_expand "setmemsi"
3542  [(parallel [(set (match_operand:BLK 0 "" "")
3543		   (match_operand 2 "const_int_operand" ""))
3544	      (clobber (match_dup 4))
3545	      (clobber (match_dup 5))
3546	      (use (match_operand:SI 1 "arith14_operand" ""))
3547	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3548  "!TARGET_64BIT && optimize > 0"
3549  "
3550{
3551  int size, align;
3552
3553  /* If value to set is not zero, use the library routine.  */
3554  if (operands[2] != const0_rtx)
3555    FAIL;
3556
3557  /* Undetermined size, use the library routine.  */
3558  if (GET_CODE (operands[1]) != CONST_INT)
3559    FAIL;
3560
3561  size = INTVAL (operands[1]);
3562  align = INTVAL (operands[3]);
3563  align = align > 4 ? 4 : align;
3564
3565  /* If size/alignment is large, then use the library routines.  */
3566  if (size / align > 16)
3567    FAIL;
3568
3569  /* This does happen, but not often enough to worry much about.  */
3570  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3571    FAIL;
3572
3573  /* Fall through means we're going to use our block clear pattern.  */
3574  operands[0]
3575    = replace_equiv_address (operands[0],
3576			     copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3577  operands[4] = gen_reg_rtx (SImode);
3578  operands[5] = gen_reg_rtx (SImode);
3579}")
3580
3581(define_insn "clrmemsi_prereload"
3582  [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3583	(const_int 0))
3584   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3585   (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))	;tmp1
3586   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3587   (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3588  "!TARGET_64BIT"
3589  "#"
3590  [(set_attr "type" "multi,multi")])
3591
3592(define_split
3593  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3594		   (const_int 0))
3595	      (clobber (match_operand:SI 1 "register_operand" ""))
3596	      (clobber (match_operand:SI 4 "register_operand" ""))
3597	      (use (match_operand:SI 2 "arith14_operand" ""))
3598	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3599  "!TARGET_64BIT && reload_completed && !flag_peephole2
3600   && GET_CODE (operands[0]) == MEM
3601   && register_operand (XEXP (operands[0], 0), SImode)"
3602  [(set (match_dup 4) (match_dup 5))
3603   (parallel [(set (match_dup 0) (const_int 0))
3604   	      (clobber (match_dup 1))
3605   	      (clobber (match_dup 4))
3606   	      (use (match_dup 2))
3607   	      (use (match_dup 3))
3608	      (const_int 0)])]
3609  "
3610{
3611  operands[5] = XEXP (operands[0], 0);
3612  operands[0] = replace_equiv_address (operands[0], operands[4]);
3613}")
3614
3615(define_peephole2
3616  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3617		   (const_int 0))
3618	      (clobber (match_operand:SI 1 "register_operand" ""))
3619	      (clobber (match_operand:SI 4 "register_operand" ""))
3620	      (use (match_operand:SI 2 "arith14_operand" ""))
3621	      (use (match_operand:SI 3 "const_int_operand" ""))])]
3622  "!TARGET_64BIT
3623   && GET_CODE (operands[0]) == MEM
3624   && register_operand (XEXP (operands[0], 0), SImode)"
3625  [(parallel [(set (match_dup 0) (const_int 0))
3626   	      (clobber (match_dup 1))
3627   	      (clobber (match_dup 4))
3628   	      (use (match_dup 2))
3629   	      (use (match_dup 3))
3630	      (const_int 0)])]
3631  "
3632{
3633  rtx addr = XEXP (operands[0], 0);
3634  if (dead_or_set_p (curr_insn, addr))
3635    operands[4] = addr;
3636  else
3637    {
3638      emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3639      operands[0] = replace_equiv_address (operands[0], operands[4]);
3640    }
3641}")
3642
3643(define_insn "clrmemsi_postreload"
3644  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3645	(const_int 0))
3646   (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3647   (clobber (match_dup 0))
3648   (use (match_operand:SI 2 "arith14_operand" "J,1"))	 ;byte count
3649   (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3650   (const_int 0)]
3651  "!TARGET_64BIT && reload_completed"
3652  "* return pa_output_block_clear (operands, !which_alternative);"
3653  [(set_attr "type" "multi,multi")])
3654
3655(define_expand "setmemdi"
3656  [(parallel [(set (match_operand:BLK 0 "" "")
3657		   (match_operand 2 "const_int_operand" ""))
3658	      (clobber (match_dup 4))
3659	      (clobber (match_dup 5))
3660	      (use (match_operand:DI 1 "arith14_operand" ""))
3661	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3662  "TARGET_64BIT && optimize > 0"
3663  "
3664{
3665  int size, align;
3666
3667  /* If value to set is not zero, use the library routine.  */
3668  if (operands[2] != const0_rtx)
3669    FAIL;
3670
3671  /* Undetermined size, use the library routine.  */
3672  if (GET_CODE (operands[1]) != CONST_INT)
3673    FAIL;
3674
3675  size = INTVAL (operands[1]);
3676  align = INTVAL (operands[3]);
3677  align = align > 8 ? 8 : align;
3678
3679  /* If size/alignment is large, then use the library routines.  */
3680  if (size / align > 16)
3681    FAIL;
3682
3683  /* This does happen, but not often enough to worry much about.  */
3684  if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3685    FAIL;
3686
3687  /* Fall through means we're going to use our block clear pattern.  */
3688  operands[0]
3689    = replace_equiv_address (operands[0],
3690			     copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3691  operands[4] = gen_reg_rtx (DImode);
3692  operands[5] = gen_reg_rtx (DImode);
3693}")
3694
3695(define_insn "clrmemdi_prereload"
3696  [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3697	(const_int 0))
3698   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3699   (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))	;item tmp1
3700   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3701   (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3702  "TARGET_64BIT"
3703  "#"
3704  [(set_attr "type" "multi,multi")])
3705
3706(define_split
3707  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3708		   (const_int 0))
3709	      (clobber (match_operand:DI 1 "register_operand" ""))
3710	      (clobber (match_operand:DI 4 "register_operand" ""))
3711	      (use (match_operand:DI 2 "arith14_operand" ""))
3712	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3713  "TARGET_64BIT && reload_completed && !flag_peephole2
3714   && GET_CODE (operands[0]) == MEM
3715   && register_operand (XEXP (operands[0], 0), DImode)"
3716  [(set (match_dup 4) (match_dup 5))
3717   (parallel [(set (match_dup 0) (const_int 0))
3718   	      (clobber (match_dup 1))
3719   	      (clobber (match_dup 4))
3720   	      (use (match_dup 2))
3721   	      (use (match_dup 3))
3722	      (const_int 0)])]
3723  "
3724{
3725  operands[5] = XEXP (operands[0], 0);
3726  operands[0] = replace_equiv_address (operands[0], operands[4]);
3727}")
3728
3729(define_peephole2
3730  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3731		   (const_int 0))
3732	      (clobber (match_operand:DI 1 "register_operand" ""))
3733	      (clobber (match_operand:DI 4 "register_operand" ""))
3734	      (use (match_operand:DI 2 "arith14_operand" ""))
3735	      (use (match_operand:DI 3 "const_int_operand" ""))])]
3736  "TARGET_64BIT
3737   && GET_CODE (operands[0]) == MEM
3738   && register_operand (XEXP (operands[0], 0), DImode)"
3739  [(parallel [(set (match_dup 0) (const_int 0))
3740   	      (clobber (match_dup 1))
3741   	      (clobber (match_dup 4))
3742   	      (use (match_dup 2))
3743   	      (use (match_dup 3))
3744	      (const_int 0)])]
3745  "
3746{
3747  rtx addr = XEXP (operands[0], 0);
3748  if (dead_or_set_p (curr_insn, addr))
3749    operands[4] = addr;
3750  else
3751    {
3752      emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3753      operands[0] = replace_equiv_address (operands[0], operands[4]);
3754    }
3755}")
3756
3757(define_insn "clrmemdi_postreload"
3758  [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3759	(const_int 0))
3760   (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))	;loop cnt/tmp
3761   (clobber (match_dup 0))
3762   (use (match_operand:DI 2 "arith14_operand" "J,1"))	 ;byte count
3763   (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3764   (const_int 0)]
3765  "TARGET_64BIT && reload_completed"
3766  "* return pa_output_block_clear (operands, !which_alternative);"
3767  [(set_attr "type" "multi,multi")])
3768
3769;; Floating point move insns
3770
3771(define_expand "movdf"
3772  [(set (match_operand:DF 0 "general_operand" "")
3773	(match_operand:DF 1 "general_operand" ""))]
3774  ""
3775  "
3776{
3777  if (pa_emit_move_sequence (operands, DFmode, 0))
3778    DONE;
3779}")
3780
3781;; Handle DFmode input reloads requiring %r1 as a scratch register.
3782(define_expand "reload_indf_r1"
3783  [(set (match_operand:DF 0 "register_operand" "=Z")
3784	(match_operand:DF 1 "non_hard_reg_operand" ""))
3785   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3786  ""
3787  "
3788{
3789  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3790    DONE;
3791
3792  /* We don't want the clobber emitted, so handle this ourselves.  */
3793  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3794  DONE;
3795}")
3796
3797;; Handle DFmode input reloads requiring a general register as a
3798;; scratch register.
3799(define_expand "reload_indf"
3800  [(set (match_operand:DF 0 "register_operand" "=Z")
3801	(match_operand:DF 1 "non_hard_reg_operand" ""))
3802   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3803  ""
3804  "
3805{
3806  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3807    DONE;
3808
3809  /* We don't want the clobber emitted, so handle this ourselves.  */
3810  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3811  DONE;
3812}")
3813
3814;; Handle DFmode output reloads requiring a general register as a
3815;; scratch register.
3816(define_expand "reload_outdf"
3817 [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3818	(match_operand:DF 1  "register_operand" "Z"))
3819   (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3820  ""
3821  "
3822{
3823  if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3824    DONE;
3825
3826  /* We don't want the clobber emitted, so handle this ourselves.  */
3827  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3828  DONE;
3829}")
3830
3831(define_insn ""
3832  [(set (match_operand:DF 0 "move_dest_operand"
3833			  "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3834	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3835			  "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3836  "(register_operand (operands[0], DFmode)
3837    || reg_or_0_operand (operands[1], DFmode))
3838   && !(GET_CODE (operands[1]) == CONST_DOUBLE
3839	&& GET_CODE (operands[0]) == MEM)
3840   && !TARGET_64BIT
3841   && !TARGET_SOFT_FLOAT"
3842  "*
3843{
3844  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3845       || operands[1] == CONST0_RTX (DFmode))
3846      && !(REG_P (operands[0]) && REG_P (operands[1])
3847	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3848    return pa_output_fp_move_double (operands);
3849  return pa_output_move_double (operands);
3850}"
3851  [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3852   (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3853
3854(define_insn ""
3855  [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3856	(match_operand:DF 1 "reg_or_0_operand" "f"))]
3857  "!TARGET_SOFT_FLOAT
3858   && !TARGET_DISABLE_INDEXING
3859   && reload_completed"
3860  "fstd%F0 %1,%0"
3861  [(set_attr "type" "fpstore")
3862   (set_attr "pa_combine_type" "addmove")
3863   (set_attr "length" "4")])
3864
3865(define_peephole2
3866  [(set (match_operand:SI 0 "register_operand" "")
3867	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3868			  (const_int 8))
3869		 (match_operand:SI 2 "register_operand" "")))
3870   (set (mem:DF (match_dup 0))
3871        (match_operand:DF 3 "register_operand" ""))]
3872  "!TARGET_SOFT_FLOAT
3873   && !TARGET_DISABLE_INDEXING
3874   && REG_OK_FOR_BASE_P (operands[2])
3875   && FP_REGNO_P (REGNO (operands[3]))"
3876  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3877	(match_dup 3))
3878   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3879			       (match_dup 2)))]
3880  "")
3881
3882(define_peephole2
3883  [(set (match_operand:SI 0 "register_operand" "")
3884	(plus:SI (match_operand:SI 2 "register_operand" "")
3885		 (mult:SI (match_operand:SI 1 "register_operand" "")
3886			  (const_int 8))))
3887   (set (mem:DF (match_dup 0))
3888        (match_operand:DF 3 "register_operand" ""))]
3889  "!TARGET_SOFT_FLOAT
3890   && !TARGET_DISABLE_INDEXING
3891   && REG_OK_FOR_BASE_P (operands[2])
3892   && FP_REGNO_P (REGNO (operands[3]))"
3893  [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3894	(match_dup 3))
3895   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3896			       (match_dup 2)))]
3897  "")
3898
3899(define_peephole2
3900  [(set (match_operand:DI 0 "register_operand" "")
3901	(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
3902			  (const_int 8))
3903		 (match_operand:DI 2 "register_operand" "")))
3904   (set (mem:DF (match_dup 0))
3905        (match_operand:DF 3 "register_operand" ""))]
3906  "!TARGET_SOFT_FLOAT
3907   && !TARGET_DISABLE_INDEXING
3908   && TARGET_64BIT
3909   && REG_OK_FOR_BASE_P (operands[2])
3910   && FP_REGNO_P (REGNO (operands[3]))"
3911  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3912	(match_dup 3))
3913   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3914			       (match_dup 2)))]
3915  "")
3916
3917(define_peephole2
3918  [(set (match_operand:DI 0 "register_operand" "")
3919	(plus:DI (match_operand:DI 2 "register_operand" "")
3920		 (mult:DI (match_operand:DI 1 "register_operand" "")
3921			  (const_int 8))))
3922   (set (mem:DF (match_dup 0))
3923        (match_operand:DF 3 "register_operand" ""))]
3924  "!TARGET_SOFT_FLOAT
3925   && !TARGET_DISABLE_INDEXING
3926   && TARGET_64BIT
3927   && REG_OK_FOR_BASE_P (operands[2])
3928   && FP_REGNO_P (REGNO (operands[3]))"
3929  [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3930	(match_dup 3))
3931   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3932			       (match_dup 2)))]
3933  "")
3934
3935(define_peephole2
3936  [(set (match_operand:SI 0 "register_operand" "")
3937	(plus:SI (match_operand:SI 1 "register_operand" "")
3938		 (match_operand:SI 2 "register_operand" "")))
3939   (set (mem:DF (match_dup 0))
3940        (match_operand:DF 3 "register_operand" ""))]
3941  "!TARGET_SOFT_FLOAT
3942   && !TARGET_DISABLE_INDEXING
3943   && TARGET_NO_SPACE_REGS
3944   && REG_OK_FOR_INDEX_P (operands[1])
3945   && REG_OK_FOR_BASE_P (operands[2])
3946   && FP_REGNO_P (REGNO (operands[3]))"
3947  [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3948	(match_dup 3))
3949   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3950  "")
3951
3952(define_peephole2
3953  [(set (match_operand:SI 0 "register_operand" "")
3954	(plus:SI (match_operand:SI 1 "register_operand" "")
3955		 (match_operand:SI 2 "register_operand" "")))
3956   (set (mem:DF (match_dup 0))
3957        (match_operand:DF 3 "register_operand" ""))]
3958  "!TARGET_SOFT_FLOAT
3959   && !TARGET_DISABLE_INDEXING
3960   && TARGET_NO_SPACE_REGS
3961   && REG_OK_FOR_BASE_P (operands[1])
3962   && REG_OK_FOR_INDEX_P (operands[2])
3963   && FP_REGNO_P (REGNO (operands[3]))"
3964  [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3965	(match_dup 3))
3966   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3967  "")
3968
3969(define_peephole2
3970  [(set (match_operand:DI 0 "register_operand" "")
3971	(plus:DI (match_operand:DI 1 "register_operand" "")
3972		 (match_operand:DI 2 "register_operand" "")))
3973   (set (mem:DF (match_dup 0))
3974        (match_operand:DF 3 "register_operand" ""))]
3975  "!TARGET_SOFT_FLOAT
3976   && !TARGET_DISABLE_INDEXING
3977   && TARGET_64BIT
3978   && TARGET_NO_SPACE_REGS
3979   && REG_OK_FOR_INDEX_P (operands[1])
3980   && REG_OK_FOR_BASE_P (operands[2])
3981   && FP_REGNO_P (REGNO (operands[3]))"
3982  [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
3983	(match_dup 3))
3984   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
3985  "")
3986
3987(define_peephole2
3988  [(set (match_operand:DI 0 "register_operand" "")
3989	(plus:DI (match_operand:DI 1 "register_operand" "")
3990		 (match_operand:DI 2 "register_operand" "")))
3991   (set (mem:DF (match_dup 0))
3992        (match_operand:DF 3 "register_operand" ""))]
3993  "!TARGET_SOFT_FLOAT
3994   && !TARGET_DISABLE_INDEXING
3995   && TARGET_64BIT
3996   && TARGET_NO_SPACE_REGS
3997   && REG_OK_FOR_BASE_P (operands[1])
3998   && REG_OK_FOR_INDEX_P (operands[2])
3999   && FP_REGNO_P (REGNO (operands[3]))"
4000  [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4001	(match_dup 3))
4002   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4003  "")
4004
4005(define_insn ""
4006  [(set (match_operand:DF 0 "move_dest_operand"
4007			  "=r,?o,?Q,r,r")
4008	(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4009			  "rG,r,r,o,RQ"))]
4010  "(register_operand (operands[0], DFmode)
4011    || reg_or_0_operand (operands[1], DFmode))
4012   && !TARGET_64BIT
4013   && TARGET_SOFT_FLOAT"
4014  "*
4015{
4016  return pa_output_move_double (operands);
4017}"
4018  [(set_attr "type" "move,store,store,load,load")
4019   (set_attr "length" "8,8,16,8,16")])
4020
4021(define_insn ""
4022  [(set (match_operand:DF 0 "move_dest_operand"
4023			  "=!*r,*r,*r,*r,*r,Q,f,f,T")
4024	(match_operand:DF 1 "move_src_operand"
4025			  "!*r,J,N,K,RQ,*rG,fG,RT,f"))]
4026  "(register_operand (operands[0], DFmode)
4027    || reg_or_0_operand (operands[1], DFmode))
4028   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4029  "@
4030   copy %1,%0
4031   ldi %1,%0
4032   ldil L'%1,%0
4033   depdi,z %z1,%0
4034   ldd%M1 %1,%0
4035   std%M0 %r1,%0
4036   fcpy,dbl %f1,%0
4037   fldd%F1 %1,%0
4038   fstd%F0 %1,%0"
4039  [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4040   (set_attr "pa_combine_type" "addmove")
4041   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4042
4043
4044(define_expand "movdi"
4045  [(set (match_operand:DI 0 "general_operand" "")
4046	(match_operand:DI 1 "general_operand" ""))]
4047  ""
4048  "
4049{
4050  if (pa_emit_move_sequence (operands, DImode, 0))
4051    DONE;
4052}")
4053
4054;; Handle DImode input reloads requiring %r1 as a scratch register.
4055(define_expand "reload_indi_r1"
4056  [(set (match_operand:DI 0 "register_operand" "=Z")
4057	(match_operand:DI 1 "non_hard_reg_operand" ""))
4058   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4059  ""
4060  "
4061{
4062  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4063    DONE;
4064
4065  /* We don't want the clobber emitted, so handle this ourselves.  */
4066  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4067  DONE;
4068}")
4069
4070;; Handle DImode input reloads requiring a general register as a
4071;; scratch register.
4072(define_expand "reload_indi"
4073  [(set (match_operand:DI 0 "register_operand" "=Z")
4074	(match_operand:DI 1 "non_hard_reg_operand" ""))
4075   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4076  ""
4077  "
4078{
4079  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4080    DONE;
4081
4082  /* We don't want the clobber emitted, so handle this ourselves.  */
4083  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4084  DONE;
4085}")
4086
4087;; Handle DImode output reloads requiring a general register as a
4088;; scratch register.
4089(define_expand "reload_outdi"
4090  [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4091	(match_operand:DI 1 "register_operand" "Z"))
4092   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4093  ""
4094  "
4095{
4096  if (pa_emit_move_sequence (operands, DImode, operands[2]))
4097    DONE;
4098
4099  /* We don't want the clobber emitted, so handle this ourselves.  */
4100  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4101  DONE;
4102}")
4103
4104(define_insn ""
4105  [(set (match_operand:DI 0 "register_operand" "=r")
4106	(high:DI (match_operand 1 "" "")))]
4107  "!TARGET_64BIT"
4108  "*
4109{
4110  rtx op0 = operands[0];
4111  rtx op1 = operands[1];
4112
4113  switch (GET_CODE (op1))
4114    {
4115    case CONST_INT:
4116#if HOST_BITS_PER_WIDE_INT <= 32
4117      operands[0] = operand_subword (op0, 1, 0, DImode);
4118      output_asm_insn (\"ldil L'%1,%0\", operands);
4119
4120      operands[0] = operand_subword (op0, 0, 0, DImode);
4121      if (INTVAL (op1) < 0)
4122	output_asm_insn (\"ldi -1,%0\", operands);
4123      else
4124	output_asm_insn (\"ldi 0,%0\", operands);
4125#else
4126      operands[0] = operand_subword (op0, 1, 0, DImode);
4127      operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4128      output_asm_insn (\"ldil L'%1,%0\", operands);
4129
4130      operands[0] = operand_subword (op0, 0, 0, DImode);
4131      operands[1] = GEN_INT (INTVAL (op1) >> 32);
4132      output_asm_insn (pa_singlemove_string (operands), operands);
4133#endif
4134      break;
4135
4136    case CONST_DOUBLE:
4137      operands[0] = operand_subword (op0, 1, 0, DImode);
4138      operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4139      output_asm_insn (\"ldil L'%1,%0\", operands);
4140
4141      operands[0] = operand_subword (op0, 0, 0, DImode);
4142      operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4143      output_asm_insn (pa_singlemove_string (operands), operands);
4144      break;
4145
4146    default:
4147      gcc_unreachable ();
4148    }
4149  return \"\";
4150}"
4151  [(set_attr "type" "move")
4152   (set_attr "length" "12")])
4153
4154(define_insn ""
4155  [(set (match_operand:DI 0 "move_dest_operand"
4156			  "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4157	(match_operand:DI 1 "move_src_operand"
4158			  "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4159  "(register_operand (operands[0], DImode)
4160    || reg_or_0_operand (operands[1], DImode))
4161   && !TARGET_64BIT
4162   && !TARGET_SOFT_FLOAT"
4163  "*
4164{
4165  if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4166       || operands[1] == CONST0_RTX (DFmode))
4167      && !(REG_P (operands[0]) && REG_P (operands[1])
4168	   && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4169    return pa_output_fp_move_double (operands);
4170  return pa_output_move_double (operands);
4171}"
4172  [(set_attr "type"
4173    "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4174   (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4175
4176(define_insn ""
4177  [(set (match_operand:DI 0 "move_dest_operand"
4178			  "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4179	(match_operand:DI 1 "move_src_operand"
4180			  "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4181  "(register_operand (operands[0], DImode)
4182    || reg_or_0_operand (operands[1], DImode))
4183   && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4184  "@
4185   ldd RT'%A1,%0
4186   copy %1,%0
4187   ldi %1,%0
4188   ldil L'%1,%0
4189   depdi,z %z1,%0
4190   ldd%M1 %1,%0
4191   std%M0 %r1,%0
4192   mtsar %r1
4193   {mfctl|mfctl,w} %%sar,%0
4194   fcpy,dbl %f1,%0
4195   fldd%F1 %1,%0
4196   fstd%F0 %1,%0"
4197  [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4198   (set_attr "pa_combine_type" "addmove")
4199   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4200
4201(define_insn ""
4202  [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4203	(match_operand:DI 1 "register_operand" "f"))]
4204  "!TARGET_SOFT_FLOAT
4205   && TARGET_64BIT
4206   && !TARGET_DISABLE_INDEXING
4207   && reload_completed"
4208  "fstd%F0 %1,%0"
4209  [(set_attr "type" "fpstore")
4210   (set_attr "pa_combine_type" "addmove")
4211   (set_attr "length" "4")])
4212
4213(define_peephole2
4214  [(set (match_operand:DI 0 "register_operand" "")
4215	(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4216			  (const_int 8))
4217		 (match_operand:DI 2 "register_operand" "")))
4218   (set (mem:DI (match_dup 0))
4219        (match_operand:DI 3 "register_operand" ""))]
4220  "!TARGET_SOFT_FLOAT
4221   && !TARGET_DISABLE_INDEXING
4222   && TARGET_64BIT
4223   && REG_OK_FOR_BASE_P (operands[2])
4224   && FP_REGNO_P (REGNO (operands[3]))"
4225  [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4226	(match_dup 3))
4227   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4228			       (match_dup 2)))]
4229  "")
4230
4231(define_peephole2
4232  [(set (match_operand:DI 0 "register_operand" "")
4233	(plus:DI (match_operand:DI 2 "register_operand" "")
4234		 (mult:DI (match_operand:DI 1 "register_operand" "")
4235			  (const_int 8))))
4236   (set (mem:DI (match_dup 0))
4237        (match_operand:DI 3 "register_operand" ""))]
4238  "!TARGET_SOFT_FLOAT
4239   && !TARGET_DISABLE_INDEXING
4240   && TARGET_64BIT
4241   && REG_OK_FOR_BASE_P (operands[2])
4242   && FP_REGNO_P (REGNO (operands[3]))"
4243  [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4244	(match_dup 3))
4245   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4246			       (match_dup 2)))]
4247  "")
4248
4249(define_peephole2
4250  [(set (match_operand:DI 0 "register_operand" "")
4251	(plus:DI (match_operand:DI 1 "register_operand" "")
4252		 (match_operand:DI 2 "register_operand" "")))
4253   (set (mem:DI (match_dup 0))
4254        (match_operand:DI 3 "register_operand" ""))]
4255  "!TARGET_SOFT_FLOAT
4256   && !TARGET_DISABLE_INDEXING
4257   && TARGET_64BIT
4258   && TARGET_NO_SPACE_REGS
4259   && REG_OK_FOR_INDEX_P (operands[1])
4260   && REG_OK_FOR_BASE_P (operands[2])
4261   && FP_REGNO_P (REGNO (operands[3]))"
4262  [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4263	(match_dup 3))
4264   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4265  "")
4266
4267(define_peephole2
4268  [(set (match_operand:DI 0 "register_operand" "")
4269	(plus:DI (match_operand:DI 1 "register_operand" "")
4270		 (match_operand:DI 2 "register_operand" "")))
4271   (set (mem:DI (match_dup 0))
4272        (match_operand:DI 3 "register_operand" ""))]
4273  "!TARGET_SOFT_FLOAT
4274   && !TARGET_DISABLE_INDEXING
4275   && TARGET_64BIT
4276   && TARGET_NO_SPACE_REGS
4277   && REG_OK_FOR_BASE_P (operands[1])
4278   && REG_OK_FOR_INDEX_P (operands[2])
4279   && FP_REGNO_P (REGNO (operands[3]))"
4280  [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4281	(match_dup 3))
4282   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4283  "")
4284
4285(define_insn ""
4286  [(set (match_operand:DI 0 "move_dest_operand"
4287			  "=r,o,Q,r,r,r")
4288	(match_operand:DI 1 "general_operand"
4289			  "rM,r,r,o,Q,i"))]
4290  "(register_operand (operands[0], DImode)
4291    || reg_or_0_operand (operands[1], DImode))
4292   && !TARGET_64BIT
4293   && TARGET_SOFT_FLOAT"
4294  "*
4295{
4296  return pa_output_move_double (operands);
4297}"
4298  [(set_attr "type" "move,store,store,load,load,multi")
4299   (set_attr "length" "8,8,16,8,16,16")])
4300
4301(define_insn ""
4302  [(set (match_operand:DI 0 "register_operand" "=r,&r")
4303	(lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4304		   (match_operand:DI 2 "immediate_operand" "i,i")))]
4305  "!TARGET_64BIT"
4306  "*
4307{
4308  /* Don't output a 64-bit constant, since we can't trust the assembler to
4309     handle it correctly.  */
4310  if (GET_CODE (operands[2]) == CONST_DOUBLE)
4311    operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4312  else if (HOST_BITS_PER_WIDE_INT > 32
4313	   && GET_CODE (operands[2]) == CONST_INT)
4314    operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4315  if (which_alternative == 1)
4316    output_asm_insn (\"copy %1,%0\", operands);
4317  return \"ldo R'%G2(%R1),%R0\";
4318}"
4319  [(set_attr "type" "move,move")
4320   (set_attr "length" "4,8")])
4321
4322(define_expand "movsf"
4323  [(set (match_operand:SF 0 "general_operand" "")
4324	(match_operand:SF 1 "general_operand" ""))]
4325  ""
4326  "
4327{
4328  if (pa_emit_move_sequence (operands, SFmode, 0))
4329    DONE;
4330}")
4331
4332;; Handle SFmode input reloads requiring %r1 as a scratch register.
4333(define_expand "reload_insf_r1"
4334  [(set (match_operand:SF 0 "register_operand" "=Z")
4335	(match_operand:SF 1 "non_hard_reg_operand" ""))
4336   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4337  ""
4338  "
4339{
4340  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4341    DONE;
4342
4343  /* We don't want the clobber emitted, so handle this ourselves.  */
4344  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4345  DONE;
4346}")
4347
4348;; Handle SFmode input reloads requiring a general register as a
4349;; scratch register.
4350(define_expand "reload_insf"
4351  [(set (match_operand:SF 0 "register_operand" "=Z")
4352	(match_operand:SF 1 "non_hard_reg_operand" ""))
4353   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4354  ""
4355  "
4356{
4357  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4358    DONE;
4359
4360  /* We don't want the clobber emitted, so handle this ourselves.  */
4361  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4362  DONE;
4363}")
4364
4365;; Handle SFmode output reloads requiring a general register as a
4366;; scratch register.
4367(define_expand "reload_outsf"
4368  [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4369	(match_operand:SF 1  "register_operand" "Z"))
4370   (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4371  ""
4372  "
4373{
4374  if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4375    DONE;
4376
4377  /* We don't want the clobber emitted, so handle this ourselves.  */
4378  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4379  DONE;
4380}")
4381
4382(define_insn ""
4383  [(set (match_operand:SF 0 "move_dest_operand"
4384			  "=f,!*r,f,*r,T,Q,?*r,?f")
4385	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4386			  "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4387  "(register_operand (operands[0], SFmode)
4388    || reg_or_0_operand (operands[1], SFmode))
4389   && !TARGET_SOFT_FLOAT
4390   && !TARGET_64BIT"
4391  "@
4392   fcpy,sgl %f1,%0
4393   copy %r1,%0
4394   fldw%F1 %1,%0
4395   ldw%M1 %1,%0
4396   fstw%F0 %1,%0
4397   stw%M0 %r1,%0
4398   {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4399   {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4400  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4401   (set_attr "pa_combine_type" "addmove")
4402   (set_attr "length" "4,4,4,4,4,4,8,8")])
4403
4404(define_insn ""
4405  [(set (match_operand:SF 0 "move_dest_operand"
4406			  "=f,!*r,f,*r,T,Q")
4407	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4408			  "fG,!*rG,RT,RQ,f,*rG"))]
4409  "(register_operand (operands[0], SFmode)
4410    || reg_or_0_operand (operands[1], SFmode))
4411   && !TARGET_SOFT_FLOAT
4412   && TARGET_64BIT"
4413  "@
4414   fcpy,sgl %f1,%0
4415   copy %r1,%0
4416   fldw%F1 %1,%0
4417   ldw%M1 %1,%0
4418   fstw%F0 %1,%0
4419   stw%M0 %r1,%0"
4420  [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4421   (set_attr "pa_combine_type" "addmove")
4422   (set_attr "length" "4,4,4,4,4,4")])
4423
4424(define_insn ""
4425  [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4426	(match_operand:SF 1 "register_operand" "f"))]
4427  "!TARGET_SOFT_FLOAT
4428   && !TARGET_DISABLE_INDEXING
4429   && reload_completed"
4430  "fstw%F0 %1,%0"
4431  [(set_attr "type" "fpstore")
4432   (set_attr "pa_combine_type" "addmove")
4433   (set_attr "length" "4")])
4434
4435(define_peephole2
4436  [(set (match_operand:SI 0 "register_operand" "")
4437	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4438			  (const_int 4))
4439		 (match_operand:SI 2 "register_operand" "")))
4440   (set (mem:SF (match_dup 0))
4441        (match_operand:SF 3 "register_operand" ""))]
4442  "!TARGET_SOFT_FLOAT
4443   && !TARGET_DISABLE_INDEXING
4444   && REG_OK_FOR_BASE_P (operands[2])
4445   && FP_REGNO_P (REGNO (operands[3]))"
4446  [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4447	(match_dup 3))
4448   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4449			       (match_dup 2)))]
4450  "")
4451
4452(define_peephole2
4453  [(set (match_operand:SI 0 "register_operand" "")
4454	(plus:SI (match_operand:SI 2 "register_operand" "")
4455		 (mult:SI (match_operand:SI 1 "register_operand" "")
4456			  (const_int 4))))
4457   (set (mem:SF (match_dup 0))
4458        (match_operand:SF 3 "register_operand" ""))]
4459  "!TARGET_SOFT_FLOAT
4460   && !TARGET_DISABLE_INDEXING
4461   && REG_OK_FOR_BASE_P (operands[2])
4462   && FP_REGNO_P (REGNO (operands[3]))"
4463  [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4464	(match_dup 3))
4465   (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4466			       (match_dup 2)))]
4467  "")
4468
4469(define_peephole2
4470  [(set (match_operand:DI 0 "register_operand" "")
4471	(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4472			  (const_int 4))
4473		 (match_operand:DI 2 "register_operand" "")))
4474   (set (mem:SF (match_dup 0))
4475        (match_operand:SF 3 "register_operand" ""))]
4476  "!TARGET_SOFT_FLOAT
4477   && !TARGET_DISABLE_INDEXING
4478   && TARGET_64BIT
4479   && REG_OK_FOR_BASE_P (operands[2])
4480   && FP_REGNO_P (REGNO (operands[3]))"
4481  [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4482	(match_dup 3))
4483   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4484			       (match_dup 2)))]
4485  "")
4486
4487(define_peephole2
4488  [(set (match_operand:DI 0 "register_operand" "")
4489	(plus:DI (match_operand:DI 2 "register_operand" "")
4490		 (mult:DI (match_operand:DI 1 "register_operand" "")
4491			  (const_int 4))))
4492   (set (mem:SF (match_dup 0))
4493        (match_operand:SF 3 "register_operand" ""))]
4494  "!TARGET_SOFT_FLOAT
4495   && !TARGET_DISABLE_INDEXING
4496   && TARGET_64BIT
4497   && REG_OK_FOR_BASE_P (operands[2])
4498   && FP_REGNO_P (REGNO (operands[3]))"
4499  [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4500	(match_dup 3))
4501   (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4502			       (match_dup 2)))]
4503  "")
4504
4505(define_peephole2
4506  [(set (match_operand:SI 0 "register_operand" "")
4507	(plus:SI (match_operand:SI 1 "register_operand" "")
4508		 (match_operand:SI 2 "register_operand" "")))
4509   (set (mem:SF (match_dup 0))
4510        (match_operand:SF 3 "register_operand" ""))]
4511  "!TARGET_SOFT_FLOAT
4512   && !TARGET_DISABLE_INDEXING
4513   && TARGET_NO_SPACE_REGS
4514   && REG_OK_FOR_INDEX_P (operands[1])
4515   && REG_OK_FOR_BASE_P (operands[2])
4516   && FP_REGNO_P (REGNO (operands[3]))"
4517  [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4518	(match_dup 3))
4519   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4520  "")
4521
4522(define_peephole2
4523  [(set (match_operand:SI 0 "register_operand" "")
4524	(plus:SI (match_operand:SI 1 "register_operand" "")
4525		 (match_operand:SI 2 "register_operand" "")))
4526   (set (mem:SF (match_dup 0))
4527        (match_operand:SF 3 "register_operand" ""))]
4528  "!TARGET_SOFT_FLOAT
4529   && !TARGET_DISABLE_INDEXING
4530   && TARGET_NO_SPACE_REGS
4531   && REG_OK_FOR_BASE_P (operands[1])
4532   && REG_OK_FOR_INDEX_P (operands[2])
4533   && FP_REGNO_P (REGNO (operands[3]))"
4534  [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4535	(match_dup 3))
4536   (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4537  "")
4538
4539(define_peephole2
4540  [(set (match_operand:DI 0 "register_operand" "")
4541	(plus:DI (match_operand:DI 1 "register_operand" "")
4542		 (match_operand:DI 2 "register_operand" "")))
4543   (set (mem:SF (match_dup 0))
4544        (match_operand:SF 3 "register_operand" ""))]
4545  "!TARGET_SOFT_FLOAT
4546   && !TARGET_DISABLE_INDEXING
4547   && TARGET_64BIT
4548   && TARGET_NO_SPACE_REGS
4549   && REG_OK_FOR_INDEX_P (operands[1])
4550   && REG_OK_FOR_BASE_P (operands[2])
4551   && FP_REGNO_P (REGNO (operands[3]))"
4552  [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4553	(match_dup 3))
4554   (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4555  "")
4556
4557(define_peephole2
4558  [(set (match_operand:DI 0 "register_operand" "")
4559	(plus:DI (match_operand:DI 1 "register_operand" "")
4560		 (match_operand:DI 2 "register_operand" "")))
4561   (set (mem:SF (match_dup 0))
4562        (match_operand:SF 3 "register_operand" ""))]
4563  "!TARGET_SOFT_FLOAT
4564   && !TARGET_DISABLE_INDEXING
4565   && TARGET_64BIT
4566   && TARGET_NO_SPACE_REGS
4567   && REG_OK_FOR_BASE_P (operands[1])
4568   && REG_OK_FOR_INDEX_P (operands[2])
4569   && FP_REGNO_P (REGNO (operands[3]))"
4570  [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4571	(match_dup 3))
4572   (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4573  "")
4574
4575(define_insn ""
4576  [(set (match_operand:SF 0 "move_dest_operand"
4577			  "=r,r,Q")
4578	(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4579			  "rG,RQ,rG"))]
4580  "(register_operand (operands[0], SFmode)
4581    || reg_or_0_operand (operands[1], SFmode))
4582   && TARGET_SOFT_FLOAT"
4583  "@
4584   copy %r1,%0
4585   ldw%M1 %1,%0
4586   stw%M0 %r1,%0"
4587  [(set_attr "type" "move,load,store")
4588   (set_attr "pa_combine_type" "addmove")
4589   (set_attr "length" "4,4,4")])
4590
4591
4592
4593;;- zero extension instructions
4594;; We have define_expand for zero extension patterns to make sure the
4595;; operands get loaded into registers.  The define_insns accept
4596;; memory operands.  This gives us better overall code than just
4597;; having a pattern that does or does not accept memory operands.
4598
4599(define_expand "zero_extendqihi2"
4600  [(set (match_operand:HI 0 "register_operand" "")
4601	(zero_extend:HI
4602	 (match_operand:QI 1 "register_operand" "")))]
4603  ""
4604  "")
4605
4606(define_insn ""
4607  [(set (match_operand:HI 0 "register_operand" "=r,r")
4608	(zero_extend:HI
4609	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4610  "GET_CODE (operands[1]) != CONST_INT"
4611  "@
4612   {extru|extrw,u} %1,31,8,%0
4613   ldb%M1 %1,%0"
4614  [(set_attr "type" "shift,load")
4615   (set_attr "length" "4,4")])
4616
4617(define_expand "zero_extendqisi2"
4618  [(set (match_operand:SI 0 "register_operand" "")
4619	(zero_extend:SI
4620	 (match_operand:QI 1 "register_operand" "")))]
4621  ""
4622  "")
4623
4624(define_insn ""
4625  [(set (match_operand:SI 0 "register_operand" "=r,r")
4626	(zero_extend:SI
4627	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4628  "GET_CODE (operands[1]) != CONST_INT"
4629  "@
4630   {extru|extrw,u} %1,31,8,%0
4631   ldb%M1 %1,%0"
4632  [(set_attr "type" "shift,load")
4633   (set_attr "length" "4,4")])
4634
4635(define_expand "zero_extendhisi2"
4636  [(set (match_operand:SI 0 "register_operand" "")
4637	(zero_extend:SI
4638	 (match_operand:HI 1 "register_operand" "")))]
4639  ""
4640  "")
4641
4642(define_insn ""
4643  [(set (match_operand:SI 0 "register_operand" "=r,r")
4644	(zero_extend:SI
4645	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4646  "GET_CODE (operands[1]) != CONST_INT"
4647  "@
4648   {extru|extrw,u} %1,31,16,%0
4649   ldh%M1 %1,%0"
4650  [(set_attr "type" "shift,load")
4651   (set_attr "length" "4,4")])
4652
4653(define_expand "zero_extendqidi2"
4654  [(set (match_operand:DI 0 "register_operand" "")
4655	(zero_extend:DI
4656	 (match_operand:QI 1 "register_operand" "")))]
4657  "TARGET_64BIT"
4658  "")
4659
4660(define_insn ""
4661  [(set (match_operand:DI 0 "register_operand" "=r,r")
4662	(zero_extend:DI
4663	 (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4664  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4665  "@
4666   extrd,u %1,63,8,%0
4667   ldb%M1 %1,%0"
4668  [(set_attr "type" "shift,load")
4669   (set_attr "length" "4,4")])
4670
4671(define_expand "zero_extendhidi2"
4672  [(set (match_operand:DI 0 "register_operand" "")
4673	(zero_extend:DI
4674	 (match_operand:HI 1 "register_operand" "")))]
4675  "TARGET_64BIT"
4676  "")
4677
4678(define_insn ""
4679  [(set (match_operand:DI 0 "register_operand" "=r,r")
4680	(zero_extend:DI
4681	 (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4682  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4683  "@
4684   extrd,u %1,63,16,%0
4685   ldh%M1 %1,%0"
4686  [(set_attr "type" "shift,load")
4687   (set_attr "length" "4,4")])
4688
4689(define_expand "zero_extendsidi2"
4690  [(set (match_operand:DI 0 "register_operand" "")
4691	(zero_extend:DI
4692	 (match_operand:SI 1 "register_operand" "")))]
4693  "TARGET_64BIT"
4694  "")
4695
4696(define_insn ""
4697  [(set (match_operand:DI 0 "register_operand" "=r,r")
4698	(zero_extend:DI
4699	 (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4700  "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4701  "@
4702   extrd,u %1,63,32,%0
4703   ldw%M1 %1,%0"
4704  [(set_attr "type" "shift,load")
4705   (set_attr "length" "4,4")])
4706
4707;;- sign extension instructions
4708
4709(define_insn "extendhisi2"
4710  [(set (match_operand:SI 0 "register_operand" "=r")
4711	(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4712  ""
4713  "{extrs|extrw,s} %1,31,16,%0"
4714  [(set_attr "type" "shift")
4715   (set_attr "length" "4")])
4716
4717(define_insn "extendqihi2"
4718  [(set (match_operand:HI 0 "register_operand" "=r")
4719	(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4720  ""
4721  "{extrs|extrw,s} %1,31,8,%0"
4722  [(set_attr "type" "shift")
4723  (set_attr "length" "4")])
4724
4725(define_insn "extendqisi2"
4726  [(set (match_operand:SI 0 "register_operand" "=r")
4727	(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4728  ""
4729  "{extrs|extrw,s} %1,31,8,%0"
4730  [(set_attr "type" "shift")
4731   (set_attr "length" "4")])
4732
4733(define_insn "extendqidi2"
4734  [(set (match_operand:DI 0 "register_operand" "=r")
4735	(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4736  "TARGET_64BIT"
4737  "extrd,s %1,63,8,%0"
4738  [(set_attr "type" "shift")
4739  (set_attr "length" "4")])
4740
4741(define_insn "extendhidi2"
4742  [(set (match_operand:DI 0 "register_operand" "=r")
4743	(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4744  "TARGET_64BIT"
4745  "extrd,s %1,63,16,%0"
4746  [(set_attr "type" "shift")
4747  (set_attr "length" "4")])
4748
4749(define_insn "extendsidi2"
4750  [(set (match_operand:DI 0 "register_operand" "=r")
4751	(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4752  "TARGET_64BIT"
4753  "extrd,s %1,63,32,%0"
4754  [(set_attr "type" "shift")
4755  (set_attr "length" "4")])
4756
4757
4758;; Conversions between float and double.
4759
4760(define_insn "extendsfdf2"
4761  [(set (match_operand:DF 0 "register_operand" "=f")
4762	(float_extend:DF
4763	 (match_operand:SF 1 "register_operand" "f")))]
4764  "! TARGET_SOFT_FLOAT"
4765  "{fcnvff|fcnv},sgl,dbl %1,%0"
4766  [(set_attr "type" "fpalu")
4767   (set_attr "length" "4")])
4768
4769(define_insn "truncdfsf2"
4770  [(set (match_operand:SF 0 "register_operand" "=f")
4771	(float_truncate:SF
4772	 (match_operand:DF 1 "register_operand" "f")))]
4773  "! TARGET_SOFT_FLOAT"
4774  "{fcnvff|fcnv},dbl,sgl %1,%0"
4775  [(set_attr "type" "fpalu")
4776   (set_attr "length" "4")])
4777
4778;; Conversion between fixed point and floating point.
4779;; Note that among the fix-to-float insns
4780;; the ones that start with SImode come first.
4781;; That is so that an operand that is a CONST_INT
4782;; (and therefore lacks a specific machine mode).
4783;; will be recognized as SImode (which is always valid)
4784;; rather than as QImode or HImode.
4785
4786;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4787;; to be reloaded by putting the constant into memory.
4788;; It must come before the more general floatsisf2 pattern.
4789(define_insn ""
4790  [(set (match_operand:SF 0 "register_operand" "=f")
4791	(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4792  "! TARGET_SOFT_FLOAT"
4793  "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4794  [(set_attr "type" "fpalu")
4795   (set_attr "length" "8")])
4796
4797(define_insn "floatsisf2"
4798  [(set (match_operand:SF 0 "register_operand" "=f")
4799	(float:SF (match_operand:SI 1 "register_operand" "f")))]
4800  "! TARGET_SOFT_FLOAT"
4801  "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4802  [(set_attr "type" "fpalu")
4803   (set_attr "length" "4")])
4804
4805;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4806;; to be reloaded by putting the constant into memory.
4807;; It must come before the more general floatsidf2 pattern.
4808(define_insn ""
4809  [(set (match_operand:DF 0 "register_operand" "=f")
4810	(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4811  "! TARGET_SOFT_FLOAT"
4812  "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4813  [(set_attr "type" "fpalu")
4814   (set_attr "length" "8")])
4815
4816(define_insn "floatsidf2"
4817  [(set (match_operand:DF 0 "register_operand" "=f")
4818	(float:DF (match_operand:SI 1 "register_operand" "f")))]
4819  "! TARGET_SOFT_FLOAT"
4820  "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4821  [(set_attr "type" "fpalu")
4822   (set_attr "length" "4")])
4823
4824(define_expand "floatunssisf2"
4825  [(set (subreg:SI (match_dup 2) 4)
4826	(match_operand:SI 1 "register_operand" ""))
4827   (set (subreg:SI (match_dup 2) 0)
4828	(const_int 0))
4829   (set (match_operand:SF 0 "register_operand" "")
4830	(float:SF (match_dup 2)))]
4831  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4832  "
4833{
4834  if (TARGET_PA_20)
4835    {
4836      emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4837      DONE;
4838    }
4839  operands[2] = gen_reg_rtx (DImode);
4840}")
4841
4842(define_expand "floatunssidf2"
4843  [(set (subreg:SI (match_dup 2) 4)
4844	(match_operand:SI 1 "register_operand" ""))
4845   (set (subreg:SI (match_dup 2) 0)
4846	(const_int 0))
4847   (set (match_operand:DF 0 "register_operand" "")
4848	(float:DF (match_dup 2)))]
4849  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4850  "
4851{
4852  if (TARGET_PA_20)
4853    {
4854      emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4855      DONE;
4856    }
4857  operands[2] = gen_reg_rtx (DImode);
4858}")
4859
4860(define_insn "floatdisf2"
4861  [(set (match_operand:SF 0 "register_operand" "=f")
4862	(float:SF (match_operand:DI 1 "register_operand" "f")))]
4863  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4864  "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4865  [(set_attr "type" "fpalu")
4866   (set_attr "length" "4")])
4867
4868(define_insn "floatdidf2"
4869  [(set (match_operand:DF 0 "register_operand" "=f")
4870	(float:DF (match_operand:DI 1 "register_operand" "f")))]
4871  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4872  "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4873  [(set_attr "type" "fpalu")
4874   (set_attr "length" "4")])
4875
4876;; Convert a float to an actual integer.
4877;; Truncation is performed as part of the conversion.
4878
4879(define_insn "fix_truncsfsi2"
4880  [(set (match_operand:SI 0 "register_operand" "=f")
4881	(fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4882  "! TARGET_SOFT_FLOAT"
4883  "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4884  [(set_attr "type" "fpalu")
4885   (set_attr "length" "4")])
4886
4887(define_insn "fix_truncdfsi2"
4888  [(set (match_operand:SI 0 "register_operand" "=f")
4889	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4890  "! TARGET_SOFT_FLOAT"
4891  "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4892  [(set_attr "type" "fpalu")
4893   (set_attr "length" "4")])
4894
4895(define_insn "fix_truncsfdi2"
4896  [(set (match_operand:DI 0 "register_operand" "=f")
4897	(fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4898  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4899  "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4900  [(set_attr "type" "fpalu")
4901   (set_attr "length" "4")])
4902
4903(define_insn "fix_truncdfdi2"
4904  [(set (match_operand:DI 0 "register_operand" "=f")
4905	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4906  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4907  "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4908  [(set_attr "type" "fpalu")
4909   (set_attr "length" "4")])
4910
4911(define_insn "floatunssidf2_pa20"
4912  [(set (match_operand:DF 0 "register_operand" "=f")
4913	(unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4914  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4915  "fcnv,uw,dbl %1,%0"
4916  [(set_attr "type" "fpalu")
4917   (set_attr "length" "4")])
4918
4919(define_insn "floatunssisf2_pa20"
4920  [(set (match_operand:SF 0 "register_operand" "=f")
4921	(unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4922  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4923  "fcnv,uw,sgl %1,%0"
4924  [(set_attr "type" "fpalu")
4925   (set_attr "length" "4")])
4926
4927(define_insn "floatunsdisf2"
4928  [(set (match_operand:SF 0 "register_operand" "=f")
4929	(unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4930  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4931  "fcnv,udw,sgl %1,%0"
4932  [(set_attr "type" "fpalu")
4933   (set_attr "length" "4")])
4934
4935(define_insn "floatunsdidf2"
4936  [(set (match_operand:DF 0 "register_operand" "=f")
4937	(unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4938  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4939  "fcnv,udw,dbl %1,%0"
4940  [(set_attr "type" "fpalu")
4941   (set_attr "length" "4")])
4942
4943(define_insn "fixuns_truncsfsi2"
4944  [(set (match_operand:SI 0 "register_operand" "=f")
4945	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4946  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4947  "fcnv,t,sgl,uw %1,%0"
4948  [(set_attr "type" "fpalu")
4949   (set_attr "length" "4")])
4950
4951(define_insn "fixuns_truncdfsi2"
4952  [(set (match_operand:SI 0 "register_operand" "=f")
4953	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4954  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4955  "fcnv,t,dbl,uw %1,%0"
4956  [(set_attr "type" "fpalu")
4957   (set_attr "length" "4")])
4958
4959(define_insn "fixuns_truncsfdi2"
4960  [(set (match_operand:DI 0 "register_operand" "=f")
4961	(unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4962  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4963  "fcnv,t,sgl,udw %1,%0"
4964  [(set_attr "type" "fpalu")
4965   (set_attr "length" "4")])
4966
4967(define_insn "fixuns_truncdfdi2"
4968  [(set (match_operand:DI 0 "register_operand" "=f")
4969	(unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4970  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4971  "fcnv,t,dbl,udw %1,%0"
4972  [(set_attr "type" "fpalu")
4973   (set_attr "length" "4")])
4974
4975;;- arithmetic instructions
4976
4977(define_expand "adddi3"
4978  [(set (match_operand:DI 0 "register_operand" "")
4979	(plus:DI (match_operand:DI 1 "register_operand" "")
4980		 (match_operand:DI 2 "adddi3_operand" "")))]
4981  ""
4982  "")
4983
4984(define_insn ""
4985  [(set (match_operand:DI 0 "register_operand" "=r")
4986	(plus:DI (match_operand:DI 1 "register_operand" "%r")
4987		 (match_operand:DI 2 "arith11_operand" "rI")))]
4988  "!TARGET_64BIT"
4989  "*
4990{
4991  if (GET_CODE (operands[2]) == CONST_INT)
4992    {
4993      if (INTVAL (operands[2]) >= 0)
4994	return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
4995      else
4996	return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
4997    }
4998  else
4999    return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5000}"
5001  [(set_attr "type" "binary")
5002   (set_attr "length" "8")])
5003
5004(define_insn ""
5005  [(set (match_operand:DI 0 "register_operand" "=r,r")
5006	(plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5007		 (match_operand:DI 2 "arith14_operand" "r,J")))]
5008  "TARGET_64BIT"
5009  "@
5010   add,l %1,%2,%0
5011   ldo %2(%1),%0"
5012  [(set_attr "type" "binary,binary")
5013   (set_attr "pa_combine_type" "addmove")
5014   (set_attr "length" "4,4")])
5015
5016(define_insn ""
5017  [(set (match_operand:DI 0 "register_operand" "=r")
5018	(plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5019		 (match_operand:DI 2 "register_operand" "r")))]
5020  "TARGET_64BIT"
5021  "uaddcm %2,%1,%0"
5022  [(set_attr "type" "binary")
5023   (set_attr "length" "4")])
5024
5025(define_insn ""
5026  [(set (match_operand:SI 0 "register_operand" "=r")
5027	(plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5028		 (match_operand:SI 2 "register_operand" "r")))]
5029  ""
5030  "uaddcm %2,%1,%0"
5031  [(set_attr "type" "binary")
5032   (set_attr "length" "4")])
5033
5034(define_expand "addvdi3"
5035  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5036		   (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5037			    (match_operand:DI 2 "arith11_operand" "")))
5038	      (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5039				    (sign_extend:TI (match_dup 2)))
5040			   (sign_extend:TI (plus:DI (match_dup 1)
5041						    (match_dup 2))))
5042		       (const_int 0))])]
5043  ""
5044  "")
5045
5046(define_insn ""
5047  [(set (match_operand:DI 0 "register_operand" "=r,r")
5048	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
5049		 (match_operand:DI 2 "arith11_operand" "r,I")))
5050   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5051			 (sign_extend:TI (match_dup 2)))
5052		(sign_extend:TI (plus:DI (match_dup 1)
5053					 (match_dup 2))))
5054	    (const_int 0))]
5055  "TARGET_64BIT"
5056  "@
5057  add,tsv,* %2,%1,%0
5058  addi,tsv,* %2,%1,%0"
5059  [(set_attr "type" "binary,binary")
5060   (set_attr "length" "4,4")])
5061
5062(define_insn ""
5063  [(set (match_operand:DI 0 "register_operand" "=r")
5064	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5065		 (match_operand:DI 2 "arith11_operand" "rI")))
5066   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5067			 (sign_extend:TI (match_dup 2)))
5068		(sign_extend:TI (plus:DI (match_dup 1)
5069					 (match_dup 2))))
5070	    (const_int 0))]
5071  "!TARGET_64BIT"
5072  "*
5073{
5074  if (GET_CODE (operands[2]) == CONST_INT)
5075    {
5076      if (INTVAL (operands[2]) >= 0)
5077	return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5078      else
5079	return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5080    }
5081  else
5082    return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5083}"
5084  [(set_attr "type" "binary")
5085   (set_attr "length" "8")])
5086
5087;; define_splits to optimize cases of adding a constant integer
5088;; to a register when the constant does not fit in 14 bits.  */
5089(define_split
5090  [(set (match_operand:SI 0 "register_operand" "")
5091	(plus:SI (match_operand:SI 1 "register_operand" "")
5092		 (match_operand:SI 2 "const_int_operand" "")))
5093   (clobber (match_operand:SI 4 "register_operand" ""))]
5094  "! pa_cint_ok_for_move (INTVAL (operands[2]))
5095   && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5096  [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5097   (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5098  "
5099{
5100  int val = INTVAL (operands[2]);
5101  int low = (val < 0) ? -0x2000 : 0x1fff;
5102  int rest = val - low;
5103
5104  operands[2] = GEN_INT (rest);
5105  operands[3] = GEN_INT (low);
5106}")
5107
5108(define_split
5109  [(set (match_operand:SI 0 "register_operand" "")
5110	(plus:SI (match_operand:SI 1 "register_operand" "")
5111		 (match_operand:SI 2 "const_int_operand" "")))
5112   (clobber (match_operand:SI 4 "register_operand" ""))]
5113  "! pa_cint_ok_for_move (INTVAL (operands[2]))"
5114  [(set (match_dup 4) (match_dup 2))
5115   (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
5116			       (match_dup 1)))]
5117  "
5118{
5119  HOST_WIDE_INT intval = INTVAL (operands[2]);
5120
5121  /* Try dividing the constant by 2, then 4, and finally 8 to see
5122     if we can get a constant which can be loaded into a register
5123     in a single instruction (pa_cint_ok_for_move).
5124
5125     If that fails, try to negate the constant and subtract it
5126     from our input operand.  */
5127  if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5128    {
5129      operands[2] = GEN_INT (intval / 2);
5130      operands[3] = const2_rtx;
5131    }
5132  else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5133    {
5134      operands[2] = GEN_INT (intval / 4);
5135      operands[3] = GEN_INT (4);
5136    }
5137  else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5138    {
5139      operands[2] = GEN_INT (intval / 8);
5140      operands[3] = GEN_INT (8);
5141    }
5142  else if (pa_cint_ok_for_move (-intval))
5143    {
5144      emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
5145      emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5146      DONE;
5147    }
5148  else
5149    FAIL;
5150}")
5151
5152(define_insn "addsi3"
5153  [(set (match_operand:SI 0 "register_operand" "=r,r")
5154	(plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5155		 (match_operand:SI 2 "arith14_operand" "r,J")))]
5156  ""
5157  "@
5158   {addl|add,l} %1,%2,%0
5159   ldo %2(%1),%0"
5160  [(set_attr "type" "binary,binary")
5161   (set_attr "pa_combine_type" "addmove")
5162   (set_attr "length" "4,4")])
5163
5164(define_insn "addvsi3"
5165  [(set (match_operand:SI 0 "register_operand" "=r,r")
5166	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5167		 (match_operand:SI 2 "arith11_operand" "r,I")))
5168   (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5169			 (sign_extend:DI (match_dup 2)))
5170		(sign_extend:DI (plus:SI (match_dup 1)
5171					 (match_dup 2))))
5172	    (const_int 0))]
5173  ""
5174  "@
5175  {addo|add,tsv} %2,%1,%0
5176  {addio|addi,tsv} %2,%1,%0"
5177  [(set_attr "type" "binary,binary")
5178   (set_attr "length" "4,4")])
5179
5180(define_expand "subdi3"
5181  [(set (match_operand:DI 0 "register_operand" "")
5182	(minus:DI (match_operand:DI 1 "arith11_operand" "")
5183		  (match_operand:DI 2 "reg_or_0_operand" "")))]
5184  ""
5185  "")
5186
5187(define_insn ""
5188  [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5189	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5190		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5191  "TARGET_64BIT"
5192  "@
5193   sub %1,%2,%0
5194   subi %1,%2,%0
5195   mtsarcm %2"
5196  [(set_attr "type" "binary,binary,move")
5197  (set_attr "length" "4,4,4")])
5198
5199(define_insn ""
5200  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5201	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5202		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5203  "!TARGET_64BIT"
5204  "*
5205{
5206  if (GET_CODE (operands[1]) == CONST_INT)
5207    {
5208      if (INTVAL (operands[1]) >= 0)
5209	return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5210      else
5211	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5212    }
5213  else
5214    return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5215}"
5216  [(set_attr "type" "binary")
5217   (set (attr "length")
5218	(if_then_else (eq_attr "alternative" "0")
5219	  (const_int 8)
5220	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5221			    (const_int 0))
5222	    (const_int 8)
5223	    (const_int 12))))])
5224
5225(define_expand "subvdi3"
5226  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5227		   (minus:DI (match_operand:DI 1 "arith11_operand" "")
5228			     (match_operand:DI 2 "reg_or_0_operand" "")))
5229	      (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5230				     (sign_extend:TI (match_dup 2)))
5231			   (sign_extend:TI (minus:DI (match_dup 1)
5232						     (match_dup 2))))
5233		       (const_int 0))])]
5234  ""
5235  "")
5236
5237(define_insn ""
5238  [(set (match_operand:DI 0 "register_operand" "=r,r")
5239	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5240		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5241   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5242			  (sign_extend:TI (match_dup 2)))
5243		(sign_extend:TI (minus:DI (match_dup 1)
5244					  (match_dup 2))))
5245	    (const_int 0))]
5246  "TARGET_64BIT"
5247  "@
5248  {subo|sub,tsv} %1,%2,%0
5249  {subio|subi,tsv} %1,%2,%0"
5250  [(set_attr "type" "binary,binary")
5251   (set_attr "length" "4,4")])
5252
5253(define_insn ""
5254  [(set (match_operand:DI 0 "register_operand" "=r,&r")
5255	(minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5256		  (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5257   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5258			  (sign_extend:TI (match_dup 2)))
5259		(sign_extend:TI (minus:DI (match_dup 1)
5260					  (match_dup 2))))
5261	    (const_int 0))]
5262  "!TARGET_64BIT"
5263  "*
5264{
5265  if (GET_CODE (operands[1]) == CONST_INT)
5266    {
5267      if (INTVAL (operands[1]) >= 0)
5268	return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5269      else
5270	return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5271    }
5272  else
5273    return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5274}"
5275  [(set_attr "type" "binary,binary")
5276   (set (attr "length")
5277	(if_then_else (eq_attr "alternative" "0")
5278	  (const_int 8)
5279	  (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5280			    (const_int 0))
5281	    (const_int 8)
5282	    (const_int 12))))])
5283
5284(define_expand "subsi3"
5285  [(set (match_operand:SI 0 "register_operand" "")
5286	(minus:SI (match_operand:SI 1 "arith11_operand" "")
5287		  (match_operand:SI 2 "register_operand" "")))]
5288  ""
5289  "")
5290
5291(define_insn ""
5292  [(set (match_operand:SI 0 "register_operand" "=r,r")
5293	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5294		  (match_operand:SI 2 "register_operand" "r,r")))]
5295  "!TARGET_PA_20"
5296  "@
5297   sub %1,%2,%0
5298   subi %1,%2,%0"
5299  [(set_attr "type" "binary,binary")
5300   (set_attr "length" "4,4")])
5301
5302(define_insn ""
5303  [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5304	(minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5305		  (match_operand:SI 2 "register_operand" "r,r,!r")))]
5306  "TARGET_PA_20"
5307  "@
5308   sub %1,%2,%0
5309   subi %1,%2,%0
5310   mtsarcm %2"
5311  [(set_attr "type" "binary,binary,move")
5312   (set_attr "length" "4,4,4")])
5313
5314(define_insn "subvsi3"
5315  [(set (match_operand:SI 0 "register_operand" "=r,r")
5316	(minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5317		  (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5318   (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5319			  (sign_extend:DI (match_dup 2)))
5320		(sign_extend:DI (minus:SI (match_dup 1)
5321					  (match_dup 2))))
5322	    (const_int 0))]
5323  ""
5324  "@
5325  {subo|sub,tsv} %1,%2,%0
5326  {subio|subi,tsv} %1,%2,%0"
5327  [(set_attr "type" "binary,binary")
5328   (set_attr "length" "4,4")])
5329
5330;; Trap instructions.
5331
5332(define_insn "trap"
5333  [(trap_if (const_int 1) (const_int 0))]
5334  ""
5335  "{addit|addi,tc},<> 1,%%r0,%%r0"
5336  [(set_attr "type" "trap")
5337   (set_attr "length" "4")])
5338
5339;; Clobbering a "register_operand" instead of a match_scratch
5340;; in operand3 of millicode calls avoids spilling %r1 and
5341;; produces better code.
5342
5343;; The mulsi3 insns set up registers for the millicode call.
5344(define_expand "mulsi3"
5345  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5346   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5347   (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5348	      (clobber (match_dup 3))
5349	      (clobber (reg:SI 26))
5350	      (clobber (reg:SI 25))
5351	      (clobber (match_dup 4))])
5352   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5353  ""
5354  "
5355{
5356  operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5357  if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5358    {
5359      rtx scratch = gen_reg_rtx (DImode);
5360      operands[1] = force_reg (SImode, operands[1]);
5361      operands[2] = force_reg (SImode, operands[2]);
5362      emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5363      emit_insn (gen_movsi (operands[0],
5364			    gen_rtx_SUBREG (SImode, scratch,
5365					    GET_MODE_SIZE (SImode))));
5366      DONE;
5367    }
5368  operands[3] = gen_reg_rtx (SImode);
5369}")
5370
5371(define_insn "umulsidi3"
5372  [(set (match_operand:DI 0 "register_operand" "=f")
5373	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5374		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
5375  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5376  "xmpyu %1,%2,%0"
5377  [(set_attr "type" "fpmuldbl")
5378   (set_attr "length" "4")])
5379
5380(define_insn ""
5381  [(set (match_operand:DI 0 "register_operand" "=f")
5382	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5383		 (match_operand:DI 2 "uint32_operand" "f")))]
5384  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5385  "xmpyu %1,%R2,%0"
5386  [(set_attr "type" "fpmuldbl")
5387   (set_attr "length" "4")])
5388
5389(define_insn ""
5390  [(set (match_operand:DI 0 "register_operand" "=f")
5391	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5392		 (match_operand:DI 2 "uint32_operand" "f")))]
5393  "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5394  "xmpyu %1,%2R,%0"
5395  [(set_attr "type" "fpmuldbl")
5396   (set_attr "length" "4")])
5397
5398(define_insn ""
5399  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5400   (clobber (match_operand:SI 0 "register_operand" "=a"))
5401   (clobber (reg:SI 26))
5402   (clobber (reg:SI 25))
5403   (clobber (reg:SI 31))]
5404  "!TARGET_64BIT"
5405  "* return pa_output_mul_insn (0, insn);"
5406  [(set_attr "type" "milli")
5407   (set (attr "length")
5408	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5409	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5410
5411(define_insn ""
5412  [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5413   (clobber (match_operand:SI 0 "register_operand" "=a"))
5414   (clobber (reg:SI 26))
5415   (clobber (reg:SI 25))
5416   (clobber (reg:SI 2))]
5417  "TARGET_64BIT"
5418  "* return pa_output_mul_insn (0, insn);"
5419  [(set_attr "type" "milli")
5420   (set (attr "length")
5421	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5422	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5423
5424(define_expand "muldi3"
5425  [(set (match_operand:DI 0 "register_operand" "")
5426        (mult:DI (match_operand:DI 1 "register_operand" "")
5427		 (match_operand:DI 2 "register_operand" "")))]
5428  "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5429  "
5430{
5431  rtx low_product = gen_reg_rtx (DImode);
5432  rtx cross_product1 = gen_reg_rtx (DImode);
5433  rtx cross_product2 = gen_reg_rtx (DImode);
5434  rtx cross_scratch = gen_reg_rtx (DImode);
5435  rtx cross_product = gen_reg_rtx (DImode);
5436  rtx op1l, op1r, op2l, op2r;
5437  rtx op1shifted, op2shifted;
5438
5439  op1shifted = gen_reg_rtx (DImode);
5440  op2shifted = gen_reg_rtx (DImode);
5441  op1l = gen_reg_rtx (SImode);
5442  op1r = gen_reg_rtx (SImode);
5443  op2l = gen_reg_rtx (SImode);
5444  op2r = gen_reg_rtx (SImode);
5445
5446  emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5447						GEN_INT (32)));
5448  emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5449						GEN_INT (32)));
5450  op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5451  op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5452  op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5453  op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5454
5455  /* Emit multiplies for the cross products.  */
5456  emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5457  emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5458
5459  /* Emit a multiply for the low sub-word.  */
5460  emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5461
5462  /* Sum the cross products and shift them into proper position.  */
5463  emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5464  emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5465
5466  /* Add the cross product to the low product and store the result
5467     into the output operand .  */
5468  emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5469  DONE;
5470}")
5471
5472;;; Division and mod.
5473(define_expand "divsi3"
5474  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5475   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5476   (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5477	      (clobber (match_dup 3))
5478	      (clobber (match_dup 4))
5479	      (clobber (reg:SI 26))
5480	      (clobber (reg:SI 25))
5481	      (clobber (match_dup 5))])
5482   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5483  ""
5484  "
5485{
5486  operands[3] = gen_reg_rtx (SImode);
5487  if (TARGET_64BIT)
5488    {
5489      operands[5] = gen_rtx_REG (SImode, 2);
5490      operands[4] = operands[5];
5491    }
5492  else
5493    {
5494      operands[5] = gen_rtx_REG (SImode, 31);
5495      operands[4] = gen_reg_rtx (SImode);
5496    }
5497  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5498    DONE;
5499}")
5500
5501(define_insn ""
5502  [(set (reg:SI 29)
5503	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5504   (clobber (match_operand:SI 1 "register_operand" "=a"))
5505   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5506   (clobber (reg:SI 26))
5507   (clobber (reg:SI 25))
5508   (clobber (reg:SI 31))]
5509  "!TARGET_64BIT"
5510  "*
5511   return pa_output_div_insn (operands, 0, insn);"
5512  [(set_attr "type" "milli")
5513   (set (attr "length")
5514	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5515	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5516
5517(define_insn ""
5518  [(set (reg:SI 29)
5519	(div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5520   (clobber (match_operand:SI 1 "register_operand" "=a"))
5521   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5522   (clobber (reg:SI 26))
5523   (clobber (reg:SI 25))
5524   (clobber (reg:SI 2))]
5525  "TARGET_64BIT"
5526  "*
5527   return pa_output_div_insn (operands, 0, insn);"
5528  [(set_attr "type" "milli")
5529   (set (attr "length")
5530	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5531	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5532
5533(define_expand "udivsi3"
5534  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5535   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5536   (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5537	      (clobber (match_dup 3))
5538	      (clobber (match_dup 4))
5539	      (clobber (reg:SI 26))
5540	      (clobber (reg:SI 25))
5541	      (clobber (match_dup 5))])
5542   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5543  ""
5544  "
5545{
5546  operands[3] = gen_reg_rtx (SImode);
5547
5548  if (TARGET_64BIT)
5549    {
5550      operands[5] = gen_rtx_REG (SImode, 2);
5551      operands[4] = operands[5];
5552    }
5553  else
5554    {
5555      operands[5] = gen_rtx_REG (SImode, 31);
5556      operands[4] = gen_reg_rtx (SImode);
5557    }
5558  if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5559    DONE;
5560}")
5561
5562(define_insn ""
5563  [(set (reg:SI 29)
5564	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5565   (clobber (match_operand:SI 1 "register_operand" "=a"))
5566   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5567   (clobber (reg:SI 26))
5568   (clobber (reg:SI 25))
5569   (clobber (reg:SI 31))]
5570  "!TARGET_64BIT"
5571  "*
5572   return pa_output_div_insn (operands, 1, insn);"
5573  [(set_attr "type" "milli")
5574   (set (attr "length")
5575	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5576	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5577
5578(define_insn ""
5579  [(set (reg:SI 29)
5580	(udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5581   (clobber (match_operand:SI 1 "register_operand" "=a"))
5582   (clobber (match_operand:SI 2 "register_operand" "=&r"))
5583   (clobber (reg:SI 26))
5584   (clobber (reg:SI 25))
5585   (clobber (reg:SI 2))]
5586  "TARGET_64BIT"
5587  "*
5588   return pa_output_div_insn (operands, 1, insn);"
5589  [(set_attr "type" "milli")
5590   (set (attr "length")
5591	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5592	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5593
5594(define_expand "modsi3"
5595  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5596   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5597   (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5598	      (clobber (match_dup 3))
5599	      (clobber (match_dup 4))
5600	      (clobber (reg:SI 26))
5601	      (clobber (reg:SI 25))
5602	      (clobber (match_dup 5))])
5603   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5604  ""
5605  "
5606{
5607  if (TARGET_64BIT)
5608    {
5609      operands[5] = gen_rtx_REG (SImode, 2);
5610      operands[4] = operands[5];
5611    }
5612  else
5613    {
5614      operands[5] = gen_rtx_REG (SImode, 31);
5615      operands[4] = gen_reg_rtx (SImode);
5616    }
5617  operands[3] = gen_reg_rtx (SImode);
5618}")
5619
5620(define_insn ""
5621  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5622   (clobber (match_operand:SI 0 "register_operand" "=a"))
5623   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5624   (clobber (reg:SI 26))
5625   (clobber (reg:SI 25))
5626   (clobber (reg:SI 31))]
5627  "!TARGET_64BIT"
5628  "*
5629  return pa_output_mod_insn (0, insn);"
5630  [(set_attr "type" "milli")
5631   (set (attr "length")
5632	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5633	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5634
5635(define_insn ""
5636  [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5637   (clobber (match_operand:SI 0 "register_operand" "=a"))
5638   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5639   (clobber (reg:SI 26))
5640   (clobber (reg:SI 25))
5641   (clobber (reg:SI 2))]
5642  "TARGET_64BIT"
5643  "*
5644  return pa_output_mod_insn (0, insn);"
5645  [(set_attr "type" "milli")
5646   (set (attr "length")
5647	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5648	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5649
5650(define_expand "umodsi3"
5651  [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5652   (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5653   (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5654	      (clobber (match_dup 3))
5655	      (clobber (match_dup 4))
5656	      (clobber (reg:SI 26))
5657	      (clobber (reg:SI 25))
5658	      (clobber (match_dup 5))])
5659   (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5660  ""
5661  "
5662{
5663  if (TARGET_64BIT)
5664    {
5665      operands[5] = gen_rtx_REG (SImode, 2);
5666      operands[4] = operands[5];
5667    }
5668  else
5669    {
5670      operands[5] = gen_rtx_REG (SImode, 31);
5671      operands[4] = gen_reg_rtx (SImode);
5672    }
5673  operands[3] = gen_reg_rtx (SImode);
5674}")
5675
5676(define_insn ""
5677  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5678   (clobber (match_operand:SI 0 "register_operand" "=a"))
5679   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5680   (clobber (reg:SI 26))
5681   (clobber (reg:SI 25))
5682   (clobber (reg:SI 31))]
5683  "!TARGET_64BIT"
5684  "*
5685  return pa_output_mod_insn (1, insn);"
5686  [(set_attr "type" "milli")
5687   (set (attr "length")
5688	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5689	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5690
5691(define_insn ""
5692  [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5693   (clobber (match_operand:SI 0 "register_operand" "=a"))
5694   (clobber (match_operand:SI 1 "register_operand" "=&r"))
5695   (clobber (reg:SI 26))
5696   (clobber (reg:SI 25))
5697   (clobber (reg:SI 2))]
5698  "TARGET_64BIT"
5699  "*
5700  return pa_output_mod_insn (1, insn);"
5701  [(set_attr "type" "milli")
5702   (set (attr "length")
5703	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5704	      (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5705
5706;;- and instructions
5707;; We define DImode `and` so with DImode `not` we can get
5708;; DImode `andn`.  Other combinations are possible.
5709
5710(define_expand "anddi3"
5711  [(set (match_operand:DI 0 "register_operand" "")
5712	(and:DI (match_operand:DI 1 "register_operand" "")
5713		(match_operand:DI 2 "and_operand" "")))]
5714  "TARGET_64BIT"
5715  "")
5716
5717(define_insn ""
5718  [(set (match_operand:DI 0 "register_operand" "=r,r")
5719	(and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5720		(match_operand:DI 2 "and_operand" "rO,P")))]
5721  "TARGET_64BIT"
5722  "* return pa_output_64bit_and (operands); "
5723  [(set_attr "type" "binary")
5724   (set_attr "length" "4")])
5725
5726; The ? for op1 makes reload prefer zdepi instead of loading a huge
5727; constant with ldil;ldo.
5728(define_insn "andsi3"
5729  [(set (match_operand:SI 0 "register_operand" "=r,r")
5730	(and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5731		(match_operand:SI 2 "and_operand" "rO,P")))]
5732  ""
5733  "* return pa_output_and (operands); "
5734  [(set_attr "type" "binary,shift")
5735   (set_attr "length" "4,4")])
5736
5737(define_insn ""
5738  [(set (match_operand:DI 0 "register_operand" "=r")
5739	(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5740		(match_operand:DI 2 "register_operand" "r")))]
5741  "TARGET_64BIT"
5742  "andcm %2,%1,%0"
5743  [(set_attr "type" "binary")
5744   (set_attr "length" "4")])
5745
5746(define_insn ""
5747  [(set (match_operand:SI 0 "register_operand" "=r")
5748	(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5749		(match_operand:SI 2 "register_operand" "r")))]
5750  ""
5751  "andcm %2,%1,%0"
5752  [(set_attr "type" "binary")
5753  (set_attr "length" "4")])
5754
5755(define_expand "iordi3"
5756  [(set (match_operand:DI 0 "register_operand" "")
5757	(ior:DI (match_operand:DI 1 "register_operand" "")
5758		(match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5759  "TARGET_64BIT"
5760  "")
5761
5762(define_insn ""
5763  [(set (match_operand:DI 0 "register_operand" "=r,r")
5764	(ior:DI (match_operand:DI 1 "register_operand" "0,0")
5765		(match_operand:DI 2 "cint_ior_operand" "M,i")))]
5766  "TARGET_64BIT"
5767  "* return pa_output_64bit_ior (operands); "
5768  [(set_attr "type" "binary,shift")
5769   (set_attr "length" "4,4")])
5770
5771(define_insn ""
5772  [(set (match_operand:DI 0 "register_operand" "=r")
5773	(ior:DI (match_operand:DI 1 "register_operand" "%r")
5774		(match_operand:DI 2 "register_operand" "r")))]
5775  "TARGET_64BIT"
5776  "or %1,%2,%0"
5777  [(set_attr "type" "binary")
5778   (set_attr "length" "4")])
5779
5780;; Need a define_expand because we've run out of CONST_OK... characters.
5781(define_expand "iorsi3"
5782  [(set (match_operand:SI 0 "register_operand" "")
5783	(ior:SI (match_operand:SI 1 "register_operand" "")
5784		(match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5785  ""
5786  "")
5787
5788(define_insn ""
5789  [(set (match_operand:SI 0 "register_operand" "=r,r")
5790	(ior:SI (match_operand:SI 1 "register_operand" "0,0")
5791		(match_operand:SI 2 "cint_ior_operand" "M,i")))]
5792  ""
5793  "* return pa_output_ior (operands); "
5794  [(set_attr "type" "binary,shift")
5795   (set_attr "length" "4,4")])
5796
5797(define_insn ""
5798  [(set (match_operand:SI 0 "register_operand" "=r")
5799	(ior:SI (match_operand:SI 1 "register_operand" "%r")
5800		(match_operand:SI 2 "register_operand" "r")))]
5801  ""
5802  "or %1,%2,%0"
5803  [(set_attr "type" "binary")
5804   (set_attr "length" "4")])
5805
5806(define_expand "xordi3"
5807  [(set (match_operand:DI 0 "register_operand" "")
5808	(xor:DI (match_operand:DI 1 "register_operand" "")
5809		(match_operand:DI 2 "register_operand" "")))]
5810  "TARGET_64BIT"
5811  "")
5812
5813(define_insn ""
5814  [(set (match_operand:DI 0 "register_operand" "=r")
5815	(xor:DI (match_operand:DI 1 "register_operand" "%r")
5816		(match_operand:DI 2 "register_operand" "r")))]
5817  "TARGET_64BIT"
5818  "xor %1,%2,%0"
5819  [(set_attr "type" "binary")
5820   (set_attr "length" "4")])
5821
5822(define_insn "xorsi3"
5823  [(set (match_operand:SI 0 "register_operand" "=r")
5824	(xor:SI (match_operand:SI 1 "register_operand" "%r")
5825		(match_operand:SI 2 "register_operand" "r")))]
5826  ""
5827  "xor %1,%2,%0"
5828  [(set_attr "type" "binary")
5829   (set_attr "length" "4")])
5830
5831(define_expand "negdi2"
5832  [(set (match_operand:DI 0 "register_operand" "")
5833	(neg:DI (match_operand:DI 1 "register_operand" "")))]
5834  ""
5835  "")
5836
5837(define_insn ""
5838  [(set (match_operand:DI 0 "register_operand" "=r")
5839	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5840  "!TARGET_64BIT"
5841  "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5842  [(set_attr "type" "unary")
5843   (set_attr "length" "8")])
5844
5845(define_insn ""
5846  [(set (match_operand:DI 0 "register_operand" "=r")
5847	(neg:DI (match_operand:DI 1 "register_operand" "r")))]
5848  "TARGET_64BIT"
5849  "sub %%r0,%1,%0"
5850  [(set_attr "type" "unary")
5851   (set_attr "length" "4")])
5852
5853(define_expand "negvdi2"
5854  [(parallel [(set (match_operand:DI 0 "register_operand" "")
5855		   (neg:DI (match_operand:DI 1 "register_operand" "")))
5856	      (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5857				   (sign_extend:TI (neg:DI (match_dup 1))))
5858		       (const_int 0))])]
5859  ""
5860  "")
5861
5862(define_insn ""
5863  [(set (match_operand:DI 0 "register_operand" "=r")
5864	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5865   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5866		(sign_extend:TI (neg:DI (match_dup 1))))
5867	    (const_int 0))]
5868  "!TARGET_64BIT"
5869  "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5870  [(set_attr "type" "unary")
5871   (set_attr "length" "8")])
5872
5873(define_insn ""
5874  [(set (match_operand:DI 0 "register_operand" "=r")
5875	(neg:DI (match_operand:DI 1 "register_operand" "r")))
5876   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5877		(sign_extend:TI (neg:DI (match_dup 1))))
5878	    (const_int 0))]
5879  "TARGET_64BIT"
5880  "sub,tsv %%r0,%1,%0"
5881  [(set_attr "type" "unary")
5882   (set_attr "length" "4")])
5883
5884(define_insn "negsi2"
5885  [(set (match_operand:SI 0 "register_operand" "=r")
5886	(neg:SI (match_operand:SI 1 "register_operand" "r")))]
5887  ""
5888  "sub %%r0,%1,%0"
5889  [(set_attr "type" "unary")
5890   (set_attr "length" "4")])
5891
5892(define_insn "negvsi2"
5893  [(set (match_operand:SI 0 "register_operand" "=r")
5894        (neg:SI (match_operand:SI 1 "register_operand" "r")))
5895   (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
5896		(sign_extend:DI (neg:SI (match_dup 1))))
5897	    (const_int 0))]
5898   ""
5899   "{subo|sub,tsv} %%r0,%1,%0"
5900  [(set_attr "type" "unary")
5901   (set_attr "length" "4")])
5902
5903(define_expand "one_cmpldi2"
5904  [(set (match_operand:DI 0 "register_operand" "")
5905	(not:DI (match_operand:DI 1 "register_operand" "")))]
5906  ""
5907  "
5908{
5909}")
5910
5911(define_insn ""
5912  [(set (match_operand:DI 0 "register_operand" "=r")
5913	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5914  "!TARGET_64BIT"
5915  "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5916  [(set_attr "type" "unary")
5917   (set_attr "length" "8")])
5918
5919(define_insn ""
5920  [(set (match_operand:DI 0 "register_operand" "=r")
5921	(not:DI (match_operand:DI 1 "register_operand" "r")))]
5922  "TARGET_64BIT"
5923  "uaddcm %%r0,%1,%0"
5924  [(set_attr "type" "unary")
5925   (set_attr "length" "4")])
5926
5927(define_insn "one_cmplsi2"
5928  [(set (match_operand:SI 0 "register_operand" "=r")
5929	(not:SI (match_operand:SI 1 "register_operand" "r")))]
5930  ""
5931  "uaddcm %%r0,%1,%0"
5932  [(set_attr "type" "unary")
5933   (set_attr "length" "4")])
5934
5935;; Floating point arithmetic instructions.
5936
5937(define_insn "adddf3"
5938  [(set (match_operand:DF 0 "register_operand" "=f")
5939	(plus:DF (match_operand:DF 1 "register_operand" "f")
5940		 (match_operand:DF 2 "register_operand" "f")))]
5941  "! TARGET_SOFT_FLOAT"
5942  "fadd,dbl %1,%2,%0"
5943  [(set_attr "type" "fpalu")
5944   (set_attr "pa_combine_type" "faddsub")
5945   (set_attr "length" "4")])
5946
5947(define_insn "addsf3"
5948  [(set (match_operand:SF 0 "register_operand" "=f")
5949	(plus:SF (match_operand:SF 1 "register_operand" "f")
5950		 (match_operand:SF 2 "register_operand" "f")))]
5951  "! TARGET_SOFT_FLOAT"
5952  "fadd,sgl %1,%2,%0"
5953  [(set_attr "type" "fpalu")
5954   (set_attr "pa_combine_type" "faddsub")
5955   (set_attr "length" "4")])
5956
5957(define_insn "subdf3"
5958  [(set (match_operand:DF 0 "register_operand" "=f")
5959	(minus:DF (match_operand:DF 1 "register_operand" "f")
5960		  (match_operand:DF 2 "register_operand" "f")))]
5961  "! TARGET_SOFT_FLOAT"
5962  "fsub,dbl %1,%2,%0"
5963  [(set_attr "type" "fpalu")
5964   (set_attr "pa_combine_type" "faddsub")
5965   (set_attr "length" "4")])
5966
5967(define_insn "subsf3"
5968  [(set (match_operand:SF 0 "register_operand" "=f")
5969	(minus:SF (match_operand:SF 1 "register_operand" "f")
5970		  (match_operand:SF 2 "register_operand" "f")))]
5971  "! TARGET_SOFT_FLOAT"
5972  "fsub,sgl %1,%2,%0"
5973  [(set_attr "type" "fpalu")
5974   (set_attr "pa_combine_type" "faddsub")
5975   (set_attr "length" "4")])
5976
5977(define_insn "muldf3"
5978  [(set (match_operand:DF 0 "register_operand" "=f")
5979	(mult:DF (match_operand:DF 1 "register_operand" "f")
5980		 (match_operand:DF 2 "register_operand" "f")))]
5981  "! TARGET_SOFT_FLOAT"
5982  "fmpy,dbl %1,%2,%0"
5983  [(set_attr "type" "fpmuldbl")
5984   (set_attr "pa_combine_type" "fmpy")
5985   (set_attr "length" "4")])
5986
5987(define_insn "mulsf3"
5988  [(set (match_operand:SF 0 "register_operand" "=f")
5989	(mult:SF (match_operand:SF 1 "register_operand" "f")
5990		 (match_operand:SF 2 "register_operand" "f")))]
5991  "! TARGET_SOFT_FLOAT"
5992  "fmpy,sgl %1,%2,%0"
5993  [(set_attr "type" "fpmulsgl")
5994   (set_attr "pa_combine_type" "fmpy")
5995   (set_attr "length" "4")])
5996
5997(define_insn "divdf3"
5998  [(set (match_operand:DF 0 "register_operand" "=f")
5999	(div:DF (match_operand:DF 1 "register_operand" "f")
6000		(match_operand:DF 2 "register_operand" "f")))]
6001  "! TARGET_SOFT_FLOAT"
6002  "fdiv,dbl %1,%2,%0"
6003  [(set_attr "type" "fpdivdbl")
6004   (set_attr "length" "4")])
6005
6006(define_insn "divsf3"
6007  [(set (match_operand:SF 0 "register_operand" "=f")
6008	(div:SF (match_operand:SF 1 "register_operand" "f")
6009		(match_operand:SF 2 "register_operand" "f")))]
6010  "! TARGET_SOFT_FLOAT"
6011  "fdiv,sgl %1,%2,%0"
6012  [(set_attr "type" "fpdivsgl")
6013   (set_attr "length" "4")])
6014
6015;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6016;; negation can be done by subtracting from plus zero.  However, this
6017;; violates the IEEE standard when negating plus and minus zero.
6018;; The slow path toggles the sign bit in the general registers.
6019(define_expand "negdf2"
6020  [(set (match_operand:DF 0 "register_operand" "")
6021	(neg:DF (match_operand:DF 1 "register_operand" "")))]
6022  "!TARGET_SOFT_FLOAT"
6023{
6024  if (TARGET_PA_20 || !flag_signed_zeros)
6025    emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6026  else
6027    emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6028  DONE;
6029})
6030
6031(define_insn "negdf2_slow"
6032  [(set (match_operand:DF 0 "register_operand" "=r")
6033	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
6034  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6035  "*
6036{
6037  if (rtx_equal_p (operands[0], operands[1]))
6038    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6039  else
6040    return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6041}"
6042  [(set_attr "type" "multi")
6043   (set (attr "length")
6044	(if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6045	    (const_int 12)
6046	    (const_int 16)))])
6047
6048(define_insn "negdf2_fast"
6049  [(set (match_operand:DF 0 "register_operand" "=f")
6050	(neg:DF (match_operand:DF 1 "register_operand" "f")))]
6051  "!TARGET_SOFT_FLOAT"
6052  "*
6053{
6054  if (TARGET_PA_20)
6055    return \"fneg,dbl %1,%0\";
6056  else
6057    return \"fsub,dbl %%fr0,%1,%0\";
6058}"
6059  [(set_attr "type" "fpalu")
6060   (set_attr "length" "4")])
6061
6062(define_expand "negsf2"
6063  [(set (match_operand:SF 0 "register_operand" "")
6064	(neg:SF (match_operand:SF 1 "register_operand" "")))]
6065  "!TARGET_SOFT_FLOAT"
6066{
6067  if (TARGET_PA_20 || !flag_signed_zeros)
6068    emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6069  else
6070    emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6071  DONE;
6072})
6073
6074(define_insn "negsf2_slow"
6075  [(set (match_operand:SF 0 "register_operand" "=r")
6076	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
6077  "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6078  "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6079  [(set_attr "type" "multi")
6080   (set_attr "length" "12")])
6081
6082(define_insn "negsf2_fast"
6083  [(set (match_operand:SF 0 "register_operand" "=f")
6084	(neg:SF (match_operand:SF 1 "register_operand" "f")))]
6085  "!TARGET_SOFT_FLOAT"
6086  "*
6087{
6088  if (TARGET_PA_20)
6089    return \"fneg,sgl %1,%0\";
6090  else
6091    return \"fsub,sgl %%fr0,%1,%0\";
6092}"
6093  [(set_attr "type" "fpalu")
6094   (set_attr "length" "4")])
6095
6096(define_insn "absdf2"
6097  [(set (match_operand:DF 0 "register_operand" "=f")
6098	(abs:DF (match_operand:DF 1 "register_operand" "f")))]
6099  "! TARGET_SOFT_FLOAT"
6100  "fabs,dbl %1,%0"
6101  [(set_attr "type" "fpalu")
6102   (set_attr "length" "4")])
6103
6104(define_insn "abssf2"
6105  [(set (match_operand:SF 0 "register_operand" "=f")
6106	(abs:SF (match_operand:SF 1 "register_operand" "f")))]
6107  "! TARGET_SOFT_FLOAT"
6108  "fabs,sgl %1,%0"
6109  [(set_attr "type" "fpalu")
6110   (set_attr "length" "4")])
6111
6112(define_insn "sqrtdf2"
6113  [(set (match_operand:DF 0 "register_operand" "=f")
6114	(sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6115  "! TARGET_SOFT_FLOAT"
6116  "fsqrt,dbl %1,%0"
6117  [(set_attr "type" "fpsqrtdbl")
6118   (set_attr "length" "4")])
6119
6120(define_insn "sqrtsf2"
6121  [(set (match_operand:SF 0 "register_operand" "=f")
6122	(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6123  "! TARGET_SOFT_FLOAT"
6124  "fsqrt,sgl %1,%0"
6125  [(set_attr "type" "fpsqrtsgl")
6126   (set_attr "length" "4")])
6127
6128;; PA 2.0 floating point instructions
6129
6130; fmpyfadd patterns
6131(define_insn "fmadf4"
6132  [(set (match_operand:DF 0 "register_operand" "=f")
6133	(fma:DF (match_operand:DF 1 "register_operand" "f")
6134		(match_operand:DF 2 "register_operand" "f")
6135		(match_operand:DF 3 "register_operand" "f")))]
6136  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6137  "fmpyfadd,dbl %1,%2,%3,%0"
6138  [(set_attr "type" "fpmuldbl")
6139   (set_attr "length" "4")])
6140
6141(define_insn "fmasf4"
6142  [(set (match_operand:SF 0 "register_operand" "=f")
6143	(fma:SF (match_operand:SF 1 "register_operand" "f")
6144		(match_operand:SF 2 "register_operand" "f")
6145		(match_operand:SF 3 "register_operand" "f")))]
6146  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6147  "fmpyfadd,sgl %1,%2,%3,%0"
6148  [(set_attr "type" "fpmulsgl")
6149   (set_attr "length" "4")])
6150
6151; fmpynfadd patterns
6152(define_insn "fnmadf4"
6153  [(set (match_operand:DF 0 "register_operand" "=f")
6154	(fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6155		(match_operand:DF 2 "register_operand" "f")
6156		(match_operand:DF 3 "register_operand" "f")))]
6157  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6158  "fmpynfadd,dbl %1,%2,%3,%0"
6159  [(set_attr "type" "fpmuldbl")
6160   (set_attr "length" "4")])
6161
6162(define_insn "fnmasf4"
6163  [(set (match_operand:SF 0 "register_operand" "=f")
6164	(fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6165		(match_operand:SF 2 "register_operand" "f")
6166		(match_operand:SF 3 "register_operand" "f")))]
6167  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6168  "fmpynfadd,sgl %1,%2,%3,%0"
6169  [(set_attr "type" "fpmulsgl")
6170   (set_attr "length" "4")])
6171
6172; fnegabs patterns
6173(define_insn ""
6174  [(set (match_operand:DF 0 "register_operand" "=f")
6175	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6176  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6177  "fnegabs,dbl %1,%0"
6178  [(set_attr "type" "fpalu")
6179   (set_attr "length" "4")])
6180
6181(define_insn ""
6182  [(set (match_operand:SF 0 "register_operand" "=f")
6183	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6184  "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6185  "fnegabs,sgl %1,%0"
6186  [(set_attr "type" "fpalu")
6187   (set_attr "length" "4")])
6188
6189(define_insn ""
6190  [(set (match_operand:DF 0 "register_operand" "=f")
6191	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6192   (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6193  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6194    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6195  "#"
6196  [(set_attr "type" "fpalu")
6197   (set_attr "length" "8")])
6198
6199(define_split
6200  [(set (match_operand:DF 0 "register_operand" "")
6201	(neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6202   (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6203  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6204  [(set (match_dup 2) (abs:DF (match_dup 1)))
6205   (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6206  "")
6207
6208(define_insn ""
6209  [(set (match_operand:SF 0 "register_operand" "=f")
6210	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6211   (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6212  "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6213    && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6214  "#"
6215  [(set_attr "type" "fpalu")
6216   (set_attr "length" "8")])
6217
6218(define_split
6219  [(set (match_operand:SF 0 "register_operand" "")
6220	(neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6221   (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6222  "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6223  [(set (match_dup 2) (abs:SF (match_dup 1)))
6224   (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6225  "")
6226
6227;; Negating a multiply can be faked by adding zero in a fused multiply-add
6228;; instruction if we can ignore the sign of zero.
6229(define_insn ""
6230  [(set (match_operand:DF 0 "register_operand" "=f")
6231	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6232			 (match_operand:DF 2 "register_operand" "f"))))]
6233  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6234  "fmpynfadd,dbl %1,%2,%%fr0,%0"
6235  [(set_attr "type" "fpmuldbl")
6236   (set_attr "length" "4")])
6237
6238(define_insn ""
6239  [(set (match_operand:SF 0 "register_operand" "=f")
6240	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6241			 (match_operand:SF 2 "register_operand" "f"))))]
6242  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6243  "fmpynfadd,sgl %1,%2,%%fr0,%0"
6244  [(set_attr "type" "fpmuldbl")
6245   (set_attr "length" "4")])
6246
6247(define_insn ""
6248  [(set (match_operand:DF 0 "register_operand" "=f")
6249	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6250			 (match_operand:DF 2 "register_operand" "f"))))
6251   (set (match_operand:DF 3 "register_operand" "=&f")
6252	(mult:DF (match_dup 1) (match_dup 2)))]
6253  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6254    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6255          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6256  "#"
6257  [(set_attr "type" "fpmuldbl")
6258   (set_attr "length" "8")])
6259
6260(define_split
6261  [(set (match_operand:DF 0 "register_operand" "")
6262	(neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6263			 (match_operand:DF 2 "register_operand" ""))))
6264   (set (match_operand:DF 3 "register_operand" "")
6265	(mult:DF (match_dup 1) (match_dup 2)))]
6266  "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6267  [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6268   (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6269  "")
6270
6271(define_insn ""
6272  [(set (match_operand:SF 0 "register_operand" "=f")
6273	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6274			 (match_operand:SF 2 "register_operand" "f"))))
6275   (set (match_operand:SF 3 "register_operand" "=&f")
6276	(mult:SF (match_dup 1) (match_dup 2)))]
6277  "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6278    && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6279          || reg_overlap_mentioned_p (operands[3], operands[2])))"
6280  "#"
6281  [(set_attr "type" "fpmuldbl")
6282   (set_attr "length" "8")])
6283
6284(define_split
6285  [(set (match_operand:SF 0 "register_operand" "")
6286	(neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6287			 (match_operand:SF 2 "register_operand" ""))))
6288   (set (match_operand:SF 3 "register_operand" "")
6289	(mult:SF (match_dup 1) (match_dup 2)))]
6290  "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6291  [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6292   (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6293  "")
6294
6295;;- Shift instructions
6296
6297;; Optimized special case of shifting.
6298
6299(define_insn ""
6300  [(set (match_operand:SI 0 "register_operand" "=r")
6301	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6302		     (const_int 24)))]
6303  ""
6304  "ldb%M1 %1,%0"
6305  [(set_attr "type" "load")
6306   (set_attr "length" "4")])
6307
6308(define_insn ""
6309  [(set (match_operand:SI 0 "register_operand" "=r")
6310	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6311		     (const_int 16)))]
6312  ""
6313  "ldh%M1 %1,%0"
6314  [(set_attr "type" "load")
6315   (set_attr "length" "4")])
6316
6317(define_insn ""
6318  [(set (match_operand:SI 0 "register_operand" "=r")
6319	(plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6320			  (match_operand:SI 3 "shadd_operand" ""))
6321		 (match_operand:SI 1 "register_operand" "r")))]
6322  ""
6323  "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
6324  [(set_attr "type" "binary")
6325   (set_attr "length" "4")])
6326
6327(define_insn ""
6328  [(set (match_operand:DI 0 "register_operand" "=r")
6329	(plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6330			  (match_operand:DI 3 "shadd_operand" ""))
6331		 (match_operand:DI 1 "register_operand" "r")))]
6332  "TARGET_64BIT"
6333  "shladd,l %2,%O3,%1,%0"
6334  [(set_attr "type" "binary")
6335   (set_attr "length" "4")])
6336
6337(define_expand "ashlsi3"
6338  [(set (match_operand:SI 0 "register_operand" "")
6339	(ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6340		   (match_operand:SI 2 "arith32_operand" "")))]
6341  ""
6342  "
6343{
6344  if (GET_CODE (operands[2]) != CONST_INT)
6345    {
6346      rtx temp = gen_reg_rtx (SImode);
6347      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6348      if (GET_CODE (operands[1]) == CONST_INT)
6349	emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6350      else
6351	emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6352      DONE;
6353    }
6354  /* Make sure both inputs are not constants,
6355     there are no patterns for that.  */
6356  operands[1] = force_reg (SImode, operands[1]);
6357}")
6358
6359(define_insn ""
6360  [(set (match_operand:SI 0 "register_operand" "=r")
6361	(ashift:SI (match_operand:SI 1 "register_operand" "r")
6362		   (match_operand:SI 2 "const_int_operand" "n")))]
6363  ""
6364  "{zdep|depw,z} %1,%P2,%L2,%0"
6365  [(set_attr "type" "shift")
6366   (set_attr "length" "4")])
6367
6368; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6369; Doing it like this makes slightly better code since reload can
6370; replace a register with a known value in range -16..15 with a
6371; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6372; but since we have no more CONST_OK... characters, that is not
6373; possible.
6374(define_insn "zvdep32"
6375  [(set (match_operand:SI 0 "register_operand" "=r,r")
6376	(ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6377		   (minus:SI (const_int 31)
6378			     (match_operand:SI 2 "register_operand" "q,q"))))]
6379  ""
6380  "@
6381   {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6382   {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6383  [(set_attr "type" "shift,shift")
6384   (set_attr "length" "4,4")])
6385
6386(define_insn "zvdep_imm32"
6387  [(set (match_operand:SI 0 "register_operand" "=r")
6388	(ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6389		   (minus:SI (const_int 31)
6390			     (match_operand:SI 2 "register_operand" "q"))))]
6391  ""
6392  "*
6393{
6394  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6395  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6396  operands[1] = GEN_INT ((x & 0xf) - 0x10);
6397  return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6398}"
6399  [(set_attr "type" "shift")
6400   (set_attr "length" "4")])
6401
6402(define_insn "vdepi_ior"
6403  [(set (match_operand:SI 0 "register_operand" "=r")
6404	(ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6405			   (minus:SI (const_int 31)
6406				     (match_operand:SI 2 "register_operand" "q")))
6407		(match_operand:SI 3 "register_operand" "0")))]
6408  ; accept ...0001...1, can this be generalized?
6409  "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6410  "*
6411{
6412  HOST_WIDE_INT x = INTVAL (operands[1]);
6413  operands[2] = GEN_INT (exact_log2 (x + 1));
6414  return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6415}"
6416  [(set_attr "type" "shift")
6417   (set_attr "length" "4")])
6418
6419(define_insn "vdepi_and"
6420  [(set (match_operand:SI 0 "register_operand" "=r")
6421	(and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6422			   (minus:SI (const_int 31)
6423				     (match_operand:SI 2 "register_operand" "q")))
6424		(match_operand:SI 3 "register_operand" "0")))]
6425  ; this can be generalized...!
6426  "INTVAL (operands[1]) == -2"
6427  "*
6428{
6429  HOST_WIDE_INT x = INTVAL (operands[1]);
6430  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6431  return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6432}"
6433  [(set_attr "type" "shift")
6434   (set_attr "length" "4")])
6435
6436(define_expand "ashldi3"
6437  [(set (match_operand:DI 0 "register_operand" "")
6438	(ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6439		   (match_operand:DI 2 "arith32_operand" "")))]
6440  "TARGET_64BIT"
6441  "
6442{
6443  if (GET_CODE (operands[2]) != CONST_INT)
6444    {
6445      rtx temp = gen_reg_rtx (DImode);
6446      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6447      if (GET_CODE (operands[1]) == CONST_INT)
6448	emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6449      else
6450	emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6451      DONE;
6452    }
6453  /* Make sure both inputs are not constants,
6454     there are no patterns for that.  */
6455  operands[1] = force_reg (DImode, operands[1]);
6456}")
6457
6458(define_insn ""
6459  [(set (match_operand:DI 0 "register_operand" "=r")
6460	(ashift:DI (match_operand:DI 1 "register_operand" "r")
6461		   (match_operand:DI 2 "const_int_operand" "n")))]
6462  "TARGET_64BIT"
6463  "depd,z %1,%p2,%Q2,%0"
6464  [(set_attr "type" "shift")
6465   (set_attr "length" "4")])
6466
6467; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6468; Doing it like this makes slightly better code since reload can
6469; replace a register with a known value in range -16..15 with a
6470; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6471; but since we have no more CONST_OK... characters, that is not
6472; possible.
6473(define_insn "zvdep64"
6474  [(set (match_operand:DI 0 "register_operand" "=r,r")
6475	(ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6476		   (minus:DI (const_int 63)
6477			     (match_operand:DI 2 "register_operand" "q,q"))))]
6478  "TARGET_64BIT"
6479  "@
6480   depd,z %1,%%sar,64,%0
6481   depdi,z %1,%%sar,64,%0"
6482  [(set_attr "type" "shift,shift")
6483   (set_attr "length" "4,4")])
6484
6485(define_insn "zvdep_imm64"
6486  [(set (match_operand:DI 0 "register_operand" "=r")
6487	(ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6488		   (minus:DI (const_int 63)
6489			     (match_operand:DI 2 "register_operand" "q"))))]
6490  "TARGET_64BIT"
6491  "*
6492{
6493  unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6494  operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6495  operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6496  return \"depdi,z %1,%%sar,%2,%0\";
6497}"
6498  [(set_attr "type" "shift")
6499   (set_attr "length" "4")])
6500
6501(define_insn ""
6502  [(set (match_operand:DI 0 "register_operand" "=r")
6503	(ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6504			   (minus:DI (const_int 63)
6505				     (match_operand:DI 2 "register_operand" "q")))
6506		(match_operand:DI 3 "register_operand" "0")))]
6507  ; accept ...0001...1, can this be generalized?
6508  "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6509  "*
6510{
6511  HOST_WIDE_INT x = INTVAL (operands[1]);
6512  operands[2] = GEN_INT (exact_log2 (x + 1));
6513  return \"depdi -1,%%sar,%2,%0\";
6514}"
6515  [(set_attr "type" "shift")
6516   (set_attr "length" "4")])
6517
6518(define_insn ""
6519  [(set (match_operand:DI 0 "register_operand" "=r")
6520	(and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6521			   (minus:DI (const_int 63)
6522				     (match_operand:DI 2 "register_operand" "q")))
6523		(match_operand:DI 3 "register_operand" "0")))]
6524  ; this can be generalized...!
6525  "TARGET_64BIT && INTVAL (operands[1]) == -2"
6526  "*
6527{
6528  HOST_WIDE_INT x = INTVAL (operands[1]);
6529  operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6530  return \"depdi 0,%%sar,%2,%0\";
6531}"
6532  [(set_attr "type" "shift")
6533   (set_attr "length" "4")])
6534
6535(define_expand "ashrsi3"
6536  [(set (match_operand:SI 0 "register_operand" "")
6537	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6538		     (match_operand:SI 2 "arith32_operand" "")))]
6539  ""
6540  "
6541{
6542  if (GET_CODE (operands[2]) != CONST_INT)
6543    {
6544      rtx temp = gen_reg_rtx (SImode);
6545      emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6546      emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6547      DONE;
6548    }
6549}")
6550
6551(define_insn ""
6552  [(set (match_operand:SI 0 "register_operand" "=r")
6553	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6554		     (match_operand:SI 2 "const_int_operand" "n")))]
6555  ""
6556  "{extrs|extrw,s} %1,%P2,%L2,%0"
6557  [(set_attr "type" "shift")
6558   (set_attr "length" "4")])
6559
6560(define_insn "vextrs32"
6561  [(set (match_operand:SI 0 "register_operand" "=r")
6562	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6563		     (minus:SI (const_int 31)
6564			       (match_operand:SI 2 "register_operand" "q"))))]
6565  ""
6566  "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6567  [(set_attr "type" "shift")
6568   (set_attr "length" "4")])
6569
6570(define_expand "ashrdi3"
6571  [(set (match_operand:DI 0 "register_operand" "")
6572	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6573		     (match_operand:DI 2 "arith32_operand" "")))]
6574  "TARGET_64BIT"
6575  "
6576{
6577  if (GET_CODE (operands[2]) != CONST_INT)
6578    {
6579      rtx temp = gen_reg_rtx (DImode);
6580      emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6581      emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6582      DONE;
6583    }
6584}")
6585
6586(define_insn ""
6587  [(set (match_operand:DI 0 "register_operand" "=r")
6588	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6589		     (match_operand:DI 2 "const_int_operand" "n")))]
6590  "TARGET_64BIT"
6591  "extrd,s %1,%p2,%Q2,%0"
6592  [(set_attr "type" "shift")
6593   (set_attr "length" "4")])
6594
6595(define_insn "vextrs64"
6596  [(set (match_operand:DI 0 "register_operand" "=r")
6597	(ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6598		     (minus:DI (const_int 63)
6599			       (match_operand:DI 2 "register_operand" "q"))))]
6600  "TARGET_64BIT"
6601  "extrd,s %1,%%sar,64,%0"
6602  [(set_attr "type" "shift")
6603   (set_attr "length" "4")])
6604
6605(define_insn "lshrsi3"
6606  [(set (match_operand:SI 0 "register_operand" "=r,r")
6607	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6608		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6609  ""
6610  "@
6611   {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6612   {extru|extrw,u} %1,%P2,%L2,%0"
6613  [(set_attr "type" "shift")
6614   (set_attr "length" "4")])
6615
6616(define_insn "lshrdi3"
6617  [(set (match_operand:DI 0 "register_operand" "=r,r")
6618	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6619		     (match_operand:DI 2 "shift6_operand" "q,n")))]
6620  "TARGET_64BIT"
6621  "@
6622   shrpd %%r0,%1,%%sar,%0
6623   extrd,u %1,%p2,%Q2,%0"
6624  [(set_attr "type" "shift")
6625   (set_attr "length" "4")])
6626
6627; Shift right pair word 0 to 31 bits.
6628(define_insn "shrpsi4"
6629  [(set (match_operand:SI 0 "register_operand" "=r,r")
6630	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
6631			   (minus:SI (const_int 32)
6632			     (match_operand:SI 3 "shift5_operand" "q,n")))
6633		(lshiftrt:SI (match_operand:SI 2 "register_operand" "r,r")
6634			     (match_dup 3))))]
6635  ""
6636  "@
6637   {vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}
6638   {shd|shrpw} %1,%2,%3,%0"
6639  [(set_attr "type" "shift")
6640   (set_attr "length" "4")])
6641
6642; Shift right pair doubleword 0 to 63 bits.
6643(define_insn "shrpdi4"
6644  [(set (match_operand:DI 0 "register_operand" "=r,r")
6645	(ior:DI (ashift:DI (match_operand:SI 1 "register_operand" "r,r")
6646			   (minus:DI (const_int 64)
6647			     (match_operand:DI 3 "shift6_operand" "q,n")))
6648		(lshiftrt:DI (match_operand:DI 2 "register_operand" "r,r")
6649			     (match_dup 3))))]
6650  "TARGET_64BIT"
6651  "@
6652   shrpd %1,%2,%%sar,%0
6653   shrpd %1,%2,%3,%0"
6654  [(set_attr "type" "shift")
6655   (set_attr "length" "4")])
6656
6657(define_insn "rotrsi3"
6658  [(set (match_operand:SI 0 "register_operand" "=r,r")
6659	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6660		     (match_operand:SI 2 "shift5_operand" "q,n")))]
6661  ""
6662  "*
6663{
6664  if (GET_CODE (operands[2]) == CONST_INT)
6665    {
6666      operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6667      return \"{shd|shrpw} %1,%1,%2,%0\";
6668    }
6669  else
6670    return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6671}"
6672  [(set_attr "type" "shift")
6673   (set_attr "length" "4")])
6674
6675(define_expand "rotlsi3"
6676  [(set (match_operand:SI 0 "register_operand" "")
6677        (rotate:SI (match_operand:SI 1 "register_operand" "")
6678                   (match_operand:SI 2 "arith32_operand" "")))]
6679  ""
6680  "
6681{
6682  if (GET_CODE (operands[2]) != CONST_INT)
6683    {
6684      rtx temp = gen_reg_rtx (SImode);
6685      emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6686      emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6687      DONE;
6688    }
6689  /* Else expand normally.  */
6690}")
6691
6692(define_insn ""
6693  [(set (match_operand:SI 0 "register_operand" "=r")
6694        (rotate:SI (match_operand:SI 1 "register_operand" "r")
6695                   (match_operand:SI 2 "const_int_operand" "n")))]
6696  ""
6697  "*
6698{
6699  operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6700  return \"{shd|shrpw} %1,%1,%2,%0\";
6701}"
6702  [(set_attr "type" "shift")
6703   (set_attr "length" "4")])
6704
6705(define_insn ""
6706  [(set (match_operand:SI 0 "register_operand" "=r")
6707	(match_operator:SI 5 "plus_xor_ior_operator"
6708	  [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6709		      (match_operand:SI 3 "const_int_operand" "n"))
6710	   (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6711			(match_operand:SI 4 "const_int_operand" "n"))]))]
6712  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6713  "{shd|shrpw} %1,%2,%4,%0"
6714  [(set_attr "type" "shift")
6715   (set_attr "length" "4")])
6716
6717(define_insn ""
6718  [(set (match_operand:SI 0 "register_operand" "=r")
6719	(match_operator:SI 5 "plus_xor_ior_operator"
6720	  [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6721			(match_operand:SI 4 "const_int_operand" "n"))
6722	   (ashift:SI (match_operand:SI 1 "register_operand" "r")
6723		      (match_operand:SI 3 "const_int_operand" "n"))]))]
6724  "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6725  "{shd|shrpw} %1,%2,%4,%0"
6726  [(set_attr "type" "shift")
6727   (set_attr "length" "4")])
6728
6729(define_insn ""
6730  [(set (match_operand:SI 0 "register_operand" "=r")
6731	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6732			   (match_operand:SI 2 "const_int_operand" ""))
6733		(match_operand:SI 3 "const_int_operand" "")))]
6734  "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6735  "*
6736{
6737  int cnt = INTVAL (operands[2]) & 31;
6738  operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6739  operands[2] = GEN_INT (31 - cnt);
6740  return \"{zdep|depw,z} %1,%2,%3,%0\";
6741}"
6742  [(set_attr "type" "shift")
6743   (set_attr "length" "4")])
6744
6745;; Unconditional and other jump instructions.
6746
6747;; Trivial return used when no epilogue is needed.
6748(define_insn "return"
6749  [(return)
6750   (use (reg:SI 2))]
6751  "pa_can_use_return_insn ()"
6752  "*
6753{
6754  if (TARGET_PA_20)
6755    return \"bve%* (%%r2)\";
6756  return \"bv%* %%r0(%%r2)\";
6757}"
6758  [(set_attr "type" "branch")
6759   (set_attr "length" "4")])
6760
6761;; This is used for most returns.
6762(define_insn "return_internal"
6763  [(return)
6764   (use (reg:SI 2))]
6765  ""
6766  "*
6767{
6768  if (TARGET_PA_20)
6769    return \"bve%* (%%r2)\";
6770  return \"bv%* %%r0(%%r2)\";
6771}"
6772  [(set_attr "type" "branch")
6773   (set_attr "length" "4")])
6774
6775;; This is used for eh returns which bypass the return stub.
6776(define_insn "return_external_pic"
6777  [(return)
6778   (clobber (reg:SI 1))
6779   (use (reg:SI 2))]
6780  "!TARGET_NO_SPACE_REGS
6781   && !TARGET_PA_20
6782   && flag_pic && crtl->calls_eh_return"
6783  "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
6784  [(set_attr "type" "branch")
6785   (set_attr "length" "12")])
6786
6787(define_expand "prologue"
6788  [(const_int 0)]
6789  ""
6790  "pa_expand_prologue ();DONE;")
6791
6792(define_expand "sibcall_epilogue"
6793  [(return)]
6794  ""
6795  "
6796{
6797  pa_expand_epilogue ();
6798  DONE;
6799}")
6800
6801(define_expand "epilogue"
6802  [(return)]
6803  ""
6804  "
6805{
6806  rtx x;
6807
6808  /* Try to use the trivial return first.  Else use the full epilogue.  */
6809  if (pa_can_use_return_insn ())
6810    x = gen_return ();
6811  else
6812    {
6813      pa_expand_epilogue ();
6814
6815      /* EH returns bypass the normal return stub.  Thus, we must do an
6816	 interspace branch to return from functions that call eh_return.
6817	 This is only a problem for returns from shared code on ports
6818	 using space registers.  */
6819      if (!TARGET_NO_SPACE_REGS
6820	  && !TARGET_PA_20
6821	  && flag_pic && crtl->calls_eh_return)
6822	x = gen_return_external_pic ();
6823      else
6824	x = gen_return_internal ();
6825    }
6826  emit_jump_insn (x);
6827  DONE;
6828}")
6829
6830; Used by hppa_profile_hook to load the starting address of the current
6831; function; operand 1 contains the address of the label in operand 3
6832(define_insn "load_offset_label_address"
6833  [(set (match_operand:SI 0 "register_operand" "=r")
6834        (plus:SI (match_operand:SI 1 "register_operand" "r")
6835		 (minus:SI (match_operand:SI 2 "" "")
6836			   (label_ref:SI (match_operand 3 "" "")))))]
6837  ""
6838  "ldo %2-%l3(%1),%0"
6839  [(set_attr "type" "multi")
6840   (set_attr "length" "4")])
6841
6842; Output a code label and load its address.
6843(define_insn "lcla1"
6844  [(set (match_operand:SI 0 "register_operand" "=r")
6845        (label_ref:SI (match_operand 1 "" "")))
6846   (const_int 0)]
6847  "!TARGET_PA_20"
6848  "*
6849{
6850  output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
6851  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6852                                     CODE_LABEL_NUMBER (operands[1]));
6853  return \"\";
6854}"
6855  [(set_attr "type" "multi")
6856   (set_attr "length" "8")])
6857
6858(define_insn "lcla2"
6859  [(set (match_operand:SI 0 "register_operand" "=r")
6860        (label_ref:SI (match_operand 1 "" "")))
6861   (const_int 0)]
6862  "TARGET_PA_20"
6863  "*
6864{
6865  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6866                                     CODE_LABEL_NUMBER (operands[1]));
6867  return \"mfia %0\";
6868}"
6869  [(set_attr "type" "move")
6870   (set_attr "length" "4")])
6871
6872(define_insn "blockage"
6873  [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
6874  ""
6875  ""
6876  [(set_attr "length" "0")])
6877
6878(define_insn "jump"
6879  [(set (pc) (label_ref (match_operand 0 "" "")))]
6880  ""
6881  "*
6882{
6883  /* An unconditional branch which can reach its target.  */
6884  if (get_attr_length (insn) < 16)
6885    return \"b%* %l0\";
6886
6887  return pa_output_lbranch (operands[0], insn, 1);
6888}"
6889  [(set_attr "type" "uncond_branch")
6890   (set_attr "pa_combine_type" "uncond_branch")
6891   (set (attr "length")
6892    (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
6893	       (const_int MAX_17BIT_OFFSET))
6894	   (const_int 4)
6895	   (match_test "TARGET_PORTABLE_RUNTIME")
6896	   (const_int 20)
6897	   (not (match_test "flag_pic"))
6898	   (const_int 16)]
6899	  (const_int 24)))])
6900
6901;;; Hope this is only within a function...
6902(define_insn "indirect_jump"
6903  [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
6904  ""
6905  "bv%* %%r0(%0)"
6906  [(set_attr "type" "branch")
6907   (set_attr "length" "4")])
6908
6909;;; An indirect jump can be optimized to a direct jump.  GAS for the
6910;;; SOM target doesn't allow branching to a label inside a function.
6911;;; We also don't correctly compute branch distances for labels
6912;;; outside the current function.  Thus, we use an indirect jump can't
6913;;; be optimized to a direct jump for all targets.  We assume that
6914;;; the branch target is in the same space (i.e., nested function
6915;;; jumping to a label in an outer function in the same translation
6916;;; unit).
6917(define_expand "nonlocal_goto"
6918  [(use (match_operand 0 "general_operand" ""))
6919   (use (match_operand 1 "general_operand" ""))
6920   (use (match_operand 2 "general_operand" ""))
6921   (use (match_operand 3 "general_operand" ""))]
6922  ""
6923{
6924  rtx lab = operands[1];
6925  rtx stack = operands[2];
6926  rtx fp = operands[3];
6927
6928  lab = copy_to_reg (lab);
6929
6930  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6931  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6932
6933  /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
6934     instead of the hard_frame_pointer_rtx in the save area.  As a
6935     result, an extra instruction is needed to adjust for the offset
6936     of the virtual stack variables and the hard frame pointer.  */
6937  if (GET_CODE (fp) != REG)
6938    fp = force_reg (Pmode, fp);
6939  emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
6940
6941  emit_stack_restore (SAVE_NONLOCAL, stack);
6942
6943  emit_use (hard_frame_pointer_rtx);
6944  emit_use (stack_pointer_rtx);
6945
6946  /* Nonlocal goto jumps are only used between functions in the same
6947     translation unit.  Thus, we can avoid the extra overhead of an
6948     interspace jump.  */
6949  emit_jump_insn (gen_indirect_goto (lab));
6950  emit_barrier ();
6951  DONE;
6952})
6953
6954(define_insn "indirect_goto"
6955  [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
6956  "GET_MODE (operands[0]) == word_mode"
6957  "bv%* %%r0(%0)"
6958  [(set_attr "type" "branch")
6959   (set_attr "length" "4")])
6960
6961;; Subroutines of "casesi".
6962;; operand 0 is index
6963;; operand 1 is the minimum bound
6964;; operand 2 is the maximum bound - minimum bound + 1
6965;; operand 3 is CODE_LABEL for the table;
6966;; operand 4 is the CODE_LABEL to go to if index out of range.
6967
6968(define_expand "casesi"
6969  [(match_operand:SI 0 "general_operand" "")
6970   (match_operand:SI 1 "const_int_operand" "")
6971   (match_operand:SI 2 "const_int_operand" "")
6972   (match_operand 3 "" "")
6973   (match_operand 4 "" "")]
6974  ""
6975  "
6976{
6977  if (GET_CODE (operands[0]) != REG)
6978    operands[0] = force_reg (SImode, operands[0]);
6979
6980  if (operands[1] != const0_rtx)
6981    {
6982      rtx index = gen_reg_rtx (SImode);
6983
6984      operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
6985      if (!INT_14_BITS (operands[1]))
6986	operands[1] = force_reg (SImode, operands[1]);
6987      emit_insn (gen_addsi3 (index, operands[0], operands[1]));
6988      operands[0] = index;
6989    }
6990
6991  if (!INT_5_BITS (operands[2]))
6992    operands[2] = force_reg (SImode, operands[2]);
6993
6994  /* This branch prevents us finding an insn for the delay slot of the
6995     following vectored branch.  It might be possible to use the delay
6996     slot if an index value of -1 was used to transfer to the out-of-range
6997     label.  In order to do this, we would have to output the -1 vector
6998     element after the delay insn.  The casesi output code would have to
6999     check if the casesi insn is in a delay branch sequence and output
7000     the delay insn if one is found.  If this was done, then it might
7001     then be worthwhile to split the casesi patterns to improve scheduling.
7002     However, it's not clear that all this extra complexity is worth
7003     the effort.  */
7004  {
7005    rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7006    emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7007  }
7008
7009  /* In 64bit mode we must make sure to wipe the upper bits of the register
7010     just in case the addition overflowed or we had random bits in the
7011     high part of the register.  */
7012  if (TARGET_64BIT)
7013    {
7014      rtx index = gen_reg_rtx (DImode);
7015
7016      emit_insn (gen_extendsidi2 (index, operands[0]));
7017      operands[0] = index;
7018    }
7019
7020  if (TARGET_64BIT)
7021    emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7022  else if (flag_pic)
7023    emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7024  else
7025    emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7026  DONE;
7027}")
7028
7029;;; 32-bit code, absolute branch table.
7030(define_insn "casesi32"
7031  [(set (pc) (mem:SI (plus:SI
7032		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7033				(const_int 4))
7034		       (label_ref (match_operand 1 "" "")))))
7035   (clobber (match_scratch:SI 2 "=&r"))]
7036  "!flag_pic"
7037  "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7038  [(set_attr "type" "multi")
7039   (set_attr "length" "16")])
7040
7041;;; 32-bit code, relative branch table.
7042(define_insn "casesi32p"
7043  [(set (pc) (mem:SI (plus:SI
7044		       (mult:SI (match_operand:SI 0 "register_operand" "r")
7045				(const_int 4))
7046		       (label_ref (match_operand 1 "" "")))))
7047   (clobber (match_scratch:SI 2 "=&r"))
7048   (clobber (match_scratch:SI 3 "=&r"))]
7049  "flag_pic"
7050  "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7051{ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7052  [(set_attr "type" "multi")
7053   (set (attr "length")
7054     (if_then_else (match_test "TARGET_PA_20")
7055	(const_int 20)
7056	(const_int 24)))])
7057
7058;;; 64-bit code, 32-bit relative branch table.
7059(define_insn "casesi64p"
7060  [(set (pc) (mem:DI (plus:DI
7061		       (mult:DI (match_operand:DI 0 "register_operand" "r")
7062				(const_int 8))
7063		       (label_ref (match_operand 1 "" "")))))
7064   (clobber (match_scratch:DI 2 "=&r"))
7065   (clobber (match_scratch:DI 3 "=&r"))]
7066  ""
7067  "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7068add,l %2,%3,%3\;bv,n %%r0(%3)"
7069  [(set_attr "type" "multi")
7070   (set_attr "length" "24")])
7071
7072
7073;; Call patterns.
7074;;- jump to subroutine
7075
7076(define_expand "call"
7077  [(parallel [(call (match_operand:SI 0 "" "")
7078		    (match_operand 1 "" ""))
7079	      (clobber (reg:SI 2))])]
7080  ""
7081  "
7082{
7083  rtx op;
7084  rtx nb = operands[1];
7085
7086  if (TARGET_PORTABLE_RUNTIME)
7087    op = force_reg (SImode, XEXP (operands[0], 0));
7088  else
7089    {
7090      op = XEXP (operands[0], 0);
7091
7092      /* Generate indirect long calls to non-local functions. */
7093      if (!TARGET_64BIT && TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7094	{
7095	  tree call_decl = SYMBOL_REF_DECL (op);
7096	  if (!(call_decl && targetm.binds_local_p (call_decl)))
7097	    op = force_reg (word_mode, op);
7098	}
7099    }
7100
7101  if (TARGET_64BIT)
7102    {
7103      if (!virtuals_instantiated)
7104	emit_move_insn (arg_pointer_rtx,
7105			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7106				      GEN_INT (64)));
7107      else
7108	{
7109	  /* The loop pass can generate new libcalls after the virtual
7110	     registers are instantiated when fpregs are disabled because
7111	     the only method that we have for doing DImode multiplication
7112	     is with a libcall.  This could be trouble if we haven't
7113	     allocated enough space for the outgoing arguments.  */
7114	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7115
7116	  emit_move_insn (arg_pointer_rtx,
7117			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7118					GEN_INT (STACK_POINTER_OFFSET + 64)));
7119	}
7120    }
7121
7122  /* Use two different patterns for calls to explicitly named functions
7123     and calls through function pointers.  This is necessary as these two
7124     types of calls use different calling conventions, and CSE might try
7125     to change the named call into an indirect call in some cases (using
7126     two patterns keeps CSE from performing this optimization).
7127
7128     We now use even more call patterns as there was a subtle bug in
7129     attempting to restore the pic register after a call using a simple
7130     move insn.  During reload, a instruction involving a pseudo register
7131     with no explicit dependence on the PIC register can be converted
7132     to an equivalent load from memory using the PIC register.  If we
7133     emit a simple move to restore the PIC register in the initial rtl
7134     generation, then it can potentially be repositioned during scheduling.
7135     and an instruction that eventually uses the PIC register may end up
7136     between the call and the PIC register restore.
7137
7138     This only worked because there is a post call group of instructions
7139     that are scheduled with the call.  These instructions are included
7140     in the same basic block as the call.  However, calls can throw in
7141     C++ code and a basic block has to terminate at the call if the call
7142     can throw.  This results in the PIC register restore being scheduled
7143     independently from the call.  So, we now hide the save and restore
7144     of the PIC register in the call pattern until after reload.  Then,
7145     we split the moves out.  A small side benefit is that we now don't
7146     need to have a use of the PIC register in the return pattern and
7147     the final save/restore operation is not needed.
7148
7149     I elected to just use register %r4 in the PIC patterns instead
7150     of trying to force hppa_pic_save_rtx () to a callee saved register.
7151     This might have required a new register class and constraint.  It
7152     was also simpler to just handle the restore from a register than a
7153     generic pseudo.  */
7154  if (TARGET_64BIT)
7155    {
7156      rtx r4 = gen_rtx_REG (word_mode, 4);
7157      if (GET_CODE (op) == SYMBOL_REF)
7158	emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7159      else
7160	{
7161	  op = force_reg (word_mode, op);
7162	  emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7163	}
7164    }
7165  else
7166    {
7167      if (GET_CODE (op) == SYMBOL_REF)
7168	{
7169	  if (flag_pic)
7170	    {
7171	      rtx r4 = gen_rtx_REG (word_mode, 4);
7172	      emit_call_insn (gen_call_symref_pic (op, nb, r4));
7173	    }
7174	  else
7175	    emit_call_insn (gen_call_symref (op, nb));
7176	}
7177      else
7178	{
7179	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7180	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7181	  if (flag_pic)
7182	    {
7183	      rtx r4 = gen_rtx_REG (word_mode, 4);
7184	      emit_call_insn (gen_call_reg_pic (nb, r4));
7185	    }
7186	  else
7187	    emit_call_insn (gen_call_reg (nb));
7188	}
7189    }
7190
7191  DONE;
7192}")
7193
7194;; We use function calls to set the attribute length of calls and millicode
7195;; calls.  This is necessary because of the large variety of call sequences.
7196;; Implementing the calculation in rtl is difficult as well as ugly.  As
7197;; we need the same calculation in several places, maintenance becomes a
7198;; nightmare.
7199;;
7200;; However, this has a subtle impact on branch shortening.  When the
7201;; expression used to set the length attribute of an instruction depends
7202;; on a relative address (e.g., pc or a branch address), genattrtab
7203;; notes that the insn's length is variable, and attempts to determine a
7204;; worst-case default length and code to compute an insn's current length.
7205
7206;; The use of a function call hides the variable dependence of our calls
7207;; and millicode calls.  The result is genattrtab doesn't treat the operation
7208;; as variable and it only generates code for the default case using our
7209;; function call.  Because of this, calls and millicode calls have a fixed
7210;; length in the branch shortening pass, and some branches will use a longer
7211;; code sequence than necessary.  However, the length of any given call
7212;; will still reflect its final code location and it may be shorter than
7213;; the initial length estimate.
7214
7215;; It's possible to trick genattrtab by adding an expression involving `pc'
7216;; in the set.  However, when genattrtab hits a function call in its attempt
7217;; to compute the default length, it marks the result as unknown and sets
7218;; the default result to MAX_INT ;-(  One possible fix that would allow
7219;; calls to participate in branch shortening would be to make the call to
7220;; insn_default_length a target option.  Then, we could massage unknown
7221;; results.  Another fix might be to change genattrtab so that it just does
7222;; the call in the variable case as it already does for the fixed case.
7223
7224(define_insn "call_symref"
7225  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7226	 (match_operand 1 "" "i"))
7227   (clobber (reg:SI 1))
7228   (clobber (reg:SI 2))
7229   (use (const_int 0))]
7230  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7231  "*
7232{
7233  pa_output_arg_descriptor (insn);
7234  return pa_output_call (insn, operands[0], 0);
7235}"
7236  [(set_attr "type" "call")
7237   (set (attr "length")
7238	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7239	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7240
7241(define_insn "call_symref_pic"
7242  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7243	 (match_operand 1 "" "i"))
7244   (clobber (reg:SI 1))
7245   (clobber (reg:SI 2))
7246   (clobber (match_operand 2))
7247   (use (reg:SI 19))
7248   (use (const_int 0))]
7249  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7250  "#")
7251
7252;; Split out the PIC register save and restore after reload.  As the
7253;; split is done after reload, there are some situations in which we
7254;; unnecessarily save and restore %r4.  This happens when there is a
7255;; single call and the PIC register is not used after the call.
7256;;
7257;; The split has to be done since call_from_call_insn () can't handle
7258;; the pattern as is.  Noreturn calls are special because they have to
7259;; terminate the basic block.  The split has to contain more than one
7260;; insn.
7261(define_split
7262  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7263		    (match_operand 1 "" ""))
7264	      (clobber (reg:SI 1))
7265	      (clobber (reg:SI 2))
7266	      (clobber (match_operand 2))
7267	      (use (reg:SI 19))
7268	      (use (const_int 0))])]
7269  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7270   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7271  [(set (match_dup 2) (reg:SI 19))
7272   (parallel [(call (mem:SI (match_dup 0))
7273		    (match_dup 1))
7274	      (clobber (reg:SI 1))
7275	      (clobber (reg:SI 2))
7276	      (use (reg:SI 19))
7277	      (use (const_int 0))])]
7278  "")
7279
7280(define_split
7281  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7282		    (match_operand 1 "" ""))
7283	      (clobber (reg:SI 1))
7284	      (clobber (reg:SI 2))
7285	      (clobber (match_operand 2))
7286	      (use (reg:SI 19))
7287	      (use (const_int 0))])]
7288  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7289  [(set (match_dup 2) (reg:SI 19))
7290   (parallel [(call (mem:SI (match_dup 0))
7291		    (match_dup 1))
7292	      (clobber (reg:SI 1))
7293	      (clobber (reg:SI 2))
7294	      (use (reg:SI 19))
7295	      (use (const_int 0))])
7296   (set (reg:SI 19) (match_dup 2))]
7297  "")
7298
7299(define_insn "*call_symref_pic_post_reload"
7300  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7301	 (match_operand 1 "" "i"))
7302   (clobber (reg:SI 1))
7303   (clobber (reg:SI 2))
7304   (use (reg:SI 19))
7305   (use (const_int 0))]
7306  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7307  "*
7308{
7309  pa_output_arg_descriptor (insn);
7310  return pa_output_call (insn, operands[0], 0);
7311}"
7312  [(set_attr "type" "call")
7313   (set (attr "length")
7314	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7315	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7316
7317;; This pattern is split if it is necessary to save and restore the
7318;; PIC register.
7319(define_insn "call_symref_64bit"
7320  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7321	 (match_operand 1 "" "i"))
7322   (clobber (reg:DI 1))
7323   (clobber (reg:DI 2))
7324   (clobber (match_operand 2))
7325   (use (reg:DI 27))
7326   (use (reg:DI 29))
7327   (use (const_int 0))]
7328  "TARGET_64BIT"
7329  "#")
7330
7331;; Split out the PIC register save and restore after reload.  As the
7332;; split is done after reload, there are some situations in which we
7333;; unnecessarily save and restore %r4.  This happens when there is a
7334;; single call and the PIC register is not used after the call.
7335;;
7336;; The split has to be done since call_from_call_insn () can't handle
7337;; the pattern as is.  Noreturn calls are special because they have to
7338;; terminate the basic block.  The split has to contain more than one
7339;; insn.
7340(define_split
7341  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7342		    (match_operand 1 "" ""))
7343	      (clobber (reg:DI 1))
7344	      (clobber (reg:DI 2))
7345	      (clobber (match_operand 2))
7346	      (use (reg:DI 27))
7347	      (use (reg:DI 29))
7348	      (use (const_int 0))])]
7349  "TARGET_64BIT && reload_completed
7350   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7351  [(set (match_dup 2) (reg:DI 27))
7352   (parallel [(call (mem:SI (match_dup 0))
7353		    (match_dup 1))
7354	      (clobber (reg:DI 1))
7355	      (clobber (reg:DI 2))
7356	      (use (reg:DI 27))
7357	      (use (reg:DI 29))
7358	      (use (const_int 0))])]
7359  "")
7360
7361(define_split
7362  [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7363		    (match_operand 1 "" ""))
7364	      (clobber (reg:DI 1))
7365	      (clobber (reg:DI 2))
7366	      (clobber (match_operand 2))
7367	      (use (reg:DI 27))
7368	      (use (reg:DI 29))
7369	      (use (const_int 0))])]
7370  "TARGET_64BIT && reload_completed"
7371  [(set (match_dup 2) (reg:DI 27))
7372   (parallel [(call (mem:SI (match_dup 0))
7373		    (match_dup 1))
7374	      (clobber (reg:DI 1))
7375	      (clobber (reg:DI 2))
7376	      (use (reg:DI 27))
7377	      (use (reg:DI 29))
7378	      (use (const_int 0))])
7379   (set (reg:DI 27) (match_dup 2))]
7380  "")
7381
7382(define_insn "*call_symref_64bit_post_reload"
7383  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7384	 (match_operand 1 "" "i"))
7385   (clobber (reg:DI 1))
7386   (clobber (reg:DI 2))
7387   (use (reg:DI 27))
7388   (use (reg:DI 29))
7389   (use (const_int 0))]
7390  "TARGET_64BIT"
7391  "*
7392{
7393  pa_output_arg_descriptor (insn);
7394  return pa_output_call (insn, operands[0], 0);
7395}"
7396  [(set_attr "type" "call")
7397   (set (attr "length")
7398	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7399	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7400
7401(define_insn "call_reg"
7402  [(call (mem:SI (reg:SI 22))
7403	 (match_operand 0 "" "i"))
7404   (clobber (reg:SI 1))
7405   (clobber (reg:SI 2))
7406   (use (const_int 1))]
7407  "!TARGET_64BIT"
7408  "*
7409{
7410  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7411}"
7412  [(set_attr "type" "dyncall")
7413   (set (attr "length")
7414	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7415	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7416
7417;; This pattern is split if it is necessary to save and restore the
7418;; PIC register.
7419(define_insn "call_reg_pic"
7420  [(call (mem:SI (reg:SI 22))
7421	 (match_operand 0 "" "i"))
7422   (clobber (reg:SI 1))
7423   (clobber (reg:SI 2))
7424   (clobber (match_operand 1))
7425   (use (reg:SI 19))
7426   (use (const_int 1))]
7427  "!TARGET_64BIT"
7428  "#")
7429
7430;; Split out the PIC register save and restore after reload.  As the
7431;; split is done after reload, there are some situations in which we
7432;; unnecessarily save and restore %r4.  This happens when there is a
7433;; single call and the PIC register is not used after the call.
7434;;
7435;; The split has to be done since call_from_call_insn () can't handle
7436;; the pattern as is.  Noreturn calls are special because they have to
7437;; terminate the basic block.  The split has to contain more than one
7438;; insn.
7439(define_split
7440  [(parallel [(call (mem:SI (reg:SI 22))
7441		    (match_operand 0 "" ""))
7442	      (clobber (reg:SI 1))
7443	      (clobber (reg:SI 2))
7444	      (clobber (match_operand 1))
7445	      (use (reg:SI 19))
7446	      (use (const_int 1))])]
7447  "!TARGET_64BIT && reload_completed
7448   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7449  [(set (match_dup 1) (reg:SI 19))
7450   (parallel [(call (mem:SI (reg:SI 22))
7451		    (match_dup 0))
7452	      (clobber (reg:SI 1))
7453	      (clobber (reg:SI 2))
7454	      (use (reg:SI 19))
7455	      (use (const_int 1))])]
7456  "")
7457
7458(define_split
7459  [(parallel [(call (mem:SI (reg:SI 22))
7460		    (match_operand 0 "" ""))
7461	      (clobber (reg:SI 1))
7462	      (clobber (reg:SI 2))
7463	      (clobber (match_operand 1))
7464	      (use (reg:SI 19))
7465	      (use (const_int 1))])]
7466  "!TARGET_64BIT && reload_completed"
7467  [(set (match_dup 1) (reg:SI 19))
7468   (parallel [(call (mem:SI (reg:SI 22))
7469		    (match_dup 0))
7470	      (clobber (reg:SI 1))
7471	      (clobber (reg:SI 2))
7472	      (use (reg:SI 19))
7473	      (use (const_int 1))])
7474   (set (reg:SI 19) (match_dup 1))]
7475  "")
7476
7477(define_insn "*call_reg_pic_post_reload"
7478  [(call (mem:SI (reg:SI 22))
7479	 (match_operand 0 "" "i"))
7480   (clobber (reg:SI 1))
7481   (clobber (reg:SI 2))
7482   (use (reg:SI 19))
7483   (use (const_int 1))]
7484  "!TARGET_64BIT"
7485  "*
7486{
7487  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7488}"
7489  [(set_attr "type" "dyncall")
7490   (set (attr "length")
7491	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7492	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7493
7494;; This pattern is split if it is necessary to save and restore the
7495;; PIC register.
7496(define_insn "call_reg_64bit"
7497  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7498	 (match_operand 1 "" "i"))
7499   (clobber (reg:DI 2))
7500   (clobber (match_operand 2))
7501   (use (reg:DI 27))
7502   (use (reg:DI 29))
7503   (use (const_int 1))]
7504  "TARGET_64BIT"
7505  "#")
7506
7507;; Split out the PIC register save and restore after reload.  As the
7508;; split is done after reload, there are some situations in which we
7509;; unnecessarily save and restore %r4.  This happens when there is a
7510;; single call and the PIC register is not used after the call.
7511;;
7512;; The split has to be done since call_from_call_insn () can't handle
7513;; the pattern as is.  Noreturn calls are special because they have to
7514;; terminate the basic block.  The split has to contain more than one
7515;; insn.
7516(define_split
7517  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7518		    (match_operand 1 "" ""))
7519	      (clobber (reg:DI 2))
7520	      (clobber (match_operand 2))
7521	      (use (reg:DI 27))
7522	      (use (reg:DI 29))
7523	      (use (const_int 1))])]
7524  "TARGET_64BIT && reload_completed
7525   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7526  [(set (match_dup 2) (reg:DI 27))
7527   (parallel [(call (mem:SI (match_dup 0))
7528		    (match_dup 1))
7529	      (clobber (reg:DI 2))
7530	      (use (reg:DI 27))
7531	      (use (reg:DI 29))
7532	      (use (const_int 1))])]
7533  "")
7534
7535(define_split
7536  [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7537		    (match_operand 1 "" ""))
7538	      (clobber (reg:DI 2))
7539	      (clobber (match_operand 2))
7540	      (use (reg:DI 27))
7541	      (use (reg:DI 29))
7542	      (use (const_int 1))])]
7543  "TARGET_64BIT && reload_completed"
7544  [(set (match_dup 2) (reg:DI 27))
7545   (parallel [(call (mem:SI (match_dup 0))
7546		    (match_dup 1))
7547	      (clobber (reg:DI 2))
7548	      (use (reg:DI 27))
7549	      (use (reg:DI 29))
7550	      (use (const_int 1))])
7551   (set (reg:DI 27) (match_dup 2))]
7552  "")
7553
7554(define_insn "*call_reg_64bit_post_reload"
7555  [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7556	 (match_operand 1 "" "i"))
7557   (clobber (reg:DI 2))
7558   (use (reg:DI 27))
7559   (use (reg:DI 29))
7560   (use (const_int 1))]
7561  "TARGET_64BIT"
7562  "*
7563{
7564  return pa_output_indirect_call (insn, operands[0]);
7565}"
7566  [(set_attr "type" "dyncall")
7567   (set (attr "length")
7568	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7569	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7570
7571(define_expand "call_value"
7572  [(parallel [(set (match_operand 0 "" "")
7573		   (call (match_operand:SI 1 "" "")
7574			 (match_operand 2 "" "")))
7575	      (clobber (reg:SI 2))])]
7576  ""
7577{
7578  rtx op;
7579  rtx dst = operands[0];
7580  rtx nb = operands[2];
7581  bool call_powf = false;
7582
7583  if (TARGET_PORTABLE_RUNTIME)
7584    op = force_reg (SImode, XEXP (operands[1], 0));
7585  else
7586    {
7587      op = XEXP (operands[1], 0);
7588      if (GET_CODE (op) == SYMBOL_REF)
7589	{
7590	  /* Handle special call to buggy powf function.  */
7591	  if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
7592	      && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7593	    call_powf = true;
7594
7595	  /* Generate indirect long calls to non-local functions. */
7596	  else if (!TARGET_64BIT && TARGET_LONG_CALLS)
7597	    {
7598	      tree call_decl = SYMBOL_REF_DECL (op);
7599	      if (!(call_decl && targetm.binds_local_p (call_decl)))
7600		op = force_reg (word_mode, op);
7601	    }
7602	}
7603    }
7604
7605  if (TARGET_64BIT)
7606    {
7607      if (!virtuals_instantiated)
7608	emit_move_insn (arg_pointer_rtx,
7609			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7610				      GEN_INT (64)));
7611      else
7612	{
7613	  /* The loop pass can generate new libcalls after the virtual
7614	     registers are instantiated when fpregs are disabled because
7615	     the only method that we have for doing DImode multiplication
7616	     is with a libcall.  This could be trouble if we haven't
7617	     allocated enough space for the outgoing arguments.  */
7618	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7619
7620	  emit_move_insn (arg_pointer_rtx,
7621			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7622					GEN_INT (STACK_POINTER_OFFSET + 64)));
7623	}
7624    }
7625
7626  /* Use two different patterns for calls to explicitly named functions
7627     and calls through function pointers.  This is necessary as these two
7628     types of calls use different calling conventions, and CSE might try
7629     to change the named call into an indirect call in some cases (using
7630     two patterns keeps CSE from performing this optimization).
7631
7632     We now use even more call patterns as there was a subtle bug in
7633     attempting to restore the pic register after a call using a simple
7634     move insn.  During reload, a instruction involving a pseudo register
7635     with no explicit dependence on the PIC register can be converted
7636     to an equivalent load from memory using the PIC register.  If we
7637     emit a simple move to restore the PIC register in the initial rtl
7638     generation, then it can potentially be repositioned during scheduling.
7639     and an instruction that eventually uses the PIC register may end up
7640     between the call and the PIC register restore.
7641
7642     This only worked because there is a post call group of instructions
7643     that are scheduled with the call.  These instructions are included
7644     in the same basic block as the call.  However, calls can throw in
7645     C++ code and a basic block has to terminate at the call if the call
7646     can throw.  This results in the PIC register restore being scheduled
7647     independently from the call.  So, we now hide the save and restore
7648     of the PIC register in the call pattern until after reload.  Then,
7649     we split the moves out.  A small side benefit is that we now don't
7650     need to have a use of the PIC register in the return pattern and
7651     the final save/restore operation is not needed.
7652
7653     I elected to just use register %r4 in the PIC patterns instead
7654     of trying to force hppa_pic_save_rtx () to a callee saved register.
7655     This might have required a new register class and constraint.  It
7656     was also simpler to just handle the restore from a register than a
7657     generic pseudo.  */
7658  if (TARGET_64BIT)
7659    {
7660      rtx r4 = gen_rtx_REG (word_mode, 4);
7661      if (GET_CODE (op) == SYMBOL_REF)
7662	{
7663	  if (call_powf)
7664	    emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
7665	  else
7666	    emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7667	}
7668      else
7669	{
7670	  op = force_reg (word_mode, op);
7671	  emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7672	}
7673    }
7674  else
7675    {
7676      if (GET_CODE (op) == SYMBOL_REF)
7677	{
7678	  if (flag_pic)
7679	    {
7680	      rtx r4 = gen_rtx_REG (word_mode, 4);
7681
7682	      if (call_powf)
7683		emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
7684	      else
7685		emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7686	    }
7687	  else
7688	    {
7689	      if (call_powf)
7690		emit_call_insn (gen_call_val_powf (dst, op, nb));
7691	      else
7692		emit_call_insn (gen_call_val_symref (dst, op, nb));
7693	    }
7694	}
7695      else
7696	{
7697	  rtx tmpreg = gen_rtx_REG (word_mode, 22);
7698	  emit_move_insn (tmpreg, force_reg (word_mode, op));
7699	  if (flag_pic)
7700	    {
7701	      rtx r4 = gen_rtx_REG (word_mode, 4);
7702	      emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7703	    }
7704	  else
7705	    emit_call_insn (gen_call_val_reg (dst, nb));
7706	}
7707    }
7708
7709  DONE;
7710})
7711
7712(define_insn "call_val_symref"
7713  [(set (match_operand 0 "" "")
7714	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7715	      (match_operand 2 "" "i")))
7716   (clobber (reg:SI 1))
7717   (clobber (reg:SI 2))
7718   (use (const_int 0))]
7719  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7720  "*
7721{
7722  pa_output_arg_descriptor (insn);
7723  return pa_output_call (insn, operands[1], 0);
7724}"
7725  [(set_attr "type" "call")
7726   (set (attr "length")
7727	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7728	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7729
7730;; powf function clobbers %fr12
7731(define_insn "call_val_powf"
7732  [(set (match_operand 0 "" "")
7733	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7734	      (match_operand 2 "" "i")))
7735   (clobber (reg:SI 1))
7736   (clobber (reg:SI 2))
7737   (clobber (reg:DF 48))
7738   (use (const_int 1))]
7739  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7740  "*
7741{
7742  pa_output_arg_descriptor (insn);
7743  return pa_output_call (insn, operands[1], 0);
7744}"
7745  [(set_attr "type" "call")
7746   (set (attr "length")
7747	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7748	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7749
7750(define_insn "call_val_symref_pic"
7751  [(set (match_operand 0 "" "")
7752	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7753	      (match_operand 2 "" "i")))
7754   (clobber (reg:SI 1))
7755   (clobber (reg:SI 2))
7756   (clobber (match_operand 3))
7757   (use (reg:SI 19))
7758   (use (const_int 0))]
7759  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7760  "#")
7761
7762;; Split out the PIC register save and restore after reload.  As the
7763;; split is done after reload, there are some situations in which we
7764;; unnecessarily save and restore %r4.  This happens when there is a
7765;; single call and the PIC register is not used after the call.
7766;;
7767;; The split has to be done since call_from_call_insn () can't handle
7768;; the pattern as is.  Noreturn calls are special because they have to
7769;; terminate the basic block.  The split has to contain more than one
7770;; insn.
7771(define_split
7772  [(parallel [(set (match_operand 0 "" "")
7773	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7774		    (match_operand 2 "" "")))
7775	      (clobber (reg:SI 1))
7776	      (clobber (reg:SI 2))
7777	      (clobber (match_operand 3))
7778	      (use (reg:SI 19))
7779	      (use (const_int 0))])]
7780  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7781   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7782  [(set (match_dup 3) (reg:SI 19))
7783   (parallel [(set (match_dup 0)
7784	      (call (mem:SI (match_dup 1))
7785		    (match_dup 2)))
7786	      (clobber (reg:SI 1))
7787	      (clobber (reg:SI 2))
7788	      (use (reg:SI 19))
7789	      (use (const_int 0))])]
7790  "")
7791
7792(define_split
7793  [(parallel [(set (match_operand 0 "" "")
7794	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7795		    (match_operand 2 "" "")))
7796	      (clobber (reg:SI 1))
7797	      (clobber (reg:SI 2))
7798	      (clobber (match_operand 3))
7799	      (use (reg:SI 19))
7800	      (use (const_int 0))])]
7801  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7802  [(set (match_dup 3) (reg:SI 19))
7803   (parallel [(set (match_dup 0)
7804	      (call (mem:SI (match_dup 1))
7805		    (match_dup 2)))
7806	      (clobber (reg:SI 1))
7807	      (clobber (reg:SI 2))
7808	      (use (reg:SI 19))
7809	      (use (const_int 0))])
7810   (set (reg:SI 19) (match_dup 3))]
7811  "")
7812
7813(define_insn "*call_val_symref_pic_post_reload"
7814  [(set (match_operand 0 "" "")
7815	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7816	      (match_operand 2 "" "i")))
7817   (clobber (reg:SI 1))
7818   (clobber (reg:SI 2))
7819   (use (reg:SI 19))
7820   (use (const_int 0))]
7821  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7822  "*
7823{
7824  pa_output_arg_descriptor (insn);
7825  return pa_output_call (insn, operands[1], 0);
7826}"
7827  [(set_attr "type" "call")
7828   (set (attr "length")
7829	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7830	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7831
7832;; powf function clobbers %fr12
7833(define_insn "call_val_powf_pic"
7834  [(set (match_operand 0 "" "")
7835	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7836	      (match_operand 2 "" "i")))
7837   (clobber (reg:SI 1))
7838   (clobber (reg:SI 2))
7839   (clobber (reg:DF 48))
7840   (clobber (match_operand 3))
7841   (use (reg:SI 19))
7842   (use (const_int 1))]
7843  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7844  "#")
7845
7846;; Split out the PIC register save and restore after reload.  As the
7847;; split is done after reload, there are some situations in which we
7848;; unnecessarily save and restore %r4.  This happens when there is a
7849;; single call and the PIC register is not used after the call.
7850;;
7851;; The split has to be done since call_from_call_insn () can't handle
7852;; the pattern as is.  Noreturn calls are special because they have to
7853;; terminate the basic block.  The split has to contain more than one
7854;; insn.
7855(define_split
7856  [(parallel [(set (match_operand 0 "" "")
7857	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7858		    (match_operand 2 "" "")))
7859	      (clobber (reg:SI 1))
7860	      (clobber (reg:SI 2))
7861	      (clobber (reg:DF 48))
7862	      (clobber (match_operand 3))
7863	      (use (reg:SI 19))
7864	      (use (const_int 1))])]
7865  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7866   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7867  [(set (match_dup 3) (reg:SI 19))
7868   (parallel [(set (match_dup 0)
7869	      (call (mem:SI (match_dup 1))
7870		    (match_dup 2)))
7871	      (clobber (reg:SI 1))
7872	      (clobber (reg:SI 2))
7873	      (clobber (reg:DF 48))
7874	      (use (reg:SI 19))
7875	      (use (const_int 1))])]
7876  "")
7877
7878(define_split
7879  [(parallel [(set (match_operand 0 "" "")
7880	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7881		    (match_operand 2 "" "")))
7882	      (clobber (reg:SI 1))
7883	      (clobber (reg:SI 2))
7884	      (clobber (reg:DF 48))
7885	      (clobber (match_operand 3))
7886	      (use (reg:SI 19))
7887	      (use (const_int 1))])]
7888  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7889  [(set (match_dup 3) (reg:SI 19))
7890   (parallel [(set (match_dup 0)
7891	      (call (mem:SI (match_dup 1))
7892		    (match_dup 2)))
7893	      (clobber (reg:SI 1))
7894	      (clobber (reg:SI 2))
7895	      (clobber (reg:DF 48))
7896	      (use (reg:SI 19))
7897	      (use (const_int 1))])
7898   (set (reg:SI 19) (match_dup 3))]
7899  "")
7900
7901(define_insn "*call_val_powf_pic_post_reload"
7902  [(set (match_operand 0 "" "")
7903	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7904	      (match_operand 2 "" "i")))
7905   (clobber (reg:SI 1))
7906   (clobber (reg:SI 2))
7907   (clobber (reg:DF 48))
7908   (use (reg:SI 19))
7909   (use (const_int 1))]
7910  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7911  "*
7912{
7913  pa_output_arg_descriptor (insn);
7914  return pa_output_call (insn, operands[1], 0);
7915}"
7916  [(set_attr "type" "call")
7917   (set (attr "length")
7918	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7919	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
7920
7921;; This pattern is split if it is necessary to save and restore the
7922;; PIC register.
7923(define_insn "call_val_symref_64bit"
7924  [(set (match_operand 0 "" "")
7925	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7926	      (match_operand 2 "" "i")))
7927   (clobber (reg:DI 1))
7928   (clobber (reg:DI 2))
7929   (clobber (match_operand 3))
7930   (use (reg:DI 27))
7931   (use (reg:DI 29))
7932   (use (const_int 0))]
7933  "TARGET_64BIT"
7934  "#")
7935
7936;; Split out the PIC register save and restore after reload.  As the
7937;; split is done after reload, there are some situations in which we
7938;; unnecessarily save and restore %r4.  This happens when there is a
7939;; single call and the PIC register is not used after the call.
7940;;
7941;; The split has to be done since call_from_call_insn () can't handle
7942;; the pattern as is.  Noreturn calls are special because they have to
7943;; terminate the basic block.  The split has to contain more than one
7944;; insn.
7945(define_split
7946  [(parallel [(set (match_operand 0 "" "")
7947	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7948		    (match_operand 2 "" "")))
7949	      (clobber (reg:DI 1))
7950	      (clobber (reg:DI 2))
7951	      (clobber (match_operand 3))
7952	      (use (reg:DI 27))
7953	      (use (reg:DI 29))
7954	      (use (const_int 0))])]
7955  "TARGET_64BIT && reload_completed
7956   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7957  [(set (match_dup 3) (reg:DI 27))
7958   (parallel [(set (match_dup 0)
7959	      (call (mem:SI (match_dup 1))
7960		    (match_dup 2)))
7961	      (clobber (reg:DI 1))
7962	      (clobber (reg:DI 2))
7963	      (use (reg:DI 27))
7964	      (use (reg:DI 29))
7965	      (use (const_int 0))])]
7966  "")
7967
7968(define_split
7969  [(parallel [(set (match_operand 0 "" "")
7970	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
7971		    (match_operand 2 "" "")))
7972	      (clobber (reg:DI 1))
7973	      (clobber (reg:DI 2))
7974	      (clobber (match_operand 3))
7975	      (use (reg:DI 27))
7976	      (use (reg:DI 29))
7977	      (use (const_int 0))])]
7978  "TARGET_64BIT && reload_completed"
7979  [(set (match_dup 3) (reg:DI 27))
7980   (parallel [(set (match_dup 0)
7981	      (call (mem:SI (match_dup 1))
7982		    (match_dup 2)))
7983	      (clobber (reg:DI 1))
7984	      (clobber (reg:DI 2))
7985	      (use (reg:DI 27))
7986	      (use (reg:DI 29))
7987	      (use (const_int 0))])
7988   (set (reg:DI 27) (match_dup 3))]
7989  "")
7990
7991(define_insn "*call_val_symref_64bit_post_reload"
7992  [(set (match_operand 0 "" "")
7993	(call (mem:SI (match_operand 1 "call_operand_address" ""))
7994	      (match_operand 2 "" "i")))
7995   (clobber (reg:DI 1))
7996   (clobber (reg:DI 2))
7997   (use (reg:DI 27))
7998   (use (reg:DI 29))
7999   (use (const_int 0))]
8000  "TARGET_64BIT"
8001  "*
8002{
8003  pa_output_arg_descriptor (insn);
8004  return pa_output_call (insn, operands[1], 0);
8005}"
8006  [(set_attr "type" "call")
8007   (set (attr "length")
8008	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8009	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8010
8011;; powf function clobbers %fr12
8012(define_insn "call_val_powf_64bit"
8013  [(set (match_operand 0 "" "")
8014	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8015	      (match_operand 2 "" "i")))
8016   (clobber (reg:DI 1))
8017   (clobber (reg:DI 2))
8018   (clobber (reg:DF 40))
8019   (clobber (match_operand 3))
8020   (use (reg:DI 27))
8021   (use (reg:DI 29))
8022   (use (const_int 1))]
8023  "TARGET_64BIT && TARGET_HPUX"
8024  "#")
8025
8026;; Split out the PIC register save and restore after reload.  As the
8027;; split is done after reload, there are some situations in which we
8028;; unnecessarily save and restore %r4.  This happens when there is a
8029;; single call and the PIC register is not used after the call.
8030;;
8031;; The split has to be done since call_from_call_insn () can't handle
8032;; the pattern as is.  Noreturn calls are special because they have to
8033;; terminate the basic block.  The split has to contain more than one
8034;; insn.
8035(define_split
8036  [(parallel [(set (match_operand 0 "" "")
8037	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8038		    (match_operand 2 "" "")))
8039	      (clobber (reg:DI 1))
8040	      (clobber (reg:DI 2))
8041	      (clobber (reg:DF 40))
8042	      (clobber (match_operand 3))
8043	      (use (reg:DI 27))
8044	      (use (reg:DI 29))
8045	      (use (const_int 1))])]
8046  "TARGET_64BIT && TARGET_HPUX && reload_completed
8047   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8048  [(set (match_dup 3) (reg:DI 27))
8049   (parallel [(set (match_dup 0)
8050	      (call (mem:SI (match_dup 1))
8051		    (match_dup 2)))
8052	      (clobber (reg:DI 1))
8053	      (clobber (reg:DI 2))
8054	      (clobber (reg:DF 40))
8055	      (use (reg:DI 27))
8056	      (use (reg:DI 29))
8057	      (use (const_int 1))])]
8058  "")
8059
8060(define_split
8061  [(parallel [(set (match_operand 0 "" "")
8062	      (call (mem:SI (match_operand 1 "call_operand_address" ""))
8063		    (match_operand 2 "" "")))
8064	      (clobber (reg:DI 1))
8065	      (clobber (reg:DI 2))
8066	      (clobber (reg:DF 40))
8067	      (clobber (match_operand 3))
8068	      (use (reg:DI 27))
8069	      (use (reg:DI 29))
8070	      (use (const_int 1))])]
8071  "TARGET_64BIT && TARGET_HPUX && reload_completed"
8072  [(set (match_dup 3) (reg:DI 27))
8073   (parallel [(set (match_dup 0)
8074	      (call (mem:SI (match_dup 1))
8075		    (match_dup 2)))
8076	      (clobber (reg:DI 1))
8077	      (clobber (reg:DI 2))
8078	      (clobber (reg:DF 40))
8079	      (use (reg:DI 27))
8080	      (use (reg:DI 29))
8081	      (use (const_int 1))])
8082   (set (reg:DI 27) (match_dup 3))]
8083  "")
8084
8085(define_insn "*call_val_powf_64bit_post_reload"
8086  [(set (match_operand 0 "" "")
8087	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8088	      (match_operand 2 "" "i")))
8089   (clobber (reg:DI 1))
8090   (clobber (reg:DI 2))
8091   (clobber (reg:DF 40))
8092   (use (reg:DI 27))
8093   (use (reg:DI 29))
8094   (use (const_int 1))]
8095  "TARGET_64BIT && TARGET_HPUX"
8096  "*
8097{
8098  pa_output_arg_descriptor (insn);
8099  return pa_output_call (insn, operands[1], 0);
8100}"
8101  [(set_attr "type" "call")
8102   (set (attr "length")
8103	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8104	      (symbol_ref "pa_attr_length_call (insn, 0)")))])
8105
8106(define_insn "call_val_reg"
8107  [(set (match_operand 0 "" "")
8108	(call (mem:SI (reg:SI 22))
8109	      (match_operand 1 "" "i")))
8110   (clobber (reg:SI 1))
8111   (clobber (reg:SI 2))
8112   (use (const_int 1))]
8113  "!TARGET_64BIT"
8114  "*
8115{
8116  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8117}"
8118  [(set_attr "type" "dyncall")
8119   (set (attr "length")
8120	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8121	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8122
8123;; This pattern is split if it is necessary to save and restore the
8124;; PIC register.
8125(define_insn "call_val_reg_pic"
8126  [(set (match_operand 0 "" "")
8127	(call (mem:SI (reg:SI 22))
8128	      (match_operand 1 "" "i")))
8129   (clobber (reg:SI 1))
8130   (clobber (reg:SI 2))
8131   (clobber (match_operand 2))
8132   (use (reg:SI 19))
8133   (use (const_int 1))]
8134  "!TARGET_64BIT"
8135  "#")
8136
8137;; Split out the PIC register save and restore after reload.  As the
8138;; split is done after reload, there are some situations in which we
8139;; unnecessarily save and restore %r4.  This happens when there is a
8140;; single call and the PIC register is not used after the call.
8141;;
8142;; The split has to be done since call_from_call_insn () can't handle
8143;; the pattern as is.  Noreturn calls are special because they have to
8144;; terminate the basic block.  The split has to contain more than one
8145;; insn.
8146(define_split
8147  [(parallel [(set (match_operand 0 "" "")
8148		   (call (mem:SI (reg:SI 22))
8149			 (match_operand 1 "" "")))
8150	      (clobber (reg:SI 1))
8151	      (clobber (reg:SI 2))
8152	      (clobber (match_operand 2))
8153	      (use (reg:SI 19))
8154	      (use (const_int 1))])]
8155  "!TARGET_64BIT && reload_completed
8156   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8157  [(set (match_dup 2) (reg:SI 19))
8158   (parallel [(set (match_dup 0)
8159		   (call (mem:SI (reg:SI 22))
8160			 (match_dup 1)))
8161	      (clobber (reg:SI 1))
8162	      (clobber (reg:SI 2))
8163	      (use (reg:SI 19))
8164	      (use (const_int 1))])]
8165  "")
8166
8167(define_split
8168  [(parallel [(set (match_operand 0 "" "")
8169		   (call (mem:SI (reg:SI 22))
8170			 (match_operand 1 "" "")))
8171	      (clobber (reg:SI 1))
8172	      (clobber (reg:SI 2))
8173	      (clobber (match_operand 2))
8174	      (use (reg:SI 19))
8175	      (use (const_int 1))])]
8176  "!TARGET_64BIT && reload_completed"
8177  [(set (match_dup 2) (reg:SI 19))
8178   (parallel [(set (match_dup 0)
8179		   (call (mem:SI (reg:SI 22))
8180			 (match_dup 1)))
8181	      (clobber (reg:SI 1))
8182	      (clobber (reg:SI 2))
8183	      (use (reg:SI 19))
8184	      (use (const_int 1))])
8185   (set (reg:SI 19) (match_dup 2))]
8186  "")
8187
8188(define_insn "*call_val_reg_pic_post_reload"
8189  [(set (match_operand 0 "" "")
8190	(call (mem:SI (reg:SI 22))
8191	      (match_operand 1 "" "i")))
8192   (clobber (reg:SI 1))
8193   (clobber (reg:SI 2))
8194   (use (reg:SI 19))
8195   (use (const_int 1))]
8196  "!TARGET_64BIT"
8197  "*
8198{
8199  return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8200}"
8201  [(set_attr "type" "dyncall")
8202   (set (attr "length")
8203	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8204	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8205
8206;; This pattern is split if it is necessary to save and restore the
8207;; PIC register.
8208(define_insn "call_val_reg_64bit"
8209  [(set (match_operand 0 "" "")
8210	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8211	      (match_operand 2 "" "i")))
8212   (clobber (reg:DI 1))
8213   (clobber (reg:DI 2))
8214   (clobber (match_operand 3))
8215   (use (reg:DI 27))
8216   (use (reg:DI 29))
8217   (use (const_int 1))]
8218  "TARGET_64BIT"
8219  "#")
8220
8221;; Split out the PIC register save and restore after reload.  As the
8222;; split is done after reload, there are some situations in which we
8223;; unnecessarily save and restore %r4.  This happens when there is a
8224;; single call and the PIC register is not used after the call.
8225;;
8226;; The split has to be done since call_from_call_insn () can't handle
8227;; the pattern as is.  Noreturn calls are special because they have to
8228;; terminate the basic block.  The split has to contain more than one
8229;; insn.
8230(define_split
8231  [(parallel [(set (match_operand 0 "" "")
8232		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8233			 (match_operand 2 "" "")))
8234	      (clobber (reg:DI 1))
8235	      (clobber (reg:DI 2))
8236	      (clobber (match_operand 3))
8237	      (use (reg:DI 27))
8238	      (use (reg:DI 29))
8239	      (use (const_int 1))])]
8240  "TARGET_64BIT && reload_completed
8241   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8242  [(set (match_dup 3) (reg:DI 27))
8243   (parallel [(set (match_dup 0)
8244		   (call (mem:SI (match_dup 1))
8245			 (match_dup 2)))
8246	      (clobber (reg:DI 1))
8247	      (clobber (reg:DI 2))
8248	      (use (reg:DI 27))
8249	      (use (reg:DI 29))
8250	      (use (const_int 1))])]
8251  "")
8252
8253(define_split
8254  [(parallel [(set (match_operand 0 "" "")
8255		   (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8256			 (match_operand 2 "" "")))
8257	      (clobber (reg:DI 1))
8258	      (clobber (reg:DI 2))
8259	      (clobber (match_operand 3))
8260	      (use (reg:DI 27))
8261	      (use (reg:DI 29))
8262	      (use (const_int 1))])]
8263  "TARGET_64BIT && reload_completed"
8264  [(set (match_dup 3) (reg:DI 27))
8265   (parallel [(set (match_dup 0)
8266		   (call (mem:SI (match_dup 1))
8267			 (match_dup 2)))
8268	      (clobber (reg:DI 1))
8269	      (clobber (reg:DI 2))
8270	      (use (reg:DI 27))
8271	      (use (reg:DI 29))
8272	      (use (const_int 1))])
8273   (set (reg:DI 27) (match_dup 3))]
8274  "")
8275
8276(define_insn "*call_val_reg_64bit_post_reload"
8277  [(set (match_operand 0 "" "")
8278	(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8279	      (match_operand 2 "" "i")))
8280   (clobber (reg:DI 1))
8281   (clobber (reg:DI 2))
8282   (use (reg:DI 27))
8283   (use (reg:DI 29))
8284   (use (const_int 1))]
8285  "TARGET_64BIT"
8286  "*
8287{
8288  return pa_output_indirect_call (insn, operands[1]);
8289}"
8290  [(set_attr "type" "dyncall")
8291   (set (attr "length")
8292	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8293	      (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8294
8295;; Call subroutine returning any type.
8296
8297(define_expand "untyped_call"
8298  [(parallel [(call (match_operand 0 "" "")
8299		    (const_int 0))
8300	      (match_operand 1 "" "")
8301	      (match_operand 2 "" "")])]
8302  ""
8303  "
8304{
8305  int i;
8306
8307  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
8308
8309  for (i = 0; i < XVECLEN (operands[2], 0); i++)
8310    {
8311      rtx set = XVECEXP (operands[2], 0, i);
8312      emit_move_insn (SET_DEST (set), SET_SRC (set));
8313    }
8314
8315  /* The optimizer does not know that the call sets the function value
8316     registers we stored in the result block.  We avoid problems by
8317     claiming that all hard registers are used and clobbered at this
8318     point.  */
8319  emit_insn (gen_blockage ());
8320
8321  DONE;
8322}")
8323
8324(define_expand "sibcall"
8325  [(call (match_operand:SI 0 "" "")
8326	 (match_operand 1 "" ""))]
8327  "!TARGET_PORTABLE_RUNTIME"
8328  "
8329{
8330  rtx op, call_insn;
8331  rtx nb = operands[1];
8332
8333  op = XEXP (operands[0], 0);
8334
8335  if (TARGET_64BIT)
8336    {
8337      if (!virtuals_instantiated)
8338	emit_move_insn (arg_pointer_rtx,
8339			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8340				      GEN_INT (64)));
8341      else
8342	{
8343	  /* The loop pass can generate new libcalls after the virtual
8344	     registers are instantiated when fpregs are disabled because
8345	     the only method that we have for doing DImode multiplication
8346	     is with a libcall.  This could be trouble if we haven't
8347	     allocated enough space for the outgoing arguments.  */
8348	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8349
8350	  emit_move_insn (arg_pointer_rtx,
8351			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8352					GEN_INT (STACK_POINTER_OFFSET + 64)));
8353	}
8354    }
8355
8356  /* Indirect sibling calls are not allowed.  */
8357  if (TARGET_64BIT)
8358    call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8359  else
8360    call_insn = gen_sibcall_internal_symref (op, operands[1]);
8361
8362  call_insn = emit_call_insn (call_insn);
8363
8364  if (TARGET_64BIT)
8365    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8366
8367  /* We don't have to restore the PIC register.  */
8368  if (flag_pic)
8369    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8370
8371  DONE;
8372}")
8373
8374(define_insn "sibcall_internal_symref"
8375  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8376	 (match_operand 1 "" "i"))
8377   (clobber (reg:SI 1))
8378   (use (reg:SI 2))
8379   (use (const_int 0))]
8380  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8381  "*
8382{
8383  pa_output_arg_descriptor (insn);
8384  return pa_output_call (insn, operands[0], 1);
8385}"
8386  [(set_attr "type" "sibcall")
8387   (set (attr "length")
8388	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8389	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8390
8391(define_insn "sibcall_internal_symref_64bit"
8392  [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8393	 (match_operand 1 "" "i"))
8394   (clobber (reg:DI 1))
8395   (use (reg:DI 2))
8396   (use (const_int 0))]
8397  "TARGET_64BIT"
8398  "*
8399{
8400  pa_output_arg_descriptor (insn);
8401  return pa_output_call (insn, operands[0], 1);
8402}"
8403  [(set_attr "type" "sibcall")
8404   (set (attr "length")
8405	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8406	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8407
8408(define_expand "sibcall_value"
8409  [(set (match_operand 0 "" "")
8410		   (call (match_operand:SI 1 "" "")
8411			 (match_operand 2 "" "")))]
8412  "!TARGET_PORTABLE_RUNTIME"
8413  "
8414{
8415  rtx op, call_insn;
8416  rtx nb = operands[1];
8417
8418  op = XEXP (operands[1], 0);
8419
8420  if (TARGET_64BIT)
8421    {
8422      if (!virtuals_instantiated)
8423	emit_move_insn (arg_pointer_rtx,
8424			gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8425				      GEN_INT (64)));
8426      else
8427	{
8428	  /* The loop pass can generate new libcalls after the virtual
8429	     registers are instantiated when fpregs are disabled because
8430	     the only method that we have for doing DImode multiplication
8431	     is with a libcall.  This could be trouble if we haven't
8432	     allocated enough space for the outgoing arguments.  */
8433	  gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8434
8435	  emit_move_insn (arg_pointer_rtx,
8436			  gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8437					GEN_INT (STACK_POINTER_OFFSET + 64)));
8438	}
8439    }
8440
8441  /* Indirect sibling calls are not allowed.  */
8442  if (TARGET_64BIT)
8443    call_insn
8444      = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8445  else
8446    call_insn
8447      = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8448
8449  call_insn = emit_call_insn (call_insn);
8450
8451  if (TARGET_64BIT)
8452    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8453
8454  /* We don't have to restore the PIC register.  */
8455  if (flag_pic)
8456    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8457
8458  DONE;
8459}")
8460
8461(define_insn "sibcall_value_internal_symref"
8462  [(set (match_operand 0 "" "")
8463	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8464	      (match_operand 2 "" "i")))
8465   (clobber (reg:SI 1))
8466   (use (reg:SI 2))
8467   (use (const_int 0))]
8468  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8469  "*
8470{
8471  pa_output_arg_descriptor (insn);
8472  return pa_output_call (insn, operands[1], 1);
8473}"
8474  [(set_attr "type" "sibcall")
8475   (set (attr "length")
8476	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8477	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8478
8479(define_insn "sibcall_value_internal_symref_64bit"
8480  [(set (match_operand 0 "" "")
8481	(call (mem:SI (match_operand 1 "call_operand_address" ""))
8482	      (match_operand 2 "" "i")))
8483   (clobber (reg:DI 1))
8484   (use (reg:DI 2))
8485   (use (const_int 0))]
8486  "TARGET_64BIT"
8487  "*
8488{
8489  pa_output_arg_descriptor (insn);
8490  return pa_output_call (insn, operands[1], 1);
8491}"
8492  [(set_attr "type" "sibcall")
8493   (set (attr "length")
8494	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8495	      (symbol_ref "pa_attr_length_call (insn, 1)")))])
8496
8497(define_insn "nop"
8498  [(const_int 0)]
8499  ""
8500  "nop"
8501  [(set_attr "type" "move")
8502   (set_attr "length" "4")])
8503
8504;;; EH does longjmp's from and within the data section.  Thus,
8505;;; an interspace branch is required for the longjmp implementation.
8506;;; Registers r1 and r2 are used as scratch registers for the jump
8507;;; when necessary.
8508(define_expand "interspace_jump"
8509  [(parallel
8510     [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8511      (clobber (match_dup 1))])]
8512  ""
8513  "
8514{
8515  operands[1] = gen_rtx_REG (word_mode, 2);
8516}")
8517
8518(define_insn ""
8519  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8520  (clobber (reg:SI 2))]
8521  "TARGET_PA_20 && !TARGET_64BIT"
8522  "bve%* (%0)"
8523   [(set_attr "type" "branch")
8524    (set_attr "length" "4")])
8525
8526(define_insn ""
8527  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8528  (clobber (reg:SI 2))]
8529  "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8530  "be%* 0(%%sr4,%0)"
8531   [(set_attr "type" "branch")
8532    (set_attr "length" "4")])
8533
8534(define_insn ""
8535  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8536  (clobber (reg:SI 2))]
8537  "!TARGET_64BIT"
8538  "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8539   [(set_attr "type" "branch")
8540    (set_attr "length" "12")])
8541
8542(define_insn ""
8543  [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8544  (clobber (reg:DI 2))]
8545  "TARGET_64BIT"
8546  "bve%* (%0)"
8547   [(set_attr "type" "branch")
8548    (set_attr "length" "4")])
8549
8550(define_expand "builtin_longjmp"
8551  [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8552  ""
8553  "
8554{
8555  /* The elements of the buffer are, in order:  */
8556  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8557  rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8558			 POINTER_SIZE / BITS_PER_UNIT));
8559  rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8560			   (POINTER_SIZE * 2) / BITS_PER_UNIT));
8561  rtx pv = gen_rtx_REG (Pmode, 1);
8562
8563  emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8564  emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8565
8566  /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
8567     instead of the hard_frame_pointer_rtx in the save area.  We need
8568     to adjust for the offset between these two values.  */
8569  if (GET_CODE (fp) != REG)
8570    fp = force_reg (Pmode, fp);
8571  emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
8572
8573  /* This bit is the same as expand_builtin_longjmp.  */
8574  emit_stack_restore (SAVE_NONLOCAL, stack);
8575  emit_use (hard_frame_pointer_rtx);
8576  emit_use (stack_pointer_rtx);
8577
8578  /* Load the label we are jumping through into r1 so that we know
8579     where to look for it when we get back to setjmp's function for
8580     restoring the gp.  */
8581  emit_move_insn (pv, lab);
8582
8583  /* Prevent the insns above from being scheduled into the delay slot
8584     of the interspace jump because the space register could change.  */
8585  emit_insn (gen_blockage ());
8586
8587  emit_jump_insn (gen_interspace_jump (pv));
8588  emit_barrier ();
8589  DONE;
8590}")
8591
8592;;; Operands 2 and 3 are assumed to be CONST_INTs.
8593(define_expand "extzvsi"
8594  [(set (match_operand:SI 0 "register_operand" "")
8595	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
8596			 (match_operand:SI 2 "uint5_operand" "")
8597			 (match_operand:SI 3 "uint5_operand" "")))]
8598  ""
8599  "
8600{
8601  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8602  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8603
8604  /* PA extraction insns don't support zero length bitfields or fields
8605     extending beyond the left or right-most bits.  Also, the predicate
8606     rejects lengths equal to a word as they are better handled by
8607     the move patterns.  */
8608  if (len == 0 || pos + len > 32)
8609    FAIL;
8610
8611  /* From mips.md: extract_bit_field doesn't verify that our source
8612     matches the predicate, so check it again here.  */
8613  if (!register_operand (operands[1], VOIDmode))
8614    FAIL;
8615
8616  emit_insn (gen_extzv_32 (operands[0], operands[1],
8617			   operands[2], operands[3]));
8618  DONE;
8619}")
8620
8621(define_insn "extzv_32"
8622  [(set (match_operand:SI 0 "register_operand" "=r")
8623	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8624			 (match_operand:SI 2 "uint5_operand" "")
8625			 (match_operand:SI 3 "uint5_operand" "")))]
8626  "UINTVAL (operands[2]) > 0
8627   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
8628  "{extru|extrw,u} %1,%3+%2-1,%2,%0"
8629  [(set_attr "type" "shift")
8630   (set_attr "length" "4")])
8631
8632(define_insn ""
8633  [(set (match_operand:SI 0 "register_operand" "=r")
8634	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8635			 (const_int 1)
8636			 (match_operand:SI 2 "register_operand" "q")))]
8637  ""
8638  "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
8639  [(set_attr "type" "shift")
8640   (set_attr "length" "4")])
8641
8642(define_expand "extzvdi"
8643  [(set (match_operand:DI 0 "register_operand" "")
8644	(zero_extract:DI (match_operand:DI 1 "register_operand" "")
8645			 (match_operand:DI 2 "uint6_operand" "")
8646			 (match_operand:DI 3 "uint6_operand" "")))]
8647  "TARGET_64BIT"
8648  "
8649{
8650  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8651  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8652
8653  /* PA extraction insns don't support zero length bitfields or fields
8654     extending beyond the left or right-most bits.  Also, the predicate
8655     rejects lengths equal to a doubleword as they are better handled by
8656     the move patterns.  */
8657  if (len == 0 || pos + len > 64)
8658    FAIL;
8659
8660  /* From mips.md: extract_bit_field doesn't verify that our source
8661     matches the predicate, so check it again here.  */
8662  if (!register_operand (operands[1], VOIDmode))
8663    FAIL;
8664
8665  emit_insn (gen_extzv_64 (operands[0], operands[1],
8666			   operands[2], operands[3]));
8667  DONE;
8668}")
8669
8670(define_insn "extzv_64"
8671  [(set (match_operand:DI 0 "register_operand" "=r")
8672	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8673			 (match_operand:DI 2 "uint6_operand" "")
8674			 (match_operand:DI 3 "uint6_operand" "")))]
8675  "TARGET_64BIT
8676   && UINTVAL (operands[2]) > 0
8677   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
8678  "extrd,u %1,%3+%2-1,%2,%0"
8679  [(set_attr "type" "shift")
8680   (set_attr "length" "4")])
8681
8682(define_insn ""
8683  [(set (match_operand:DI 0 "register_operand" "=r")
8684	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8685			 (const_int 1)
8686			 (match_operand:DI 2 "register_operand" "q")))]
8687  "TARGET_64BIT"
8688  "extrd,u %1,%%sar,1,%0"
8689  [(set_attr "type" "shift")
8690   (set_attr "length" "4")])
8691
8692;;; Operands 2 and 3 are assumed to be CONST_INTs.
8693(define_expand "extvsi"
8694  [(set (match_operand:SI 0 "register_operand" "")
8695	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
8696			 (match_operand:SI 2 "uint5_operand" "")
8697			 (match_operand:SI 3 "uint5_operand" "")))]
8698  ""
8699  "
8700{
8701  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8702  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8703
8704  /* PA extraction insns don't support zero length bitfields or fields
8705     extending beyond the left or right-most bits.  Also, the predicate
8706     rejects lengths equal to a word as they are better handled by
8707     the move patterns.  */
8708  if (len == 0 || pos + len > 32)
8709    FAIL;
8710
8711  /* From mips.md: extract_bit_field doesn't verify that our source
8712     matches the predicate, so check it again here.  */
8713  if (!register_operand (operands[1], VOIDmode))
8714    FAIL;
8715
8716  emit_insn (gen_extv_32 (operands[0], operands[1],
8717			  operands[2], operands[3]));
8718  DONE;
8719}")
8720
8721(define_insn "extv_32"
8722  [(set (match_operand:SI 0 "register_operand" "=r")
8723	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8724			 (match_operand:SI 2 "uint5_operand" "")
8725			 (match_operand:SI 3 "uint5_operand" "")))]
8726  "UINTVAL (operands[2]) > 0
8727   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
8728  "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
8729  [(set_attr "type" "shift")
8730   (set_attr "length" "4")])
8731
8732(define_insn ""
8733  [(set (match_operand:SI 0 "register_operand" "=r")
8734	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8735			 (const_int 1)
8736			 (match_operand:SI 2 "register_operand" "q")))]
8737  "!TARGET_64BIT"
8738  "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
8739  [(set_attr "type" "shift")
8740   (set_attr "length" "4")])
8741
8742(define_expand "extvdi"
8743  [(set (match_operand:DI 0 "register_operand" "")
8744	(sign_extract:DI (match_operand:DI 1 "register_operand" "")
8745			 (match_operand:DI 2 "uint6_operand" "")
8746			 (match_operand:DI 3 "uint6_operand" "")))]
8747  "TARGET_64BIT"
8748  "
8749{
8750  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8751  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8752
8753  /* PA extraction insns don't support zero length bitfields or fields
8754     extending beyond the left or right-most bits.  Also, the predicate
8755     rejects lengths equal to a doubleword as they are better handled by
8756     the move patterns.  */
8757  if (len == 0 || pos + len > 64)
8758    FAIL;
8759
8760  /* From mips.md: extract_bit_field doesn't verify that our source
8761     matches the predicate, so check it again here.  */
8762  if (!register_operand (operands[1], VOIDmode))
8763    FAIL;
8764
8765  emit_insn (gen_extv_64 (operands[0], operands[1],
8766			  operands[2], operands[3]));
8767  DONE;
8768}")
8769
8770(define_insn "extv_64"
8771  [(set (match_operand:DI 0 "register_operand" "=r")
8772	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8773			 (match_operand:DI 2 "uint6_operand" "")
8774			 (match_operand:DI 3 "uint6_operand" "")))]
8775  "TARGET_64BIT
8776   && UINTVAL (operands[2]) > 0
8777   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
8778  "extrd,s %1,%3+%2-1,%2,%0"
8779  [(set_attr "type" "shift")
8780   (set_attr "length" "4")])
8781
8782(define_insn ""
8783  [(set (match_operand:DI 0 "register_operand" "=r")
8784	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8785			 (const_int 1)
8786			 (match_operand:DI 2 "register_operand" "q")))]
8787  "TARGET_64BIT"
8788  "extrd,s %1,%%sar,1,%0"
8789  [(set_attr "type" "shift")
8790   (set_attr "length" "4")])
8791
8792;;; Operands 1 and 2 are assumed to be CONST_INTs.
8793(define_expand "insvsi"
8794  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
8795			 (match_operand:SI 1 "uint5_operand" "")
8796			 (match_operand:SI 2 "uint5_operand" ""))
8797	(match_operand:SI 3 "arith5_operand" ""))]
8798  ""
8799  "
8800{
8801  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
8802  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
8803
8804  /* PA insertion insns don't support zero length bitfields or fields
8805     extending beyond the left or right-most bits.  Also, the predicate
8806     rejects lengths equal to a word as they are better handled by
8807     the move patterns.  */
8808  if (len <= 0 || pos + len > 32)
8809    FAIL;
8810
8811  /* From mips.md: insert_bit_field doesn't verify that our destination
8812     matches the predicate, so check it again here.  */
8813  if (!register_operand (operands[0], VOIDmode))
8814    FAIL;
8815
8816  emit_insn (gen_insv_32 (operands[0], operands[1],
8817			  operands[2], operands[3]));
8818  DONE;
8819}")
8820
8821(define_insn "insv_32"
8822  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
8823			 (match_operand:SI 1 "uint5_operand" "")
8824			 (match_operand:SI 2 "uint5_operand" ""))
8825	(match_operand:SI 3 "arith5_operand" "r,L"))]
8826  "UINTVAL (operands[1]) > 0
8827   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
8828  "@
8829   {dep|depw} %3,%2+%1-1,%1,%0
8830   {depi|depwi} %3,%2+%1-1,%1,%0"
8831  [(set_attr "type" "shift,shift")
8832   (set_attr "length" "4,4")])
8833
8834;; Optimize insertion of const_int values of type 1...1xxxx.
8835(define_insn ""
8836  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
8837			 (match_operand:SI 1 "uint5_operand" "")
8838			 (match_operand:SI 2 "uint5_operand" ""))
8839	(match_operand:SI 3 "const_int_operand" ""))]
8840  "(INTVAL (operands[3]) & 0x10) != 0 &&
8841   (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8842  "*
8843{
8844  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8845  return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
8846}"
8847  [(set_attr "type" "shift")
8848   (set_attr "length" "4")])
8849
8850(define_expand "insvdi"
8851  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
8852			 (match_operand:DI 1 "uint6_operand" "")
8853			 (match_operand:DI 2 "uint6_operand" ""))
8854	(match_operand:DI 3 "arith5_operand" ""))]
8855  "TARGET_64BIT"
8856  "
8857{
8858  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
8859  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
8860
8861  /* PA insertion insns don't support zero length bitfields or fields
8862     extending beyond the left or right-most bits.  Also, the predicate
8863     rejects lengths equal to a doubleword as they are better handled by
8864     the move patterns.  */
8865  if (len <= 0 || pos + len > 64)
8866    FAIL;
8867
8868  /* From mips.md: insert_bit_field doesn't verify that our destination
8869     matches the predicate, so check it again here.  */
8870  if (!register_operand (operands[0], VOIDmode))
8871    FAIL;
8872
8873  emit_insn (gen_insv_64 (operands[0], operands[1],
8874			  operands[2], operands[3]));
8875  DONE;
8876}")
8877
8878(define_insn "insv_64"
8879  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
8880			 (match_operand:DI 1 "uint6_operand" "")
8881			 (match_operand:DI 2 "uint6_operand" ""))
8882	(match_operand:DI 3 "arith5_operand" "r,L"))]
8883  "TARGET_64BIT
8884   && UINTVAL (operands[1]) > 0
8885   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
8886  "@
8887   depd %3,%2+%1-1,%1,%0
8888   depdi %3,%2+%1-1,%1,%0"
8889  [(set_attr "type" "shift,shift")
8890   (set_attr "length" "4,4")])
8891
8892;; Optimize insertion of const_int values of type 1...1xxxx.
8893(define_insn ""
8894  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
8895			 (match_operand:DI 1 "uint6_operand" "")
8896			 (match_operand:DI 2 "uint6_operand" ""))
8897	(match_operand:DI 3 "const_int_operand" ""))]
8898  "(INTVAL (operands[3]) & 0x10) != 0
8899   && TARGET_64BIT
8900   && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8901  "*
8902{
8903  operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8904  return \"depdi %3,%2+%1-1,%1,%0\";
8905}"
8906  [(set_attr "type" "shift")
8907   (set_attr "length" "4")])
8908
8909(define_insn ""
8910  [(set (match_operand:DI 0 "register_operand" "=r")
8911	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
8912		   (const_int 32)))]
8913  "TARGET_64BIT"
8914  "depd,z %1,31,32,%0"
8915  [(set_attr "type" "shift")
8916   (set_attr "length" "4")])
8917
8918;; This insn is used for some loop tests, typically loops reversed when
8919;; strength reduction is used.  It is actually created when the instruction
8920;; combination phase combines the special loop test.  Since this insn
8921;; is both a jump insn and has an output, it must deal with its own
8922;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
8923;; to not choose the register alternatives in the event a reload is needed.
8924(define_insn "decrement_and_branch_until_zero"
8925  [(set (pc)
8926	(if_then_else
8927	  (match_operator 2 "comparison_operator"
8928	   [(plus:SI
8929	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
8930	      (match_operand:SI 1 "int5_operand" "L,L,L"))
8931	    (const_int 0)])
8932	  (label_ref (match_operand 3 "" ""))
8933	  (pc)))
8934   (set (match_dup 0)
8935	(plus:SI (match_dup 0) (match_dup 1)))
8936   (clobber (match_scratch:SI 4 "=X,r,r"))]
8937  ""
8938  "* return pa_output_dbra (operands, insn, which_alternative); "
8939;; Do not expect to understand this the first time through.
8940[(set_attr "type" "cbranch,multi,multi")
8941 (set (attr "length")
8942      (if_then_else (eq_attr "alternative" "0")
8943;; Loop counter in register case
8944;; Short branch has length of 4
8945;; Long branch has length of 8, 20, 24 or 28
8946	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8947	       (const_int MAX_12BIT_OFFSET))
8948	   (const_int 4)
8949	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8950	       (const_int MAX_17BIT_OFFSET))
8951	   (const_int 8)
8952	   (match_test "TARGET_PORTABLE_RUNTIME")
8953	   (const_int 24)
8954	   (not (match_test "flag_pic"))
8955	   (const_int 20)]
8956	  (const_int 28))
8957
8958;; Loop counter in FP reg case.
8959;; Extra goo to deal with additional reload insns.
8960	(if_then_else (eq_attr "alternative" "1")
8961	  (if_then_else (lt (match_dup 3) (pc))
8962	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
8963		      (const_int MAX_12BIT_OFFSET))
8964		    (const_int 24)
8965		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
8966		      (const_int MAX_17BIT_OFFSET))
8967		    (const_int 28)
8968		    (match_test "TARGET_PORTABLE_RUNTIME")
8969		    (const_int 44)
8970		    (not (match_test "flag_pic"))
8971		    (const_int 40)]
8972		  (const_int 48))
8973	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8974		      (const_int MAX_12BIT_OFFSET))
8975		    (const_int 24)
8976		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8977		      (const_int MAX_17BIT_OFFSET))
8978		    (const_int 28)
8979		    (match_test "TARGET_PORTABLE_RUNTIME")
8980		    (const_int 44)
8981		    (not (match_test "flag_pic"))
8982		    (const_int 40)]
8983		  (const_int 48)))
8984
8985;; Loop counter in memory case.
8986;; Extra goo to deal with additional reload insns.
8987	(if_then_else (lt (match_dup 3) (pc))
8988	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8989		      (const_int MAX_12BIT_OFFSET))
8990		    (const_int 12)
8991		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8992		      (const_int MAX_17BIT_OFFSET))
8993		    (const_int 16)
8994		    (match_test "TARGET_PORTABLE_RUNTIME")
8995		    (const_int 32)
8996		    (not (match_test "flag_pic"))
8997		    (const_int 28)]
8998		  (const_int 36))
8999	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9000		      (const_int MAX_12BIT_OFFSET))
9001		    (const_int 12)
9002		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9003		      (const_int MAX_17BIT_OFFSET))
9004		    (const_int 16)
9005		    (match_test "TARGET_PORTABLE_RUNTIME")
9006		    (const_int 32)
9007		    (not (match_test "flag_pic"))
9008		    (const_int 28)]
9009		  (const_int 36))))))])
9010
9011(define_insn ""
9012  [(set (pc)
9013	(if_then_else
9014	  (match_operator 2 "movb_comparison_operator"
9015	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9016	  (label_ref (match_operand 3 "" ""))
9017	  (pc)))
9018   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9019	(match_dup 1))]
9020  ""
9021"* return pa_output_movb (operands, insn, which_alternative, 0); "
9022;; Do not expect to understand this the first time through.
9023[(set_attr "type" "cbranch,multi,multi,multi")
9024 (set (attr "length")
9025      (if_then_else (eq_attr "alternative" "0")
9026;; Loop counter in register case
9027;; Short branch has length of 4
9028;; Long branch has length of 8, 20, 24 or 28
9029        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9030	       (const_int MAX_12BIT_OFFSET))
9031	   (const_int 4)
9032	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9033	       (const_int MAX_17BIT_OFFSET))
9034	   (const_int 8)
9035	   (match_test "TARGET_PORTABLE_RUNTIME")
9036	   (const_int 24)
9037	   (not (match_test "flag_pic"))
9038	   (const_int 20)]
9039	  (const_int 28))
9040
9041;; Loop counter in FP reg case.
9042;; Extra goo to deal with additional reload insns.
9043	(if_then_else (eq_attr "alternative" "1")
9044	  (if_then_else (lt (match_dup 3) (pc))
9045	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9046		      (const_int MAX_12BIT_OFFSET))
9047		    (const_int 12)
9048		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9049		      (const_int MAX_17BIT_OFFSET))
9050		    (const_int 16)
9051		    (match_test "TARGET_PORTABLE_RUNTIME")
9052		    (const_int 32)
9053		    (not (match_test "flag_pic"))
9054		    (const_int 28)]
9055		  (const_int 36))
9056	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9057		      (const_int MAX_12BIT_OFFSET))
9058		    (const_int 12)
9059		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9060		      (const_int MAX_17BIT_OFFSET))
9061		    (const_int 16)
9062		    (match_test "TARGET_PORTABLE_RUNTIME")
9063		    (const_int 32)
9064		    (not (match_test "flag_pic"))
9065		    (const_int 28)]
9066		  (const_int 36)))
9067
9068;; Loop counter in memory or sar case.
9069;; Extra goo to deal with additional reload insns.
9070	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9071		   (const_int MAX_12BIT_OFFSET))
9072		(const_int 8)
9073		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9074		  (const_int MAX_17BIT_OFFSET))
9075		(const_int 12)
9076		(match_test "TARGET_PORTABLE_RUNTIME")
9077		(const_int 28)
9078		(not (match_test "flag_pic"))
9079		(const_int 24)]
9080	      (const_int 32)))))])
9081
9082;; Handle negated branch.
9083(define_insn ""
9084  [(set (pc)
9085	(if_then_else
9086	  (match_operator 2 "movb_comparison_operator"
9087	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9088	  (pc)
9089	  (label_ref (match_operand 3 "" ""))))
9090   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9091	(match_dup 1))]
9092  ""
9093"* return pa_output_movb (operands, insn, which_alternative, 1); "
9094;; Do not expect to understand this the first time through.
9095[(set_attr "type" "cbranch,multi,multi,multi")
9096 (set (attr "length")
9097      (if_then_else (eq_attr "alternative" "0")
9098;; Loop counter in register case
9099;; Short branch has length of 4
9100;; Long branch has length of 8
9101        (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9102	       (const_int MAX_12BIT_OFFSET))
9103	   (const_int 4)
9104	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9105	       (const_int MAX_17BIT_OFFSET))
9106	   (const_int 8)
9107	   (match_test "TARGET_PORTABLE_RUNTIME")
9108	   (const_int 24)
9109	   (not (match_test "flag_pic"))
9110	   (const_int 20)]
9111	  (const_int 28))
9112
9113;; Loop counter in FP reg case.
9114;; Extra goo to deal with additional reload insns.
9115	(if_then_else (eq_attr "alternative" "1")
9116	  (if_then_else (lt (match_dup 3) (pc))
9117	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9118		      (const_int MAX_12BIT_OFFSET))
9119		    (const_int 12)
9120		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9121		      (const_int MAX_17BIT_OFFSET))
9122		    (const_int 16)
9123		    (match_test "TARGET_PORTABLE_RUNTIME")
9124		    (const_int 32)
9125		    (not (match_test "flag_pic"))
9126		    (const_int 28)]
9127		  (const_int 36))
9128	     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9129		      (const_int MAX_12BIT_OFFSET))
9130		    (const_int 12)
9131		    (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9132		      (const_int MAX_17BIT_OFFSET))
9133		    (const_int 16)
9134		    (match_test "TARGET_PORTABLE_RUNTIME")
9135		    (const_int 32)
9136		    (not (match_test "flag_pic"))
9137		    (const_int 28)]
9138		  (const_int 36)))
9139
9140;; Loop counter in memory or SAR case.
9141;; Extra goo to deal with additional reload insns.
9142	(cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9143		   (const_int MAX_12BIT_OFFSET))
9144		(const_int 8)
9145		(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9146		  (const_int MAX_17BIT_OFFSET))
9147		(const_int 12)
9148		(match_test "TARGET_PORTABLE_RUNTIME")
9149		(const_int 28)
9150		(not (match_test "flag_pic"))
9151		(const_int 24)]
9152	      (const_int 32)))))])
9153
9154(define_insn ""
9155  [(set (pc) (label_ref (match_operand 3 "" "" )))
9156   (set (match_operand:SI 0 "ireg_operand" "=r")
9157	(plus:SI (match_operand:SI 1 "ireg_operand" "r")
9158		 (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9159  "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9160  "*
9161{
9162  return pa_output_parallel_addb (operands, insn);
9163}"
9164[(set_attr "type" "parallel_branch")
9165 (set (attr "length")
9166    (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9167	       (const_int MAX_12BIT_OFFSET))
9168	   (const_int 4)
9169	   (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9170	       (const_int MAX_17BIT_OFFSET))
9171	   (const_int 8)
9172	   (match_test "TARGET_PORTABLE_RUNTIME")
9173	   (const_int 24)
9174	   (not (match_test "flag_pic"))
9175	   (const_int 20)]
9176	  (const_int 28)))])
9177
9178(define_insn ""
9179  [(set (pc) (label_ref (match_operand 2 "" "" )))
9180   (set (match_operand:SF 0 "ireg_operand" "=r")
9181	(match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9182  "reload_completed"
9183  "*
9184{
9185  return pa_output_parallel_movb (operands, insn);
9186}"
9187[(set_attr "type" "parallel_branch")
9188 (set (attr "length")
9189    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9190	       (const_int MAX_12BIT_OFFSET))
9191	   (const_int 4)
9192	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9193	       (const_int MAX_17BIT_OFFSET))
9194	   (const_int 8)
9195	   (match_test "TARGET_PORTABLE_RUNTIME")
9196	   (const_int 24)
9197	   (not (match_test "flag_pic"))
9198	   (const_int 20)]
9199	  (const_int 28)))])
9200
9201(define_insn ""
9202  [(set (pc) (label_ref (match_operand 2 "" "" )))
9203   (set (match_operand:SI 0 "ireg_operand" "=r")
9204	(match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9205  "reload_completed"
9206  "*
9207{
9208  return pa_output_parallel_movb (operands, insn);
9209}"
9210[(set_attr "type" "parallel_branch")
9211 (set (attr "length")
9212    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9213	       (const_int MAX_12BIT_OFFSET))
9214	   (const_int 4)
9215	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9216	       (const_int MAX_17BIT_OFFSET))
9217	   (const_int 8)
9218	   (match_test "TARGET_PORTABLE_RUNTIME")
9219	   (const_int 24)
9220	   (not (match_test "flag_pic"))
9221	   (const_int 20)]
9222	  (const_int 28)))])
9223
9224(define_insn ""
9225  [(set (pc) (label_ref (match_operand 2 "" "" )))
9226   (set (match_operand:HI 0 "ireg_operand" "=r")
9227	(match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9228  "reload_completed"
9229  "*
9230{
9231  return pa_output_parallel_movb (operands, insn);
9232}"
9233[(set_attr "type" "parallel_branch")
9234 (set (attr "length")
9235    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9236	       (const_int MAX_12BIT_OFFSET))
9237	   (const_int 4)
9238	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9239	       (const_int MAX_17BIT_OFFSET))
9240	   (const_int 8)
9241	   (match_test "TARGET_PORTABLE_RUNTIME")
9242	   (const_int 24)
9243	   (not (match_test "flag_pic"))
9244	   (const_int 20)]
9245	  (const_int 28)))])
9246
9247(define_insn ""
9248  [(set (pc) (label_ref (match_operand 2 "" "" )))
9249   (set (match_operand:QI 0 "ireg_operand" "=r")
9250	(match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9251  "reload_completed"
9252  "*
9253{
9254  return pa_output_parallel_movb (operands, insn);
9255}"
9256[(set_attr "type" "parallel_branch")
9257 (set (attr "length")
9258    (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9259	       (const_int MAX_12BIT_OFFSET))
9260	   (const_int 4)
9261	   (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9262	       (const_int MAX_17BIT_OFFSET))
9263	   (const_int 8)
9264	   (match_test "TARGET_PORTABLE_RUNTIME")
9265	   (const_int 24)
9266	   (not (match_test "flag_pic"))
9267	   (const_int 20)]
9268	  (const_int 28)))])
9269
9270(define_insn ""
9271  [(set (match_operand 0 "register_operand" "=f")
9272	(mult (match_operand 1 "register_operand" "f")
9273	      (match_operand 2 "register_operand" "f")))
9274   (set (match_operand 3 "register_operand" "+f")
9275	(plus (match_operand 4 "register_operand" "f")
9276	      (match_operand 5 "register_operand" "f")))]
9277  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9278   && reload_completed && pa_fmpyaddoperands (operands)"
9279  "*
9280{
9281  if (GET_MODE (operands[0]) == DFmode)
9282    {
9283      if (rtx_equal_p (operands[3], operands[5]))
9284	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9285      else
9286	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9287    }
9288  else
9289    {
9290      if (rtx_equal_p (operands[3], operands[5]))
9291	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9292      else
9293	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9294    }
9295}"
9296  [(set_attr "type" "fpalu")
9297   (set_attr "length" "4")])
9298
9299(define_insn ""
9300  [(set (match_operand 3 "register_operand" "+f")
9301	(plus (match_operand 4 "register_operand" "f")
9302	      (match_operand 5 "register_operand" "f")))
9303   (set (match_operand 0 "register_operand" "=f")
9304	(mult (match_operand 1 "register_operand" "f")
9305	      (match_operand 2 "register_operand" "f")))]
9306  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9307   && reload_completed && pa_fmpyaddoperands (operands)"
9308  "*
9309{
9310  if (GET_MODE (operands[0]) == DFmode)
9311    {
9312      if (rtx_equal_p (operands[3], operands[5]))
9313	return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9314      else
9315	return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9316    }
9317  else
9318    {
9319      if (rtx_equal_p (operands[3], operands[5]))
9320	return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9321      else
9322	return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9323    }
9324}"
9325  [(set_attr "type" "fpalu")
9326   (set_attr "length" "4")])
9327
9328(define_insn ""
9329  [(set (match_operand 0 "register_operand" "=f")
9330	(mult (match_operand 1 "register_operand" "f")
9331	      (match_operand 2 "register_operand" "f")))
9332   (set (match_operand 3 "register_operand" "+f")
9333	(minus (match_operand 4 "register_operand" "f")
9334	       (match_operand 5 "register_operand" "f")))]
9335  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9336   && reload_completed && pa_fmpysuboperands (operands)"
9337  "*
9338{
9339  if (GET_MODE (operands[0]) == DFmode)
9340    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9341  else
9342    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9343}"
9344  [(set_attr "type" "fpalu")
9345   (set_attr "length" "4")])
9346
9347(define_insn ""
9348  [(set (match_operand 3 "register_operand" "+f")
9349	(minus (match_operand 4 "register_operand" "f")
9350	       (match_operand 5 "register_operand" "f")))
9351   (set (match_operand 0 "register_operand" "=f")
9352	(mult (match_operand 1 "register_operand" "f")
9353	      (match_operand 2 "register_operand" "f")))]
9354  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9355   && reload_completed && pa_fmpysuboperands (operands)"
9356  "*
9357{
9358  if (GET_MODE (operands[0]) == DFmode)
9359    return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9360  else
9361    return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9362}"
9363  [(set_attr "type" "fpalu")
9364   (set_attr "length" "4")])
9365
9366;; The following two patterns are used by the trampoline code for nested
9367;; functions.  They flush the I and D cache lines from the start address
9368;; (operand0) to the end address (operand1).  No lines are flushed if the
9369;; end address is less than the start address (unsigned).
9370;;
9371;; Because the range of memory flushed is variable and the size of a MEM
9372;; can only be a CONST_INT, the patterns specify that they perform an
9373;; unspecified volatile operation on all memory.
9374;;
9375;; The address range for an icache flush must lie within a single
9376;; space on targets with non-equivalent space registers.
9377;;
9378;; Operand 0 contains the start address.
9379;; Operand 1 contains the end address.
9380;; Operand 2 contains the line length to use.
9381(define_insn "dcacheflush<P:mode>"
9382  [(const_int 1)
9383   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9384   (use (match_operand 0 "pmode_register_operand" "r"))
9385   (use (match_operand 1 "pmode_register_operand" "r"))
9386   (use (match_operand 2 "pmode_register_operand" "r"))
9387   (clobber (match_scratch:P 3 "=&0"))]
9388  ""
9389  "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9390  [(set_attr "type" "multi")
9391   (set_attr "length" "12")])
9392
9393(define_insn "icacheflush<P:mode>"
9394  [(const_int 2)
9395   (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9396   (use (match_operand 0 "pmode_register_operand" "r"))
9397   (use (match_operand 1 "pmode_register_operand" "r"))
9398   (use (match_operand 2 "pmode_register_operand" "r"))
9399   (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9400   (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9401   (clobber (match_scratch:P 5 "=&0"))]
9402  ""
9403  "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"
9404  [(set_attr "type" "multi")
9405   (set_attr "length" "52")])
9406
9407;; An out-of-line prologue.
9408(define_insn "outline_prologue_call"
9409  [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9410   (clobber (reg:SI 31))
9411   (clobber (reg:SI 22))
9412   (clobber (reg:SI 21))
9413   (clobber (reg:SI 20))
9414   (clobber (reg:SI 19))
9415   (clobber (reg:SI 1))]
9416  ""
9417  "*
9418{
9419
9420  /* We need two different versions depending on whether or not we
9421     need a frame pointer.   Also note that we return to the instruction
9422     immediately after the branch rather than two instructions after the
9423     break as normally is the case.  */
9424  if (frame_pointer_needed)
9425    {
9426      /* Must import the magic millicode routine(s).  */
9427      output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9428
9429      if (TARGET_PORTABLE_RUNTIME)
9430	{
9431	  output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9432	  output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9433			   NULL);
9434	}
9435      else
9436	output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9437    }
9438  else
9439    {
9440      /* Must import the magic millicode routine(s).  */
9441      output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9442
9443      if (TARGET_PORTABLE_RUNTIME)
9444	{
9445	  output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9446	  output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9447	}
9448      else
9449	output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9450    }
9451  return \"\";
9452}"
9453  [(set_attr "type" "multi")
9454   (set_attr "length" "8")])
9455
9456;; An out-of-line epilogue.
9457(define_insn "outline_epilogue_call"
9458  [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9459   (use (reg:SI 29))
9460   (use (reg:SI 28))
9461   (clobber (reg:SI 31))
9462   (clobber (reg:SI 22))
9463   (clobber (reg:SI 21))
9464   (clobber (reg:SI 20))
9465   (clobber (reg:SI 19))
9466   (clobber (reg:SI 2))
9467   (clobber (reg:SI 1))]
9468  ""
9469  "*
9470{
9471
9472  /* We need two different versions depending on whether or not we
9473     need a frame pointer.   Also note that we return to the instruction
9474     immediately after the branch rather than two instructions after the
9475     break as normally is the case.  */
9476  if (frame_pointer_needed)
9477    {
9478      /* Must import the magic millicode routine.  */
9479      output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9480
9481      /* The out-of-line prologue will make sure we return to the right
9482	 instruction.  */
9483      if (TARGET_PORTABLE_RUNTIME)
9484	{
9485	  output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9486	  output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9487			   NULL);
9488	}
9489      else
9490	output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9491    }
9492  else
9493    {
9494      /* Must import the magic millicode routine.  */
9495      output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9496
9497      /* The out-of-line prologue will make sure we return to the right
9498	 instruction.  */
9499      if (TARGET_PORTABLE_RUNTIME)
9500	{
9501	  output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9502	  output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9503	}
9504      else
9505	output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9506    }
9507  return \"\";
9508}"
9509  [(set_attr "type" "multi")
9510   (set_attr "length" "8")])
9511
9512;; Given a function pointer, canonicalize it so it can be
9513;; reliably compared to another function pointer.  */
9514(define_expand "canonicalize_funcptr_for_compare"
9515  [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9516   (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9517	      (clobber (match_dup 2))
9518	      (clobber (reg:SI 26))
9519	      (clobber (reg:SI 22))
9520	      (clobber (reg:SI 31))])
9521   (set (match_operand:SI 0 "register_operand" "")
9522	(reg:SI 29))]
9523  "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9524  "
9525{
9526  if (TARGET_ELF32)
9527    {
9528      rtx canonicalize_funcptr_for_compare_libfunc
9529        = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9530
9531      emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9532      			       operands[0], LCT_NORMAL, Pmode,
9533			       1, operands[1], Pmode);
9534      DONE;
9535    }
9536
9537  operands[2] = gen_reg_rtx (SImode);
9538  if (GET_CODE (operands[1]) != REG)
9539    {
9540      rtx tmp = gen_reg_rtx (Pmode);
9541      emit_move_insn (tmp, operands[1]);
9542      operands[1] = tmp;
9543    }
9544}")
9545
9546(define_insn "*$$sh_func_adrs"
9547  [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9548   (clobber (match_operand:SI 0 "register_operand" "=a"))
9549   (clobber (reg:SI 26))
9550   (clobber (reg:SI 22))
9551   (clobber (reg:SI 31))]
9552  "!TARGET_64BIT"
9553  "*
9554{
9555  int length = get_attr_length (insn);
9556  rtx xoperands[2];
9557
9558  xoperands[0] = GEN_INT (length - 8);
9559  xoperands[1] = GEN_INT (length - 16);
9560
9561  /* Must import the magic millicode routine.  */
9562  output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9563
9564  /* This is absolutely amazing.
9565
9566     First, copy our input parameter into %r29 just in case we don't
9567     need to call $$sh_func_adrs.  */
9568  output_asm_insn (\"copy %%r26,%%r29\", NULL);
9569  output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9570
9571  /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9572     we use %r26 unchanged.  */
9573  output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9574  output_asm_insn (\"ldi 4096,%%r31\", NULL);
9575
9576  /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9577     4096, then again we use %r26 unchanged.  */
9578  output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9579
9580  /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
9581  return pa_output_millicode_call (insn,
9582				   gen_rtx_SYMBOL_REF (SImode,
9583						       \"$$sh_func_adrs\"));
9584}"
9585  [(set_attr "type" "sh_func_adrs")
9586   (set (attr "length")
9587	(cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
9588	      (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9589		    (const_int 20))))])
9590
9591;; On the PA, the PIC register is call clobbered, so it must
9592;; be saved & restored around calls by the caller.  If the call
9593;; doesn't return normally (nonlocal goto, or an exception is
9594;; thrown), then the code at the exception handler label must
9595;; restore the PIC register.
9596(define_expand "exception_receiver"
9597  [(const_int 4)]
9598  "flag_pic"
9599  "
9600{
9601  /* On the 64-bit port, we need a blockage because there is
9602     confusion regarding the dependence of the restore on the
9603     frame pointer.  As a result, the frame pointer and pic
9604     register restores sometimes are interchanged erroneously.  */
9605  if (TARGET_64BIT)
9606    emit_insn (gen_blockage ());
9607  /* Restore the PIC register using hppa_pic_save_rtx ().  The
9608     PIC register is not saved in the frame in 64-bit ABI.  */
9609  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9610  emit_insn (gen_blockage ());
9611  DONE;
9612}")
9613
9614(define_expand "builtin_setjmp_receiver"
9615  [(label_ref (match_operand 0 "" ""))]
9616  "flag_pic"
9617  "
9618{
9619  if (TARGET_64BIT)
9620    emit_insn (gen_blockage ());
9621  /* Restore the PIC register.  Hopefully, this will always be from
9622     a stack slot.  The only registers that are valid after a
9623     builtin_longjmp are the stack and frame pointers.  */
9624  emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9625  emit_insn (gen_blockage ());
9626  DONE;
9627}")
9628
9629;; Allocate new stack space and update the saved stack pointer in the
9630;; frame marker.  The HP C compilers also copy additional words in the
9631;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
9632;; The 32-bit compiler copies the word at -16 (Static Link).  We
9633;; currently don't copy these values.
9634;;
9635;; Since the copy of the frame marker can't be done atomically, I
9636;; suspect that using it for unwind purposes may be somewhat unreliable.
9637;; The HP compilers appear to raise the stack and copy the frame
9638;; marker in a strict instruction sequence.  This suggests that the
9639;; unwind library may check for an alloca sequence when ALLOCA_FRAME
9640;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
9641;; as GAS doesn't support it, or try to keep the instructions emitted
9642;; here in strict sequence.
9643(define_expand "allocate_stack"
9644  [(match_operand 0 "" "")
9645   (match_operand 1 "" "")]
9646  ""
9647  "
9648{
9649  rtx addr;
9650
9651  /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
9652     in operand 0 before adjusting the stack.  */
9653  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9654  anti_adjust_stack (operands[1]);
9655  if (TARGET_HPUX_UNWIND_LIBRARY)
9656    {
9657      addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
9658			   GEN_INT (TARGET_64BIT ? -8 : -4));
9659      emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
9660    }
9661  if (!TARGET_64BIT && flag_pic)
9662    {
9663      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
9664      emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
9665    }
9666  DONE;
9667}")
9668
9669(define_expand "prefetch"
9670  [(match_operand 0 "address_operand" "")
9671   (match_operand 1 "const_int_operand" "")
9672   (match_operand 2 "const_int_operand" "")]
9673  "TARGET_PA_20"
9674{
9675  operands[0] = copy_addr_to_reg (operands[0]);
9676  emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
9677  DONE;
9678})
9679
9680(define_insn "prefetch_20"
9681  [(prefetch (match_operand 0 "pmode_register_operand" "r")
9682	     (match_operand:SI 1 "const_int_operand" "n")
9683	     (match_operand:SI 2 "const_int_operand" "n"))]
9684  "TARGET_PA_20"
9685{
9686  /* The SL cache-control completer indicates good spatial locality but
9687     poor temporal locality.  The ldw instruction with a target of general
9688     register 0 prefetches a cache line for a read.  The ldd instruction
9689     prefetches a cache line for a write.  */
9690  static const char * const instr[2][2] = {
9691    {
9692      "ldw,sl 0(%0),%%r0",
9693      "ldd,sl 0(%0),%%r0"
9694    },
9695    {
9696      "ldw 0(%0),%%r0",
9697      "ldd 0(%0),%%r0"
9698    }
9699  };
9700  int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
9701  int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
9702
9703  return instr [locality][read_or_write];
9704}
9705  [(set_attr "type" "load")
9706   (set_attr "length" "4")])
9707
9708;; TLS Support
9709(define_insn "tgd_load"
9710 [(set (match_operand:SI 0 "register_operand" "=r")
9711       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
9712  (clobber (reg:SI 1))
9713  (use (reg:SI 27))]
9714  ""
9715  "*
9716{
9717  return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
9718}"
9719  [(set_attr "type" "multi")
9720   (set_attr "length" "8")])
9721
9722(define_insn "tgd_load_pic"
9723 [(set (match_operand:SI 0 "register_operand" "=r")
9724       (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
9725  (clobber (reg:SI 1))
9726  (use (reg:SI 19))]
9727  ""
9728  "*
9729{
9730  return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
9731}"
9732  [(set_attr "type" "multi")
9733   (set_attr "length" "8")])
9734
9735(define_insn "tld_load"
9736 [(set (match_operand:SI 0 "register_operand" "=r")
9737       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
9738  (clobber (reg:SI 1))
9739  (use (reg:SI 27))]
9740  ""
9741  "*
9742{
9743  return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
9744}"
9745  [(set_attr "type" "multi")
9746   (set_attr "length" "8")])
9747
9748(define_insn "tld_load_pic"
9749 [(set (match_operand:SI 0 "register_operand" "=r")
9750       (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
9751  (clobber (reg:SI 1))
9752  (use (reg:SI 19))]
9753  ""
9754  "*
9755{
9756  return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
9757}"
9758  [(set_attr "type" "multi")
9759   (set_attr "length" "8")])
9760
9761(define_insn "tld_offset_load"
9762  [(set (match_operand:SI 0 "register_operand" "=r")
9763        (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
9764		 	    UNSPEC_TLSLDO)
9765		 (match_operand:SI 2 "register_operand" "r")))
9766   (clobber (reg:SI 1))]
9767  ""
9768  "*
9769{
9770  return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\";
9771}"
9772  [(set_attr "type" "multi")
9773   (set_attr "length" "8")])
9774
9775(define_insn "tp_load"
9776  [(set (match_operand:SI 0 "register_operand" "=r")
9777	(unspec:SI [(const_int 0)] UNSPEC_TP))]
9778  ""
9779  "mfctl %%cr27,%0"
9780  [(set_attr "type" "multi")
9781   (set_attr "length" "4")])
9782
9783(define_insn "tie_load"
9784  [(set (match_operand:SI 0 "register_operand" "=r")
9785        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
9786   (clobber (reg:SI 1))
9787   (use (reg:SI 27))]
9788  ""
9789  "*
9790{
9791  return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
9792}"
9793  [(set_attr "type" "multi")
9794   (set_attr "length" "8")])
9795
9796(define_insn "tie_load_pic"
9797  [(set (match_operand:SI 0 "register_operand" "=r")
9798        (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
9799   (clobber (reg:SI 1))
9800   (use (reg:SI 19))]
9801  ""
9802  "*
9803{
9804  return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
9805}"
9806  [(set_attr "type" "multi")
9807   (set_attr "length" "8")])
9808
9809(define_insn "tle_load"
9810  [(set (match_operand:SI 0 "register_operand" "=r")
9811        (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
9812		 	    UNSPEC_TLSLE)
9813		 (match_operand:SI 2 "register_operand" "r")))
9814   (clobber (reg:SI 1))]
9815  ""
9816  "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
9817  [(set_attr "type" "multi")
9818   (set_attr "length" "8")])
9819
9820;; Atomic instructions
9821
9822;; All memory loads and stores access storage atomically except
9823;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
9824;; doubleword loads and stores are not guaranteed to be atomic
9825;; when referencing the I/O address space.
9826
9827;; The kernel cmpxchg operation on linux is not atomic with respect to
9828;; memory stores on SMP machines, so we must do stores using a cmpxchg
9829;; operation.
9830
9831;; These patterns are at the bottom so the non atomic versions are preferred.
9832
9833;; Implement atomic QImode store using exchange.
9834
9835(define_expand "atomic_storeqi"
9836  [(match_operand:QI 0 "memory_operand")                ;; memory
9837   (match_operand:QI 1 "register_operand")              ;; val out
9838   (match_operand:SI 2 "const_int_operand")]            ;; model
9839  ""
9840{
9841  if (TARGET_SYNC_LIBCALL)
9842    {
9843      rtx mem = operands[0];
9844      rtx val = operands[1];
9845      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
9846	DONE;
9847    }
9848  FAIL;
9849})
9850
9851;; Implement atomic HImode stores using exchange.
9852
9853(define_expand "atomic_storehi"
9854  [(match_operand:HI 0 "memory_operand")                ;; memory
9855   (match_operand:HI 1 "register_operand")              ;; val out
9856   (match_operand:SI 2 "const_int_operand")]            ;; model
9857  ""
9858{
9859  if (TARGET_SYNC_LIBCALL)
9860    {
9861      rtx mem = operands[0];
9862      rtx val = operands[1];
9863      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
9864	DONE;
9865    }
9866  FAIL;
9867})
9868
9869;; Implement atomic SImode store using exchange.
9870
9871(define_expand "atomic_storesi"
9872  [(match_operand:SI 0 "memory_operand")                ;; memory
9873   (match_operand:SI 1 "register_operand")              ;; val out
9874   (match_operand:SI 2 "const_int_operand")]            ;; model
9875  ""
9876{
9877  if (TARGET_SYNC_LIBCALL)
9878    {
9879      rtx mem = operands[0];
9880      rtx val = operands[1];
9881      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
9882	DONE;
9883    }
9884  FAIL;
9885})
9886
9887;; Implement atomic SFmode store using exchange.
9888
9889(define_expand "atomic_storesf"
9890  [(match_operand:SF 0 "memory_operand")                ;; memory
9891   (match_operand:SF 1 "register_operand")              ;; val out
9892   (match_operand:SI 2 "const_int_operand")]            ;; model
9893  ""
9894{
9895  if (TARGET_SYNC_LIBCALL)
9896    {
9897      rtx mem = operands[0];
9898      rtx val = operands[1];
9899      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
9900	DONE;
9901    }
9902  FAIL;
9903})
9904
9905;; Implement atomic DImode load using 64-bit floating point load.
9906
9907(define_expand "atomic_loaddi"
9908  [(match_operand:DI 0 "register_operand")              ;; val out
9909   (match_operand:DI 1 "memory_operand")                ;; memory
9910   (match_operand:SI 2 "const_int_operand")]            ;; model
9911  ""
9912{
9913  enum memmodel model;
9914
9915  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
9916    FAIL;
9917
9918  model = memmodel_from_int (INTVAL (operands[2]));
9919  operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9920  expand_mem_thread_fence (model);
9921  emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9922  if (is_mm_seq_cst (model))
9923    expand_mem_thread_fence (model);
9924  DONE;
9925})
9926
9927(define_insn "atomic_loaddi_1"
9928  [(set (match_operand:DI 0 "register_operand" "=f,r")
9929        (mem:DI (match_operand:SI 1 "register_operand" "r,r")))
9930   (clobber (match_scratch:DI 2 "=X,f"))]
9931  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
9932  "@
9933   {fldds|fldd} 0(%1),%0
9934   {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"
9935  [(set_attr "type" "move,move")
9936   (set_attr "length" "4,16")])
9937
9938;; Implement atomic DImode store.
9939
9940(define_expand "atomic_storedi"
9941  [(match_operand:DI 0 "memory_operand")                ;; memory
9942   (match_operand:DI 1 "register_operand")              ;; val out
9943   (match_operand:SI 2 "const_int_operand")]            ;; model
9944  ""
9945{
9946  enum memmodel model;
9947
9948  if (TARGET_SYNC_LIBCALL)
9949    {
9950      rtx mem = operands[0];
9951      rtx val = operands[1];
9952      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
9953	DONE;
9954    }
9955
9956  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
9957    FAIL;
9958
9959  model = memmodel_from_int (INTVAL (operands[2]));
9960  operands[0] = force_reg (SImode, XEXP (operands[0], 0));
9961  expand_mem_thread_fence (model);
9962  emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9963  if (is_mm_seq_cst (model))
9964    expand_mem_thread_fence (model);
9965  DONE;
9966})
9967
9968(define_insn "atomic_storedi_1"
9969  [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
9970        (match_operand:DI 1 "register_operand" "f,r"))
9971   (clobber (match_scratch:DI 2 "=X,f"))]
9972  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS
9973   && !TARGET_SOFT_FLOAT && !TARGET_SYNC_LIBCALL"
9974  "@
9975   {fstds|fstd} %1,0(%0)
9976   {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)"
9977  [(set_attr "type" "move,move")
9978   (set_attr "length" "4,16")])
9979
9980;; Implement atomic DFmode load using 64-bit floating point load.
9981
9982(define_expand "atomic_loaddf"
9983  [(match_operand:DF 0 "register_operand")              ;; val out
9984   (match_operand:DF 1 "memory_operand")                ;; memory
9985   (match_operand:SI 2 "const_int_operand")]            ;; model
9986  ""
9987{
9988  enum memmodel model;
9989
9990  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
9991    FAIL;
9992
9993  model = memmodel_from_int (INTVAL (operands[2]));
9994  operands[1] = force_reg (SImode, XEXP (operands[1], 0));
9995  expand_mem_thread_fence (model);
9996  emit_insn (gen_atomic_loaddf_1 (operands[0], operands[1]));
9997  if (is_mm_seq_cst (model))
9998    expand_mem_thread_fence (model);
9999  DONE;
10000})
10001
10002(define_insn "atomic_loaddf_1"
10003  [(set (match_operand:DF 0 "register_operand" "=f,r")
10004        (mem:DF (match_operand:SI 1 "register_operand" "r,r")))
10005   (clobber (match_scratch:DF 2 "=X,f"))]
10006  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT"
10007  "@
10008   {fldds|fldd} 0(%1),%0
10009   {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"
10010  [(set_attr "type" "move,move")
10011   (set_attr "length" "4,16")])
10012
10013;; Implement atomic DFmode store using 64-bit floating point store.
10014
10015(define_expand "atomic_storedf"
10016  [(match_operand:DF 0 "memory_operand")                ;; memory
10017   (match_operand:DF 1 "register_operand")              ;; val out
10018   (match_operand:SI 2 "const_int_operand")]            ;; model
10019  ""
10020{
10021  enum memmodel model;
10022
10023  if (TARGET_SYNC_LIBCALL)
10024    {
10025      rtx mem = operands[0];
10026      rtx val = operands[1];
10027      if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10028	DONE;
10029    }
10030
10031  if (TARGET_64BIT || TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
10032    FAIL;
10033
10034  model = memmodel_from_int (INTVAL (operands[2]));
10035  operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10036  expand_mem_thread_fence (model);
10037  emit_insn (gen_atomic_storedf_1 (operands[0], operands[1]));
10038  if (is_mm_seq_cst (model))
10039    expand_mem_thread_fence (model);
10040  DONE;
10041})
10042
10043(define_insn "atomic_storedf_1"
10044  [(set (mem:DF (match_operand:SI 0 "register_operand" "r,r"))
10045        (match_operand:DF 1 "register_operand" "f,r"))
10046   (clobber (match_scratch:DF 2 "=X,f"))]
10047  "!TARGET_64BIT && !TARGET_DISABLE_FPREGS
10048   && !TARGET_SOFT_FLOAT && !TARGET_SYNC_LIBCALL"
10049  "@
10050   {fstds|fstd} %1,0(%0)
10051   {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)"
10052  [(set_attr "type" "move,move")
10053   (set_attr "length" "4,16")])
10054