hppa: Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV
[official-gcc.git] / gcc / config / pa / pa.md
blobb0f29a44baea5b7751262884ab68a2f9fb269d0d
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;;   Copyright (C) 1992-2024 Free Software Foundation, Inc.
3 ;;   Contributed by the Center for Software Science at the University
4 ;;   of Utah.
6 ;; This file is part of GCC.
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.
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.
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/>.
22 ;; This machine description is inspired by sparc.md and to a lesser
23 ;; extent mips.md.
25 ;; Possible improvements:
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.
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:
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
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.
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:
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 ;;   
69 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
71 ;; Uses of UNSPEC in this file:
73 (define_c_enum "unspec"
74   [UNSPEC_CFFC          ; canonicalize_funcptr_for_compare
75    UNSPEC_GOTO          ; indirect_goto
76    UNSPEC_DLTIND14R
77    UNSPEC_TP
78    UNSPEC_TLSGD
79    UNSPEC_TLSLDM
80    UNSPEC_TLSLDO
81    UNSPEC_TLSLDBASE
82    UNSPEC_TLSIE
83    UNSPEC_TLSLE 
84    UNSPEC_TLSGD_PIC
85    UNSPEC_TLSLDM_PIC
86    UNSPEC_TLSIE_PIC
87    UNSPEC_MEMORY_BARRIER
88   ])
90 ;; UNSPEC_VOLATILE:
92 (define_c_enum "unspecv"
93   [UNSPECV_BLOCKAGE     ; blockage
94    UNSPECV_DCACHE       ; dcacheflush
95    UNSPECV_ICACHE       ; icacheflush
96    UNSPECV_OPC          ; outline_prologue_call
97    UNSPECV_OEC          ; outline_epilogue_call
98    UNSPECV_LONGJMP      ; builtin_longjmp
99    UNSPECV_GET_FPSR     ; get floating-point status register
100    UNSPECV_SET_FPSR     ; set floating-point status register
101   ])
103 ;; Maximum pc-relative branch offsets.
105 ;; These numbers are a bit smaller than the maximum allowable offsets
106 ;; so that a few instructions may be inserted before the actual branch.
108 (define_constants
109   [(MAX_12BIT_OFFSET     8184)  ; 12-bit branch
110    (MAX_17BIT_OFFSET   262100)  ; 17-bit branch
111   ])
113 ;; Register numbers
115 (define_constants
116   [(R1_REGNUM            1)
117    (R19_REGNUM          19)
118    (R27_REGNUM          27)
119   ])
121 ;; Mode and code iterators
123 ;; This mode iterator allows :P to be used for patterns that operate on
124 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
125 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
127 ;; This attribute defines the condition prefix for word and double word
128 ;; add, compare, subtract and logical instructions.
129 (define_mode_attr dwc [(SI "") (DI "*")])
131 ;; Insn type.  Used to default other attribute values.
133 ;; type "unary" insns have one input operand (1) and one output operand (0)
134 ;; type "binary" insns have two input operands (1,2) and one output (0)
136 (define_attr "type"
137   "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"
138   (const_string "binary"))
140 (define_attr "pa_combine_type"
141   "fmpy,faddsub,uncond_branch,addmove,none"
142   (const_string "none"))
144 ;; Processor type (for scheduling, not code generation) -- this attribute
145 ;; must exactly match the processor_type enumeration in pa.h.
147 ;; FIXME: Add 800 scheduling for completeness?
149 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
151 ;; Length (in # of bytes).
152 (define_attr "length" ""
153   (cond [(eq_attr "type" "load,fpload")
154          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
155                        (const_int 8) (const_int 4))
157          (eq_attr "type" "store,fpstore")
158          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
159                        (const_int 8) (const_int 4))
161          (eq_attr "type" "binary,shift,nullshift")
162          (if_then_else (match_operand 2 "arith14_operand" "")
163                        (const_int 4) (const_int 12))
165          (eq_attr "type" "move,unary,shift,nullshift")
166          (if_then_else (match_operand 1 "arith14_operand" "")
167                        (const_int 4) (const_int 8))]
169         (const_int 4)))
171 (define_asm_attributes
172   [(set_attr "length" "4")
173    (set_attr "type" "multi")])
175 ;; Attributes for instruction and branch scheduling
177 ;; For conditional branches. Frame related instructions are not allowed
178 ;; because they confuse the unwind support.
179 (define_attr "in_branch_delay" "false,true"
180   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
181                      (eq_attr "length" "4")
182                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
183                 (const_string "true")
184                 (const_string "false")))
186 ;; Disallow instructions which use the FPU since they will tie up the FPU
187 ;; even if the instruction is nullified.
188 (define_attr "in_nullified_branch_delay" "false,true"
189   (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")
190                      (eq_attr "length" "4")
191                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
192                 (const_string "true")
193                 (const_string "false")))
195 ;; For calls and millicode calls.
196 (define_attr "in_call_delay" "false,true"
197   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
198                      (eq_attr "length" "4")
199                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
200                 (const_string "true")
201                 (const_string "false")))
203 ;; Call delay slot description.
204 (define_delay (eq_attr "type" "call")
205   [(eq_attr "in_call_delay" "true") (nil) (nil)])
207 ;; Sibcall delay slot description.
208 (define_delay (eq_attr "type" "sibcall")
209   [(eq_attr "in_call_delay" "true") (nil) (nil)])
211 ;; Millicode call delay slot description.
212 (define_delay (eq_attr "type" "milli")
213   [(eq_attr "in_call_delay" "true") (nil) (nil)])
215 ;; Return and other similar instructions.
216 (define_delay (eq_attr "type" "branch,parallel_branch")
217   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
219 ;; Floating point conditional branch delay slot description.
220 (define_delay (eq_attr "type" "fbranch")
221   [(eq_attr "in_branch_delay" "true")
222    (eq_attr "in_nullified_branch_delay" "true")
223    (nil)])
225 ;; Integer conditional branch delay slot description.
226 ;; Nullification of conditional branches on the PA is dependent on the
227 ;; direction of the branch.  Forward branches nullify true and
228 ;; backward branches nullify false.  If the direction is unknown
229 ;; then nullification is not allowed.
230 (define_delay (eq_attr "type" "cbranch")
231   [(eq_attr "in_branch_delay" "true")
232    (and (eq_attr "in_nullified_branch_delay" "true")
233         (attr_flag "forward"))
234    (and (eq_attr "in_nullified_branch_delay" "true")
235         (attr_flag "backward"))])
237 (define_delay (eq_attr "type" "uncond_branch")
238   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
240 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
241 ;; load: 2, fpload: 3
242 ;; store, fpstore: 3, no D-cache operations should be scheduled.
244 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
245 ;; Timings:
246 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
247 ;; fcpy         3       ALU     2
248 ;; fabs         3       ALU     2
249 ;; fadd         3       ALU     2
250 ;; fsub         3       ALU     2
251 ;; fcmp         3       ALU     2
252 ;; fcnv         3       ALU     2
253 ;; fmpyadd      3       ALU,MPY 2
254 ;; fmpysub      3       ALU,MPY 2
255 ;; fmpycfxt     3       ALU,MPY 2
256 ;; fmpy         3       MPY     2
257 ;; fmpyi        3       MPY     2
258 ;; fdiv,sgl     10      MPY     10
259 ;; fdiv,dbl     12      MPY     12
260 ;; fsqrt,sgl    14      MPY     14
261 ;; fsqrt,dbl    18      MPY     18
263 ;; We don't model fmpyadd/fmpysub properly as those instructions
264 ;; keep both the FP ALU and MPY units busy.  Given that these
265 ;; processors are obsolete, I'm not going to spend the time to
266 ;; model those instructions correctly.
268 (define_automaton "pa700")
269 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
271 (define_insn_reservation "W0" 4
272   (and (eq_attr "type" "fpcc")
273        (eq_attr "cpu" "700"))
274   "fpalu_700*2")
276 (define_insn_reservation "W1" 3
277   (and (eq_attr "type" "fpalu")
278        (eq_attr "cpu" "700"))
279   "fpalu_700*2")
281 (define_insn_reservation "W2" 3
282   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
283        (eq_attr "cpu" "700"))
284   "fpmpy_700*2")
286 (define_insn_reservation "W3" 10
287   (and (eq_attr "type" "fpdivsgl")
288        (eq_attr "cpu" "700"))
289   "fpmpy_700*10")
291 (define_insn_reservation "W4" 12
292   (and (eq_attr "type" "fpdivdbl")
293        (eq_attr "cpu" "700"))
294   "fpmpy_700*12")
296 (define_insn_reservation "W5" 14
297   (and (eq_attr "type" "fpsqrtsgl")
298        (eq_attr "cpu" "700"))
299   "fpmpy_700*14")
301 (define_insn_reservation "W6" 18
302   (and (eq_attr "type" "fpsqrtdbl")
303        (eq_attr "cpu" "700"))
304   "fpmpy_700*18")
306 (define_insn_reservation "W7" 2
307   (and (eq_attr "type" "load")
308        (eq_attr "cpu" "700"))
309   "mem_700")
311 (define_insn_reservation "W8" 2
312   (and (eq_attr "type" "fpload")
313        (eq_attr "cpu" "700"))
314   "mem_700")
316 (define_insn_reservation "W9" 3
317   (and (eq_attr "type" "store")
318        (eq_attr "cpu" "700"))
319   "mem_700*3")
321 (define_insn_reservation "W10" 3
322   (and (eq_attr "type" "fpstore")
323        (eq_attr "cpu" "700"))
324   "mem_700*3")
326 (define_insn_reservation "W11" 5
327   (and (eq_attr "type" "fpstore_load")
328        (eq_attr "cpu" "700"))
329   "mem_700*5")
331 (define_insn_reservation "W12" 6
332   (and (eq_attr "type" "store_fpload")
333        (eq_attr "cpu" "700"))
334   "mem_700*6")
336 (define_insn_reservation "W13" 1
337   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
338        (eq_attr "cpu" "700"))
339   "dummy_700")
341 ;; We have a bypass for all computations in the FP unit which feed an
342 ;; FP store as long as the sizes are the same.
343 (define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
344 (define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
345 (define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
346 (define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
347 (define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
349 ;; We have an "anti-bypass" for FP loads which feed an FP store.
350 (define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
352 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
353 ;; floating point computations with non-floating point computations (fp loads
354 ;; and stores are not fp computations).
356 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
357 ;; take two cycles, during which no Dcache operations should be scheduled.
358 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
359 ;; all have the same memory characteristics if one disregards cache misses.
361 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
362 ;; There's no value in modeling the ALU and MUL separately though
363 ;; since there can never be a functional unit conflict given the
364 ;; latency and issue rates for those units.
366 ;; Timings:
367 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
368 ;; fcpy         2       ALU     1
369 ;; fabs         2       ALU     1
370 ;; fadd         2       ALU     1
371 ;; fsub         2       ALU     1
372 ;; fcmp         2       ALU     1
373 ;; fcnv         2       ALU     1
374 ;; fmpyadd      2       ALU,MPY 1
375 ;; fmpysub      2       ALU,MPY 1
376 ;; fmpycfxt     2       ALU,MPY 1
377 ;; fmpy         2       MPY     1
378 ;; fmpyi        2       MPY     1
379 ;; fdiv,sgl     8       DIV     8
380 ;; fdiv,dbl     15      DIV     15
381 ;; fsqrt,sgl    8       DIV     8
382 ;; fsqrt,dbl    15      DIV     15
384 (define_automaton "pa7100")
385 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
387 (define_insn_reservation "X0" 2
388   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
389        (eq_attr "cpu" "7100"))
390   "f_7100,fpmac_7100")
392 (define_insn_reservation "X1" 8
393   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
394        (eq_attr "cpu" "7100"))
395   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
397 (define_insn_reservation "X2" 15
398   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
399        (eq_attr "cpu" "7100"))
400   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
402 (define_insn_reservation "X3" 2
403   (and (eq_attr "type" "load")
404        (eq_attr "cpu" "7100"))
405   "i_7100+mem_7100")
407 (define_insn_reservation "X4" 2
408   (and (eq_attr "type" "fpload")
409        (eq_attr "cpu" "7100"))
410   "i_7100+mem_7100")
412 (define_insn_reservation "X5" 2
413   (and (eq_attr "type" "store")
414        (eq_attr "cpu" "7100"))
415   "i_7100+mem_7100,mem_7100")
417 (define_insn_reservation "X6" 2
418   (and (eq_attr "type" "fpstore")
419        (eq_attr "cpu" "7100"))
420   "i_7100+mem_7100,mem_7100")
422 (define_insn_reservation "X7" 4
423   (and (eq_attr "type" "fpstore_load")
424        (eq_attr "cpu" "7100"))
425   "i_7100+mem_7100,mem_7100*3")
427 (define_insn_reservation "X8" 4
428   (and (eq_attr "type" "store_fpload")
429        (eq_attr "cpu" "7100"))
430   "i_7100+mem_7100,mem_7100*3")
432 (define_insn_reservation "X9" 1
433   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
434        (eq_attr "cpu" "7100"))
435   "i_7100")
437 ;; We have a bypass for all computations in the FP unit which feed an
438 ;; FP store as long as the sizes are the same.
439 (define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
440 (define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
441 (define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
443 ;; We have an "anti-bypass" for FP loads which feed an FP store.
444 (define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
446 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
447 ;; There's no value in modeling the ALU and MUL separately though
448 ;; since there can never be a functional unit conflict that
449 ;; can be avoided given the latency, issue rates and mandatory
450 ;; one cycle cpu-wide lock for a double precision fp multiply.
452 ;; Timings:
453 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
454 ;; fcpy         2       ALU     1
455 ;; fabs         2       ALU     1
456 ;; fadd         2       ALU     1
457 ;; fsub         2       ALU     1
458 ;; fcmp         2       ALU     1
459 ;; fcnv         2       ALU     1
460 ;; fmpyadd,sgl  2       ALU,MPY 1
461 ;; fmpyadd,dbl  3       ALU,MPY 2
462 ;; fmpysub,sgl  2       ALU,MPY 1
463 ;; fmpysub,dbl  3       ALU,MPY 2
464 ;; fmpycfxt,sgl 2       ALU,MPY 1
465 ;; fmpycfxt,dbl 3       ALU,MPY 2
466 ;; fmpy,sgl     2       MPY     1
467 ;; fmpy,dbl     3       MPY     2
468 ;; fmpyi        3       MPY     2
469 ;; fdiv,sgl     8       DIV     8
470 ;; fdiv,dbl     15      DIV     15
471 ;; fsqrt,sgl    8       DIV     8
472 ;; fsqrt,dbl    15      DIV     15
474 ;; The PA7200 is just like the PA7100LC except that there is
475 ;; no store-store penalty.
477 ;; The PA7300 is just like the PA7200 except that there is
478 ;; no store-load penalty.
480 ;; Note there are some aspects of the 7100LC we are not modeling
481 ;; at the moment.  I'll be reviewing the 7100LC scheduling info
482 ;; shortly and updating this description.
484 ;;   load-load pairs
485 ;;   store-store pairs
486 ;;   other issue modeling
488 (define_automaton "pa7100lc")
489 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
490 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
491 (define_cpu_unit "mem_7100lc" "pa7100lc")
493 ;; Double precision multiplies lock the entire CPU for one
494 ;; cycle.  There is no way to avoid this lock and trying to
495 ;; schedule around the lock is pointless and thus there is no
496 ;; value in trying to model this lock.
498 ;; Not modeling the lock allows us to treat fp multiplies just
499 ;; like any other FP alu instruction.  It allows for a smaller
500 ;; DFA and may reduce register pressure.
501 (define_insn_reservation "Y0" 2
502   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
503        (eq_attr "cpu" "7100LC,7200,7300"))
504   "f_7100lc,fpmac_7100lc")
506 ;; fp division and sqrt instructions lock the entire CPU for
507 ;; 7 cycles (single precision) or 14 cycles (double precision).
508 ;; There is no way to avoid this lock and trying to schedule
509 ;; around the lock is pointless and thus there is no value in
510 ;; trying to model this lock.  Not modeling the lock allows
511 ;; for a smaller DFA and may reduce register pressure.
512 (define_insn_reservation "Y1" 1
513   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
514        (eq_attr "cpu" "7100LC,7200,7300"))
515   "f_7100lc")
517 (define_insn_reservation "Y2" 2
518   (and (eq_attr "type" "load")
519        (eq_attr "cpu" "7100LC,7200,7300"))
520   "i1_7100lc+mem_7100lc")
522 (define_insn_reservation "Y3" 2
523   (and (eq_attr "type" "fpload")
524        (eq_attr "cpu" "7100LC,7200,7300"))
525   "i1_7100lc+mem_7100lc")
527 (define_insn_reservation "Y4" 2
528   (and (eq_attr "type" "store")
529        (eq_attr "cpu" "7100LC"))
530   "i1_7100lc+mem_7100lc,mem_7100lc")
532 (define_insn_reservation "Y5" 2
533   (and (eq_attr "type" "fpstore")
534        (eq_attr "cpu" "7100LC"))
535   "i1_7100lc+mem_7100lc,mem_7100lc")
537 (define_insn_reservation "Y6" 4
538   (and (eq_attr "type" "fpstore_load")
539        (eq_attr "cpu" "7100LC"))
540   "i1_7100lc+mem_7100lc,mem_7100lc*3")
542 (define_insn_reservation "Y7" 4
543   (and (eq_attr "type" "store_fpload")
544        (eq_attr "cpu" "7100LC"))
545   "i1_7100lc+mem_7100lc,mem_7100lc*3")
547 (define_insn_reservation "Y8" 1
548   (and (eq_attr "type" "shift,nullshift")
549        (eq_attr "cpu" "7100LC,7200,7300"))
550   "i1_7100lc")
552 (define_insn_reservation "Y9" 1
553   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
554        (eq_attr "cpu" "7100LC,7200,7300"))
555   "(i0_7100lc|i1_7100lc)")
557 ;; The 7200 has a store-load penalty
558 (define_insn_reservation "Y10" 2
559   (and (eq_attr "type" "store")
560        (eq_attr "cpu" "7200"))
561   "i1_7100lc,mem_7100lc")
563 (define_insn_reservation "Y11" 2
564   (and (eq_attr "type" "fpstore")
565        (eq_attr "cpu" "7200"))
566   "i1_7100lc,mem_7100lc")
568 (define_insn_reservation "Y12" 4
569   (and (eq_attr "type" "fpstore_load")
570        (eq_attr "cpu" "7200"))
571   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
573 (define_insn_reservation "Y13" 4
574   (and (eq_attr "type" "store_fpload")
575        (eq_attr "cpu" "7200"))
576   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
578 ;; The 7300 has no penalty for store-store or store-load
579 (define_insn_reservation "Y14" 2
580   (and (eq_attr "type" "store")
581        (eq_attr "cpu" "7300"))
582   "i1_7100lc")
584 (define_insn_reservation "Y15" 2
585   (and (eq_attr "type" "fpstore")
586        (eq_attr "cpu" "7300"))
587   "i1_7100lc")
589 (define_insn_reservation "Y16" 4
590   (and (eq_attr "type" "fpstore_load")
591        (eq_attr "cpu" "7300"))
592   "i1_7100lc,i1_7100lc+mem_7100lc")
594 (define_insn_reservation "Y17" 4
595   (and (eq_attr "type" "store_fpload")
596        (eq_attr "cpu" "7300"))
597   "i1_7100lc,i1_7100lc+mem_7100lc")
599 ;; We have an "anti-bypass" for FP loads which feed an FP store.
600 (define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
602 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
603 ;; traditional architecture.
605 ;; The PA8000 has a large (56) entry reorder buffer that is split between
606 ;; memory and non-memory operations.
608 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
609 ;; the function units, with the exception of branches and multi-output
610 ;; instructions.  The PA8000 can retire two non-memory operations per cycle
611 ;; and two memory operations per cycle, only one of which may be a store.
613 ;; Given the large reorder buffer, the processor can hide most latencies.
614 ;; According to HP, they've got the best results by scheduling for retirement
615 ;; bandwidth with limited latency scheduling for floating point operations.
616 ;; Latency for integer operations and memory references is ignored.
619 ;; We claim floating point operations have a 2 cycle latency and are
620 ;; fully pipelined, except for div and sqrt which are not pipelined and
621 ;; take from 17 to 31 cycles to complete.
623 ;; It's worth noting that there is no way to saturate all the functional
624 ;; units on the PA8000 as there is not enough issue bandwidth.
626 (define_automaton "pa8000")
627 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
628 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
629 (define_cpu_unit "store_8000" "pa8000")
630 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
631 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
632 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
633 (define_reservation "im_8000" "im0_8000 | im1_8000")
634 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
635 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
636 (define_reservation "f_8000" "f0_8000 | f1_8000")
637 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
639 ;; We can issue any two memops per cycle, but we can only retire
640 ;; one memory store per cycle.  We assume that the reorder buffer
641 ;; will hide any memory latencies per HP's recommendation.
642 (define_insn_reservation "Z0" 0
643   (and
644     (eq_attr "type" "load,fpload")
645     (eq_attr "cpu" "8000"))
646   "im_8000,rm_8000")
648 (define_insn_reservation "Z1" 0
649   (and
650     (eq_attr "type" "store,fpstore")
651     (eq_attr "cpu" "8000"))
652   "im_8000,rm_8000+store_8000")
654 (define_insn_reservation "Z2" 0
655   (and (eq_attr "type" "fpstore_load,store_fpload")
656        (eq_attr "cpu" "8000"))
657   "im_8000,rm_8000+store_8000,im_8000,rm_8000")
659 ;; We can issue and retire two non-memory operations per cycle with
660 ;; a few exceptions (branches).  This group catches those we want
661 ;; to assume have zero latency.
662 (define_insn_reservation "Z3" 0
663   (and
664     (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")
665     (eq_attr "cpu" "8000"))
666   "inm_8000,rnm_8000")
668 ;; Branches use both slots in the non-memory issue and
669 ;; retirement unit.
670 (define_insn_reservation "Z4" 0
671   (and
672     (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
673     (eq_attr "cpu" "8000"))
674   "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
676 ;; We partial latency schedule the floating point units.
677 ;; They can issue/retire two at a time in the non-memory
678 ;; units.  We fix their latency at 2 cycles and they
679 ;; are fully pipelined.
680 (define_insn_reservation "Z5" 1
681  (and
682    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
683    (eq_attr "cpu" "8000"))
684  "inm_8000,f_8000,rnm_8000")
686 ;; The fdivsqrt units are not pipelined and have a very long latency.  
687 ;; To keep the DFA from exploding, we do not show all the
688 ;; reservations for the divsqrt unit.
689 (define_insn_reservation "Z6" 17
690  (and
691    (eq_attr "type" "fpdivsgl,fpsqrtsgl")
692    (eq_attr "cpu" "8000"))
693  "inm_8000,fdivsqrt_8000*6,rnm_8000")
695 (define_insn_reservation "Z7" 31
696  (and
697    (eq_attr "type" "fpdivdbl,fpsqrtdbl")
698    (eq_attr "cpu" "8000"))
699  "inm_8000,fdivsqrt_8000*6,rnm_8000")
701 ;; Operand and operator predicates and constraints
703 (include "predicates.md")
704 (include "constraints.md")
706 ;; Compare instructions.
707 ;; This controls RTL generation and register allocation.
709 (define_insn ""
710   [(set (reg:CCFP 0)
711         (match_operator:CCFP 2 "comparison_operator"
712                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
713                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
714   "! TARGET_SOFT_FLOAT"
715   "fcmp,sgl,%Y2 %f0,%f1"
716   [(set_attr "length" "4")
717    (set_attr "type" "fpcc")])
719 (define_insn ""
720   [(set (reg:CCFP 0)
721         (match_operator:CCFP 2 "comparison_operator"
722                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
723                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
724   "! TARGET_SOFT_FLOAT"
725   "fcmp,dbl,%Y2 %f0,%f1"
726   [(set_attr "length" "4")
727    (set_attr "type" "fpcc")])
729 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
730 ;; placeholders.  This is necessary in rare situations when a
731 ;; placeholder is re-emitted (see PR 8705).
733 (define_expand "movccfp"
734   [(set (reg:CCFP 0)
735         (match_operand 0 "const_int_operand" ""))]
736   "! TARGET_SOFT_FLOAT"
737   "
739   if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
740     FAIL;
743 ;; The following patterns are optimization placeholders.  In almost
744 ;; all cases, the user of the condition code will be simplified and the
745 ;; original condition code setting insn should be eliminated.
747 (define_insn "*movccfp0"
748   [(set (reg:CCFP 0)
749         (const_int 0))]
750   "! TARGET_SOFT_FLOAT"
751   "fcmp,dbl,= %%fr0,%%fr0"
752   [(set_attr "length" "4")
753    (set_attr "type" "fpcc")])
755 (define_insn "*movccfp1"
756   [(set (reg:CCFP 0)
757         (const_int 1))]
758   "! TARGET_SOFT_FLOAT"
759   "fcmp,dbl,!= %%fr0,%%fr0"
760   [(set_attr "length" "4")
761    (set_attr "type" "fpcc")])
763 ;; scc insns.
765 (define_expand "cstoresi4"
766   [(set (match_operand:SI 0 "register_operand")
767         (match_operator:SI 1 "ordered_comparison_operator"
768          [(match_operand:SI 2 "reg_or_0_operand" "")
769           (match_operand:SI 3 "arith5_operand" "")]))]
770   "!TARGET_64BIT"
771   "")
773 ;; Instruction canonicalization puts immediate operands second, which
774 ;; is the reverse of what we want.
776 (define_insn "scc"
777   [(set (match_operand:SI 0 "register_operand" "=r")
778         (match_operator:SI 3 "ordered_comparison_operator"
779                            [(match_operand:SI 1 "reg_or_0_operand" "rM")
780                             (match_operand:SI 2 "arith11_operand" "rI")]))]
781   ""
782   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
783   [(set_attr "type" "binary")
784    (set_attr "length" "8")])
786 (define_insn ""
787   [(set (match_operand:DI 0 "register_operand" "=r")
788         (match_operator:DI 3 "ordered_comparison_operator"
789                            [(match_operand:DI 1 "reg_or_0_operand" "rM")
790                             (match_operand:DI 2 "arith11_operand" "rI")]))]
791   "TARGET_64BIT"
792   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
793   [(set_attr "type" "binary")
794    (set_attr "length" "8")])
796 (define_insn "iorscc"
797   [(set (match_operand:SI 0 "register_operand" "=r")
798         (ior:SI (match_operator:SI 3 "ordered_comparison_operator"
799                                    [(match_operand:SI 1 "reg_or_0_operand" "rM")
800                                     (match_operand:SI 2 "arith11_operand" "rI")])
801                 (match_operator:SI 6 "ordered_comparison_operator"
802                                    [(match_operand:SI 4 "reg_or_0_operand" "rM")
803                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
804   ""
805   "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
806   [(set_attr "type" "binary")
807    (set_attr "length" "12")])
809 (define_insn ""
810   [(set (match_operand:DI 0 "register_operand" "=r")
811         (ior:DI (match_operator:DI 3 "ordered_comparison_operator"
812                                    [(match_operand:DI 1 "reg_or_0_operand" "rM")
813                                     (match_operand:DI 2 "arith11_operand" "rI")])
814                 (match_operator:DI 6 "ordered_comparison_operator"
815                                    [(match_operand:DI 4 "reg_or_0_operand" "rM")
816                                     (match_operand:DI 5 "arith11_operand" "rI")])))]
817   "TARGET_64BIT"
818   "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
819   [(set_attr "type" "binary")
820    (set_attr "length" "12")])
822 ;; Combiner patterns for common operations performed with the output
823 ;; from an scc insn (negscc and incscc).
824 (define_insn "negscc"
825   [(set (match_operand:SI 0 "register_operand" "=r")
826         (neg:SI (match_operator:SI 3 "ordered_comparison_operator"
827                [(match_operand:SI 1 "reg_or_0_operand" "rM")
828                 (match_operand:SI 2 "arith11_operand" "rI")])))]
829   ""
830   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
831   [(set_attr "type" "binary")
832    (set_attr "length" "8")])
834 (define_insn ""
835   [(set (match_operand:DI 0 "register_operand" "=r")
836         (neg:DI (match_operator:DI 3 "ordered_comparison_operator"
837                [(match_operand:DI 1 "reg_or_0_operand" "rM")
838                 (match_operand:DI 2 "arith11_operand" "rI")])))]
839   "TARGET_64BIT"
840   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
841   [(set_attr "type" "binary")
842    (set_attr "length" "8")])
844 ;; Patterns for adding/subtracting the result of a boolean expression from
845 ;; a register.  First we have special patterns that make use of the carry
846 ;; bit, and output only two instructions.  For the cases we can't in
847 ;; general do in two instructions, the incscc pattern at the end outputs
848 ;; two or three instructions.
850 (define_insn ""
851   [(set (match_operand:SI 0 "register_operand" "=r")
852         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
853                          (match_operand:SI 3 "arith11_operand" "rI"))
854                  (match_operand:SI 1 "register_operand" "r")))]
855   ""
856   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
857   [(set_attr "type" "binary")
858    (set_attr "length" "8")])
860 (define_insn ""
861   [(set (match_operand:DI 0 "register_operand" "=r")
862         (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
863                          (match_operand:DI 3 "arith11_operand" "rI"))
864                  (match_operand:DI 1 "register_operand" "r")))]
865   "TARGET_64BIT"
866   "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
867   [(set_attr "type" "binary")
868    (set_attr "length" "8")])
870 ; This need only accept registers for op3, since canonicalization
871 ; replaces geu with gtu when op3 is an integer.
872 (define_insn ""
873   [(set (match_operand:SI 0 "register_operand" "=r")
874         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
875                          (match_operand:SI 3 "register_operand" "r"))
876                  (match_operand:SI 1 "register_operand" "r")))]
877   ""
878   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
879   [(set_attr "type" "binary")
880    (set_attr "length" "8")])
882 (define_insn ""
883   [(set (match_operand:DI 0 "register_operand" "=r")
884         (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
885                          (match_operand:DI 3 "register_operand" "r"))
886                  (match_operand:DI 1 "register_operand" "r")))]
887   "TARGET_64BIT"
888   "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
889   [(set_attr "type" "binary")
890    (set_attr "length" "8")])
892 ; Match only integers for op3 here.  This is used as canonical form of the
893 ; geu pattern when op3 is an integer.  Don't match registers since we can't
894 ; make better code than the general incscc pattern.
895 (define_insn ""
896   [(set (match_operand:SI 0 "register_operand" "=r")
897         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
898                          (match_operand:SI 3 "int11_operand" "I"))
899                  (match_operand:SI 1 "register_operand" "r")))]
900   ""
901   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
902   [(set_attr "type" "binary")
903    (set_attr "length" "8")])
905 (define_insn ""
906   [(set (match_operand:DI 0 "register_operand" "=r")
907         (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
908                          (match_operand:DI 3 "int11_operand" "I"))
909                  (match_operand:DI 1 "register_operand" "r")))]
910   "TARGET_64BIT"
911   "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
912   [(set_attr "type" "binary")
913    (set_attr "length" "8")])
915 (define_insn "incscc"
916   [(set (match_operand:SI 0 "register_operand" "=r,r")
917         (plus:SI (match_operator:SI 4 "ordered_comparison_operator"
918                     [(match_operand:SI 2 "register_operand" "r,r")
919                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
920                  (match_operand:SI 1 "register_operand" "0,?r")))]
921   ""
922   "@
923    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
924    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
925   [(set_attr "type" "binary,binary")
926    (set_attr "length" "8,12")])
928 (define_insn ""
929   [(set (match_operand:DI 0 "register_operand" "=r,r")
930         (plus:DI (match_operator:DI 4 "ordered_comparison_operator"
931                     [(match_operand:DI 2 "register_operand" "r,r")
932                      (match_operand:DI 3 "arith11_operand" "rI,rI")])
933                  (match_operand:DI 1 "register_operand" "0,?r")))]
934   "TARGET_64BIT"
935   "@
936    cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
937    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
938   [(set_attr "type" "binary,binary")
939    (set_attr "length" "8,12")])
941 (define_insn ""
942   [(set (match_operand:SI 0 "register_operand" "=r")
943         (minus:SI (match_operand:SI 1 "register_operand" "r")
944                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
945                           (match_operand:SI 3 "arith11_operand" "rI"))))]
946   ""
947   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
948   [(set_attr "type" "binary")
949    (set_attr "length" "8")])
951 (define_insn ""
952   [(set (match_operand:DI 0 "register_operand" "=r")
953         (minus:DI (match_operand:DI 1 "register_operand" "r")
954                   (gtu:DI (match_operand:DI 2 "register_operand" "r")
955                           (match_operand:DI 3 "arith11_operand" "rI"))))]
956   "TARGET_64BIT"
957   "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
958   [(set_attr "type" "binary")
959    (set_attr "length" "8")])
961 (define_insn ""
962   [(set (match_operand:SI 0 "register_operand" "=r")
963         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
964                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
965                                     (match_operand:SI 3 "arith11_operand" "rI")))
966                   (match_operand:SI 4 "register_operand" "r")))]
967   ""
968   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
969   [(set_attr "type" "binary")
970    (set_attr "length" "8")])
972 (define_insn ""
973   [(set (match_operand:DI 0 "register_operand" "=r")
974         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
975                             (gtu:DI (match_operand:DI 2 "register_operand" "r")
976                                     (match_operand:DI 3 "arith11_operand" "rI")))
977                   (match_operand:DI 4 "register_operand" "r")))]
978   "TARGET_64BIT"
979   "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
980   [(set_attr "type" "binary")
981    (set_attr "length" "8")])
983 ; This need only accept registers for op3, since canonicalization
984 ; replaces ltu with leu when op3 is an integer.
985 (define_insn ""
986   [(set (match_operand:SI 0 "register_operand" "=r")
987         (minus:SI (match_operand:SI 1 "register_operand" "r")
988                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
989                           (match_operand:SI 3 "register_operand" "r"))))]
990   ""
991   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
992   [(set_attr "type" "binary")
993    (set_attr "length" "8")])
995 (define_insn ""
996   [(set (match_operand:DI 0 "register_operand" "=r")
997         (minus:DI (match_operand:DI 1 "register_operand" "r")
998                   (ltu:DI (match_operand:DI 2 "register_operand" "r")
999                           (match_operand:DI 3 "register_operand" "r"))))]
1000   "TARGET_64BIT"
1001   "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
1002   [(set_attr "type" "binary")
1003    (set_attr "length" "8")])
1005 (define_insn ""
1006   [(set (match_operand:SI 0 "register_operand" "=r")
1007         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1008                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
1009                                     (match_operand:SI 3 "register_operand" "r")))
1010                   (match_operand:SI 4 "register_operand" "r")))]
1011   ""
1012   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1013   [(set_attr "type" "binary")
1014    (set_attr "length" "8")])
1016 (define_insn ""
1017   [(set (match_operand:DI 0 "register_operand" "=r")
1018         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1019                             (ltu:DI (match_operand:DI 2 "register_operand" "r")
1020                                     (match_operand:DI 3 "register_operand" "r")))
1021                   (match_operand:DI 4 "register_operand" "r")))]
1022   "TARGET_64BIT"
1023   "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1024   [(set_attr "type" "binary")
1025    (set_attr "length" "8")])
1027 ; Match only integers for op3 here.  This is used as canonical form of the
1028 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
1029 ; make better code than the general incscc pattern.
1030 (define_insn ""
1031   [(set (match_operand:SI 0 "register_operand" "=r")
1032         (minus:SI (match_operand:SI 1 "register_operand" "r")
1033                   (leu:SI (match_operand:SI 2 "register_operand" "r")
1034                           (match_operand:SI 3 "int11_operand" "I"))))]
1035   ""
1036   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1037   [(set_attr "type" "binary")
1038    (set_attr "length" "8")])
1040 (define_insn ""
1041   [(set (match_operand:DI 0 "register_operand" "=r")
1042         (minus:DI (match_operand:DI 1 "register_operand" "r")
1043                   (leu:DI (match_operand:DI 2 "register_operand" "r")
1044                           (match_operand:DI 3 "int11_operand" "I"))))]
1045   "TARGET_64BIT"
1046   "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1047   [(set_attr "type" "binary")
1048    (set_attr "length" "8")])
1050 (define_insn ""
1051   [(set (match_operand:SI 0 "register_operand" "=r")
1052         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1053                             (leu:SI (match_operand:SI 2 "register_operand" "r")
1054                                     (match_operand:SI 3 "int11_operand" "I")))
1055                   (match_operand:SI 4 "register_operand" "r")))]
1056   ""
1057   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1058   [(set_attr "type" "binary")
1059    (set_attr "length" "8")])
1061 (define_insn ""
1062   [(set (match_operand:DI 0 "register_operand" "=r")
1063         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1064                             (leu:DI (match_operand:DI 2 "register_operand" "r")
1065                                     (match_operand:DI 3 "int11_operand" "I")))
1066                   (match_operand:DI 4 "register_operand" "r")))]
1067   "TARGET_64BIT"
1068   "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1069   [(set_attr "type" "binary")
1070    (set_attr "length" "8")])
1072 (define_insn "decscc"
1073   [(set (match_operand:SI 0 "register_operand" "=r,r")
1074         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1075                   (match_operator:SI 4 "ordered_comparison_operator"
1076                      [(match_operand:SI 2 "register_operand" "r,r")
1077                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1078   ""
1079   "@
1080    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1081    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1082   [(set_attr "type" "binary,binary")
1083    (set_attr "length" "8,12")])
1085 (define_insn ""
1086   [(set (match_operand:DI 0 "register_operand" "=r,r")
1087         (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1088                   (match_operator:DI 4 "ordered_comparison_operator"
1089                      [(match_operand:DI 2 "register_operand" "r,r")
1090                       (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1091   "TARGET_64BIT"
1092   "@
1093    cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1094    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1095   [(set_attr "type" "binary,binary")
1096    (set_attr "length" "8,12")])
1098 ; Patterns for max and min.  (There is no need for an earlyclobber in the
1099 ; last alternative since the middle alternative will match if op0 == op1.)
1101 (define_insn "sminsi3"
1102   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1103         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1104                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1105   ""
1106   "@
1107   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1108   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1109   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1110 [(set_attr "type" "multi,multi,multi")
1111  (set_attr "length" "8,8,8")])
1113 (define_insn "smindi3"
1114   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1115         (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1116                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1117   "TARGET_64BIT"
1118   "@
1119   cmpclr,*> %2,%0,%%r0\;copy %2,%0
1120   cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1121   cmpclr,*> %1,%r2,%0\;copy %1,%0"
1122 [(set_attr "type" "multi,multi,multi")
1123  (set_attr "length" "8,8,8")])
1125 (define_insn "uminsi3"
1126   [(set (match_operand:SI 0 "register_operand" "=r,r")
1127         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1128                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1129   ""
1130   "@
1131   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1132   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1133 [(set_attr "type" "multi,multi")
1134  (set_attr "length" "8,8")])
1136 (define_insn "umindi3"
1137   [(set (match_operand:DI 0 "register_operand" "=r,r")
1138         (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1139                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1140   "TARGET_64BIT"
1141   "@
1142   cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1143   cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1144 [(set_attr "type" "multi,multi")
1145  (set_attr "length" "8,8")])
1147 (define_insn "smaxsi3"
1148   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1149         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1150                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1151   ""
1152   "@
1153   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1154   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1155   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1156 [(set_attr "type" "multi,multi,multi")
1157  (set_attr "length" "8,8,8")])
1159 (define_insn "smaxdi3"
1160   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1161         (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1162                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1163   "TARGET_64BIT"
1164   "@
1165   cmpclr,*< %2,%0,%%r0\;copy %2,%0
1166   cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1167   cmpclr,*< %1,%r2,%0\;copy %1,%0"
1168 [(set_attr "type" "multi,multi,multi")
1169  (set_attr "length" "8,8,8")])
1171 (define_insn "umaxsi3"
1172   [(set (match_operand:SI 0 "register_operand" "=r,r")
1173         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1174                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1175   ""
1176   "@
1177   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1178   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1179 [(set_attr "type" "multi,multi")
1180  (set_attr "length" "8,8")])
1182 (define_insn "umaxdi3"
1183   [(set (match_operand:DI 0 "register_operand" "=r,r")
1184         (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1185                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1186   "TARGET_64BIT"
1187   "@
1188   cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1189   cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1190 [(set_attr "type" "multi,multi")
1191  (set_attr "length" "8,8")])
1193 (define_insn "absqi2"
1194   [(set (match_operand:QI 0 "register_operand" "=r")
1195         (abs:QI (match_operand:QI 1 "register_operand" "r")))]
1196   ""
1197   "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1198   [(set_attr "type" "multi")
1199    (set_attr "length" "8")])
1201 (define_insn "abshi2"
1202   [(set (match_operand:HI 0 "register_operand" "=r")
1203         (abs:HI (match_operand:HI 1 "register_operand" "r")))]
1204   ""
1205   "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1206   [(set_attr "type" "multi")
1207    (set_attr "length" "8")])
1209 (define_insn "abssi2"
1210   [(set (match_operand:SI 0 "register_operand" "=r")
1211         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1212   ""
1213   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1214   [(set_attr "type" "multi")
1215    (set_attr "length" "8")])
1217 (define_insn "absdi2"
1218   [(set (match_operand:DI 0 "register_operand" "=r")
1219         (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1220   "TARGET_64BIT"
1221   "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1222   [(set_attr "type" "multi")
1223    (set_attr "length" "8")])
1225 (define_insn "bswaphi2"
1226   [(set (match_operand:HI 0 "register_operand" "=&r")
1227         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1228   ""
1229   "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1230   [(set_attr "type" "multi")
1231    (set_attr "length" "8")])
1233 (define_insn "bswapsi2"
1234   [(set (match_operand:SI 0 "register_operand" "=&r")
1235         (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1236   ""
1237   "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1238   [(set_attr "type" "multi")
1239    (set_attr "length" "12")])
1241 (define_insn "bswapdi2"
1242   [(set (match_operand:DI 0 "register_operand" "=&r")
1243         (bswap:DI (match_operand:DI 1 "register_operand" "r")))
1244    (clobber (match_scratch:DI 2 "=r"))]
1245   "TARGET_64BIT"
1246   "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1247   [(set_attr "type" "multi")
1248    (set_attr "length" "16")])
1250 ;;; Experimental conditional move patterns
1252 (define_expand "movsicc"
1253   [(set (match_operand:SI 0 "register_operand" "")
1254         (if_then_else:SI
1255          (match_operand 1 "ordered_comparison_operator" "")
1256          (match_operand:SI 2 "reg_or_cint_move_operand" "")
1257          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1258   ""
1259   "
1261   if (GET_MODE (XEXP (operands[1], 0)) != SImode
1262       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1263     FAIL;
1266 ;; We used to accept any register for op1.
1268 ;; However, it loses sometimes because the compiler will end up using
1269 ;; different registers for op0 and op1 in some critical cases.  local-alloc
1270 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1272 ;; If/when global register allocation supports tying we should allow any
1273 ;; register for op1 again.
1274 (define_insn ""
1275   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1276         (if_then_else:SI
1277          (match_operator 2 "ordered_comparison_operator"
1278             [(match_operand:SI 3 "register_operand" "r,r,r,r")
1279              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1280          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1281          (const_int 0)))]
1282   ""
1283   "@
1284    {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1285    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1286    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1287    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1288   [(set_attr "type" "multi,multi,multi,nullshift")
1289    (set_attr "length" "8,8,8,8")])
1291 (define_insn ""
1292   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1293         (if_then_else:SI
1294          (match_operator 5 "ordered_comparison_operator"
1295             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1296              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1297          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1298          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1299   ""
1300   "@
1301    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1302    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1303    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1304    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1305    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1306    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1307    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1308    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1309   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1310    (set_attr "length" "8,8,8,8,8,8,8,8")])
1312 (define_expand "movdicc"
1313   [(set (match_operand:DI 0 "register_operand" "")
1314         (if_then_else:DI
1315          (match_operand 1 "ordered_comparison_operator" "")
1316          (match_operand:DI 2 "reg_or_cint_move_operand" "")
1317          (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1318   "TARGET_64BIT"
1319   "
1321   if (GET_MODE (XEXP (operands[1], 0)) != DImode
1322       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1323     FAIL;
1326 ; We need the first constraint alternative in order to avoid
1327 ; earlyclobbers on all other alternatives.
1328 (define_insn ""
1329   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1330         (if_then_else:DI
1331          (match_operator 2 "ordered_comparison_operator"
1332             [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1333              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1334          (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1335          (const_int 0)))]
1336   "TARGET_64BIT"
1337   "@
1338    cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1339    cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1340    cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1341    cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1342    cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1343   [(set_attr "type" "multi,multi,multi,multi,nullshift")
1344    (set_attr "length" "8,8,8,8,8")])
1346 (define_insn ""
1347   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1348         (if_then_else:DI
1349          (match_operator 5 "ordered_comparison_operator"
1350             [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1351              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1352          (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1353          (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1354   "TARGET_64BIT"
1355   "@
1356    cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1357    cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1358    cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1359    cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1360    cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1361    cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1362    cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1363    cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1364   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1365    (set_attr "length" "8,8,8,8,8,8,8,8")])
1367 ;; Conditional Branches
1369 (define_expand "cbranchdi4"
1370   [(set (pc)
1371         (if_then_else (match_operator 0 "ordered_comparison_operator"
1372                        [(match_operand:DI 1 "reg_or_0_operand" "")
1373                         (match_operand:DI 2 "register_operand" "")])
1374                       (label_ref (match_operand 3 "" ""))
1375                       (pc)))]
1376   "TARGET_64BIT"
1377   "")
1379 (define_expand "cbranchsi4"
1380   [(set (pc)
1381         (if_then_else (match_operator 0 "ordered_comparison_operator"
1382                        [(match_operand:SI 1 "reg_or_0_operand" "")
1383                         (match_operand:SI 2 "arith5_operand" "")])
1384                       (label_ref (match_operand 3 "" ""))
1385                       (pc)))]
1386   ""
1387   "")
1389 (define_expand "cbranchsf4"
1390   [(set (pc)
1391         (if_then_else (match_operator 0 "comparison_operator"
1392                        [(match_operand:SF 1 "reg_or_0_operand" "")
1393                         (match_operand:SF 2 "reg_or_0_operand" "")])
1394                       (label_ref (match_operand 3 "" ""))
1395                       (pc)))]
1396   "! TARGET_SOFT_FLOAT"
1397   "
1399   pa_emit_bcond_fp (operands);
1400   DONE;
1404 (define_expand "cbranchdf4"
1405   [(set (pc)
1406         (if_then_else (match_operator 0 "comparison_operator"
1407                        [(match_operand:DF 1 "reg_or_0_operand" "")
1408                         (match_operand:DF 2 "reg_or_0_operand" "")])
1409                       (label_ref (match_operand 3 "" ""))
1410                       (pc)))]
1411   "! TARGET_SOFT_FLOAT"
1412   "
1414   pa_emit_bcond_fp (operands);
1415   DONE;
1418 ;; Match the branch patterns.
1421 ;; Note a long backward conditional branch with an annulled delay slot
1422 ;; has a length of 12.
1423 (define_insn ""
1424   [(set (pc)
1425         (if_then_else
1426          (match_operator 3 "ordered_comparison_operator"
1427                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1428                           (match_operand:SI 2 "arith5_operand" "rL")])
1429          (label_ref (match_operand 0 "" ""))
1430          (pc)))]
1431   ""
1432   "*
1434   return pa_output_cbranch (operands, 0, insn);
1436 [(set_attr "type" "cbranch")
1437  (set (attr "length")
1438     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1439                (const_int MAX_12BIT_OFFSET))
1440            (const_int 4)
1441            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1442                (const_int MAX_17BIT_OFFSET))
1443            (const_int 8)
1444            (match_test "TARGET_PORTABLE_RUNTIME")
1445            (const_int 24)
1446            (not (match_test "flag_pic"))
1447            (const_int 20)]
1448           (const_int 28)))])
1450 ;; Match the negated branch.
1452 (define_insn ""
1453   [(set (pc)
1454         (if_then_else
1455          (match_operator 3 "ordered_comparison_operator"
1456                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1457                           (match_operand:SI 2 "arith5_operand" "rL")])
1458          (pc)
1459          (label_ref (match_operand 0 "" ""))))]
1460   ""
1461   "*
1463   return pa_output_cbranch (operands, 1, insn);
1465 [(set_attr "type" "cbranch")
1466  (set (attr "length")
1467     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1468                (const_int MAX_12BIT_OFFSET))
1469            (const_int 4)
1470            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1471                (const_int MAX_17BIT_OFFSET))
1472            (const_int 8)
1473            (match_test "TARGET_PORTABLE_RUNTIME")
1474            (const_int 24)
1475            (not (match_test "flag_pic"))
1476            (const_int 20)]
1477           (const_int 28)))])
1479 (define_insn ""
1480   [(set (pc)
1481         (if_then_else
1482          (match_operator 3 "ordered_comparison_operator"
1483                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1484                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1485          (label_ref (match_operand 0 "" ""))
1486          (pc)))]
1487   "TARGET_64BIT"
1488   "*
1490   return pa_output_cbranch (operands, 0, insn);
1492 [(set_attr "type" "cbranch")
1493  (set (attr "length")
1494     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1495                (const_int MAX_12BIT_OFFSET))
1496            (const_int 4)
1497            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1498                (const_int MAX_17BIT_OFFSET))
1499            (const_int 8)
1500            (match_test "TARGET_PORTABLE_RUNTIME")
1501            (const_int 24)
1502            (not (match_test "flag_pic"))
1503            (const_int 20)]
1504           (const_int 28)))])
1506 ;; Match the negated branch.
1508 (define_insn ""
1509   [(set (pc)
1510         (if_then_else
1511          (match_operator 3 "ordered_comparison_operator"
1512                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1513                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1514          (pc)
1515          (label_ref (match_operand 0 "" ""))))]
1516   "TARGET_64BIT"
1517   "*
1519   return pa_output_cbranch (operands, 1, insn);
1521 [(set_attr "type" "cbranch")
1522  (set (attr "length")
1523     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1524                (const_int MAX_12BIT_OFFSET))
1525            (const_int 4)
1526            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1527                (const_int MAX_17BIT_OFFSET))
1528            (const_int 8)
1529            (match_test "TARGET_PORTABLE_RUNTIME")
1530            (const_int 24)
1531            (not (match_test "flag_pic"))
1532            (const_int 20)]
1533           (const_int 28)))])
1534 (define_insn ""
1535   [(set (pc)
1536         (if_then_else
1537          (match_operator 3 "cmpib_comparison_operator"
1538                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1539                           (match_operand:DI 2 "arith5_operand" "rL")])
1540          (label_ref (match_operand 0 "" ""))
1541          (pc)))]
1542   "TARGET_64BIT"
1543   "*
1545   return pa_output_cbranch (operands, 0, insn);
1547 [(set_attr "type" "cbranch")
1548  (set (attr "length")
1549     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1550                (const_int MAX_12BIT_OFFSET))
1551            (const_int 4)
1552            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1553                (const_int MAX_17BIT_OFFSET))
1554            (const_int 8)
1555            (match_test "TARGET_PORTABLE_RUNTIME")
1556            (const_int 24)
1557            (not (match_test "flag_pic"))
1558            (const_int 20)]
1559           (const_int 28)))])
1561 ;; Match the negated branch.
1563 (define_insn ""
1564   [(set (pc)
1565         (if_then_else
1566          (match_operator 3 "cmpib_comparison_operator"
1567                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1568                           (match_operand:DI 2 "arith5_operand" "rL")])
1569          (pc)
1570          (label_ref (match_operand 0 "" ""))))]
1571   "TARGET_64BIT"
1572   "*
1574   return pa_output_cbranch (operands, 1, insn);
1576 [(set_attr "type" "cbranch")
1577  (set (attr "length")
1578     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1579                (const_int MAX_12BIT_OFFSET))
1580            (const_int 4)
1581            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1582                (const_int MAX_17BIT_OFFSET))
1583            (const_int 8)
1584            (match_test "TARGET_PORTABLE_RUNTIME")
1585            (const_int 24)
1586            (not (match_test "flag_pic"))
1587            (const_int 20)]
1588           (const_int 28)))])
1590 ;; Branch on Bit patterns.
1591 (define_insn ""
1592   [(set (pc)
1593         (if_then_else
1594          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1595                               (const_int 1)
1596                               (match_operand:SI 1 "uint5_operand" ""))
1597              (const_int 0))
1598          (label_ref (match_operand 2 "" ""))
1599          (pc)))]
1600   ""
1601   "*
1603   return pa_output_bb (operands, 0, insn, 0);
1605 [(set_attr "type" "cbranch")
1606  (set (attr "length")
1607     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1608                (const_int MAX_12BIT_OFFSET))
1609            (const_int 4)
1610            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1611                (const_int MAX_17BIT_OFFSET))
1612            (const_int 8)
1613            (match_test "TARGET_PORTABLE_RUNTIME")
1614            (const_int 24)
1615            (not (match_test "flag_pic"))
1616            (const_int 20)]
1617           (const_int 28)))])
1619 (define_insn ""
1620   [(set (pc)
1621         (if_then_else
1622          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1623                               (const_int 1)
1624                               (match_operand:DI 1 "uint32_operand" ""))
1625              (const_int 0))
1626          (label_ref (match_operand 2 "" ""))
1627          (pc)))]
1628   "TARGET_64BIT"
1629   "*
1631   return pa_output_bb (operands, 0, insn, 0);
1633 [(set_attr "type" "cbranch")
1634  (set (attr "length")
1635     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1636                (const_int MAX_12BIT_OFFSET))
1637            (const_int 4)
1638            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1639                (const_int MAX_17BIT_OFFSET))
1640            (const_int 8)
1641            (match_test "TARGET_PORTABLE_RUNTIME")
1642            (const_int 24)
1643            (not (match_test "flag_pic"))
1644            (const_int 20)]
1645           (const_int 28)))])
1647 (define_insn ""
1648   [(set (pc)
1649         (if_then_else
1650          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1651                               (const_int 1)
1652                               (match_operand:SI 1 "uint5_operand" ""))
1653              (const_int 0))
1654          (pc)
1655          (label_ref (match_operand 2 "" ""))))]
1656   ""
1657   "*
1659   return pa_output_bb (operands, 1, insn, 0);
1661 [(set_attr "type" "cbranch")
1662  (set (attr "length")
1663     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1664                (const_int MAX_12BIT_OFFSET))
1665            (const_int 4)
1666            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1667                (const_int MAX_17BIT_OFFSET))
1668            (const_int 8)
1669            (match_test "TARGET_PORTABLE_RUNTIME")
1670            (const_int 24)
1671            (not (match_test "flag_pic"))
1672            (const_int 20)]
1673           (const_int 28)))])
1675 (define_insn ""
1676   [(set (pc)
1677         (if_then_else
1678          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1679                               (const_int 1)
1680                               (match_operand:DI 1 "uint32_operand" ""))
1681              (const_int 0))
1682          (pc)
1683          (label_ref (match_operand 2 "" ""))))]
1684   "TARGET_64BIT"
1685   "*
1687   return pa_output_bb (operands, 1, insn, 0);
1689 [(set_attr "type" "cbranch")
1690  (set (attr "length")
1691     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1692                (const_int MAX_12BIT_OFFSET))
1693            (const_int 4)
1694            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1695                (const_int MAX_17BIT_OFFSET))
1696            (const_int 8)
1697            (match_test "TARGET_PORTABLE_RUNTIME")
1698            (const_int 24)
1699            (not (match_test "flag_pic"))
1700            (const_int 20)]
1701           (const_int 28)))])
1703 (define_insn ""
1704   [(set (pc)
1705         (if_then_else
1706          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1707                               (const_int 1)
1708                               (match_operand:SI 1 "uint5_operand" ""))
1709              (const_int 0))
1710          (label_ref (match_operand 2 "" ""))
1711          (pc)))]
1712   ""
1713   "*
1715   return pa_output_bb (operands, 0, insn, 1);
1717 [(set_attr "type" "cbranch")
1718  (set (attr "length")
1719     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1720                (const_int MAX_12BIT_OFFSET))
1721            (const_int 4)
1722            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1723                (const_int MAX_17BIT_OFFSET))
1724            (const_int 8)
1725            (match_test "TARGET_PORTABLE_RUNTIME")
1726            (const_int 24)
1727            (not (match_test "flag_pic"))
1728            (const_int 20)]
1729           (const_int 28)))])
1731 (define_insn ""
1732   [(set (pc)
1733         (if_then_else
1734          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1735                               (const_int 1)
1736                               (match_operand:DI 1 "uint32_operand" ""))
1737              (const_int 0))
1738          (label_ref (match_operand 2 "" ""))
1739          (pc)))]
1740   "TARGET_64BIT"
1741   "*
1743   return pa_output_bb (operands, 0, insn, 1);
1745 [(set_attr "type" "cbranch")
1746  (set (attr "length")
1747     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1748                (const_int MAX_12BIT_OFFSET))
1749            (const_int 4)
1750            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1751                (const_int MAX_17BIT_OFFSET))
1752            (const_int 8)
1753            (match_test "TARGET_PORTABLE_RUNTIME")
1754            (const_int 24)
1755            (not (match_test "flag_pic"))
1756            (const_int 20)]
1757           (const_int 28)))])
1759 (define_insn ""
1760   [(set (pc)
1761         (if_then_else
1762          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1763                               (const_int 1)
1764                               (match_operand:SI 1 "uint5_operand" ""))
1765              (const_int 0))
1766          (pc)
1767          (label_ref (match_operand 2 "" ""))))]
1768   ""
1769   "*
1771   return pa_output_bb (operands, 1, insn, 1);
1773 [(set_attr "type" "cbranch")
1774  (set (attr "length")
1775     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1776                (const_int MAX_12BIT_OFFSET))
1777            (const_int 4)
1778            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1779                (const_int MAX_17BIT_OFFSET))
1780            (const_int 8)
1781            (match_test "TARGET_PORTABLE_RUNTIME")
1782            (const_int 24)
1783            (not (match_test "flag_pic"))
1784            (const_int 20)]
1785           (const_int 28)))])
1787 (define_insn ""
1788   [(set (pc)
1789         (if_then_else
1790          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1791                               (const_int 1)
1792                               (match_operand:DI 1 "uint32_operand" ""))
1793              (const_int 0))
1794          (pc)
1795          (label_ref (match_operand 2 "" ""))))]
1796   "TARGET_64BIT"
1797   "*
1799   return pa_output_bb (operands, 1, insn, 1);
1801 [(set_attr "type" "cbranch")
1802  (set (attr "length")
1803     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1804                (const_int MAX_12BIT_OFFSET))
1805            (const_int 4)
1806            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1807                (const_int MAX_17BIT_OFFSET))
1808            (const_int 8)
1809            (match_test "TARGET_PORTABLE_RUNTIME")
1810            (const_int 24)
1811            (not (match_test "flag_pic"))
1812            (const_int 20)]
1813           (const_int 28)))])
1815 ;; Branch on Variable Bit patterns.
1816 (define_insn ""
1817   [(set (pc)
1818         (if_then_else
1819          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1820                               (const_int 1)
1821                               (match_operand:SI 1 "register_operand" "q"))
1822              (const_int 0))
1823          (label_ref (match_operand 2 "" ""))
1824          (pc)))]
1825   ""
1826   "*
1828   return pa_output_bvb (operands, 0, insn, 0);
1830 [(set_attr "type" "cbranch")
1831  (set (attr "length")
1832     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1833                (const_int MAX_12BIT_OFFSET))
1834            (const_int 4)
1835            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1836                (const_int MAX_17BIT_OFFSET))
1837            (const_int 8)
1838            (match_test "TARGET_PORTABLE_RUNTIME")
1839            (const_int 24)
1840            (not (match_test "flag_pic"))
1841            (const_int 20)]
1842           (const_int 28)))])
1844 (define_insn ""
1845   [(set (pc)
1846         (if_then_else
1847          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1848                               (const_int 1)
1849                               (match_operand:DI 1 "register_operand" "q"))
1850              (const_int 0))
1851          (label_ref (match_operand 2 "" ""))
1852          (pc)))]
1853   "TARGET_64BIT"
1854   "*
1856   return pa_output_bvb (operands, 0, insn, 0);
1858 [(set_attr "type" "cbranch")
1859  (set (attr "length")
1860     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1861                (const_int MAX_12BIT_OFFSET))
1862            (const_int 4)
1863            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1864                (const_int MAX_17BIT_OFFSET))
1865            (const_int 8)
1866            (match_test "TARGET_PORTABLE_RUNTIME")
1867            (const_int 24)
1868            (not (match_test "flag_pic"))
1869            (const_int 20)]
1870           (const_int 28)))])
1872 (define_insn ""
1873   [(set (pc)
1874         (if_then_else
1875          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1876                               (const_int 1)
1877                               (match_operand:SI 1 "register_operand" "q"))
1878              (const_int 0))
1879          (pc)
1880          (label_ref (match_operand 2 "" ""))))]
1881   ""
1882   "*
1884   return pa_output_bvb (operands, 1, insn, 0);
1886 [(set_attr "type" "cbranch")
1887  (set (attr "length")
1888     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1889                (const_int MAX_12BIT_OFFSET))
1890            (const_int 4)
1891            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1892                (const_int MAX_17BIT_OFFSET))
1893            (const_int 8)
1894            (match_test "TARGET_PORTABLE_RUNTIME")
1895            (const_int 24)
1896            (not (match_test "flag_pic"))
1897            (const_int 20)]
1898           (const_int 28)))])
1900 (define_insn ""
1901   [(set (pc)
1902         (if_then_else
1903          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1904                               (const_int 1)
1905                               (match_operand:DI 1 "register_operand" "q"))
1906              (const_int 0))
1907          (pc)
1908          (label_ref (match_operand 2 "" ""))))]
1909   "TARGET_64BIT"
1910   "*
1912   return pa_output_bvb (operands, 1, insn, 0);
1914 [(set_attr "type" "cbranch")
1915  (set (attr "length")
1916     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1917                (const_int MAX_12BIT_OFFSET))
1918            (const_int 4)
1919            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1920                (const_int MAX_17BIT_OFFSET))
1921            (const_int 8)
1922            (match_test "TARGET_PORTABLE_RUNTIME")
1923            (const_int 24)
1924            (not (match_test "flag_pic"))
1925            (const_int 20)]
1926           (const_int 28)))])
1928 (define_insn ""
1929   [(set (pc)
1930         (if_then_else
1931          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1932                               (const_int 1)
1933                               (match_operand:SI 1 "register_operand" "q"))
1934              (const_int 0))
1935          (label_ref (match_operand 2 "" ""))
1936          (pc)))]
1937   ""
1938   "*
1940   return pa_output_bvb (operands, 0, insn, 1);
1942 [(set_attr "type" "cbranch")
1943  (set (attr "length")
1944     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1945                (const_int MAX_12BIT_OFFSET))
1946            (const_int 4)
1947            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1948                (const_int MAX_17BIT_OFFSET))
1949            (const_int 8)
1950            (match_test "TARGET_PORTABLE_RUNTIME")
1951            (const_int 24)
1952            (not (match_test "flag_pic"))
1953            (const_int 20)]
1954           (const_int 28)))])
1956 (define_insn ""
1957   [(set (pc)
1958         (if_then_else
1959          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1960                               (const_int 1)
1961                               (match_operand:DI 1 "register_operand" "q"))
1962              (const_int 0))
1963          (label_ref (match_operand 2 "" ""))
1964          (pc)))]
1965   "TARGET_64BIT"
1966   "*
1968   return pa_output_bvb (operands, 0, insn, 1);
1970 [(set_attr "type" "cbranch")
1971  (set (attr "length")
1972     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1973                (const_int MAX_12BIT_OFFSET))
1974            (const_int 4)
1975            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1976                (const_int MAX_17BIT_OFFSET))
1977            (const_int 8)
1978            (match_test "TARGET_PORTABLE_RUNTIME")
1979            (const_int 24)
1980            (not (match_test "flag_pic"))
1981            (const_int 20)]
1982           (const_int 28)))])
1984 (define_insn ""
1985   [(set (pc)
1986         (if_then_else
1987          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1988                               (const_int 1)
1989                               (match_operand:SI 1 "register_operand" "q"))
1990              (const_int 0))
1991          (pc)
1992          (label_ref (match_operand 2 "" ""))))]
1993   ""
1994   "*
1996   return pa_output_bvb (operands, 1, insn, 1);
1998 [(set_attr "type" "cbranch")
1999  (set (attr "length")
2000     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2001                (const_int MAX_12BIT_OFFSET))
2002            (const_int 4)
2003            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2004                (const_int MAX_17BIT_OFFSET))
2005            (const_int 8)
2006            (match_test "TARGET_PORTABLE_RUNTIME")
2007            (const_int 24)
2008            (not (match_test "flag_pic"))
2009            (const_int 20)]
2010           (const_int 28)))])
2012 (define_insn ""
2013   [(set (pc)
2014         (if_then_else
2015          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2016                               (const_int 1)
2017                               (match_operand:DI 1 "register_operand" "q"))
2018              (const_int 0))
2019          (pc)
2020          (label_ref (match_operand 2 "" ""))))]
2021   "TARGET_64BIT"
2022   "*
2024   return pa_output_bvb (operands, 1, insn, 1);
2026 [(set_attr "type" "cbranch")
2027  (set (attr "length")
2028     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2029                (const_int MAX_12BIT_OFFSET))
2030            (const_int 4)
2031            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2032                (const_int MAX_17BIT_OFFSET))
2033            (const_int 8)
2034            (match_test "TARGET_PORTABLE_RUNTIME")
2035            (const_int 24)
2036            (not (match_test "flag_pic"))
2037            (const_int 20)]
2038           (const_int 28)))])
2040 ;; Floating point branches
2042 ;; ??? Nullification is handled differently from other branches.
2043 ;; If nullification is specified, the delay slot is nullified on any
2044 ;; taken branch regardless of branch direction.
2045 (define_insn ""
2046   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2047                            (label_ref (match_operand 0 "" ""))
2048                            (pc)))]
2049   "!TARGET_SOFT_FLOAT"
2050   "*
2052   int length = get_attr_length (insn);
2053   rtx xoperands[1];
2054   int nullify, xdelay;
2056   if (length < 16)
2057     return \"ftest\;b%* %l0\";
2059   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2060     {
2061       nullify = 1;
2062       xdelay = 0;
2063       xoperands[0] = GEN_INT (length - 8);
2064     }
2065   else
2066     {
2067       nullify = 0;
2068       xdelay = 1;
2069       xoperands[0] = GEN_INT (length - 4);
2070     }
2072   if (nullify)
2073     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2074   else
2075     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2076   return pa_output_lbranch (operands[0], insn, xdelay);
2078 [(set_attr "type" "fbranch")
2079  (set (attr "length")
2080     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2081                (const_int MAX_17BIT_OFFSET))
2082            (const_int 8)
2083            (match_test "TARGET_PORTABLE_RUNTIME")
2084            (const_int 32)
2085            (not (match_test "flag_pic"))
2086            (const_int 28)]
2087           (const_int 36)))])
2089 (define_insn ""
2090   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2091                            (pc)
2092                            (label_ref (match_operand 0 "" ""))))]
2093   "!TARGET_SOFT_FLOAT"
2094   "*
2096   int length = get_attr_length (insn);
2097   rtx xoperands[1];
2098   int nullify, xdelay;
2100   if (length < 16)
2101     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2103   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2104     {
2105       nullify = 1;
2106       xdelay = 0;
2107       xoperands[0] = GEN_INT (length - 4);
2108     }
2109   else
2110     {
2111       nullify = 0;
2112       xdelay = 1;
2113       xoperands[0] = GEN_INT (length);
2114     }
2116   if (nullify)
2117     output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2118   else
2119     output_asm_insn (\"ftest\;b .+%0\", xoperands);
2120   return pa_output_lbranch (operands[0], insn, xdelay);
2122 [(set_attr "type" "fbranch")
2123  (set (attr "length")
2124     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2125                (const_int MAX_17BIT_OFFSET))
2126            (const_int 12)
2127            (match_test "TARGET_PORTABLE_RUNTIME")
2128            (const_int 28)
2129            (not (match_test "flag_pic"))
2130            (const_int 24)]
2131           (const_int 32)))])
2133 ;; Move instructions
2135 (define_expand "movsi"
2136   [(set (match_operand:SI 0 "general_operand" "")
2137         (match_operand:SI 1 "general_operand" ""))]
2138   ""
2139   "
2141   if (pa_emit_move_sequence (operands, SImode, 0))
2142     DONE;
2145 ;; Handle SImode input reloads requiring %r1 as a scratch register.
2146 (define_expand "reload_insi_r1"
2147   [(set (match_operand:SI 0 "register_operand" "=Z")
2148         (match_operand:SI 1 "non_hard_reg_operand" ""))
2149    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2150   ""
2151   "
2153   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2154     DONE;
2156   /* We don't want the clobber emitted, so handle this ourselves.  */
2157   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2158   DONE;
2161 ;; Handle SImode input reloads requiring a general register as a
2162 ;; scratch register.
2163 (define_expand "reload_insi"
2164   [(set (match_operand:SI 0 "register_operand" "=Z")
2165         (match_operand:SI 1 "non_hard_reg_operand" ""))
2166    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2167   ""
2168   "
2170   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2171     DONE;
2173   /* We don't want the clobber emitted, so handle this ourselves.  */
2174   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2175   DONE;
2178 ;; Handle SImode output reloads requiring a general register as a
2179 ;; scratch register.
2180 (define_expand "reload_outsi"
2181   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2182         (match_operand:SI 1  "register_operand" "Z"))
2183    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2184   ""
2185   "
2187   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2188     DONE;
2190   /* We don't want the clobber emitted, so handle this ourselves.  */
2191   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2192   DONE;
2195 (define_insn ""
2196   [(set (match_operand:SI 0 "move_dest_operand"
2197                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2198         (match_operand:SI 1 "move_src_operand"
2199                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2200   "(register_operand (operands[0], SImode)
2201     || reg_or_0_operand (operands[1], SImode))
2202    && !TARGET_SOFT_FLOAT
2203    && !TARGET_64BIT"
2204   "@
2205    ldw RT'%A1,%0
2206    copy %1,%0
2207    ldi %1,%0
2208    ldil L'%1,%0
2209    {zdepi|depwi,z} %Z1,%0
2210    ldw%M1 %1,%0
2211    stw%M0 %r1,%0
2212    mtsar %r1
2213    {mfctl|mfctl,w} %%sar,%0
2214    fcpy,sgl %f1,%0
2215    fldw%F1 %1,%0
2216    fstw%F0 %1,%0
2217    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2218    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2219   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2220    (set_attr "pa_combine_type" "addmove")
2221    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2223 (define_insn ""
2224   [(set (match_operand:SI 0 "move_dest_operand"
2225                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2226         (match_operand:SI 1 "move_src_operand"
2227                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2228   "(register_operand (operands[0], SImode)
2229     || reg_or_0_operand (operands[1], SImode))
2230    && !TARGET_SOFT_FLOAT
2231    && TARGET_64BIT"
2232   "@
2233    ldw RT'%A1,%0
2234    copy %1,%0
2235    ldi %1,%0
2236    ldil L'%1,%0
2237    {zdepi|depwi,z} %Z1,%0
2238    ldw%M1 %1,%0
2239    stw%M0 %r1,%0
2240    mtsar %r1
2241    {mfctl|mfctl,w} %%sar,%0
2242    fcpy,sgl %f1,%0
2243    fldw%F1 %1,%0
2244    fstw%F0 %1,%0"
2245   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2246    (set_attr "pa_combine_type" "addmove")
2247    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2249 (define_insn ""
2250   [(set (match_operand:SI 0 "move_dest_operand"
2251                           "=r,r,r,r,r,r,Q,!*q,!r")
2252         (match_operand:SI 1 "move_src_operand"
2253                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2254   "(register_operand (operands[0], SImode)
2255     || reg_or_0_operand (operands[1], SImode))
2256    && TARGET_SOFT_FLOAT
2257    && TARGET_64BIT"
2258   "@
2259    ldw RT'%A1,%0
2260    copy %1,%0
2261    ldi %1,%0
2262    ldil L'%1,%0
2263    {zdepi|depwi,z} %Z1,%0
2264    ldw%M1 %1,%0
2265    stw%M0 %r1,%0
2266    mtsar %r1
2267    {mfctl|mfctl,w} %%sar,%0"
2268   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
2269    (set_attr "pa_combine_type" "addmove")
2270    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2272 (define_insn ""
2273   [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2274         (match_operand:SI 1 "register_operand" "f"))]
2275   "!TARGET_SOFT_FLOAT
2276    && !TARGET_DISABLE_INDEXING
2277    && reload_completed"
2278   "fstw%F0 %1,%0"
2279   [(set_attr "type" "fpstore")
2280    (set_attr "pa_combine_type" "addmove")
2281    (set_attr "length" "4")])
2283 ; Rewrite RTL using an indexed store.  This will allow the insn that
2284 ; computes the address to be deleted if the register it sets is dead.
2285 (define_peephole2
2286   [(set (match_operand:SI 0 "register_operand" "")
2287         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2288                             (const_int 2))
2289                  (match_operand:SI 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    && REG_OK_FOR_BASE_P (operands[2])
2295    && FP_REGNO_P (REGNO (operands[3]))"
2296   [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2297         (match_dup 3))
2298    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2299                                (match_dup 2)))]
2300   "")
2302 (define_peephole2
2303   [(set (match_operand:DI 0 "register_operand" "")
2304         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2305                             (const_int 2))
2306                  (match_operand:DI 2 "register_operand" "")))
2307    (set (mem:SI (match_dup 0))
2308         (match_operand:SI 3 "register_operand" ""))]
2309   "!TARGET_SOFT_FLOAT
2310    && !TARGET_DISABLE_INDEXING
2311    && TARGET_64BIT
2312    && REG_OK_FOR_BASE_P (operands[2])
2313    && FP_REGNO_P (REGNO (operands[3]))"
2314   [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2315         (match_dup 3))
2316    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2317                                (match_dup 2)))]
2318   "")
2320 (define_peephole2
2321   [(set (match_operand:SI 0 "register_operand" "")
2322         (plus:SI (match_operand:SI 1 "register_operand" "")
2323                  (match_operand:SI 2 "register_operand" "")))
2324    (set (mem:SI (match_dup 0))
2325         (match_operand:SI 3 "register_operand" ""))]
2326   "!TARGET_SOFT_FLOAT
2327    && !TARGET_DISABLE_INDEXING
2328    && TARGET_NO_SPACE_REGS
2329    && REG_OK_FOR_INDEX_P (operands[1])
2330    && REG_OK_FOR_BASE_P (operands[2])
2331    && FP_REGNO_P (REGNO (operands[3]))"
2332   [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2333         (match_dup 3))
2334    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2335   "")
2337 (define_peephole2
2338   [(set (match_operand:SI 0 "register_operand" "")
2339         (plus:SI (match_operand:SI 1 "register_operand" "")
2340                  (match_operand:SI 2 "register_operand" "")))
2341    (set (mem:SI (match_dup 0))
2342         (match_operand:SI 3 "register_operand" ""))]
2343   "!TARGET_SOFT_FLOAT
2344    && !TARGET_DISABLE_INDEXING
2345    && TARGET_NO_SPACE_REGS
2346    && REG_OK_FOR_BASE_P (operands[1])
2347    && REG_OK_FOR_INDEX_P (operands[2])
2348    && FP_REGNO_P (REGNO (operands[3]))"
2349   [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2350         (match_dup 3))
2351    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2352   "")
2354 (define_peephole2
2355   [(set (match_operand:DI 0 "register_operand" "")
2356         (plus:DI (match_operand:DI 1 "register_operand" "")
2357                  (match_operand:DI 2 "register_operand" "")))
2358    (set (mem:SI (match_dup 0))
2359         (match_operand:SI 3 "register_operand" ""))]
2360   "!TARGET_SOFT_FLOAT
2361    && !TARGET_DISABLE_INDEXING
2362    && TARGET_64BIT
2363    && TARGET_NO_SPACE_REGS
2364    && REG_OK_FOR_INDEX_P (operands[1])
2365    && REG_OK_FOR_BASE_P (operands[2])
2366    && FP_REGNO_P (REGNO (operands[3]))"
2367   [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2368         (match_dup 3))
2369    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2370   "")
2372 (define_peephole2
2373   [(set (match_operand:DI 0 "register_operand" "")
2374         (plus:DI (match_operand:DI 1 "register_operand" "")
2375                  (match_operand:DI 2 "register_operand" "")))
2376    (set (mem:SI (match_dup 0))
2377         (match_operand:SI 3 "register_operand" ""))]
2378   "!TARGET_SOFT_FLOAT
2379    && !TARGET_DISABLE_INDEXING
2380    && TARGET_64BIT
2381    && TARGET_NO_SPACE_REGS
2382    && REG_OK_FOR_BASE_P (operands[1])
2383    && REG_OK_FOR_INDEX_P (operands[2])
2384    && FP_REGNO_P (REGNO (operands[3]))"
2385   [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2386         (match_dup 3))
2387    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2388   "")
2390 (define_insn ""
2391   [(set (match_operand:SI 0 "move_dest_operand"
2392                           "=r,r,r,r,r,r,Q,!*q,!r")
2393         (match_operand:SI 1 "move_src_operand"
2394                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2395   "(register_operand (operands[0], SImode)
2396     || reg_or_0_operand (operands[1], SImode))
2397    && TARGET_SOFT_FLOAT"
2398   "@
2399    ldw RT'%A1,%0
2400    copy %1,%0
2401    ldi %1,%0
2402    ldil L'%1,%0
2403    {zdepi|depwi,z} %Z1,%0
2404    ldw%M1 %1,%0
2405    stw%M0 %r1,%0
2406    mtsar %r1
2407    {mfctl|mfctl,w} %%sar,%0"
2408   [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2409    (set_attr "pa_combine_type" "addmove")
2410    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2412 ;; Load or store with base-register modification.
2413 (define_insn ""
2414   [(set (match_operand:SI 0 "register_operand" "=r")
2415         (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2416                          (match_operand:DI 2 "int5_operand" "L"))))
2417    (set (match_dup 1)
2418         (plus:DI (match_dup 1) (match_dup 2)))]
2419   "TARGET_64BIT"
2420   "ldw,mb %2(%1),%0"
2421   [(set_attr "type" "load")
2422    (set_attr "length" "4")])
2424 ; And a zero extended variant.
2425 (define_insn ""
2426   [(set (match_operand:DI 0 "register_operand" "=r")
2427         (zero_extend:DI (mem:SI
2428                           (plus:DI
2429                             (match_operand:DI 1 "register_operand" "+r")
2430                             (match_operand:DI 2 "int5_operand" "L")))))
2431    (set (match_dup 1)
2432         (plus:DI (match_dup 1) (match_dup 2)))]
2433   "TARGET_64BIT"
2434   "ldw,mb %2(%1),%0"
2435   [(set_attr "type" "load")
2436    (set_attr "length" "4")])
2438 (define_expand "pre_load"
2439   [(parallel [(set (match_operand:SI 0 "register_operand" "")
2440               (mem (plus (match_operand 1 "register_operand" "")
2441                                (match_operand 2 "pre_cint_operand" ""))))
2442               (set (match_dup 1)
2443                    (plus (match_dup 1) (match_dup 2)))])]
2444   ""
2445   "
2447   if (TARGET_64BIT)
2448     {
2449       emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2450       DONE;
2451     }
2452   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2453   DONE;
2456 (define_insn "pre_ldw"
2457   [(set (match_operand:SI 0 "register_operand" "=r")
2458         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2459                          (match_operand:SI 2 "pre_cint_operand" ""))))
2460    (set (match_dup 1)
2461         (plus:SI (match_dup 1) (match_dup 2)))]
2462   ""
2463   "*
2465   if (INTVAL (operands[2]) < 0)
2466     return \"{ldwm|ldw,mb} %2(%1),%0\";
2467   return \"{ldws|ldw},mb %2(%1),%0\";
2469   [(set_attr "type" "load")
2470    (set_attr "length" "4")])
2472 (define_insn "pre_ldd"
2473   [(set (match_operand:DI 0 "register_operand" "=r")
2474         (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2475                          (match_operand:DI 2 "pre_cint_operand" ""))))
2476    (set (match_dup 1)
2477         (plus:DI (match_dup 1) (match_dup 2)))]
2478   "TARGET_64BIT"
2479   "ldd,mb %2(%1),%0"
2480   [(set_attr "type" "load")
2481    (set_attr "length" "4")])
2483 (define_insn ""
2484   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2485                          (match_operand:SI 1 "pre_cint_operand" "")))
2486         (match_operand:SI 2 "reg_or_0_operand" "rM"))
2487    (set (match_dup 0)
2488         (plus:SI (match_dup 0) (match_dup 1)))]
2489   ""
2490   "*
2492   if (INTVAL (operands[1]) < 0)
2493     return \"{stwm|stw,mb} %r2,%1(%0)\";
2494   return \"{stws|stw},mb %r2,%1(%0)\";
2496   [(set_attr "type" "store")
2497    (set_attr "length" "4")])
2499 (define_insn ""
2500   [(set (match_operand:SI 0 "register_operand" "=r")
2501         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2502    (set (match_dup 1)
2503         (plus:SI (match_dup 1)
2504                  (match_operand:SI 2 "post_cint_operand" "")))]
2505   ""
2506   "*
2508   if (INTVAL (operands[2]) > 0)
2509     return \"{ldwm|ldw,ma} %2(%1),%0\";
2510   return \"{ldws|ldw},ma %2(%1),%0\";
2512   [(set_attr "type" "load")
2513    (set_attr "length" "4")])
2515 (define_expand "post_store"
2516   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2517                    (match_operand 1 "reg_or_0_operand" ""))
2518               (set (match_dup 0)
2519                    (plus (match_dup 0)
2520                          (match_operand 2 "post_cint_operand" "")))])]
2521   ""
2522   "
2524   if (TARGET_64BIT)
2525     {
2526       emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2527       DONE;
2528     }
2529   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2530   DONE;
2533 (define_insn "post_stw"
2534   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2535         (match_operand:SI 1 "reg_or_0_operand" "rM"))
2536    (set (match_dup 0)
2537         (plus:SI (match_dup 0)
2538                  (match_operand:SI 2 "post_cint_operand" "")))]
2539   ""
2540   "*
2542   if (INTVAL (operands[2]) > 0)
2543     return \"{stwm|stw,ma} %r1,%2(%0)\";
2544   return \"{stws|stw},ma %r1,%2(%0)\";
2546   [(set_attr "type" "store")
2547    (set_attr "length" "4")])
2549 (define_insn "post_std"
2550   [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2551         (match_operand:DI 1 "reg_or_0_operand" "rM"))
2552    (set (match_dup 0)
2553         (plus:DI (match_dup 0)
2554                  (match_operand:DI 2 "post_cint_operand" "")))]
2555   "TARGET_64BIT"
2556   "std,ma %r1,%2(%0)"
2557   [(set_attr "type" "store")
2558    (set_attr "length" "4")])
2560 ;; For loading the address of a label while generating PIC code.
2561 ;; Note since this pattern can be created at reload time (via movsi), all
2562 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2563 (define_insn ""
2564   [(set (match_operand 0 "pmode_register_operand" "=a")
2565         (match_operand 1 "pic_label_operand" ""))]
2566   "TARGET_PA_20"
2567   "*
2569   rtx xoperands[3];
2571   xoperands[0] = operands[0];
2572   xoperands[1] = operands[1];
2574   if (GET_CODE (operands[1]) == LABEL_REF
2575       && !LABEL_REF_NONLOCAL_P (operands[1]))
2576     {
2577       xoperands[2] = gen_label_rtx ();
2578       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2579                                          CODE_LABEL_NUMBER (xoperands[2]));
2580       output_asm_insn (\"mfia %0\", xoperands);
2582       /* If we're trying to load the address of a label that happens to be
2583          close, then we can use a shorter sequence.  */
2584       if (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     }
2594   else
2595     {
2596       /* Load using linkage table.  */
2597       if (TARGET_64BIT)
2598         {
2599           output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
2600           output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
2601         }
2602       else
2603         {
2604           output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2605           output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2606         }
2607     }
2608   return \"\";
2610   [(set_attr "type" "multi")
2611    (set_attr "length" "12")])           ; 8 or 12
2613 (define_insn ""
2614   [(set (match_operand 0 "pmode_register_operand" "=a")
2615         (match_operand 1 "pic_label_operand" ""))]
2616   "!TARGET_PA_20"
2617   "*
2619   rtx xoperands[3];
2621   xoperands[0] = operands[0];
2622   xoperands[1] = operands[1];
2624   if (GET_CODE (operands[1]) == LABEL_REF
2625       && !LABEL_REF_NONLOCAL_P (operands[1]))
2626     {
2627       xoperands[2] = gen_label_rtx ();
2628       output_asm_insn (\"bl .+8,%0\", xoperands);
2629       output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2630       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2631                                          CODE_LABEL_NUMBER (xoperands[2]));
2633       /* If we're trying to load the address of a label that happens to be
2634          close, then we can use a shorter sequence.  */
2635       if (INSN_ADDRESSES_SET_P ()
2636           && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2637                   - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2638         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2639       else
2640         {
2641           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2642           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2643         }
2644     }
2645   else
2646     {
2647       /* Load using linkage table.  */
2648       output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2649       output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2650     }
2651   return \"\";
2653   [(set_attr "type" "multi")
2654    (set_attr "length" "16")])           ; 12 or 16
2656 (define_insn ""
2657   [(set (match_operand:SI 0 "register_operand" "=a")
2658         (plus:SI (match_operand:SI 1 "register_operand" "r")
2659                  (high:SI (match_operand 2 "" ""))))]
2660   "symbolic_operand (operands[2], Pmode)
2661    && ! function_label_operand (operands[2], Pmode)
2662    && flag_pic"
2663   "addil LT'%G2,%1"
2664   [(set_attr "type" "binary")
2665    (set_attr "length" "4")])
2667 (define_insn ""
2668   [(set (match_operand:DI 0 "register_operand" "=a")
2669         (plus:DI (match_operand:DI 1 "register_operand" "r")
2670                  (high:DI (match_operand 2 "" ""))))]
2671   "symbolic_operand (operands[2], Pmode)
2672    && ! function_label_operand (operands[2], Pmode)
2673    && TARGET_64BIT
2674    && flag_pic"
2675   "addil LT'%G2,%1"
2676   [(set_attr "type" "binary")
2677    (set_attr "length" "4")])
2679 (define_insn ""
2680  [(set (match_operand:SI 0 "register_operand" "=r")
2681        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2682                   (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2683   "symbolic_operand (operands[2], Pmode)
2684    && ! function_label_operand (operands[2], Pmode)
2685    && flag_pic"
2686   "ldo RT'%G2(%1),%0"
2687   [(set_attr "type" "binary")
2688    (set_attr "length" "4")])
2690 (define_insn ""
2691  [(set (match_operand:DI 0 "register_operand" "=r")
2692        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2693                   (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2694   "symbolic_operand (operands[2], Pmode)
2695    && ! function_label_operand (operands[2], Pmode)
2696    && TARGET_64BIT
2697    && flag_pic"
2698   "ldo RT'%G2(%1),%0"
2699   [(set_attr "type" "binary")
2700    (set_attr "length" "4")])
2702 ;; Always use addil rather than ldil;add sequences.  This allows the
2703 ;; HP linker to eliminate the dp relocation if the symbolic operand
2704 ;; lives in the TEXT space.
2705 (define_insn ""
2706   [(set (match_operand:SI 0 "register_operand" "=a")
2707         (high:SI (match_operand 1 "" "")))]
2708   "symbolic_operand (operands[1], Pmode)
2709    && ! function_label_operand (operands[1], Pmode)
2710    && ! read_only_operand (operands[1], Pmode)
2711    && ! flag_pic"
2712   "*
2714   if (TARGET_LONG_LOAD_STORE)
2715     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2716   else
2717     return \"addil LR'%H1,%%r27\";
2719   [(set_attr "type" "binary")
2720    (set (attr "length")
2721       (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2722                     (const_int 4)
2723                     (const_int 8)))])
2726 ;; This is for use in the prologue/epilogue code.  We need it
2727 ;; to add large constants to a stack pointer or frame pointer.
2728 ;; Because of the additional %r1 pressure, we probably do not
2729 ;; want to use this in general code, so make it available
2730 ;; only after reload.
2731 (define_insn ""
2732   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2733         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2734                  (high:SI (match_operand 2 "const_int_operand" ""))))]
2735   "reload_completed"
2736   "@
2737    addil L'%G2,%1
2738    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2739   [(set_attr "type" "binary,binary")
2740    (set_attr "length" "4,8")])
2742 (define_insn ""
2743   [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2744         (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2745                  (high:DI (match_operand 2 "const_int_operand" ""))))]
2746   "reload_completed && TARGET_64BIT"
2747   "@
2748    addil L'%G2,%1
2749    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2750   [(set_attr "type" "binary,binary")
2751    (set_attr "length" "4,8")])
2753 (define_insn ""
2754   [(set (match_operand:SI 0 "register_operand" "=r")
2755         (high:SI (match_operand 1 "" "")))]
2756   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2757     && !pa_is_function_label_plus_const (operands[1])"
2758   "*
2760   if (symbolic_operand (operands[1], Pmode))
2761     return \"ldil LR'%H1,%0\";
2762   else
2763     return \"ldil L'%G1,%0\";
2765   [(set_attr "type" "move")
2766    (set_attr "length" "4")])
2768 (define_insn ""
2769   [(set (match_operand:DI 0 "register_operand" "=r")
2770         (high:DI (match_operand 1 "const_int_operand" "")))]
2771   "TARGET_64BIT"
2772   "ldil L'%G1,%0";
2773   [(set_attr "type" "move")
2774    (set_attr "length" "4")])
2776 (define_insn ""
2777   [(set (match_operand:DI 0 "register_operand" "=r")
2778         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2779                    (match_operand:DI 2 "const_int_operand" "i")))]
2780   "TARGET_64BIT"
2781   "ldo R'%G2(%1),%0";
2782   [(set_attr "type" "move")
2783    (set_attr "length" "4")])
2785 (define_insn ""
2786   [(set (match_operand:SI 0 "register_operand" "=r")
2787         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2788                    (match_operand:SI 2 "immediate_operand" "i")))]
2789   "!pa_is_function_label_plus_const (operands[2])"
2790   "*
2792   gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2793   
2794   if (symbolic_operand (operands[2], Pmode))
2795     return \"ldo RR'%G2(%1),%0\";
2796   else
2797     return \"ldo R'%G2(%1),%0\";
2799   [(set_attr "type" "move")
2800    (set_attr "length" "4")])
2802 ;; Now that a symbolic_address plus a constant is broken up early
2803 ;; in the compilation phase (for better CSE) we need a special
2804 ;; combiner pattern to load the symbolic address plus the constant
2805 ;; in only 2 instructions. (For cases where the symbolic address
2806 ;; was not a common subexpression.)
2807 (define_split
2808   [(set (match_operand:SI 0 "register_operand" "")
2809         (match_operand:SI 1 "symbolic_operand" ""))
2810    (clobber (match_operand:SI 2 "register_operand" ""))]
2811   "! (flag_pic && pic_label_operand (operands[1], SImode))"
2812   [(set (match_dup 2) (high:SI (match_dup 1)))
2813    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2814   "")
2816 ;; hppa_legitimize_address goes to a great deal of trouble to
2817 ;; create addresses which use indexing.  In some cases, this
2818 ;; is a lose because there isn't any store instructions which
2819 ;; allow indexed addresses (with integer register source).
2821 ;; These define_splits try to turn a 3 insn store into
2822 ;; a 2 insn store with some creative RTL rewriting.
2823 (define_split
2824   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2825                                (match_operand:SI 1 "mem_shadd_operand" ""))
2826                    (plus:SI (match_operand:SI 2 "register_operand" "")
2827                             (match_operand:SI 3 "const_int_operand" ""))))
2828         (match_operand:SI 4 "register_operand" ""))
2829    (clobber (match_operand:SI 5 "register_operand" ""))]
2830   ""
2831   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2832                                (match_dup 2)))
2833    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2834   "
2836   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2840 (define_split
2841   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2842                                (match_operand:SI 1 "mem_shadd_operand" ""))
2843                    (plus:SI (match_operand:SI 2 "register_operand" "")
2844                             (match_operand:SI 3 "const_int_operand" ""))))
2845         (match_operand:HI 4 "register_operand" ""))
2846    (clobber (match_operand:SI 5 "register_operand" ""))]
2847   ""
2848   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2849                                (match_dup 2)))
2850    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2851   "
2853   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2857 (define_split
2858   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2859                                (match_operand:SI 1 "mem_shadd_operand" ""))
2860                    (plus:SI (match_operand:SI 2 "register_operand" "")
2861                             (match_operand:SI 3 "const_int_operand" ""))))
2862         (match_operand:QI 4 "register_operand" ""))
2863    (clobber (match_operand:SI 5 "register_operand" ""))]
2864   ""
2865   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2866                                (match_dup 2)))
2867    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2868   "
2870   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2874 (define_expand "movhi"
2875   [(set (match_operand:HI 0 "general_operand" "")
2876         (match_operand:HI 1 "general_operand" ""))]
2877   ""
2878   "
2880   if (pa_emit_move_sequence (operands, HImode, 0))
2881     DONE;
2884 ;; Handle HImode input reloads requiring a general register as a
2885 ;; scratch register.
2886 (define_expand "reload_inhi"
2887   [(set (match_operand:HI 0 "register_operand" "=Z")
2888         (match_operand:HI 1 "non_hard_reg_operand" ""))
2889    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2890   ""
2891   "
2893   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2894     DONE;
2896   /* We don't want the clobber emitted, so handle this ourselves.  */
2897   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2898   DONE;
2901 ;; Handle HImode output reloads requiring a general register as a
2902 ;; scratch register.
2903 (define_expand "reload_outhi"
2904   [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2905         (match_operand:HI 1  "register_operand" "Z"))
2906    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2907   ""
2908   "
2910   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2911     DONE;
2913   /* We don't want the clobber emitted, so handle this ourselves.  */
2914   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2915   DONE;
2918 (define_insn ""
2919   [(set (match_operand:HI 0 "move_dest_operand"
2920                           "=r,r,r,r,r,Q,!*q,!r")
2921         (match_operand:HI 1 "move_src_operand"
2922                           "r,J,N,K,RQ,rM,!rM,!*q"))]
2923   "(register_operand (operands[0], HImode)
2924     || reg_or_0_operand (operands[1], HImode))"
2925   "@
2926    copy %1,%0
2927    ldi %1,%0
2928    ldil L'%1,%0
2929    {zdepi|depwi,z} %Z1,%0
2930    ldh%M1 %1,%0
2931    sth%M0 %r1,%0
2932    mtsar %r1
2933    {mfctl|mfctl,w} %sar,%0"
2934   [(set_attr "type" "move,move,move,shift,load,store,move,move")
2935    (set_attr "pa_combine_type" "addmove")
2936    (set_attr "length" "4,4,4,4,4,4,4,4")])
2938 (define_insn ""
2939   [(set (match_operand:HI 0 "register_operand" "=r")
2940         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2941                          (match_operand:SI 2 "int5_operand" "L"))))
2942    (set (match_dup 1)
2943         (plus:SI (match_dup 1) (match_dup 2)))]
2944   ""
2945   "{ldhs|ldh},mb %2(%1),%0"
2946   [(set_attr "type" "load")
2947    (set_attr "length" "4")])
2949 (define_insn ""
2950   [(set (match_operand:HI 0 "register_operand" "=r")
2951         (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2952                          (match_operand:DI 2 "int5_operand" "L"))))
2953    (set (match_dup 1)
2954         (plus:DI (match_dup 1) (match_dup 2)))]
2955   "TARGET_64BIT"
2956   "ldh,mb %2(%1),%0"
2957   [(set_attr "type" "load")
2958    (set_attr "length" "4")])
2960 ; And a zero extended variant.
2961 (define_insn ""
2962   [(set (match_operand:DI 0 "register_operand" "=r")
2963         (zero_extend:DI (mem:HI
2964                           (plus:DI
2965                             (match_operand:DI 1 "register_operand" "+r")
2966                             (match_operand:DI 2 "int5_operand" "L")))))
2967    (set (match_dup 1)
2968         (plus:DI (match_dup 1) (match_dup 2)))]
2969   "TARGET_64BIT"
2970   "ldh,mb %2(%1),%0"
2971   [(set_attr "type" "load")
2972    (set_attr "length" "4")])
2974 (define_insn ""
2975   [(set (match_operand:SI 0 "register_operand" "=r")
2976         (zero_extend:SI (mem:HI
2977                           (plus:SI
2978                             (match_operand:SI 1 "register_operand" "+r")
2979                             (match_operand:SI 2 "int5_operand" "L")))))
2980    (set (match_dup 1)
2981         (plus:SI (match_dup 1) (match_dup 2)))]
2982   ""
2983   "{ldhs|ldh},mb %2(%1),%0"
2984   [(set_attr "type" "load")
2985    (set_attr "length" "4")])
2987 (define_insn ""
2988   [(set (match_operand:SI 0 "register_operand" "=r")
2989         (zero_extend:SI (mem:HI
2990                           (plus:DI
2991                             (match_operand:DI 1 "register_operand" "+r")
2992                             (match_operand:DI 2 "int5_operand" "L")))))
2993    (set (match_dup 1)
2994         (plus:DI (match_dup 1) (match_dup 2)))]
2995   "TARGET_64BIT"
2996   "ldh,mb %2(%1),%0"
2997   [(set_attr "type" "load")
2998    (set_attr "length" "4")])
3000 (define_insn ""
3001   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3002                          (match_operand:SI 1 "int5_operand" "L")))
3003         (match_operand:HI 2 "reg_or_0_operand" "rM"))
3004    (set (match_dup 0)
3005         (plus:SI (match_dup 0) (match_dup 1)))]
3006   ""
3007   "{sths|sth},mb %r2,%1(%0)"
3008   [(set_attr "type" "store")
3009    (set_attr "length" "4")])
3011 (define_insn ""
3012   [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3013                          (match_operand:DI 1 "int5_operand" "L")))
3014         (match_operand:HI 2 "reg_or_0_operand" "rM"))
3015    (set (match_dup 0)
3016         (plus:DI (match_dup 0) (match_dup 1)))]
3017   "TARGET_64BIT"
3018   "sth,mb %r2,%1(%0)"
3019   [(set_attr "type" "store")
3020    (set_attr "length" "4")])
3022 (define_insn "addhi3"
3023   [(set (match_operand:HI 0 "register_operand" "=r,r")
3024         (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3025                  (match_operand:HI 2 "arith14_operand" "r,J")))]
3026   ""
3027   "@
3028    {addl|add,l} %1,%2,%0
3029    ldo %2(%1),%0"
3030   [(set_attr "type" "binary,binary")
3031    (set_attr "pa_combine_type" "addmove")
3032    (set_attr "length" "4,4")])
3034 (define_expand "movqi"
3035   [(set (match_operand:QI 0 "general_operand" "")
3036         (match_operand:QI 1 "general_operand" ""))]
3037   ""
3038   "
3040   if (pa_emit_move_sequence (operands, QImode, 0))
3041     DONE;
3044 ;; Handle QImode input reloads requiring a general register as a
3045 ;; scratch register.
3046 (define_expand "reload_inqi"
3047   [(set (match_operand:QI 0 "register_operand" "=Z")
3048         (match_operand:QI 1 "non_hard_reg_operand" ""))
3049    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3050   ""
3051   "
3053   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3054     DONE;
3056   /* We don't want the clobber emitted, so handle this ourselves.  */
3057   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3058   DONE;
3061 ;; Handle QImode output reloads requiring a general register as a
3062 ;; scratch register.
3063 (define_expand "reload_outqi"
3064   [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3065         (match_operand:QI 1  "register_operand" "Z"))
3066    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3067   ""
3068   "
3070   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3071     DONE;
3073   /* We don't want the clobber emitted, so handle this ourselves.  */
3074   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3075   DONE;
3078 (define_insn ""
3079   [(set (match_operand:QI 0 "move_dest_operand"
3080                           "=r,r,r,r,r,Q,!*q,!r")
3081         (match_operand:QI 1 "move_src_operand"
3082                           "r,J,N,K,RQ,rM,!rM,!*q"))]
3083   "(register_operand (operands[0], QImode)
3084     || reg_or_0_operand (operands[1], QImode))"
3085   "@
3086    copy %1,%0
3087    ldi %1,%0
3088    ldil L'%1,%0
3089    {zdepi|depwi,z} %Z1,%0
3090    ldb%M1 %1,%0
3091    stb%M0 %r1,%0
3092    mtsar %r1
3093    {mfctl|mfctl,w} %%sar,%0"
3094   [(set_attr "type" "move,move,move,shift,load,store,move,move")
3095    (set_attr "pa_combine_type" "addmove")
3096    (set_attr "length" "4,4,4,4,4,4,4,4")])
3098 (define_insn ""
3099   [(set (match_operand:QI 0 "register_operand" "=r")
3100         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3101                          (match_operand:SI 2 "int5_operand" "L"))))
3102    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3103   ""
3104   "{ldbs|ldb},mb %2(%1),%0"
3105   [(set_attr "type" "load")
3106    (set_attr "length" "4")])
3108 (define_insn ""
3109   [(set (match_operand:QI 0 "register_operand" "=r")
3110         (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3111                          (match_operand:DI 2 "int5_operand" "L"))))
3112    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3113   "TARGET_64BIT"
3114   "ldb,mb %2(%1),%0"
3115   [(set_attr "type" "load")
3116    (set_attr "length" "4")])
3118 ; Now the same thing with zero extensions.
3119 (define_insn ""
3120   [(set (match_operand:DI 0 "register_operand" "=r")
3121         (zero_extend:DI (mem:QI (plus:DI
3122                                   (match_operand:DI 1 "register_operand" "+r")
3123                                   (match_operand:DI 2 "int5_operand" "L")))))
3124    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3125   "TARGET_64BIT"
3126   "ldb,mb %2(%1),%0"
3127   [(set_attr "type" "load")
3128    (set_attr "length" "4")])
3130 (define_insn ""
3131   [(set (match_operand:SI 0 "register_operand" "=r")
3132         (zero_extend:SI (mem:QI (plus:SI
3133                                   (match_operand:SI 1 "register_operand" "+r")
3134                                   (match_operand:SI 2 "int5_operand" "L")))))
3135    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3136   ""
3137   "{ldbs|ldb},mb %2(%1),%0"
3138   [(set_attr "type" "load")
3139    (set_attr "length" "4")])
3141 (define_insn ""
3142   [(set (match_operand:SI 0 "register_operand" "=r")
3143         (zero_extend:SI (mem:QI (plus:DI
3144                                   (match_operand:DI 1 "register_operand" "+r")
3145                                   (match_operand:DI 2 "int5_operand" "L")))))
3146    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3147   "TARGET_64BIT"
3148   "ldb,mb %2(%1),%0"
3149   [(set_attr "type" "load")
3150    (set_attr "length" "4")])
3152 (define_insn ""
3153   [(set (match_operand:HI 0 "register_operand" "=r")
3154         (zero_extend:HI (mem:QI (plus:SI
3155                                   (match_operand:SI 1 "register_operand" "+r")
3156                                   (match_operand:SI 2 "int5_operand" "L")))))
3157    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3158   ""
3159   "{ldbs|ldb},mb %2(%1),%0"
3160   [(set_attr "type" "load")
3161    (set_attr "length" "4")])
3163 (define_insn ""
3164   [(set (match_operand:HI 0 "register_operand" "=r")
3165         (zero_extend:HI (mem:QI (plus:DI
3166                                   (match_operand:DI 1 "register_operand" "+r")
3167                                   (match_operand:DI 2 "int5_operand" "L")))))
3168    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3169   "TARGET_64BIT"
3170   "ldb,mb %2(%1),%0"
3171   [(set_attr "type" "load")
3172    (set_attr "length" "4")])
3174 (define_insn ""
3175   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3176                          (match_operand:SI 1 "int5_operand" "L")))
3177         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3178    (set (match_dup 0)
3179         (plus:SI (match_dup 0) (match_dup 1)))]
3180   ""
3181   "{stbs|stb},mb %r2,%1(%0)"
3182   [(set_attr "type" "store")
3183    (set_attr "length" "4")])
3185 (define_insn ""
3186   [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3187                          (match_operand:DI 1 "int5_operand" "L")))
3188         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3189    (set (match_dup 0)
3190         (plus:DI (match_dup 0) (match_dup 1)))]
3191   "TARGET_64BIT"
3192   "stb,mb %r2,%1(%0)"
3193   [(set_attr "type" "store")
3194    (set_attr "length" "4")])
3196 ;; The definition of this insn does not really explain what it does,
3197 ;; but it should suffice that anything generated as this insn will be
3198 ;; recognized as a cpymemsi operation, and that it will not successfully
3199 ;; combine with anything.
3200 (define_expand "cpymemsi"
3201   [(parallel [(set (match_operand:BLK 0 "" "")
3202                    (match_operand:BLK 1 "" ""))
3203               (clobber (match_dup 4))
3204               (clobber (match_dup 5))
3205               (clobber (match_dup 6))
3206               (clobber (match_dup 7))
3207               (clobber (match_dup 8))
3208               (use (match_operand:SI 2 "arith14_operand" ""))
3209               (use (match_operand:SI 3 "const_int_operand" ""))])]
3210   "!TARGET_64BIT && optimize > 0"
3211   "
3213   int size, align;
3215   /* HP provides very fast block move library routine for the PA;
3216      this routine includes:
3218         4x4 byte at a time block moves,
3219         1x4 byte at a time with alignment checked at runtime with
3220             attempts to align the source and destination as needed
3221         1x1 byte loop
3223      With that in mind, here's the heuristics to try and guess when
3224      the inlined block move will be better than the library block
3225      move:
3227         If the size isn't constant, then always use the library routines.
3229         If the size is large in respect to the known alignment, then use
3230         the library routines.
3232         If the size is small in respect to the known alignment, then open
3233         code the copy (since that will lead to better scheduling).
3235         Else use the block move pattern.   */
3237   /* Undetermined size, use the library routine.  */
3238   if (GET_CODE (operands[2]) != CONST_INT)
3239     FAIL;
3241   size = INTVAL (operands[2]);
3242   align = INTVAL (operands[3]);
3243   align = align > 4 ? 4 : (align ? align : 1);
3245   /* If size/alignment is large, then use the library routines.  */
3246   if (size / align > 16)
3247     FAIL;
3249   /* This does happen, but not often enough to worry much about.  */
3250   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3251     FAIL;
3252   
3253   /* Fall through means we're going to use our block move pattern.  */
3254   operands[0]
3255     = replace_equiv_address (operands[0],
3256                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3257   operands[1]
3258     = replace_equiv_address (operands[1],
3259                              copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3260   operands[4] = gen_reg_rtx (SImode);
3261   operands[5] = gen_reg_rtx (SImode);
3262   operands[6] = gen_reg_rtx (SImode);
3263   operands[7] = gen_reg_rtx (SImode);
3264   operands[8] = gen_reg_rtx (SImode);
3267 ;; The operand constraints are written like this to support both compile-time
3268 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3269 ;; only support compile-time determined counts at this time.
3271 ;; If the count is run-time determined, the register with the byte count
3272 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3274 ;; We used to clobber operands 0 and 1.  However, a change to regrename.cc
3275 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3276 ;; as this requires two registers in the class R1_REGS when the MEMs for
3277 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3278 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3279 ;; respectively.  We then split or peephole optimize after reload.
3280 (define_insn "cpymemsi_prereload"
3281   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3282         (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3283    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3284    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3285    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3286    (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))   ;item tmp3
3287    (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))   ;item tmp4
3288    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3289    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3290   "!TARGET_64BIT"
3291   "#"
3292   [(set_attr "type" "multi,multi")])
3294 (define_split
3295   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3296                    (match_operand:BLK 1 "memory_operand" ""))
3297               (clobber (match_operand:SI 2 "register_operand" ""))
3298               (clobber (match_operand:SI 3 "register_operand" ""))
3299               (clobber (match_operand:SI 6 "register_operand" ""))
3300               (clobber (match_operand:SI 7 "register_operand" ""))
3301               (clobber (match_operand:SI 8 "register_operand" ""))
3302               (use (match_operand:SI 4 "arith14_operand" ""))
3303               (use (match_operand:SI 5 "const_int_operand" ""))])]
3304   "!TARGET_64BIT && reload_completed && !flag_peephole2
3305    && GET_CODE (operands[0]) == MEM
3306    && register_operand (XEXP (operands[0], 0), SImode)
3307    && GET_CODE (operands[1]) == MEM
3308    && register_operand (XEXP (operands[1], 0), SImode)"
3309   [(set (match_dup 7) (match_dup 9))
3310    (set (match_dup 8) (match_dup 10))
3311    (parallel [(set (match_dup 0) (match_dup 1))
3312               (clobber (match_dup 2))
3313               (clobber (match_dup 3))
3314               (clobber (match_dup 6))
3315               (clobber (match_dup 7))
3316               (clobber (match_dup 8))
3317               (use (match_dup 4))
3318               (use (match_dup 5))
3319               (const_int 0)])]
3320   "
3322   operands[9] = XEXP (operands[0], 0);
3323   operands[10] = XEXP (operands[1], 0);
3324   operands[0] = replace_equiv_address (operands[0], operands[7]);
3325   operands[1] = replace_equiv_address (operands[1], operands[8]);
3328 (define_peephole2
3329   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3330                    (match_operand:BLK 1 "memory_operand" ""))
3331               (clobber (match_operand:SI 2 "register_operand" ""))
3332               (clobber (match_operand:SI 3 "register_operand" ""))
3333               (clobber (match_operand:SI 6 "register_operand" ""))
3334               (clobber (match_operand:SI 7 "register_operand" ""))
3335               (clobber (match_operand:SI 8 "register_operand" ""))
3336               (use (match_operand:SI 4 "arith14_operand" ""))
3337               (use (match_operand:SI 5 "const_int_operand" ""))])]
3338   "!TARGET_64BIT
3339    && GET_CODE (operands[0]) == MEM
3340    && register_operand (XEXP (operands[0], 0), SImode)
3341    && GET_CODE (operands[1]) == MEM
3342    && register_operand (XEXP (operands[1], 0), SImode)"
3343   [(parallel [(set (match_dup 0) (match_dup 1))
3344               (clobber (match_dup 2))
3345               (clobber (match_dup 3))
3346               (clobber (match_dup 6))
3347               (clobber (match_dup 7))
3348               (clobber (match_dup 8))
3349               (use (match_dup 4))
3350               (use (match_dup 5))
3351               (const_int 0)])]
3352   "
3354   rtx addr = XEXP (operands[0], 0);
3355   if (dead_or_set_p (curr_insn, addr))
3356     operands[7] = addr;
3357   else
3358     {
3359       emit_insn (gen_rtx_SET (operands[7], addr));
3360       operands[0] = replace_equiv_address (operands[0], operands[7]);
3361     }
3363   addr = XEXP (operands[1], 0);
3364   if (dead_or_set_p (curr_insn, addr))
3365     operands[8] = addr;
3366   else
3367     {
3368       emit_insn (gen_rtx_SET (operands[8], addr));
3369       operands[1] = replace_equiv_address (operands[1], operands[8]);
3370     }
3373 (define_insn "cpymemsi_postreload"
3374   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3375         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3376    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3377    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3378    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3379    (clobber (match_dup 0))
3380    (clobber (match_dup 1))
3381    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3382    (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3383    (const_int 0)]
3384   "!TARGET_64BIT && reload_completed"
3385   "* return pa_output_block_move (operands, !which_alternative);"
3386   [(set_attr "type" "multi,multi")])
3388 (define_expand "cpymemdi"
3389   [(parallel [(set (match_operand:BLK 0 "" "")
3390                    (match_operand:BLK 1 "" ""))
3391               (clobber (match_dup 4))
3392               (clobber (match_dup 5))
3393               (clobber (match_dup 6))
3394               (clobber (match_dup 7))
3395               (clobber (match_dup 8))
3396               (use (match_operand:DI 2 "arith14_operand" ""))
3397               (use (match_operand:DI 3 "const_int_operand" ""))])]
3398   "TARGET_64BIT && optimize > 0"
3399   "
3401   int size, align;
3403   /* HP provides very fast block move library routine for the PA;
3404      this routine includes:
3406         4x4 byte at a time block moves,
3407         1x4 byte at a time with alignment checked at runtime with
3408             attempts to align the source and destination as needed
3409         1x1 byte loop
3411      With that in mind, here's the heuristics to try and guess when
3412      the inlined block move will be better than the library block
3413      move:
3415         If the size isn't constant, then always use the library routines.
3417         If the size is large in respect to the known alignment, then use
3418         the library routines.
3420         If the size is small in respect to the known alignment, then open
3421         code the copy (since that will lead to better scheduling).
3423         Else use the block move pattern.   */
3425   /* Undetermined size, use the library routine.  */
3426   if (GET_CODE (operands[2]) != CONST_INT)
3427     FAIL;
3429   size = INTVAL (operands[2]);
3430   align = INTVAL (operands[3]);
3431   align = align > 8 ? 8 : (align ? align : 1);
3433   /* If size/alignment is large, then use the library routines.  */
3434   if (size / align > 16)
3435     FAIL;
3437   /* This does happen, but not often enough to worry much about.  */
3438   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3439     FAIL;
3440   
3441   /* Fall through means we're going to use our block move pattern.  */
3442   operands[0]
3443     = replace_equiv_address (operands[0],
3444                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3445   operands[1]
3446     = replace_equiv_address (operands[1],
3447                              copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3448   operands[4] = gen_reg_rtx (DImode);
3449   operands[5] = gen_reg_rtx (DImode);
3450   operands[6] = gen_reg_rtx (DImode);
3451   operands[7] = gen_reg_rtx (DImode);
3452   operands[8] = gen_reg_rtx (DImode);
3455 ;; The operand constraints are written like this to support both compile-time
3456 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3457 ;; only support compile-time determined counts at this time.
3459 ;; If the count is run-time determined, the register with the byte count
3460 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3462 ;; We used to clobber operands 0 and 1.  However, a change to regrename.cc
3463 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3464 ;; as this requires two registers in the class R1_REGS when the MEMs for
3465 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3466 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3467 ;; respectively.  We then split or peephole optimize after reload.
3468 (define_insn "cpymemdi_prereload"
3469   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3470         (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3471    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3472    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3473    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3474    (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))   ;item tmp3
3475    (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))   ;item tmp4
3476    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3477    (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3478   "TARGET_64BIT"
3479   "#"
3480   [(set_attr "type" "multi,multi")])
3482 (define_split
3483   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3484                    (match_operand:BLK 1 "memory_operand" ""))
3485               (clobber (match_operand:DI 2 "register_operand" ""))
3486               (clobber (match_operand:DI 3 "register_operand" ""))
3487               (clobber (match_operand:DI 6 "register_operand" ""))
3488               (clobber (match_operand:DI 7 "register_operand" ""))
3489               (clobber (match_operand:DI 8 "register_operand" ""))
3490               (use (match_operand:DI 4 "arith14_operand" ""))
3491               (use (match_operand:DI 5 "const_int_operand" ""))])]
3492   "TARGET_64BIT && reload_completed && !flag_peephole2
3493    && GET_CODE (operands[0]) == MEM
3494    && register_operand (XEXP (operands[0], 0), DImode)
3495    && GET_CODE (operands[1]) == MEM
3496    && register_operand (XEXP (operands[1], 0), DImode)"
3497   [(set (match_dup 7) (match_dup 9))
3498    (set (match_dup 8) (match_dup 10))
3499    (parallel [(set (match_dup 0) (match_dup 1))
3500               (clobber (match_dup 2))
3501               (clobber (match_dup 3))
3502               (clobber (match_dup 6))
3503               (clobber (match_dup 7))
3504               (clobber (match_dup 8))
3505               (use (match_dup 4))
3506               (use (match_dup 5))
3507               (const_int 0)])]
3508   "
3510   operands[9] = XEXP (operands[0], 0);
3511   operands[10] = XEXP (operands[1], 0);
3512   operands[0] = replace_equiv_address (operands[0], operands[7]);
3513   operands[1] = replace_equiv_address (operands[1], operands[8]);
3516 (define_peephole2
3517   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3518                    (match_operand:BLK 1 "memory_operand" ""))
3519               (clobber (match_operand:DI 2 "register_operand" ""))
3520               (clobber (match_operand:DI 3 "register_operand" ""))
3521               (clobber (match_operand:DI 6 "register_operand" ""))
3522               (clobber (match_operand:DI 7 "register_operand" ""))
3523               (clobber (match_operand:DI 8 "register_operand" ""))
3524               (use (match_operand:DI 4 "arith14_operand" ""))
3525               (use (match_operand:DI 5 "const_int_operand" ""))])]
3526   "TARGET_64BIT
3527    && GET_CODE (operands[0]) == MEM
3528    && register_operand (XEXP (operands[0], 0), DImode)
3529    && GET_CODE (operands[1]) == MEM
3530    && register_operand (XEXP (operands[1], 0), DImode)"
3531   [(parallel [(set (match_dup 0) (match_dup 1))
3532               (clobber (match_dup 2))
3533               (clobber (match_dup 3))
3534               (clobber (match_dup 6))
3535               (clobber (match_dup 7))
3536               (clobber (match_dup 8))
3537               (use (match_dup 4))
3538               (use (match_dup 5))
3539               (const_int 0)])]
3540   "
3542   rtx addr = XEXP (operands[0], 0);
3543   if (dead_or_set_p (curr_insn, addr))
3544     operands[7] = addr;
3545   else
3546     {
3547       emit_insn (gen_rtx_SET (operands[7], addr));
3548       operands[0] = replace_equiv_address (operands[0], operands[7]);
3549     }
3551   addr = XEXP (operands[1], 0);
3552   if (dead_or_set_p (curr_insn, addr))
3553     operands[8] = addr;
3554   else
3555     {
3556       emit_insn (gen_rtx_SET (operands[8], addr));
3557       operands[1] = replace_equiv_address (operands[1], operands[8]);
3558     }
3561 (define_insn "cpymemdi_postreload"
3562   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3563         (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3564    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3565    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3566    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3567    (clobber (match_dup 0))
3568    (clobber (match_dup 1))
3569    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3570    (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3571    (const_int 0)]
3572   "TARGET_64BIT && reload_completed"
3573   "* return pa_output_block_move (operands, !which_alternative);"
3574   [(set_attr "type" "multi,multi")])
3576 (define_expand "setmemsi"
3577   [(parallel [(set (match_operand:BLK 0 "" "")
3578                    (match_operand 2 "const_int_operand" ""))
3579               (clobber (match_dup 4))
3580               (clobber (match_dup 5))
3581               (use (match_operand:SI 1 "arith14_operand" ""))
3582               (use (match_operand:SI 3 "const_int_operand" ""))])]
3583   "!TARGET_64BIT && optimize > 0"
3584   "
3586   int size, align;
3588   /* If value to set is not zero, use the library routine.  */
3589   if (operands[2] != const0_rtx)
3590     FAIL;
3592   /* Undetermined size, use the library routine.  */
3593   if (GET_CODE (operands[1]) != CONST_INT)
3594     FAIL;
3596   size = INTVAL (operands[1]);
3597   align = INTVAL (operands[3]);
3598   align = align > 4 ? 4 : align;
3600   /* If size/alignment is large, then use the library routines.  */
3601   if (size / align > 16)
3602     FAIL;
3604   /* This does happen, but not often enough to worry much about.  */
3605   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3606     FAIL;
3607   
3608   /* Fall through means we're going to use our block clear pattern.  */
3609   operands[0]
3610     = replace_equiv_address (operands[0],
3611                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3612   operands[4] = gen_reg_rtx (SImode);
3613   operands[5] = gen_reg_rtx (SImode);
3616 (define_insn "clrmemsi_prereload"
3617   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3618         (const_int 0))
3619    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3620    (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))   ;tmp1
3621    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3622    (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3623   "!TARGET_64BIT"
3624   "#"
3625   [(set_attr "type" "multi,multi")])
3627 (define_split
3628   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3629                    (const_int 0))
3630               (clobber (match_operand:SI 1 "register_operand" ""))
3631               (clobber (match_operand:SI 4 "register_operand" ""))
3632               (use (match_operand:SI 2 "arith14_operand" ""))
3633               (use (match_operand:SI 3 "const_int_operand" ""))])]
3634   "!TARGET_64BIT && reload_completed && !flag_peephole2
3635    && GET_CODE (operands[0]) == MEM
3636    && register_operand (XEXP (operands[0], 0), SImode)"
3637   [(set (match_dup 4) (match_dup 5))
3638    (parallel [(set (match_dup 0) (const_int 0))
3639               (clobber (match_dup 1))
3640               (clobber (match_dup 4))
3641               (use (match_dup 2))
3642               (use (match_dup 3))
3643               (const_int 0)])]
3644   "
3646   operands[5] = XEXP (operands[0], 0);
3647   operands[0] = replace_equiv_address (operands[0], operands[4]);
3650 (define_peephole2
3651   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3652                    (const_int 0))
3653               (clobber (match_operand:SI 1 "register_operand" ""))
3654               (clobber (match_operand:SI 4 "register_operand" ""))
3655               (use (match_operand:SI 2 "arith14_operand" ""))
3656               (use (match_operand:SI 3 "const_int_operand" ""))])]
3657   "!TARGET_64BIT
3658    && GET_CODE (operands[0]) == MEM
3659    && register_operand (XEXP (operands[0], 0), SImode)"
3660   [(parallel [(set (match_dup 0) (const_int 0))
3661               (clobber (match_dup 1))
3662               (clobber (match_dup 4))
3663               (use (match_dup 2))
3664               (use (match_dup 3))
3665               (const_int 0)])]
3666   "
3668   rtx addr = XEXP (operands[0], 0);
3669   if (dead_or_set_p (curr_insn, addr))
3670     operands[4] = addr;
3671   else
3672     {
3673       emit_insn (gen_rtx_SET (operands[4], addr));
3674       operands[0] = replace_equiv_address (operands[0], operands[4]);
3675     }
3678 (define_insn "clrmemsi_postreload"
3679   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3680         (const_int 0))
3681    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3682    (clobber (match_dup 0))
3683    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3684    (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3685    (const_int 0)]
3686   "!TARGET_64BIT && reload_completed"
3687   "* return pa_output_block_clear (operands, !which_alternative);"
3688   [(set_attr "type" "multi,multi")])
3690 (define_expand "setmemdi"
3691   [(parallel [(set (match_operand:BLK 0 "" "")
3692                    (match_operand 2 "const_int_operand" ""))
3693               (clobber (match_dup 4))
3694               (clobber (match_dup 5))
3695               (use (match_operand:DI 1 "arith14_operand" ""))
3696               (use (match_operand:DI 3 "const_int_operand" ""))])]
3697   "TARGET_64BIT && optimize > 0"
3698   "
3700   int size, align;
3702   /* If value to set is not zero, use the library routine.  */
3703   if (operands[2] != const0_rtx)
3704     FAIL;
3706   /* Undetermined size, use the library routine.  */
3707   if (GET_CODE (operands[1]) != CONST_INT)
3708     FAIL;
3710   size = INTVAL (operands[1]);
3711   align = INTVAL (operands[3]);
3712   align = align > 8 ? 8 : align;
3714   /* If size/alignment is large, then use the library routines.  */
3715   if (size / align > 16)
3716     FAIL;
3718   /* This does happen, but not often enough to worry much about.  */
3719   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3720     FAIL;
3721   
3722   /* Fall through means we're going to use our block clear pattern.  */
3723   operands[0]
3724     = replace_equiv_address (operands[0],
3725                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3726   operands[4] = gen_reg_rtx (DImode);
3727   operands[5] = gen_reg_rtx (DImode);
3730 (define_insn "clrmemdi_prereload"
3731   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3732         (const_int 0))
3733    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3734    (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))   ;item tmp1
3735    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3736    (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3737   "TARGET_64BIT"
3738   "#"
3739   [(set_attr "type" "multi,multi")])
3741 (define_split
3742   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3743                    (const_int 0))
3744               (clobber (match_operand:DI 1 "register_operand" ""))
3745               (clobber (match_operand:DI 4 "register_operand" ""))
3746               (use (match_operand:DI 2 "arith14_operand" ""))
3747               (use (match_operand:DI 3 "const_int_operand" ""))])]
3748   "TARGET_64BIT && reload_completed && !flag_peephole2
3749    && GET_CODE (operands[0]) == MEM
3750    && register_operand (XEXP (operands[0], 0), DImode)"
3751   [(set (match_dup 4) (match_dup 5))
3752    (parallel [(set (match_dup 0) (const_int 0))
3753               (clobber (match_dup 1))
3754               (clobber (match_dup 4))
3755               (use (match_dup 2))
3756               (use (match_dup 3))
3757               (const_int 0)])]
3758   "
3760   operands[5] = XEXP (operands[0], 0);
3761   operands[0] = replace_equiv_address (operands[0], operands[4]);
3764 (define_peephole2
3765   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3766                    (const_int 0))
3767               (clobber (match_operand:DI 1 "register_operand" ""))
3768               (clobber (match_operand:DI 4 "register_operand" ""))
3769               (use (match_operand:DI 2 "arith14_operand" ""))
3770               (use (match_operand:DI 3 "const_int_operand" ""))])]
3771   "TARGET_64BIT
3772    && GET_CODE (operands[0]) == MEM
3773    && register_operand (XEXP (operands[0], 0), DImode)"
3774   [(parallel [(set (match_dup 0) (const_int 0))
3775               (clobber (match_dup 1))
3776               (clobber (match_dup 4))
3777               (use (match_dup 2))
3778               (use (match_dup 3))
3779               (const_int 0)])]
3780   "
3781 {  
3782   rtx addr = XEXP (operands[0], 0);
3783   if (dead_or_set_p (curr_insn, addr))
3784     operands[4] = addr;
3785   else
3786     {
3787       emit_insn (gen_rtx_SET (operands[4], addr));
3788       operands[0] = replace_equiv_address (operands[0], operands[4]);
3789     }
3792 (define_insn "clrmemdi_postreload"
3793   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3794         (const_int 0))
3795    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3796    (clobber (match_dup 0))
3797    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3798    (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3799    (const_int 0)]
3800   "TARGET_64BIT && reload_completed"
3801   "* return pa_output_block_clear (operands, !which_alternative);"
3802   [(set_attr "type" "multi,multi")])
3804 ;; Floating point move insns
3806 (define_expand "movdf"
3807   [(set (match_operand:DF 0 "general_operand" "")
3808         (match_operand:DF 1 "general_operand" ""))]
3809   ""
3810   "
3812   if (pa_emit_move_sequence (operands, DFmode, 0))
3813     DONE;
3816 ;; Handle DFmode input reloads requiring %r1 as a scratch register.
3817 (define_expand "reload_indf_r1"
3818   [(set (match_operand:DF 0 "register_operand" "=Z")
3819         (match_operand:DF 1 "non_hard_reg_operand" ""))
3820    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3821   ""
3822   "
3824   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3825     DONE;
3827   /* We don't want the clobber emitted, so handle this ourselves.  */
3828   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3829   DONE;
3832 ;; Handle DFmode input reloads requiring a general register as a
3833 ;; scratch register.
3834 (define_expand "reload_indf"
3835   [(set (match_operand:DF 0 "register_operand" "=Z")
3836         (match_operand:DF 1 "non_hard_reg_operand" ""))
3837    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3838   ""
3839   "
3841   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3842     DONE;
3844   /* We don't want the clobber emitted, so handle this ourselves.  */
3845   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3846   DONE;
3849 ;; Handle DFmode output reloads requiring a general register as a
3850 ;; scratch register.
3851 (define_expand "reload_outdf" 
3852  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3853         (match_operand:DF 1  "register_operand" "Z"))
3854    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3855   ""
3856   "
3858   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3859     DONE;
3861   /* We don't want the clobber emitted, so handle this ourselves.  */
3862   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3863   DONE;
3866 (define_insn ""
3867   [(set (match_operand:DF 0 "move_dest_operand"
3868                           "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3869         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3870                           "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3871   "(register_operand (operands[0], DFmode)
3872     || reg_or_0_operand (operands[1], DFmode))
3873    && !(GET_CODE (operands[1]) == CONST_DOUBLE
3874         && GET_CODE (operands[0]) == MEM)
3875    && !TARGET_64BIT
3876    && !TARGET_SOFT_FLOAT"
3877   "*
3879   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3880        || operands[1] == CONST0_RTX (DFmode))
3881       && !(REG_P (operands[0]) && REG_P (operands[1])
3882            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3883     return pa_output_fp_move_double (operands);
3884   return pa_output_move_double (operands);
3886   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3887    (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3889 (define_insn ""
3890   [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3891         (match_operand:DF 1 "reg_or_0_operand" "f"))]
3892   "!TARGET_SOFT_FLOAT
3893    && !TARGET_DISABLE_INDEXING
3894    && reload_completed"
3895   "fstd%F0 %1,%0"
3896   [(set_attr "type" "fpstore")
3897    (set_attr "pa_combine_type" "addmove")
3898    (set_attr "length" "4")])
3900 (define_peephole2
3901   [(set (match_operand:SI 0 "register_operand" "")
3902         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3903                             (const_int 3))
3904                  (match_operand:SI 2 "register_operand" "")))
3905    (set (mem:DF (match_dup 0))
3906         (match_operand:DF 3 "register_operand" ""))]
3907   "!TARGET_SOFT_FLOAT
3908    && !TARGET_DISABLE_INDEXING
3909    && REG_OK_FOR_BASE_P (operands[2])
3910    && FP_REGNO_P (REGNO (operands[3]))"
3911   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3912         (match_dup 3))
3913    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3914                                (match_dup 2)))]
3915   "")
3917 (define_peephole2
3918   [(set (match_operand:SI 0 "register_operand" "")
3919         (plus:SI (match_operand:SI 2 "register_operand" "")
3920                  (ashift:SI (match_operand:SI 1 "register_operand" "")
3921                             (const_int 3))))
3922    (set (mem:DF (match_dup 0))
3923         (match_operand:DF 3 "register_operand" ""))]
3924   "!TARGET_SOFT_FLOAT
3925    && !TARGET_DISABLE_INDEXING
3926    && REG_OK_FOR_BASE_P (operands[2])
3927    && FP_REGNO_P (REGNO (operands[3]))"
3928   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3929         (match_dup 3))
3930    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3931                                (match_dup 2)))]
3932   "")
3934 (define_peephole2
3935   [(set (match_operand:DI 0 "register_operand" "")
3936         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
3937                             (const_int 3))
3938                  (match_operand:DI 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_64BIT
3944    && REG_OK_FOR_BASE_P (operands[2])
3945    && FP_REGNO_P (REGNO (operands[3]))"
3946   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3947         (match_dup 3))
3948    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3949                                (match_dup 2)))]
3950   "")
3952 (define_peephole2
3953   [(set (match_operand:DI 0 "register_operand" "")
3954         (plus:DI (match_operand:DI 2 "register_operand" "")
3955                  (ashift:DI (match_operand:DI 1 "register_operand" "")
3956                             (const_int 3))))
3957    (set (mem:DF (match_dup 0))
3958         (match_operand:DF 3 "register_operand" ""))]
3959   "!TARGET_SOFT_FLOAT
3960    && !TARGET_DISABLE_INDEXING
3961    && TARGET_64BIT
3962    && REG_OK_FOR_BASE_P (operands[2])
3963    && FP_REGNO_P (REGNO (operands[3]))"
3964   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3965         (match_dup 3))
3966    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3967                                (match_dup 2)))]
3968   "")
3970 (define_peephole2
3971   [(set (match_operand:SI 0 "register_operand" "")
3972         (plus:SI (match_operand:SI 1 "register_operand" "")
3973                  (match_operand:SI 2 "register_operand" "")))
3974    (set (mem:DF (match_dup 0))
3975         (match_operand:DF 3 "register_operand" ""))]
3976   "!TARGET_SOFT_FLOAT
3977    && !TARGET_DISABLE_INDEXING
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:SI (match_dup 1) (match_dup 2)))
3983         (match_dup 3))
3984    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3985   "")
3987 (define_peephole2
3988   [(set (match_operand:SI 0 "register_operand" "")
3989         (plus:SI (match_operand:SI 1 "register_operand" "")
3990                  (match_operand:SI 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_NO_SPACE_REGS
3996    && REG_OK_FOR_BASE_P (operands[1])
3997    && REG_OK_FOR_INDEX_P (operands[2])
3998    && FP_REGNO_P (REGNO (operands[3]))"
3999   [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
4000         (match_dup 3))
4001    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4002   "")
4004 (define_peephole2
4005   [(set (match_operand:DI 0 "register_operand" "")
4006         (plus:DI (match_operand:DI 1 "register_operand" "")
4007                  (match_operand:DI 2 "register_operand" "")))
4008    (set (mem:DF (match_dup 0))
4009         (match_operand:DF 3 "register_operand" ""))]
4010   "!TARGET_SOFT_FLOAT
4011    && !TARGET_DISABLE_INDEXING
4012    && TARGET_64BIT
4013    && TARGET_NO_SPACE_REGS
4014    && REG_OK_FOR_INDEX_P (operands[1])
4015    && REG_OK_FOR_BASE_P (operands[2])
4016    && FP_REGNO_P (REGNO (operands[3]))"
4017   [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4018         (match_dup 3))
4019    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4020   "")
4022 (define_peephole2
4023   [(set (match_operand:DI 0 "register_operand" "")
4024         (plus:DI (match_operand:DI 1 "register_operand" "")
4025                  (match_operand:DI 2 "register_operand" "")))
4026    (set (mem:DF (match_dup 0))
4027         (match_operand:DF 3 "register_operand" ""))]
4028   "!TARGET_SOFT_FLOAT
4029    && !TARGET_DISABLE_INDEXING
4030    && TARGET_64BIT
4031    && TARGET_NO_SPACE_REGS
4032    && REG_OK_FOR_BASE_P (operands[1])
4033    && REG_OK_FOR_INDEX_P (operands[2])
4034    && FP_REGNO_P (REGNO (operands[3]))"
4035   [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4036         (match_dup 3))
4037    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4038   "")
4040 (define_insn ""
4041   [(set (match_operand:DF 0 "move_dest_operand"
4042                           "=r,?o,?Q,r,r")
4043         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4044                           "rG,r,r,o,RQ"))]
4045   "(register_operand (operands[0], DFmode)
4046     || reg_or_0_operand (operands[1], DFmode))
4047    && !TARGET_64BIT
4048    && TARGET_SOFT_FLOAT"
4049   "*
4051   return pa_output_move_double (operands);
4053   [(set_attr "type" "move,store,store,load,load")
4054    (set_attr "length" "8,8,16,8,16")])
4056 (define_insn ""
4057   [(set (match_operand:DF 0 "move_dest_operand"
4058                           "=!*r,*r,*r,*r,*r,Q,f,f,T")
4059         (match_operand:DF 1 "move_src_operand"
4060                           "!*rG,J,N,K,RQ,*rG,fG,RT,f"))]
4061   "(register_operand (operands[0], DFmode)
4062     || reg_or_0_operand (operands[1], DFmode))
4063    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4064   "@
4065    copy %r1,%0
4066    ldi %1,%0
4067    ldil L'%1,%0
4068    depdi,z %z1,%0
4069    ldd%M1 %1,%0
4070    std%M0 %r1,%0
4071    fcpy,dbl %f1,%0
4072    fldd%F1 %1,%0
4073    fstd%F0 %1,%0"
4074   [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4075    (set_attr "pa_combine_type" "addmove")
4076    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4078 (define_insn ""
4079   [(set (match_operand:DF 0 "move_dest_operand"
4080                           "=!*r,*r,*r,*r,*r,Q")
4081         (match_operand:DF 1 "move_src_operand"
4082                           "!*rG,J,N,K,RQ,*rG"))]
4083   "(register_operand (operands[0], DFmode)
4084     || reg_or_0_operand (operands[1], DFmode))
4085    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4086   "@
4087    copy %r1,%0
4088    ldi %1,%0
4089    ldil L'%1,%0
4090    depdi,z %z1,%0
4091    ldd%M1 %1,%0
4092    std%M0 %r1,%0"
4093   [(set_attr "type" "move,move,move,shift,load,store")
4094    (set_attr "pa_combine_type" "addmove")
4095    (set_attr "length" "4,4,4,4,4,4")])
4098 (define_expand "movdi"
4099   [(set (match_operand:DI 0 "general_operand" "")
4100         (match_operand:DI 1 "general_operand" ""))]
4101   ""
4102   "
4104   if (pa_emit_move_sequence (operands, DImode, 0))
4105     DONE;
4108 ;; Handle DImode input reloads requiring %r1 as a scratch register.
4109 (define_expand "reload_indi_r1"
4110   [(set (match_operand:DI 0 "register_operand" "=Z")
4111         (match_operand:DI 1 "non_hard_reg_operand" ""))
4112    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4113   ""
4114   "
4116   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4117     DONE;
4119   /* We don't want the clobber emitted, so handle this ourselves.  */
4120   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4121   DONE;
4124 ;; Handle DImode input reloads requiring a general register as a
4125 ;; scratch register.
4126 (define_expand "reload_indi"
4127   [(set (match_operand:DI 0 "register_operand" "=Z")
4128         (match_operand:DI 1 "non_hard_reg_operand" ""))
4129    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4130   ""
4131   "
4133   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4134     DONE;
4136   /* We don't want the clobber emitted, so handle this ourselves.  */
4137   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4138   DONE;
4141 ;; Handle DImode output reloads requiring a general register as a
4142 ;; scratch register.
4143 (define_expand "reload_outdi"
4144   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4145         (match_operand:DI 1 "register_operand" "Z"))
4146    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4147   ""
4148   "
4150   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4151     DONE;
4153   /* We don't want the clobber emitted, so handle this ourselves.  */
4154   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4155   DONE;
4158 (define_insn ""
4159   [(set (match_operand:DI 0 "register_operand" "=r")
4160         (high:DI (match_operand 1 "" "")))]
4161   "!TARGET_64BIT"
4162   "*
4164   rtx op0 = operands[0];
4165   rtx op1 = operands[1];
4167   switch (GET_CODE (op1))
4168     {
4169     case CONST_INT:
4170 #if HOST_BITS_PER_WIDE_INT <= 32
4171       operands[0] = operand_subword (op0, 1, 0, DImode);
4172       output_asm_insn (\"ldil L'%1,%0\", operands);
4174       operands[0] = operand_subword (op0, 0, 0, DImode);
4175       if (INTVAL (op1) < 0)
4176         output_asm_insn (\"ldi -1,%0\", operands);
4177       else
4178         output_asm_insn (\"ldi 0,%0\", operands);
4179 #else
4180       operands[0] = operand_subword (op0, 1, 0, DImode);
4181       operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4182       output_asm_insn (\"ldil L'%1,%0\", operands);
4184       operands[0] = operand_subword (op0, 0, 0, DImode);
4185       operands[1] = GEN_INT (INTVAL (op1) >> 32);
4186       output_asm_insn (pa_singlemove_string (operands), operands);
4187 #endif
4188       break;
4190     case CONST_DOUBLE:
4191       operands[0] = operand_subword (op0, 1, 0, DImode);
4192       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4193       output_asm_insn (\"ldil L'%1,%0\", operands);
4195       operands[0] = operand_subword (op0, 0, 0, DImode);
4196       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4197       output_asm_insn (pa_singlemove_string (operands), operands);
4198       break;
4200     default:
4201       gcc_unreachable ();
4202     }
4203   return \"\";
4205   [(set_attr "type" "move")
4206    (set_attr "length" "12")])
4208 (define_insn ""
4209   [(set (match_operand:DI 0 "move_dest_operand"
4210                           "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4211         (match_operand:DI 1 "move_src_operand"
4212                           "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4213   "(register_operand (operands[0], DImode)
4214     || reg_or_0_operand (operands[1], DImode))
4215    && !TARGET_64BIT
4216    && !TARGET_SOFT_FLOAT"
4217   "*
4219   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4220        || operands[1] == CONST0_RTX (DFmode))
4221       && !(REG_P (operands[0]) && REG_P (operands[1])
4222            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4223     return pa_output_fp_move_double (operands);
4224   return pa_output_move_double (operands);
4226   [(set_attr "type"
4227     "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4228    (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4230 (define_insn ""
4231   [(set (match_operand:DI 0 "move_dest_operand"
4232                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4233         (match_operand:DI 1 "move_src_operand"
4234                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4235   "(register_operand (operands[0], DImode)
4236     || reg_or_0_operand (operands[1], DImode))
4237    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4238   "@
4239    ldd RT'%A1,%0
4240    copy %1,%0
4241    ldi %1,%0
4242    ldil L'%1,%0
4243    depdi,z %z1,%0
4244    ldd%M1 %1,%0
4245    std%M0 %r1,%0
4246    mtsar %r1
4247    {mfctl|mfctl,w} %%sar,%0
4248    fcpy,dbl %f1,%0
4249    fldd%F1 %1,%0
4250    fstd%F0 %1,%0"
4251   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4252    (set_attr "pa_combine_type" "addmove")
4253    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4255 (define_insn ""
4256   [(set (match_operand:DI 0 "move_dest_operand"
4257                           "=r,r,r,r,r,r,Q,!*q,!r")
4258         (match_operand:DI 1 "move_src_operand"
4259                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
4260   "(register_operand (operands[0], DImode)
4261     || reg_or_0_operand (operands[1], DImode))
4262    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4263   "@
4264    ldd RT'%A1,%0
4265    copy %1,%0
4266    ldi %1,%0
4267    ldil L'%1,%0
4268    depdi,z %z1,%0
4269    ldd%M1 %1,%0
4270    std%M0 %r1,%0
4271    mtsar %r1
4272    {mfctl|mfctl,w} %%sar,%0"
4273   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
4274    (set_attr "pa_combine_type" "addmove")
4275    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4277 (define_insn ""
4278   [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4279         (match_operand:DI 1 "register_operand" "f"))]
4280   "!TARGET_SOFT_FLOAT
4281    && TARGET_64BIT
4282    && !TARGET_DISABLE_INDEXING
4283    && reload_completed"
4284   "fstd%F0 %1,%0"
4285   [(set_attr "type" "fpstore")
4286    (set_attr "pa_combine_type" "addmove")
4287    (set_attr "length" "4")])
4289 (define_peephole2
4290   [(set (match_operand:DI 0 "register_operand" "")
4291         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4292                             (const_int 3))
4293                  (match_operand:DI 2 "register_operand" "")))
4294    (set (mem:DI (match_dup 0))
4295         (match_operand:DI 3 "register_operand" ""))]
4296   "!TARGET_SOFT_FLOAT
4297    && !TARGET_DISABLE_INDEXING
4298    && TARGET_64BIT
4299    && REG_OK_FOR_BASE_P (operands[2])
4300    && FP_REGNO_P (REGNO (operands[3]))"
4301   [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4302         (match_dup 3))
4303    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4304                                (match_dup 2)))]
4305   "")
4307 (define_peephole2
4308   [(set (match_operand:DI 0 "register_operand" "")
4309         (plus:DI (match_operand:DI 1 "register_operand" "")
4310                  (match_operand:DI 2 "register_operand" "")))
4311    (set (mem:DI (match_dup 0))
4312         (match_operand:DI 3 "register_operand" ""))]
4313   "!TARGET_SOFT_FLOAT
4314    && !TARGET_DISABLE_INDEXING
4315    && TARGET_64BIT
4316    && TARGET_NO_SPACE_REGS
4317    && REG_OK_FOR_INDEX_P (operands[1])
4318    && REG_OK_FOR_BASE_P (operands[2])
4319    && FP_REGNO_P (REGNO (operands[3]))"
4320   [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4321         (match_dup 3))
4322    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4323   "")
4325 (define_peephole2
4326   [(set (match_operand:DI 0 "register_operand" "")
4327         (plus:DI (match_operand:DI 1 "register_operand" "")
4328                  (match_operand:DI 2 "register_operand" "")))
4329    (set (mem:DI (match_dup 0))
4330         (match_operand:DI 3 "register_operand" ""))]
4331   "!TARGET_SOFT_FLOAT
4332    && !TARGET_DISABLE_INDEXING
4333    && TARGET_64BIT
4334    && TARGET_NO_SPACE_REGS
4335    && REG_OK_FOR_BASE_P (operands[1])
4336    && REG_OK_FOR_INDEX_P (operands[2])
4337    && FP_REGNO_P (REGNO (operands[3]))"
4338   [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4339         (match_dup 3))
4340    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4341   "")
4343 (define_insn ""
4344   [(set (match_operand:DI 0 "move_dest_operand"
4345                           "=r,o,Q,r,r,r")
4346         (match_operand:DI 1 "general_operand"
4347                           "rM,r,r,o,Q,i"))]
4348   "(register_operand (operands[0], DImode)
4349     || reg_or_0_operand (operands[1], DImode))
4350    && !TARGET_64BIT
4351    && TARGET_SOFT_FLOAT"
4352   "*
4354   return pa_output_move_double (operands);
4356   [(set_attr "type" "move,store,store,load,load,multi")
4357    (set_attr "length" "8,8,16,8,16,16")])
4359 (define_insn ""
4360   [(set (match_operand:DI 0 "register_operand" "=r,&r")
4361         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4362                    (match_operand:DI 2 "immediate_operand" "i,i")))]
4363   "!TARGET_64BIT"
4364   "*
4366   /* Don't output a 64-bit constant, since we can't trust the assembler to
4367      handle it correctly.  */
4368   if (GET_CODE (operands[2]) == CONST_DOUBLE)
4369     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4370   else if (HOST_BITS_PER_WIDE_INT > 32
4371            && GET_CODE (operands[2]) == CONST_INT)
4372     operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4373   if (which_alternative == 1)
4374     output_asm_insn (\"copy %1,%0\", operands);
4375   return \"ldo R'%G2(%R1),%R0\";
4377   [(set_attr "type" "move,move")
4378    (set_attr "length" "4,8")])
4380 (define_expand "movsf"
4381   [(set (match_operand:SF 0 "general_operand" "")
4382         (match_operand:SF 1 "general_operand" ""))]
4383   ""
4384   "
4386   if (pa_emit_move_sequence (operands, SFmode, 0))
4387     DONE;
4390 ;; Handle SFmode input reloads requiring %r1 as a scratch register.
4391 (define_expand "reload_insf_r1"
4392   [(set (match_operand:SF 0 "register_operand" "=Z")
4393         (match_operand:SF 1 "non_hard_reg_operand" ""))
4394    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4395   ""
4396   "
4398   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4399     DONE;
4401   /* We don't want the clobber emitted, so handle this ourselves.  */
4402   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4403   DONE;
4406 ;; Handle SFmode input reloads requiring a general register as a
4407 ;; scratch register.
4408 (define_expand "reload_insf"
4409   [(set (match_operand:SF 0 "register_operand" "=Z")
4410         (match_operand:SF 1 "non_hard_reg_operand" ""))
4411    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4412   ""
4413   "
4415   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4416     DONE;
4418   /* We don't want the clobber emitted, so handle this ourselves.  */
4419   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4420   DONE;
4423 ;; Handle SFmode output reloads requiring a general register as a
4424 ;; scratch register.
4425 (define_expand "reload_outsf"
4426   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4427         (match_operand:SF 1  "register_operand" "Z"))
4428    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4429   ""
4430   "
4432   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4433     DONE;
4435   /* We don't want the clobber emitted, so handle this ourselves.  */
4436   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4437   DONE;
4440 (define_insn ""
4441   [(set (match_operand:SF 0 "move_dest_operand"
4442                           "=f,!*r,f,*r,T,Q,?*r,?f")
4443         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4444                           "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4445   "(register_operand (operands[0], SFmode)
4446     || reg_or_0_operand (operands[1], SFmode))
4447    && !TARGET_SOFT_FLOAT
4448    && !TARGET_64BIT"
4449   "@
4450    fcpy,sgl %f1,%0
4451    copy %r1,%0
4452    fldw%F1 %1,%0
4453    ldw%M1 %1,%0
4454    fstw%F0 %1,%0
4455    stw%M0 %r1,%0
4456    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4457    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4458   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4459    (set_attr "pa_combine_type" "addmove")
4460    (set_attr "length" "4,4,4,4,4,4,8,8")])
4462 (define_insn ""
4463   [(set (match_operand:SF 0 "move_dest_operand"
4464                           "=f,!*r,f,*r,T,Q")
4465         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4466                           "fG,!*rG,RT,RQ,f,*rG"))]
4467   "(register_operand (operands[0], SFmode)
4468     || reg_or_0_operand (operands[1], SFmode))
4469    && !TARGET_SOFT_FLOAT
4470    && TARGET_64BIT"
4471   "@
4472    fcpy,sgl %f1,%0
4473    copy %r1,%0
4474    fldw%F1 %1,%0
4475    ldw%M1 %1,%0
4476    fstw%F0 %1,%0
4477    stw%M0 %r1,%0"
4478   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4479    (set_attr "pa_combine_type" "addmove")
4480    (set_attr "length" "4,4,4,4,4,4")])
4482 (define_insn ""
4483   [(set (match_operand:SF 0 "move_dest_operand"
4484                           "=!*r,*r,Q")
4485         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4486                           "!*rG,RQ,*rG"))]
4487   "(register_operand (operands[0], SFmode)
4488     || reg_or_0_operand (operands[1], SFmode))
4489    && TARGET_SOFT_FLOAT
4490    && TARGET_64BIT"
4491   "@
4492    copy %r1,%0
4493    ldw%M1 %1,%0
4494    stw%M0 %r1,%0"
4495   [(set_attr "type" "move,load,store")
4496    (set_attr "pa_combine_type" "addmove")
4497    (set_attr "length" "4,4,4")])
4499 (define_insn ""
4500   [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4501         (match_operand:SF 1 "register_operand" "f"))]
4502   "!TARGET_SOFT_FLOAT
4503    && !TARGET_DISABLE_INDEXING
4504    && reload_completed"
4505   "fstw%F0 %1,%0"
4506   [(set_attr "type" "fpstore")
4507    (set_attr "pa_combine_type" "addmove")
4508    (set_attr "length" "4")])
4510 (define_peephole2
4511   [(set (match_operand:SI 0 "register_operand" "")
4512         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4513                             (const_int 2))
4514                  (match_operand:SI 2 "register_operand" "")))
4515    (set (mem:SF (match_dup 0))
4516         (match_operand:SF 3 "register_operand" ""))]
4517   "!TARGET_SOFT_FLOAT
4518    && !TARGET_DISABLE_INDEXING
4519    && REG_OK_FOR_BASE_P (operands[2])
4520    && FP_REGNO_P (REGNO (operands[3]))"
4521   [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4522         (match_dup 3))
4523    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4524                                (match_dup 2)))]
4525   "")
4527 (define_peephole2
4528   [(set (match_operand:DI 0 "register_operand" "")
4529         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4530                             (const_int 2))
4531                  (match_operand:DI 2 "register_operand" "")))
4532    (set (mem:SF (match_dup 0))
4533         (match_operand:SF 3 "register_operand" ""))]
4534   "!TARGET_SOFT_FLOAT
4535    && !TARGET_DISABLE_INDEXING
4536    && TARGET_64BIT
4537    && REG_OK_FOR_BASE_P (operands[2])
4538    && FP_REGNO_P (REGNO (operands[3]))"
4539   [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4540         (match_dup 3))
4541    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4542                                (match_dup 2)))]
4543   "")
4545 (define_peephole2
4546   [(set (match_operand:SI 0 "register_operand" "")
4547         (plus:SI (match_operand:SI 1 "register_operand" "")
4548                  (match_operand:SI 2 "register_operand" "")))
4549    (set (mem:SF (match_dup 0))
4550         (match_operand:SF 3 "register_operand" ""))]
4551   "!TARGET_SOFT_FLOAT
4552    && !TARGET_DISABLE_INDEXING
4553    && TARGET_NO_SPACE_REGS
4554    && REG_OK_FOR_INDEX_P (operands[1])
4555    && REG_OK_FOR_BASE_P (operands[2])
4556    && FP_REGNO_P (REGNO (operands[3]))"
4557   [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4558         (match_dup 3))
4559    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4560   "")
4562 (define_peephole2
4563   [(set (match_operand:SI 0 "register_operand" "")
4564         (plus:SI (match_operand:SI 1 "register_operand" "")
4565                  (match_operand:SI 2 "register_operand" "")))
4566    (set (mem:SF (match_dup 0))
4567         (match_operand:SF 3 "register_operand" ""))]
4568   "!TARGET_SOFT_FLOAT
4569    && !TARGET_DISABLE_INDEXING
4570    && TARGET_NO_SPACE_REGS
4571    && REG_OK_FOR_BASE_P (operands[1])
4572    && REG_OK_FOR_INDEX_P (operands[2])
4573    && FP_REGNO_P (REGNO (operands[3]))"
4574   [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4575         (match_dup 3))
4576    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4577   "")
4579 (define_peephole2
4580   [(set (match_operand:DI 0 "register_operand" "")
4581         (plus:DI (match_operand:DI 1 "register_operand" "")
4582                  (match_operand:DI 2 "register_operand" "")))
4583    (set (mem:SF (match_dup 0))
4584         (match_operand:SF 3 "register_operand" ""))]
4585   "!TARGET_SOFT_FLOAT
4586    && !TARGET_DISABLE_INDEXING
4587    && TARGET_64BIT
4588    && TARGET_NO_SPACE_REGS
4589    && REG_OK_FOR_INDEX_P (operands[1])
4590    && REG_OK_FOR_BASE_P (operands[2])
4591    && FP_REGNO_P (REGNO (operands[3]))"
4592   [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4593         (match_dup 3))
4594    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4595   "")
4597 (define_peephole2
4598   [(set (match_operand:DI 0 "register_operand" "")
4599         (plus:DI (match_operand:DI 1 "register_operand" "")
4600                  (match_operand:DI 2 "register_operand" "")))
4601    (set (mem:SF (match_dup 0))
4602         (match_operand:SF 3 "register_operand" ""))]
4603   "!TARGET_SOFT_FLOAT
4604    && !TARGET_DISABLE_INDEXING
4605    && TARGET_64BIT
4606    && TARGET_NO_SPACE_REGS
4607    && REG_OK_FOR_BASE_P (operands[1])
4608    && REG_OK_FOR_INDEX_P (operands[2])
4609    && FP_REGNO_P (REGNO (operands[3]))"
4610   [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4611         (match_dup 3))
4612    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4613   "")
4615 (define_insn ""
4616   [(set (match_operand:SF 0 "move_dest_operand"
4617                           "=r,r,Q")
4618         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4619                           "rG,RQ,rG"))]
4620   "(register_operand (operands[0], SFmode)
4621     || reg_or_0_operand (operands[1], SFmode))
4622    && TARGET_SOFT_FLOAT"
4623   "@
4624    copy %r1,%0
4625    ldw%M1 %1,%0
4626    stw%M0 %r1,%0"
4627   [(set_attr "type" "move,load,store")
4628    (set_attr "pa_combine_type" "addmove")
4629    (set_attr "length" "4,4,4")])
4633 ;;- zero extension instructions
4634 ;; We have define_expand for zero extension patterns to make sure the
4635 ;; operands get loaded into registers.  The define_insns accept
4636 ;; memory operands.  This gives us better overall code than just
4637 ;; having a pattern that does or does not accept memory operands.
4639 (define_expand "zero_extendqihi2"
4640   [(set (match_operand:HI 0 "register_operand" "")
4641         (zero_extend:HI
4642          (match_operand:QI 1 "register_operand" "")))]
4643   ""
4644   "")
4646 (define_insn ""
4647   [(set (match_operand:HI 0 "register_operand" "=r,r")
4648         (zero_extend:HI
4649          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4650   "GET_CODE (operands[1]) != CONST_INT"
4651   "@
4652    {extru|extrw,u} %1,31,8,%0
4653    ldb%M1 %1,%0"
4654   [(set_attr "type" "shift,load")
4655    (set_attr "length" "4,4")])
4657 (define_expand "zero_extendqisi2"
4658   [(set (match_operand:SI 0 "register_operand" "")
4659         (zero_extend:SI
4660          (match_operand:QI 1 "register_operand" "")))]
4661   ""
4662   "")
4664 (define_insn ""
4665   [(set (match_operand:SI 0 "register_operand" "=r,r")
4666         (zero_extend:SI
4667          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4668   "GET_CODE (operands[1]) != CONST_INT"
4669   "@
4670    {extru|extrw,u} %1,31,8,%0
4671    ldb%M1 %1,%0"
4672   [(set_attr "type" "shift,load")
4673    (set_attr "length" "4,4")])
4675 (define_expand "zero_extendhisi2"
4676   [(set (match_operand:SI 0 "register_operand" "")
4677         (zero_extend:SI
4678          (match_operand:HI 1 "register_operand" "")))]
4679   ""
4680   "")
4682 (define_insn ""
4683   [(set (match_operand:SI 0 "register_operand" "=r,r")
4684         (zero_extend:SI
4685          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4686   "GET_CODE (operands[1]) != CONST_INT"
4687   "@
4688    {extru|extrw,u} %1,31,16,%0
4689    ldh%M1 %1,%0"
4690   [(set_attr "type" "shift,load")
4691    (set_attr "length" "4,4")])
4693 (define_expand "zero_extendqidi2"
4694   [(set (match_operand:DI 0 "register_operand" "")
4695         (zero_extend:DI
4696          (match_operand:QI 1 "register_operand" "")))]
4697   "TARGET_64BIT"
4698   "")
4700 (define_insn ""
4701   [(set (match_operand:DI 0 "register_operand" "=r,r")
4702         (zero_extend:DI
4703          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4704   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4705   "@
4706    extrd,u %1,63,8,%0
4707    ldb%M1 %1,%0"
4708   [(set_attr "type" "shift,load")
4709    (set_attr "length" "4,4")])
4711 (define_expand "zero_extendhidi2"
4712   [(set (match_operand:DI 0 "register_operand" "")
4713         (zero_extend:DI
4714          (match_operand:HI 1 "register_operand" "")))]
4715   "TARGET_64BIT"
4716   "")
4718 (define_insn ""
4719   [(set (match_operand:DI 0 "register_operand" "=r,r")
4720         (zero_extend:DI
4721          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4722   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4723   "@
4724    extrd,u %1,63,16,%0
4725    ldh%M1 %1,%0"
4726   [(set_attr "type" "shift,load")
4727    (set_attr "length" "4,4")])
4729 (define_expand "zero_extendsidi2"
4730   [(set (match_operand:DI 0 "register_operand" "")
4731         (zero_extend:DI
4732          (match_operand:SI 1 "register_operand" "")))]
4733   "TARGET_64BIT"
4734   "")
4736 (define_insn ""
4737   [(set (match_operand:DI 0 "register_operand" "=r,r")
4738         (zero_extend:DI
4739          (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4740   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4741   "@
4742    extrd,u %1,63,32,%0
4743    ldw%M1 %1,%0"
4744   [(set_attr "type" "shift,load")
4745    (set_attr "length" "4,4")])
4747 ;;- sign extension instructions
4749 (define_insn "extendhisi2"
4750   [(set (match_operand:SI 0 "register_operand" "=r")
4751         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4752   ""
4753   "{extrs|extrw,s} %1,31,16,%0"
4754   [(set_attr "type" "shift")
4755    (set_attr "length" "4")])
4757 (define_insn "extendqihi2"
4758   [(set (match_operand:HI 0 "register_operand" "=r")
4759         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4760   ""
4761   "{extrs|extrw,s} %1,31,8,%0"
4762   [(set_attr "type" "shift") 
4763   (set_attr "length" "4")])
4765 (define_insn "extendqisi2"
4766   [(set (match_operand:SI 0 "register_operand" "=r")
4767         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4768   ""
4769   "{extrs|extrw,s} %1,31,8,%0"
4770   [(set_attr "type" "shift")
4771    (set_attr "length" "4")])
4773 (define_insn "extendqidi2"
4774   [(set (match_operand:DI 0 "register_operand" "=r")
4775         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4776   "TARGET_64BIT"
4777   "extrd,s %1,63,8,%0"
4778   [(set_attr "type" "shift") 
4779   (set_attr "length" "4")])
4781 (define_insn "extendhidi2"
4782   [(set (match_operand:DI 0 "register_operand" "=r")
4783         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4784   "TARGET_64BIT"
4785   "extrd,s %1,63,16,%0"
4786   [(set_attr "type" "shift") 
4787   (set_attr "length" "4")])
4789 (define_insn "extendsidi2"
4790   [(set (match_operand:DI 0 "register_operand" "=r")
4791         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4792   "TARGET_64BIT"
4793   "extrd,s %1,63,32,%0"
4794   [(set_attr "type" "shift") 
4795   (set_attr "length" "4")])
4798 ;; Conversions between float and double.
4800 (define_insn "extendsfdf2"
4801   [(set (match_operand:DF 0 "register_operand" "=f")
4802         (float_extend:DF
4803          (match_operand:SF 1 "register_operand" "f")))]
4804   "! TARGET_SOFT_FLOAT"
4805   "{fcnvff|fcnv},sgl,dbl %1,%0"
4806   [(set_attr "type" "fpalu")
4807    (set_attr "length" "4")])
4809 (define_insn "truncdfsf2"
4810   [(set (match_operand:SF 0 "register_operand" "=f")
4811         (float_truncate:SF
4812          (match_operand:DF 1 "register_operand" "f")))]
4813   "! TARGET_SOFT_FLOAT"
4814   "{fcnvff|fcnv},dbl,sgl %1,%0"
4815   [(set_attr "type" "fpalu")
4816    (set_attr "length" "4")])
4818 ;; Conversion between fixed point and floating point.
4819 ;; Note that among the fix-to-float insns
4820 ;; the ones that start with SImode come first.
4821 ;; That is so that an operand that is a CONST_INT
4822 ;; (and therefore lacks a specific machine mode).
4823 ;; will be recognized as SImode (which is always valid)
4824 ;; rather than as QImode or HImode.
4826 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4827 ;; to be reloaded by putting the constant into memory.
4828 ;; It must come before the more general floatsisf2 pattern.
4829 (define_insn ""
4830   [(set (match_operand:SF 0 "register_operand" "=f")
4831         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4832   "! TARGET_SOFT_FLOAT"
4833   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4834   [(set_attr "type" "fpalu")
4835    (set_attr "length" "8")])
4837 (define_insn "floatsisf2"
4838   [(set (match_operand:SF 0 "register_operand" "=f")
4839         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4840   "! TARGET_SOFT_FLOAT"
4841   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4842   [(set_attr "type" "fpalu")
4843    (set_attr "length" "4")])
4845 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4846 ;; to be reloaded by putting the constant into memory.
4847 ;; It must come before the more general floatsidf2 pattern.
4848 (define_insn ""
4849   [(set (match_operand:DF 0 "register_operand" "=f")
4850         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4851   "! TARGET_SOFT_FLOAT"
4852   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4853   [(set_attr "type" "fpalu")
4854    (set_attr "length" "8")])
4856 (define_insn "floatsidf2"
4857   [(set (match_operand:DF 0 "register_operand" "=f")
4858         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4859   "! TARGET_SOFT_FLOAT"
4860   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4861   [(set_attr "type" "fpalu")
4862    (set_attr "length" "4")])
4864 (define_expand "floatunssisf2"
4865   [(set (subreg:SI (match_dup 2) 4)
4866         (match_operand:SI 1 "register_operand" ""))
4867    (set (subreg:SI (match_dup 2) 0)
4868         (const_int 0))
4869    (set (match_operand:SF 0 "register_operand" "")
4870         (float:SF (match_dup 2)))]
4871   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4872   "
4874   if (TARGET_PA_20)
4875     {
4876       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4877       DONE;
4878     }
4879   operands[2] = gen_reg_rtx (DImode);
4882 (define_expand "floatunssidf2"
4883   [(set (subreg:SI (match_dup 2) 4)
4884         (match_operand:SI 1 "register_operand" ""))
4885    (set (subreg:SI (match_dup 2) 0)
4886         (const_int 0))
4887    (set (match_operand:DF 0 "register_operand" "")
4888         (float:DF (match_dup 2)))]
4889   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4890   "
4892   if (TARGET_PA_20)
4893     {
4894       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4895       DONE;
4896     }
4897   operands[2] = gen_reg_rtx (DImode);
4900 (define_insn "floatdisf2"
4901   [(set (match_operand:SF 0 "register_operand" "=f")
4902         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4903   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4904   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4905   [(set_attr "type" "fpalu")
4906    (set_attr "length" "4")])
4908 (define_insn "floatdidf2"
4909   [(set (match_operand:DF 0 "register_operand" "=f")
4910         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4911   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4912   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4913   [(set_attr "type" "fpalu")
4914    (set_attr "length" "4")])
4916 ;; Convert a float to an actual integer.
4917 ;; Truncation is performed as part of the conversion.
4919 (define_insn "fix_truncsfsi2"
4920   [(set (match_operand:SI 0 "register_operand" "=f")
4921         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4922   "! TARGET_SOFT_FLOAT"
4923   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4924   [(set_attr "type" "fpalu")
4925    (set_attr "length" "4")])
4927 (define_insn "fix_truncdfsi2"
4928   [(set (match_operand:SI 0 "register_operand" "=f")
4929         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4930   "! TARGET_SOFT_FLOAT"
4931   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4932   [(set_attr "type" "fpalu")
4933    (set_attr "length" "4")])
4935 (define_insn "fix_truncsfdi2"
4936   [(set (match_operand:DI 0 "register_operand" "=f")
4937         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4938   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4939   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4940   [(set_attr "type" "fpalu")
4941    (set_attr "length" "4")])
4943 (define_insn "fix_truncdfdi2"
4944   [(set (match_operand:DI 0 "register_operand" "=f")
4945         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4946   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4947   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4948   [(set_attr "type" "fpalu")
4949    (set_attr "length" "4")])
4951 (define_insn "floatunssidf2_pa20"
4952   [(set (match_operand:DF 0 "register_operand" "=f")
4953         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4954   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4955   "fcnv,uw,dbl %1,%0"
4956   [(set_attr "type" "fpalu")
4957    (set_attr "length" "4")])
4959 (define_insn "floatunssisf2_pa20"
4960   [(set (match_operand:SF 0 "register_operand" "=f")
4961         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4962   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4963   "fcnv,uw,sgl %1,%0"
4964   [(set_attr "type" "fpalu")
4965    (set_attr "length" "4")])
4967 (define_insn "floatunsdisf2"
4968   [(set (match_operand:SF 0 "register_operand" "=f")
4969         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4970   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4971   "fcnv,udw,sgl %1,%0"
4972   [(set_attr "type" "fpalu")
4973    (set_attr "length" "4")])
4975 (define_insn "floatunsdidf2"
4976   [(set (match_operand:DF 0 "register_operand" "=f")
4977         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4978   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4979   "fcnv,udw,dbl %1,%0"
4980   [(set_attr "type" "fpalu")
4981    (set_attr "length" "4")])
4983 (define_insn "fixuns_truncsfsi2"
4984   [(set (match_operand:SI 0 "register_operand" "=f")
4985         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4986   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4987   "fcnv,t,sgl,uw %1,%0"
4988   [(set_attr "type" "fpalu")
4989    (set_attr "length" "4")])
4991 (define_insn "fixuns_truncdfsi2"
4992   [(set (match_operand:SI 0 "register_operand" "=f")
4993         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4994   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4995   "fcnv,t,dbl,uw %1,%0"
4996   [(set_attr "type" "fpalu")
4997    (set_attr "length" "4")])
4999 (define_insn "fixuns_truncsfdi2"
5000   [(set (match_operand:DI 0 "register_operand" "=f")
5001         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5002   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5003   "fcnv,t,sgl,udw %1,%0"
5004   [(set_attr "type" "fpalu")
5005    (set_attr "length" "4")])
5007 (define_insn "fixuns_truncdfdi2"
5008   [(set (match_operand:DI 0 "register_operand" "=f")
5009         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5010   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5011   "fcnv,t,dbl,udw %1,%0"
5012   [(set_attr "type" "fpalu")
5013    (set_attr "length" "4")])
5015 ;;- arithmetic instructions
5017 (define_expand "adddi3"
5018   [(set (match_operand:DI 0 "register_operand" "")
5019         (plus:DI (match_operand:DI 1 "register_operand" "")
5020                  (match_operand:DI 2 "adddi3_operand" "")))]
5021   ""
5022   "")
5024 (define_insn ""
5025   [(set (match_operand:DI 0 "register_operand" "=r")
5026         (plus:DI (match_operand:DI 1 "register_operand" "%r")
5027                  (match_operand:DI 2 "arith11_operand" "rI")))]
5028   "!TARGET_64BIT"
5029   "*
5031   if (GET_CODE (operands[2]) == CONST_INT)
5032     {
5033       if (INTVAL (operands[2]) >= 0)
5034         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5035       else
5036         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5037     }
5038   else
5039     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5041   [(set_attr "type" "binary")
5042    (set_attr "length" "8")])
5044 (define_insn ""
5045   [(set (match_operand:DI 0 "register_operand" "=r,r")
5046         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5047                  (match_operand:DI 2 "arith14_operand" "r,J")))]
5048   "TARGET_64BIT"
5049   "@
5050    add,l %1,%2,%0
5051    ldo %2(%1),%0"
5052   [(set_attr "type" "binary,binary")
5053    (set_attr "pa_combine_type" "addmove")
5054    (set_attr "length" "4,4")])
5056 (define_insn ""
5057   [(set (match_operand:DI 0 "register_operand" "=r")
5058         (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5059                  (match_operand:DI 2 "register_operand" "r")))]
5060   "TARGET_64BIT"
5061   "uaddcm %2,%1,%0"
5062   [(set_attr "type" "binary")
5063    (set_attr "length" "4")])
5065 (define_insn ""
5066   [(set (match_operand:SI 0 "register_operand" "=r")
5067         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5068                  (match_operand:SI 2 "register_operand" "r")))]
5069   ""
5070   "uaddcm %2,%1,%0"
5071   [(set_attr "type" "binary")
5072    (set_attr "length" "4")])
5074 (define_expand "addvdi3"
5075   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5076                    (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5077                             (match_operand:DI 2 "arith11_operand" "")))
5078               (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5079                                     (sign_extend:TI (match_dup 2)))
5080                            (sign_extend:TI (plus:DI (match_dup 1)
5081                                                     (match_dup 2))))
5082                        (const_int 0))])]
5083   ""
5084   "
5086   if (TARGET_64BIT)
5087     operands[2] = force_reg (DImode, operands[2]);
5090 (define_insn ""
5091   [(set (match_operand:DI 0 "register_operand" "=r")
5092         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5093                  (match_operand:DI 2 "register_operand" "r")))
5094    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5095                          (sign_extend:TI (match_dup 2)))
5096                 (sign_extend:TI (plus:DI (match_dup 1)
5097                                          (match_dup 2))))
5098             (const_int 0))]
5099   "TARGET_64BIT"
5100   "add,tsv,* %2,%1,%0"
5101   [(set_attr "type" "binary")
5102    (set_attr "length" "4")])
5104 (define_insn ""
5105   [(set (match_operand:DI 0 "register_operand" "=r")
5106         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5107                  (match_operand:DI 2 "arith11_operand" "rI")))
5108    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5109                          (sign_extend:TI (match_dup 2)))
5110                 (sign_extend:TI (plus:DI (match_dup 1)
5111                                          (match_dup 2))))
5112             (const_int 0))]
5113   "!TARGET_64BIT"
5114   "*
5116   if (GET_CODE (operands[2]) == CONST_INT)
5117     {
5118       if (INTVAL (operands[2]) >= 0)
5119         return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5120       else
5121         return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5122     }
5123   else
5124     return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5126   [(set_attr "type" "binary")
5127    (set_attr "length" "8")])
5129 ;; define_splits to optimize cases of adding a constant integer
5130 ;; to a register when the constant does not fit in 14 bits.  */
5131 (define_split
5132   [(set (match_operand:SI 0 "register_operand" "")
5133         (plus:SI (match_operand:SI 1 "register_operand" "")
5134                  (match_operand:SI 2 "const_int_operand" "")))
5135    (clobber (match_operand:SI 4 "register_operand" ""))]
5136   "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5137    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5138   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5139    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5140   "
5142   int val = INTVAL (operands[2]);
5143   int low = (val < 0) ? -0x2000 : 0x1fff;
5144   int rest = val - low;
5146   operands[2] = GEN_INT (rest);
5147   operands[3] = GEN_INT (low);
5150 (define_split
5151   [(set (match_operand:SI 0 "register_operand" "")
5152         (plus:SI (match_operand:SI 1 "register_operand" "")
5153                  (match_operand:SI 2 "const_int_operand" "")))
5154    (clobber (match_operand:SI 4 "register_operand" ""))]
5155   "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5156   [(set (match_dup 4) (match_dup 2))
5157    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5158                                (match_dup 1)))]
5159   "
5161   unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5163   /* Try dividing the constant by 2, then 4, and finally 8 to see
5164      if we can get a constant which can be loaded into a register
5165      in a single instruction (pa_cint_ok_for_move). 
5167      If that fails, try to negate the constant and subtract it
5168      from our input operand.  */
5169   if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5170     {
5171       operands[2] = GEN_INT (intval / 2);
5172       operands[3] = const1_rtx;
5173     }
5174   else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5175     {
5176       operands[2] = GEN_INT (intval / 4);
5177       operands[3] = const2_rtx;
5178     }
5179   else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5180     {
5181       operands[2] = GEN_INT (intval / 8);
5182       operands[3] = GEN_INT (3);
5183     }
5184   else if (pa_cint_ok_for_move (-intval))
5185     {
5186       emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5187       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5188       DONE;
5189     }
5190   else
5191     FAIL;
5194 (define_insn "addsi3"
5195   [(set (match_operand:SI 0 "register_operand" "=r,r")
5196         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5197                  (match_operand:SI 2 "arith14_operand" "r,J")))]
5198   ""
5199   "@
5200    {addl|add,l} %1,%2,%0
5201    ldo %2(%1),%0"
5202   [(set_attr "type" "binary,binary")
5203    (set_attr "pa_combine_type" "addmove")
5204    (set_attr "length" "4,4")])
5206 (define_insn "addvsi3"
5207   [(set (match_operand:SI 0 "register_operand" "=r,r")
5208         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5209                  (match_operand:SI 2 "arith11_operand" "r,I")))
5210    (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5211                          (sign_extend:DI (match_dup 2)))
5212                 (sign_extend:DI (plus:SI (match_dup 1)
5213                                          (match_dup 2))))
5214             (const_int 0))]
5215   ""
5216   "@
5217   {addo|add,tsv} %2,%1,%0
5218   {addio|addi,tsv} %2,%1,%0"
5219   [(set_attr "type" "binary,binary")
5220    (set_attr "length" "4,4")])
5222 (define_expand "subdi3"
5223   [(set (match_operand:DI 0 "register_operand" "")
5224         (minus:DI (match_operand:DI 1 "arith11_operand" "")
5225                   (match_operand:DI 2 "reg_or_0_operand" "")))]
5226   ""
5227   "")
5229 (define_insn ""
5230   [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5231         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5232                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5233   "TARGET_64BIT"
5234   "@
5235    sub %1,%2,%0
5236    subi %1,%2,%0
5237    mtsarcm %2"
5238   [(set_attr "type" "binary,binary,move")
5239   (set_attr "length" "4,4,4")])
5241 (define_insn ""
5242   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5243         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5244                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5245   "!TARGET_64BIT"
5246   "*
5248   if (GET_CODE (operands[1]) == CONST_INT)
5249     {
5250       if (INTVAL (operands[1]) >= 0)
5251         return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5252       else
5253         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5254     }
5255   else
5256     return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5258   [(set_attr "type" "binary")
5259    (set (attr "length")
5260         (if_then_else (eq_attr "alternative" "0")
5261           (const_int 8)
5262           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5263                             (const_int 0))
5264             (const_int 8)
5265             (const_int 12))))])
5267 (define_expand "subvdi3"
5268   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5269                    (minus:DI (match_operand:DI 1 "arith11_operand" "")
5270                              (match_operand:DI 2 "reg_or_0_operand" "")))
5271               (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5272                                      (sign_extend:TI (match_dup 2)))
5273                            (sign_extend:TI (minus:DI (match_dup 1)
5274                                                      (match_dup 2))))
5275                        (const_int 0))])]
5276   ""
5277   "
5279   if (TARGET_64BIT)
5280     operands[1] = force_reg (DImode, operands[1]);
5283 (define_insn ""
5284   [(set (match_operand:DI 0 "register_operand" "=r")
5285         (minus:DI (match_operand:DI 1 "register_operand" "r")
5286                   (match_operand:DI 2 "reg_or_0_operand" "rM")))
5287    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5288                           (sign_extend:TI (match_dup 2)))
5289                 (sign_extend:TI (minus:DI (match_dup 1)
5290                                           (match_dup 2))))
5291             (const_int 0))]
5292   "TARGET_64BIT"
5293   "sub,tsv,* %1,%2,%0"
5294   [(set_attr "type" "binary")
5295    (set_attr "length" "4")])
5297 (define_insn ""
5298   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5299         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5300                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5301    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5302                           (sign_extend:TI (match_dup 2)))
5303                 (sign_extend:TI (minus:DI (match_dup 1)
5304                                           (match_dup 2))))
5305             (const_int 0))]
5306   "!TARGET_64BIT"
5307   "*
5309   if (GET_CODE (operands[1]) == CONST_INT)
5310     {
5311       if (INTVAL (operands[1]) >= 0)
5312         return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5313       else
5314         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5315     }
5316   else
5317     return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5319   [(set_attr "type" "binary,binary")
5320    (set (attr "length")
5321         (if_then_else (eq_attr "alternative" "0")
5322           (const_int 8)
5323           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5324                             (const_int 0))
5325             (const_int 8)
5326             (const_int 12))))])
5328 (define_expand "subsi3"
5329   [(set (match_operand:SI 0 "register_operand" "")
5330         (minus:SI (match_operand:SI 1 "arith11_operand" "")
5331                   (match_operand:SI 2 "register_operand" "")))]
5332   ""
5333   "")
5335 (define_insn ""
5336   [(set (match_operand:SI 0 "register_operand" "=r,r")
5337         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5338                   (match_operand:SI 2 "register_operand" "r,r")))]
5339   "!TARGET_PA_20"
5340   "@
5341    sub %1,%2,%0
5342    subi %1,%2,%0"
5343   [(set_attr "type" "binary,binary")
5344    (set_attr "length" "4,4")])
5346 (define_insn ""
5347   [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5348         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5349                   (match_operand:SI 2 "register_operand" "r,r,!r")))]
5350   "TARGET_PA_20"
5351   "@
5352    sub %1,%2,%0
5353    subi %1,%2,%0
5354    mtsarcm %2"
5355   [(set_attr "type" "binary,binary,move")
5356    (set_attr "length" "4,4,4")])
5358 (define_insn "subvsi3"
5359   [(set (match_operand:SI 0 "register_operand" "=r,r")
5360         (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5361                   (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5362    (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5363                           (sign_extend:DI (match_dup 2)))
5364                 (sign_extend:DI (minus:SI (match_dup 1)
5365                                           (match_dup 2))))
5366             (const_int 0))]
5367   ""
5368   "@
5369   {subo|sub,tsv} %1,%2,%0
5370   {subio|subi,tsv} %1,%2,%0"
5371   [(set_attr "type" "binary,binary")
5372    (set_attr "length" "4,4")])
5374 (define_insn "addti3"
5375   [(set (match_operand:TI 0 "register_operand" "=r")
5376         (plus:TI (match_operand:TI 1 "register_operand" "r")
5377                  (match_operand:TI 2 "register_operand" "r")))]
5378   "TARGET_64BIT"
5379   "*
5381   operands[3] = gen_lowpart (DImode, operands[0]);
5382   operands[4] = gen_lowpart (DImode, operands[1]);
5383   operands[5] = gen_lowpart (DImode, operands[2]);
5384   operands[0] = gen_highpart (DImode, operands[0]);
5385   operands[1] = gen_highpart (DImode, operands[1]);
5386   operands[2] = gen_highpart (DImode, operands[2]);
5387   return \"add %4,%5,%3\;add,dc %1,%2,%0\";
5389   [(set_attr "type" "multi")
5390    (set_attr "length" "8")])
5392 (define_insn "addvti3"
5393   [(set (match_operand:TI 0 "register_operand" "=r")
5394         (plus:TI (match_operand:TI 1 "register_operand" "r")
5395                  (match_operand:TI 2 "register_operand" "r")))
5396    (trap_if (ne (plus:OI (sign_extend:OI (match_dup 1))
5397                          (sign_extend:OI (match_dup 2)))
5398                 (sign_extend:OI (plus:TI (match_dup 1)
5399                                          (match_dup 2))))
5400             (const_int 0))]
5401   "TARGET_64BIT"
5402   "*
5404   operands[3] = gen_lowpart (DImode, operands[0]);
5405   operands[4] = gen_lowpart (DImode, operands[1]);
5406   operands[5] = gen_lowpart (DImode, operands[2]);
5407   operands[0] = gen_highpart (DImode, operands[0]);
5408   operands[1] = gen_highpart (DImode, operands[1]);
5409   operands[2] = gen_highpart (DImode, operands[2]);
5410   return \"add %4,%5,%3\;add,dc,tsv %1,%2,%0\";
5412   [(set_attr "type" "multi")
5413    (set_attr "length" "8")])
5415 (define_insn "subti3"
5416   [(set (match_operand:TI 0 "register_operand" "=r")
5417         (minus:TI (match_operand:TI 1 "register_operand" "r")
5418                   (match_operand:TI 2 "register_operand" "r")))]
5419   "TARGET_64BIT"
5420   "*
5422   operands[3] = gen_lowpart (DImode, operands[0]);
5423   operands[4] = gen_lowpart (DImode, operands[1]);
5424   operands[5] = gen_lowpart (DImode, operands[2]);
5425   operands[0] = gen_highpart (DImode, operands[0]);
5426   operands[1] = gen_highpart (DImode, operands[1]);
5427   operands[2] = gen_highpart (DImode, operands[2]);
5428   return \"sub %4,%5,%3\;sub,db %1,%2,%0\";
5430   [(set_attr "type" "multi")
5431    (set_attr "length" "8")])
5433 (define_insn "subvti3"
5434   [(set (match_operand:TI 0 "register_operand" "=r")
5435         (minus:TI (match_operand:TI 1 "register_operand" "r")
5436                   (match_operand:TI 2 "register_operand" "r")))
5437    (trap_if (ne (minus:OI (sign_extend:OI (match_dup 1))
5438                           (sign_extend:OI (match_dup 2)))
5439                 (sign_extend:OI (minus:TI (match_dup 1)
5440                                           (match_dup 2))))
5441             (const_int 0))]
5442   "TARGET_64BIT"
5443   "*
5445   operands[3] = gen_lowpart (DImode, operands[0]);
5446   operands[4] = gen_lowpart (DImode, operands[1]);
5447   operands[5] = gen_lowpart (DImode, operands[2]);
5448   operands[0] = gen_highpart (DImode, operands[0]);
5449   operands[1] = gen_highpart (DImode, operands[1]);
5450   operands[2] = gen_highpart (DImode, operands[2]);
5451   return \"sub %4,%5,%3\;sub,db,tsv %1,%2,%0\";
5453   [(set_attr "type" "multi")
5454    (set_attr "length" "8")])
5456 ;; Trap instructions.
5458 (define_insn "trap"
5459   [(trap_if (const_int 1) (const_int 0))]
5460   ""
5461   "{addit|addi,tc},<> 1,%%r0,%%r0"
5462   [(set_attr "type" "trap")
5463    (set_attr "length" "4")])
5465 ;; Clobbering a "register_operand" instead of a match_scratch
5466 ;; in operand3 of millicode calls avoids spilling %r1 and
5467 ;; produces better code.
5469 ;; The mulsi3 insns set up registers for the millicode call.
5470 (define_expand "mulsi3"
5471   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5472    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5473    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5474               (clobber (match_dup 3))
5475               (clobber (reg:SI 26))
5476               (clobber (reg:SI 25))
5477               (clobber (match_dup 4))])
5478    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5479   ""
5480   "
5482   operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5483   if (TARGET_PA_11 && !TARGET_SOFT_FLOAT && !TARGET_SOFT_MULT)
5484     {
5485       rtx scratch = gen_reg_rtx (DImode);
5486       operands[1] = force_reg (SImode, operands[1]);
5487       operands[2] = force_reg (SImode, operands[2]);
5488       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5489       emit_insn (gen_movsi (operands[0],
5490                             gen_rtx_SUBREG (SImode, scratch,
5491                                             GET_MODE_SIZE (SImode))));
5492       DONE;
5493     }
5494   operands[3] = gen_reg_rtx (SImode);
5497 (define_insn "umulsidi3"
5498   [(set (match_operand:DI 0 "register_operand" "=f")
5499         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5500                  (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5501   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT"
5502   "xmpyu %1,%2,%0"
5503   [(set_attr "type" "fpmuldbl")
5504    (set_attr "length" "4")])
5506 (define_insn ""
5507   [(set (match_operand:DI 0 "register_operand" "=f")
5508         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5509                  (match_operand:DI 2 "uint32_operand" "f")))]
5510   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && !TARGET_64BIT"
5511   "xmpyu %1,%R2,%0"
5512   [(set_attr "type" "fpmuldbl")
5513    (set_attr "length" "4")])
5515 (define_insn ""
5516   [(set (match_operand:DI 0 "register_operand" "=f")
5517         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5518                  (match_operand:DI 2 "uint32_operand" "f")))]
5519   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && TARGET_64BIT"
5520   "xmpyu %1,%2R,%0"
5521   [(set_attr "type" "fpmuldbl")
5522    (set_attr "length" "4")])
5524 (define_insn ""
5525   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5526    (clobber (match_operand:SI 0 "register_operand" "=a"))
5527    (clobber (reg:SI 26))
5528    (clobber (reg:SI 25))
5529    (clobber (reg:SI 31))]
5530   "!TARGET_64BIT"
5531   "* return pa_output_mul_insn (0, insn);"
5532   [(set_attr "type" "milli")
5533    (set (attr "length")
5534         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5535               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5537 (define_insn ""
5538   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5539    (clobber (match_operand:SI 0 "register_operand" "=a"))
5540    (clobber (reg:SI 26))
5541    (clobber (reg:SI 25))
5542    (clobber (reg:SI 2))]
5543   "TARGET_64BIT"
5544   "* return pa_output_mul_insn (0, insn);"
5545   [(set_attr "type" "milli")
5546    (set (attr "length")
5547         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5548               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5550 (define_expand "muldi3"
5551   [(set (match_operand:DI 0 "register_operand" "")
5552         (mult:DI (match_operand:DI 1 "register_operand" "")
5553                  (match_operand:DI 2 "register_operand" "")))]
5554   "! optimize_size
5555    && TARGET_PA_11
5556    && ! TARGET_SOFT_FLOAT
5557    && ! TARGET_SOFT_MULT"
5558   "
5560   rtx low_product = gen_reg_rtx (DImode);
5561   rtx cross_product1 = gen_reg_rtx (DImode);
5562   rtx cross_product2 = gen_reg_rtx (DImode);
5563   rtx op1l, op1r, op2l, op2r;
5565   if (TARGET_64BIT)
5566     {
5567       rtx op1shifted = gen_reg_rtx (DImode);
5568       rtx op2shifted = gen_reg_rtx (DImode);
5570       emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5571                                                     GEN_INT (32)));
5572       emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5573                                                     GEN_INT (32)));
5574       op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5575       op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5576       op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5577       op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5578     }
5579   else
5580     {
5581       op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5582       op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5583       op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5584       op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5585     }
5587   /* Emit multiplies for the cross products.  */
5588   emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5589   emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5591   /* Emit a multiply for the low sub-word.  */
5592   emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5594   if (TARGET_64BIT)
5595     {
5596       rtx cross_scratch = gen_reg_rtx (DImode);
5597       rtx cross_product = gen_reg_rtx (DImode);
5599       /* Sum the cross products and shift them into proper position.  */
5600       emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5601       emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5603       /* Add the cross product to the low product and store the result
5604          into the output operand .  */
5605       emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5606     }
5607   else
5608     {
5609       rtx cross_scratch = gen_reg_rtx (SImode);
5611       /* Sum cross products.  */
5612       emit_move_insn (cross_scratch,
5613                       gen_rtx_PLUS (SImode,
5614                                     gen_lowpart (SImode, cross_product1),
5615                                     gen_lowpart (SImode, cross_product2)));
5616       emit_move_insn (gen_lowpart (SImode, operands[0]),
5617                       gen_lowpart (SImode, low_product));
5618       emit_move_insn (gen_highpart (SImode, operands[0]),
5619                       gen_rtx_PLUS (SImode,
5620                                     gen_highpart (SImode, low_product),
5621                                     cross_scratch));
5622     }
5623   DONE;
5626 ;;; Division and mod.
5627 (define_expand "divsi3"
5628   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5629    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5630    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5631               (clobber (match_dup 3))
5632               (clobber (match_dup 4))
5633               (clobber (reg:SI 26))
5634               (clobber (reg:SI 25))
5635               (clobber (match_dup 5))])
5636    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5637   ""
5638   "
5640   operands[3] = gen_reg_rtx (SImode);
5641   if (TARGET_64BIT)
5642     {
5643       operands[5] = gen_rtx_REG (SImode, 2);
5644       operands[4] = operands[5];
5645     }
5646   else
5647     {
5648       operands[5] = gen_rtx_REG (SImode, 31);
5649       operands[4] = gen_reg_rtx (SImode);
5650     }
5651   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5652     DONE;
5655 (define_insn ""
5656   [(set (reg:SI 29)
5657         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5658    (clobber (match_operand:SI 1 "register_operand" "=a"))
5659    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5660    (clobber (reg:SI 26))
5661    (clobber (reg:SI 25))
5662    (clobber (reg:SI 31))]
5663   "!TARGET_64BIT"
5664   "*
5665    return pa_output_div_insn (operands, 0, insn);"
5666   [(set_attr "type" "milli")
5667    (set (attr "length")
5668         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5669               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5671 (define_insn ""
5672   [(set (reg:SI 29)
5673         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5674    (clobber (match_operand:SI 1 "register_operand" "=a"))
5675    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5676    (clobber (reg:SI 26))
5677    (clobber (reg:SI 25))
5678    (clobber (reg:SI 2))]
5679   "TARGET_64BIT"
5680   "*
5681    return pa_output_div_insn (operands, 0, insn);"
5682   [(set_attr "type" "milli")
5683    (set (attr "length")
5684         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5685               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5687 (define_expand "udivsi3"
5688   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5689    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5690    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5691               (clobber (match_dup 3))
5692               (clobber (match_dup 4))
5693               (clobber (reg:SI 26))
5694               (clobber (reg:SI 25))
5695               (clobber (match_dup 5))])
5696    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5697   ""
5698   "
5700   operands[3] = gen_reg_rtx (SImode);
5702   if (TARGET_64BIT)
5703     {
5704       operands[5] = gen_rtx_REG (SImode, 2);
5705       operands[4] = operands[5];
5706     }
5707   else
5708     {
5709       operands[5] = gen_rtx_REG (SImode, 31);
5710       operands[4] = gen_reg_rtx (SImode);
5711     }
5712   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5713     DONE;
5716 (define_insn ""
5717   [(set (reg:SI 29)
5718         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5719    (clobber (match_operand:SI 1 "register_operand" "=a"))
5720    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5721    (clobber (reg:SI 26))
5722    (clobber (reg:SI 25))
5723    (clobber (reg:SI 31))]
5724   "!TARGET_64BIT"
5725   "*
5726    return pa_output_div_insn (operands, 1, insn);"
5727   [(set_attr "type" "milli")
5728    (set (attr "length")
5729         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5730               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5732 (define_insn ""
5733   [(set (reg:SI 29)
5734         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5735    (clobber (match_operand:SI 1 "register_operand" "=a"))
5736    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5737    (clobber (reg:SI 26))
5738    (clobber (reg:SI 25))
5739    (clobber (reg:SI 2))]
5740   "TARGET_64BIT"
5741   "*
5742    return pa_output_div_insn (operands, 1, insn);"
5743   [(set_attr "type" "milli")
5744    (set (attr "length")
5745         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5746               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5748 (define_expand "modsi3"
5749   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5750    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5751    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5752               (clobber (match_dup 3))
5753               (clobber (match_dup 4))
5754               (clobber (reg:SI 26))
5755               (clobber (reg:SI 25))
5756               (clobber (match_dup 5))])
5757    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5758   ""
5759   "
5761   if (TARGET_64BIT)
5762     {
5763       operands[5] = gen_rtx_REG (SImode, 2);
5764       operands[4] = operands[5];
5765     }
5766   else
5767     {
5768       operands[5] = gen_rtx_REG (SImode, 31);
5769       operands[4] = gen_reg_rtx (SImode);
5770     }
5771   operands[3] = gen_reg_rtx (SImode);
5774 (define_insn ""
5775   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5776    (clobber (match_operand:SI 0 "register_operand" "=a"))
5777    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5778    (clobber (reg:SI 26))
5779    (clobber (reg:SI 25))
5780    (clobber (reg:SI 31))]
5781   "!TARGET_64BIT"
5782   "*
5783   return pa_output_mod_insn (0, insn);"
5784   [(set_attr "type" "milli")
5785    (set (attr "length")
5786         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5787               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5789 (define_insn ""
5790   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5791    (clobber (match_operand:SI 0 "register_operand" "=a"))
5792    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5793    (clobber (reg:SI 26))
5794    (clobber (reg:SI 25))
5795    (clobber (reg:SI 2))]
5796   "TARGET_64BIT"
5797   "*
5798   return pa_output_mod_insn (0, insn);"
5799   [(set_attr "type" "milli")
5800    (set (attr "length")
5801         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5802               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5804 (define_expand "umodsi3"
5805   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5806    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5807    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5808               (clobber (match_dup 3))
5809               (clobber (match_dup 4))
5810               (clobber (reg:SI 26))
5811               (clobber (reg:SI 25))
5812               (clobber (match_dup 5))])
5813    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5814   ""
5815   "
5817   if (TARGET_64BIT)
5818     {
5819       operands[5] = gen_rtx_REG (SImode, 2);
5820       operands[4] = operands[5];
5821     }
5822   else
5823     {
5824       operands[5] = gen_rtx_REG (SImode, 31);
5825       operands[4] = gen_reg_rtx (SImode);
5826     }
5827   operands[3] = gen_reg_rtx (SImode);
5830 (define_insn ""
5831   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5832    (clobber (match_operand:SI 0 "register_operand" "=a"))
5833    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5834    (clobber (reg:SI 26))
5835    (clobber (reg:SI 25))
5836    (clobber (reg:SI 31))]
5837   "!TARGET_64BIT"
5838   "*
5839   return pa_output_mod_insn (1, insn);"
5840   [(set_attr "type" "milli")
5841    (set (attr "length")
5842         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5843               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5845 (define_insn ""
5846   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5847    (clobber (match_operand:SI 0 "register_operand" "=a"))
5848    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5849    (clobber (reg:SI 26))
5850    (clobber (reg:SI 25))
5851    (clobber (reg:SI 2))]
5852   "TARGET_64BIT"
5853   "*
5854   return pa_output_mod_insn (1, insn);"
5855   [(set_attr "type" "milli")
5856    (set (attr "length")
5857         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5858               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5860 ;;- and instructions
5861 ;; We define DImode `and` so with DImode `not` we can get
5862 ;; DImode `andn`.  Other combinations are possible.
5864 (define_expand "anddi3"
5865   [(set (match_operand:DI 0 "register_operand" "")
5866         (and:DI (match_operand:DI 1 "register_operand" "")
5867                 (match_operand:DI 2 "and_operand" "")))]
5868   "TARGET_64BIT"
5869   "")
5871 (define_insn ""
5872   [(set (match_operand:DI 0 "register_operand" "=r,r")
5873         (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5874                 (match_operand:DI 2 "and_operand" "rO,P")))]
5875   "TARGET_64BIT"
5876   "* return pa_output_64bit_and (operands); "
5877   [(set_attr "type" "binary")
5878    (set_attr "length" "4")])
5880 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5881 ; constant with ldil;ldo.
5882 (define_insn "andsi3"
5883   [(set (match_operand:SI 0 "register_operand" "=r,r")
5884         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5885                 (match_operand:SI 2 "and_operand" "rO,P")))]
5886   ""
5887   "* return pa_output_and (operands); "
5888   [(set_attr "type" "binary,shift")
5889    (set_attr "length" "4,4")])
5891 (define_insn ""
5892   [(set (match_operand:DI 0 "register_operand" "=r")
5893         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5894                 (match_operand:DI 2 "register_operand" "r")))]
5895   "TARGET_64BIT"
5896   "andcm %2,%1,%0"
5897   [(set_attr "type" "binary")
5898    (set_attr "length" "4")])
5900 (define_insn ""
5901   [(set (match_operand:SI 0 "register_operand" "=r")
5902         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5903                 (match_operand:SI 2 "register_operand" "r")))]
5904   ""
5905   "andcm %2,%1,%0"
5906   [(set_attr "type" "binary")
5907   (set_attr "length" "4")])
5909 (define_expand "iordi3"
5910   [(set (match_operand:DI 0 "register_operand" "")
5911         (ior:DI (match_operand:DI 1 "register_operand" "")
5912                 (match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5913   "TARGET_64BIT"
5914   "")
5916 (define_insn ""
5917   [(set (match_operand:DI 0 "register_operand" "=r,r")
5918         (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5919                 (match_operand:DI 2 "cint_ior_operand" "M,i")))]
5920   "TARGET_64BIT"
5921   "* return pa_output_64bit_ior (operands); "
5922   [(set_attr "type" "binary,shift")
5923    (set_attr "length" "4,4")])
5925 (define_insn ""
5926   [(set (match_operand:DI 0 "register_operand" "=r")
5927         (ior:DI (match_operand:DI 1 "register_operand" "%r")
5928                 (match_operand:DI 2 "register_operand" "r")))]
5929   "TARGET_64BIT"
5930   "or %1,%2,%0"
5931   [(set_attr "type" "binary")
5932    (set_attr "length" "4")])
5934 ;; Need a define_expand because we've run out of CONST_OK... characters.
5935 (define_expand "iorsi3"
5936   [(set (match_operand:SI 0 "register_operand" "")
5937         (ior:SI (match_operand:SI 1 "register_operand" "")
5938                 (match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5939   ""
5940   "")
5942 (define_insn ""
5943   [(set (match_operand:SI 0 "register_operand" "=r,r")
5944         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5945                 (match_operand:SI 2 "cint_ior_operand" "M,i")))]
5946   ""
5947   "* return pa_output_ior (operands); "
5948   [(set_attr "type" "binary,shift")
5949    (set_attr "length" "4,4")])
5951 (define_insn ""
5952   [(set (match_operand:SI 0 "register_operand" "=r")
5953         (ior:SI (match_operand:SI 1 "register_operand" "%r")
5954                 (match_operand:SI 2 "register_operand" "r")))]
5955   ""
5956   "or %1,%2,%0"
5957   [(set_attr "type" "binary")
5958    (set_attr "length" "4")])
5960 (define_expand "xordi3"
5961   [(set (match_operand:DI 0 "register_operand" "")
5962         (xor:DI (match_operand:DI 1 "register_operand" "")
5963                 (match_operand:DI 2 "register_operand" "")))]
5964   "TARGET_64BIT"
5965   "")
5967 (define_insn ""
5968   [(set (match_operand:DI 0 "register_operand" "=r")
5969         (xor:DI (match_operand:DI 1 "register_operand" "%r")
5970                 (match_operand:DI 2 "register_operand" "r")))]
5971   "TARGET_64BIT"
5972   "xor %1,%2,%0"
5973   [(set_attr "type" "binary")
5974    (set_attr "length" "4")])
5976 (define_insn "xorsi3"
5977   [(set (match_operand:SI 0 "register_operand" "=r")
5978         (xor:SI (match_operand:SI 1 "register_operand" "%r")
5979                 (match_operand:SI 2 "register_operand" "r")))]
5980   ""
5981   "xor %1,%2,%0"
5982   [(set_attr "type" "binary")
5983    (set_attr "length" "4")])
5985 (define_expand "negdi2"
5986   [(set (match_operand:DI 0 "register_operand" "")
5987         (neg:DI (match_operand:DI 1 "register_operand" "")))]
5988   ""
5989   "")
5991 (define_insn ""
5992   [(set (match_operand:DI 0 "register_operand" "=r")
5993         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5994   "!TARGET_64BIT"
5995   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5996   [(set_attr "type" "multi")
5997    (set_attr "length" "8")])
5999 (define_insn ""
6000   [(set (match_operand:DI 0 "register_operand" "=r")
6001         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6002   "TARGET_64BIT"
6003   "sub %%r0,%1,%0"
6004   [(set_attr "type" "unary")
6005    (set_attr "length" "4")])
6007 (define_insn "negti2"
6008   [(set (match_operand:TI 0 "register_operand" "=r")
6009         (neg:TI (match_operand:TI 1 "register_operand" "r")))]
6010   "TARGET_64BIT"
6011   "*
6013   operands[2] = gen_lowpart (DImode, operands[0]);
6014   operands[3] = gen_lowpart (DImode, operands[1]);
6015   operands[0] = gen_highpart (DImode, operands[0]);
6016   operands[1] = gen_highpart (DImode, operands[1]);
6017   return \"sub %%r0,%3,%2\;sub,db %%r0,%1,%0\";
6019   [(set_attr "type" "multi")
6020    (set_attr "length" "8")])
6022 (define_expand "negvdi2"
6023   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6024                    (neg:DI (match_operand:DI 1 "register_operand" "")))
6025               (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6026                                    (sign_extend:TI (neg:DI (match_dup 1))))
6027                        (const_int 0))])]
6028   ""
6029   "")
6031 (define_insn ""
6032   [(set (match_operand:DI 0 "register_operand" "=r")
6033         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6034    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6035                 (sign_extend:TI (neg:DI (match_dup 1))))
6036             (const_int 0))]
6037   "!TARGET_64BIT"
6038   "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
6039   [(set_attr "type" "multi")
6040    (set_attr "length" "8")])
6042 (define_insn ""
6043   [(set (match_operand:DI 0 "register_operand" "=r")
6044         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6045    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6046                 (sign_extend:TI (neg:DI (match_dup 1))))
6047             (const_int 0))]
6048   "TARGET_64BIT"
6049   "sub,tsv %%r0,%1,%0"
6050   [(set_attr "type" "unary")
6051    (set_attr "length" "4")])
6053 (define_insn "negvti2"
6054   [(set (match_operand:TI 0 "register_operand" "=r")
6055         (neg:TI (match_operand:TI 1 "register_operand" "r")))
6056    (trap_if (ne (neg:OI (sign_extend:OI (match_dup 1)))
6057                 (sign_extend:OI (neg:TI (match_dup 1))))
6058             (const_int 0))]
6059   "TARGET_64BIT"
6060   "*
6062   operands[2] = gen_lowpart (DImode, operands[0]);
6063   operands[3] = gen_lowpart (DImode, operands[1]);
6064   operands[0] = gen_highpart (DImode, operands[0]);
6065   operands[1] = gen_highpart (DImode, operands[1]);
6066   return \"sub %%r0,%3,%2\;sub,db,tsv %%r0,%1,%0\";
6068   [(set_attr "type" "multi")
6069    (set_attr "length" "8")])
6071 (define_insn "negsi2"
6072   [(set (match_operand:SI 0 "register_operand" "=r")
6073         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
6074   ""
6075   "sub %%r0,%1,%0"
6076   [(set_attr "type" "unary")
6077    (set_attr "length" "4")])
6079 (define_insn "negvsi2"
6080   [(set (match_operand:SI 0 "register_operand" "=r")
6081         (neg:SI (match_operand:SI 1 "register_operand" "r")))
6082    (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
6083                 (sign_extend:DI (neg:SI (match_dup 1))))
6084             (const_int 0))]
6085    ""
6086    "{subo|sub,tsv} %%r0,%1,%0"
6087   [(set_attr "type" "unary")
6088    (set_attr "length" "4")])
6090 (define_expand "one_cmpldi2"
6091   [(set (match_operand:DI 0 "register_operand" "")
6092         (not:DI (match_operand:DI 1 "register_operand" "")))]
6093   ""
6094   "
6098 (define_insn ""
6099   [(set (match_operand:DI 0 "register_operand" "=r")
6100         (not:DI (match_operand:DI 1 "register_operand" "r")))]
6101   "!TARGET_64BIT"
6102   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
6103   [(set_attr "type" "unary")
6104    (set_attr "length" "8")])
6106 (define_insn ""
6107   [(set (match_operand:DI 0 "register_operand" "=r")
6108         (not:DI (match_operand:DI 1 "register_operand" "r")))]
6109   "TARGET_64BIT"
6110   "uaddcm %%r0,%1,%0"
6111   [(set_attr "type" "unary")
6112    (set_attr "length" "4")])
6114 (define_insn "one_cmplsi2"
6115   [(set (match_operand:SI 0 "register_operand" "=r")
6116         (not:SI (match_operand:SI 1 "register_operand" "r")))]
6117   ""
6118   "uaddcm %%r0,%1,%0"
6119   [(set_attr "type" "unary")
6120    (set_attr "length" "4")])
6122 ;; Floating point arithmetic instructions.
6124 (define_insn "adddf3"
6125   [(set (match_operand:DF 0 "register_operand" "=f")
6126         (plus:DF (match_operand:DF 1 "register_operand" "f")
6127                  (match_operand:DF 2 "register_operand" "f")))]
6128   "! TARGET_SOFT_FLOAT"
6129   "fadd,dbl %1,%2,%0"
6130   [(set_attr "type" "fpalu")
6131    (set_attr "pa_combine_type" "faddsub")
6132    (set_attr "length" "4")])
6134 (define_insn "addsf3"
6135   [(set (match_operand:SF 0 "register_operand" "=f")
6136         (plus:SF (match_operand:SF 1 "register_operand" "f")
6137                  (match_operand:SF 2 "register_operand" "f")))]
6138   "! TARGET_SOFT_FLOAT"
6139   "fadd,sgl %1,%2,%0"
6140   [(set_attr "type" "fpalu")
6141    (set_attr "pa_combine_type" "faddsub")
6142    (set_attr "length" "4")])
6144 (define_insn "subdf3"
6145   [(set (match_operand:DF 0 "register_operand" "=f")
6146         (minus:DF (match_operand:DF 1 "register_operand" "f")
6147                   (match_operand:DF 2 "register_operand" "f")))]
6148   "! TARGET_SOFT_FLOAT"
6149   "fsub,dbl %1,%2,%0"
6150   [(set_attr "type" "fpalu")
6151    (set_attr "pa_combine_type" "faddsub")
6152    (set_attr "length" "4")])
6154 (define_insn "subsf3"
6155   [(set (match_operand:SF 0 "register_operand" "=f")
6156         (minus:SF (match_operand:SF 1 "register_operand" "f")
6157                   (match_operand:SF 2 "register_operand" "f")))]
6158   "! TARGET_SOFT_FLOAT"
6159   "fsub,sgl %1,%2,%0"
6160   [(set_attr "type" "fpalu")
6161    (set_attr "pa_combine_type" "faddsub")
6162    (set_attr "length" "4")])
6164 (define_insn "muldf3"
6165   [(set (match_operand:DF 0 "register_operand" "=f")
6166         (mult:DF (match_operand:DF 1 "register_operand" "f")
6167                  (match_operand:DF 2 "register_operand" "f")))]
6168   "! TARGET_SOFT_FLOAT"
6169   "fmpy,dbl %1,%2,%0"
6170   [(set_attr "type" "fpmuldbl")
6171    (set_attr "pa_combine_type" "fmpy")
6172    (set_attr "length" "4")])
6174 (define_insn "mulsf3"
6175   [(set (match_operand:SF 0 "register_operand" "=f")
6176         (mult:SF (match_operand:SF 1 "register_operand" "f")
6177                  (match_operand:SF 2 "register_operand" "f")))]
6178   "! TARGET_SOFT_FLOAT"
6179   "fmpy,sgl %1,%2,%0"
6180   [(set_attr "type" "fpmulsgl")
6181    (set_attr "pa_combine_type" "fmpy")
6182    (set_attr "length" "4")])
6184 (define_insn "divdf3"
6185   [(set (match_operand:DF 0 "register_operand" "=f")
6186         (div:DF (match_operand:DF 1 "register_operand" "f")
6187                 (match_operand:DF 2 "register_operand" "f")))]
6188   "! TARGET_SOFT_FLOAT"
6189   "fdiv,dbl %1,%2,%0"
6190   [(set_attr "type" "fpdivdbl")
6191    (set_attr "length" "4")])
6193 (define_insn "divsf3"
6194   [(set (match_operand:SF 0 "register_operand" "=f")
6195         (div:SF (match_operand:SF 1 "register_operand" "f")
6196                 (match_operand:SF 2 "register_operand" "f")))]
6197   "! TARGET_SOFT_FLOAT"
6198   "fdiv,sgl %1,%2,%0"
6199   [(set_attr "type" "fpdivsgl")
6200    (set_attr "length" "4")])
6202 ;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6203 ;; negation can be done by subtracting from plus zero.  However, this
6204 ;; violates the IEEE standard when negating plus and minus zero.
6205 ;; The slow path toggles the sign bit in the general registers.
6206 (define_expand "negdf2"
6207   [(set (match_operand:DF 0 "register_operand" "")
6208         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6209   "!TARGET_SOFT_FLOAT"
6211   if (TARGET_PA_20 || !flag_signed_zeros)
6212     emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6213   else
6214     emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6215   DONE;
6218 (define_insn "negdf2_slow"
6219   [(set (match_operand:DF 0 "register_operand" "=r")
6220         (neg:DF (match_operand:DF 1 "register_operand" "r")))]
6221   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6222   "*
6224   if (rtx_equal_p (operands[0], operands[1]))
6225     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6226   else
6227     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6229   [(set_attr "type" "multi")
6230    (set (attr "length")
6231         (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6232             (const_int 12)
6233             (const_int 16)))])
6235 (define_insn "negdf2_fast"
6236   [(set (match_operand:DF 0 "register_operand" "=f")
6237         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
6238   "!TARGET_SOFT_FLOAT"
6239   "*
6241   if (TARGET_PA_20)
6242     return \"fneg,dbl %1,%0\";
6243   else
6244     return \"fsub,dbl %%fr0,%1,%0\";
6246   [(set_attr "type" "fpalu")
6247    (set_attr "length" "4")])
6249 (define_expand "negsf2"
6250   [(set (match_operand:SF 0 "register_operand" "")
6251         (neg:SF (match_operand:SF 1 "register_operand" "")))]
6252   "!TARGET_SOFT_FLOAT"
6254   if (TARGET_PA_20 || !flag_signed_zeros)
6255     emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6256   else
6257     emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6258   DONE;
6261 (define_insn "negsf2_slow"
6262   [(set (match_operand:SF 0 "register_operand" "=r")
6263         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
6264   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6265   "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6266   [(set_attr "type" "multi")
6267    (set_attr "length" "12")])
6269 (define_insn "negsf2_fast"
6270   [(set (match_operand:SF 0 "register_operand" "=f")
6271         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6272   "!TARGET_SOFT_FLOAT"
6273   "*
6275   if (TARGET_PA_20)
6276     return \"fneg,sgl %1,%0\";
6277   else
6278     return \"fsub,sgl %%fr0,%1,%0\";
6280   [(set_attr "type" "fpalu")
6281    (set_attr "length" "4")])
6283 (define_insn "absdf2"
6284   [(set (match_operand:DF 0 "register_operand" "=f")
6285         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
6286   "! TARGET_SOFT_FLOAT"
6287   "fabs,dbl %1,%0"
6288   [(set_attr "type" "fpalu")
6289    (set_attr "length" "4")])
6291 (define_insn "abssf2"
6292   [(set (match_operand:SF 0 "register_operand" "=f")
6293         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6294   "! TARGET_SOFT_FLOAT"
6295   "fabs,sgl %1,%0"
6296   [(set_attr "type" "fpalu")
6297    (set_attr "length" "4")])
6299 (define_insn "sqrtdf2"
6300   [(set (match_operand:DF 0 "register_operand" "=f")
6301         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6302   "! TARGET_SOFT_FLOAT"
6303   "fsqrt,dbl %1,%0"
6304   [(set_attr "type" "fpsqrtdbl")
6305    (set_attr "length" "4")])
6307 (define_insn "sqrtsf2"
6308   [(set (match_operand:SF 0 "register_operand" "=f")
6309         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6310   "! TARGET_SOFT_FLOAT"
6311   "fsqrt,sgl %1,%0"
6312   [(set_attr "type" "fpsqrtsgl")
6313    (set_attr "length" "4")])
6315 ;; PA 2.0 floating point instructions
6317 ; fmpyfadd patterns
6318 (define_insn "fmadf4"
6319   [(set (match_operand:DF 0 "register_operand" "=f")
6320         (fma:DF (match_operand:DF 1 "register_operand" "f")
6321                 (match_operand:DF 2 "register_operand" "f")
6322                 (match_operand:DF 3 "register_operand" "f")))]
6323   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6324   "fmpyfadd,dbl %1,%2,%3,%0"
6325   [(set_attr "type" "fpmuldbl")
6326    (set_attr "length" "4")])
6328 (define_insn "fmasf4"
6329   [(set (match_operand:SF 0 "register_operand" "=f")
6330         (fma:SF (match_operand:SF 1 "register_operand" "f")
6331                 (match_operand:SF 2 "register_operand" "f")
6332                 (match_operand:SF 3 "register_operand" "f")))]
6333   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6334   "fmpyfadd,sgl %1,%2,%3,%0"
6335   [(set_attr "type" "fpmulsgl")
6336    (set_attr "length" "4")])
6338 ; fmpynfadd patterns
6339 (define_insn "fnmadf4"
6340   [(set (match_operand:DF 0 "register_operand" "=f")
6341         (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6342                 (match_operand:DF 2 "register_operand" "f")
6343                 (match_operand:DF 3 "register_operand" "f")))]
6344   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6345   "fmpynfadd,dbl %1,%2,%3,%0"
6346   [(set_attr "type" "fpmuldbl")
6347    (set_attr "length" "4")])
6349 (define_insn "fnmasf4"
6350   [(set (match_operand:SF 0 "register_operand" "=f")
6351         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6352                 (match_operand:SF 2 "register_operand" "f")
6353                 (match_operand:SF 3 "register_operand" "f")))]
6354   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6355   "fmpynfadd,sgl %1,%2,%3,%0"
6356   [(set_attr "type" "fpmulsgl")
6357    (set_attr "length" "4")])
6359 ; fnegabs patterns
6360 (define_insn ""
6361   [(set (match_operand:DF 0 "register_operand" "=f")
6362         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6363   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6364   "fnegabs,dbl %1,%0"
6365   [(set_attr "type" "fpalu")
6366    (set_attr "length" "4")])
6368 (define_insn ""
6369   [(set (match_operand:SF 0 "register_operand" "=f")
6370         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6371   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6372   "fnegabs,sgl %1,%0"
6373   [(set_attr "type" "fpalu")
6374    (set_attr "length" "4")])
6376 (define_insn ""
6377   [(set (match_operand:DF 0 "register_operand" "=f")
6378         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6379    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6380   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6381     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6382   "#"
6383   [(set_attr "type" "fpalu")
6384    (set_attr "length" "8")])
6386 (define_split
6387   [(set (match_operand:DF 0 "register_operand" "")
6388         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6389    (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6390   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6391   [(set (match_dup 2) (abs:DF (match_dup 1)))
6392    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6393   "")
6395 (define_insn ""
6396   [(set (match_operand:SF 0 "register_operand" "=f")
6397         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6398    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6399   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6400     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6401   "#"
6402   [(set_attr "type" "fpalu")
6403    (set_attr "length" "8")])
6405 (define_split
6406   [(set (match_operand:SF 0 "register_operand" "")
6407         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6408    (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6409   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6410   [(set (match_dup 2) (abs:SF (match_dup 1)))
6411    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6412   "")
6414 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6415 ;; instruction if we can ignore the sign of zero.
6416 (define_insn ""
6417   [(set (match_operand:DF 0 "register_operand" "=f")
6418         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6419                          (match_operand:DF 2 "register_operand" "f"))))]
6420   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6421   "fmpynfadd,dbl %1,%2,%%fr0,%0"
6422   [(set_attr "type" "fpmuldbl")
6423    (set_attr "length" "4")])
6425 (define_insn ""
6426   [(set (match_operand:SF 0 "register_operand" "=f")
6427         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6428                          (match_operand:SF 2 "register_operand" "f"))))]
6429   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6430   "fmpynfadd,sgl %1,%2,%%fr0,%0"
6431   [(set_attr "type" "fpmuldbl")
6432    (set_attr "length" "4")])
6434 (define_insn ""
6435   [(set (match_operand:DF 0 "register_operand" "=f")
6436         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6437                          (match_operand:DF 2 "register_operand" "f"))))
6438    (set (match_operand:DF 3 "register_operand" "=&f")
6439         (mult:DF (match_dup 1) (match_dup 2)))]
6440   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6441     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6442           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6443   "#"
6444   [(set_attr "type" "fpmuldbl")
6445    (set_attr "length" "8")])
6447 (define_split
6448   [(set (match_operand:DF 0 "register_operand" "")
6449         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6450                          (match_operand:DF 2 "register_operand" ""))))
6451    (set (match_operand:DF 3 "register_operand" "")
6452         (mult:DF (match_dup 1) (match_dup 2)))]
6453   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6454   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6455    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6456   "")
6458 (define_insn ""
6459   [(set (match_operand:SF 0 "register_operand" "=f")
6460         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6461                          (match_operand:SF 2 "register_operand" "f"))))
6462    (set (match_operand:SF 3 "register_operand" "=&f")
6463         (mult:SF (match_dup 1) (match_dup 2)))]
6464   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6465     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6466           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6467   "#"
6468   [(set_attr "type" "fpmuldbl")
6469    (set_attr "length" "8")])
6471 (define_split
6472   [(set (match_operand:SF 0 "register_operand" "")
6473         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6474                          (match_operand:SF 2 "register_operand" ""))))
6475    (set (match_operand:SF 3 "register_operand" "")
6476         (mult:SF (match_dup 1) (match_dup 2)))]
6477   "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6478   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6479    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6480   "")
6482 ;;- Shift instructions
6484 ;; Optimized special case of shifting.
6486 (define_insn ""
6487   [(set (match_operand:SI 0 "register_operand" "=r")
6488         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6489                      (const_int 24)))]
6490   ""
6491   "ldb%M1 %1,%0"
6492   [(set_attr "type" "load")
6493    (set_attr "length" "4")])
6495 (define_insn ""
6496   [(set (match_operand:SI 0 "register_operand" "=r")
6497         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6498                      (const_int 16)))]
6499   ""
6500   "ldh%M1 %1,%0"
6501   [(set_attr "type" "load")
6502    (set_attr "length" "4")])
6504 (define_insn ""
6505   [(set (match_operand:SI 0 "register_operand" "=r")
6506         (plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6507                             (match_operand:SI 3 "shadd_operand" ""))
6508                  (match_operand:SI 1 "register_operand" "r")))]
6509   ""
6510   "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6511   [(set_attr "type" "binary")
6512    (set_attr "length" "4")])
6514 (define_insn ""
6515   [(set (match_operand:SI 0 "register_operand" "=r")
6516         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6517                           (match_operand:SI 3 "mem_shadd_operand" ""))
6518                  (match_operand:SI 1 "register_operand" "r")))]
6519   ""
6520   "*
6522   int shift_val = exact_log2 (INTVAL (operands[3]));
6523   operands[3] = GEN_INT (shift_val);
6524   return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6526   [(set_attr "type" "binary")
6527    (set_attr "length" "4")])
6529 (define_insn ""
6530   [(set (match_operand:DI 0 "register_operand" "=r")
6531         (plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6532                             (match_operand:DI 3 "shadd_operand" ""))
6533                  (match_operand:DI 1 "register_operand" "r")))]
6534   "TARGET_64BIT"
6535   "shladd,l %2,%o3,%1,%0"
6536   [(set_attr "type" "binary")
6537    (set_attr "length" "4")])
6539 (define_insn ""
6540   [(set (match_operand:DI 0 "register_operand" "=r")
6541         (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6542                           (match_operand:DI 3 "mem_shadd_operand" ""))
6543                  (match_operand:DI 1 "register_operand" "r")))]
6544   "TARGET_64BIT"
6545   "*
6547   int shift_val = exact_log2 (INTVAL (operands[3]));
6548   operands[3] = GEN_INT (shift_val);
6549   return \"shladd,l %2,%o3,%1,%0\";
6551   [(set_attr "type" "binary")
6552    (set_attr "length" "4")])
6554 (define_expand "ashlsi3"
6555   [(set (match_operand:SI 0 "register_operand" "")
6556         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6557                    (match_operand:SI 2 "arith32_operand" "")))]
6558   ""
6559   "
6561   if (GET_CODE (operands[2]) != CONST_INT)
6562     {
6563       rtx temp = gen_reg_rtx (SImode);
6564       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6565       if (GET_CODE (operands[1]) == CONST_INT)
6566         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6567       else
6568         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6569       DONE;
6570     }
6571   /* Make sure both inputs are not constants,
6572      there are no patterns for that.  */
6573   operands[1] = force_reg (SImode, operands[1]);
6576 (define_insn ""
6577   [(set (match_operand:SI 0 "register_operand" "=r")
6578         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6579                    (match_operand:SI 2 "const_int_operand" "n")))]
6580   ""
6581   "{zdep|depw,z} %1,%P2,%L2,%0"
6582   [(set_attr "type" "shift")
6583    (set_attr "length" "4")])
6585 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6586 ; Doing it like this makes slightly better code since reload can
6587 ; replace a register with a known value in range -16..15 with a
6588 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6589 ; but since we have no more CONST_OK... characters, that is not
6590 ; possible.
6591 (define_insn "zvdep32"
6592   [(set (match_operand:SI 0 "register_operand" "=r,r")
6593         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6594                    (minus:SI (const_int 31)
6595                              (match_operand:SI 2 "register_operand" "q,q"))))]
6596   ""
6597   "@
6598    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6599    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6600   [(set_attr "type" "shift,shift")
6601    (set_attr "length" "4,4")])
6603 (define_insn "zvdep_imm32"
6604   [(set (match_operand:SI 0 "register_operand" "=r")
6605         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6606                    (minus:SI (const_int 31)
6607                              (match_operand:SI 2 "register_operand" "q"))))]
6608   ""
6609   "*
6611   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6612   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6613   operands[1] = GEN_INT ((x & 0xf) - 0x10);
6614   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6616   [(set_attr "type" "shift")
6617    (set_attr "length" "4")])
6619 (define_insn "vdepi_ior"
6620   [(set (match_operand:SI 0 "register_operand" "=r")
6621         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6622                            (minus:SI (const_int 31)
6623                                      (match_operand:SI 2 "register_operand" "q")))
6624                 (match_operand:SI 3 "register_operand" "0")))]
6625   ; accept ...0001...1, can this be generalized?
6626   "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6627   "*
6629   HOST_WIDE_INT x = INTVAL (operands[1]);
6630   operands[2] = GEN_INT (exact_log2 (x + 1));
6631   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6633   [(set_attr "type" "shift")
6634    (set_attr "length" "4")])
6636 (define_insn "vdepi_and"
6637   [(set (match_operand:SI 0 "register_operand" "=r")
6638         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6639                            (minus:SI (const_int 31)
6640                                      (match_operand:SI 2 "register_operand" "q")))
6641                 (match_operand:SI 3 "register_operand" "0")))]
6642   ; this can be generalized...!
6643   "INTVAL (operands[1]) == -2"
6644   "*
6646   HOST_WIDE_INT x = INTVAL (operands[1]);
6647   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6648   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6650   [(set_attr "type" "shift")
6651    (set_attr "length" "4")])
6653 (define_expand "ashldi3"
6654   [(set (match_operand:DI 0 "register_operand" "")
6655         (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6656                    (match_operand:DI 2 "arith32_operand" "")))]
6657   ""
6658   "
6660   if (!TARGET_64BIT)
6661     {
6662       if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6663         {
6664           unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6665           if (shift >= 1 && shift <= 31)
6666             {
6667               rtx dst = operands[0];
6668               rtx src = force_reg (DImode, operands[1]);
6669               emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6670                                            gen_lowpart (SImode, src),
6671                                            GEN_INT (32-shift),
6672                                            gen_highpart (SImode, src),
6673                                            GEN_INT (shift)));
6674               emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6675                                       gen_lowpart (SImode, src),
6676                                       GEN_INT (shift)));
6677               DONE;
6678             }
6679         }
6680       /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6681       FAIL;
6682     }
6683   if (GET_CODE (operands[2]) != CONST_INT)
6684     {
6685       rtx temp = gen_reg_rtx (DImode);
6686       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6687       if (GET_CODE (operands[1]) == CONST_INT)
6688         emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6689       else
6690         emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6691       DONE;
6692     }
6693   /* Make sure both inputs are not constants,
6694      there are no patterns for that.  */
6695   operands[1] = force_reg (DImode, operands[1]);
6698 (define_expand "ashlti3"
6699   [(set (match_operand:TI 0 "register_operand" "")
6700         (ashift:TI (match_operand:TI 1 "lhs_lshift_operand" "")
6701                    (match_operand:TI 2 "arith32_operand" "")))]
6702   "TARGET_64BIT"
6704   if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6705     {
6706       unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6707       rtx dst = operands[0];
6708       rtx src = force_reg (TImode, operands[1]);
6709       if (shift >= 1 && shift <= 63)
6710         {
6711           emit_insn (gen_shrpd_internal (gen_highpart (DImode, dst),
6712                                          gen_lowpart (DImode, src),
6713                                          GEN_INT (64-shift),
6714                                          gen_highpart (DImode, src),
6715                                          GEN_INT (shift)));
6716           emit_insn (gen_ashldi3 (gen_lowpart (DImode, dst),
6717                                   gen_lowpart (DImode, src),
6718                                   GEN_INT (shift)));
6719           DONE;
6720         }
6721       else if (shift >= 64 && shift <= 127)
6722         {
6723           emit_insn (gen_ashldi3 (gen_highpart (DImode, dst),
6724                                   gen_lowpart (DImode, src),
6725                                   GEN_INT (shift - 64)));
6726           emit_move_insn (gen_lowpart (DImode, dst), GEN_INT (0));
6727           DONE;
6728         }
6729     }
6730   /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6731   FAIL;
6734 (define_insn ""
6735   [(set (match_operand:DI 0 "register_operand" "=r")
6736         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6737                    (match_operand:DI 2 "const_int_operand" "n")))]
6738   "TARGET_64BIT"
6739   "depd,z %1,%p2,%Q2,%0"
6740   [(set_attr "type" "shift")
6741    (set_attr "length" "4")])
6743 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6744 ; Doing it like this makes slightly better code since reload can
6745 ; replace a register with a known value in range -16..15 with a
6746 ; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6747 ; but since we have no more CONST_OK... characters, that is not
6748 ; possible.
6749 (define_insn "zvdep64"
6750   [(set (match_operand:DI 0 "register_operand" "=r,r")
6751         (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6752                    (minus:DI (const_int 63)
6753                              (match_operand:DI 2 "register_operand" "q,q"))))]
6754   "TARGET_64BIT"
6755   "@
6756    depd,z %1,%%sar,64,%0
6757    depdi,z %1,%%sar,64,%0"
6758   [(set_attr "type" "shift,shift")
6759    (set_attr "length" "4,4")])
6761 (define_insn "zvdep_imm64"
6762   [(set (match_operand:DI 0 "register_operand" "=r")
6763         (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6764                    (minus:DI (const_int 63)
6765                              (match_operand:DI 2 "register_operand" "q"))))]
6766   "TARGET_64BIT"
6767   "*
6769   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6770   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6771   operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6772   return \"depdi,z %1,%%sar,%2,%0\";
6774   [(set_attr "type" "shift")
6775    (set_attr "length" "4")])
6777 (define_insn ""
6778   [(set (match_operand:DI 0 "register_operand" "=r")
6779         (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6780                            (minus:DI (const_int 63)
6781                                      (match_operand:DI 2 "register_operand" "q")))
6782                 (match_operand:DI 3 "register_operand" "0")))]
6783   ; accept ...0001...1, can this be generalized?
6784   "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6785   "*
6787   HOST_WIDE_INT x = INTVAL (operands[1]);
6788   operands[2] = GEN_INT (exact_log2 (x + 1));
6789   return \"depdi -1,%%sar,%2,%0\";
6791   [(set_attr "type" "shift")
6792    (set_attr "length" "4")])
6794 (define_insn ""
6795   [(set (match_operand:DI 0 "register_operand" "=r")
6796         (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6797                            (minus:DI (const_int 63)
6798                                      (match_operand:DI 2 "register_operand" "q")))
6799                 (match_operand:DI 3 "register_operand" "0")))]
6800   ; this can be generalized...!
6801   "TARGET_64BIT && INTVAL (operands[1]) == -2"
6802   "*
6804   HOST_WIDE_INT x = INTVAL (operands[1]);
6805   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6806   return \"depdi 0,%%sar,%2,%0\";
6808   [(set_attr "type" "shift")
6809    (set_attr "length" "4")])
6811 (define_expand "ashrsi3"
6812   [(set (match_operand:SI 0 "register_operand" "")
6813         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6814                      (match_operand:SI 2 "arith32_operand" "")))]
6815   ""
6816   "
6818   if (GET_CODE (operands[2]) != CONST_INT)
6819     {
6820       rtx temp = gen_reg_rtx (SImode);
6821       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6822       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6823       DONE;
6824     }
6827 (define_insn ""
6828   [(set (match_operand:SI 0 "register_operand" "=r")
6829         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6830                      (match_operand:SI 2 "const_int_operand" "n")))]
6831   ""
6832   "{extrs|extrw,s} %1,%P2,%L2,%0"
6833   [(set_attr "type" "shift")
6834    (set_attr "length" "4")])
6836 (define_insn "vextrs32"
6837   [(set (match_operand:SI 0 "register_operand" "=r")
6838         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6839                      (minus:SI (const_int 31)
6840                                (match_operand:SI 2 "register_operand" "q"))))]
6841   ""
6842   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6843   [(set_attr "type" "shift")
6844    (set_attr "length" "4")])
6846 (define_expand "ashrdi3"
6847   [(set (match_operand:DI 0 "register_operand" "")
6848         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6849                      (match_operand:DI 2 "arith32_operand" "")))]
6850   "TARGET_64BIT"
6851   "
6853   if (GET_CODE (operands[2]) != CONST_INT)
6854     {
6855       rtx temp = gen_reg_rtx (DImode);
6856       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6857       emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6858       DONE;
6859     }
6862 (define_insn ""
6863   [(set (match_operand:DI 0 "register_operand" "=r")
6864         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6865                      (match_operand:DI 2 "const_int_operand" "n")))]
6866   "TARGET_64BIT"
6867   "extrd,s %1,%p2,%Q2,%0"
6868   [(set_attr "type" "shift")
6869    (set_attr "length" "4")])
6871 (define_insn "vextrs64"
6872   [(set (match_operand:DI 0 "register_operand" "=r")
6873         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6874                      (minus:DI (const_int 63)
6875                                (match_operand:DI 2 "register_operand" "q"))))]
6876   "TARGET_64BIT"
6877   "extrd,s %1,%%sar,64,%0"
6878   [(set_attr "type" "shift")
6879    (set_attr "length" "4")])
6881 (define_insn "lshrsi3"
6882   [(set (match_operand:SI 0 "register_operand" "=r,r")
6883         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6884                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6885   ""
6886   "@
6887    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6888    {extru|extrw,u} %1,%P2,%L2,%0"
6889   [(set_attr "type" "shift")
6890    (set_attr "length" "4")])
6892 (define_insn "lshrdi3"
6893   [(set (match_operand:DI 0 "register_operand" "=r,r")
6894         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6895                      (match_operand:DI 2 "shift6_operand" "q,n")))]
6896   "TARGET_64BIT"
6897   "@
6898    shrpd %%r0,%1,%%sar,%0
6899    extrd,u %1,%p2,%Q2,%0"
6900   [(set_attr "type" "shift")
6901    (set_attr "length" "4")])
6903 ; Shift right pair word 0 to 31 bits.
6904 (define_insn "*shrpsi4_1"
6905   [(set (match_operand:SI 0 "register_operand" "=r")
6906         (match_operator:SI 4 "plus_xor_ior_operator"
6907           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6908                       (minus:SI (const_int 32)
6909                                 (match_operand:SI 3 "register_operand" "q")))
6910            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6911                         (match_dup 3))]))]
6912   ""
6913   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6914   [(set_attr "type" "shift")
6915    (set_attr "length" "4")])
6917 (define_insn "*shrpsi4_2"
6918   [(set (match_operand:SI 0 "register_operand" "=r")
6919         (match_operator:SI 4 "plus_xor_ior_operator"
6920           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6921                         (match_operand:SI 3 "register_operand" "q"))
6922            (ashift:SI (match_operand:SI 1 "register_operand" "r")
6923                       (minus:SI (const_int 32)
6924                                 (match_dup 3)))]))]
6925   ""
6926   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6927   [(set_attr "type" "shift")
6928    (set_attr "length" "4")])
6930 ; Shift right pair doubleword 0 to 63 bits.
6931 (define_insn "*shrpdi4_1"
6932   [(set (match_operand:DI 0 "register_operand" "=r")
6933         (match_operator:DI 4 "plus_xor_ior_operator"
6934           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6935                       (minus:DI (const_int 64)
6936                                 (match_operand:DI 3 "register_operand" "q")))
6937            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6938                         (match_dup 3))]))]
6939   "TARGET_64BIT"
6940   "shrpd %1,%2,%%sar,%0"
6941   [(set_attr "type" "shift")
6942    (set_attr "length" "4")])
6944 (define_insn "*shrpdi4_2"
6945   [(set (match_operand:DI 0 "register_operand" "=r")
6946         (match_operator:DI 4 "plus_xor_ior_operator"
6947           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6948                         (match_operand:DI 3 "shift6_operand" "q"))
6949            (ashift:DI (match_operand:SI 1 "register_operand" "r")
6950                       (minus:DI (const_int 64)
6951                                 (match_dup 3)))]))]
6952   "TARGET_64BIT"
6953   "shrpd %1,%2,%%sar,%0"
6954   [(set_attr "type" "shift")
6955    (set_attr "length" "4")])
6957 (define_insn "*shrpdi4_3"
6958   [(set (match_operand:DI 0 "register_operand" "=r")
6959         (match_operator:DI 5 "plus_xor_ior_operator"
6960           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6961                       (match_operand:DI 3 "const_int_operand" "n"))
6962            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6963                         (match_operand:DI 4 "const_int_operand" "n"))]))]
6964   "TARGET_64BIT
6965    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6966   "shrpd %1,%2,%4,%0"
6967   [(set_attr "type" "shift")
6968    (set_attr "length" "4")])
6970 (define_insn "*shrpdi4_4"
6971   [(set (match_operand:DI 0 "register_operand" "=r")
6972         (match_operator:DI 5 "plus_xor_ior_operator"
6973           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6974                         (match_operand:DI 4 "const_int_operand" "n"))
6975            (ashift:DI (match_operand:DI 1 "register_operand" "r")
6976                       (match_operand:DI 3 "const_int_operand" "n"))]))]
6977   "TARGET_64BIT
6978    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6979   "shrpd %1,%2,%4,%0"
6980   [(set_attr "type" "shift")
6981    (set_attr "length" "4")])
6983 (define_insn "rotrsi3"
6984   [(set (match_operand:SI 0 "register_operand" "=r,r")
6985         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6986                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6987   ""
6988   "*
6990   if (GET_CODE (operands[2]) == CONST_INT)
6991     {
6992       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6993       return \"{shd|shrpw} %1,%1,%2,%0\";
6994     }
6995   else
6996     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6998   [(set_attr "type" "shift")
6999    (set_attr "length" "4")])
7001 (define_expand "rotlsi3"
7002   [(set (match_operand:SI 0 "register_operand" "")
7003         (rotate:SI (match_operand:SI 1 "register_operand" "")
7004                    (match_operand:SI 2 "arith32_operand" "")))]
7005   ""
7006   "
7008   if (GET_CODE (operands[2]) != CONST_INT)
7009     {
7010       rtx temp = gen_reg_rtx (SImode);
7011       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
7012       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
7013       DONE;
7014     }
7015   /* Else expand normally.  */
7018 (define_insn "*rotlsi3_internal"
7019   [(set (match_operand:SI 0 "register_operand" "=r")
7020         (rotate:SI (match_operand:SI 1 "register_operand" "r")
7021                    (match_operand:SI 2 "const_int_operand" "n")))]
7022   ""
7023   "*
7025   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
7026   return \"{shd|shrpw} %1,%1,%2,%0\";
7028   [(set_attr "type" "shift")
7029    (set_attr "length" "4")])
7031 (define_insn "rotrdi3"
7032   [(set (match_operand:DI 0 "register_operand" "=r,r")
7033         (rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
7034                      (match_operand:DI 2 "shift6_operand" "q,n")))]
7035   "TARGET_64BIT"
7036   "*
7038   if (GET_CODE (operands[2]) == CONST_INT)
7039     {
7040       operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
7041       return \"shrpd %1,%1,%2,%0\";
7042     }
7043   else
7044     return \"shrpd %1,%1,%%sar,%0\";
7046   [(set_attr "type" "shift")
7047    (set_attr "length" "4")])
7049 (define_expand "rotldi3"
7050   [(set (match_operand:DI 0 "register_operand" "")
7051         (rotate:DI (match_operand:DI 1 "register_operand" "")
7052                    (match_operand:DI 2 "arith32_operand" "")))]
7053   "TARGET_64BIT"
7054   "
7056   if (GET_CODE (operands[2]) != CONST_INT)
7057     {
7058       rtx temp = gen_reg_rtx (DImode);
7059       emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
7060       emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
7061       DONE;
7062     }
7063   /* Else expand normally.  */
7066 (define_insn "*rotldi3_internal"
7067   [(set (match_operand:DI 0 "register_operand" "=r")
7068         (rotate:DI (match_operand:DI 1 "register_operand" "r")
7069                    (match_operand:DI 2 "const_int_operand" "n")))]
7070   "TARGET_64BIT"
7071   "*
7073   operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
7074   return \"shrpd %1,%1,%2,%0\";
7076   [(set_attr "type" "shift")
7077    (set_attr "length" "4")])
7079 (define_insn ""
7080   [(set (match_operand:SI 0 "register_operand" "=r")
7081         (match_operator:SI 5 "plus_xor_ior_operator"
7082           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
7083                       (match_operand:SI 3 "const_int_operand" "n"))
7084            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7085                         (match_operand:SI 4 "const_int_operand" "n"))]))]
7086   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7087   "{shd|shrpw} %1,%2,%4,%0"
7088   [(set_attr "type" "shift")
7089    (set_attr "length" "4")])
7091 (define_insn ""
7092   [(set (match_operand:SI 0 "register_operand" "=r")
7093         (match_operator:SI 5 "plus_xor_ior_operator"
7094           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7095                         (match_operand:SI 4 "const_int_operand" "n"))
7096            (ashift:SI (match_operand:SI 1 "register_operand" "r")
7097                       (match_operand:SI 3 "const_int_operand" "n"))]))]
7098   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7099   "{shd|shrpw} %1,%2,%4,%0"
7100   [(set_attr "type" "shift")
7101    (set_attr "length" "4")])
7103 (define_expand "shd_internal"
7104   [(set (match_operand:SI 0 "register_operand")
7105         (ior:SI
7106           (lshiftrt:SI (match_operand:SI 1 "register_operand")
7107                        (match_operand:SI 2 "const_int_operand"))
7108           (ashift:SI (match_operand:SI 3 "register_operand")
7109                      (match_operand:SI 4 "const_int_operand"))))]
7110   "")
7112 (define_expand "shrpd_internal"
7113   [(set (match_operand:DI 0 "register_operand")
7114         (ior:DI
7115           (lshiftrt:DI (match_operand:DI 1 "register_operand")
7116                        (match_operand:DI 2 "const_int_operand"))
7117           (ashift:DI (match_operand:DI 3 "register_operand")
7118                      (match_operand:DI 4 "const_int_operand"))))]
7119   "TARGET_64BIT")
7121 (define_insn ""
7122   [(set (match_operand:SI 0 "register_operand" "=r")
7123         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
7124                            (match_operand:SI 2 "const_int_operand" ""))
7125                 (match_operand:SI 3 "const_int_operand" "")))]
7126   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
7127   "*
7129   int cnt = INTVAL (operands[2]) & 31;
7130   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
7131   operands[2] = GEN_INT (31 - cnt);
7132   return \"{zdep|depw,z} %1,%2,%3,%0\";
7134   [(set_attr "type" "shift")
7135    (set_attr "length" "4")])
7137 ;; Unconditional and other jump instructions.
7139 ;; Trivial return used when no epilogue is needed.
7140 (define_insn "return"
7141   [(return)
7142    (use (reg:SI 2))]
7143   "pa_can_use_return_insn ()"
7144   "*
7146   if (TARGET_PA_20)
7147     return \"bve%* (%%r2)\";
7148   return \"bv%* %%r0(%%r2)\";
7150   [(set_attr "type" "branch")
7151    (set_attr "length" "4")])
7153 ;; This is used for most returns.
7154 (define_insn "return_internal"
7155   [(return)
7156    (use (reg:SI 2))]
7157   ""
7158   "*
7160   if (TARGET_PA_20)
7161     return \"bve%* (%%r2)\";
7162   return \"bv%* %%r0(%%r2)\";
7164   [(set_attr "type" "branch")
7165    (set_attr "length" "4")])
7167 ;; This is used for eh returns which bypass the return stub.
7168 (define_insn "return_external_pic"
7169   [(return)
7170    (clobber (reg:SI 1))
7171    (use (reg:SI 2))]
7172   "!TARGET_NO_SPACE_REGS
7173    && !TARGET_PA_20
7174    && flag_pic && crtl->calls_eh_return"
7175   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7176   [(set_attr "type" "branch")
7177    (set_attr "length" "12")])
7179 (define_expand "prologue"
7180   [(const_int 0)]
7181   ""
7182   "pa_expand_prologue ();DONE;")
7184 (define_expand "sibcall_epilogue"
7185   [(return)]
7186   ""
7187   "
7189   pa_expand_epilogue ();
7190   DONE;
7193 (define_expand "epilogue"
7194   [(return)]
7195   ""
7196   "
7198   rtx x;
7200   /* Try to use the trivial return first.  Else use the full epilogue.  */
7201   if (pa_can_use_return_insn ())
7202     x = gen_return ();
7203   else
7204     {
7205       pa_expand_epilogue ();
7207       /* EH returns bypass the normal return stub.  Thus, we must do an
7208          interspace branch to return from functions that call eh_return.
7209          This is only a problem for returns from shared code on ports
7210          using space registers.  */
7211       if (!TARGET_NO_SPACE_REGS
7212           && !TARGET_PA_20
7213           && flag_pic && crtl->calls_eh_return)
7214         x = gen_return_external_pic ();
7215       else
7216         x = gen_return_internal ();
7217     }
7218   emit_jump_insn (x);
7219   DONE;
7222 ; Used by hppa_profile_hook to load the starting address of the current
7223 ; function; operand 1 contains the address of the label in operand 3
7224 (define_insn "load_offset_label_address"
7225   [(set (match_operand:SI 0 "register_operand" "=r")
7226         (plus:SI (match_operand:SI 1 "register_operand" "r")
7227                  (minus:SI (match_operand:SI 2 "" "")
7228                            (label_ref:SI (match_operand 3 "" "")))))]
7229   ""
7230   "ldo %2-%l3(%1),%0"
7231   [(set_attr "type" "multi")
7232    (set_attr "length" "4")])
7234 ; Output a code label and load its address.
7235 (define_insn "lcla1"
7236   [(set (match_operand:SI 0 "register_operand" "=r")
7237         (label_ref:SI (match_operand 1 "" "")))
7238    (const_int 0)]
7239   "!TARGET_PA_20"
7240   "*
7242   output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7243   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7244                                      CODE_LABEL_NUMBER (operands[1]));
7245   return \"\";
7247   [(set_attr "type" "multi")
7248    (set_attr "length" "8")])
7250 (define_insn "lcla2"
7251   [(set (match_operand:SI 0 "register_operand" "=r")
7252         (label_ref:SI (match_operand 1 "" "")))
7253    (const_int 0)]
7254   "TARGET_PA_20"
7255   "*
7257   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7258                                      CODE_LABEL_NUMBER (operands[1]));
7259   return \"mfia %0\";
7261   [(set_attr "type" "move")
7262    (set_attr "length" "4")])
7264 (define_insn "blockage"
7265   [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7266   ""
7267   ""
7268   [(set_attr "length" "0")])
7270 (define_insn "jump"
7271   [(set (pc) (label_ref (match_operand 0 "" "")))]
7272   ""
7273   "*
7275   /* An unconditional branch which can reach its target.  */
7276   if (get_attr_length (insn) < 16)
7277     return \"b%* %l0\";
7279   return pa_output_lbranch (operands[0], insn, 1);
7281   [(set_attr "type" "uncond_branch")
7282    (set_attr "pa_combine_type" "uncond_branch")
7283    (set (attr "length")
7284     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7285                (const_int MAX_17BIT_OFFSET))
7286            (const_int 4)
7287            (match_test "TARGET_PORTABLE_RUNTIME")
7288            (const_int 20)
7289            (not (match_test "flag_pic"))
7290            (const_int 16)]
7291           (const_int 24)))])
7293 ;;; Hope this is only within a function...
7294 (define_insn "indirect_jump"
7295   [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7296   ""
7297   "bv%* %%r0(%0)"
7298   [(set_attr "type" "branch")
7299    (set_attr "length" "4")])
7301 ;;; An indirect jump can be optimized to a direct jump.  GAS for the
7302 ;;; SOM target doesn't allow branching to a label inside a function.
7303 ;;; We also don't correctly compute branch distances for labels
7304 ;;; outside the current function.  Thus, we use an indirect jump can't
7305 ;;; be optimized to a direct jump for all targets.  We assume that
7306 ;;; the branch target is in the same space (i.e., nested function
7307 ;;; jumping to a label in an outer function in the same translation
7308 ;;; unit).
7309 (define_expand "nonlocal_goto"
7310   [(use (match_operand 0 "general_operand" ""))
7311    (use (match_operand 1 "general_operand" ""))
7312    (use (match_operand 2 "general_operand" ""))
7313    (use (match_operand 3 "general_operand" ""))]
7314   ""
7316   rtx lab = operands[1];
7317   rtx stack = operands[2];
7318   rtx fp = operands[3];
7320   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7321   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7323   lab = copy_to_reg (lab);
7325   /* Restore the stack and frame pointers.  */
7326   fp = copy_to_reg (fp);
7327   emit_stack_restore (SAVE_NONLOCAL, stack);
7329   /* Ensure the frame pointer move is not optimized.  */
7330   emit_insn (gen_blockage ());
7331   emit_clobber (hard_frame_pointer_rtx);
7332   emit_clobber (frame_pointer_rtx);
7333   emit_move_insn (hard_frame_pointer_rtx, fp);
7335   emit_use (hard_frame_pointer_rtx);
7336   emit_use (stack_pointer_rtx);
7338   /* Nonlocal goto jumps are only used between functions in the same
7339      translation unit.  Thus, we can avoid the extra overhead of an
7340      interspace jump.  */
7341   emit_jump_insn (gen_indirect_goto (lab));
7342   emit_barrier ();
7343   DONE;
7346 (define_insn "indirect_goto"
7347   [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7348   "GET_MODE (operands[0]) == word_mode"
7349   "bv%* %%r0(%0)"
7350   [(set_attr "type" "branch")
7351    (set_attr "length" "4")])
7353 ;; Subroutines of "casesi".
7354 ;; operand 0 is index
7355 ;; operand 1 is the minimum bound
7356 ;; operand 2 is the maximum bound - minimum bound + 1
7357 ;; operand 3 is CODE_LABEL for the table;
7358 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7360 (define_expand "casesi"
7361   [(match_operand:SI 0 "general_operand" "")
7362    (match_operand:SI 1 "const_int_operand" "")
7363    (match_operand:SI 2 "const_int_operand" "")
7364    (match_operand 3 "" "")
7365    (match_operand 4 "" "")]
7366   ""
7367   "
7369   if (GET_CODE (operands[0]) != REG)
7370     operands[0] = force_reg (SImode, operands[0]);
7372   if (operands[1] != const0_rtx)
7373     {
7374       rtx index = gen_reg_rtx (SImode);
7376       operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7377       if (!INT_14_BITS (operands[1]))
7378         operands[1] = force_reg (SImode, operands[1]);
7379       emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7380       operands[0] = index;
7381     }
7383   if (!INT_5_BITS (operands[2]))
7384     operands[2] = force_reg (SImode, operands[2]);
7386   /* This branch prevents us finding an insn for the delay slot of the
7387      following vectored branch.  It might be possible to use the delay
7388      slot if an index value of -1 was used to transfer to the out-of-range
7389      label.  In order to do this, we would have to output the -1 vector
7390      element after the delay insn.  The casesi output code would have to
7391      check if the casesi insn is in a delay branch sequence and output
7392      the delay insn if one is found.  If this was done, then it might
7393      then be worthwhile to split the casesi patterns to improve scheduling.
7394      However, it's not clear that all this extra complexity is worth
7395      the effort.  */
7396   {
7397     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7398     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7399   }
7401   /* In 64bit mode we must make sure to wipe the upper bits of the register
7402      just in case the addition overflowed or we had random bits in the
7403      high part of the register.  */
7404   if (TARGET_64BIT)
7405     {
7406       rtx index = gen_reg_rtx (DImode);
7408       emit_insn (gen_extendsidi2 (index, operands[0]));
7409       operands[0] = index;
7410     }
7412   if (TARGET_64BIT)
7413     emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7414   else if (flag_pic)
7415     emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7416   else
7417     emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7418   DONE;
7421 ;;; 32-bit code, absolute branch table.
7422 (define_insn "casesi32"
7423   [(set (pc) (mem:SI (plus:SI
7424                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7425                                 (const_int 4))
7426                        (label_ref (match_operand 1 "" "")))))
7427    (clobber (match_scratch:SI 2 "=&r"))]
7428   "!flag_pic"
7429   "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7430   [(set_attr "type" "multi")
7431    (set_attr "length" "16")])
7433 ;;; 32-bit code, relative branch table.
7434 (define_insn "casesi32p"
7435   [(set (pc) (mem:SI (plus:SI
7436                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7437                                 (const_int 4))
7438                        (label_ref (match_operand 1 "" "")))))
7439    (clobber (match_scratch:SI 2 "=&r"))
7440    (clobber (match_scratch:SI 3 "=&r"))]
7441   "flag_pic"
7442   "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7443 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7444   [(set_attr "type" "multi")
7445    (set (attr "length")
7446      (if_then_else (match_test "TARGET_PA_20")
7447         (const_int 20)
7448         (const_int 24)))])
7450 ;;; 64-bit code, 32-bit relative branch table.
7451 (define_insn "casesi64p"
7452   [(set (pc) (mem:DI (plus:DI
7453                        (mult:DI (match_operand:DI 0 "register_operand" "r")
7454                                 (const_int 8))
7455                        (label_ref (match_operand 1 "" "")))))
7456    (clobber (match_scratch:DI 2 "=&r"))
7457    (clobber (match_scratch:DI 3 "=&r"))]
7458   ""
7459   "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7460 add,l %2,%3,%3\;bv,n %%r0(%3)"
7461   [(set_attr "type" "multi")
7462    (set_attr "length" "24")])
7465 ;; Call patterns.
7466 ;;- jump to subroutine
7468 (define_expand "call"
7469   [(parallel [(call (match_operand:SI 0 "" "")
7470                     (match_operand 1 "" ""))
7471               (clobber (reg:SI 2))])]
7472   ""
7473   "
7475   rtx op;
7476   rtx nb = operands[1];
7478   if (TARGET_PORTABLE_RUNTIME)
7479     op = force_reg (SImode, XEXP (operands[0], 0));
7480   else
7481     {
7482       op = XEXP (operands[0], 0);
7484       /* Generate indirect long calls to non-local functions. */
7485       if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7486         {
7487           tree call_decl = SYMBOL_REF_DECL (op);
7488           if (!(call_decl && targetm.binds_local_p (call_decl)))
7489             op = force_reg (word_mode, op);
7490         }
7491     }
7493   if (TARGET_64BIT)
7494     {
7495       if (!virtuals_instantiated)
7496         emit_move_insn (arg_pointer_rtx,
7497                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7498                                       GEN_INT (64)));
7499       else
7500         {
7501           /* The loop pass can generate new libcalls after the virtual
7502              registers are instantiated when fpregs are disabled because
7503              the only method that we have for doing DImode multiplication
7504              is with a libcall.  This could be trouble if we haven't
7505              allocated enough space for the outgoing arguments.  */
7506           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7508           emit_move_insn (arg_pointer_rtx,
7509                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7510                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7511         }
7512     }
7514   /* Use two different patterns for calls to explicitly named functions
7515      and calls through function pointers.  This is necessary as these two
7516      types of calls use different calling conventions, and CSE might try
7517      to change the named call into an indirect call in some cases (using
7518      two patterns keeps CSE from performing this optimization).
7519      
7520      We now use even more call patterns as there was a subtle bug in
7521      attempting to restore the pic register after a call using a simple
7522      move insn.  During reload, a instruction involving a pseudo register
7523      with no explicit dependence on the PIC register can be converted
7524      to an equivalent load from memory using the PIC register.  If we
7525      emit a simple move to restore the PIC register in the initial rtl
7526      generation, then it can potentially be repositioned during scheduling.
7527      and an instruction that eventually uses the PIC register may end up
7528      between the call and the PIC register restore.
7529      
7530      This only worked because there is a post call group of instructions
7531      that are scheduled with the call.  These instructions are included
7532      in the same basic block as the call.  However, calls can throw in
7533      C++ code and a basic block has to terminate at the call if the call
7534      can throw.  This results in the PIC register restore being scheduled
7535      independently from the call.  So, we now hide the save and restore
7536      of the PIC register in the call pattern until after reload.  Then,
7537      we split the moves out.  A small side benefit is that we now don't
7538      need to have a use of the PIC register in the return pattern and
7539      the final save/restore operation is not needed.
7540      
7541      I elected to just use register %r4 in the PIC patterns instead
7542      of trying to force hppa_pic_save_rtx () to a callee saved register.
7543      This might have required a new register class and constraint.  It
7544      was also simpler to just handle the restore from a register than a
7545      generic pseudo.  */
7546   if (TARGET_64BIT)
7547     {
7548       rtx r4 = gen_rtx_REG (word_mode, 4);
7549       if (GET_CODE (op) == SYMBOL_REF)
7550         emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7551       else
7552         {
7553           op = force_reg (word_mode, op);
7554           emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7555         }
7556     }
7557   else
7558     {
7559       if (GET_CODE (op) == SYMBOL_REF)
7560         {
7561           if (flag_pic)
7562             {
7563               rtx r4 = gen_rtx_REG (word_mode, 4);
7564               emit_call_insn (gen_call_symref_pic (op, nb, r4));
7565             }
7566           else
7567             emit_call_insn (gen_call_symref (op, nb));
7568         }
7569       else
7570         {
7571           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7572           emit_move_insn (tmpreg, force_reg (word_mode, op));
7573           if (flag_pic)
7574             {
7575               rtx r4 = gen_rtx_REG (word_mode, 4);
7576               emit_call_insn (gen_call_reg_pic (nb, r4));
7577             }
7578           else
7579             emit_call_insn (gen_call_reg (nb));
7580         }
7581     }
7583   DONE;
7586 ;; We use function calls to set the attribute length of calls and millicode
7587 ;; calls.  This is necessary because of the large variety of call sequences.
7588 ;; Implementing the calculation in rtl is difficult as well as ugly.  As
7589 ;; we need the same calculation in several places, maintenance becomes a
7590 ;; nightmare.
7592 ;; However, this has a subtle impact on branch shortening.  When the
7593 ;; expression used to set the length attribute of an instruction depends
7594 ;; on a relative address (e.g., pc or a branch address), genattrtab
7595 ;; notes that the insn's length is variable, and attempts to determine a
7596 ;; worst-case default length and code to compute an insn's current length.
7598 ;; The use of a function call hides the variable dependence of our calls
7599 ;; and millicode calls.  The result is genattrtab doesn't treat the operation
7600 ;; as variable and it only generates code for the default case using our
7601 ;; function call.  Because of this, calls and millicode calls have a fixed
7602 ;; length in the branch shortening pass, and some branches will use a longer
7603 ;; code sequence than necessary.  However, the length of any given call
7604 ;; will still reflect its final code location and it may be shorter than
7605 ;; the initial length estimate.
7607 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7608 ;; in the set.  However, when genattrtab hits a function call in its attempt
7609 ;; to compute the default length, it marks the result as unknown and sets
7610 ;; the default result to MAX_INT ;-(  One possible fix that would allow
7611 ;; calls to participate in branch shortening would be to make the call to
7612 ;; insn_default_length a target option.  Then, we could massage unknown
7613 ;; results.  Another fix might be to change genattrtab so that it just does
7614 ;; the call in the variable case as it already does for the fixed case.
7616 (define_insn "call_symref"
7617   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7618          (match_operand 1 "" "i"))
7619    (clobber (reg:SI 1))
7620    (clobber (reg:SI 2))
7621    (use (const_int 0))]
7622   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7623   "*
7625   pa_output_arg_descriptor (insn);
7626   return pa_output_call (insn, operands[0], 0);
7628   [(set_attr "type" "call")
7629    (set (attr "length")
7630         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7631               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7633 (define_insn "call_symref_pic"
7634   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7635          (match_operand 1 "" "i"))
7636    (clobber (reg:SI 1))
7637    (clobber (reg:SI 2))
7638    (clobber (match_operand 2))
7639    (use (reg:SI 19))
7640    (use (const_int 0))]
7641   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7642   "#")
7644 ;; Split out the PIC register save and restore after reload.  As the
7645 ;; split is done after reload, there are some situations in which we
7646 ;; unnecessarily save and restore %r4.  This happens when there is a
7647 ;; single call and the PIC register is not used after the call.
7649 ;; The split has to be done since call_from_call_insn () can't handle
7650 ;; the pattern as is.  Noreturn calls are special because they have to
7651 ;; terminate the basic block.  The split has to contain more than one
7652 ;; insn.
7653 (define_split
7654   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7655                     (match_operand 1 "" ""))
7656               (clobber (reg:SI 1))
7657               (clobber (reg:SI 2))
7658               (clobber (match_operand 2))
7659               (use (reg:SI 19))
7660               (use (const_int 0))])]
7661   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7662    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7663   [(set (match_dup 2) (reg:SI 19))
7664    (parallel [(call (mem:SI (match_dup 0))
7665                     (match_dup 1))
7666               (clobber (reg:SI 1))
7667               (clobber (reg:SI 2))
7668               (use (reg:SI 19))
7669               (use (const_int 0))])]
7670   "")
7672 (define_split
7673   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7674                     (match_operand 1 "" ""))
7675               (clobber (reg:SI 1))
7676               (clobber (reg:SI 2))
7677               (clobber (match_operand 2))
7678               (use (reg:SI 19))
7679               (use (const_int 0))])]
7680   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7681   [(set (match_dup 2) (reg:SI 19))
7682    (parallel [(call (mem:SI (match_dup 0))
7683                     (match_dup 1))
7684               (clobber (reg:SI 1))
7685               (clobber (reg:SI 2))
7686               (use (reg:SI 19))
7687               (use (const_int 0))])
7688    (set (reg:SI 19) (match_dup 2))]
7689   "")
7691 (define_insn "*call_symref_pic_post_reload"
7692   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7693          (match_operand 1 "" "i"))
7694    (clobber (reg:SI 1))
7695    (clobber (reg:SI 2))
7696    (use (reg:SI 19))
7697    (use (const_int 0))]
7698   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7699   "*
7701   pa_output_arg_descriptor (insn);
7702   return pa_output_call (insn, operands[0], 0);
7704   [(set_attr "type" "call")
7705    (set (attr "length")
7706         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7707               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7709 ;; This pattern is split if it is necessary to save and restore the
7710 ;; PIC register.
7711 (define_insn "call_symref_64bit"
7712   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7713          (match_operand 1 "" "i"))
7714    (clobber (reg:DI 1))
7715    (clobber (reg:DI 2))
7716    (clobber (match_operand 2))
7717    (use (reg:DI 27))
7718    (use (reg:DI 29))
7719    (use (const_int 0))]
7720   "TARGET_64BIT"
7721   "#")
7723 ;; Split out the PIC register save and restore after reload.  As the
7724 ;; split is done after reload, there are some situations in which we
7725 ;; unnecessarily save and restore %r4.  This happens when there is a
7726 ;; single call and the PIC register is not used after the call.
7728 ;; The split has to be done since call_from_call_insn () can't handle
7729 ;; the pattern as is.  Noreturn calls are special because they have to
7730 ;; terminate the basic block.  The split has to contain more than one
7731 ;; insn.
7732 (define_split
7733   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7734                     (match_operand 1 "" ""))
7735               (clobber (reg:DI 1))
7736               (clobber (reg:DI 2))
7737               (clobber (match_operand 2))
7738               (use (reg:DI 27))
7739               (use (reg:DI 29))
7740               (use (const_int 0))])]
7741   "TARGET_64BIT && reload_completed
7742    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7743   [(set (match_dup 2) (reg:DI 27))
7744    (parallel [(call (mem:SI (match_dup 0))
7745                     (match_dup 1))
7746               (clobber (reg:DI 1))
7747               (clobber (reg:DI 2))
7748               (use (reg:DI 27))
7749               (use (reg:DI 29))
7750               (use (const_int 0))])]
7751   "")
7753 (define_split
7754   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7755                     (match_operand 1 "" ""))
7756               (clobber (reg:DI 1))
7757               (clobber (reg:DI 2))
7758               (clobber (match_operand 2))
7759               (use (reg:DI 27))
7760               (use (reg:DI 29))
7761               (use (const_int 0))])]
7762   "TARGET_64BIT && reload_completed"
7763   [(set (match_dup 2) (reg:DI 27))
7764    (parallel [(call (mem:SI (match_dup 0))
7765                     (match_dup 1))
7766               (clobber (reg:DI 1))
7767               (clobber (reg:DI 2))
7768               (use (reg:DI 27))
7769               (use (reg:DI 29))
7770               (use (const_int 0))])
7771    (set (reg:DI 27) (match_dup 2))]
7772   "")
7774 (define_insn "*call_symref_64bit_post_reload"
7775   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7776          (match_operand 1 "" "i"))
7777    (clobber (reg:DI 1))
7778    (clobber (reg:DI 2))
7779    (use (reg:DI 27))
7780    (use (reg:DI 29))
7781    (use (const_int 0))]
7782   "TARGET_64BIT"
7783   "*
7785   return pa_output_call (insn, operands[0], 0);
7787   [(set_attr "type" "call")
7788    (set (attr "length")
7789         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7790               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7792 (define_insn "call_reg"
7793   [(call (mem:SI (reg:SI 22))
7794          (match_operand 0 "" "i"))
7795    (clobber (reg:SI 1))
7796    (clobber (reg:SI 2))
7797    (use (const_int 1))]
7798   "!TARGET_64BIT"
7799   "*
7801   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7803   [(set_attr "type" "dyncall")
7804    (set (attr "length")
7805         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7806               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7808 ;; This pattern is split if it is necessary to save and restore the
7809 ;; PIC register.
7810 (define_insn "call_reg_pic"
7811   [(call (mem:SI (reg:SI 22))
7812          (match_operand 0 "" "i"))
7813    (clobber (reg:SI 1))
7814    (clobber (reg:SI 2))
7815    (clobber (match_operand 1))
7816    (use (reg:SI 19))
7817    (use (const_int 1))]
7818   "!TARGET_64BIT"
7819   "#")
7821 ;; Split out the PIC register save and restore after reload.  As the
7822 ;; split is done after reload, there are some situations in which we
7823 ;; unnecessarily save and restore %r4.  This happens when there is a
7824 ;; single call and the PIC register is not used after the call.
7826 ;; The split has to be done since call_from_call_insn () can't handle
7827 ;; the pattern as is.  Noreturn calls are special because they have to
7828 ;; terminate the basic block.  The split has to contain more than one
7829 ;; insn.
7830 (define_split
7831   [(parallel [(call (mem:SI (reg:SI 22))
7832                     (match_operand 0 "" ""))
7833               (clobber (reg:SI 1))
7834               (clobber (reg:SI 2))
7835               (clobber (match_operand 1))
7836               (use (reg:SI 19))
7837               (use (const_int 1))])]
7838   "!TARGET_64BIT && reload_completed
7839    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7840   [(set (match_dup 1) (reg:SI 19))
7841    (parallel [(call (mem:SI (reg:SI 22))
7842                     (match_dup 0))
7843               (clobber (reg:SI 1))
7844               (clobber (reg:SI 2))
7845               (use (reg:SI 19))
7846               (use (const_int 1))])]
7847   "")
7849 (define_split
7850   [(parallel [(call (mem:SI (reg:SI 22))
7851                     (match_operand 0 "" ""))
7852               (clobber (reg:SI 1))
7853               (clobber (reg:SI 2))
7854               (clobber (match_operand 1))
7855               (use (reg:SI 19))
7856               (use (const_int 1))])]
7857   "!TARGET_64BIT && reload_completed"
7858   [(set (match_dup 1) (reg:SI 19))
7859    (parallel [(call (mem:SI (reg:SI 22))
7860                     (match_dup 0))
7861               (clobber (reg:SI 1))
7862               (clobber (reg:SI 2))
7863               (use (reg:SI 19))
7864               (use (const_int 1))])
7865    (set (reg:SI 19) (match_dup 1))]
7866   "")
7868 (define_insn "*call_reg_pic_post_reload"
7869   [(call (mem:SI (reg:SI 22))
7870          (match_operand 0 "" "i"))
7871    (clobber (reg:SI 1))
7872    (clobber (reg:SI 2))
7873    (use (reg:SI 19))
7874    (use (const_int 1))]
7875   "!TARGET_64BIT"
7876   "*
7878   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7880   [(set_attr "type" "dyncall")
7881    (set (attr "length")
7882         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7883               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7885 ;; This pattern is split if it is necessary to save and restore the
7886 ;; PIC register.
7887 (define_insn "call_reg_64bit"
7888   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7889          (match_operand 1 "" "i"))
7890    (clobber (reg:DI 2))
7891    (clobber (match_operand 2))
7892    (use (reg:DI 27))
7893    (use (reg:DI 29))
7894    (use (const_int 1))]
7895   "TARGET_64BIT"
7896   "#")
7898 ;; Split out the PIC register save and restore after reload.  As the
7899 ;; split is done after reload, there are some situations in which we
7900 ;; unnecessarily save and restore %r4.  This happens when there is a
7901 ;; single call and the PIC register is not used after the call.
7903 ;; The split has to be done since call_from_call_insn () can't handle
7904 ;; the pattern as is.  Noreturn calls are special because they have to
7905 ;; terminate the basic block.  The split has to contain more than one
7906 ;; insn.
7907 (define_split
7908   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7909                     (match_operand 1 "" ""))
7910               (clobber (reg:DI 2))
7911               (clobber (match_operand 2))
7912               (use (reg:DI 27))
7913               (use (reg:DI 29))
7914               (use (const_int 1))])]
7915   "TARGET_64BIT && reload_completed
7916    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7917   [(set (match_dup 2) (reg:DI 27))
7918    (parallel [(call (mem:SI (match_dup 0))
7919                     (match_dup 1))
7920               (clobber (reg:DI 2))
7921               (use (reg:DI 27))
7922               (use (reg:DI 29))
7923               (use (const_int 1))])]
7924   "")
7926 (define_split
7927   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7928                     (match_operand 1 "" ""))
7929               (clobber (reg:DI 2))
7930               (clobber (match_operand 2))
7931               (use (reg:DI 27))
7932               (use (reg:DI 29))
7933               (use (const_int 1))])]
7934   "TARGET_64BIT && reload_completed"
7935   [(set (match_dup 2) (reg:DI 27))
7936    (parallel [(call (mem:SI (match_dup 0))
7937                     (match_dup 1))
7938               (clobber (reg:DI 2))
7939               (use (reg:DI 27))
7940               (use (reg:DI 29))
7941               (use (const_int 1))])
7942    (set (reg:DI 27) (match_dup 2))]
7943   "")
7945 (define_insn "*call_reg_64bit_post_reload"
7946   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7947          (match_operand 1 "" "i"))
7948    (clobber (reg:DI 2))
7949    (use (reg:DI 27))
7950    (use (reg:DI 29))
7951    (use (const_int 1))]
7952   "TARGET_64BIT"
7953   "*
7955   return pa_output_indirect_call (insn, operands[0]);
7957   [(set_attr "type" "dyncall")
7958    (set (attr "length")
7959         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7960               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7962 (define_expand "call_value"
7963   [(parallel [(set (match_operand 0 "" "")
7964                    (call (match_operand:SI 1 "" "")
7965                          (match_operand 2 "" "")))
7966               (clobber (reg:SI 2))])]
7967   ""
7969   rtx op;
7970   rtx dst = operands[0];
7971   rtx nb = operands[2];
7972   bool call_powf = false;
7974   if (TARGET_PORTABLE_RUNTIME)
7975     op = force_reg (SImode, XEXP (operands[1], 0));
7976   else
7977     {
7978       op = XEXP (operands[1], 0);
7979       if (GET_CODE (op) == SYMBOL_REF)
7980         {
7981           /* Handle special call to buggy powf function.  */
7982           if (TARGET_HPUX && !TARGET_SOFT_FLOAT
7983               && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7984             call_powf = true;
7986           /* Generate indirect long calls to non-local functions. */
7987           else if (TARGET_LONG_CALLS)
7988             {
7989               tree call_decl = SYMBOL_REF_DECL (op);
7990               if (!(call_decl && targetm.binds_local_p (call_decl)))
7991                 op = force_reg (word_mode, op);
7992             }
7993         }
7994     }
7996   if (TARGET_64BIT)
7997     {
7998       if (!virtuals_instantiated)
7999         emit_move_insn (arg_pointer_rtx,
8000                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8001                                       GEN_INT (64)));
8002       else
8003         {
8004           /* The loop pass can generate new libcalls after the virtual
8005              registers are instantiated when fpregs are disabled because
8006              the only method that we have for doing DImode multiplication
8007              is with a libcall.  This could be trouble if we haven't
8008              allocated enough space for the outgoing arguments.  */
8009           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8011           emit_move_insn (arg_pointer_rtx,
8012                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8013                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8014         }
8015     }
8017   /* Use two different patterns for calls to explicitly named functions
8018      and calls through function pointers.  This is necessary as these two
8019      types of calls use different calling conventions, and CSE might try
8020      to change the named call into an indirect call in some cases (using
8021      two patterns keeps CSE from performing this optimization).
8023      We now use even more call patterns as there was a subtle bug in
8024      attempting to restore the pic register after a call using a simple
8025      move insn.  During reload, a instruction involving a pseudo register
8026      with no explicit dependence on the PIC register can be converted
8027      to an equivalent load from memory using the PIC register.  If we
8028      emit a simple move to restore the PIC register in the initial rtl
8029      generation, then it can potentially be repositioned during scheduling.
8030      and an instruction that eventually uses the PIC register may end up
8031      between the call and the PIC register restore.
8032      
8033      This only worked because there is a post call group of instructions
8034      that are scheduled with the call.  These instructions are included
8035      in the same basic block as the call.  However, calls can throw in
8036      C++ code and a basic block has to terminate at the call if the call
8037      can throw.  This results in the PIC register restore being scheduled
8038      independently from the call.  So, we now hide the save and restore
8039      of the PIC register in the call pattern until after reload.  Then,
8040      we split the moves out.  A small side benefit is that we now don't
8041      need to have a use of the PIC register in the return pattern and
8042      the final save/restore operation is not needed.
8043      
8044      I elected to just use register %r4 in the PIC patterns instead
8045      of trying to force hppa_pic_save_rtx () to a callee saved register.
8046      This might have required a new register class and constraint.  It
8047      was also simpler to just handle the restore from a register than a
8048      generic pseudo.  */
8049   if (TARGET_64BIT)
8050     {
8051       rtx r4 = gen_rtx_REG (word_mode, 4);
8052       if (GET_CODE (op) == SYMBOL_REF)
8053         {
8054           if (call_powf)
8055             emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
8056           else
8057             emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
8058         }
8059       else
8060         {
8061           op = force_reg (word_mode, op);
8062           emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
8063         }
8064     }
8065   else
8066     {
8067       if (GET_CODE (op) == SYMBOL_REF)
8068         {
8069           if (flag_pic)
8070             {
8071               rtx r4 = gen_rtx_REG (word_mode, 4);
8073               if (call_powf)
8074                 emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
8075               else
8076                 emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
8077             }
8078           else
8079             {
8080               if (call_powf)
8081                 emit_call_insn (gen_call_val_powf (dst, op, nb));
8082               else
8083                 emit_call_insn (gen_call_val_symref (dst, op, nb));
8084             }
8085         }
8086       else
8087         {
8088           rtx tmpreg = gen_rtx_REG (word_mode, 22);
8089           emit_move_insn (tmpreg, force_reg (word_mode, op));
8090           if (flag_pic)
8091             {
8092               rtx r4 = gen_rtx_REG (word_mode, 4);
8093               emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
8094             }
8095           else
8096             emit_call_insn (gen_call_val_reg (dst, nb));
8097         }
8098     }
8100   DONE;
8103 (define_insn "call_val_symref"
8104   [(set (match_operand 0 "" "")
8105         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8106               (match_operand 2 "" "i")))
8107    (clobber (reg:SI 1))
8108    (clobber (reg:SI 2))
8109    (use (const_int 0))]
8110   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8111   "*
8113   pa_output_arg_descriptor (insn);
8114   return pa_output_call (insn, operands[1], 0);
8116   [(set_attr "type" "call")
8117    (set (attr "length")
8118         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8119               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8121 ;; powf function clobbers %fr12
8122 (define_insn "call_val_powf"
8123   [(set (match_operand 0 "" "")
8124         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8125               (match_operand 2 "" "i")))
8126    (clobber (reg:SI 1))
8127    (clobber (reg:SI 2))
8128    (clobber (reg:DF 48))
8129    (use (const_int 1))]
8130   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8131   "*
8133   pa_output_arg_descriptor (insn);
8134   return pa_output_call (insn, operands[1], 0);
8136   [(set_attr "type" "call")
8137    (set (attr "length")
8138         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8139               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8141 (define_insn "call_val_symref_pic"
8142   [(set (match_operand 0 "" "")
8143         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8144               (match_operand 2 "" "i")))
8145    (clobber (reg:SI 1))
8146    (clobber (reg:SI 2))
8147    (clobber (match_operand 3))
8148    (use (reg:SI 19))
8149    (use (const_int 0))]
8150   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8151   "#")
8153 ;; Split out the PIC register save and restore after reload.  As the
8154 ;; split is done after reload, there are some situations in which we
8155 ;; unnecessarily save and restore %r4.  This happens when there is a
8156 ;; single call and the PIC register is not used after the call.
8158 ;; The split has to be done since call_from_call_insn () can't handle
8159 ;; the pattern as is.  Noreturn calls are special because they have to
8160 ;; terminate the basic block.  The split has to contain more than one
8161 ;; insn.
8162 (define_split
8163   [(parallel [(set (match_operand 0 "" "")
8164               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8165                     (match_operand 2 "" "")))
8166               (clobber (reg:SI 1))
8167               (clobber (reg:SI 2))
8168               (clobber (match_operand 3))
8169               (use (reg:SI 19))
8170               (use (const_int 0))])]
8171   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8172    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8173   [(set (match_dup 3) (reg:SI 19))
8174    (parallel [(set (match_dup 0)
8175               (call (mem:SI (match_dup 1))
8176                     (match_dup 2)))
8177               (clobber (reg:SI 1))
8178               (clobber (reg:SI 2))
8179               (use (reg:SI 19))
8180               (use (const_int 0))])]
8181   "")
8183 (define_split
8184   [(parallel [(set (match_operand 0 "" "")
8185               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8186                     (match_operand 2 "" "")))
8187               (clobber (reg:SI 1))
8188               (clobber (reg:SI 2))
8189               (clobber (match_operand 3))
8190               (use (reg:SI 19))
8191               (use (const_int 0))])]
8192   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8193   [(set (match_dup 3) (reg:SI 19))
8194    (parallel [(set (match_dup 0)
8195               (call (mem:SI (match_dup 1))
8196                     (match_dup 2)))
8197               (clobber (reg:SI 1))
8198               (clobber (reg:SI 2))
8199               (use (reg:SI 19))
8200               (use (const_int 0))])
8201    (set (reg:SI 19) (match_dup 3))]
8202   "")
8204 (define_insn "*call_val_symref_pic_post_reload"
8205   [(set (match_operand 0 "" "")
8206         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8207               (match_operand 2 "" "i")))
8208    (clobber (reg:SI 1))
8209    (clobber (reg:SI 2))
8210    (use (reg:SI 19))
8211    (use (const_int 0))]
8212   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8213   "*
8215   pa_output_arg_descriptor (insn);
8216   return pa_output_call (insn, operands[1], 0);
8218   [(set_attr "type" "call")
8219    (set (attr "length")
8220         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8221               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8223 ;; powf function clobbers %fr12
8224 (define_insn "call_val_powf_pic"
8225   [(set (match_operand 0 "" "")
8226         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8227               (match_operand 2 "" "i")))
8228    (clobber (reg:SI 1))
8229    (clobber (reg:SI 2))
8230    (clobber (reg:DF 48))
8231    (clobber (match_operand 3))
8232    (use (reg:SI 19))
8233    (use (const_int 1))]
8234   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8235   "#")
8237 ;; Split out the PIC register save and restore after reload.  As the
8238 ;; split is done after reload, there are some situations in which we
8239 ;; unnecessarily save and restore %r4.  This happens when there is a
8240 ;; single call and the PIC register is not used after the call.
8242 ;; The split has to be done since call_from_call_insn () can't handle
8243 ;; the pattern as is.  Noreturn calls are special because they have to
8244 ;; terminate the basic block.  The split has to contain more than one
8245 ;; insn.
8246 (define_split
8247   [(parallel [(set (match_operand 0 "" "")
8248               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8249                     (match_operand 2 "" "")))
8250               (clobber (reg:SI 1))
8251               (clobber (reg:SI 2))
8252               (clobber (reg:DF 48))
8253               (clobber (match_operand 3))
8254               (use (reg:SI 19))
8255               (use (const_int 1))])]
8256   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8257    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8258   [(set (match_dup 3) (reg:SI 19))
8259    (parallel [(set (match_dup 0)
8260               (call (mem:SI (match_dup 1))
8261                     (match_dup 2)))
8262               (clobber (reg:SI 1))
8263               (clobber (reg:SI 2))
8264               (clobber (reg:DF 48))
8265               (use (reg:SI 19))
8266               (use (const_int 1))])]
8267   "")
8269 (define_split
8270   [(parallel [(set (match_operand 0 "" "")
8271               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8272                     (match_operand 2 "" "")))
8273               (clobber (reg:SI 1))
8274               (clobber (reg:SI 2))
8275               (clobber (reg:DF 48))
8276               (clobber (match_operand 3))
8277               (use (reg:SI 19))
8278               (use (const_int 1))])]
8279   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8280   [(set (match_dup 3) (reg:SI 19))
8281    (parallel [(set (match_dup 0)
8282               (call (mem:SI (match_dup 1))
8283                     (match_dup 2)))
8284               (clobber (reg:SI 1))
8285               (clobber (reg:SI 2))
8286               (clobber (reg:DF 48))
8287               (use (reg:SI 19))
8288               (use (const_int 1))])
8289    (set (reg:SI 19) (match_dup 3))]
8290   "")
8292 (define_insn "*call_val_powf_pic_post_reload"
8293   [(set (match_operand 0 "" "")
8294         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8295               (match_operand 2 "" "i")))
8296    (clobber (reg:SI 1))
8297    (clobber (reg:SI 2))
8298    (clobber (reg:DF 48))
8299    (use (reg:SI 19))
8300    (use (const_int 1))]
8301   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8302   "*
8304   pa_output_arg_descriptor (insn);
8305   return pa_output_call (insn, operands[1], 0);
8307   [(set_attr "type" "call")
8308    (set (attr "length")
8309         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8310               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8312 ;; This pattern is split if it is necessary to save and restore the
8313 ;; PIC register.
8314 (define_insn "call_val_symref_64bit"
8315   [(set (match_operand 0 "" "")
8316         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8317               (match_operand 2 "" "i")))
8318    (clobber (reg:DI 1))
8319    (clobber (reg:DI 2))
8320    (clobber (match_operand 3))
8321    (use (reg:DI 27))
8322    (use (reg:DI 29))
8323    (use (const_int 0))]
8324   "TARGET_64BIT"
8325   "#")
8327 ;; Split out the PIC register save and restore after reload.  As the
8328 ;; split is done after reload, there are some situations in which we
8329 ;; unnecessarily save and restore %r4.  This happens when there is a
8330 ;; single call and the PIC register is not used after the call.
8332 ;; The split has to be done since call_from_call_insn () can't handle
8333 ;; the pattern as is.  Noreturn calls are special because they have to
8334 ;; terminate the basic block.  The split has to contain more than one
8335 ;; insn.
8336 (define_split
8337   [(parallel [(set (match_operand 0 "" "")
8338               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8339                     (match_operand 2 "" "")))
8340               (clobber (reg:DI 1))
8341               (clobber (reg:DI 2))
8342               (clobber (match_operand 3))
8343               (use (reg:DI 27))
8344               (use (reg:DI 29))
8345               (use (const_int 0))])]
8346   "TARGET_64BIT && reload_completed
8347    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8348   [(set (match_dup 3) (reg:DI 27))
8349    (parallel [(set (match_dup 0)
8350               (call (mem:SI (match_dup 1))
8351                     (match_dup 2)))
8352               (clobber (reg:DI 1))
8353               (clobber (reg:DI 2))
8354               (use (reg:DI 27))
8355               (use (reg:DI 29))
8356               (use (const_int 0))])]
8357   "")
8359 (define_split
8360   [(parallel [(set (match_operand 0 "" "")
8361               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8362                     (match_operand 2 "" "")))
8363               (clobber (reg:DI 1))
8364               (clobber (reg:DI 2))
8365               (clobber (match_operand 3))
8366               (use (reg:DI 27))
8367               (use (reg:DI 29))
8368               (use (const_int 0))])]
8369   "TARGET_64BIT && reload_completed"
8370   [(set (match_dup 3) (reg:DI 27))
8371    (parallel [(set (match_dup 0)
8372               (call (mem:SI (match_dup 1))
8373                     (match_dup 2)))
8374               (clobber (reg:DI 1))
8375               (clobber (reg:DI 2))
8376               (use (reg:DI 27))
8377               (use (reg:DI 29))
8378               (use (const_int 0))])
8379    (set (reg:DI 27) (match_dup 3))]
8380   "")
8382 (define_insn "*call_val_symref_64bit_post_reload"
8383   [(set (match_operand 0 "" "")
8384         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8385               (match_operand 2 "" "i")))
8386    (clobber (reg:DI 1))
8387    (clobber (reg:DI 2))
8388    (use (reg:DI 27))
8389    (use (reg:DI 29))
8390    (use (const_int 0))]
8391   "TARGET_64BIT"
8392   "*
8394   return pa_output_call (insn, operands[1], 0);
8396   [(set_attr "type" "call")
8397    (set (attr "length")
8398         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8399               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8401 ;; powf function clobbers %fr12
8402 (define_insn "call_val_powf_64bit"
8403   [(set (match_operand 0 "" "")
8404         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8405               (match_operand 2 "" "i")))
8406    (clobber (reg:DI 1))
8407    (clobber (reg:DI 2))
8408    (clobber (reg:DF 40))
8409    (clobber (match_operand 3))
8410    (use (reg:DI 27))
8411    (use (reg:DI 29))
8412    (use (const_int 1))]
8413   "TARGET_64BIT && TARGET_HPUX"
8414   "#")
8416 ;; Split out the PIC register save and restore after reload.  As the
8417 ;; split is done after reload, there are some situations in which we
8418 ;; unnecessarily save and restore %r4.  This happens when there is a
8419 ;; single call and the PIC register is not used after the call.
8421 ;; The split has to be done since call_from_call_insn () can't handle
8422 ;; the pattern as is.  Noreturn calls are special because they have to
8423 ;; terminate the basic block.  The split has to contain more than one
8424 ;; insn.
8425 (define_split
8426   [(parallel [(set (match_operand 0 "" "")
8427               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8428                     (match_operand 2 "" "")))
8429               (clobber (reg:DI 1))
8430               (clobber (reg:DI 2))
8431               (clobber (reg:DF 40))
8432               (clobber (match_operand 3))
8433               (use (reg:DI 27))
8434               (use (reg:DI 29))
8435               (use (const_int 1))])]
8436   "TARGET_64BIT && TARGET_HPUX && reload_completed
8437    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8438   [(set (match_dup 3) (reg:DI 27))
8439    (parallel [(set (match_dup 0)
8440               (call (mem:SI (match_dup 1))
8441                     (match_dup 2)))
8442               (clobber (reg:DI 1))
8443               (clobber (reg:DI 2))
8444               (clobber (reg:DF 40))
8445               (use (reg:DI 27))
8446               (use (reg:DI 29))
8447               (use (const_int 1))])]
8448   "")
8450 (define_split
8451   [(parallel [(set (match_operand 0 "" "")
8452               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8453                     (match_operand 2 "" "")))
8454               (clobber (reg:DI 1))
8455               (clobber (reg:DI 2))
8456               (clobber (reg:DF 40))
8457               (clobber (match_operand 3))
8458               (use (reg:DI 27))
8459               (use (reg:DI 29))
8460               (use (const_int 1))])]
8461   "TARGET_64BIT && TARGET_HPUX && reload_completed"
8462   [(set (match_dup 3) (reg:DI 27))
8463    (parallel [(set (match_dup 0)
8464               (call (mem:SI (match_dup 1))
8465                     (match_dup 2)))
8466               (clobber (reg:DI 1))
8467               (clobber (reg:DI 2))
8468               (clobber (reg:DF 40))
8469               (use (reg:DI 27))
8470               (use (reg:DI 29))
8471               (use (const_int 1))])
8472    (set (reg:DI 27) (match_dup 3))]
8473   "")
8475 (define_insn "*call_val_powf_64bit_post_reload"
8476   [(set (match_operand 0 "" "")
8477         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8478               (match_operand 2 "" "i")))
8479    (clobber (reg:DI 1))
8480    (clobber (reg:DI 2))
8481    (clobber (reg:DF 40))
8482    (use (reg:DI 27))
8483    (use (reg:DI 29))
8484    (use (const_int 1))]
8485   "TARGET_64BIT && TARGET_HPUX"
8486   "*
8488   return pa_output_call (insn, operands[1], 0);
8490   [(set_attr "type" "call")
8491    (set (attr "length")
8492         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8493               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8495 (define_insn "call_val_reg"
8496   [(set (match_operand 0 "" "")
8497         (call (mem:SI (reg:SI 22))
8498               (match_operand 1 "" "i")))
8499    (clobber (reg:SI 1))
8500    (clobber (reg:SI 2))
8501    (use (const_int 1))]
8502   "!TARGET_64BIT"
8503   "*
8505   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8507   [(set_attr "type" "dyncall")
8508    (set (attr "length")
8509         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8510               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8512 ;; This pattern is split if it is necessary to save and restore the
8513 ;; PIC register.
8514 (define_insn "call_val_reg_pic"
8515   [(set (match_operand 0 "" "")
8516         (call (mem:SI (reg:SI 22))
8517               (match_operand 1 "" "i")))
8518    (clobber (reg:SI 1))
8519    (clobber (reg:SI 2))
8520    (clobber (match_operand 2))
8521    (use (reg:SI 19))
8522    (use (const_int 1))]
8523   "!TARGET_64BIT"
8524   "#")
8526 ;; Split out the PIC register save and restore after reload.  As the
8527 ;; split is done after reload, there are some situations in which we
8528 ;; unnecessarily save and restore %r4.  This happens when there is a
8529 ;; single call and the PIC register is not used after the call.
8531 ;; The split has to be done since call_from_call_insn () can't handle
8532 ;; the pattern as is.  Noreturn calls are special because they have to
8533 ;; terminate the basic block.  The split has to contain more than one
8534 ;; insn.
8535 (define_split
8536   [(parallel [(set (match_operand 0 "" "")
8537                    (call (mem:SI (reg:SI 22))
8538                          (match_operand 1 "" "")))
8539               (clobber (reg:SI 1))
8540               (clobber (reg:SI 2))
8541               (clobber (match_operand 2))
8542               (use (reg:SI 19))
8543               (use (const_int 1))])]
8544   "!TARGET_64BIT && reload_completed
8545    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8546   [(set (match_dup 2) (reg:SI 19))
8547    (parallel [(set (match_dup 0)
8548                    (call (mem:SI (reg:SI 22))
8549                          (match_dup 1)))
8550               (clobber (reg:SI 1))
8551               (clobber (reg:SI 2))
8552               (use (reg:SI 19))
8553               (use (const_int 1))])]
8554   "")
8556 (define_split
8557   [(parallel [(set (match_operand 0 "" "")
8558                    (call (mem:SI (reg:SI 22))
8559                          (match_operand 1 "" "")))
8560               (clobber (reg:SI 1))
8561               (clobber (reg:SI 2))
8562               (clobber (match_operand 2))
8563               (use (reg:SI 19))
8564               (use (const_int 1))])]
8565   "!TARGET_64BIT && reload_completed"
8566   [(set (match_dup 2) (reg:SI 19))
8567    (parallel [(set (match_dup 0)
8568                    (call (mem:SI (reg:SI 22))
8569                          (match_dup 1)))
8570               (clobber (reg:SI 1))
8571               (clobber (reg:SI 2))
8572               (use (reg:SI 19))
8573               (use (const_int 1))])
8574    (set (reg:SI 19) (match_dup 2))]
8575   "")
8577 (define_insn "*call_val_reg_pic_post_reload"
8578   [(set (match_operand 0 "" "")
8579         (call (mem:SI (reg:SI 22))
8580               (match_operand 1 "" "i")))
8581    (clobber (reg:SI 1))
8582    (clobber (reg:SI 2))
8583    (use (reg:SI 19))
8584    (use (const_int 1))]
8585   "!TARGET_64BIT"
8586   "*
8588   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8590   [(set_attr "type" "dyncall")
8591    (set (attr "length")
8592         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8593               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8595 ;; This pattern is split if it is necessary to save and restore the
8596 ;; PIC register.
8597 (define_insn "call_val_reg_64bit"
8598   [(set (match_operand 0 "" "")
8599         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8600               (match_operand 2 "" "i")))
8601    (clobber (reg:DI 2))
8602    (clobber (match_operand 3))
8603    (use (reg:DI 27))
8604    (use (reg:DI 29))
8605    (use (const_int 1))]
8606   "TARGET_64BIT"
8607   "#")
8609 ;; Split out the PIC register save and restore after reload.  As the
8610 ;; split is done after reload, there are some situations in which we
8611 ;; unnecessarily save and restore %r4.  This happens when there is a
8612 ;; single call and the PIC register is not used after the call.
8614 ;; The split has to be done since call_from_call_insn () can't handle
8615 ;; the pattern as is.  Noreturn calls are special because they have to
8616 ;; terminate the basic block.  The split has to contain more than one
8617 ;; insn.
8618 (define_split
8619   [(parallel [(set (match_operand 0 "" "")
8620                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8621                          (match_operand 2 "" "")))
8622               (clobber (reg:DI 2))
8623               (clobber (match_operand 3))
8624               (use (reg:DI 27))
8625               (use (reg:DI 29))
8626               (use (const_int 1))])]
8627   "TARGET_64BIT && reload_completed
8628    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8629   [(set (match_dup 3) (reg:DI 27))
8630    (parallel [(set (match_dup 0)
8631                    (call (mem:SI (match_dup 1))
8632                          (match_dup 2)))
8633               (clobber (reg:DI 2))
8634               (use (reg:DI 27))
8635               (use (reg:DI 29))
8636               (use (const_int 1))])]
8637   "")
8639 (define_split
8640   [(parallel [(set (match_operand 0 "" "")
8641                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8642                          (match_operand 2 "" "")))
8643               (clobber (reg:DI 2))
8644               (clobber (match_operand 3))
8645               (use (reg:DI 27))
8646               (use (reg:DI 29))
8647               (use (const_int 1))])]
8648   "TARGET_64BIT && reload_completed"
8649   [(set (match_dup 3) (reg:DI 27))
8650    (parallel [(set (match_dup 0)
8651                    (call (mem:SI (match_dup 1))
8652                          (match_dup 2)))
8653               (clobber (reg:DI 2))
8654               (use (reg:DI 27))
8655               (use (reg:DI 29))
8656               (use (const_int 1))])
8657    (set (reg:DI 27) (match_dup 3))]
8658   "")
8660 (define_insn "*call_val_reg_64bit_post_reload"
8661   [(set (match_operand 0 "" "")
8662         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8663               (match_operand 2 "" "i")))
8664    (clobber (reg:DI 2))
8665    (use (reg:DI 27))
8666    (use (reg:DI 29))
8667    (use (const_int 1))]
8668   "TARGET_64BIT"
8669   "*
8671   return pa_output_indirect_call (insn, operands[1]);
8673   [(set_attr "type" "dyncall")
8674    (set (attr "length")
8675         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8676               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8678 /* Expand special pc-relative call to _mcount.  */
8680 (define_expand "call_mcount"
8681   [(parallel [(call (match_operand:SI 0 "" "")
8682                     (match_operand 1 "" ""))
8683               (set (reg:SI 25)
8684                    (plus:SI (reg:SI 2)
8685                             (minus:SI (match_operand 2 "" "")
8686                                       (plus:SI (pc) (const_int 4)))))
8687               (clobber (reg:SI 2))])]
8688   "!TARGET_PORTABLE_RUNTIME"
8689   "
8691   rtx op = XEXP (operands[0], 0);
8692   rtx nb = operands[1];
8693   rtx lab = operands[2];
8695   if (TARGET_64BIT)
8696     {
8697       rtx r4 = gen_rtx_REG (word_mode, 4);
8698       emit_move_insn (arg_pointer_rtx,
8699                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8700                                     GEN_INT (64)));
8701       emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8702     }
8703   else
8704     {
8705       if (flag_pic)
8706         {
8707           rtx r4 = gen_rtx_REG (word_mode, 4);
8708           emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8709         }
8710       else
8711         emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8712     }
8714   DONE;
8717 (define_insn "call_mcount_nonpic"
8718   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8719          (match_operand 1 "" "i"))
8720    (set (reg:SI 25)
8721         (plus:SI (reg:SI 2)
8722                  (minus:SI (match_operand 2 "" "")
8723                            (plus:SI (pc) (const_int 4)))))
8724    (clobber (reg:SI 2))]
8725   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8726   "*
8728   pa_output_arg_descriptor (insn);
8729   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8731   [(set_attr "type" "multi")
8732    (set_attr "length" "8")])
8734 (define_insn "call_mcount_pic"
8735   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8736          (match_operand 1 "" "i"))
8737    (set (reg:SI 25)
8738         (plus:SI (reg:SI 2)
8739                  (minus:SI (match_operand 2 "" "")
8740                            (plus:SI (pc) (const_int 4)))))
8741    (clobber (reg:SI 2))
8742    (clobber (match_operand 3))
8743    (use (reg:SI 19))]
8744   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8745   "#")
8747 (define_split
8748   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8749                     (match_operand 1 "" ""))
8750               (set (reg:SI 25)
8751                    (plus:SI (reg:SI 2)
8752                             (minus:SI (match_operand 2 "" "")
8753                                       (plus:SI (pc) (const_int 4)))))
8754               (clobber (reg:SI 2))
8755               (clobber (match_operand 3))
8756               (use (reg:SI 19))])]
8757   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8758   [(set (match_dup 3) (reg:SI 19))
8759    (parallel [(call (mem:SI (match_dup 0))
8760                     (match_dup 1))
8761               (set (reg:SI 25)
8762                    (plus:SI (reg:SI 2)
8763                             (minus:SI (match_dup 2)
8764                                       (plus:SI (pc) (const_int 4)))))
8765               (clobber (reg:SI 2))
8766               (use (reg:SI 19))])
8767    (set (reg:SI 19) (match_dup 3))]
8768   "")
8770 (define_insn "*call_mcount_pic_post_reload"
8771   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8772          (match_operand 1 "" "i"))
8773    (set (reg:SI 25)
8774         (plus:SI (reg:SI 2)
8775                  (minus:SI (match_operand 2 "" "")
8776                            (plus:SI (pc) (const_int 4)))))
8777    (clobber (reg:SI 2))
8778    (use (reg:SI 19))]
8779   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8780   "*
8782   pa_output_arg_descriptor (insn);
8783   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8785   [(set_attr "type" "multi")
8786    (set_attr "length" "8")])
8788 (define_insn "call_mcount_64bit"
8789   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8790          (match_operand 1 "" "i"))
8791    (set (reg:SI 25)
8792         (plus:SI (reg:SI 2)
8793                  (minus:SI (match_operand 2 "" "")
8794                            (plus:SI (pc) (const_int 4)))))
8795    (clobber (reg:DI 2))
8796    (clobber (match_operand 3))
8797    (use (reg:DI 27))
8798    (use (reg:DI 29))]
8799   "TARGET_64BIT"
8800   "#")
8802 (define_split
8803   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8804                     (match_operand 1 "" ""))
8805               (set (reg:SI 25)
8806                    (plus:SI (reg:SI 2)
8807                             (minus:SI (match_operand 2 "" "")
8808                                       (plus:SI (pc) (const_int 4)))))
8809               (clobber (reg:DI 2))
8810               (clobber (match_operand 3))
8811               (use (reg:DI 27))
8812               (use (reg:DI 29))])]
8813   "TARGET_64BIT && reload_completed"
8814   [(set (match_dup 3) (reg:DI 27))
8815    (parallel [(call (mem:SI (match_dup 0))
8816                     (match_dup 1))
8817               (set (reg:SI 25)
8818                    (plus:SI (reg:SI 2)
8819                             (minus:SI (match_dup 2)
8820                                       (plus:SI (pc) (const_int 4)))))
8821               (clobber (reg:DI 2))
8822               (use (reg:DI 27))
8823               (use (reg:DI 29))])
8824    (set (reg:DI 27) (match_dup 3))]
8825   "")
8827 (define_insn "*call_mcount_64bit_post_reload"
8828   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8829          (match_operand 1 "" "i"))
8830    (set (reg:SI 25)
8831         (plus:SI (reg:SI 2)
8832                  (minus:SI (match_operand 2 "" "")
8833                            (plus:SI (pc) (const_int 4)))))
8834    (clobber (reg:DI 2))
8835    (use (reg:DI 27))
8836    (use (reg:DI 29))]
8837   "TARGET_64BIT"
8838   "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8839   [(set_attr "type" "multi")
8840    (set_attr "length" "8")])
8842 ;; Call subroutine returning any type.
8844 (define_expand "untyped_call"
8845   [(parallel [(call (match_operand 0 "" "")
8846                     (const_int 0))
8847               (match_operand 1 "" "")
8848               (match_operand 2 "" "")])]
8849   ""
8850   "
8852   int i;
8854   emit_call_insn (gen_call (operands[0], const0_rtx));
8856   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8857     {
8858       rtx set = XVECEXP (operands[2], 0, i);
8859       emit_move_insn (SET_DEST (set), SET_SRC (set));
8860     }
8862   /* The optimizer does not know that the call sets the function value
8863      registers we stored in the result block.  We avoid problems by
8864      claiming that all hard registers are used and clobbered at this
8865      point.  */
8866   emit_insn (gen_blockage ());
8868   DONE;
8871 (define_expand "sibcall"
8872   [(call (match_operand:SI 0 "" "")
8873          (match_operand 1 "" ""))]
8874   "!TARGET_PORTABLE_RUNTIME"
8875   "
8877   rtx op, call_insn;
8878   rtx nb = operands[1];
8880   op = XEXP (operands[0], 0);
8882   if (TARGET_64BIT)
8883     {
8884       if (!virtuals_instantiated)
8885         emit_move_insn (arg_pointer_rtx,
8886                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8887                                       GEN_INT (64)));
8888       else
8889         {
8890           /* The loop pass can generate new libcalls after the virtual
8891              registers are instantiated when fpregs are disabled because
8892              the only method that we have for doing DImode multiplication
8893              is with a libcall.  This could be trouble if we haven't
8894              allocated enough space for the outgoing arguments.  */
8895           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8897           emit_move_insn (arg_pointer_rtx,
8898                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8899                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8900         }
8901     }
8903   /* Indirect sibling calls are not allowed.  */
8904   if (TARGET_64BIT)
8905     call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8906   else
8907     call_insn = gen_sibcall_internal_symref (op, operands[1]);
8909   call_insn = emit_call_insn (call_insn);
8911   if (TARGET_64BIT)
8912     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8914   /* We don't have to restore the PIC register.  */
8915   if (flag_pic)
8916     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8918   DONE;
8921 (define_insn "sibcall_internal_symref"
8922   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8923          (match_operand 1 "" "i"))
8924    (clobber (reg:SI 1))
8925    (use (reg:SI 2))
8926    (use (const_int 0))]
8927   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8928   "*
8930   pa_output_arg_descriptor (insn);
8931   return pa_output_call (insn, operands[0], 1);
8933   [(set_attr "type" "sibcall")
8934    (set (attr "length")
8935         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8936               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8938 (define_insn "sibcall_internal_symref_64bit"
8939   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8940          (match_operand 1 "" "i"))
8941    (clobber (reg:DI 1))
8942    (use (reg:DI 2))
8943    (use (const_int 0))]
8944   "TARGET_64BIT"
8945   "*
8947   return pa_output_call (insn, operands[0], 1);
8949   [(set_attr "type" "sibcall")
8950    (set (attr "length")
8951         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8952               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8954 (define_expand "sibcall_value"
8955   [(set (match_operand 0 "" "")
8956                    (call (match_operand:SI 1 "" "")
8957                          (match_operand 2 "" "")))]
8958   "!TARGET_PORTABLE_RUNTIME"
8959   "
8961   rtx op, call_insn;
8962   rtx nb = operands[1];
8964   op = XEXP (operands[1], 0);
8966   if (TARGET_64BIT)
8967     {
8968       if (!virtuals_instantiated)
8969         emit_move_insn (arg_pointer_rtx,
8970                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8971                                       GEN_INT (64)));
8972       else
8973         {
8974           /* The loop pass can generate new libcalls after the virtual
8975              registers are instantiated when fpregs are disabled because
8976              the only method that we have for doing DImode multiplication
8977              is with a libcall.  This could be trouble if we haven't
8978              allocated enough space for the outgoing arguments.  */
8979           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8981           emit_move_insn (arg_pointer_rtx,
8982                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8983                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8984         }
8985     }
8987   /* Indirect sibling calls are not allowed.  */
8988   if (TARGET_64BIT)
8989     call_insn
8990       = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8991   else
8992     call_insn
8993       = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8995   call_insn = emit_call_insn (call_insn);
8997   if (TARGET_64BIT)
8998     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
9000   /* We don't have to restore the PIC register.  */
9001   if (flag_pic)
9002     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
9004   DONE;
9007 (define_insn "sibcall_value_internal_symref"
9008   [(set (match_operand 0 "" "")
9009         (call (mem:SI (match_operand 1 "call_operand_address" ""))
9010               (match_operand 2 "" "i")))
9011    (clobber (reg:SI 1))
9012    (use (reg:SI 2))
9013    (use (const_int 0))]
9014   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9015   "*
9017   pa_output_arg_descriptor (insn);
9018   return pa_output_call (insn, operands[1], 1);
9020   [(set_attr "type" "sibcall")
9021    (set (attr "length")
9022         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9023               (symbol_ref "pa_attr_length_call (insn, 1)")))])
9025 (define_insn "sibcall_value_internal_symref_64bit"
9026   [(set (match_operand 0 "" "")
9027         (call (mem:SI (match_operand 1 "call_operand_address" ""))
9028               (match_operand 2 "" "i")))
9029    (clobber (reg:DI 1))
9030    (use (reg:DI 2))
9031    (use (const_int 0))]
9032   "TARGET_64BIT"
9033   "*
9035   return pa_output_call (insn, operands[1], 1);
9037   [(set_attr "type" "sibcall")
9038    (set (attr "length")
9039         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9040               (symbol_ref "pa_attr_length_call (insn, 1)")))])
9042 (define_insn "nop"
9043   [(const_int 0)]
9044   ""
9045   "nop"
9046   [(set_attr "type" "move")
9047    (set_attr "length" "4")])
9049 ;;; EH does longjmp's from and within the data section.  Thus,
9050 ;;; an interspace branch is required for the longjmp implementation.
9051 ;;; Registers r1 and r2 are used as scratch registers for the jump
9052 ;;; when necessary.
9053 (define_expand "interspace_jump"
9054   [(parallel
9055      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9056       (clobber (match_dup 1))])]
9057   ""
9058   "
9060   operands[1] = gen_rtx_REG (word_mode, 2);
9063 (define_insn ""
9064   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9065   (clobber (reg:SI 2))]
9066   "TARGET_PA_20 && !TARGET_64BIT"
9067   "bve%* (%0)"
9068    [(set_attr "type" "branch")
9069     (set_attr "length" "4")])
9071 (define_insn ""
9072   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9073   (clobber (reg:SI 2))]
9074   "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
9075   "be%* 0(%%sr4,%0)"
9076    [(set_attr "type" "branch")
9077     (set_attr "length" "4")])
9079 (define_insn ""
9080   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9081   (clobber (reg:SI 2))]
9082   "!TARGET_64BIT"
9083   "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
9084    [(set_attr "type" "branch")
9085     (set_attr "length" "12")])
9087 (define_insn ""
9088   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9089   (clobber (reg:DI 2))]
9090   "TARGET_64BIT"
9091   "bve%* (%0)"
9092    [(set_attr "type" "branch")
9093     (set_attr "length" "4")])
9095 (define_expand "builtin_longjmp"
9096   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
9097   ""
9098   "
9100   /* The elements of the buffer are, in order:  */
9101   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9102   rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9103                          POINTER_SIZE / BITS_PER_UNIT));
9104   rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9105                            (POINTER_SIZE * 2) / BITS_PER_UNIT));
9106   rtx pv = gen_rtx_REG (Pmode, 1);
9108   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
9109   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
9111   /* Load the label we are jumping through into r1 so that we know
9112      where to look for it when we get back to setjmp's function for
9113      restoring the gp.  */
9114   emit_move_insn (pv, lab);
9116   /* Restore the stack and frame pointers.  */
9117   fp = copy_to_reg (fp);
9118   emit_stack_restore (SAVE_NONLOCAL, stack);
9120   /* Ensure the frame pointer move is not optimized.  */
9121   emit_insn (gen_blockage ());
9122   emit_clobber (hard_frame_pointer_rtx);
9123   emit_clobber (frame_pointer_rtx);
9124   emit_move_insn (hard_frame_pointer_rtx, fp);
9126   emit_use (hard_frame_pointer_rtx);
9127   emit_use (stack_pointer_rtx);
9129   /* Prevent the insns above from being scheduled into the delay slot
9130      of the interspace jump because the space register could change.  */
9131   emit_insn (gen_blockage ());
9133   emit_jump_insn (gen_interspace_jump (pv));
9134   emit_barrier ();
9135   DONE;
9138 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
9139 (define_expand "extzvsi"
9140   [(set (match_operand:SI 0 "register_operand" "")
9141         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
9142                          (match_operand:SI 2 "uint5_operand" "")
9143                          (match_operand:SI 3 "uint5_operand" "")))]
9144   ""
9145   "
9147   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9148   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9150   /* PA extraction insns don't support zero length bitfields or fields
9151      extending beyond the left or right-most bits.  Also, the predicate
9152      rejects lengths equal to a word as they are better handled by
9153      the move patterns.  */
9154   if (len == 0 || pos + len > 32)
9155     FAIL;
9157   /* From mips.md: extract_bit_field doesn't verify that our source
9158      matches the predicate, so check it again here.  */
9159   if (!register_operand (operands[1], VOIDmode))
9160     FAIL;
9162   emit_insn (gen_extzv_32 (operands[0], operands[1],
9163                            operands[2], operands[3]));
9164   DONE;
9167 (define_insn "extzv_32"
9168   [(set (match_operand:SI 0 "register_operand" "=r")
9169         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9170                          (match_operand:SI 2 "uint5_operand" "")
9171                          (match_operand:SI 3 "uint5_operand" "")))]
9172   "UINTVAL (operands[2]) > 0
9173    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9174   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9175   [(set_attr "type" "shift")
9176    (set_attr "length" "4")])
9178 (define_insn ""
9179   [(set (match_operand:SI 0 "register_operand" "=r")
9180         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9181                          (const_int 1)
9182                          (match_operand:SI 2 "register_operand" "q")))]
9183   ""
9184   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9185   [(set_attr "type" "shift")
9186    (set_attr "length" "4")])
9188 (define_expand "extzvdi"
9189   [(set (match_operand:DI 0 "register_operand" "")
9190         (zero_extract:DI (match_operand:DI 1 "register_operand" "")
9191                          (match_operand:DI 2 "uint6_operand" "")
9192                          (match_operand:DI 3 "uint6_operand" "")))]
9193   "TARGET_64BIT"
9194   "
9196   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9197   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9199   /* PA extraction insns don't support zero length bitfields or fields
9200      extending beyond the left or right-most bits.  Also, the predicate
9201      rejects lengths equal to a doubleword as they are better handled by
9202      the move patterns.  */
9203   if (len == 0 || pos + len > 64)
9204     FAIL;
9206   /* From mips.md: extract_bit_field doesn't verify that our source
9207      matches the predicate, so check it again here.  */
9208   if (!register_operand (operands[1], VOIDmode))
9209     FAIL;
9211   emit_insn (gen_extzv_64 (operands[0], operands[1],
9212                            operands[2], operands[3]));
9213   DONE;
9216 (define_insn "extzv_64"
9217   [(set (match_operand:DI 0 "register_operand" "=r")
9218         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9219                          (match_operand:DI 2 "uint6_operand" "")
9220                          (match_operand:DI 3 "uint6_operand" "")))]
9221   "TARGET_64BIT
9222    && UINTVAL (operands[2]) > 0
9223    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9224   "extrd,u %1,%3+%2-1,%2,%0"
9225   [(set_attr "type" "shift")
9226    (set_attr "length" "4")])
9228 (define_insn ""
9229   [(set (match_operand:DI 0 "register_operand" "=r")
9230         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9231                          (const_int 1)
9232                          (match_operand:DI 2 "register_operand" "q")))]
9233   "TARGET_64BIT"
9234   "extrd,u %1,%%sar,1,%0"
9235   [(set_attr "type" "shift")
9236    (set_attr "length" "4")])
9238 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
9239 (define_expand "extvsi"
9240   [(set (match_operand:SI 0 "register_operand" "")
9241         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9242                          (match_operand:SI 2 "uint5_operand" "")
9243                          (match_operand:SI 3 "uint5_operand" "")))]
9244   ""
9245   "
9247   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9248   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9250   /* PA extraction insns don't support zero length bitfields or fields
9251      extending beyond the left or right-most bits.  Also, the predicate
9252      rejects lengths equal to a word as they are better handled by
9253      the move patterns.  */
9254   if (len == 0 || pos + len > 32)
9255     FAIL;
9257   /* From mips.md: extract_bit_field doesn't verify that our source
9258      matches the predicate, so check it again here.  */
9259   if (!register_operand (operands[1], VOIDmode))
9260     FAIL;
9262   emit_insn (gen_extv_32 (operands[0], operands[1],
9263                           operands[2], operands[3]));
9264   DONE;
9267 (define_insn "extv_32"
9268   [(set (match_operand:SI 0 "register_operand" "=r")
9269         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9270                          (match_operand:SI 2 "uint5_operand" "")
9271                          (match_operand:SI 3 "uint5_operand" "")))]
9272   "UINTVAL (operands[2]) > 0
9273    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9274   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9275   [(set_attr "type" "shift")
9276    (set_attr "length" "4")])
9278 (define_insn ""
9279   [(set (match_operand:SI 0 "register_operand" "=r")
9280         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9281                          (const_int 1)
9282                          (match_operand:SI 2 "register_operand" "q")))]
9283   "!TARGET_64BIT"
9284   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9285   [(set_attr "type" "shift")
9286    (set_attr "length" "4")])
9288 (define_expand "extvdi"
9289   [(set (match_operand:DI 0 "register_operand" "")
9290         (sign_extract:DI (match_operand:DI 1 "register_operand" "")
9291                          (match_operand:DI 2 "uint6_operand" "")
9292                          (match_operand:DI 3 "uint6_operand" "")))]
9293   "TARGET_64BIT"
9294   "
9296   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9297   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9299   /* PA extraction insns don't support zero length bitfields or fields
9300      extending beyond the left or right-most bits.  Also, the predicate
9301      rejects lengths equal to a doubleword as they are better handled by
9302      the move patterns.  */
9303   if (len == 0 || pos + len > 64)
9304     FAIL;
9306   /* From mips.md: extract_bit_field doesn't verify that our source
9307      matches the predicate, so check it again here.  */
9308   if (!register_operand (operands[1], VOIDmode))
9309     FAIL;
9311   emit_insn (gen_extv_64 (operands[0], operands[1],
9312                           operands[2], operands[3]));
9313   DONE;
9316 (define_insn "extv_64"
9317   [(set (match_operand:DI 0 "register_operand" "=r")
9318         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9319                          (match_operand:DI 2 "uint6_operand" "")
9320                          (match_operand:DI 3 "uint6_operand" "")))]
9321   "TARGET_64BIT
9322    && UINTVAL (operands[2]) > 0
9323    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9324   "extrd,s %1,%3+%2-1,%2,%0"
9325   [(set_attr "type" "shift")
9326    (set_attr "length" "4")])
9328 (define_insn ""
9329   [(set (match_operand:DI 0 "register_operand" "=r")
9330         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9331                          (const_int 1)
9332                          (match_operand:DI 2 "register_operand" "q")))]
9333   "TARGET_64BIT"
9334   "extrd,s %1,%%sar,1,%0"
9335   [(set_attr "type" "shift")
9336    (set_attr "length" "4")])
9338 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
9339 (define_expand "insvsi"
9340   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9341                          (match_operand:SI 1 "uint5_operand" "")
9342                          (match_operand:SI 2 "uint5_operand" ""))
9343         (match_operand:SI 3 "arith5_operand" ""))]
9344   ""
9345   "
9347   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9348   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9350   /* PA insertion insns don't support zero length bitfields or fields
9351      extending beyond the left or right-most bits.  Also, the predicate
9352      rejects lengths equal to a word as they are better handled by
9353      the move patterns.  */
9354   if (len <= 0 || pos + len > 32)
9355     FAIL;
9357   /* From mips.md: insert_bit_field doesn't verify that our destination
9358      matches the predicate, so check it again here.  */
9359   if (!register_operand (operands[0], VOIDmode))
9360     FAIL;
9362   emit_insn (gen_insv_32 (operands[0], operands[1],
9363                           operands[2], operands[3]));
9364   DONE;
9367 (define_insn "insv_32"
9368   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9369                          (match_operand:SI 1 "uint5_operand" "")
9370                          (match_operand:SI 2 "uint5_operand" ""))
9371         (match_operand:SI 3 "arith5_operand" "r,L"))]
9372   "UINTVAL (operands[1]) > 0
9373    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9374   "@
9375    {dep|depw} %3,%2+%1-1,%1,%0
9376    {depi|depwi} %3,%2+%1-1,%1,%0"
9377   [(set_attr "type" "shift,shift")
9378    (set_attr "length" "4,4")])
9380 ;; Optimize insertion of const_int values of type 1...1xxxx.
9381 (define_insn ""
9382   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9383                          (match_operand:SI 1 "uint5_operand" "")
9384                          (match_operand:SI 2 "uint5_operand" ""))
9385         (match_operand:SI 3 "const_int_operand" ""))]
9386   "(INTVAL (operands[3]) & 0x10) != 0 &&
9387    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9388   "*
9390   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9391   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9393   [(set_attr "type" "shift")
9394    (set_attr "length" "4")])
9396 (define_expand "insvdi"
9397   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9398                          (match_operand:DI 1 "uint6_operand" "")
9399                          (match_operand:DI 2 "uint6_operand" ""))
9400         (match_operand:DI 3 "arith5_operand" ""))]
9401   "TARGET_64BIT"
9402   "
9404   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9405   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9407   /* PA insertion insns don't support zero length bitfields or fields
9408      extending beyond the left or right-most bits.  Also, the predicate
9409      rejects lengths equal to a doubleword as they are better handled by
9410      the move patterns.  */
9411   if (len <= 0 || pos + len > 64)
9412     FAIL;
9414   /* From mips.md: insert_bit_field doesn't verify that our destination
9415      matches the predicate, so check it again here.  */
9416   if (!register_operand (operands[0], VOIDmode))
9417     FAIL;
9419   emit_insn (gen_insv_64 (operands[0], operands[1],
9420                           operands[2], operands[3]));
9421   DONE;
9424 (define_insn "insv_64"
9425   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9426                          (match_operand:DI 1 "uint6_operand" "")
9427                          (match_operand:DI 2 "uint6_operand" ""))
9428         (match_operand:DI 3 "arith5_operand" "r,L"))]
9429   "TARGET_64BIT
9430    && UINTVAL (operands[1]) > 0
9431    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9432   "@
9433    depd %3,%2+%1-1,%1,%0
9434    depdi %3,%2+%1-1,%1,%0"
9435   [(set_attr "type" "shift,shift")
9436    (set_attr "length" "4,4")])
9438 ;; Optimize insertion of const_int values of type 1...1xxxx.
9439 (define_insn ""
9440   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9441                          (match_operand:DI 1 "uint6_operand" "")
9442                          (match_operand:DI 2 "uint6_operand" ""))
9443         (match_operand:DI 3 "const_int_operand" ""))]
9444   "(INTVAL (operands[3]) & 0x10) != 0
9445    && TARGET_64BIT
9446    && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9447   "*
9449   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9450   return \"depdi %3,%2+%1-1,%1,%0\";
9452   [(set_attr "type" "shift")
9453    (set_attr "length" "4")])
9455 (define_insn ""
9456   [(set (match_operand:DI 0 "register_operand" "=r")
9457         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9458                    (const_int 32)))]
9459   "TARGET_64BIT"
9460   "depd,z %1,31,32,%0"
9461   [(set_attr "type" "shift")
9462    (set_attr "length" "4")])
9464 ;; This insn is used for some loop tests, typically loops reversed when
9465 ;; strength reduction is used.  It is actually created when the instruction
9466 ;; combination phase combines the special loop test.  Since this insn
9467 ;; is both a jump insn and has an output, it must deal with its own
9468 ;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9469 ;; to not choose the register alternatives in the event a reload is needed.
9470 (define_insn "decrement_and_branch_until_zero"
9471   [(set (pc)
9472         (if_then_else
9473           (match_operator 2 "ordered_comparison_operator"
9474            [(plus:SI
9475               (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9476               (match_operand:SI 1 "int5_operand" "L,L,L"))
9477             (const_int 0)])
9478           (label_ref (match_operand 3 "" ""))
9479           (pc)))
9480    (set (match_dup 0)
9481         (plus:SI (match_dup 0) (match_dup 1)))
9482    (clobber (match_scratch:SI 4 "=X,r,r"))]
9483   ""
9484   "* return pa_output_dbra (operands, insn, which_alternative); "
9485 ;; Do not expect to understand this the first time through.
9486 [(set_attr "type" "cbranch,multi,multi")
9487  (set (attr "length")
9488       (if_then_else (eq_attr "alternative" "0")
9489 ;; Loop counter in register case
9490 ;; Short branch has length of 4
9491 ;; Long branch has length of 8, 20, 24 or 28
9492         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9493                (const_int MAX_12BIT_OFFSET))
9494            (const_int 4)
9495            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9496                (const_int MAX_17BIT_OFFSET))
9497            (const_int 8)
9498            (match_test "TARGET_PORTABLE_RUNTIME")
9499            (const_int 24)
9500            (not (match_test "flag_pic"))
9501            (const_int 20)]
9502           (const_int 28))
9504 ;; Loop counter in FP reg case.
9505 ;; Extra goo to deal with additional reload insns.
9506         (if_then_else (eq_attr "alternative" "1")
9507           (if_then_else (lt (match_dup 3) (pc))
9508              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9509                       (const_int MAX_12BIT_OFFSET))
9510                     (const_int 24)
9511                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9512                       (const_int MAX_17BIT_OFFSET))
9513                     (const_int 28)
9514                     (match_test "TARGET_PORTABLE_RUNTIME")
9515                     (const_int 44)
9516                     (not (match_test "flag_pic"))
9517                     (const_int 40)]
9518                   (const_int 48))
9519              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9520                       (const_int MAX_12BIT_OFFSET))
9521                     (const_int 24)
9522                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9523                       (const_int MAX_17BIT_OFFSET))
9524                     (const_int 28)
9525                     (match_test "TARGET_PORTABLE_RUNTIME")
9526                     (const_int 44)
9527                     (not (match_test "flag_pic"))
9528                     (const_int 40)]
9529                   (const_int 48)))
9531 ;; Loop counter in memory case.
9532 ;; Extra goo to deal with additional reload insns.
9533         (if_then_else (lt (match_dup 3) (pc))
9534              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9535                       (const_int MAX_12BIT_OFFSET))
9536                     (const_int 12)
9537                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9538                       (const_int MAX_17BIT_OFFSET))
9539                     (const_int 16)
9540                     (match_test "TARGET_PORTABLE_RUNTIME")
9541                     (const_int 32)
9542                     (not (match_test "flag_pic"))
9543                     (const_int 28)]
9544                   (const_int 36))
9545              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9546                       (const_int MAX_12BIT_OFFSET))
9547                     (const_int 12)
9548                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9549                       (const_int MAX_17BIT_OFFSET))
9550                     (const_int 16)
9551                     (match_test "TARGET_PORTABLE_RUNTIME")
9552                     (const_int 32)
9553                     (not (match_test "flag_pic"))
9554                     (const_int 28)]
9555                   (const_int 36))))))])
9557 (define_insn ""
9558   [(set (pc)
9559         (if_then_else
9560           (match_operator 2 "movb_comparison_operator"
9561            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9562           (label_ref (match_operand 3 "" ""))
9563           (pc)))
9564    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9565         (match_dup 1))]
9566   ""
9567 "* return pa_output_movb (operands, insn, which_alternative, 0); "
9568 ;; Do not expect to understand this the first time through.
9569 [(set_attr "type" "cbranch,multi,multi,multi")
9570  (set (attr "length")
9571       (if_then_else (eq_attr "alternative" "0")
9572 ;; Loop counter in register case
9573 ;; Short branch has length of 4
9574 ;; Long branch has length of 8, 20, 24 or 28
9575         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9576                (const_int MAX_12BIT_OFFSET))
9577            (const_int 4)
9578            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9579                (const_int MAX_17BIT_OFFSET))
9580            (const_int 8)
9581            (match_test "TARGET_PORTABLE_RUNTIME")
9582            (const_int 24)
9583            (not (match_test "flag_pic"))
9584            (const_int 20)]
9585           (const_int 28))
9587 ;; Loop counter in FP reg case.
9588 ;; Extra goo to deal with additional reload insns.
9589         (if_then_else (eq_attr "alternative" "1")
9590           (if_then_else (lt (match_dup 3) (pc))
9591              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9592                       (const_int MAX_12BIT_OFFSET))
9593                     (const_int 12)
9594                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9595                       (const_int MAX_17BIT_OFFSET))
9596                     (const_int 16)
9597                     (match_test "TARGET_PORTABLE_RUNTIME")
9598                     (const_int 32)
9599                     (not (match_test "flag_pic"))
9600                     (const_int 28)]
9601                   (const_int 36))
9602              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9603                       (const_int MAX_12BIT_OFFSET))
9604                     (const_int 12)
9605                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9606                       (const_int MAX_17BIT_OFFSET))
9607                     (const_int 16)
9608                     (match_test "TARGET_PORTABLE_RUNTIME")
9609                     (const_int 32)
9610                     (not (match_test "flag_pic"))
9611                     (const_int 28)]
9612                   (const_int 36)))
9614 ;; Loop counter in memory or sar case.
9615 ;; Extra goo to deal with additional reload insns.
9616         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9617                    (const_int MAX_12BIT_OFFSET))
9618                 (const_int 8)
9619                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9620                   (const_int MAX_17BIT_OFFSET))
9621                 (const_int 12)
9622                 (match_test "TARGET_PORTABLE_RUNTIME")
9623                 (const_int 28)
9624                 (not (match_test "flag_pic"))
9625                 (const_int 24)]
9626               (const_int 32)))))])
9628 ;; Handle negated branch.
9629 (define_insn ""
9630   [(set (pc)
9631         (if_then_else
9632           (match_operator 2 "movb_comparison_operator"
9633            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9634           (pc)
9635           (label_ref (match_operand 3 "" ""))))
9636    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9637         (match_dup 1))]
9638   ""
9639 "* return pa_output_movb (operands, insn, which_alternative, 1); "
9640 ;; Do not expect to understand this the first time through.
9641 [(set_attr "type" "cbranch,multi,multi,multi")
9642  (set (attr "length")
9643       (if_then_else (eq_attr "alternative" "0")
9644 ;; Loop counter in register case
9645 ;; Short branch has length of 4
9646 ;; Long branch has length of 8
9647         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9648                (const_int MAX_12BIT_OFFSET))
9649            (const_int 4)
9650            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9651                (const_int MAX_17BIT_OFFSET))
9652            (const_int 8)
9653            (match_test "TARGET_PORTABLE_RUNTIME")
9654            (const_int 24)
9655            (not (match_test "flag_pic"))
9656            (const_int 20)]
9657           (const_int 28))
9659 ;; Loop counter in FP reg case.
9660 ;; Extra goo to deal with additional reload insns.
9661         (if_then_else (eq_attr "alternative" "1")
9662           (if_then_else (lt (match_dup 3) (pc))
9663              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9664                       (const_int MAX_12BIT_OFFSET))
9665                     (const_int 12)
9666                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9667                       (const_int MAX_17BIT_OFFSET))
9668                     (const_int 16)
9669                     (match_test "TARGET_PORTABLE_RUNTIME")
9670                     (const_int 32)
9671                     (not (match_test "flag_pic"))
9672                     (const_int 28)]
9673                   (const_int 36))
9674              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9675                       (const_int MAX_12BIT_OFFSET))
9676                     (const_int 12)
9677                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9678                       (const_int MAX_17BIT_OFFSET))
9679                     (const_int 16)
9680                     (match_test "TARGET_PORTABLE_RUNTIME")
9681                     (const_int 32)
9682                     (not (match_test "flag_pic"))
9683                     (const_int 28)]
9684                   (const_int 36)))
9686 ;; Loop counter in memory or SAR case.
9687 ;; Extra goo to deal with additional reload insns.
9688         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9689                    (const_int MAX_12BIT_OFFSET))
9690                 (const_int 8)
9691                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9692                   (const_int MAX_17BIT_OFFSET))
9693                 (const_int 12)
9694                 (match_test "TARGET_PORTABLE_RUNTIME")
9695                 (const_int 28)
9696                 (not (match_test "flag_pic"))
9697                 (const_int 24)]
9698               (const_int 32)))))])
9700 (define_insn ""
9701   [(set (pc) (label_ref (match_operand 3 "" "" )))
9702    (set (match_operand:SI 0 "ireg_operand" "=r")
9703         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
9704                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9705   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9706   "*
9708   return pa_output_parallel_addb (operands, insn);
9710 [(set_attr "type" "parallel_branch")
9711  (set (attr "length")
9712     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9713                (const_int MAX_12BIT_OFFSET))
9714            (const_int 4)
9715            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9716                (const_int MAX_17BIT_OFFSET))
9717            (const_int 8)
9718            (match_test "TARGET_PORTABLE_RUNTIME")
9719            (const_int 24)
9720            (not (match_test "flag_pic"))
9721            (const_int 20)]
9722           (const_int 28)))])
9724 (define_insn ""
9725   [(set (pc) (label_ref (match_operand 2 "" "" )))
9726    (set (match_operand:SF 0 "ireg_operand" "=r")
9727         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9728   "reload_completed"
9729   "*
9731   return pa_output_parallel_movb (operands, insn);
9733 [(set_attr "type" "parallel_branch")
9734  (set (attr "length")
9735     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9736                (const_int MAX_12BIT_OFFSET))
9737            (const_int 4)
9738            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9739                (const_int MAX_17BIT_OFFSET))
9740            (const_int 8)
9741            (match_test "TARGET_PORTABLE_RUNTIME")
9742            (const_int 24)
9743            (not (match_test "flag_pic"))
9744            (const_int 20)]
9745           (const_int 28)))])
9747 (define_insn ""
9748   [(set (pc) (label_ref (match_operand 2 "" "" )))
9749    (set (match_operand:SI 0 "ireg_operand" "=r")
9750         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9751   "reload_completed"
9752   "*
9754   return pa_output_parallel_movb (operands, insn);
9756 [(set_attr "type" "parallel_branch")
9757  (set (attr "length")
9758     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9759                (const_int MAX_12BIT_OFFSET))
9760            (const_int 4)
9761            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9762                (const_int MAX_17BIT_OFFSET))
9763            (const_int 8)
9764            (match_test "TARGET_PORTABLE_RUNTIME")
9765            (const_int 24)
9766            (not (match_test "flag_pic"))
9767            (const_int 20)]
9768           (const_int 28)))])
9770 (define_insn ""
9771   [(set (pc) (label_ref (match_operand 2 "" "" )))
9772    (set (match_operand:HI 0 "ireg_operand" "=r")
9773         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9774   "reload_completed"
9775   "*
9777   return pa_output_parallel_movb (operands, insn);
9779 [(set_attr "type" "parallel_branch")
9780  (set (attr "length")
9781     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9782                (const_int MAX_12BIT_OFFSET))
9783            (const_int 4)
9784            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9785                (const_int MAX_17BIT_OFFSET))
9786            (const_int 8)
9787            (match_test "TARGET_PORTABLE_RUNTIME")
9788            (const_int 24)
9789            (not (match_test "flag_pic"))
9790            (const_int 20)]
9791           (const_int 28)))])
9793 (define_insn ""
9794   [(set (pc) (label_ref (match_operand 2 "" "" )))
9795    (set (match_operand:QI 0 "ireg_operand" "=r")
9796         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9797   "reload_completed"
9798   "*
9800   return pa_output_parallel_movb (operands, insn);
9802 [(set_attr "type" "parallel_branch")
9803  (set (attr "length")
9804     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9805                (const_int MAX_12BIT_OFFSET))
9806            (const_int 4)
9807            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9808                (const_int MAX_17BIT_OFFSET))
9809            (const_int 8)
9810            (match_test "TARGET_PORTABLE_RUNTIME")
9811            (const_int 24)
9812            (not (match_test "flag_pic"))
9813            (const_int 20)]
9814           (const_int 28)))])
9816 (define_insn ""
9817   [(set (match_operand 0 "register_operand" "=f")
9818         (mult (match_operand 1 "register_operand" "f")
9819               (match_operand 2 "register_operand" "f")))
9820    (set (match_operand 3 "register_operand" "+f")
9821         (plus (match_operand 4 "register_operand" "f")
9822               (match_operand 5 "register_operand" "f")))]
9823   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9824    && reload_completed && pa_fmpyaddoperands (operands)"
9825   "*
9827   if (GET_MODE (operands[0]) == DFmode)
9828     {
9829       if (rtx_equal_p (operands[3], operands[5]))
9830         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9831       else
9832         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9833     }
9834   else
9835     {
9836       if (rtx_equal_p (operands[3], operands[5]))
9837         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9838       else
9839         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9840     }
9842   [(set_attr "type" "fpalu")
9843    (set_attr "length" "4")])
9845 (define_insn ""
9846   [(set (match_operand 3 "register_operand" "+f")
9847         (plus (match_operand 4 "register_operand" "f")
9848               (match_operand 5 "register_operand" "f")))
9849    (set (match_operand 0 "register_operand" "=f")
9850         (mult (match_operand 1 "register_operand" "f")
9851               (match_operand 2 "register_operand" "f")))]
9852   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9853    && reload_completed && pa_fmpyaddoperands (operands)"
9854   "*
9856   if (GET_MODE (operands[0]) == DFmode)
9857     {
9858       if (rtx_equal_p (operands[3], operands[5]))
9859         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9860       else
9861         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9862     }
9863   else
9864     {
9865       if (rtx_equal_p (operands[3], operands[5]))
9866         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9867       else
9868         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9869     }
9871   [(set_attr "type" "fpalu")
9872    (set_attr "length" "4")])
9874 (define_insn ""
9875   [(set (match_operand 0 "register_operand" "=f")
9876         (mult (match_operand 1 "register_operand" "f")
9877               (match_operand 2 "register_operand" "f")))
9878    (set (match_operand 3 "register_operand" "+f")
9879         (minus (match_operand 4 "register_operand" "f")
9880                (match_operand 5 "register_operand" "f")))]
9881   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9882    && reload_completed && pa_fmpysuboperands (operands)"
9883   "*
9885   if (GET_MODE (operands[0]) == DFmode)
9886     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9887   else
9888     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9890   [(set_attr "type" "fpalu")
9891    (set_attr "length" "4")])
9893 (define_insn ""
9894   [(set (match_operand 3 "register_operand" "+f")
9895         (minus (match_operand 4 "register_operand" "f")
9896                (match_operand 5 "register_operand" "f")))
9897    (set (match_operand 0 "register_operand" "=f")
9898         (mult (match_operand 1 "register_operand" "f")
9899               (match_operand 2 "register_operand" "f")))]
9900   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9901    && reload_completed && pa_fmpysuboperands (operands)"
9902   "*
9904   if (GET_MODE (operands[0]) == DFmode)
9905     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9906   else
9907     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9909   [(set_attr "type" "fpalu")
9910    (set_attr "length" "4")])
9912 ;; The following two patterns are used by the trampoline code for nested
9913 ;; functions.  They flush the I and D cache lines from the start address
9914 ;; (operand0) to the end address (operand1).  No lines are flushed if the
9915 ;; end address is less than the start address (unsigned).
9917 ;; Because the range of memory flushed is variable and the size of a MEM
9918 ;; can only be a CONST_INT, the patterns specify that they perform an
9919 ;; unspecified volatile operation on all memory.
9921 ;; The address range for an icache flush must lie within a single
9922 ;; space on targets with non-equivalent space registers.
9924 ;; Operand 0 contains the start address.
9925 ;; Operand 1 contains the end address.
9926 ;; Operand 2 contains the line length to use.
9927 (define_insn "dcacheflush<P:mode>"
9928   [(const_int 1)
9929    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9930    (use (match_operand 0 "pmode_register_operand" "r"))
9931    (use (match_operand 1 "pmode_register_operand" "r"))
9932    (use (match_operand 2 "pmode_register_operand" "r"))
9933    (clobber (match_scratch:P 3 "=&0"))]
9934   ""
9935   "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9936   [(set_attr "type" "multi")
9937    (set_attr "length" "12")])
9939 (define_insn "icacheflush<P:mode>"
9940   [(const_int 2)
9941    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9942    (use (match_operand 0 "pmode_register_operand" "r"))
9943    (use (match_operand 1 "pmode_register_operand" "r"))
9944    (use (match_operand 2 "pmode_register_operand" "r"))
9945    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9946    (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9947    (clobber (match_scratch:P 5 "=&0"))]
9948   ""
9949   "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"
9950   [(set_attr "type" "multi")
9951    (set_attr "length" "52")])
9953 (define_expand "clear_cache"
9954   [(match_operand 0 "pmode_register_operand")
9955    (match_operand 1 "pmode_register_operand")]
9956   ""
9958   rtx line_length = gen_reg_rtx (Pmode);
9960   emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
9961   if (TARGET_64BIT)
9962     emit_insn (gen_icacheflushdi (operands[0], operands[1], line_length,
9963                                   gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));
9964   else
9965     emit_insn (gen_icacheflushsi (operands[0], operands[1], line_length,
9966                                   gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));
9967   DONE;
9970 ;; An out-of-line prologue.
9971 (define_insn "outline_prologue_call"
9972   [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9973    (clobber (reg:SI 31))
9974    (clobber (reg:SI 22))
9975    (clobber (reg:SI 21))
9976    (clobber (reg:SI 20))
9977    (clobber (reg:SI 19))
9978    (clobber (reg:SI 1))]
9979   ""
9980   "*
9983   /* We need two different versions depending on whether or not we
9984      need a frame pointer.   Also note that we return to the instruction
9985      immediately after the branch rather than two instructions after the
9986      break as normally is the case.  */
9987   if (frame_pointer_needed)
9988     {
9989       /* Must import the magic millicode routine(s).  */
9990       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9992       if (TARGET_PORTABLE_RUNTIME)
9993         {
9994           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9995           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9996                            NULL);
9997         }
9998       else
9999         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
10000     }
10001   else
10002     {
10003       /* Must import the magic millicode routine(s).  */
10004       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
10006       if (TARGET_PORTABLE_RUNTIME)
10007         {
10008           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
10009           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
10010         }
10011       else
10012         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
10013     }
10014   return \"\";
10016   [(set_attr "type" "multi")
10017    (set_attr "length" "8")])
10019 ;; An out-of-line epilogue.
10020 (define_insn "outline_epilogue_call"
10021   [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
10022    (use (reg:SI 29))
10023    (use (reg:SI 28))
10024    (clobber (reg:SI 31))
10025    (clobber (reg:SI 22))
10026    (clobber (reg:SI 21))
10027    (clobber (reg:SI 20))
10028    (clobber (reg:SI 19))
10029    (clobber (reg:SI 2))
10030    (clobber (reg:SI 1))]
10031   ""
10032   "*
10035   /* We need two different versions depending on whether or not we
10036      need a frame pointer.   Also note that we return to the instruction
10037      immediately after the branch rather than two instructions after the
10038      break as normally is the case.  */
10039   if (frame_pointer_needed)
10040     {
10041       /* Must import the magic millicode routine.  */
10042       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
10044       /* The out-of-line prologue will make sure we return to the right
10045          instruction.  */
10046       if (TARGET_PORTABLE_RUNTIME)
10047         {
10048           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
10049           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
10050                            NULL);
10051         }
10052       else
10053         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
10054     }
10055   else
10056     {
10057       /* Must import the magic millicode routine.  */
10058       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
10060       /* The out-of-line prologue will make sure we return to the right
10061          instruction.  */
10062       if (TARGET_PORTABLE_RUNTIME)
10063         {
10064           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
10065           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
10066         }
10067       else
10068         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
10069     }
10070   return \"\";
10072   [(set_attr "type" "multi")
10073    (set_attr "length" "8")])
10075 ;; Given a function pointer, canonicalize it so it can be 
10076 ;; reliably compared to another function pointer.  */
10077 (define_expand "canonicalize_funcptr_for_compare"
10078   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
10079    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10080               (clobber (match_dup 2))
10081               (clobber (reg:SI 26))
10082               (clobber (reg:SI 22))
10083               (clobber (reg:SI 31))])
10084    (set (match_operand:SI 0 "register_operand" "")
10085         (reg:SI 29))]
10086   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
10087   "
10089   if (TARGET_ELF32)
10090     {
10091       rtx canonicalize_funcptr_for_compare_libfunc
10092         = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
10094       emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
10095                                operands[0], LCT_NORMAL, Pmode,
10096                                operands[1], Pmode);
10097       DONE;
10098     }
10100   operands[2] = gen_reg_rtx (SImode);
10101   if (GET_CODE (operands[1]) != REG)
10102     {
10103       rtx tmp = gen_reg_rtx (Pmode);
10104       emit_move_insn (tmp, operands[1]);
10105       operands[1] = tmp;
10106     }
10109 (define_insn "*$$sh_func_adrs"
10110   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10111    (clobber (match_operand:SI 0 "register_operand" "=a"))
10112    (clobber (reg:SI 26))
10113    (clobber (reg:SI 22))
10114    (clobber (reg:SI 31))]
10115   "!TARGET_64BIT"
10116   "*
10118   int length = get_attr_length (insn);
10119   rtx xoperands[2];
10121   xoperands[0] = GEN_INT (length - 8);
10122   xoperands[1] = GEN_INT (length - 16);
10124   /* Must import the magic millicode routine.  */
10125   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
10127   /* This is absolutely amazing.
10129      First, copy our input parameter into %r29 just in case we don't
10130      need to call $$sh_func_adrs.  */
10131   output_asm_insn (\"copy %%r26,%%r29\", NULL);
10132   output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
10134   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
10135      we use %r26 unchanged.  */
10136   output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
10137   output_asm_insn (\"ldi 4096,%%r31\", NULL);
10139   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
10140      4096, then again we use %r26 unchanged.  */
10141   output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
10143   /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
10144   return pa_output_millicode_call (insn,
10145                                    gen_rtx_SYMBOL_REF (SImode,
10146                                                        \"$$sh_func_adrs\"));
10148   [(set_attr "type" "sh_func_adrs")
10149    (set (attr "length")
10150         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
10151               (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
10152                     (const_int 20))))])
10154 ;; On the PA, the PIC register is call clobbered, so it must
10155 ;; be saved & restored around calls by the caller.  If the call
10156 ;; doesn't return normally (nonlocal goto, or an exception is
10157 ;; thrown), then the code at the exception handler label must
10158 ;; restore the PIC register.
10159 (define_expand "exception_receiver"
10160   [(const_int 4)]
10161   "flag_pic"
10162   "
10164   /* On the 64-bit port, we need a blockage because there is
10165      confusion regarding the dependence of the restore on the
10166      frame pointer.  As a result, the frame pointer and pic
10167      register restores sometimes are interchanged erroneously.  */
10168   if (TARGET_64BIT)
10169     emit_insn (gen_blockage ());
10170   /* Restore the PIC register using hppa_pic_save_rtx ().  The
10171      PIC register is not saved in the frame in 64-bit ABI.  */
10172   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10173   emit_insn (gen_blockage ());
10174   DONE;
10177 (define_expand "builtin_setjmp_receiver"
10178   [(label_ref (match_operand 0 "" ""))]
10179   "flag_pic"
10180   "
10182   if (TARGET_64BIT)
10183     emit_insn (gen_blockage ());
10184   /* Restore the PIC register.  Hopefully, this will always be from
10185      a stack slot.  The only registers that are valid after a
10186      builtin_longjmp are the stack and frame pointers.  */
10187   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10188   emit_insn (gen_blockage ());
10189   DONE;
10192 ;; Allocate new stack space and update the saved stack pointer in the
10193 ;; frame marker.  The HP C compilers also copy additional words in the
10194 ;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10195 ;; The 32-bit compiler copies the word at -16 (Static Link).  We
10196 ;; currently don't copy these values.
10198 ;; Since the copy of the frame marker can't be done atomically, I
10199 ;; suspect that using it for unwind purposes may be somewhat unreliable.
10200 ;; The HP compilers appear to raise the stack and copy the frame
10201 ;; marker in a strict instruction sequence.  This suggests that the
10202 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10203 ;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10204 ;; as GAS doesn't support it, or try to keep the instructions emitted
10205 ;; here in strict sequence.
10206 (define_expand "allocate_stack"
10207   [(match_operand 0 "" "")
10208    (match_operand 1 "" "")]
10209   ""
10210   "
10212   rtx addr;
10214   /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10215      in operand 0 before adjusting the stack.  */
10216   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10217   anti_adjust_stack (operands[1]);
10218   if (TARGET_HPUX_UNWIND_LIBRARY)
10219     {
10220       addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10221                            GEN_INT (TARGET_64BIT ? -8 : -4));
10222       emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10223     }
10224   if (!TARGET_64BIT && flag_pic)
10225     {
10226       rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10227       emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10228     }
10229   DONE;
10232 (define_expand "prefetch"
10233   [(match_operand 0 "address_operand" "")
10234    (match_operand 1 "const_int_operand" "")
10235    (match_operand 2 "const_int_operand" "")]
10236   "TARGET_PA_20"
10238   operands[0] = copy_addr_to_reg (operands[0]);
10239   emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10240   DONE;
10243 (define_insn "prefetch_20"
10244   [(prefetch (match_operand 0 "pmode_register_operand" "r")
10245              (match_operand:SI 1 "const_int_operand" "n")
10246              (match_operand:SI 2 "const_int_operand" "n"))]
10247   "TARGET_PA_20"
10249   /* The SL cache-control completer indicates good spatial locality but
10250      poor temporal locality.  The ldw instruction with a target of general
10251      register 0 prefetches a cache line for a read.  The ldd instruction
10252      prefetches a cache line for a write.  */
10253   static const char * const instr[2][2] = {
10254     {
10255       "ldw,sl 0(%0),%%r0",
10256       "ldd,sl 0(%0),%%r0"
10257     },
10258     {
10259       "ldw 0(%0),%%r0",
10260       "ldd 0(%0),%%r0"
10261     }
10262   };
10263   int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10264   int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10266   return instr [locality][read_or_write];
10268   [(set_attr "type" "load")
10269    (set_attr "length" "4")])
10271 ;; TLS Support
10272 (define_insn "tgd_load"
10273  [(set (match_operand:SI 0 "register_operand" "=r")
10274        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10275   (clobber (reg:SI R1_REGNUM))
10276   (use (reg:SI R27_REGNUM))]
10277   "!TARGET_64BIT"
10278   "*
10280   return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10282   [(set_attr "type" "multi")
10283    (set_attr "length" "8")])
10285 (define_expand "tgd_load_pic"
10286  [(set (match_operand 0 "register_operand")
10287        (unspec [(match_operand 1 "tgd_symbolic_operand")] UNSPEC_TLSGD_PIC))
10288   (clobber (reg R1_REGNUM))]
10289   ""
10291   if (TARGET_64BIT)
10292     emit_insn (gen_tgd_load_picdi (operands[0], operands[1]));
10293   else
10294     emit_insn (gen_tgd_load_picsi (operands[0], operands[1]));
10295   DONE;
10298 (define_insn "tgd_load_picsi"
10299  [(set (match_operand:SI 0 "register_operand" "=r")
10300        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10301   (clobber (reg:SI R1_REGNUM))
10302   (use (reg:SI R19_REGNUM))]
10303   "!TARGET_64BIT"
10304   "*
10306   return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10308   [(set_attr "type" "multi")
10309    (set_attr "length" "8")])
10311 (define_insn "tgd_load_picdi"
10312  [(set (match_operand:DI 0 "register_operand" "=r")
10313        (unspec:DI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10314   (clobber (reg:DI R1_REGNUM))
10315   (use (reg:DI R27_REGNUM))]
10316   "TARGET_64BIT"
10317   "*
10319   return \"addil LT'%1-$tls_gdidx$,%%r27\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10321   [(set_attr "type" "multi")
10322    (set_attr "length" "8")])
10324 (define_insn "tld_load"
10325  [(set (match_operand:SI 0 "register_operand" "=r")
10326        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10327   (clobber (reg:SI R1_REGNUM))
10328   (use (reg:SI R27_REGNUM))]
10329   "!TARGET_64BIT"
10330   "*
10332   return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10334   [(set_attr "type" "multi")
10335    (set_attr "length" "8")])
10337 (define_expand "tld_load_pic"
10338  [(set (match_operand 0 "register_operand")
10339        (unspec [(match_operand 1 "tld_symbolic_operand")] UNSPEC_TLSLDM_PIC))
10340   (clobber (reg R1_REGNUM))]
10341   ""
10343   if (TARGET_64BIT)
10344     emit_insn (gen_tld_load_picdi (operands[0], operands[1]));
10345   else
10346     emit_insn (gen_tld_load_picsi (operands[0], operands[1]));
10347   DONE;
10350 (define_insn "tld_load_picsi"
10351  [(set (match_operand:SI 0 "register_operand" "=r")
10352        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10353   (clobber (reg:SI R1_REGNUM))
10354   (use (reg:SI R19_REGNUM))]
10355   "!TARGET_64BIT"
10356   "*
10358   return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10360   [(set_attr "type" "multi")
10361    (set_attr "length" "8")])
10363 (define_insn "tld_load_picdi"
10364  [(set (match_operand:DI 0 "register_operand" "=r")
10365        (unspec:DI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10366   (clobber (reg:DI R1_REGNUM))
10367   (use (reg:DI R27_REGNUM))]
10368   "TARGET_64BIT"
10369   "*
10371   return \"addil LT'%1-$tls_ldidx$,%%r27\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10373   [(set_attr "type" "multi")
10374    (set_attr "length" "8")])
10376 (define_expand "tld_offset_load"
10377   [(set (match_operand 0 "register_operand")
10378         (plus (unspec [(match_operand 1 "tld_symbolic_operand")] 
10379                             UNSPEC_TLSLDO)
10380                  (match_operand 2 "register_operand")))
10381    (clobber (reg R1_REGNUM))]
10382   ""
10384   if (TARGET_64BIT)
10385     emit_insn (gen_tld_offset_loaddi (operands[0], operands[1], operands[2]));
10386   else
10387     emit_insn (gen_tld_offset_loadsi (operands[0], operands[1], operands[2]));
10388   DONE;
10391 (define_insn "tld_offset_load<P:mode>"
10392   [(set (match_operand:P 0 "register_operand" "=r")
10393         (plus:P (unspec:P [(match_operand 1 "tld_symbolic_operand" "")] 
10394                             UNSPEC_TLSLDO)
10395                 (match_operand:P 2 "register_operand" "r")))
10396    (clobber (reg:P R1_REGNUM))]
10397   ""
10398   "*
10400   return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\"; 
10402   [(set_attr "type" "multi")
10403    (set_attr "length" "8")])
10405 (define_expand "tp_load"
10406   [(set (match_operand 0 "register_operand")
10407         (unspec [(const_int 0)] UNSPEC_TP))]
10408   ""
10410   if (TARGET_64BIT)
10411     emit_insn (gen_tp_loaddi (operands[0]));
10412   else
10413     emit_insn (gen_tp_loadsi (operands[0]));
10414   DONE;
10417 (define_insn "tp_load<P:mode>"
10418   [(set (match_operand:P 0 "register_operand" "=r")
10419         (unspec:P [(const_int 0)] UNSPEC_TP))]
10420   ""
10421   "mfctl %%cr27,%0"
10422   [(set_attr "type" "multi")
10423    (set_attr "length" "4")])
10425 (define_insn "tie_load"
10426   [(set (match_operand:SI 0 "register_operand" "=r")
10427         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10428    (clobber (reg:SI R1_REGNUM))
10429    (use (reg:SI R27_REGNUM))]
10430   "!TARGET_64BIT"
10431   "*
10433   return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10435   [(set_attr "type" "multi")
10436    (set_attr "length" "8")])
10438 (define_expand "tie_load_pic"
10439   [(set (match_operand 0 "register_operand")
10440         (unspec [(match_operand 1 "tie_symbolic_operand")] UNSPEC_TLSIE_PIC))
10441    (clobber (reg R1_REGNUM))]
10442   ""
10444   if (TARGET_64BIT)
10445     emit_insn (gen_tie_load_picdi (operands[0], operands[1]));
10446   else
10447     emit_insn (gen_tie_load_picsi (operands[0], operands[1]));
10448   DONE;
10451 (define_insn "tie_load_picsi"
10452   [(set (match_operand:SI 0 "register_operand" "=r")
10453         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10454    (clobber (reg:SI R1_REGNUM))
10455    (use (reg:SI R19_REGNUM))]
10456   "!TARGET_64BIT"
10457   "*
10459   return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10461   [(set_attr "type" "multi")
10462    (set_attr "length" "8")])
10464 (define_insn "tie_load_picdi"
10465   [(set (match_operand:DI 0 "register_operand" "=r")
10466         (unspec:DI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10467    (clobber (reg:DI R1_REGNUM))
10468    (use (reg:DI R27_REGNUM))]
10469   "!TARGET_64BIT"
10470   "*
10472   return \"addil LT'%1-$tls_ieoff$,%%r27\;ldd RT'%1-$tls_ieoff$(%%r1),%0\";
10474   [(set_attr "type" "multi")
10475    (set_attr "length" "8")])
10477 (define_expand "tle_load"
10478   [(set (match_operand 0 "register_operand")
10479         (plus (unspec [(match_operand 1 "tle_symbolic_operand")] 
10480                             UNSPEC_TLSLE)
10481                 (match_operand 2 "register_operand")))
10482    (clobber (reg R1_REGNUM))]
10483   ""
10485   if (TARGET_64BIT)
10486     emit_insn (gen_tle_loaddi (operands[0], operands[1], operands[2]));
10487   else
10488     emit_insn (gen_tle_loadsi (operands[0], operands[1], operands[2]));
10489   DONE;
10492 (define_insn "tle_load<P:mode>"
10493   [(set (match_operand:P 0 "register_operand" "=r")
10494         (plus:P (unspec:P [(match_operand 1 "tle_symbolic_operand" "")] 
10495                             UNSPEC_TLSLE)
10496                  (match_operand:P 2 "register_operand" "r")))
10497    (clobber (reg:P R1_REGNUM))]
10498   ""
10499   "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10500   [(set_attr "type" "multi")
10501    (set_attr "length" "8")])
10503 ;; Atomic instructions
10505 ;; All memory loads and stores access storage atomically except
10506 ;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10507 ;; doubleword loads and stores are not guaranteed to be atomic
10508 ;; when referencing the I/O address space.
10510 ;; Atomic and sync libcalls use different lock sets.  Great care is
10511 ;; needed if both are used in a single application.
10513 ;; Atomic load and store libcalls are enabled by the -matomic-libcalls
10514 ;; option.  This option is not enabled by default as the generated
10515 ;; libcalls depend on libatomic which is not built until the end of
10516 ;; the gcc build.  For loads, we only need an atomic libcall for DImode.
10517 ;; Sync libcalls are not generated when atomic libcalls are enabled.
10519 ;; Sync libcalls are enabled by default when supported.  They can be
10520 ;; disabled by the -fno-sync-libcalls option.  Sync libcalls always
10521 ;; use a single memory store in their implementation, even for DImode.
10522 ;; DImode stores are done using either std or fstd.  Thus, we only
10523 ;; need a sync load libcall for DImode when we don't have an atomic
10524 ;; processor load available for the mode (TARGET_SOFT_FLOAT).
10526 ;; Implement atomic QImode store using exchange.
10528 (define_expand "atomic_storeqi"
10529   [(match_operand:QI 0 "memory_operand")                ;; memory
10530    (match_operand:QI 1 "register_operand")              ;; val out
10531    (match_operand:SI 2 "const_int_operand")]            ;; model
10532   ""
10534   rtx addr, libfunc;
10536   if (TARGET_SYNC_LIBCALLS)
10537     {
10538       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10539       libfunc = optab_libfunc (sync_lock_test_and_set_optab, QImode);
10540       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10541                          operands[1], QImode);
10542       DONE;
10543     }
10545   if (TARGET_ATOMIC_LIBCALLS)
10546     {
10547       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10548       libfunc = init_one_libfunc ("__atomic_exchange_1");
10549       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10550                          operands[1], QImode);
10551       DONE;
10552     }
10554   FAIL;
10557 ;; Implement atomic HImode store using exchange.
10559 (define_expand "atomic_storehi"
10560   [(match_operand:HI 0 "memory_operand")                ;; memory
10561    (match_operand:HI 1 "register_operand")              ;; val out
10562    (match_operand:SI 2 "const_int_operand")]            ;; model
10563   ""
10565   rtx addr, libfunc;
10567   if (TARGET_SYNC_LIBCALLS)
10568     {
10569       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10570       libfunc = optab_libfunc (sync_lock_test_and_set_optab, HImode);
10571       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10572                          operands[1], HImode);
10573       DONE;
10574     }
10576   if (TARGET_ATOMIC_LIBCALLS)
10577     {
10578       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10579       libfunc = init_one_libfunc ("__atomic_exchange_2");
10580       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10581                          operands[1], HImode);
10582       DONE;
10583     }
10585   FAIL;
10588 ;; Implement atomic SImode store using exchange.
10590 (define_expand "atomic_storesi"
10591   [(match_operand:SI 0 "memory_operand")                ;; memory
10592    (match_operand:SI 1 "register_operand")              ;; val out
10593    (match_operand:SI 2 "const_int_operand")]            ;; model
10594   ""
10596   rtx addr, libfunc;
10598   if (TARGET_SYNC_LIBCALLS)
10599     {
10600       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10601       libfunc = optab_libfunc (sync_lock_test_and_set_optab, SImode);
10602       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10603                          operands[1], SImode);
10604       DONE;
10605     }
10607   if (TARGET_ATOMIC_LIBCALLS)
10608     {
10609       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10610       libfunc = init_one_libfunc ("__atomic_exchange_4");
10611       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10612                          operands[1], SImode);
10613       DONE;
10614     }
10616   FAIL;
10619 ;; Implement atomic DImode load.
10621 ;; We need an atomic or sync libcall whenever the processor load or
10622 ;; store used for DImode is not atomic.  The 32-bit libatomic
10623 ;; implementation uses a pair of stw instructions.  They are not
10624 ;; atomic, so we need to call __atomic_load_8.  The linux libgcc
10625 ;; sync implementation uses a std or fstd instruction.  They are
10626 ;; atomic, so we only need to call __sync_load_8 when the load
10627 ;; operation would not be atomic (e.g., 32-bit TARGET_SOFT_FLOAT).
10629 (define_expand "atomic_loaddi"
10630   [(match_operand:DI 0 "register_operand")              ;; val out
10631    (match_operand:DI 1 "memory_operand")                ;; memory
10632    (match_operand:SI 2 "const_int_operand")]            ;; model
10633   ""
10635   enum memmodel model;
10636   rtx addr, libfunc;
10638   if (TARGET_64BIT)
10639     FAIL;
10641   if (TARGET_SYNC_LIBCALLS && MAX_SYNC_LIBFUNC_SIZE >= 8 && TARGET_SOFT_FLOAT)
10642     {
10643       addr = convert_memory_address (Pmode, XEXP (operands[1], 0));
10644       libfunc = init_one_libfunc ("__sync_load_8");
10645       emit_library_call_value (libfunc, operands[0], LCT_NORMAL, DImode,
10646                                addr, Pmode);
10647       DONE;
10648     }
10650   if (TARGET_ATOMIC_LIBCALLS && TARGET_SOFT_FLOAT)
10651     {
10652       addr = convert_memory_address (Pmode, XEXP (operands[1], 0));
10653       libfunc = init_one_libfunc ("__atomic_load_8");
10654       emit_library_call_value (libfunc, operands[0], LCT_NORMAL, DImode,
10655                                addr, Pmode);
10656       DONE;
10657     }
10659   if (TARGET_SOFT_FLOAT)
10660     FAIL;
10662   /* Fallback to processor load with barriers.  */
10663   model = memmodel_from_int (INTVAL (operands[2]));
10664   operands[1] = force_reg (Pmode, XEXP (operands[1], 0));
10665   if (is_mm_seq_cst (model))
10666     expand_mem_thread_fence (model);
10667   emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10668   expand_mem_thread_fence (model);
10669   DONE;
10672 (define_insn "atomic_loaddi_1"
10673   [(set (match_operand:DI 0 "register_operand" "=r")
10674         (mem:DI (match_operand:SI 1 "register_operand" "r")))
10675    (clobber (match_scratch:DI 2 "=f"))]
10676   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10677   "{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"
10678   [(set_attr "type" "move")
10679    (set_attr "length" "16")])
10681 ;; Implement atomic DImode store.
10683 (define_expand "atomic_storedi"
10684   [(match_operand:DI 0 "memory_operand")                ;; memory
10685    (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10686    (match_operand:SI 2 "const_int_operand")]            ;; model
10687   ""
10689   enum memmodel model;
10690   rtx addr, libfunc;
10692   if (TARGET_SYNC_LIBCALLS && MAX_SYNC_LIBFUNC_SIZE >= 8)
10693     {
10694       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10695       libfunc = optab_libfunc (sync_lock_test_and_set_optab, DImode);
10696       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10697                          operands[1], DImode);
10698       DONE;
10699     }
10701   if (TARGET_ATOMIC_LIBCALLS)
10702     {
10703       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10704       libfunc = init_one_libfunc ("__atomic_exchange_8");
10705       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10706                          operands[1], DImode);
10707       DONE;
10708     }
10710   if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10711     FAIL;
10713   /* Fallback to processor store with barriers.  */
10714   model = memmodel_from_int (INTVAL (operands[2]));
10715   operands[0] = force_reg (Pmode, XEXP (operands[0], 0));
10716   if (operands[1] != CONST0_RTX (DImode))
10717     operands[1] = force_reg (DImode, operands[1]);
10718   expand_mem_thread_fence (model);
10719   emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10720   if (is_mm_seq_cst (model))
10721     expand_mem_thread_fence (model);
10722   DONE;
10725 (define_insn "atomic_storedi_1"
10726   [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10727         (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10728    (clobber (match_scratch:DI 2 "=f,f"))]
10729   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10730   "@
10731    fcpy,dbl %%fr0,%2\n\t{fstds|fstd} %2,0(%0)
10732    {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)"
10733   [(set_attr "type" "move,move")
10734    (set_attr "length" "8,16")])
10736 ;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10737 ;; we need memory barriers to enforce program order for memory references
10738 ;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10739 ;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10740 ;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10741 ;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10743 ;; When barriers are needed, we use a strongly ordered ldcw instruction as
10744 ;; the barrier.  All PA 2.0 targets accept the "co" cache control hint but
10745 ;; only PA8800 and PA8900 processors implement the cacheable hint.  In
10746 ;; that case, we can avoid aligning the ldcw address.  In spite of its
10747 ;; description, it is not clear that the sync instruction works as a barrier.
10749 (define_expand "memory_barrier"
10750   [(parallel
10751      [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10752       (clobber (match_dup 1))])]
10753   ""
10755   /* We don't need a barrier if the target uses ordered memory references.  */
10756   if (TARGET_ORDERED)
10757     FAIL;
10758   operands[1] = gen_reg_rtx (Pmode);
10759   operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10760   MEM_VOLATILE_P (operands[0]) = 1;
10763 (define_insn "*memory_barrier_coherent"
10764   [(set (match_operand:BLK 0 "" "")
10765         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10766    (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10767   "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10768   "ldcw,co 0(%%sp),%1"
10769   [(set_attr "type" "binary")
10770    (set_attr "length" "4")])
10772 (define_insn "*memory_barrier_64"
10773   [(set (match_operand:BLK 0 "" "")
10774         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10775     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10776   "TARGET_64BIT"
10777   "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw,co 0(%1),%1"
10778   [(set_attr "type" "binary")
10779    (set_attr "length" "12")])
10781 (define_insn "*memory_barrier_32"
10782   [(set (match_operand:BLK 0 "" "")
10783         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10784     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10785   ""
10786   "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\t{ldcw|ldcw,co} 0(%1),%1"
10787   [(set_attr "type" "binary")
10788    (set_attr "length" "12")])
10790 ;; Get floating-point status register.
10792 (define_expand "get_fpsr"
10793   [(set (match_operand:SI 0 "register_operand" "=r")
10794         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
10795   ""
10797   if (TARGET_SOFT_FLOAT)
10798     FAIL;
10800   if (TARGET_64BIT)
10801     emit_insn (gen_get_fpsr_64 (operands[0]));
10802   else
10803     emit_insn (gen_get_fpsr_32 (operands[0]));
10804   DONE;
10807 ;; The floating-point status register is stored to an unused slot in
10808 ;; the frame marker and then loaded to register operand 0.  The final
10809 ;; floating-point load restores the T bit in the status register.
10811 ;; The final load might be avoided if a word mode store was used to
10812 ;; store the status register.  It is unclear why we need a double-word
10813 ;; store.  I suspect PA 1.0 didn't support single-word stores of the
10814 ;; status register.
10816 (define_insn "get_fpsr_32"
10817   [(set (match_operand:SI 0 "register_operand" "=r")
10818         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
10819   "!TARGET_SOFT_FLOAT && !TARGET_64BIT"
10820   "{fstds|fstd} %%fr0,-16(%%sp)\n\tldw -16(%%sp),%0\n\t{fldds|fldd} -16(%%sp),%%fr0"
10821   [(set_attr "type" "fpstore_load")
10822    (set_attr "length" "12")])
10824 ;; The 64-bit pattern is similar to the 32-bit pattern except we need
10825 ;; compute the address of the frame location as long displacements aren't
10826 ;; supported on Linux targets.
10828 (define_insn "get_fpsr_64"
10829   [(set (match_operand:SI 0 "register_operand" "=r")
10830         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))
10831    (clobber (match_scratch:DI 1 "=&r"))]
10832   "!TARGET_SOFT_FLOAT && TARGET_64BIT"
10833   "ldo -40(%%sp),%1\n\tfstd %%fr0,0(%1)\n\tldw 0(%1),%0\n\tfldd 0(%1),%%fr0"
10834   [(set_attr "type" "fpstore_load")
10835    (set_attr "length" "16")])
10837 ;; Set floating-point status register.
10839 (define_expand "set_fpsr"
10840   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
10841   ""
10843   if (TARGET_SOFT_FLOAT)
10844     FAIL;
10846   if (TARGET_64BIT)
10847     emit_insn (gen_set_fpsr_64 (operands[0]));
10848   else
10849     emit_insn (gen_set_fpsr_32 (operands[0]));
10850   DONE;
10853 ;; The old T bit is extracted and stored in the new status register.
10855 (define_insn "set_fpsr_32"
10856   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)
10857    (clobber (match_scratch:SI 1 "=&r"))]
10858   "!TARGET_SOFT_FLOAT && !TARGET_64BIT"
10859   "{fstds|fstd} %%fr0,-16(%%sp)\n\tldw -16(%%sp),%1\n\t{extru|extrw,u} %1,25,1,%1\n\t{dep|depw} %1,25,1,%0\n\tstw %0,-16(%%sp)\n\t{fldds|fldd} -16(%%sp),%%fr0"
10860   [(set_attr "type" "store_fpload")
10861    (set_attr "length" "24")])
10863 (define_insn "set_fpsr_64"
10864   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)
10865    (clobber (match_scratch:DI 1 "=&r"))
10866    (clobber (match_scratch:SI 2 "=&r"))]
10867   "!TARGET_SOFT_FLOAT && TARGET_64BIT"
10868   "ldo -40(%%sp),%1\n\tfstd %%fr0,0(%1)\n\tldw 0(%1),%2\n\textrw,u %2,25,1,%2\n\tdepw %2,25,1,%0\n\tstw %0,0(%1)\n\tfldd 0(%1),%%fr0"
10869   [(set_attr "type" "store_fpload")
10870    (set_attr "length" "28")])