Revise -mdisable-fpregs option and add new -msoft-mult option
[official-gcc.git] / gcc / config / pa / pa.md
blobea6da457fcbd531f7a16960c06b978a53bf46ebc
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;;   Copyright (C) 1992-2021 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   ])
101 ;; Maximum pc-relative branch offsets.
103 ;; These numbers are a bit smaller than the maximum allowable offsets
104 ;; so that a few instructions may be inserted before the actual branch.
106 (define_constants
107   [(MAX_12BIT_OFFSET     8184)  ; 12-bit branch
108    (MAX_17BIT_OFFSET   262100)  ; 17-bit branch
109   ])
111 ;; Mode and code iterators
113 ;; This mode iterator allows :P to be used for patterns that operate on
114 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
115 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
117 ;; This attribute defines the condition prefix for word and double word
118 ;; add, compare, subtract and logical instructions.
119 (define_mode_attr dwc [(SI "") (DI "*")])
121 ;; Insn type.  Used to default other attribute values.
123 ;; type "unary" insns have one input operand (1) and one output operand (0)
124 ;; type "binary" insns have two input operands (1,2) and one output (0)
126 (define_attr "type"
127   "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload,trap"
128   (const_string "binary"))
130 (define_attr "pa_combine_type"
131   "fmpy,faddsub,uncond_branch,addmove,none"
132   (const_string "none"))
134 ;; Processor type (for scheduling, not code generation) -- this attribute
135 ;; must exactly match the processor_type enumeration in pa.h.
137 ;; FIXME: Add 800 scheduling for completeness?
139 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
141 ;; Length (in # of bytes).
142 (define_attr "length" ""
143   (cond [(eq_attr "type" "load,fpload")
144          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
145                        (const_int 8) (const_int 4))
147          (eq_attr "type" "store,fpstore")
148          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
149                        (const_int 8) (const_int 4))
151          (eq_attr "type" "binary,shift,nullshift")
152          (if_then_else (match_operand 2 "arith14_operand" "")
153                        (const_int 4) (const_int 12))
155          (eq_attr "type" "move,unary,shift,nullshift")
156          (if_then_else (match_operand 1 "arith14_operand" "")
157                        (const_int 4) (const_int 8))]
159         (const_int 4)))
161 (define_asm_attributes
162   [(set_attr "length" "4")
163    (set_attr "type" "multi")])
165 ;; Attributes for instruction and branch scheduling
167 ;; For conditional branches. Frame related instructions are not allowed
168 ;; because they confuse the unwind support.
169 (define_attr "in_branch_delay" "false,true"
170   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
171                      (eq_attr "length" "4")
172                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
173                 (const_string "true")
174                 (const_string "false")))
176 ;; Disallow instructions which use the FPU since they will tie up the FPU
177 ;; even if the instruction is nullified.
178 (define_attr "in_nullified_branch_delay" "false,true"
179   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch,trap")
180                      (eq_attr "length" "4")
181                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
182                 (const_string "true")
183                 (const_string "false")))
185 ;; For calls and millicode calls.
186 (define_attr "in_call_delay" "false,true"
187   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
188                      (eq_attr "length" "4")
189                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
190                 (const_string "true")
191                 (const_string "false")))
193 ;; Call delay slot description.
194 (define_delay (eq_attr "type" "call")
195   [(eq_attr "in_call_delay" "true") (nil) (nil)])
197 ;; Sibcall delay slot description.
198 (define_delay (eq_attr "type" "sibcall")
199   [(eq_attr "in_call_delay" "true") (nil) (nil)])
201 ;; Millicode call delay slot description.
202 (define_delay (eq_attr "type" "milli")
203   [(eq_attr "in_call_delay" "true") (nil) (nil)])
205 ;; Return and other similar instructions.
206 (define_delay (eq_attr "type" "branch,parallel_branch")
207   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
209 ;; Floating point conditional branch delay slot description.
210 (define_delay (eq_attr "type" "fbranch")
211   [(eq_attr "in_branch_delay" "true")
212    (eq_attr "in_nullified_branch_delay" "true")
213    (nil)])
215 ;; Integer conditional branch delay slot description.
216 ;; Nullification of conditional branches on the PA is dependent on the
217 ;; direction of the branch.  Forward branches nullify true and
218 ;; backward branches nullify false.  If the direction is unknown
219 ;; then nullification is not allowed.
220 (define_delay (eq_attr "type" "cbranch")
221   [(eq_attr "in_branch_delay" "true")
222    (and (eq_attr "in_nullified_branch_delay" "true")
223         (attr_flag "forward"))
224    (and (eq_attr "in_nullified_branch_delay" "true")
225         (attr_flag "backward"))])
227 (define_delay (eq_attr "type" "uncond_branch")
228   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
230 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
231 ;; load: 2, fpload: 3
232 ;; store, fpstore: 3, no D-cache operations should be scheduled.
234 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
235 ;; Timings:
236 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
237 ;; fcpy         3       ALU     2
238 ;; fabs         3       ALU     2
239 ;; fadd         3       ALU     2
240 ;; fsub         3       ALU     2
241 ;; fcmp         3       ALU     2
242 ;; fcnv         3       ALU     2
243 ;; fmpyadd      3       ALU,MPY 2
244 ;; fmpysub      3       ALU,MPY 2
245 ;; fmpycfxt     3       ALU,MPY 2
246 ;; fmpy         3       MPY     2
247 ;; fmpyi        3       MPY     2
248 ;; fdiv,sgl     10      MPY     10
249 ;; fdiv,dbl     12      MPY     12
250 ;; fsqrt,sgl    14      MPY     14
251 ;; fsqrt,dbl    18      MPY     18
253 ;; We don't model fmpyadd/fmpysub properly as those instructions
254 ;; keep both the FP ALU and MPY units busy.  Given that these
255 ;; processors are obsolete, I'm not going to spend the time to
256 ;; model those instructions correctly.
258 (define_automaton "pa700")
259 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
261 (define_insn_reservation "W0" 4
262   (and (eq_attr "type" "fpcc")
263        (eq_attr "cpu" "700"))
264   "fpalu_700*2")
266 (define_insn_reservation "W1" 3
267   (and (eq_attr "type" "fpalu")
268        (eq_attr "cpu" "700"))
269   "fpalu_700*2")
271 (define_insn_reservation "W2" 3
272   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
273        (eq_attr "cpu" "700"))
274   "fpmpy_700*2")
276 (define_insn_reservation "W3" 10
277   (and (eq_attr "type" "fpdivsgl")
278        (eq_attr "cpu" "700"))
279   "fpmpy_700*10")
281 (define_insn_reservation "W4" 12
282   (and (eq_attr "type" "fpdivdbl")
283        (eq_attr "cpu" "700"))
284   "fpmpy_700*12")
286 (define_insn_reservation "W5" 14
287   (and (eq_attr "type" "fpsqrtsgl")
288        (eq_attr "cpu" "700"))
289   "fpmpy_700*14")
291 (define_insn_reservation "W6" 18
292   (and (eq_attr "type" "fpsqrtdbl")
293        (eq_attr "cpu" "700"))
294   "fpmpy_700*18")
296 (define_insn_reservation "W7" 2
297   (and (eq_attr "type" "load")
298        (eq_attr "cpu" "700"))
299   "mem_700")
301 (define_insn_reservation "W8" 2
302   (and (eq_attr "type" "fpload")
303        (eq_attr "cpu" "700"))
304   "mem_700")
306 (define_insn_reservation "W9" 3
307   (and (eq_attr "type" "store")
308        (eq_attr "cpu" "700"))
309   "mem_700*3")
311 (define_insn_reservation "W10" 3
312   (and (eq_attr "type" "fpstore")
313        (eq_attr "cpu" "700"))
314   "mem_700*3")
316 (define_insn_reservation "W11" 5
317   (and (eq_attr "type" "fpstore_load")
318        (eq_attr "cpu" "700"))
319   "mem_700*5")
321 (define_insn_reservation "W12" 6
322   (and (eq_attr "type" "store_fpload")
323        (eq_attr "cpu" "700"))
324   "mem_700*6")
326 (define_insn_reservation "W13" 1
327   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
328        (eq_attr "cpu" "700"))
329   "dummy_700")
331 ;; We have a bypass for all computations in the FP unit which feed an
332 ;; FP store as long as the sizes are the same.
333 (define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
334 (define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
335 (define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
336 (define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
337 (define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
339 ;; We have an "anti-bypass" for FP loads which feed an FP store.
340 (define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
342 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
343 ;; floating point computations with non-floating point computations (fp loads
344 ;; and stores are not fp computations).
346 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
347 ;; take two cycles, during which no Dcache operations should be scheduled.
348 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
349 ;; all have the same memory characteristics if one disregards cache misses.
351 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
352 ;; There's no value in modeling the ALU and MUL separately though
353 ;; since there can never be a functional unit conflict given the
354 ;; latency and issue rates for those units.
356 ;; Timings:
357 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
358 ;; fcpy         2       ALU     1
359 ;; fabs         2       ALU     1
360 ;; fadd         2       ALU     1
361 ;; fsub         2       ALU     1
362 ;; fcmp         2       ALU     1
363 ;; fcnv         2       ALU     1
364 ;; fmpyadd      2       ALU,MPY 1
365 ;; fmpysub      2       ALU,MPY 1
366 ;; fmpycfxt     2       ALU,MPY 1
367 ;; fmpy         2       MPY     1
368 ;; fmpyi        2       MPY     1
369 ;; fdiv,sgl     8       DIV     8
370 ;; fdiv,dbl     15      DIV     15
371 ;; fsqrt,sgl    8       DIV     8
372 ;; fsqrt,dbl    15      DIV     15
374 (define_automaton "pa7100")
375 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
377 (define_insn_reservation "X0" 2
378   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
379        (eq_attr "cpu" "7100"))
380   "f_7100,fpmac_7100")
382 (define_insn_reservation "X1" 8
383   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
384        (eq_attr "cpu" "7100"))
385   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
387 (define_insn_reservation "X2" 15
388   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
389        (eq_attr "cpu" "7100"))
390   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
392 (define_insn_reservation "X3" 2
393   (and (eq_attr "type" "load")
394        (eq_attr "cpu" "7100"))
395   "i_7100+mem_7100")
397 (define_insn_reservation "X4" 2
398   (and (eq_attr "type" "fpload")
399        (eq_attr "cpu" "7100"))
400   "i_7100+mem_7100")
402 (define_insn_reservation "X5" 2
403   (and (eq_attr "type" "store")
404        (eq_attr "cpu" "7100"))
405   "i_7100+mem_7100,mem_7100")
407 (define_insn_reservation "X6" 2
408   (and (eq_attr "type" "fpstore")
409        (eq_attr "cpu" "7100"))
410   "i_7100+mem_7100,mem_7100")
412 (define_insn_reservation "X7" 4
413   (and (eq_attr "type" "fpstore_load")
414        (eq_attr "cpu" "7100"))
415   "i_7100+mem_7100,mem_7100*3")
417 (define_insn_reservation "X8" 4
418   (and (eq_attr "type" "store_fpload")
419        (eq_attr "cpu" "7100"))
420   "i_7100+mem_7100,mem_7100*3")
422 (define_insn_reservation "X9" 1
423   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
424        (eq_attr "cpu" "7100"))
425   "i_7100")
427 ;; We have a bypass for all computations in the FP unit which feed an
428 ;; FP store as long as the sizes are the same.
429 (define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
430 (define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
431 (define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
433 ;; We have an "anti-bypass" for FP loads which feed an FP store.
434 (define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
436 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
437 ;; There's no value in modeling the ALU and MUL separately though
438 ;; since there can never be a functional unit conflict that
439 ;; can be avoided given the latency, issue rates and mandatory
440 ;; one cycle cpu-wide lock for a double precision fp multiply.
442 ;; Timings:
443 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
444 ;; fcpy         2       ALU     1
445 ;; fabs         2       ALU     1
446 ;; fadd         2       ALU     1
447 ;; fsub         2       ALU     1
448 ;; fcmp         2       ALU     1
449 ;; fcnv         2       ALU     1
450 ;; fmpyadd,sgl  2       ALU,MPY 1
451 ;; fmpyadd,dbl  3       ALU,MPY 2
452 ;; fmpysub,sgl  2       ALU,MPY 1
453 ;; fmpysub,dbl  3       ALU,MPY 2
454 ;; fmpycfxt,sgl 2       ALU,MPY 1
455 ;; fmpycfxt,dbl 3       ALU,MPY 2
456 ;; fmpy,sgl     2       MPY     1
457 ;; fmpy,dbl     3       MPY     2
458 ;; fmpyi        3       MPY     2
459 ;; fdiv,sgl     8       DIV     8
460 ;; fdiv,dbl     15      DIV     15
461 ;; fsqrt,sgl    8       DIV     8
462 ;; fsqrt,dbl    15      DIV     15
464 ;; The PA7200 is just like the PA7100LC except that there is
465 ;; no store-store penalty.
467 ;; The PA7300 is just like the PA7200 except that there is
468 ;; no store-load penalty.
470 ;; Note there are some aspects of the 7100LC we are not modeling
471 ;; at the moment.  I'll be reviewing the 7100LC scheduling info
472 ;; shortly and updating this description.
474 ;;   load-load pairs
475 ;;   store-store pairs
476 ;;   other issue modeling
478 (define_automaton "pa7100lc")
479 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
480 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
481 (define_cpu_unit "mem_7100lc" "pa7100lc")
483 ;; Double precision multiplies lock the entire CPU for one
484 ;; cycle.  There is no way to avoid this lock and trying to
485 ;; schedule around the lock is pointless and thus there is no
486 ;; value in trying to model this lock.
488 ;; Not modeling the lock allows us to treat fp multiplies just
489 ;; like any other FP alu instruction.  It allows for a smaller
490 ;; DFA and may reduce register pressure.
491 (define_insn_reservation "Y0" 2
492   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
493        (eq_attr "cpu" "7100LC,7200,7300"))
494   "f_7100lc,fpmac_7100lc")
496 ;; fp division and sqrt instructions lock the entire CPU for
497 ;; 7 cycles (single precision) or 14 cycles (double precision).
498 ;; There is no way to avoid this lock and trying to schedule
499 ;; around the lock is pointless and thus there is no value in
500 ;; trying to model this lock.  Not modeling the lock allows
501 ;; for a smaller DFA and may reduce register pressure.
502 (define_insn_reservation "Y1" 1
503   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
504        (eq_attr "cpu" "7100LC,7200,7300"))
505   "f_7100lc")
507 (define_insn_reservation "Y2" 2
508   (and (eq_attr "type" "load")
509        (eq_attr "cpu" "7100LC,7200,7300"))
510   "i1_7100lc+mem_7100lc")
512 (define_insn_reservation "Y3" 2
513   (and (eq_attr "type" "fpload")
514        (eq_attr "cpu" "7100LC,7200,7300"))
515   "i1_7100lc+mem_7100lc")
517 (define_insn_reservation "Y4" 2
518   (and (eq_attr "type" "store")
519        (eq_attr "cpu" "7100LC"))
520   "i1_7100lc+mem_7100lc,mem_7100lc")
522 (define_insn_reservation "Y5" 2
523   (and (eq_attr "type" "fpstore")
524        (eq_attr "cpu" "7100LC"))
525   "i1_7100lc+mem_7100lc,mem_7100lc")
527 (define_insn_reservation "Y6" 4
528   (and (eq_attr "type" "fpstore_load")
529        (eq_attr "cpu" "7100LC"))
530   "i1_7100lc+mem_7100lc,mem_7100lc*3")
532 (define_insn_reservation "Y7" 4
533   (and (eq_attr "type" "store_fpload")
534        (eq_attr "cpu" "7100LC"))
535   "i1_7100lc+mem_7100lc,mem_7100lc*3")
537 (define_insn_reservation "Y8" 1
538   (and (eq_attr "type" "shift,nullshift")
539        (eq_attr "cpu" "7100LC,7200,7300"))
540   "i1_7100lc")
542 (define_insn_reservation "Y9" 1
543   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
544        (eq_attr "cpu" "7100LC,7200,7300"))
545   "(i0_7100lc|i1_7100lc)")
547 ;; The 7200 has a store-load penalty
548 (define_insn_reservation "Y10" 2
549   (and (eq_attr "type" "store")
550        (eq_attr "cpu" "7200"))
551   "i1_7100lc,mem_7100lc")
553 (define_insn_reservation "Y11" 2
554   (and (eq_attr "type" "fpstore")
555        (eq_attr "cpu" "7200"))
556   "i1_7100lc,mem_7100lc")
558 (define_insn_reservation "Y12" 4
559   (and (eq_attr "type" "fpstore_load")
560        (eq_attr "cpu" "7200"))
561   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
563 (define_insn_reservation "Y13" 4
564   (and (eq_attr "type" "store_fpload")
565        (eq_attr "cpu" "7200"))
566   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
568 ;; The 7300 has no penalty for store-store or store-load
569 (define_insn_reservation "Y14" 2
570   (and (eq_attr "type" "store")
571        (eq_attr "cpu" "7300"))
572   "i1_7100lc")
574 (define_insn_reservation "Y15" 2
575   (and (eq_attr "type" "fpstore")
576        (eq_attr "cpu" "7300"))
577   "i1_7100lc")
579 (define_insn_reservation "Y16" 4
580   (and (eq_attr "type" "fpstore_load")
581        (eq_attr "cpu" "7300"))
582   "i1_7100lc,i1_7100lc+mem_7100lc")
584 (define_insn_reservation "Y17" 4
585   (and (eq_attr "type" "store_fpload")
586        (eq_attr "cpu" "7300"))
587   "i1_7100lc,i1_7100lc+mem_7100lc")
589 ;; We have an "anti-bypass" for FP loads which feed an FP store.
590 (define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
592 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
593 ;; traditional architecture.
595 ;; The PA8000 has a large (56) entry reorder buffer that is split between
596 ;; memory and non-memory operations.
598 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
599 ;; the function units, with the exception of branches and multi-output
600 ;; instructions.  The PA8000 can retire two non-memory operations per cycle
601 ;; and two memory operations per cycle, only one of which may be a store.
603 ;; Given the large reorder buffer, the processor can hide most latencies.
604 ;; According to HP, they've got the best results by scheduling for retirement
605 ;; bandwidth with limited latency scheduling for floating point operations.
606 ;; Latency for integer operations and memory references is ignored.
609 ;; We claim floating point operations have a 2 cycle latency and are
610 ;; fully pipelined, except for div and sqrt which are not pipelined and
611 ;; take from 17 to 31 cycles to complete.
613 ;; It's worth noting that there is no way to saturate all the functional
614 ;; units on the PA8000 as there is not enough issue bandwidth.
616 (define_automaton "pa8000")
617 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
618 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
619 (define_cpu_unit "store_8000" "pa8000")
620 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
621 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
622 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
623 (define_reservation "im_8000" "im0_8000 | im1_8000")
624 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
625 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
626 (define_reservation "f_8000" "f0_8000 | f1_8000")
627 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
629 ;; We can issue any two memops per cycle, but we can only retire
630 ;; one memory store per cycle.  We assume that the reorder buffer
631 ;; will hide any memory latencies per HP's recommendation.
632 (define_insn_reservation "Z0" 0
633   (and
634     (eq_attr "type" "load,fpload")
635     (eq_attr "cpu" "8000"))
636   "im_8000,rm_8000")
638 (define_insn_reservation "Z1" 0
639   (and
640     (eq_attr "type" "store,fpstore")
641     (eq_attr "cpu" "8000"))
642   "im_8000,rm_8000+store_8000")
644 (define_insn_reservation "Z2" 0
645   (and (eq_attr "type" "fpstore_load,store_fpload")
646        (eq_attr "cpu" "8000"))
647   "im_8000,rm_8000+store_8000,im_8000,rm_8000")
649 ;; We can issue and retire two non-memory operations per cycle with
650 ;; a few exceptions (branches).  This group catches those we want
651 ;; to assume have zero latency.
652 (define_insn_reservation "Z3" 0
653   (and
654     (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload")
655     (eq_attr "cpu" "8000"))
656   "inm_8000,rnm_8000")
658 ;; Branches use both slots in the non-memory issue and
659 ;; retirement unit.
660 (define_insn_reservation "Z4" 0
661   (and
662     (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
663     (eq_attr "cpu" "8000"))
664   "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
666 ;; We partial latency schedule the floating point units.
667 ;; They can issue/retire two at a time in the non-memory
668 ;; units.  We fix their latency at 2 cycles and they
669 ;; are fully pipelined.
670 (define_insn_reservation "Z5" 1
671  (and
672    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
673    (eq_attr "cpu" "8000"))
674  "inm_8000,f_8000,rnm_8000")
676 ;; The fdivsqrt units are not pipelined and have a very long latency.  
677 ;; To keep the DFA from exploding, we do not show all the
678 ;; reservations for the divsqrt unit.
679 (define_insn_reservation "Z6" 17
680  (and
681    (eq_attr "type" "fpdivsgl,fpsqrtsgl")
682    (eq_attr "cpu" "8000"))
683  "inm_8000,fdivsqrt_8000*6,rnm_8000")
685 (define_insn_reservation "Z7" 31
686  (and
687    (eq_attr "type" "fpdivdbl,fpsqrtdbl")
688    (eq_attr "cpu" "8000"))
689  "inm_8000,fdivsqrt_8000*6,rnm_8000")
691 ;; Operand and operator predicates and constraints
693 (include "predicates.md")
694 (include "constraints.md")
696 ;; Compare instructions.
697 ;; This controls RTL generation and register allocation.
699 (define_insn ""
700   [(set (reg:CCFP 0)
701         (match_operator:CCFP 2 "comparison_operator"
702                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
703                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
704   "! TARGET_SOFT_FLOAT"
705   "fcmp,sgl,%Y2 %f0,%f1"
706   [(set_attr "length" "4")
707    (set_attr "type" "fpcc")])
709 (define_insn ""
710   [(set (reg:CCFP 0)
711         (match_operator:CCFP 2 "comparison_operator"
712                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
713                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
714   "! TARGET_SOFT_FLOAT"
715   "fcmp,dbl,%Y2 %f0,%f1"
716   [(set_attr "length" "4")
717    (set_attr "type" "fpcc")])
719 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
720 ;; placeholders.  This is necessary in rare situations when a
721 ;; placeholder is re-emitted (see PR 8705).
723 (define_expand "movccfp"
724   [(set (reg:CCFP 0)
725         (match_operand 0 "const_int_operand" ""))]
726   "! TARGET_SOFT_FLOAT"
727   "
729   if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
730     FAIL;
733 ;; The following patterns are optimization placeholders.  In almost
734 ;; all cases, the user of the condition code will be simplified and the
735 ;; original condition code setting insn should be eliminated.
737 (define_insn "*movccfp0"
738   [(set (reg:CCFP 0)
739         (const_int 0))]
740   "! TARGET_SOFT_FLOAT"
741   "fcmp,dbl,= %%fr0,%%fr0"
742   [(set_attr "length" "4")
743    (set_attr "type" "fpcc")])
745 (define_insn "*movccfp1"
746   [(set (reg:CCFP 0)
747         (const_int 1))]
748   "! TARGET_SOFT_FLOAT"
749   "fcmp,dbl,!= %%fr0,%%fr0"
750   [(set_attr "length" "4")
751    (set_attr "type" "fpcc")])
753 ;; scc insns.
755 (define_expand "cstoresi4"
756   [(set (match_operand:SI 0 "register_operand")
757         (match_operator:SI 1 "ordered_comparison_operator"
758          [(match_operand:SI 2 "reg_or_0_operand" "")
759           (match_operand:SI 3 "arith5_operand" "")]))]
760   "!TARGET_64BIT"
761   "")
763 ;; Instruction canonicalization puts immediate operands second, which
764 ;; is the reverse of what we want.
766 (define_insn "scc"
767   [(set (match_operand:SI 0 "register_operand" "=r")
768         (match_operator:SI 3 "ordered_comparison_operator"
769                            [(match_operand:SI 1 "reg_or_0_operand" "rM")
770                             (match_operand:SI 2 "arith11_operand" "rI")]))]
771   ""
772   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
773   [(set_attr "type" "binary")
774    (set_attr "length" "8")])
776 (define_insn ""
777   [(set (match_operand:DI 0 "register_operand" "=r")
778         (match_operator:DI 3 "ordered_comparison_operator"
779                            [(match_operand:DI 1 "reg_or_0_operand" "rM")
780                             (match_operand:DI 2 "arith11_operand" "rI")]))]
781   "TARGET_64BIT"
782   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
783   [(set_attr "type" "binary")
784    (set_attr "length" "8")])
786 (define_insn "iorscc"
787   [(set (match_operand:SI 0 "register_operand" "=r")
788         (ior:SI (match_operator:SI 3 "ordered_comparison_operator"
789                                    [(match_operand:SI 1 "reg_or_0_operand" "rM")
790                                     (match_operand:SI 2 "arith11_operand" "rI")])
791                 (match_operator:SI 6 "ordered_comparison_operator"
792                                    [(match_operand:SI 4 "reg_or_0_operand" "rM")
793                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
794   ""
795   "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
796   [(set_attr "type" "binary")
797    (set_attr "length" "12")])
799 (define_insn ""
800   [(set (match_operand:DI 0 "register_operand" "=r")
801         (ior:DI (match_operator:DI 3 "ordered_comparison_operator"
802                                    [(match_operand:DI 1 "reg_or_0_operand" "rM")
803                                     (match_operand:DI 2 "arith11_operand" "rI")])
804                 (match_operator:DI 6 "ordered_comparison_operator"
805                                    [(match_operand:DI 4 "reg_or_0_operand" "rM")
806                                     (match_operand:DI 5 "arith11_operand" "rI")])))]
807   "TARGET_64BIT"
808   "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
809   [(set_attr "type" "binary")
810    (set_attr "length" "12")])
812 ;; Combiner patterns for common operations performed with the output
813 ;; from an scc insn (negscc and incscc).
814 (define_insn "negscc"
815   [(set (match_operand:SI 0 "register_operand" "=r")
816         (neg:SI (match_operator:SI 3 "ordered_comparison_operator"
817                [(match_operand:SI 1 "reg_or_0_operand" "rM")
818                 (match_operand:SI 2 "arith11_operand" "rI")])))]
819   ""
820   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
821   [(set_attr "type" "binary")
822    (set_attr "length" "8")])
824 (define_insn ""
825   [(set (match_operand:DI 0 "register_operand" "=r")
826         (neg:DI (match_operator:DI 3 "ordered_comparison_operator"
827                [(match_operand:DI 1 "reg_or_0_operand" "rM")
828                 (match_operand:DI 2 "arith11_operand" "rI")])))]
829   "TARGET_64BIT"
830   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
831   [(set_attr "type" "binary")
832    (set_attr "length" "8")])
834 ;; Patterns for adding/subtracting the result of a boolean expression from
835 ;; a register.  First we have special patterns that make use of the carry
836 ;; bit, and output only two instructions.  For the cases we can't in
837 ;; general do in two instructions, the incscc pattern at the end outputs
838 ;; two or three instructions.
840 (define_insn ""
841   [(set (match_operand:SI 0 "register_operand" "=r")
842         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
843                          (match_operand:SI 3 "arith11_operand" "rI"))
844                  (match_operand:SI 1 "register_operand" "r")))]
845   ""
846   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
847   [(set_attr "type" "binary")
848    (set_attr "length" "8")])
850 (define_insn ""
851   [(set (match_operand:DI 0 "register_operand" "=r")
852         (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
853                          (match_operand:DI 3 "arith11_operand" "rI"))
854                  (match_operand:DI 1 "register_operand" "r")))]
855   "TARGET_64BIT"
856   "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
857   [(set_attr "type" "binary")
858    (set_attr "length" "8")])
860 ; This need only accept registers for op3, since canonicalization
861 ; replaces geu with gtu when op3 is an integer.
862 (define_insn ""
863   [(set (match_operand:SI 0 "register_operand" "=r")
864         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
865                          (match_operand:SI 3 "register_operand" "r"))
866                  (match_operand:SI 1 "register_operand" "r")))]
867   ""
868   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
869   [(set_attr "type" "binary")
870    (set_attr "length" "8")])
872 (define_insn ""
873   [(set (match_operand:DI 0 "register_operand" "=r")
874         (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
875                          (match_operand:DI 3 "register_operand" "r"))
876                  (match_operand:DI 1 "register_operand" "r")))]
877   "TARGET_64BIT"
878   "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
879   [(set_attr "type" "binary")
880    (set_attr "length" "8")])
882 ; Match only integers for op3 here.  This is used as canonical form of the
883 ; geu pattern when op3 is an integer.  Don't match registers since we can't
884 ; make better code than the general incscc pattern.
885 (define_insn ""
886   [(set (match_operand:SI 0 "register_operand" "=r")
887         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
888                          (match_operand:SI 3 "int11_operand" "I"))
889                  (match_operand:SI 1 "register_operand" "r")))]
890   ""
891   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
892   [(set_attr "type" "binary")
893    (set_attr "length" "8")])
895 (define_insn ""
896   [(set (match_operand:DI 0 "register_operand" "=r")
897         (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
898                          (match_operand:DI 3 "int11_operand" "I"))
899                  (match_operand:DI 1 "register_operand" "r")))]
900   "TARGET_64BIT"
901   "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
902   [(set_attr "type" "binary")
903    (set_attr "length" "8")])
905 (define_insn "incscc"
906   [(set (match_operand:SI 0 "register_operand" "=r,r")
907         (plus:SI (match_operator:SI 4 "ordered_comparison_operator"
908                     [(match_operand:SI 2 "register_operand" "r,r")
909                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
910                  (match_operand:SI 1 "register_operand" "0,?r")))]
911   ""
912   "@
913    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
914    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
915   [(set_attr "type" "binary,binary")
916    (set_attr "length" "8,12")])
918 (define_insn ""
919   [(set (match_operand:DI 0 "register_operand" "=r,r")
920         (plus:DI (match_operator:DI 4 "ordered_comparison_operator"
921                     [(match_operand:DI 2 "register_operand" "r,r")
922                      (match_operand:DI 3 "arith11_operand" "rI,rI")])
923                  (match_operand:DI 1 "register_operand" "0,?r")))]
924   "TARGET_64BIT"
925   "@
926    cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
927    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
928   [(set_attr "type" "binary,binary")
929    (set_attr "length" "8,12")])
931 (define_insn ""
932   [(set (match_operand:SI 0 "register_operand" "=r")
933         (minus:SI (match_operand:SI 1 "register_operand" "r")
934                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
935                           (match_operand:SI 3 "arith11_operand" "rI"))))]
936   ""
937   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
938   [(set_attr "type" "binary")
939    (set_attr "length" "8")])
941 (define_insn ""
942   [(set (match_operand:DI 0 "register_operand" "=r")
943         (minus:DI (match_operand:DI 1 "register_operand" "r")
944                   (gtu:DI (match_operand:DI 2 "register_operand" "r")
945                           (match_operand:DI 3 "arith11_operand" "rI"))))]
946   "TARGET_64BIT"
947   "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
948   [(set_attr "type" "binary")
949    (set_attr "length" "8")])
951 (define_insn ""
952   [(set (match_operand:SI 0 "register_operand" "=r")
953         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
954                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
955                                     (match_operand:SI 3 "arith11_operand" "rI")))
956                   (match_operand:SI 4 "register_operand" "r")))]
957   ""
958   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
959   [(set_attr "type" "binary")
960    (set_attr "length" "8")])
962 (define_insn ""
963   [(set (match_operand:DI 0 "register_operand" "=r")
964         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
965                             (gtu:DI (match_operand:DI 2 "register_operand" "r")
966                                     (match_operand:DI 3 "arith11_operand" "rI")))
967                   (match_operand:DI 4 "register_operand" "r")))]
968   "TARGET_64BIT"
969   "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
970   [(set_attr "type" "binary")
971    (set_attr "length" "8")])
973 ; This need only accept registers for op3, since canonicalization
974 ; replaces ltu with leu when op3 is an integer.
975 (define_insn ""
976   [(set (match_operand:SI 0 "register_operand" "=r")
977         (minus:SI (match_operand:SI 1 "register_operand" "r")
978                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
979                           (match_operand:SI 3 "register_operand" "r"))))]
980   ""
981   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
982   [(set_attr "type" "binary")
983    (set_attr "length" "8")])
985 (define_insn ""
986   [(set (match_operand:DI 0 "register_operand" "=r")
987         (minus:DI (match_operand:DI 1 "register_operand" "r")
988                   (ltu:DI (match_operand:DI 2 "register_operand" "r")
989                           (match_operand:DI 3 "register_operand" "r"))))]
990   "TARGET_64BIT"
991   "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
992   [(set_attr "type" "binary")
993    (set_attr "length" "8")])
995 (define_insn ""
996   [(set (match_operand:SI 0 "register_operand" "=r")
997         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
998                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
999                                     (match_operand:SI 3 "register_operand" "r")))
1000                   (match_operand:SI 4 "register_operand" "r")))]
1001   ""
1002   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1003   [(set_attr "type" "binary")
1004    (set_attr "length" "8")])
1006 (define_insn ""
1007   [(set (match_operand:DI 0 "register_operand" "=r")
1008         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1009                             (ltu:DI (match_operand:DI 2 "register_operand" "r")
1010                                     (match_operand:DI 3 "register_operand" "r")))
1011                   (match_operand:DI 4 "register_operand" "r")))]
1012   "TARGET_64BIT"
1013   "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1014   [(set_attr "type" "binary")
1015    (set_attr "length" "8")])
1017 ; Match only integers for op3 here.  This is used as canonical form of the
1018 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
1019 ; make better code than the general incscc pattern.
1020 (define_insn ""
1021   [(set (match_operand:SI 0 "register_operand" "=r")
1022         (minus:SI (match_operand:SI 1 "register_operand" "r")
1023                   (leu:SI (match_operand:SI 2 "register_operand" "r")
1024                           (match_operand:SI 3 "int11_operand" "I"))))]
1025   ""
1026   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1027   [(set_attr "type" "binary")
1028    (set_attr "length" "8")])
1030 (define_insn ""
1031   [(set (match_operand:DI 0 "register_operand" "=r")
1032         (minus:DI (match_operand:DI 1 "register_operand" "r")
1033                   (leu:DI (match_operand:DI 2 "register_operand" "r")
1034                           (match_operand:DI 3 "int11_operand" "I"))))]
1035   "TARGET_64BIT"
1036   "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1037   [(set_attr "type" "binary")
1038    (set_attr "length" "8")])
1040 (define_insn ""
1041   [(set (match_operand:SI 0 "register_operand" "=r")
1042         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1043                             (leu:SI (match_operand:SI 2 "register_operand" "r")
1044                                     (match_operand:SI 3 "int11_operand" "I")))
1045                   (match_operand:SI 4 "register_operand" "r")))]
1046   ""
1047   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1048   [(set_attr "type" "binary")
1049    (set_attr "length" "8")])
1051 (define_insn ""
1052   [(set (match_operand:DI 0 "register_operand" "=r")
1053         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1054                             (leu:DI (match_operand:DI 2 "register_operand" "r")
1055                                     (match_operand:DI 3 "int11_operand" "I")))
1056                   (match_operand:DI 4 "register_operand" "r")))]
1057   "TARGET_64BIT"
1058   "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1059   [(set_attr "type" "binary")
1060    (set_attr "length" "8")])
1062 (define_insn "decscc"
1063   [(set (match_operand:SI 0 "register_operand" "=r,r")
1064         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1065                   (match_operator:SI 4 "ordered_comparison_operator"
1066                      [(match_operand:SI 2 "register_operand" "r,r")
1067                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1068   ""
1069   "@
1070    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1071    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1072   [(set_attr "type" "binary,binary")
1073    (set_attr "length" "8,12")])
1075 (define_insn ""
1076   [(set (match_operand:DI 0 "register_operand" "=r,r")
1077         (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1078                   (match_operator:DI 4 "ordered_comparison_operator"
1079                      [(match_operand:DI 2 "register_operand" "r,r")
1080                       (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1081   "TARGET_64BIT"
1082   "@
1083    cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1084    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1085   [(set_attr "type" "binary,binary")
1086    (set_attr "length" "8,12")])
1088 ; Patterns for max and min.  (There is no need for an earlyclobber in the
1089 ; last alternative since the middle alternative will match if op0 == op1.)
1091 (define_insn "sminsi3"
1092   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1093         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1094                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1095   ""
1096   "@
1097   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1098   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1099   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1100 [(set_attr "type" "multi,multi,multi")
1101  (set_attr "length" "8,8,8")])
1103 (define_insn "smindi3"
1104   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1105         (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1106                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1107   "TARGET_64BIT"
1108   "@
1109   cmpclr,*> %2,%0,%%r0\;copy %2,%0
1110   cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1111   cmpclr,*> %1,%r2,%0\;copy %1,%0"
1112 [(set_attr "type" "multi,multi,multi")
1113  (set_attr "length" "8,8,8")])
1115 (define_insn "uminsi3"
1116   [(set (match_operand:SI 0 "register_operand" "=r,r")
1117         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1118                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1119   ""
1120   "@
1121   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1122   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1123 [(set_attr "type" "multi,multi")
1124  (set_attr "length" "8,8")])
1126 (define_insn "umindi3"
1127   [(set (match_operand:DI 0 "register_operand" "=r,r")
1128         (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1129                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1130   "TARGET_64BIT"
1131   "@
1132   cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1133   cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1134 [(set_attr "type" "multi,multi")
1135  (set_attr "length" "8,8")])
1137 (define_insn "smaxsi3"
1138   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1139         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1140                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1141   ""
1142   "@
1143   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1144   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1145   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1146 [(set_attr "type" "multi,multi,multi")
1147  (set_attr "length" "8,8,8")])
1149 (define_insn "smaxdi3"
1150   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1151         (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1152                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1153   "TARGET_64BIT"
1154   "@
1155   cmpclr,*< %2,%0,%%r0\;copy %2,%0
1156   cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1157   cmpclr,*< %1,%r2,%0\;copy %1,%0"
1158 [(set_attr "type" "multi,multi,multi")
1159  (set_attr "length" "8,8,8")])
1161 (define_insn "umaxsi3"
1162   [(set (match_operand:SI 0 "register_operand" "=r,r")
1163         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1164                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1165   ""
1166   "@
1167   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1168   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1169 [(set_attr "type" "multi,multi")
1170  (set_attr "length" "8,8")])
1172 (define_insn "umaxdi3"
1173   [(set (match_operand:DI 0 "register_operand" "=r,r")
1174         (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1175                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1176   "TARGET_64BIT"
1177   "@
1178   cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1179   cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1180 [(set_attr "type" "multi,multi")
1181  (set_attr "length" "8,8")])
1183 (define_insn "absqi2"
1184   [(set (match_operand:QI 0 "register_operand" "=r")
1185         (abs:QI (match_operand:QI 1 "register_operand" "r")))]
1186   ""
1187   "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1188   [(set_attr "type" "multi")
1189    (set_attr "length" "8")])
1191 (define_insn "abshi2"
1192   [(set (match_operand:HI 0 "register_operand" "=r")
1193         (abs:HI (match_operand:HI 1 "register_operand" "r")))]
1194   ""
1195   "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1196   [(set_attr "type" "multi")
1197    (set_attr "length" "8")])
1199 (define_insn "abssi2"
1200   [(set (match_operand:SI 0 "register_operand" "=r")
1201         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1202   ""
1203   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1204   [(set_attr "type" "multi")
1205    (set_attr "length" "8")])
1207 (define_insn "absdi2"
1208   [(set (match_operand:DI 0 "register_operand" "=r")
1209         (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1210   "TARGET_64BIT"
1211   "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1212   [(set_attr "type" "multi")
1213    (set_attr "length" "8")])
1215 (define_insn "bswaphi2"
1216   [(set (match_operand:HI 0 "register_operand" "=&r")
1217         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1218   ""
1219   "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1220   [(set_attr "type" "multi")
1221    (set_attr "length" "8")])
1223 (define_insn "bswapsi2"
1224   [(set (match_operand:SI 0 "register_operand" "=&r")
1225         (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1226   ""
1227   "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1228   [(set_attr "type" "multi")
1229    (set_attr "length" "12")])
1231 (define_insn "bswapdi2"
1232   [(set (match_operand:DI 0 "register_operand" "=&r")
1233         (bswap:DI (match_operand:DI 1 "register_operand" "r")))
1234    (clobber (match_scratch:DI 2 "=r"))]
1235   "TARGET_64BIT"
1236   "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1237   [(set_attr "type" "multi")
1238    (set_attr "length" "16")])
1240 ;;; Experimental conditional move patterns
1242 (define_expand "movsicc"
1243   [(set (match_operand:SI 0 "register_operand" "")
1244         (if_then_else:SI
1245          (match_operand 1 "ordered_comparison_operator" "")
1246          (match_operand:SI 2 "reg_or_cint_move_operand" "")
1247          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1248   ""
1249   "
1251   if (GET_MODE (XEXP (operands[1], 0)) != SImode
1252       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1253     FAIL;
1256 ;; We used to accept any register for op1.
1258 ;; However, it loses sometimes because the compiler will end up using
1259 ;; different registers for op0 and op1 in some critical cases.  local-alloc
1260 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1262 ;; If/when global register allocation supports tying we should allow any
1263 ;; register for op1 again.
1264 (define_insn ""
1265   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1266         (if_then_else:SI
1267          (match_operator 2 "ordered_comparison_operator"
1268             [(match_operand:SI 3 "register_operand" "r,r,r,r")
1269              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1270          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1271          (const_int 0)))]
1272   ""
1273   "@
1274    {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1275    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1276    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1277    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1278   [(set_attr "type" "multi,multi,multi,nullshift")
1279    (set_attr "length" "8,8,8,8")])
1281 (define_insn ""
1282   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1283         (if_then_else:SI
1284          (match_operator 5 "ordered_comparison_operator"
1285             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1286              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1287          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1288          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1289   ""
1290   "@
1291    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1292    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1293    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1294    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1295    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1296    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1297    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1298    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1299   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1300    (set_attr "length" "8,8,8,8,8,8,8,8")])
1302 (define_expand "movdicc"
1303   [(set (match_operand:DI 0 "register_operand" "")
1304         (if_then_else:DI
1305          (match_operand 1 "ordered_comparison_operator" "")
1306          (match_operand:DI 2 "reg_or_cint_move_operand" "")
1307          (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1308   "TARGET_64BIT"
1309   "
1311   if (GET_MODE (XEXP (operands[1], 0)) != DImode
1312       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1313     FAIL;
1316 ; We need the first constraint alternative in order to avoid
1317 ; earlyclobbers on all other alternatives.
1318 (define_insn ""
1319   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1320         (if_then_else:DI
1321          (match_operator 2 "ordered_comparison_operator"
1322             [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1323              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1324          (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1325          (const_int 0)))]
1326   "TARGET_64BIT"
1327   "@
1328    cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1329    cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1330    cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1331    cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1332    cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1333   [(set_attr "type" "multi,multi,multi,multi,nullshift")
1334    (set_attr "length" "8,8,8,8,8")])
1336 (define_insn ""
1337   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1338         (if_then_else:DI
1339          (match_operator 5 "ordered_comparison_operator"
1340             [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1341              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1342          (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1343          (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1344   "TARGET_64BIT"
1345   "@
1346    cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1347    cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1348    cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1349    cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1350    cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1351    cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1352    cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1353    cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1354   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1355    (set_attr "length" "8,8,8,8,8,8,8,8")])
1357 ;; Conditional Branches
1359 (define_expand "cbranchdi4"
1360   [(set (pc)
1361         (if_then_else (match_operator 0 "ordered_comparison_operator"
1362                        [(match_operand:DI 1 "reg_or_0_operand" "")
1363                         (match_operand:DI 2 "register_operand" "")])
1364                       (label_ref (match_operand 3 "" ""))
1365                       (pc)))]
1366   "TARGET_64BIT"
1367   "")
1369 (define_expand "cbranchsi4"
1370   [(set (pc)
1371         (if_then_else (match_operator 0 "ordered_comparison_operator"
1372                        [(match_operand:SI 1 "reg_or_0_operand" "")
1373                         (match_operand:SI 2 "arith5_operand" "")])
1374                       (label_ref (match_operand 3 "" ""))
1375                       (pc)))]
1376   ""
1377   "")
1379 (define_expand "cbranchsf4"
1380   [(set (pc)
1381         (if_then_else (match_operator 0 "comparison_operator"
1382                        [(match_operand:SF 1 "reg_or_0_operand" "")
1383                         (match_operand:SF 2 "reg_or_0_operand" "")])
1384                       (label_ref (match_operand 3 "" ""))
1385                       (pc)))]
1386   "! TARGET_SOFT_FLOAT"
1387   "
1389   pa_emit_bcond_fp (operands);
1390   DONE;
1394 (define_expand "cbranchdf4"
1395   [(set (pc)
1396         (if_then_else (match_operator 0 "comparison_operator"
1397                        [(match_operand:DF 1 "reg_or_0_operand" "")
1398                         (match_operand:DF 2 "reg_or_0_operand" "")])
1399                       (label_ref (match_operand 3 "" ""))
1400                       (pc)))]
1401   "! TARGET_SOFT_FLOAT"
1402   "
1404   pa_emit_bcond_fp (operands);
1405   DONE;
1408 ;; Match the branch patterns.
1411 ;; Note a long backward conditional branch with an annulled delay slot
1412 ;; has a length of 12.
1413 (define_insn ""
1414   [(set (pc)
1415         (if_then_else
1416          (match_operator 3 "ordered_comparison_operator"
1417                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1418                           (match_operand:SI 2 "arith5_operand" "rL")])
1419          (label_ref (match_operand 0 "" ""))
1420          (pc)))]
1421   ""
1422   "*
1424   return pa_output_cbranch (operands, 0, insn);
1426 [(set_attr "type" "cbranch")
1427  (set (attr "length")
1428     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1429                (const_int MAX_12BIT_OFFSET))
1430            (const_int 4)
1431            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1432                (const_int MAX_17BIT_OFFSET))
1433            (const_int 8)
1434            (match_test "TARGET_PORTABLE_RUNTIME")
1435            (const_int 24)
1436            (not (match_test "flag_pic"))
1437            (const_int 20)]
1438           (const_int 28)))])
1440 ;; Match the negated branch.
1442 (define_insn ""
1443   [(set (pc)
1444         (if_then_else
1445          (match_operator 3 "ordered_comparison_operator"
1446                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1447                           (match_operand:SI 2 "arith5_operand" "rL")])
1448          (pc)
1449          (label_ref (match_operand 0 "" ""))))]
1450   ""
1451   "*
1453   return pa_output_cbranch (operands, 1, insn);
1455 [(set_attr "type" "cbranch")
1456  (set (attr "length")
1457     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1458                (const_int MAX_12BIT_OFFSET))
1459            (const_int 4)
1460            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1461                (const_int MAX_17BIT_OFFSET))
1462            (const_int 8)
1463            (match_test "TARGET_PORTABLE_RUNTIME")
1464            (const_int 24)
1465            (not (match_test "flag_pic"))
1466            (const_int 20)]
1467           (const_int 28)))])
1469 (define_insn ""
1470   [(set (pc)
1471         (if_then_else
1472          (match_operator 3 "ordered_comparison_operator"
1473                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1474                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1475          (label_ref (match_operand 0 "" ""))
1476          (pc)))]
1477   "TARGET_64BIT"
1478   "*
1480   return pa_output_cbranch (operands, 0, insn);
1482 [(set_attr "type" "cbranch")
1483  (set (attr "length")
1484     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1485                (const_int MAX_12BIT_OFFSET))
1486            (const_int 4)
1487            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1488                (const_int MAX_17BIT_OFFSET))
1489            (const_int 8)
1490            (match_test "TARGET_PORTABLE_RUNTIME")
1491            (const_int 24)
1492            (not (match_test "flag_pic"))
1493            (const_int 20)]
1494           (const_int 28)))])
1496 ;; Match the negated branch.
1498 (define_insn ""
1499   [(set (pc)
1500         (if_then_else
1501          (match_operator 3 "ordered_comparison_operator"
1502                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1503                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1504          (pc)
1505          (label_ref (match_operand 0 "" ""))))]
1506   "TARGET_64BIT"
1507   "*
1509   return pa_output_cbranch (operands, 1, insn);
1511 [(set_attr "type" "cbranch")
1512  (set (attr "length")
1513     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1514                (const_int MAX_12BIT_OFFSET))
1515            (const_int 4)
1516            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1517                (const_int MAX_17BIT_OFFSET))
1518            (const_int 8)
1519            (match_test "TARGET_PORTABLE_RUNTIME")
1520            (const_int 24)
1521            (not (match_test "flag_pic"))
1522            (const_int 20)]
1523           (const_int 28)))])
1524 (define_insn ""
1525   [(set (pc)
1526         (if_then_else
1527          (match_operator 3 "cmpib_comparison_operator"
1528                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1529                           (match_operand:DI 2 "arith5_operand" "rL")])
1530          (label_ref (match_operand 0 "" ""))
1531          (pc)))]
1532   "TARGET_64BIT"
1533   "*
1535   return pa_output_cbranch (operands, 0, insn);
1537 [(set_attr "type" "cbranch")
1538  (set (attr "length")
1539     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1540                (const_int MAX_12BIT_OFFSET))
1541            (const_int 4)
1542            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1543                (const_int MAX_17BIT_OFFSET))
1544            (const_int 8)
1545            (match_test "TARGET_PORTABLE_RUNTIME")
1546            (const_int 24)
1547            (not (match_test "flag_pic"))
1548            (const_int 20)]
1549           (const_int 28)))])
1551 ;; Match the negated branch.
1553 (define_insn ""
1554   [(set (pc)
1555         (if_then_else
1556          (match_operator 3 "cmpib_comparison_operator"
1557                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1558                           (match_operand:DI 2 "arith5_operand" "rL")])
1559          (pc)
1560          (label_ref (match_operand 0 "" ""))))]
1561   "TARGET_64BIT"
1562   "*
1564   return pa_output_cbranch (operands, 1, insn);
1566 [(set_attr "type" "cbranch")
1567  (set (attr "length")
1568     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1569                (const_int MAX_12BIT_OFFSET))
1570            (const_int 4)
1571            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1572                (const_int MAX_17BIT_OFFSET))
1573            (const_int 8)
1574            (match_test "TARGET_PORTABLE_RUNTIME")
1575            (const_int 24)
1576            (not (match_test "flag_pic"))
1577            (const_int 20)]
1578           (const_int 28)))])
1580 ;; Branch on Bit patterns.
1581 (define_insn ""
1582   [(set (pc)
1583         (if_then_else
1584          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1585                               (const_int 1)
1586                               (match_operand:SI 1 "uint5_operand" ""))
1587              (const_int 0))
1588          (label_ref (match_operand 2 "" ""))
1589          (pc)))]
1590   ""
1591   "*
1593   return pa_output_bb (operands, 0, insn, 0);
1595 [(set_attr "type" "cbranch")
1596  (set (attr "length")
1597     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1598                (const_int MAX_12BIT_OFFSET))
1599            (const_int 4)
1600            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1601                (const_int MAX_17BIT_OFFSET))
1602            (const_int 8)
1603            (match_test "TARGET_PORTABLE_RUNTIME")
1604            (const_int 24)
1605            (not (match_test "flag_pic"))
1606            (const_int 20)]
1607           (const_int 28)))])
1609 (define_insn ""
1610   [(set (pc)
1611         (if_then_else
1612          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1613                               (const_int 1)
1614                               (match_operand:DI 1 "uint32_operand" ""))
1615              (const_int 0))
1616          (label_ref (match_operand 2 "" ""))
1617          (pc)))]
1618   "TARGET_64BIT"
1619   "*
1621   return pa_output_bb (operands, 0, insn, 0);
1623 [(set_attr "type" "cbranch")
1624  (set (attr "length")
1625     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1626                (const_int MAX_12BIT_OFFSET))
1627            (const_int 4)
1628            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1629                (const_int MAX_17BIT_OFFSET))
1630            (const_int 8)
1631            (match_test "TARGET_PORTABLE_RUNTIME")
1632            (const_int 24)
1633            (not (match_test "flag_pic"))
1634            (const_int 20)]
1635           (const_int 28)))])
1637 (define_insn ""
1638   [(set (pc)
1639         (if_then_else
1640          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1641                               (const_int 1)
1642                               (match_operand:SI 1 "uint5_operand" ""))
1643              (const_int 0))
1644          (pc)
1645          (label_ref (match_operand 2 "" ""))))]
1646   ""
1647   "*
1649   return pa_output_bb (operands, 1, insn, 0);
1651 [(set_attr "type" "cbranch")
1652  (set (attr "length")
1653     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1654                (const_int MAX_12BIT_OFFSET))
1655            (const_int 4)
1656            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1657                (const_int MAX_17BIT_OFFSET))
1658            (const_int 8)
1659            (match_test "TARGET_PORTABLE_RUNTIME")
1660            (const_int 24)
1661            (not (match_test "flag_pic"))
1662            (const_int 20)]
1663           (const_int 28)))])
1665 (define_insn ""
1666   [(set (pc)
1667         (if_then_else
1668          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1669                               (const_int 1)
1670                               (match_operand:DI 1 "uint32_operand" ""))
1671              (const_int 0))
1672          (pc)
1673          (label_ref (match_operand 2 "" ""))))]
1674   "TARGET_64BIT"
1675   "*
1677   return pa_output_bb (operands, 1, insn, 0);
1679 [(set_attr "type" "cbranch")
1680  (set (attr "length")
1681     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1682                (const_int MAX_12BIT_OFFSET))
1683            (const_int 4)
1684            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1685                (const_int MAX_17BIT_OFFSET))
1686            (const_int 8)
1687            (match_test "TARGET_PORTABLE_RUNTIME")
1688            (const_int 24)
1689            (not (match_test "flag_pic"))
1690            (const_int 20)]
1691           (const_int 28)))])
1693 (define_insn ""
1694   [(set (pc)
1695         (if_then_else
1696          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1697                               (const_int 1)
1698                               (match_operand:SI 1 "uint5_operand" ""))
1699              (const_int 0))
1700          (label_ref (match_operand 2 "" ""))
1701          (pc)))]
1702   ""
1703   "*
1705   return pa_output_bb (operands, 0, insn, 1);
1707 [(set_attr "type" "cbranch")
1708  (set (attr "length")
1709     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1710                (const_int MAX_12BIT_OFFSET))
1711            (const_int 4)
1712            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1713                (const_int MAX_17BIT_OFFSET))
1714            (const_int 8)
1715            (match_test "TARGET_PORTABLE_RUNTIME")
1716            (const_int 24)
1717            (not (match_test "flag_pic"))
1718            (const_int 20)]
1719           (const_int 28)))])
1721 (define_insn ""
1722   [(set (pc)
1723         (if_then_else
1724          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1725                               (const_int 1)
1726                               (match_operand:DI 1 "uint32_operand" ""))
1727              (const_int 0))
1728          (label_ref (match_operand 2 "" ""))
1729          (pc)))]
1730   "TARGET_64BIT"
1731   "*
1733   return pa_output_bb (operands, 0, insn, 1);
1735 [(set_attr "type" "cbranch")
1736  (set (attr "length")
1737     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1738                (const_int MAX_12BIT_OFFSET))
1739            (const_int 4)
1740            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1741                (const_int MAX_17BIT_OFFSET))
1742            (const_int 8)
1743            (match_test "TARGET_PORTABLE_RUNTIME")
1744            (const_int 24)
1745            (not (match_test "flag_pic"))
1746            (const_int 20)]
1747           (const_int 28)))])
1749 (define_insn ""
1750   [(set (pc)
1751         (if_then_else
1752          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1753                               (const_int 1)
1754                               (match_operand:SI 1 "uint5_operand" ""))
1755              (const_int 0))
1756          (pc)
1757          (label_ref (match_operand 2 "" ""))))]
1758   ""
1759   "*
1761   return pa_output_bb (operands, 1, insn, 1);
1763 [(set_attr "type" "cbranch")
1764  (set (attr "length")
1765     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1766                (const_int MAX_12BIT_OFFSET))
1767            (const_int 4)
1768            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1769                (const_int MAX_17BIT_OFFSET))
1770            (const_int 8)
1771            (match_test "TARGET_PORTABLE_RUNTIME")
1772            (const_int 24)
1773            (not (match_test "flag_pic"))
1774            (const_int 20)]
1775           (const_int 28)))])
1777 (define_insn ""
1778   [(set (pc)
1779         (if_then_else
1780          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1781                               (const_int 1)
1782                               (match_operand:DI 1 "uint32_operand" ""))
1783              (const_int 0))
1784          (pc)
1785          (label_ref (match_operand 2 "" ""))))]
1786   "TARGET_64BIT"
1787   "*
1789   return pa_output_bb (operands, 1, insn, 1);
1791 [(set_attr "type" "cbranch")
1792  (set (attr "length")
1793     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1794                (const_int MAX_12BIT_OFFSET))
1795            (const_int 4)
1796            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1797                (const_int MAX_17BIT_OFFSET))
1798            (const_int 8)
1799            (match_test "TARGET_PORTABLE_RUNTIME")
1800            (const_int 24)
1801            (not (match_test "flag_pic"))
1802            (const_int 20)]
1803           (const_int 28)))])
1805 ;; Branch on Variable Bit patterns.
1806 (define_insn ""
1807   [(set (pc)
1808         (if_then_else
1809          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1810                               (const_int 1)
1811                               (match_operand:SI 1 "register_operand" "q"))
1812              (const_int 0))
1813          (label_ref (match_operand 2 "" ""))
1814          (pc)))]
1815   ""
1816   "*
1818   return pa_output_bvb (operands, 0, insn, 0);
1820 [(set_attr "type" "cbranch")
1821  (set (attr "length")
1822     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1823                (const_int MAX_12BIT_OFFSET))
1824            (const_int 4)
1825            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1826                (const_int MAX_17BIT_OFFSET))
1827            (const_int 8)
1828            (match_test "TARGET_PORTABLE_RUNTIME")
1829            (const_int 24)
1830            (not (match_test "flag_pic"))
1831            (const_int 20)]
1832           (const_int 28)))])
1834 (define_insn ""
1835   [(set (pc)
1836         (if_then_else
1837          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1838                               (const_int 1)
1839                               (match_operand:DI 1 "register_operand" "q"))
1840              (const_int 0))
1841          (label_ref (match_operand 2 "" ""))
1842          (pc)))]
1843   "TARGET_64BIT"
1844   "*
1846   return pa_output_bvb (operands, 0, insn, 0);
1848 [(set_attr "type" "cbranch")
1849  (set (attr "length")
1850     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1851                (const_int MAX_12BIT_OFFSET))
1852            (const_int 4)
1853            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1854                (const_int MAX_17BIT_OFFSET))
1855            (const_int 8)
1856            (match_test "TARGET_PORTABLE_RUNTIME")
1857            (const_int 24)
1858            (not (match_test "flag_pic"))
1859            (const_int 20)]
1860           (const_int 28)))])
1862 (define_insn ""
1863   [(set (pc)
1864         (if_then_else
1865          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1866                               (const_int 1)
1867                               (match_operand:SI 1 "register_operand" "q"))
1868              (const_int 0))
1869          (pc)
1870          (label_ref (match_operand 2 "" ""))))]
1871   ""
1872   "*
1874   return pa_output_bvb (operands, 1, insn, 0);
1876 [(set_attr "type" "cbranch")
1877  (set (attr "length")
1878     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1879                (const_int MAX_12BIT_OFFSET))
1880            (const_int 4)
1881            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1882                (const_int MAX_17BIT_OFFSET))
1883            (const_int 8)
1884            (match_test "TARGET_PORTABLE_RUNTIME")
1885            (const_int 24)
1886            (not (match_test "flag_pic"))
1887            (const_int 20)]
1888           (const_int 28)))])
1890 (define_insn ""
1891   [(set (pc)
1892         (if_then_else
1893          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1894                               (const_int 1)
1895                               (match_operand:DI 1 "register_operand" "q"))
1896              (const_int 0))
1897          (pc)
1898          (label_ref (match_operand 2 "" ""))))]
1899   "TARGET_64BIT"
1900   "*
1902   return pa_output_bvb (operands, 1, insn, 0);
1904 [(set_attr "type" "cbranch")
1905  (set (attr "length")
1906     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1907                (const_int MAX_12BIT_OFFSET))
1908            (const_int 4)
1909            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1910                (const_int MAX_17BIT_OFFSET))
1911            (const_int 8)
1912            (match_test "TARGET_PORTABLE_RUNTIME")
1913            (const_int 24)
1914            (not (match_test "flag_pic"))
1915            (const_int 20)]
1916           (const_int 28)))])
1918 (define_insn ""
1919   [(set (pc)
1920         (if_then_else
1921          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1922                               (const_int 1)
1923                               (match_operand:SI 1 "register_operand" "q"))
1924              (const_int 0))
1925          (label_ref (match_operand 2 "" ""))
1926          (pc)))]
1927   ""
1928   "*
1930   return pa_output_bvb (operands, 0, insn, 1);
1932 [(set_attr "type" "cbranch")
1933  (set (attr "length")
1934     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1935                (const_int MAX_12BIT_OFFSET))
1936            (const_int 4)
1937            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1938                (const_int MAX_17BIT_OFFSET))
1939            (const_int 8)
1940            (match_test "TARGET_PORTABLE_RUNTIME")
1941            (const_int 24)
1942            (not (match_test "flag_pic"))
1943            (const_int 20)]
1944           (const_int 28)))])
1946 (define_insn ""
1947   [(set (pc)
1948         (if_then_else
1949          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1950                               (const_int 1)
1951                               (match_operand:DI 1 "register_operand" "q"))
1952              (const_int 0))
1953          (label_ref (match_operand 2 "" ""))
1954          (pc)))]
1955   "TARGET_64BIT"
1956   "*
1958   return pa_output_bvb (operands, 0, insn, 1);
1960 [(set_attr "type" "cbranch")
1961  (set (attr "length")
1962     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1963                (const_int MAX_12BIT_OFFSET))
1964            (const_int 4)
1965            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1966                (const_int MAX_17BIT_OFFSET))
1967            (const_int 8)
1968            (match_test "TARGET_PORTABLE_RUNTIME")
1969            (const_int 24)
1970            (not (match_test "flag_pic"))
1971            (const_int 20)]
1972           (const_int 28)))])
1974 (define_insn ""
1975   [(set (pc)
1976         (if_then_else
1977          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1978                               (const_int 1)
1979                               (match_operand:SI 1 "register_operand" "q"))
1980              (const_int 0))
1981          (pc)
1982          (label_ref (match_operand 2 "" ""))))]
1983   ""
1984   "*
1986   return pa_output_bvb (operands, 1, insn, 1);
1988 [(set_attr "type" "cbranch")
1989  (set (attr "length")
1990     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1991                (const_int MAX_12BIT_OFFSET))
1992            (const_int 4)
1993            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1994                (const_int MAX_17BIT_OFFSET))
1995            (const_int 8)
1996            (match_test "TARGET_PORTABLE_RUNTIME")
1997            (const_int 24)
1998            (not (match_test "flag_pic"))
1999            (const_int 20)]
2000           (const_int 28)))])
2002 (define_insn ""
2003   [(set (pc)
2004         (if_then_else
2005          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2006                               (const_int 1)
2007                               (match_operand:DI 1 "register_operand" "q"))
2008              (const_int 0))
2009          (pc)
2010          (label_ref (match_operand 2 "" ""))))]
2011   "TARGET_64BIT"
2012   "*
2014   return pa_output_bvb (operands, 1, insn, 1);
2016 [(set_attr "type" "cbranch")
2017  (set (attr "length")
2018     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2019                (const_int MAX_12BIT_OFFSET))
2020            (const_int 4)
2021            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2022                (const_int MAX_17BIT_OFFSET))
2023            (const_int 8)
2024            (match_test "TARGET_PORTABLE_RUNTIME")
2025            (const_int 24)
2026            (not (match_test "flag_pic"))
2027            (const_int 20)]
2028           (const_int 28)))])
2030 ;; Floating point branches
2032 ;; ??? Nullification is handled differently from other branches.
2033 ;; If nullification is specified, the delay slot is nullified on any
2034 ;; taken branch regardless of branch direction.
2035 (define_insn ""
2036   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2037                            (label_ref (match_operand 0 "" ""))
2038                            (pc)))]
2039   "!TARGET_SOFT_FLOAT"
2040   "*
2042   int length = get_attr_length (insn);
2043   rtx xoperands[1];
2044   int nullify, xdelay;
2046   if (length < 16)
2047     return \"ftest\;b%* %l0\";
2049   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2050     {
2051       nullify = 1;
2052       xdelay = 0;
2053       xoperands[0] = GEN_INT (length - 8);
2054     }
2055   else
2056     {
2057       nullify = 0;
2058       xdelay = 1;
2059       xoperands[0] = GEN_INT (length - 4);
2060     }
2062   if (nullify)
2063     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2064   else
2065     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2066   return pa_output_lbranch (operands[0], insn, xdelay);
2068 [(set_attr "type" "fbranch")
2069  (set (attr "length")
2070     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2071                (const_int MAX_17BIT_OFFSET))
2072            (const_int 8)
2073            (match_test "TARGET_PORTABLE_RUNTIME")
2074            (const_int 32)
2075            (not (match_test "flag_pic"))
2076            (const_int 28)]
2077           (const_int 36)))])
2079 (define_insn ""
2080   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2081                            (pc)
2082                            (label_ref (match_operand 0 "" ""))))]
2083   "!TARGET_SOFT_FLOAT"
2084   "*
2086   int length = get_attr_length (insn);
2087   rtx xoperands[1];
2088   int nullify, xdelay;
2090   if (length < 16)
2091     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2093   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2094     {
2095       nullify = 1;
2096       xdelay = 0;
2097       xoperands[0] = GEN_INT (length - 4);
2098     }
2099   else
2100     {
2101       nullify = 0;
2102       xdelay = 1;
2103       xoperands[0] = GEN_INT (length);
2104     }
2106   if (nullify)
2107     output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2108   else
2109     output_asm_insn (\"ftest\;b .+%0\", xoperands);
2110   return pa_output_lbranch (operands[0], insn, xdelay);
2112 [(set_attr "type" "fbranch")
2113  (set (attr "length")
2114     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2115                (const_int MAX_17BIT_OFFSET))
2116            (const_int 12)
2117            (match_test "TARGET_PORTABLE_RUNTIME")
2118            (const_int 28)
2119            (not (match_test "flag_pic"))
2120            (const_int 24)]
2121           (const_int 32)))])
2123 ;; Move instructions
2125 (define_expand "movsi"
2126   [(set (match_operand:SI 0 "general_operand" "")
2127         (match_operand:SI 1 "general_operand" ""))]
2128   ""
2129   "
2131   if (pa_emit_move_sequence (operands, SImode, 0))
2132     DONE;
2135 ;; Handle SImode input reloads requiring %r1 as a scratch register.
2136 (define_expand "reload_insi_r1"
2137   [(set (match_operand:SI 0 "register_operand" "=Z")
2138         (match_operand:SI 1 "non_hard_reg_operand" ""))
2139    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2140   ""
2141   "
2143   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2144     DONE;
2146   /* We don't want the clobber emitted, so handle this ourselves.  */
2147   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2148   DONE;
2151 ;; Handle SImode input reloads requiring a general register as a
2152 ;; scratch register.
2153 (define_expand "reload_insi"
2154   [(set (match_operand:SI 0 "register_operand" "=Z")
2155         (match_operand:SI 1 "non_hard_reg_operand" ""))
2156    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2157   ""
2158   "
2160   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2161     DONE;
2163   /* We don't want the clobber emitted, so handle this ourselves.  */
2164   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2165   DONE;
2168 ;; Handle SImode output reloads requiring a general register as a
2169 ;; scratch register.
2170 (define_expand "reload_outsi"
2171   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2172         (match_operand:SI 1  "register_operand" "Z"))
2173    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2174   ""
2175   "
2177   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2178     DONE;
2180   /* We don't want the clobber emitted, so handle this ourselves.  */
2181   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2182   DONE;
2185 (define_insn ""
2186   [(set (match_operand:SI 0 "move_dest_operand"
2187                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2188         (match_operand:SI 1 "move_src_operand"
2189                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2190   "(register_operand (operands[0], SImode)
2191     || reg_or_0_operand (operands[1], SImode))
2192    && !TARGET_SOFT_FLOAT
2193    && !TARGET_64BIT"
2194   "@
2195    ldw RT'%A1,%0
2196    copy %1,%0
2197    ldi %1,%0
2198    ldil L'%1,%0
2199    {zdepi|depwi,z} %Z1,%0
2200    ldw%M1 %1,%0
2201    stw%M0 %r1,%0
2202    mtsar %r1
2203    {mfctl|mfctl,w} %%sar,%0
2204    fcpy,sgl %f1,%0
2205    fldw%F1 %1,%0
2206    fstw%F0 %1,%0
2207    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2208    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2209   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2210    (set_attr "pa_combine_type" "addmove")
2211    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2213 (define_insn ""
2214   [(set (match_operand:SI 0 "move_dest_operand"
2215                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2216         (match_operand:SI 1 "move_src_operand"
2217                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2218   "(register_operand (operands[0], SImode)
2219     || reg_or_0_operand (operands[1], SImode))
2220    && !TARGET_SOFT_FLOAT
2221    && TARGET_64BIT"
2222   "@
2223    ldw RT'%A1,%0
2224    copy %1,%0
2225    ldi %1,%0
2226    ldil L'%1,%0
2227    {zdepi|depwi,z} %Z1,%0
2228    ldw%M1 %1,%0
2229    stw%M0 %r1,%0
2230    mtsar %r1
2231    {mfctl|mfctl,w} %%sar,%0
2232    fcpy,sgl %f1,%0
2233    fldw%F1 %1,%0
2234    fstw%F0 %1,%0"
2235   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2236    (set_attr "pa_combine_type" "addmove")
2237    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2239 (define_insn ""
2240   [(set (match_operand:SI 0 "move_dest_operand"
2241                           "=r,r,r,r,r,r,Q,!*q,!r")
2242         (match_operand:SI 1 "move_src_operand"
2243                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2244   "(register_operand (operands[0], SImode)
2245     || reg_or_0_operand (operands[1], SImode))
2246    && TARGET_SOFT_FLOAT
2247    && TARGET_64BIT"
2248   "@
2249    ldw RT'%A1,%0
2250    copy %1,%0
2251    ldi %1,%0
2252    ldil L'%1,%0
2253    {zdepi|depwi,z} %Z1,%0
2254    ldw%M1 %1,%0
2255    stw%M0 %r1,%0
2256    mtsar %r1
2257    {mfctl|mfctl,w} %%sar,%0"
2258   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
2259    (set_attr "pa_combine_type" "addmove")
2260    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2262 (define_insn ""
2263   [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2264         (match_operand:SI 1 "register_operand" "f"))]
2265   "!TARGET_SOFT_FLOAT
2266    && !TARGET_DISABLE_INDEXING
2267    && reload_completed"
2268   "fstw%F0 %1,%0"
2269   [(set_attr "type" "fpstore")
2270    (set_attr "pa_combine_type" "addmove")
2271    (set_attr "length" "4")])
2273 ; Rewrite RTL using an indexed store.  This will allow the insn that
2274 ; computes the address to be deleted if the register it sets is dead.
2275 (define_peephole2
2276   [(set (match_operand:SI 0 "register_operand" "")
2277         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2278                             (const_int 2))
2279                  (match_operand:SI 2 "register_operand" "")))
2280    (set (mem:SI (match_dup 0))
2281         (match_operand:SI 3 "register_operand" ""))]
2282   "!TARGET_SOFT_FLOAT
2283    && !TARGET_DISABLE_INDEXING
2284    && REG_OK_FOR_BASE_P (operands[2])
2285    && FP_REGNO_P (REGNO (operands[3]))"
2286   [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2287         (match_dup 3))
2288    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2289                                (match_dup 2)))]
2290   "")
2292 (define_peephole2
2293   [(set (match_operand:DI 0 "register_operand" "")
2294         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2295                             (const_int 2))
2296                  (match_operand:DI 2 "register_operand" "")))
2297    (set (mem:SI (match_dup 0))
2298         (match_operand:SI 3 "register_operand" ""))]
2299   "!TARGET_SOFT_FLOAT
2300    && !TARGET_DISABLE_INDEXING
2301    && TARGET_64BIT
2302    && REG_OK_FOR_BASE_P (operands[2])
2303    && FP_REGNO_P (REGNO (operands[3]))"
2304   [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2305         (match_dup 3))
2306    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2307                                (match_dup 2)))]
2308   "")
2310 (define_peephole2
2311   [(set (match_operand:SI 0 "register_operand" "")
2312         (plus:SI (match_operand:SI 1 "register_operand" "")
2313                  (match_operand:SI 2 "register_operand" "")))
2314    (set (mem:SI (match_dup 0))
2315         (match_operand:SI 3 "register_operand" ""))]
2316   "!TARGET_SOFT_FLOAT
2317    && !TARGET_DISABLE_INDEXING
2318    && TARGET_NO_SPACE_REGS
2319    && REG_OK_FOR_INDEX_P (operands[1])
2320    && REG_OK_FOR_BASE_P (operands[2])
2321    && FP_REGNO_P (REGNO (operands[3]))"
2322   [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2323         (match_dup 3))
2324    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2325   "")
2327 (define_peephole2
2328   [(set (match_operand:SI 0 "register_operand" "")
2329         (plus:SI (match_operand:SI 1 "register_operand" "")
2330                  (match_operand:SI 2 "register_operand" "")))
2331    (set (mem:SI (match_dup 0))
2332         (match_operand:SI 3 "register_operand" ""))]
2333   "!TARGET_SOFT_FLOAT
2334    && !TARGET_DISABLE_INDEXING
2335    && TARGET_NO_SPACE_REGS
2336    && REG_OK_FOR_BASE_P (operands[1])
2337    && REG_OK_FOR_INDEX_P (operands[2])
2338    && FP_REGNO_P (REGNO (operands[3]))"
2339   [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2340         (match_dup 3))
2341    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2342   "")
2344 (define_peephole2
2345   [(set (match_operand:DI 0 "register_operand" "")
2346         (plus:DI (match_operand:DI 1 "register_operand" "")
2347                  (match_operand:DI 2 "register_operand" "")))
2348    (set (mem:SI (match_dup 0))
2349         (match_operand:SI 3 "register_operand" ""))]
2350   "!TARGET_SOFT_FLOAT
2351    && !TARGET_DISABLE_INDEXING
2352    && TARGET_64BIT
2353    && TARGET_NO_SPACE_REGS
2354    && REG_OK_FOR_INDEX_P (operands[1])
2355    && REG_OK_FOR_BASE_P (operands[2])
2356    && FP_REGNO_P (REGNO (operands[3]))"
2357   [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2358         (match_dup 3))
2359    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2360   "")
2362 (define_peephole2
2363   [(set (match_operand:DI 0 "register_operand" "")
2364         (plus:DI (match_operand:DI 1 "register_operand" "")
2365                  (match_operand:DI 2 "register_operand" "")))
2366    (set (mem:SI (match_dup 0))
2367         (match_operand:SI 3 "register_operand" ""))]
2368   "!TARGET_SOFT_FLOAT
2369    && !TARGET_DISABLE_INDEXING
2370    && TARGET_64BIT
2371    && TARGET_NO_SPACE_REGS
2372    && REG_OK_FOR_BASE_P (operands[1])
2373    && REG_OK_FOR_INDEX_P (operands[2])
2374    && FP_REGNO_P (REGNO (operands[3]))"
2375   [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2376         (match_dup 3))
2377    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2378   "")
2380 (define_insn ""
2381   [(set (match_operand:SI 0 "move_dest_operand"
2382                           "=r,r,r,r,r,r,Q,!*q,!r")
2383         (match_operand:SI 1 "move_src_operand"
2384                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2385   "(register_operand (operands[0], SImode)
2386     || reg_or_0_operand (operands[1], SImode))
2387    && TARGET_SOFT_FLOAT"
2388   "@
2389    ldw RT'%A1,%0
2390    copy %1,%0
2391    ldi %1,%0
2392    ldil L'%1,%0
2393    {zdepi|depwi,z} %Z1,%0
2394    ldw%M1 %1,%0
2395    stw%M0 %r1,%0
2396    mtsar %r1
2397    {mfctl|mfctl,w} %%sar,%0"
2398   [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2399    (set_attr "pa_combine_type" "addmove")
2400    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2402 ;; Load or store with base-register modification.
2403 (define_insn ""
2404   [(set (match_operand:SI 0 "register_operand" "=r")
2405         (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2406                          (match_operand:DI 2 "int5_operand" "L"))))
2407    (set (match_dup 1)
2408         (plus:DI (match_dup 1) (match_dup 2)))]
2409   "TARGET_64BIT"
2410   "ldw,mb %2(%1),%0"
2411   [(set_attr "type" "load")
2412    (set_attr "length" "4")])
2414 ; And a zero extended variant.
2415 (define_insn ""
2416   [(set (match_operand:DI 0 "register_operand" "=r")
2417         (zero_extend:DI (mem:SI
2418                           (plus:DI
2419                             (match_operand:DI 1 "register_operand" "+r")
2420                             (match_operand:DI 2 "int5_operand" "L")))))
2421    (set (match_dup 1)
2422         (plus:DI (match_dup 1) (match_dup 2)))]
2423   "TARGET_64BIT"
2424   "ldw,mb %2(%1),%0"
2425   [(set_attr "type" "load")
2426    (set_attr "length" "4")])
2428 (define_expand "pre_load"
2429   [(parallel [(set (match_operand:SI 0 "register_operand" "")
2430               (mem (plus (match_operand 1 "register_operand" "")
2431                                (match_operand 2 "pre_cint_operand" ""))))
2432               (set (match_dup 1)
2433                    (plus (match_dup 1) (match_dup 2)))])]
2434   ""
2435   "
2437   if (TARGET_64BIT)
2438     {
2439       emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2440       DONE;
2441     }
2442   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2443   DONE;
2446 (define_insn "pre_ldw"
2447   [(set (match_operand:SI 0 "register_operand" "=r")
2448         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2449                          (match_operand:SI 2 "pre_cint_operand" ""))))
2450    (set (match_dup 1)
2451         (plus:SI (match_dup 1) (match_dup 2)))]
2452   ""
2453   "*
2455   if (INTVAL (operands[2]) < 0)
2456     return \"{ldwm|ldw,mb} %2(%1),%0\";
2457   return \"{ldws|ldw},mb %2(%1),%0\";
2459   [(set_attr "type" "load")
2460    (set_attr "length" "4")])
2462 (define_insn "pre_ldd"
2463   [(set (match_operand:DI 0 "register_operand" "=r")
2464         (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2465                          (match_operand:DI 2 "pre_cint_operand" ""))))
2466    (set (match_dup 1)
2467         (plus:DI (match_dup 1) (match_dup 2)))]
2468   "TARGET_64BIT"
2469   "ldd,mb %2(%1),%0"
2470   [(set_attr "type" "load")
2471    (set_attr "length" "4")])
2473 (define_insn ""
2474   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2475                          (match_operand:SI 1 "pre_cint_operand" "")))
2476         (match_operand:SI 2 "reg_or_0_operand" "rM"))
2477    (set (match_dup 0)
2478         (plus:SI (match_dup 0) (match_dup 1)))]
2479   ""
2480   "*
2482   if (INTVAL (operands[1]) < 0)
2483     return \"{stwm|stw,mb} %r2,%1(%0)\";
2484   return \"{stws|stw},mb %r2,%1(%0)\";
2486   [(set_attr "type" "store")
2487    (set_attr "length" "4")])
2489 (define_insn ""
2490   [(set (match_operand:SI 0 "register_operand" "=r")
2491         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2492    (set (match_dup 1)
2493         (plus:SI (match_dup 1)
2494                  (match_operand:SI 2 "post_cint_operand" "")))]
2495   ""
2496   "*
2498   if (INTVAL (operands[2]) > 0)
2499     return \"{ldwm|ldw,ma} %2(%1),%0\";
2500   return \"{ldws|ldw},ma %2(%1),%0\";
2502   [(set_attr "type" "load")
2503    (set_attr "length" "4")])
2505 (define_expand "post_store"
2506   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2507                    (match_operand 1 "reg_or_0_operand" ""))
2508               (set (match_dup 0)
2509                    (plus (match_dup 0)
2510                          (match_operand 2 "post_cint_operand" "")))])]
2511   ""
2512   "
2514   if (TARGET_64BIT)
2515     {
2516       emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2517       DONE;
2518     }
2519   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2520   DONE;
2523 (define_insn "post_stw"
2524   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2525         (match_operand:SI 1 "reg_or_0_operand" "rM"))
2526    (set (match_dup 0)
2527         (plus:SI (match_dup 0)
2528                  (match_operand:SI 2 "post_cint_operand" "")))]
2529   ""
2530   "*
2532   if (INTVAL (operands[2]) > 0)
2533     return \"{stwm|stw,ma} %r1,%2(%0)\";
2534   return \"{stws|stw},ma %r1,%2(%0)\";
2536   [(set_attr "type" "store")
2537    (set_attr "length" "4")])
2539 (define_insn "post_std"
2540   [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2541         (match_operand:DI 1 "reg_or_0_operand" "rM"))
2542    (set (match_dup 0)
2543         (plus:DI (match_dup 0)
2544                  (match_operand:DI 2 "post_cint_operand" "")))]
2545   "TARGET_64BIT"
2546   "std,ma %r1,%2(%0)"
2547   [(set_attr "type" "store")
2548    (set_attr "length" "4")])
2550 ;; For loading the address of a label while generating PIC code.
2551 ;; Note since this pattern can be created at reload time (via movsi), all
2552 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2553 (define_insn ""
2554   [(set (match_operand 0 "pmode_register_operand" "=a")
2555         (match_operand 1 "pic_label_operand" ""))]
2556   "TARGET_PA_20"
2557   "*
2559   rtx xoperands[3];
2561   xoperands[0] = operands[0];
2562   xoperands[1] = operands[1];
2564   if (GET_CODE (operands[1]) == LABEL_REF
2565       && !LABEL_REF_NONLOCAL_P (operands[1]))
2566     {
2567       xoperands[2] = gen_label_rtx ();
2568       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2569                                          CODE_LABEL_NUMBER (xoperands[2]));
2570       output_asm_insn (\"mfia %0\", xoperands);
2572       /* If we're trying to load the address of a label that happens to be
2573          close, then we can use a shorter sequence.  */
2574       if (INSN_ADDRESSES_SET_P ()
2575           && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2576                   - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2577         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2578       else
2579         {
2580           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2581           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2582         }
2583     }
2584   else
2585     {
2586       /* Load using linkage table.  */
2587       if (TARGET_64BIT)
2588         {
2589           output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
2590           output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
2591         }
2592       else
2593         {
2594           output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2595           output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2596         }
2597     }
2598   return \"\";
2600   [(set_attr "type" "multi")
2601    (set_attr "length" "12")])           ; 8 or 12
2603 (define_insn ""
2604   [(set (match_operand 0 "pmode_register_operand" "=a")
2605         (match_operand 1 "pic_label_operand" ""))]
2606   "!TARGET_PA_20"
2607   "*
2609   rtx xoperands[3];
2611   xoperands[0] = operands[0];
2612   xoperands[1] = operands[1];
2614   if (GET_CODE (operands[1]) == LABEL_REF
2615       && !LABEL_REF_NONLOCAL_P (operands[1]))
2616     {
2617       xoperands[2] = gen_label_rtx ();
2618       output_asm_insn (\"bl .+8,%0\", xoperands);
2619       output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2620       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2621                                          CODE_LABEL_NUMBER (xoperands[2]));
2623       /* If we're trying to load the address of a label that happens to be
2624          close, then we can use a shorter sequence.  */
2625       if (INSN_ADDRESSES_SET_P ()
2626           && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2627                   - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2628         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2629       else
2630         {
2631           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2632           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2633         }
2634     }
2635   else
2636     {
2637       /* Load using linkage table.  */
2638       output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2639       output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2640     }
2641   return \"\";
2643   [(set_attr "type" "multi")
2644    (set_attr "length" "16")])           ; 12 or 16
2646 (define_insn ""
2647   [(set (match_operand:SI 0 "register_operand" "=a")
2648         (plus:SI (match_operand:SI 1 "register_operand" "r")
2649                  (high:SI (match_operand 2 "" ""))))]
2650   "symbolic_operand (operands[2], Pmode)
2651    && ! function_label_operand (operands[2], Pmode)
2652    && flag_pic"
2653   "addil LT'%G2,%1"
2654   [(set_attr "type" "binary")
2655    (set_attr "length" "4")])
2657 (define_insn ""
2658   [(set (match_operand:DI 0 "register_operand" "=a")
2659         (plus:DI (match_operand:DI 1 "register_operand" "r")
2660                  (high:DI (match_operand 2 "" ""))))]
2661   "symbolic_operand (operands[2], Pmode)
2662    && ! function_label_operand (operands[2], Pmode)
2663    && TARGET_64BIT
2664    && flag_pic"
2665   "addil LT'%G2,%1"
2666   [(set_attr "type" "binary")
2667    (set_attr "length" "4")])
2669 (define_insn ""
2670  [(set (match_operand:SI 0 "register_operand" "=r")
2671        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2672                   (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2673   "symbolic_operand (operands[2], Pmode)
2674    && ! function_label_operand (operands[2], Pmode)
2675    && flag_pic"
2676   "ldo RT'%G2(%1),%0"
2677   [(set_attr "type" "binary")
2678    (set_attr "length" "4")])
2680 (define_insn ""
2681  [(set (match_operand:DI 0 "register_operand" "=r")
2682        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2683                   (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2684   "symbolic_operand (operands[2], Pmode)
2685    && ! function_label_operand (operands[2], Pmode)
2686    && TARGET_64BIT
2687    && flag_pic"
2688   "ldo RT'%G2(%1),%0"
2689   [(set_attr "type" "binary")
2690    (set_attr "length" "4")])
2692 ;; Always use addil rather than ldil;add sequences.  This allows the
2693 ;; HP linker to eliminate the dp relocation if the symbolic operand
2694 ;; lives in the TEXT space.
2695 (define_insn ""
2696   [(set (match_operand:SI 0 "register_operand" "=a")
2697         (high:SI (match_operand 1 "" "")))]
2698   "symbolic_operand (operands[1], Pmode)
2699    && ! function_label_operand (operands[1], Pmode)
2700    && ! read_only_operand (operands[1], Pmode)
2701    && ! flag_pic"
2702   "*
2704   if (TARGET_LONG_LOAD_STORE)
2705     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2706   else
2707     return \"addil LR'%H1,%%r27\";
2709   [(set_attr "type" "binary")
2710    (set (attr "length")
2711       (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2712                     (const_int 4)
2713                     (const_int 8)))])
2716 ;; This is for use in the prologue/epilogue code.  We need it
2717 ;; to add large constants to a stack pointer or frame pointer.
2718 ;; Because of the additional %r1 pressure, we probably do not
2719 ;; want to use this in general code, so make it available
2720 ;; only after reload.
2721 (define_insn ""
2722   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2723         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2724                  (high:SI (match_operand 2 "const_int_operand" ""))))]
2725   "reload_completed"
2726   "@
2727    addil L'%G2,%1
2728    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2729   [(set_attr "type" "binary,binary")
2730    (set_attr "length" "4,8")])
2732 (define_insn ""
2733   [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2734         (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2735                  (high:DI (match_operand 2 "const_int_operand" ""))))]
2736   "reload_completed && TARGET_64BIT"
2737   "@
2738    addil L'%G2,%1
2739    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2740   [(set_attr "type" "binary,binary")
2741    (set_attr "length" "4,8")])
2743 (define_insn ""
2744   [(set (match_operand:SI 0 "register_operand" "=r")
2745         (high:SI (match_operand 1 "" "")))]
2746   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2747     && !pa_is_function_label_plus_const (operands[1])"
2748   "*
2750   if (symbolic_operand (operands[1], Pmode))
2751     return \"ldil LR'%H1,%0\";
2752   else
2753     return \"ldil L'%G1,%0\";
2755   [(set_attr "type" "move")
2756    (set_attr "length" "4")])
2758 (define_insn ""
2759   [(set (match_operand:DI 0 "register_operand" "=r")
2760         (high:DI (match_operand 1 "const_int_operand" "")))]
2761   "TARGET_64BIT"
2762   "ldil L'%G1,%0";
2763   [(set_attr "type" "move")
2764    (set_attr "length" "4")])
2766 (define_insn ""
2767   [(set (match_operand:DI 0 "register_operand" "=r")
2768         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2769                    (match_operand:DI 2 "const_int_operand" "i")))]
2770   "TARGET_64BIT"
2771   "ldo R'%G2(%1),%0";
2772   [(set_attr "type" "move")
2773    (set_attr "length" "4")])
2775 (define_insn ""
2776   [(set (match_operand:SI 0 "register_operand" "=r")
2777         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2778                    (match_operand:SI 2 "immediate_operand" "i")))]
2779   "!pa_is_function_label_plus_const (operands[2])"
2780   "*
2782   gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2783   
2784   if (symbolic_operand (operands[2], Pmode))
2785     return \"ldo RR'%G2(%1),%0\";
2786   else
2787     return \"ldo R'%G2(%1),%0\";
2789   [(set_attr "type" "move")
2790    (set_attr "length" "4")])
2792 ;; Now that a symbolic_address plus a constant is broken up early
2793 ;; in the compilation phase (for better CSE) we need a special
2794 ;; combiner pattern to load the symbolic address plus the constant
2795 ;; in only 2 instructions. (For cases where the symbolic address
2796 ;; was not a common subexpression.)
2797 (define_split
2798   [(set (match_operand:SI 0 "register_operand" "")
2799         (match_operand:SI 1 "symbolic_operand" ""))
2800    (clobber (match_operand:SI 2 "register_operand" ""))]
2801   "! (flag_pic && pic_label_operand (operands[1], SImode))"
2802   [(set (match_dup 2) (high:SI (match_dup 1)))
2803    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2804   "")
2806 ;; hppa_legitimize_address goes to a great deal of trouble to
2807 ;; create addresses which use indexing.  In some cases, this
2808 ;; is a lose because there isn't any store instructions which
2809 ;; allow indexed addresses (with integer register source).
2811 ;; These define_splits try to turn a 3 insn store into
2812 ;; a 2 insn store with some creative RTL rewriting.
2813 (define_split
2814   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2815                                (match_operand:SI 1 "mem_shadd_operand" ""))
2816                    (plus:SI (match_operand:SI 2 "register_operand" "")
2817                             (match_operand:SI 3 "const_int_operand" ""))))
2818         (match_operand:SI 4 "register_operand" ""))
2819    (clobber (match_operand:SI 5 "register_operand" ""))]
2820   ""
2821   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2822                                (match_dup 2)))
2823    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2824   "
2826   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2830 (define_split
2831   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2832                                (match_operand:SI 1 "mem_shadd_operand" ""))
2833                    (plus:SI (match_operand:SI 2 "register_operand" "")
2834                             (match_operand:SI 3 "const_int_operand" ""))))
2835         (match_operand:HI 4 "register_operand" ""))
2836    (clobber (match_operand:SI 5 "register_operand" ""))]
2837   ""
2838   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2839                                (match_dup 2)))
2840    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2841   "
2843   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2847 (define_split
2848   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2849                                (match_operand:SI 1 "mem_shadd_operand" ""))
2850                    (plus:SI (match_operand:SI 2 "register_operand" "")
2851                             (match_operand:SI 3 "const_int_operand" ""))))
2852         (match_operand:QI 4 "register_operand" ""))
2853    (clobber (match_operand:SI 5 "register_operand" ""))]
2854   ""
2855   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2856                                (match_dup 2)))
2857    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2858   "
2860   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2864 (define_expand "movhi"
2865   [(set (match_operand:HI 0 "general_operand" "")
2866         (match_operand:HI 1 "general_operand" ""))]
2867   ""
2868   "
2870   if (pa_emit_move_sequence (operands, HImode, 0))
2871     DONE;
2874 ;; Handle HImode input reloads requiring a general register as a
2875 ;; scratch register.
2876 (define_expand "reload_inhi"
2877   [(set (match_operand:HI 0 "register_operand" "=Z")
2878         (match_operand:HI 1 "non_hard_reg_operand" ""))
2879    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2880   ""
2881   "
2883   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2884     DONE;
2886   /* We don't want the clobber emitted, so handle this ourselves.  */
2887   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2888   DONE;
2891 ;; Handle HImode output reloads requiring a general register as a
2892 ;; scratch register.
2893 (define_expand "reload_outhi"
2894   [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2895         (match_operand:HI 1  "register_operand" "Z"))
2896    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2897   ""
2898   "
2900   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2901     DONE;
2903   /* We don't want the clobber emitted, so handle this ourselves.  */
2904   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2905   DONE;
2908 (define_insn ""
2909   [(set (match_operand:HI 0 "move_dest_operand"
2910                           "=r,r,r,r,r,Q,!*q,!r")
2911         (match_operand:HI 1 "move_src_operand"
2912                           "r,J,N,K,RQ,rM,!rM,!*q"))]
2913   "(register_operand (operands[0], HImode)
2914     || reg_or_0_operand (operands[1], HImode))"
2915   "@
2916    copy %1,%0
2917    ldi %1,%0
2918    ldil L'%1,%0
2919    {zdepi|depwi,z} %Z1,%0
2920    ldh%M1 %1,%0
2921    sth%M0 %r1,%0
2922    mtsar %r1
2923    {mfctl|mfctl,w} %sar,%0"
2924   [(set_attr "type" "move,move,move,shift,load,store,move,move")
2925    (set_attr "pa_combine_type" "addmove")
2926    (set_attr "length" "4,4,4,4,4,4,4,4")])
2928 (define_insn ""
2929   [(set (match_operand:HI 0 "register_operand" "=r")
2930         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2931                          (match_operand:SI 2 "int5_operand" "L"))))
2932    (set (match_dup 1)
2933         (plus:SI (match_dup 1) (match_dup 2)))]
2934   ""
2935   "{ldhs|ldh},mb %2(%1),%0"
2936   [(set_attr "type" "load")
2937    (set_attr "length" "4")])
2939 (define_insn ""
2940   [(set (match_operand:HI 0 "register_operand" "=r")
2941         (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2942                          (match_operand:DI 2 "int5_operand" "L"))))
2943    (set (match_dup 1)
2944         (plus:DI (match_dup 1) (match_dup 2)))]
2945   "TARGET_64BIT"
2946   "ldh,mb %2(%1),%0"
2947   [(set_attr "type" "load")
2948    (set_attr "length" "4")])
2950 ; And a zero extended variant.
2951 (define_insn ""
2952   [(set (match_operand:DI 0 "register_operand" "=r")
2953         (zero_extend:DI (mem:HI
2954                           (plus:DI
2955                             (match_operand:DI 1 "register_operand" "+r")
2956                             (match_operand:DI 2 "int5_operand" "L")))))
2957    (set (match_dup 1)
2958         (plus:DI (match_dup 1) (match_dup 2)))]
2959   "TARGET_64BIT"
2960   "ldh,mb %2(%1),%0"
2961   [(set_attr "type" "load")
2962    (set_attr "length" "4")])
2964 (define_insn ""
2965   [(set (match_operand:SI 0 "register_operand" "=r")
2966         (zero_extend:SI (mem:HI
2967                           (plus:SI
2968                             (match_operand:SI 1 "register_operand" "+r")
2969                             (match_operand:SI 2 "int5_operand" "L")))))
2970    (set (match_dup 1)
2971         (plus:SI (match_dup 1) (match_dup 2)))]
2972   ""
2973   "{ldhs|ldh},mb %2(%1),%0"
2974   [(set_attr "type" "load")
2975    (set_attr "length" "4")])
2977 (define_insn ""
2978   [(set (match_operand:SI 0 "register_operand" "=r")
2979         (zero_extend:SI (mem:HI
2980                           (plus:DI
2981                             (match_operand:DI 1 "register_operand" "+r")
2982                             (match_operand:DI 2 "int5_operand" "L")))))
2983    (set (match_dup 1)
2984         (plus:DI (match_dup 1) (match_dup 2)))]
2985   "TARGET_64BIT"
2986   "ldh,mb %2(%1),%0"
2987   [(set_attr "type" "load")
2988    (set_attr "length" "4")])
2990 (define_insn ""
2991   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2992                          (match_operand:SI 1 "int5_operand" "L")))
2993         (match_operand:HI 2 "reg_or_0_operand" "rM"))
2994    (set (match_dup 0)
2995         (plus:SI (match_dup 0) (match_dup 1)))]
2996   ""
2997   "{sths|sth},mb %r2,%1(%0)"
2998   [(set_attr "type" "store")
2999    (set_attr "length" "4")])
3001 (define_insn ""
3002   [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3003                          (match_operand:DI 1 "int5_operand" "L")))
3004         (match_operand:HI 2 "reg_or_0_operand" "rM"))
3005    (set (match_dup 0)
3006         (plus:DI (match_dup 0) (match_dup 1)))]
3007   "TARGET_64BIT"
3008   "sth,mb %r2,%1(%0)"
3009   [(set_attr "type" "store")
3010    (set_attr "length" "4")])
3012 (define_insn "addhi3"
3013   [(set (match_operand:HI 0 "register_operand" "=r,r")
3014         (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3015                  (match_operand:HI 2 "arith14_operand" "r,J")))]
3016   ""
3017   "@
3018    {addl|add,l} %1,%2,%0
3019    ldo %2(%1),%0"
3020   [(set_attr "type" "binary,binary")
3021    (set_attr "pa_combine_type" "addmove")
3022    (set_attr "length" "4,4")])
3024 (define_expand "movqi"
3025   [(set (match_operand:QI 0 "general_operand" "")
3026         (match_operand:QI 1 "general_operand" ""))]
3027   ""
3028   "
3030   if (pa_emit_move_sequence (operands, QImode, 0))
3031     DONE;
3034 ;; Handle QImode input reloads requiring a general register as a
3035 ;; scratch register.
3036 (define_expand "reload_inqi"
3037   [(set (match_operand:QI 0 "register_operand" "=Z")
3038         (match_operand:QI 1 "non_hard_reg_operand" ""))
3039    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3040   ""
3041   "
3043   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3044     DONE;
3046   /* We don't want the clobber emitted, so handle this ourselves.  */
3047   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3048   DONE;
3051 ;; Handle QImode output reloads requiring a general register as a
3052 ;; scratch register.
3053 (define_expand "reload_outqi"
3054   [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3055         (match_operand:QI 1  "register_operand" "Z"))
3056    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3057   ""
3058   "
3060   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3061     DONE;
3063   /* We don't want the clobber emitted, so handle this ourselves.  */
3064   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3065   DONE;
3068 (define_insn ""
3069   [(set (match_operand:QI 0 "move_dest_operand"
3070                           "=r,r,r,r,r,Q,!*q,!r")
3071         (match_operand:QI 1 "move_src_operand"
3072                           "r,J,N,K,RQ,rM,!rM,!*q"))]
3073   "(register_operand (operands[0], QImode)
3074     || reg_or_0_operand (operands[1], QImode))"
3075   "@
3076    copy %1,%0
3077    ldi %1,%0
3078    ldil L'%1,%0
3079    {zdepi|depwi,z} %Z1,%0
3080    ldb%M1 %1,%0
3081    stb%M0 %r1,%0
3082    mtsar %r1
3083    {mfctl|mfctl,w} %%sar,%0"
3084   [(set_attr "type" "move,move,move,shift,load,store,move,move")
3085    (set_attr "pa_combine_type" "addmove")
3086    (set_attr "length" "4,4,4,4,4,4,4,4")])
3088 (define_insn ""
3089   [(set (match_operand:QI 0 "register_operand" "=r")
3090         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3091                          (match_operand:SI 2 "int5_operand" "L"))))
3092    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3093   ""
3094   "{ldbs|ldb},mb %2(%1),%0"
3095   [(set_attr "type" "load")
3096    (set_attr "length" "4")])
3098 (define_insn ""
3099   [(set (match_operand:QI 0 "register_operand" "=r")
3100         (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3101                          (match_operand:DI 2 "int5_operand" "L"))))
3102    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3103   "TARGET_64BIT"
3104   "ldb,mb %2(%1),%0"
3105   [(set_attr "type" "load")
3106    (set_attr "length" "4")])
3108 ; Now the same thing with zero extensions.
3109 (define_insn ""
3110   [(set (match_operand:DI 0 "register_operand" "=r")
3111         (zero_extend:DI (mem:QI (plus:DI
3112                                   (match_operand:DI 1 "register_operand" "+r")
3113                                   (match_operand:DI 2 "int5_operand" "L")))))
3114    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3115   "TARGET_64BIT"
3116   "ldb,mb %2(%1),%0"
3117   [(set_attr "type" "load")
3118    (set_attr "length" "4")])
3120 (define_insn ""
3121   [(set (match_operand:SI 0 "register_operand" "=r")
3122         (zero_extend:SI (mem:QI (plus:SI
3123                                   (match_operand:SI 1 "register_operand" "+r")
3124                                   (match_operand:SI 2 "int5_operand" "L")))))
3125    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3126   ""
3127   "{ldbs|ldb},mb %2(%1),%0"
3128   [(set_attr "type" "load")
3129    (set_attr "length" "4")])
3131 (define_insn ""
3132   [(set (match_operand:SI 0 "register_operand" "=r")
3133         (zero_extend:SI (mem:QI (plus:DI
3134                                   (match_operand:DI 1 "register_operand" "+r")
3135                                   (match_operand:DI 2 "int5_operand" "L")))))
3136    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3137   "TARGET_64BIT"
3138   "ldb,mb %2(%1),%0"
3139   [(set_attr "type" "load")
3140    (set_attr "length" "4")])
3142 (define_insn ""
3143   [(set (match_operand:HI 0 "register_operand" "=r")
3144         (zero_extend:HI (mem:QI (plus:SI
3145                                   (match_operand:SI 1 "register_operand" "+r")
3146                                   (match_operand:SI 2 "int5_operand" "L")))))
3147    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3148   ""
3149   "{ldbs|ldb},mb %2(%1),%0"
3150   [(set_attr "type" "load")
3151    (set_attr "length" "4")])
3153 (define_insn ""
3154   [(set (match_operand:HI 0 "register_operand" "=r")
3155         (zero_extend:HI (mem:QI (plus:DI
3156                                   (match_operand:DI 1 "register_operand" "+r")
3157                                   (match_operand:DI 2 "int5_operand" "L")))))
3158    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3159   "TARGET_64BIT"
3160   "ldb,mb %2(%1),%0"
3161   [(set_attr "type" "load")
3162    (set_attr "length" "4")])
3164 (define_insn ""
3165   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3166                          (match_operand:SI 1 "int5_operand" "L")))
3167         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3168    (set (match_dup 0)
3169         (plus:SI (match_dup 0) (match_dup 1)))]
3170   ""
3171   "{stbs|stb},mb %r2,%1(%0)"
3172   [(set_attr "type" "store")
3173    (set_attr "length" "4")])
3175 (define_insn ""
3176   [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3177                          (match_operand:DI 1 "int5_operand" "L")))
3178         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3179    (set (match_dup 0)
3180         (plus:DI (match_dup 0) (match_dup 1)))]
3181   "TARGET_64BIT"
3182   "stb,mb %r2,%1(%0)"
3183   [(set_attr "type" "store")
3184    (set_attr "length" "4")])
3186 ;; The definition of this insn does not really explain what it does,
3187 ;; but it should suffice that anything generated as this insn will be
3188 ;; recognized as a cpymemsi operation, and that it will not successfully
3189 ;; combine with anything.
3190 (define_expand "cpymemsi"
3191   [(parallel [(set (match_operand:BLK 0 "" "")
3192                    (match_operand:BLK 1 "" ""))
3193               (clobber (match_dup 4))
3194               (clobber (match_dup 5))
3195               (clobber (match_dup 6))
3196               (clobber (match_dup 7))
3197               (clobber (match_dup 8))
3198               (use (match_operand:SI 2 "arith14_operand" ""))
3199               (use (match_operand:SI 3 "const_int_operand" ""))])]
3200   "!TARGET_64BIT && optimize > 0"
3201   "
3203   int size, align;
3205   /* HP provides very fast block move library routine for the PA;
3206      this routine includes:
3208         4x4 byte at a time block moves,
3209         1x4 byte at a time with alignment checked at runtime with
3210             attempts to align the source and destination as needed
3211         1x1 byte loop
3213      With that in mind, here's the heuristics to try and guess when
3214      the inlined block move will be better than the library block
3215      move:
3217         If the size isn't constant, then always use the library routines.
3219         If the size is large in respect to the known alignment, then use
3220         the library routines.
3222         If the size is small in respect to the known alignment, then open
3223         code the copy (since that will lead to better scheduling).
3225         Else use the block move pattern.   */
3227   /* Undetermined size, use the library routine.  */
3228   if (GET_CODE (operands[2]) != CONST_INT)
3229     FAIL;
3231   size = INTVAL (operands[2]);
3232   align = INTVAL (operands[3]);
3233   align = align > 4 ? 4 : (align ? align : 1);
3235   /* If size/alignment is large, then use the library routines.  */
3236   if (size / align > 16)
3237     FAIL;
3239   /* This does happen, but not often enough to worry much about.  */
3240   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3241     FAIL;
3242   
3243   /* Fall through means we're going to use our block move pattern.  */
3244   operands[0]
3245     = replace_equiv_address (operands[0],
3246                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3247   operands[1]
3248     = replace_equiv_address (operands[1],
3249                              copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3250   operands[4] = gen_reg_rtx (SImode);
3251   operands[5] = gen_reg_rtx (SImode);
3252   operands[6] = gen_reg_rtx (SImode);
3253   operands[7] = gen_reg_rtx (SImode);
3254   operands[8] = gen_reg_rtx (SImode);
3257 ;; The operand constraints are written like this to support both compile-time
3258 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3259 ;; only support compile-time determined counts at this time.
3261 ;; If the count is run-time determined, the register with the byte count
3262 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3264 ;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3265 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3266 ;; as this requires two registers in the class R1_REGS when the MEMs for
3267 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3268 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3269 ;; respectively.  We then split or peephole optimize after reload.
3270 (define_insn "cpymemsi_prereload"
3271   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3272         (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3273    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3274    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3275    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3276    (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))   ;item tmp3
3277    (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))   ;item tmp4
3278    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3279    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3280   "!TARGET_64BIT"
3281   "#"
3282   [(set_attr "type" "multi,multi")])
3284 (define_split
3285   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3286                    (match_operand:BLK 1 "memory_operand" ""))
3287               (clobber (match_operand:SI 2 "register_operand" ""))
3288               (clobber (match_operand:SI 3 "register_operand" ""))
3289               (clobber (match_operand:SI 6 "register_operand" ""))
3290               (clobber (match_operand:SI 7 "register_operand" ""))
3291               (clobber (match_operand:SI 8 "register_operand" ""))
3292               (use (match_operand:SI 4 "arith14_operand" ""))
3293               (use (match_operand:SI 5 "const_int_operand" ""))])]
3294   "!TARGET_64BIT && reload_completed && !flag_peephole2
3295    && GET_CODE (operands[0]) == MEM
3296    && register_operand (XEXP (operands[0], 0), SImode)
3297    && GET_CODE (operands[1]) == MEM
3298    && register_operand (XEXP (operands[1], 0), SImode)"
3299   [(set (match_dup 7) (match_dup 9))
3300    (set (match_dup 8) (match_dup 10))
3301    (parallel [(set (match_dup 0) (match_dup 1))
3302               (clobber (match_dup 2))
3303               (clobber (match_dup 3))
3304               (clobber (match_dup 6))
3305               (clobber (match_dup 7))
3306               (clobber (match_dup 8))
3307               (use (match_dup 4))
3308               (use (match_dup 5))
3309               (const_int 0)])]
3310   "
3312   operands[9] = XEXP (operands[0], 0);
3313   operands[10] = XEXP (operands[1], 0);
3314   operands[0] = replace_equiv_address (operands[0], operands[7]);
3315   operands[1] = replace_equiv_address (operands[1], operands[8]);
3318 (define_peephole2
3319   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3320                    (match_operand:BLK 1 "memory_operand" ""))
3321               (clobber (match_operand:SI 2 "register_operand" ""))
3322               (clobber (match_operand:SI 3 "register_operand" ""))
3323               (clobber (match_operand:SI 6 "register_operand" ""))
3324               (clobber (match_operand:SI 7 "register_operand" ""))
3325               (clobber (match_operand:SI 8 "register_operand" ""))
3326               (use (match_operand:SI 4 "arith14_operand" ""))
3327               (use (match_operand:SI 5 "const_int_operand" ""))])]
3328   "!TARGET_64BIT
3329    && GET_CODE (operands[0]) == MEM
3330    && register_operand (XEXP (operands[0], 0), SImode)
3331    && GET_CODE (operands[1]) == MEM
3332    && register_operand (XEXP (operands[1], 0), SImode)"
3333   [(parallel [(set (match_dup 0) (match_dup 1))
3334               (clobber (match_dup 2))
3335               (clobber (match_dup 3))
3336               (clobber (match_dup 6))
3337               (clobber (match_dup 7))
3338               (clobber (match_dup 8))
3339               (use (match_dup 4))
3340               (use (match_dup 5))
3341               (const_int 0)])]
3342   "
3344   rtx addr = XEXP (operands[0], 0);
3345   if (dead_or_set_p (curr_insn, addr))
3346     operands[7] = addr;
3347   else
3348     {
3349       emit_insn (gen_rtx_SET (operands[7], addr));
3350       operands[0] = replace_equiv_address (operands[0], operands[7]);
3351     }
3353   addr = XEXP (operands[1], 0);
3354   if (dead_or_set_p (curr_insn, addr))
3355     operands[8] = addr;
3356   else
3357     {
3358       emit_insn (gen_rtx_SET (operands[8], addr));
3359       operands[1] = replace_equiv_address (operands[1], operands[8]);
3360     }
3363 (define_insn "cpymemsi_postreload"
3364   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3365         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3366    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3367    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3368    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3369    (clobber (match_dup 0))
3370    (clobber (match_dup 1))
3371    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3372    (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3373    (const_int 0)]
3374   "!TARGET_64BIT && reload_completed"
3375   "* return pa_output_block_move (operands, !which_alternative);"
3376   [(set_attr "type" "multi,multi")])
3378 (define_expand "cpymemdi"
3379   [(parallel [(set (match_operand:BLK 0 "" "")
3380                    (match_operand:BLK 1 "" ""))
3381               (clobber (match_dup 4))
3382               (clobber (match_dup 5))
3383               (clobber (match_dup 6))
3384               (clobber (match_dup 7))
3385               (clobber (match_dup 8))
3386               (use (match_operand:DI 2 "arith14_operand" ""))
3387               (use (match_operand:DI 3 "const_int_operand" ""))])]
3388   "TARGET_64BIT && optimize > 0"
3389   "
3391   int size, align;
3393   /* HP provides very fast block move library routine for the PA;
3394      this routine includes:
3396         4x4 byte at a time block moves,
3397         1x4 byte at a time with alignment checked at runtime with
3398             attempts to align the source and destination as needed
3399         1x1 byte loop
3401      With that in mind, here's the heuristics to try and guess when
3402      the inlined block move will be better than the library block
3403      move:
3405         If the size isn't constant, then always use the library routines.
3407         If the size is large in respect to the known alignment, then use
3408         the library routines.
3410         If the size is small in respect to the known alignment, then open
3411         code the copy (since that will lead to better scheduling).
3413         Else use the block move pattern.   */
3415   /* Undetermined size, use the library routine.  */
3416   if (GET_CODE (operands[2]) != CONST_INT)
3417     FAIL;
3419   size = INTVAL (operands[2]);
3420   align = INTVAL (operands[3]);
3421   align = align > 8 ? 8 : (align ? align : 1);
3423   /* If size/alignment is large, then use the library routines.  */
3424   if (size / align > 16)
3425     FAIL;
3427   /* This does happen, but not often enough to worry much about.  */
3428   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3429     FAIL;
3430   
3431   /* Fall through means we're going to use our block move pattern.  */
3432   operands[0]
3433     = replace_equiv_address (operands[0],
3434                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3435   operands[1]
3436     = replace_equiv_address (operands[1],
3437                              copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3438   operands[4] = gen_reg_rtx (DImode);
3439   operands[5] = gen_reg_rtx (DImode);
3440   operands[6] = gen_reg_rtx (DImode);
3441   operands[7] = gen_reg_rtx (DImode);
3442   operands[8] = gen_reg_rtx (DImode);
3445 ;; The operand constraints are written like this to support both compile-time
3446 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3447 ;; only support compile-time determined counts at this time.
3449 ;; If the count is run-time determined, the register with the byte count
3450 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3452 ;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3453 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3454 ;; as this requires two registers in the class R1_REGS when the MEMs for
3455 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3456 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3457 ;; respectively.  We then split or peephole optimize after reload.
3458 (define_insn "cpymemdi_prereload"
3459   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3460         (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3461    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3462    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3463    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3464    (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))   ;item tmp3
3465    (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))   ;item tmp4
3466    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3467    (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3468   "TARGET_64BIT"
3469   "#"
3470   [(set_attr "type" "multi,multi")])
3472 (define_split
3473   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3474                    (match_operand:BLK 1 "memory_operand" ""))
3475               (clobber (match_operand:DI 2 "register_operand" ""))
3476               (clobber (match_operand:DI 3 "register_operand" ""))
3477               (clobber (match_operand:DI 6 "register_operand" ""))
3478               (clobber (match_operand:DI 7 "register_operand" ""))
3479               (clobber (match_operand:DI 8 "register_operand" ""))
3480               (use (match_operand:DI 4 "arith14_operand" ""))
3481               (use (match_operand:DI 5 "const_int_operand" ""))])]
3482   "TARGET_64BIT && reload_completed && !flag_peephole2
3483    && GET_CODE (operands[0]) == MEM
3484    && register_operand (XEXP (operands[0], 0), DImode)
3485    && GET_CODE (operands[1]) == MEM
3486    && register_operand (XEXP (operands[1], 0), DImode)"
3487   [(set (match_dup 7) (match_dup 9))
3488    (set (match_dup 8) (match_dup 10))
3489    (parallel [(set (match_dup 0) (match_dup 1))
3490               (clobber (match_dup 2))
3491               (clobber (match_dup 3))
3492               (clobber (match_dup 6))
3493               (clobber (match_dup 7))
3494               (clobber (match_dup 8))
3495               (use (match_dup 4))
3496               (use (match_dup 5))
3497               (const_int 0)])]
3498   "
3500   operands[9] = XEXP (operands[0], 0);
3501   operands[10] = XEXP (operands[1], 0);
3502   operands[0] = replace_equiv_address (operands[0], operands[7]);
3503   operands[1] = replace_equiv_address (operands[1], operands[8]);
3506 (define_peephole2
3507   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3508                    (match_operand:BLK 1 "memory_operand" ""))
3509               (clobber (match_operand:DI 2 "register_operand" ""))
3510               (clobber (match_operand:DI 3 "register_operand" ""))
3511               (clobber (match_operand:DI 6 "register_operand" ""))
3512               (clobber (match_operand:DI 7 "register_operand" ""))
3513               (clobber (match_operand:DI 8 "register_operand" ""))
3514               (use (match_operand:DI 4 "arith14_operand" ""))
3515               (use (match_operand:DI 5 "const_int_operand" ""))])]
3516   "TARGET_64BIT
3517    && GET_CODE (operands[0]) == MEM
3518    && register_operand (XEXP (operands[0], 0), DImode)
3519    && GET_CODE (operands[1]) == MEM
3520    && register_operand (XEXP (operands[1], 0), DImode)"
3521   [(parallel [(set (match_dup 0) (match_dup 1))
3522               (clobber (match_dup 2))
3523               (clobber (match_dup 3))
3524               (clobber (match_dup 6))
3525               (clobber (match_dup 7))
3526               (clobber (match_dup 8))
3527               (use (match_dup 4))
3528               (use (match_dup 5))
3529               (const_int 0)])]
3530   "
3532   rtx addr = XEXP (operands[0], 0);
3533   if (dead_or_set_p (curr_insn, addr))
3534     operands[7] = addr;
3535   else
3536     {
3537       emit_insn (gen_rtx_SET (operands[7], addr));
3538       operands[0] = replace_equiv_address (operands[0], operands[7]);
3539     }
3541   addr = XEXP (operands[1], 0);
3542   if (dead_or_set_p (curr_insn, addr))
3543     operands[8] = addr;
3544   else
3545     {
3546       emit_insn (gen_rtx_SET (operands[8], addr));
3547       operands[1] = replace_equiv_address (operands[1], operands[8]);
3548     }
3551 (define_insn "cpymemdi_postreload"
3552   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3553         (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3554    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3555    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3556    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3557    (clobber (match_dup 0))
3558    (clobber (match_dup 1))
3559    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3560    (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3561    (const_int 0)]
3562   "TARGET_64BIT && reload_completed"
3563   "* return pa_output_block_move (operands, !which_alternative);"
3564   [(set_attr "type" "multi,multi")])
3566 (define_expand "setmemsi"
3567   [(parallel [(set (match_operand:BLK 0 "" "")
3568                    (match_operand 2 "const_int_operand" ""))
3569               (clobber (match_dup 4))
3570               (clobber (match_dup 5))
3571               (use (match_operand:SI 1 "arith14_operand" ""))
3572               (use (match_operand:SI 3 "const_int_operand" ""))])]
3573   "!TARGET_64BIT && optimize > 0"
3574   "
3576   int size, align;
3578   /* If value to set is not zero, use the library routine.  */
3579   if (operands[2] != const0_rtx)
3580     FAIL;
3582   /* Undetermined size, use the library routine.  */
3583   if (GET_CODE (operands[1]) != CONST_INT)
3584     FAIL;
3586   size = INTVAL (operands[1]);
3587   align = INTVAL (operands[3]);
3588   align = align > 4 ? 4 : align;
3590   /* If size/alignment is large, then use the library routines.  */
3591   if (size / align > 16)
3592     FAIL;
3594   /* This does happen, but not often enough to worry much about.  */
3595   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3596     FAIL;
3597   
3598   /* Fall through means we're going to use our block clear pattern.  */
3599   operands[0]
3600     = replace_equiv_address (operands[0],
3601                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3602   operands[4] = gen_reg_rtx (SImode);
3603   operands[5] = gen_reg_rtx (SImode);
3606 (define_insn "clrmemsi_prereload"
3607   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3608         (const_int 0))
3609    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3610    (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))   ;tmp1
3611    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3612    (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3613   "!TARGET_64BIT"
3614   "#"
3615   [(set_attr "type" "multi,multi")])
3617 (define_split
3618   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3619                    (const_int 0))
3620               (clobber (match_operand:SI 1 "register_operand" ""))
3621               (clobber (match_operand:SI 4 "register_operand" ""))
3622               (use (match_operand:SI 2 "arith14_operand" ""))
3623               (use (match_operand:SI 3 "const_int_operand" ""))])]
3624   "!TARGET_64BIT && reload_completed && !flag_peephole2
3625    && GET_CODE (operands[0]) == MEM
3626    && register_operand (XEXP (operands[0], 0), SImode)"
3627   [(set (match_dup 4) (match_dup 5))
3628    (parallel [(set (match_dup 0) (const_int 0))
3629               (clobber (match_dup 1))
3630               (clobber (match_dup 4))
3631               (use (match_dup 2))
3632               (use (match_dup 3))
3633               (const_int 0)])]
3634   "
3636   operands[5] = XEXP (operands[0], 0);
3637   operands[0] = replace_equiv_address (operands[0], operands[4]);
3640 (define_peephole2
3641   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3642                    (const_int 0))
3643               (clobber (match_operand:SI 1 "register_operand" ""))
3644               (clobber (match_operand:SI 4 "register_operand" ""))
3645               (use (match_operand:SI 2 "arith14_operand" ""))
3646               (use (match_operand:SI 3 "const_int_operand" ""))])]
3647   "!TARGET_64BIT
3648    && GET_CODE (operands[0]) == MEM
3649    && register_operand (XEXP (operands[0], 0), SImode)"
3650   [(parallel [(set (match_dup 0) (const_int 0))
3651               (clobber (match_dup 1))
3652               (clobber (match_dup 4))
3653               (use (match_dup 2))
3654               (use (match_dup 3))
3655               (const_int 0)])]
3656   "
3658   rtx addr = XEXP (operands[0], 0);
3659   if (dead_or_set_p (curr_insn, addr))
3660     operands[4] = addr;
3661   else
3662     {
3663       emit_insn (gen_rtx_SET (operands[4], addr));
3664       operands[0] = replace_equiv_address (operands[0], operands[4]);
3665     }
3668 (define_insn "clrmemsi_postreload"
3669   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3670         (const_int 0))
3671    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3672    (clobber (match_dup 0))
3673    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3674    (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3675    (const_int 0)]
3676   "!TARGET_64BIT && reload_completed"
3677   "* return pa_output_block_clear (operands, !which_alternative);"
3678   [(set_attr "type" "multi,multi")])
3680 (define_expand "setmemdi"
3681   [(parallel [(set (match_operand:BLK 0 "" "")
3682                    (match_operand 2 "const_int_operand" ""))
3683               (clobber (match_dup 4))
3684               (clobber (match_dup 5))
3685               (use (match_operand:DI 1 "arith14_operand" ""))
3686               (use (match_operand:DI 3 "const_int_operand" ""))])]
3687   "TARGET_64BIT && optimize > 0"
3688   "
3690   int size, align;
3692   /* If value to set is not zero, use the library routine.  */
3693   if (operands[2] != const0_rtx)
3694     FAIL;
3696   /* Undetermined size, use the library routine.  */
3697   if (GET_CODE (operands[1]) != CONST_INT)
3698     FAIL;
3700   size = INTVAL (operands[1]);
3701   align = INTVAL (operands[3]);
3702   align = align > 8 ? 8 : align;
3704   /* If size/alignment is large, then use the library routines.  */
3705   if (size / align > 16)
3706     FAIL;
3708   /* This does happen, but not often enough to worry much about.  */
3709   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3710     FAIL;
3711   
3712   /* Fall through means we're going to use our block clear pattern.  */
3713   operands[0]
3714     = replace_equiv_address (operands[0],
3715                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3716   operands[4] = gen_reg_rtx (DImode);
3717   operands[5] = gen_reg_rtx (DImode);
3720 (define_insn "clrmemdi_prereload"
3721   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3722         (const_int 0))
3723    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3724    (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))   ;item tmp1
3725    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3726    (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3727   "TARGET_64BIT"
3728   "#"
3729   [(set_attr "type" "multi,multi")])
3731 (define_split
3732   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3733                    (const_int 0))
3734               (clobber (match_operand:DI 1 "register_operand" ""))
3735               (clobber (match_operand:DI 4 "register_operand" ""))
3736               (use (match_operand:DI 2 "arith14_operand" ""))
3737               (use (match_operand:DI 3 "const_int_operand" ""))])]
3738   "TARGET_64BIT && reload_completed && !flag_peephole2
3739    && GET_CODE (operands[0]) == MEM
3740    && register_operand (XEXP (operands[0], 0), DImode)"
3741   [(set (match_dup 4) (match_dup 5))
3742    (parallel [(set (match_dup 0) (const_int 0))
3743               (clobber (match_dup 1))
3744               (clobber (match_dup 4))
3745               (use (match_dup 2))
3746               (use (match_dup 3))
3747               (const_int 0)])]
3748   "
3750   operands[5] = XEXP (operands[0], 0);
3751   operands[0] = replace_equiv_address (operands[0], operands[4]);
3754 (define_peephole2
3755   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3756                    (const_int 0))
3757               (clobber (match_operand:DI 1 "register_operand" ""))
3758               (clobber (match_operand:DI 4 "register_operand" ""))
3759               (use (match_operand:DI 2 "arith14_operand" ""))
3760               (use (match_operand:DI 3 "const_int_operand" ""))])]
3761   "TARGET_64BIT
3762    && GET_CODE (operands[0]) == MEM
3763    && register_operand (XEXP (operands[0], 0), DImode)"
3764   [(parallel [(set (match_dup 0) (const_int 0))
3765               (clobber (match_dup 1))
3766               (clobber (match_dup 4))
3767               (use (match_dup 2))
3768               (use (match_dup 3))
3769               (const_int 0)])]
3770   "
3771 {  
3772   rtx addr = XEXP (operands[0], 0);
3773   if (dead_or_set_p (curr_insn, addr))
3774     operands[4] = addr;
3775   else
3776     {
3777       emit_insn (gen_rtx_SET (operands[4], addr));
3778       operands[0] = replace_equiv_address (operands[0], operands[4]);
3779     }
3782 (define_insn "clrmemdi_postreload"
3783   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3784         (const_int 0))
3785    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3786    (clobber (match_dup 0))
3787    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3788    (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3789    (const_int 0)]
3790   "TARGET_64BIT && reload_completed"
3791   "* return pa_output_block_clear (operands, !which_alternative);"
3792   [(set_attr "type" "multi,multi")])
3794 ;; Floating point move insns
3796 (define_expand "movdf"
3797   [(set (match_operand:DF 0 "general_operand" "")
3798         (match_operand:DF 1 "general_operand" ""))]
3799   ""
3800   "
3802   if (pa_emit_move_sequence (operands, DFmode, 0))
3803     DONE;
3806 ;; Handle DFmode input reloads requiring %r1 as a scratch register.
3807 (define_expand "reload_indf_r1"
3808   [(set (match_operand:DF 0 "register_operand" "=Z")
3809         (match_operand:DF 1 "non_hard_reg_operand" ""))
3810    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3811   ""
3812   "
3814   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3815     DONE;
3817   /* We don't want the clobber emitted, so handle this ourselves.  */
3818   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3819   DONE;
3822 ;; Handle DFmode input reloads requiring a general register as a
3823 ;; scratch register.
3824 (define_expand "reload_indf"
3825   [(set (match_operand:DF 0 "register_operand" "=Z")
3826         (match_operand:DF 1 "non_hard_reg_operand" ""))
3827    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3828   ""
3829   "
3831   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3832     DONE;
3834   /* We don't want the clobber emitted, so handle this ourselves.  */
3835   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3836   DONE;
3839 ;; Handle DFmode output reloads requiring a general register as a
3840 ;; scratch register.
3841 (define_expand "reload_outdf" 
3842  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3843         (match_operand:DF 1  "register_operand" "Z"))
3844    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3845   ""
3846   "
3848   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3849     DONE;
3851   /* We don't want the clobber emitted, so handle this ourselves.  */
3852   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3853   DONE;
3856 (define_insn ""
3857   [(set (match_operand:DF 0 "move_dest_operand"
3858                           "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3859         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3860                           "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3861   "(register_operand (operands[0], DFmode)
3862     || reg_or_0_operand (operands[1], DFmode))
3863    && !(GET_CODE (operands[1]) == CONST_DOUBLE
3864         && GET_CODE (operands[0]) == MEM)
3865    && !TARGET_64BIT
3866    && !TARGET_SOFT_FLOAT"
3867   "*
3869   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3870        || operands[1] == CONST0_RTX (DFmode))
3871       && !(REG_P (operands[0]) && REG_P (operands[1])
3872            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3873     return pa_output_fp_move_double (operands);
3874   return pa_output_move_double (operands);
3876   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3877    (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3879 (define_insn ""
3880   [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3881         (match_operand:DF 1 "reg_or_0_operand" "f"))]
3882   "!TARGET_SOFT_FLOAT
3883    && !TARGET_DISABLE_INDEXING
3884    && reload_completed"
3885   "fstd%F0 %1,%0"
3886   [(set_attr "type" "fpstore")
3887    (set_attr "pa_combine_type" "addmove")
3888    (set_attr "length" "4")])
3890 (define_peephole2
3891   [(set (match_operand:SI 0 "register_operand" "")
3892         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3893                             (const_int 3))
3894                  (match_operand:SI 2 "register_operand" "")))
3895    (set (mem:DF (match_dup 0))
3896         (match_operand:DF 3 "register_operand" ""))]
3897   "!TARGET_SOFT_FLOAT
3898    && !TARGET_DISABLE_INDEXING
3899    && REG_OK_FOR_BASE_P (operands[2])
3900    && FP_REGNO_P (REGNO (operands[3]))"
3901   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3902         (match_dup 3))
3903    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3904                                (match_dup 2)))]
3905   "")
3907 (define_peephole2
3908   [(set (match_operand:SI 0 "register_operand" "")
3909         (plus:SI (match_operand:SI 2 "register_operand" "")
3910                  (ashift:SI (match_operand:SI 1 "register_operand" "")
3911                             (const_int 3))))
3912    (set (mem:DF (match_dup 0))
3913         (match_operand:DF 3 "register_operand" ""))]
3914   "!TARGET_SOFT_FLOAT
3915    && !TARGET_DISABLE_INDEXING
3916    && REG_OK_FOR_BASE_P (operands[2])
3917    && FP_REGNO_P (REGNO (operands[3]))"
3918   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3919         (match_dup 3))
3920    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3921                                (match_dup 2)))]
3922   "")
3924 (define_peephole2
3925   [(set (match_operand:DI 0 "register_operand" "")
3926         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
3927                             (const_int 3))
3928                  (match_operand:DI 2 "register_operand" "")))
3929    (set (mem:DF (match_dup 0))
3930         (match_operand:DF 3 "register_operand" ""))]
3931   "!TARGET_SOFT_FLOAT
3932    && !TARGET_DISABLE_INDEXING
3933    && TARGET_64BIT
3934    && REG_OK_FOR_BASE_P (operands[2])
3935    && FP_REGNO_P (REGNO (operands[3]))"
3936   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3937         (match_dup 3))
3938    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3939                                (match_dup 2)))]
3940   "")
3942 (define_peephole2
3943   [(set (match_operand:DI 0 "register_operand" "")
3944         (plus:DI (match_operand:DI 2 "register_operand" "")
3945                  (ashift:DI (match_operand:DI 1 "register_operand" "")
3946                             (const_int 3))))
3947    (set (mem:DF (match_dup 0))
3948         (match_operand:DF 3 "register_operand" ""))]
3949   "!TARGET_SOFT_FLOAT
3950    && !TARGET_DISABLE_INDEXING
3951    && TARGET_64BIT
3952    && REG_OK_FOR_BASE_P (operands[2])
3953    && FP_REGNO_P (REGNO (operands[3]))"
3954   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3955         (match_dup 3))
3956    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3957                                (match_dup 2)))]
3958   "")
3960 (define_peephole2
3961   [(set (match_operand:SI 0 "register_operand" "")
3962         (plus:SI (match_operand:SI 1 "register_operand" "")
3963                  (match_operand:SI 2 "register_operand" "")))
3964    (set (mem:DF (match_dup 0))
3965         (match_operand:DF 3 "register_operand" ""))]
3966   "!TARGET_SOFT_FLOAT
3967    && !TARGET_DISABLE_INDEXING
3968    && TARGET_NO_SPACE_REGS
3969    && REG_OK_FOR_INDEX_P (operands[1])
3970    && REG_OK_FOR_BASE_P (operands[2])
3971    && FP_REGNO_P (REGNO (operands[3]))"
3972   [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3973         (match_dup 3))
3974    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3975   "")
3977 (define_peephole2
3978   [(set (match_operand:SI 0 "register_operand" "")
3979         (plus:SI (match_operand:SI 1 "register_operand" "")
3980                  (match_operand:SI 2 "register_operand" "")))
3981    (set (mem:DF (match_dup 0))
3982         (match_operand:DF 3 "register_operand" ""))]
3983   "!TARGET_SOFT_FLOAT
3984    && !TARGET_DISABLE_INDEXING
3985    && TARGET_NO_SPACE_REGS
3986    && REG_OK_FOR_BASE_P (operands[1])
3987    && REG_OK_FOR_INDEX_P (operands[2])
3988    && FP_REGNO_P (REGNO (operands[3]))"
3989   [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3990         (match_dup 3))
3991    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3992   "")
3994 (define_peephole2
3995   [(set (match_operand:DI 0 "register_operand" "")
3996         (plus:DI (match_operand:DI 1 "register_operand" "")
3997                  (match_operand:DI 2 "register_operand" "")))
3998    (set (mem:DF (match_dup 0))
3999         (match_operand:DF 3 "register_operand" ""))]
4000   "!TARGET_SOFT_FLOAT
4001    && !TARGET_DISABLE_INDEXING
4002    && TARGET_64BIT
4003    && TARGET_NO_SPACE_REGS
4004    && REG_OK_FOR_INDEX_P (operands[1])
4005    && REG_OK_FOR_BASE_P (operands[2])
4006    && FP_REGNO_P (REGNO (operands[3]))"
4007   [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4008         (match_dup 3))
4009    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4010   "")
4012 (define_peephole2
4013   [(set (match_operand:DI 0 "register_operand" "")
4014         (plus:DI (match_operand:DI 1 "register_operand" "")
4015                  (match_operand:DI 2 "register_operand" "")))
4016    (set (mem:DF (match_dup 0))
4017         (match_operand:DF 3 "register_operand" ""))]
4018   "!TARGET_SOFT_FLOAT
4019    && !TARGET_DISABLE_INDEXING
4020    && TARGET_64BIT
4021    && TARGET_NO_SPACE_REGS
4022    && REG_OK_FOR_BASE_P (operands[1])
4023    && REG_OK_FOR_INDEX_P (operands[2])
4024    && FP_REGNO_P (REGNO (operands[3]))"
4025   [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4026         (match_dup 3))
4027    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4028   "")
4030 (define_insn ""
4031   [(set (match_operand:DF 0 "move_dest_operand"
4032                           "=r,?o,?Q,r,r")
4033         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4034                           "rG,r,r,o,RQ"))]
4035   "(register_operand (operands[0], DFmode)
4036     || reg_or_0_operand (operands[1], DFmode))
4037    && !TARGET_64BIT
4038    && TARGET_SOFT_FLOAT"
4039   "*
4041   return pa_output_move_double (operands);
4043   [(set_attr "type" "move,store,store,load,load")
4044    (set_attr "length" "8,8,16,8,16")])
4046 (define_insn ""
4047   [(set (match_operand:DF 0 "move_dest_operand"
4048                           "=!*r,*r,*r,*r,*r,Q,f,f,T")
4049         (match_operand:DF 1 "move_src_operand"
4050                           "!*rG,J,N,K,RQ,*rG,fG,RT,f"))]
4051   "(register_operand (operands[0], DFmode)
4052     || reg_or_0_operand (operands[1], DFmode))
4053    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4054   "@
4055    copy %r1,%0
4056    ldi %1,%0
4057    ldil L'%1,%0
4058    depdi,z %z1,%0
4059    ldd%M1 %1,%0
4060    std%M0 %r1,%0
4061    fcpy,dbl %f1,%0
4062    fldd%F1 %1,%0
4063    fstd%F0 %1,%0"
4064   [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4065    (set_attr "pa_combine_type" "addmove")
4066    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4068 (define_insn ""
4069   [(set (match_operand:DF 0 "move_dest_operand"
4070                           "=!*r,*r,*r,*r,*r,Q")
4071         (match_operand:DF 1 "move_src_operand"
4072                           "!*rG,J,N,K,RQ,*rG"))]
4073   "(register_operand (operands[0], DFmode)
4074     || reg_or_0_operand (operands[1], DFmode))
4075    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4076   "@
4077    copy %r1,%0
4078    ldi %1,%0
4079    ldil L'%1,%0
4080    depdi,z %z1,%0
4081    ldd%M1 %1,%0
4082    std%M0 %r1,%0"
4083   [(set_attr "type" "move,move,move,shift,load,store")
4084    (set_attr "pa_combine_type" "addmove")
4085    (set_attr "length" "4,4,4,4,4,4")])
4088 (define_expand "movdi"
4089   [(set (match_operand:DI 0 "general_operand" "")
4090         (match_operand:DI 1 "general_operand" ""))]
4091   ""
4092   "
4094   if (pa_emit_move_sequence (operands, DImode, 0))
4095     DONE;
4098 ;; Handle DImode input reloads requiring %r1 as a scratch register.
4099 (define_expand "reload_indi_r1"
4100   [(set (match_operand:DI 0 "register_operand" "=Z")
4101         (match_operand:DI 1 "non_hard_reg_operand" ""))
4102    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4103   ""
4104   "
4106   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4107     DONE;
4109   /* We don't want the clobber emitted, so handle this ourselves.  */
4110   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4111   DONE;
4114 ;; Handle DImode input reloads requiring a general register as a
4115 ;; scratch register.
4116 (define_expand "reload_indi"
4117   [(set (match_operand:DI 0 "register_operand" "=Z")
4118         (match_operand:DI 1 "non_hard_reg_operand" ""))
4119    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4120   ""
4121   "
4123   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4124     DONE;
4126   /* We don't want the clobber emitted, so handle this ourselves.  */
4127   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4128   DONE;
4131 ;; Handle DImode output reloads requiring a general register as a
4132 ;; scratch register.
4133 (define_expand "reload_outdi"
4134   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4135         (match_operand:DI 1 "register_operand" "Z"))
4136    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4137   ""
4138   "
4140   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4141     DONE;
4143   /* We don't want the clobber emitted, so handle this ourselves.  */
4144   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4145   DONE;
4148 (define_insn ""
4149   [(set (match_operand:DI 0 "register_operand" "=r")
4150         (high:DI (match_operand 1 "" "")))]
4151   "!TARGET_64BIT"
4152   "*
4154   rtx op0 = operands[0];
4155   rtx op1 = operands[1];
4157   switch (GET_CODE (op1))
4158     {
4159     case CONST_INT:
4160 #if HOST_BITS_PER_WIDE_INT <= 32
4161       operands[0] = operand_subword (op0, 1, 0, DImode);
4162       output_asm_insn (\"ldil L'%1,%0\", operands);
4164       operands[0] = operand_subword (op0, 0, 0, DImode);
4165       if (INTVAL (op1) < 0)
4166         output_asm_insn (\"ldi -1,%0\", operands);
4167       else
4168         output_asm_insn (\"ldi 0,%0\", operands);
4169 #else
4170       operands[0] = operand_subword (op0, 1, 0, DImode);
4171       operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4172       output_asm_insn (\"ldil L'%1,%0\", operands);
4174       operands[0] = operand_subword (op0, 0, 0, DImode);
4175       operands[1] = GEN_INT (INTVAL (op1) >> 32);
4176       output_asm_insn (pa_singlemove_string (operands), operands);
4177 #endif
4178       break;
4180     case CONST_DOUBLE:
4181       operands[0] = operand_subword (op0, 1, 0, DImode);
4182       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4183       output_asm_insn (\"ldil L'%1,%0\", operands);
4185       operands[0] = operand_subword (op0, 0, 0, DImode);
4186       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4187       output_asm_insn (pa_singlemove_string (operands), operands);
4188       break;
4190     default:
4191       gcc_unreachable ();
4192     }
4193   return \"\";
4195   [(set_attr "type" "move")
4196    (set_attr "length" "12")])
4198 (define_insn ""
4199   [(set (match_operand:DI 0 "move_dest_operand"
4200                           "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4201         (match_operand:DI 1 "move_src_operand"
4202                           "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4203   "(register_operand (operands[0], DImode)
4204     || reg_or_0_operand (operands[1], DImode))
4205    && !TARGET_64BIT
4206    && !TARGET_SOFT_FLOAT"
4207   "*
4209   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4210        || operands[1] == CONST0_RTX (DFmode))
4211       && !(REG_P (operands[0]) && REG_P (operands[1])
4212            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4213     return pa_output_fp_move_double (operands);
4214   return pa_output_move_double (operands);
4216   [(set_attr "type"
4217     "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4218    (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4220 (define_insn ""
4221   [(set (match_operand:DI 0 "move_dest_operand"
4222                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4223         (match_operand:DI 1 "move_src_operand"
4224                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4225   "(register_operand (operands[0], DImode)
4226     || reg_or_0_operand (operands[1], DImode))
4227    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4228   "@
4229    ldd RT'%A1,%0
4230    copy %1,%0
4231    ldi %1,%0
4232    ldil L'%1,%0
4233    depdi,z %z1,%0
4234    ldd%M1 %1,%0
4235    std%M0 %r1,%0
4236    mtsar %r1
4237    {mfctl|mfctl,w} %%sar,%0
4238    fcpy,dbl %f1,%0
4239    fldd%F1 %1,%0
4240    fstd%F0 %1,%0"
4241   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4242    (set_attr "pa_combine_type" "addmove")
4243    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4245 (define_insn ""
4246   [(set (match_operand:DI 0 "move_dest_operand"
4247                           "=r,r,r,r,r,r,Q,!*q,!r")
4248         (match_operand:DI 1 "move_src_operand"
4249                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
4250   "(register_operand (operands[0], DImode)
4251     || reg_or_0_operand (operands[1], DImode))
4252    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4253   "@
4254    ldd RT'%A1,%0
4255    copy %1,%0
4256    ldi %1,%0
4257    ldil L'%1,%0
4258    depdi,z %z1,%0
4259    ldd%M1 %1,%0
4260    std%M0 %r1,%0
4261    mtsar %r1
4262    {mfctl|mfctl,w} %%sar,%0"
4263   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
4264    (set_attr "pa_combine_type" "addmove")
4265    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4267 (define_insn ""
4268   [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4269         (match_operand:DI 1 "register_operand" "f"))]
4270   "!TARGET_SOFT_FLOAT
4271    && TARGET_64BIT
4272    && !TARGET_DISABLE_INDEXING
4273    && reload_completed"
4274   "fstd%F0 %1,%0"
4275   [(set_attr "type" "fpstore")
4276    (set_attr "pa_combine_type" "addmove")
4277    (set_attr "length" "4")])
4279 (define_peephole2
4280   [(set (match_operand:DI 0 "register_operand" "")
4281         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4282                             (const_int 3))
4283                  (match_operand:DI 2 "register_operand" "")))
4284    (set (mem:DI (match_dup 0))
4285         (match_operand:DI 3 "register_operand" ""))]
4286   "!TARGET_SOFT_FLOAT
4287    && !TARGET_DISABLE_INDEXING
4288    && TARGET_64BIT
4289    && REG_OK_FOR_BASE_P (operands[2])
4290    && FP_REGNO_P (REGNO (operands[3]))"
4291   [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4292         (match_dup 3))
4293    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4294                                (match_dup 2)))]
4295   "")
4297 (define_peephole2
4298   [(set (match_operand:DI 0 "register_operand" "")
4299         (plus:DI (match_operand:DI 1 "register_operand" "")
4300                  (match_operand:DI 2 "register_operand" "")))
4301    (set (mem:DI (match_dup 0))
4302         (match_operand:DI 3 "register_operand" ""))]
4303   "!TARGET_SOFT_FLOAT
4304    && !TARGET_DISABLE_INDEXING
4305    && TARGET_64BIT
4306    && TARGET_NO_SPACE_REGS
4307    && REG_OK_FOR_INDEX_P (operands[1])
4308    && REG_OK_FOR_BASE_P (operands[2])
4309    && FP_REGNO_P (REGNO (operands[3]))"
4310   [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4311         (match_dup 3))
4312    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4313   "")
4315 (define_peephole2
4316   [(set (match_operand:DI 0 "register_operand" "")
4317         (plus:DI (match_operand:DI 1 "register_operand" "")
4318                  (match_operand:DI 2 "register_operand" "")))
4319    (set (mem:DI (match_dup 0))
4320         (match_operand:DI 3 "register_operand" ""))]
4321   "!TARGET_SOFT_FLOAT
4322    && !TARGET_DISABLE_INDEXING
4323    && TARGET_64BIT
4324    && TARGET_NO_SPACE_REGS
4325    && REG_OK_FOR_BASE_P (operands[1])
4326    && REG_OK_FOR_INDEX_P (operands[2])
4327    && FP_REGNO_P (REGNO (operands[3]))"
4328   [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4329         (match_dup 3))
4330    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4331   "")
4333 (define_insn ""
4334   [(set (match_operand:DI 0 "move_dest_operand"
4335                           "=r,o,Q,r,r,r")
4336         (match_operand:DI 1 "general_operand"
4337                           "rM,r,r,o,Q,i"))]
4338   "(register_operand (operands[0], DImode)
4339     || reg_or_0_operand (operands[1], DImode))
4340    && !TARGET_64BIT
4341    && TARGET_SOFT_FLOAT"
4342   "*
4344   return pa_output_move_double (operands);
4346   [(set_attr "type" "move,store,store,load,load,multi")
4347    (set_attr "length" "8,8,16,8,16,16")])
4349 (define_insn ""
4350   [(set (match_operand:DI 0 "register_operand" "=r,&r")
4351         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4352                    (match_operand:DI 2 "immediate_operand" "i,i")))]
4353   "!TARGET_64BIT"
4354   "*
4356   /* Don't output a 64-bit constant, since we can't trust the assembler to
4357      handle it correctly.  */
4358   if (GET_CODE (operands[2]) == CONST_DOUBLE)
4359     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4360   else if (HOST_BITS_PER_WIDE_INT > 32
4361            && GET_CODE (operands[2]) == CONST_INT)
4362     operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4363   if (which_alternative == 1)
4364     output_asm_insn (\"copy %1,%0\", operands);
4365   return \"ldo R'%G2(%R1),%R0\";
4367   [(set_attr "type" "move,move")
4368    (set_attr "length" "4,8")])
4370 (define_expand "movsf"
4371   [(set (match_operand:SF 0 "general_operand" "")
4372         (match_operand:SF 1 "general_operand" ""))]
4373   ""
4374   "
4376   if (pa_emit_move_sequence (operands, SFmode, 0))
4377     DONE;
4380 ;; Handle SFmode input reloads requiring %r1 as a scratch register.
4381 (define_expand "reload_insf_r1"
4382   [(set (match_operand:SF 0 "register_operand" "=Z")
4383         (match_operand:SF 1 "non_hard_reg_operand" ""))
4384    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4385   ""
4386   "
4388   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4389     DONE;
4391   /* We don't want the clobber emitted, so handle this ourselves.  */
4392   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4393   DONE;
4396 ;; Handle SFmode input reloads requiring a general register as a
4397 ;; scratch register.
4398 (define_expand "reload_insf"
4399   [(set (match_operand:SF 0 "register_operand" "=Z")
4400         (match_operand:SF 1 "non_hard_reg_operand" ""))
4401    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4402   ""
4403   "
4405   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4406     DONE;
4408   /* We don't want the clobber emitted, so handle this ourselves.  */
4409   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4410   DONE;
4413 ;; Handle SFmode output reloads requiring a general register as a
4414 ;; scratch register.
4415 (define_expand "reload_outsf"
4416   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4417         (match_operand:SF 1  "register_operand" "Z"))
4418    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4419   ""
4420   "
4422   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4423     DONE;
4425   /* We don't want the clobber emitted, so handle this ourselves.  */
4426   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4427   DONE;
4430 (define_insn ""
4431   [(set (match_operand:SF 0 "move_dest_operand"
4432                           "=f,!*r,f,*r,T,Q,?*r,?f")
4433         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4434                           "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4435   "(register_operand (operands[0], SFmode)
4436     || reg_or_0_operand (operands[1], SFmode))
4437    && !TARGET_SOFT_FLOAT
4438    && !TARGET_64BIT"
4439   "@
4440    fcpy,sgl %f1,%0
4441    copy %r1,%0
4442    fldw%F1 %1,%0
4443    ldw%M1 %1,%0
4444    fstw%F0 %1,%0
4445    stw%M0 %r1,%0
4446    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4447    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4448   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4449    (set_attr "pa_combine_type" "addmove")
4450    (set_attr "length" "4,4,4,4,4,4,8,8")])
4452 (define_insn ""
4453   [(set (match_operand:SF 0 "move_dest_operand"
4454                           "=f,!*r,f,*r,T,Q")
4455         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4456                           "fG,!*rG,RT,RQ,f,*rG"))]
4457   "(register_operand (operands[0], SFmode)
4458     || reg_or_0_operand (operands[1], SFmode))
4459    && !TARGET_SOFT_FLOAT
4460    && TARGET_64BIT"
4461   "@
4462    fcpy,sgl %f1,%0
4463    copy %r1,%0
4464    fldw%F1 %1,%0
4465    ldw%M1 %1,%0
4466    fstw%F0 %1,%0
4467    stw%M0 %r1,%0"
4468   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4469    (set_attr "pa_combine_type" "addmove")
4470    (set_attr "length" "4,4,4,4,4,4")])
4472 (define_insn ""
4473   [(set (match_operand:SF 0 "move_dest_operand"
4474                           "=!*r,*r,Q")
4475         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4476                           "!*rG,RQ,*rG"))]
4477   "(register_operand (operands[0], SFmode)
4478     || reg_or_0_operand (operands[1], SFmode))
4479    && TARGET_SOFT_FLOAT
4480    && TARGET_64BIT"
4481   "@
4482    copy %r1,%0
4483    ldw%M1 %1,%0
4484    stw%M0 %r1,%0"
4485   [(set_attr "type" "move,load,store")
4486    (set_attr "pa_combine_type" "addmove")
4487    (set_attr "length" "4,4,4")])
4489 (define_insn ""
4490   [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4491         (match_operand:SF 1 "register_operand" "f"))]
4492   "!TARGET_SOFT_FLOAT
4493    && !TARGET_DISABLE_INDEXING
4494    && reload_completed"
4495   "fstw%F0 %1,%0"
4496   [(set_attr "type" "fpstore")
4497    (set_attr "pa_combine_type" "addmove")
4498    (set_attr "length" "4")])
4500 (define_peephole2
4501   [(set (match_operand:SI 0 "register_operand" "")
4502         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4503                             (const_int 2))
4504                  (match_operand:SI 2 "register_operand" "")))
4505    (set (mem:SF (match_dup 0))
4506         (match_operand:SF 3 "register_operand" ""))]
4507   "!TARGET_SOFT_FLOAT
4508    && !TARGET_DISABLE_INDEXING
4509    && REG_OK_FOR_BASE_P (operands[2])
4510    && FP_REGNO_P (REGNO (operands[3]))"
4511   [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4512         (match_dup 3))
4513    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4514                                (match_dup 2)))]
4515   "")
4517 (define_peephole2
4518   [(set (match_operand:DI 0 "register_operand" "")
4519         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4520                             (const_int 2))
4521                  (match_operand:DI 2 "register_operand" "")))
4522    (set (mem:SF (match_dup 0))
4523         (match_operand:SF 3 "register_operand" ""))]
4524   "!TARGET_SOFT_FLOAT
4525    && !TARGET_DISABLE_INDEXING
4526    && TARGET_64BIT
4527    && REG_OK_FOR_BASE_P (operands[2])
4528    && FP_REGNO_P (REGNO (operands[3]))"
4529   [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4530         (match_dup 3))
4531    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4532                                (match_dup 2)))]
4533   "")
4535 (define_peephole2
4536   [(set (match_operand:SI 0 "register_operand" "")
4537         (plus:SI (match_operand:SI 1 "register_operand" "")
4538                  (match_operand:SI 2 "register_operand" "")))
4539    (set (mem:SF (match_dup 0))
4540         (match_operand:SF 3 "register_operand" ""))]
4541   "!TARGET_SOFT_FLOAT
4542    && !TARGET_DISABLE_INDEXING
4543    && TARGET_NO_SPACE_REGS
4544    && REG_OK_FOR_INDEX_P (operands[1])
4545    && REG_OK_FOR_BASE_P (operands[2])
4546    && FP_REGNO_P (REGNO (operands[3]))"
4547   [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4548         (match_dup 3))
4549    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4550   "")
4552 (define_peephole2
4553   [(set (match_operand:SI 0 "register_operand" "")
4554         (plus:SI (match_operand:SI 1 "register_operand" "")
4555                  (match_operand:SI 2 "register_operand" "")))
4556    (set (mem:SF (match_dup 0))
4557         (match_operand:SF 3 "register_operand" ""))]
4558   "!TARGET_SOFT_FLOAT
4559    && !TARGET_DISABLE_INDEXING
4560    && TARGET_NO_SPACE_REGS
4561    && REG_OK_FOR_BASE_P (operands[1])
4562    && REG_OK_FOR_INDEX_P (operands[2])
4563    && FP_REGNO_P (REGNO (operands[3]))"
4564   [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4565         (match_dup 3))
4566    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4567   "")
4569 (define_peephole2
4570   [(set (match_operand:DI 0 "register_operand" "")
4571         (plus:DI (match_operand:DI 1 "register_operand" "")
4572                  (match_operand:DI 2 "register_operand" "")))
4573    (set (mem:SF (match_dup 0))
4574         (match_operand:SF 3 "register_operand" ""))]
4575   "!TARGET_SOFT_FLOAT
4576    && !TARGET_DISABLE_INDEXING
4577    && TARGET_64BIT
4578    && TARGET_NO_SPACE_REGS
4579    && REG_OK_FOR_INDEX_P (operands[1])
4580    && REG_OK_FOR_BASE_P (operands[2])
4581    && FP_REGNO_P (REGNO (operands[3]))"
4582   [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4583         (match_dup 3))
4584    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4585   "")
4587 (define_peephole2
4588   [(set (match_operand:DI 0 "register_operand" "")
4589         (plus:DI (match_operand:DI 1 "register_operand" "")
4590                  (match_operand:DI 2 "register_operand" "")))
4591    (set (mem:SF (match_dup 0))
4592         (match_operand:SF 3 "register_operand" ""))]
4593   "!TARGET_SOFT_FLOAT
4594    && !TARGET_DISABLE_INDEXING
4595    && TARGET_64BIT
4596    && TARGET_NO_SPACE_REGS
4597    && REG_OK_FOR_BASE_P (operands[1])
4598    && REG_OK_FOR_INDEX_P (operands[2])
4599    && FP_REGNO_P (REGNO (operands[3]))"
4600   [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4601         (match_dup 3))
4602    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4603   "")
4605 (define_insn ""
4606   [(set (match_operand:SF 0 "move_dest_operand"
4607                           "=r,r,Q")
4608         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4609                           "rG,RQ,rG"))]
4610   "(register_operand (operands[0], SFmode)
4611     || reg_or_0_operand (operands[1], SFmode))
4612    && TARGET_SOFT_FLOAT"
4613   "@
4614    copy %r1,%0
4615    ldw%M1 %1,%0
4616    stw%M0 %r1,%0"
4617   [(set_attr "type" "move,load,store")
4618    (set_attr "pa_combine_type" "addmove")
4619    (set_attr "length" "4,4,4")])
4623 ;;- zero extension instructions
4624 ;; We have define_expand for zero extension patterns to make sure the
4625 ;; operands get loaded into registers.  The define_insns accept
4626 ;; memory operands.  This gives us better overall code than just
4627 ;; having a pattern that does or does not accept memory operands.
4629 (define_expand "zero_extendqihi2"
4630   [(set (match_operand:HI 0 "register_operand" "")
4631         (zero_extend:HI
4632          (match_operand:QI 1 "register_operand" "")))]
4633   ""
4634   "")
4636 (define_insn ""
4637   [(set (match_operand:HI 0 "register_operand" "=r,r")
4638         (zero_extend:HI
4639          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4640   "GET_CODE (operands[1]) != CONST_INT"
4641   "@
4642    {extru|extrw,u} %1,31,8,%0
4643    ldb%M1 %1,%0"
4644   [(set_attr "type" "shift,load")
4645    (set_attr "length" "4,4")])
4647 (define_expand "zero_extendqisi2"
4648   [(set (match_operand:SI 0 "register_operand" "")
4649         (zero_extend:SI
4650          (match_operand:QI 1 "register_operand" "")))]
4651   ""
4652   "")
4654 (define_insn ""
4655   [(set (match_operand:SI 0 "register_operand" "=r,r")
4656         (zero_extend:SI
4657          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4658   "GET_CODE (operands[1]) != CONST_INT"
4659   "@
4660    {extru|extrw,u} %1,31,8,%0
4661    ldb%M1 %1,%0"
4662   [(set_attr "type" "shift,load")
4663    (set_attr "length" "4,4")])
4665 (define_expand "zero_extendhisi2"
4666   [(set (match_operand:SI 0 "register_operand" "")
4667         (zero_extend:SI
4668          (match_operand:HI 1 "register_operand" "")))]
4669   ""
4670   "")
4672 (define_insn ""
4673   [(set (match_operand:SI 0 "register_operand" "=r,r")
4674         (zero_extend:SI
4675          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4676   "GET_CODE (operands[1]) != CONST_INT"
4677   "@
4678    {extru|extrw,u} %1,31,16,%0
4679    ldh%M1 %1,%0"
4680   [(set_attr "type" "shift,load")
4681    (set_attr "length" "4,4")])
4683 (define_expand "zero_extendqidi2"
4684   [(set (match_operand:DI 0 "register_operand" "")
4685         (zero_extend:DI
4686          (match_operand:QI 1 "register_operand" "")))]
4687   "TARGET_64BIT"
4688   "")
4690 (define_insn ""
4691   [(set (match_operand:DI 0 "register_operand" "=r,r")
4692         (zero_extend:DI
4693          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4694   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4695   "@
4696    extrd,u %1,63,8,%0
4697    ldb%M1 %1,%0"
4698   [(set_attr "type" "shift,load")
4699    (set_attr "length" "4,4")])
4701 (define_expand "zero_extendhidi2"
4702   [(set (match_operand:DI 0 "register_operand" "")
4703         (zero_extend:DI
4704          (match_operand:HI 1 "register_operand" "")))]
4705   "TARGET_64BIT"
4706   "")
4708 (define_insn ""
4709   [(set (match_operand:DI 0 "register_operand" "=r,r")
4710         (zero_extend:DI
4711          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4712   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4713   "@
4714    extrd,u %1,63,16,%0
4715    ldh%M1 %1,%0"
4716   [(set_attr "type" "shift,load")
4717    (set_attr "length" "4,4")])
4719 (define_expand "zero_extendsidi2"
4720   [(set (match_operand:DI 0 "register_operand" "")
4721         (zero_extend:DI
4722          (match_operand:SI 1 "register_operand" "")))]
4723   "TARGET_64BIT"
4724   "")
4726 (define_insn ""
4727   [(set (match_operand:DI 0 "register_operand" "=r,r")
4728         (zero_extend:DI
4729          (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4730   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4731   "@
4732    extrd,u %1,63,32,%0
4733    ldw%M1 %1,%0"
4734   [(set_attr "type" "shift,load")
4735    (set_attr "length" "4,4")])
4737 ;;- sign extension instructions
4739 (define_insn "extendhisi2"
4740   [(set (match_operand:SI 0 "register_operand" "=r")
4741         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4742   ""
4743   "{extrs|extrw,s} %1,31,16,%0"
4744   [(set_attr "type" "shift")
4745    (set_attr "length" "4")])
4747 (define_insn "extendqihi2"
4748   [(set (match_operand:HI 0 "register_operand" "=r")
4749         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4750   ""
4751   "{extrs|extrw,s} %1,31,8,%0"
4752   [(set_attr "type" "shift") 
4753   (set_attr "length" "4")])
4755 (define_insn "extendqisi2"
4756   [(set (match_operand:SI 0 "register_operand" "=r")
4757         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4758   ""
4759   "{extrs|extrw,s} %1,31,8,%0"
4760   [(set_attr "type" "shift")
4761    (set_attr "length" "4")])
4763 (define_insn "extendqidi2"
4764   [(set (match_operand:DI 0 "register_operand" "=r")
4765         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4766   "TARGET_64BIT"
4767   "extrd,s %1,63,8,%0"
4768   [(set_attr "type" "shift") 
4769   (set_attr "length" "4")])
4771 (define_insn "extendhidi2"
4772   [(set (match_operand:DI 0 "register_operand" "=r")
4773         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4774   "TARGET_64BIT"
4775   "extrd,s %1,63,16,%0"
4776   [(set_attr "type" "shift") 
4777   (set_attr "length" "4")])
4779 (define_insn "extendsidi2"
4780   [(set (match_operand:DI 0 "register_operand" "=r")
4781         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4782   "TARGET_64BIT"
4783   "extrd,s %1,63,32,%0"
4784   [(set_attr "type" "shift") 
4785   (set_attr "length" "4")])
4788 ;; Conversions between float and double.
4790 (define_insn "extendsfdf2"
4791   [(set (match_operand:DF 0 "register_operand" "=f")
4792         (float_extend:DF
4793          (match_operand:SF 1 "register_operand" "f")))]
4794   "! TARGET_SOFT_FLOAT"
4795   "{fcnvff|fcnv},sgl,dbl %1,%0"
4796   [(set_attr "type" "fpalu")
4797    (set_attr "length" "4")])
4799 (define_insn "truncdfsf2"
4800   [(set (match_operand:SF 0 "register_operand" "=f")
4801         (float_truncate:SF
4802          (match_operand:DF 1 "register_operand" "f")))]
4803   "! TARGET_SOFT_FLOAT"
4804   "{fcnvff|fcnv},dbl,sgl %1,%0"
4805   [(set_attr "type" "fpalu")
4806    (set_attr "length" "4")])
4808 ;; Conversion between fixed point and floating point.
4809 ;; Note that among the fix-to-float insns
4810 ;; the ones that start with SImode come first.
4811 ;; That is so that an operand that is a CONST_INT
4812 ;; (and therefore lacks a specific machine mode).
4813 ;; will be recognized as SImode (which is always valid)
4814 ;; rather than as QImode or HImode.
4816 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4817 ;; to be reloaded by putting the constant into memory.
4818 ;; It must come before the more general floatsisf2 pattern.
4819 (define_insn ""
4820   [(set (match_operand:SF 0 "register_operand" "=f")
4821         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4822   "! TARGET_SOFT_FLOAT"
4823   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4824   [(set_attr "type" "fpalu")
4825    (set_attr "length" "8")])
4827 (define_insn "floatsisf2"
4828   [(set (match_operand:SF 0 "register_operand" "=f")
4829         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4830   "! TARGET_SOFT_FLOAT"
4831   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4832   [(set_attr "type" "fpalu")
4833    (set_attr "length" "4")])
4835 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4836 ;; to be reloaded by putting the constant into memory.
4837 ;; It must come before the more general floatsidf2 pattern.
4838 (define_insn ""
4839   [(set (match_operand:DF 0 "register_operand" "=f")
4840         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4841   "! TARGET_SOFT_FLOAT"
4842   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4843   [(set_attr "type" "fpalu")
4844    (set_attr "length" "8")])
4846 (define_insn "floatsidf2"
4847   [(set (match_operand:DF 0 "register_operand" "=f")
4848         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4849   "! TARGET_SOFT_FLOAT"
4850   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4851   [(set_attr "type" "fpalu")
4852    (set_attr "length" "4")])
4854 (define_expand "floatunssisf2"
4855   [(set (subreg:SI (match_dup 2) 4)
4856         (match_operand:SI 1 "register_operand" ""))
4857    (set (subreg:SI (match_dup 2) 0)
4858         (const_int 0))
4859    (set (match_operand:SF 0 "register_operand" "")
4860         (float:SF (match_dup 2)))]
4861   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4862   "
4864   if (TARGET_PA_20)
4865     {
4866       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4867       DONE;
4868     }
4869   operands[2] = gen_reg_rtx (DImode);
4872 (define_expand "floatunssidf2"
4873   [(set (subreg:SI (match_dup 2) 4)
4874         (match_operand:SI 1 "register_operand" ""))
4875    (set (subreg:SI (match_dup 2) 0)
4876         (const_int 0))
4877    (set (match_operand:DF 0 "register_operand" "")
4878         (float:DF (match_dup 2)))]
4879   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4880   "
4882   if (TARGET_PA_20)
4883     {
4884       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4885       DONE;
4886     }
4887   operands[2] = gen_reg_rtx (DImode);
4890 (define_insn "floatdisf2"
4891   [(set (match_operand:SF 0 "register_operand" "=f")
4892         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4893   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4894   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4895   [(set_attr "type" "fpalu")
4896    (set_attr "length" "4")])
4898 (define_insn "floatdidf2"
4899   [(set (match_operand:DF 0 "register_operand" "=f")
4900         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4901   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4902   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4903   [(set_attr "type" "fpalu")
4904    (set_attr "length" "4")])
4906 ;; Convert a float to an actual integer.
4907 ;; Truncation is performed as part of the conversion.
4909 (define_insn "fix_truncsfsi2"
4910   [(set (match_operand:SI 0 "register_operand" "=f")
4911         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4912   "! TARGET_SOFT_FLOAT"
4913   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4914   [(set_attr "type" "fpalu")
4915    (set_attr "length" "4")])
4917 (define_insn "fix_truncdfsi2"
4918   [(set (match_operand:SI 0 "register_operand" "=f")
4919         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4920   "! TARGET_SOFT_FLOAT"
4921   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4922   [(set_attr "type" "fpalu")
4923    (set_attr "length" "4")])
4925 (define_insn "fix_truncsfdi2"
4926   [(set (match_operand:DI 0 "register_operand" "=f")
4927         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4928   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4929   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4930   [(set_attr "type" "fpalu")
4931    (set_attr "length" "4")])
4933 (define_insn "fix_truncdfdi2"
4934   [(set (match_operand:DI 0 "register_operand" "=f")
4935         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4936   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4937   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4938   [(set_attr "type" "fpalu")
4939    (set_attr "length" "4")])
4941 (define_insn "floatunssidf2_pa20"
4942   [(set (match_operand:DF 0 "register_operand" "=f")
4943         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4944   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4945   "fcnv,uw,dbl %1,%0"
4946   [(set_attr "type" "fpalu")
4947    (set_attr "length" "4")])
4949 (define_insn "floatunssisf2_pa20"
4950   [(set (match_operand:SF 0 "register_operand" "=f")
4951         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4952   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4953   "fcnv,uw,sgl %1,%0"
4954   [(set_attr "type" "fpalu")
4955    (set_attr "length" "4")])
4957 (define_insn "floatunsdisf2"
4958   [(set (match_operand:SF 0 "register_operand" "=f")
4959         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4960   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4961   "fcnv,udw,sgl %1,%0"
4962   [(set_attr "type" "fpalu")
4963    (set_attr "length" "4")])
4965 (define_insn "floatunsdidf2"
4966   [(set (match_operand:DF 0 "register_operand" "=f")
4967         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4968   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4969   "fcnv,udw,dbl %1,%0"
4970   [(set_attr "type" "fpalu")
4971    (set_attr "length" "4")])
4973 (define_insn "fixuns_truncsfsi2"
4974   [(set (match_operand:SI 0 "register_operand" "=f")
4975         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4976   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4977   "fcnv,t,sgl,uw %1,%0"
4978   [(set_attr "type" "fpalu")
4979    (set_attr "length" "4")])
4981 (define_insn "fixuns_truncdfsi2"
4982   [(set (match_operand:SI 0 "register_operand" "=f")
4983         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4984   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4985   "fcnv,t,dbl,uw %1,%0"
4986   [(set_attr "type" "fpalu")
4987    (set_attr "length" "4")])
4989 (define_insn "fixuns_truncsfdi2"
4990   [(set (match_operand:DI 0 "register_operand" "=f")
4991         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4992   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4993   "fcnv,t,sgl,udw %1,%0"
4994   [(set_attr "type" "fpalu")
4995    (set_attr "length" "4")])
4997 (define_insn "fixuns_truncdfdi2"
4998   [(set (match_operand:DI 0 "register_operand" "=f")
4999         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5000   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5001   "fcnv,t,dbl,udw %1,%0"
5002   [(set_attr "type" "fpalu")
5003    (set_attr "length" "4")])
5005 ;;- arithmetic instructions
5007 (define_expand "adddi3"
5008   [(set (match_operand:DI 0 "register_operand" "")
5009         (plus:DI (match_operand:DI 1 "register_operand" "")
5010                  (match_operand:DI 2 "adddi3_operand" "")))]
5011   ""
5012   "")
5014 (define_insn ""
5015   [(set (match_operand:DI 0 "register_operand" "=r")
5016         (plus:DI (match_operand:DI 1 "register_operand" "%r")
5017                  (match_operand:DI 2 "arith11_operand" "rI")))]
5018   "!TARGET_64BIT"
5019   "*
5021   if (GET_CODE (operands[2]) == CONST_INT)
5022     {
5023       if (INTVAL (operands[2]) >= 0)
5024         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5025       else
5026         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5027     }
5028   else
5029     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5031   [(set_attr "type" "binary")
5032    (set_attr "length" "8")])
5034 (define_insn ""
5035   [(set (match_operand:DI 0 "register_operand" "=r,r")
5036         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5037                  (match_operand:DI 2 "arith14_operand" "r,J")))]
5038   "TARGET_64BIT"
5039   "@
5040    add,l %1,%2,%0
5041    ldo %2(%1),%0"
5042   [(set_attr "type" "binary,binary")
5043    (set_attr "pa_combine_type" "addmove")
5044    (set_attr "length" "4,4")])
5046 (define_insn ""
5047   [(set (match_operand:DI 0 "register_operand" "=r")
5048         (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5049                  (match_operand:DI 2 "register_operand" "r")))]
5050   "TARGET_64BIT"
5051   "uaddcm %2,%1,%0"
5052   [(set_attr "type" "binary")
5053    (set_attr "length" "4")])
5055 (define_insn ""
5056   [(set (match_operand:SI 0 "register_operand" "=r")
5057         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5058                  (match_operand:SI 2 "register_operand" "r")))]
5059   ""
5060   "uaddcm %2,%1,%0"
5061   [(set_attr "type" "binary")
5062    (set_attr "length" "4")])
5064 (define_expand "addvdi3"
5065   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5066                    (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5067                             (match_operand:DI 2 "arith11_operand" "")))
5068               (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5069                                     (sign_extend:TI (match_dup 2)))
5070                            (sign_extend:TI (plus:DI (match_dup 1)
5071                                                     (match_dup 2))))
5072                        (const_int 0))])]
5073   ""
5074   "")
5076 (define_insn ""
5077   [(set (match_operand:DI 0 "register_operand" "=r,r")
5078         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM,rM")
5079                  (match_operand:DI 2 "arith11_operand" "r,I")))
5080    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5081                          (sign_extend:TI (match_dup 2)))
5082                 (sign_extend:TI (plus:DI (match_dup 1)
5083                                          (match_dup 2))))
5084             (const_int 0))]
5085   "TARGET_64BIT"
5086   "@
5087   add,tsv,* %2,%1,%0
5088   addi,tsv,* %2,%1,%0"
5089   [(set_attr "type" "binary,binary")
5090    (set_attr "length" "4,4")])
5092 (define_insn ""
5093   [(set (match_operand:DI 0 "register_operand" "=r")
5094         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5095                  (match_operand:DI 2 "arith11_operand" "rI")))
5096    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5097                          (sign_extend:TI (match_dup 2)))
5098                 (sign_extend:TI (plus:DI (match_dup 1)
5099                                          (match_dup 2))))
5100             (const_int 0))]
5101   "!TARGET_64BIT"
5102   "*
5104   if (GET_CODE (operands[2]) == CONST_INT)
5105     {
5106       if (INTVAL (operands[2]) >= 0)
5107         return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5108       else
5109         return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5110     }
5111   else
5112     return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5114   [(set_attr "type" "binary")
5115    (set_attr "length" "8")])
5117 ;; define_splits to optimize cases of adding a constant integer
5118 ;; to a register when the constant does not fit in 14 bits.  */
5119 (define_split
5120   [(set (match_operand:SI 0 "register_operand" "")
5121         (plus:SI (match_operand:SI 1 "register_operand" "")
5122                  (match_operand:SI 2 "const_int_operand" "")))
5123    (clobber (match_operand:SI 4 "register_operand" ""))]
5124   "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5125    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5126   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5127    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5128   "
5130   int val = INTVAL (operands[2]);
5131   int low = (val < 0) ? -0x2000 : 0x1fff;
5132   int rest = val - low;
5134   operands[2] = GEN_INT (rest);
5135   operands[3] = GEN_INT (low);
5138 (define_split
5139   [(set (match_operand:SI 0 "register_operand" "")
5140         (plus:SI (match_operand:SI 1 "register_operand" "")
5141                  (match_operand:SI 2 "const_int_operand" "")))
5142    (clobber (match_operand:SI 4 "register_operand" ""))]
5143   "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5144   [(set (match_dup 4) (match_dup 2))
5145    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5146                                (match_dup 1)))]
5147   "
5149   unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5151   /* Try dividing the constant by 2, then 4, and finally 8 to see
5152      if we can get a constant which can be loaded into a register
5153      in a single instruction (pa_cint_ok_for_move). 
5155      If that fails, try to negate the constant and subtract it
5156      from our input operand.  */
5157   if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5158     {
5159       operands[2] = GEN_INT (intval / 2);
5160       operands[3] = const1_rtx;
5161     }
5162   else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5163     {
5164       operands[2] = GEN_INT (intval / 4);
5165       operands[3] = const2_rtx;
5166     }
5167   else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5168     {
5169       operands[2] = GEN_INT (intval / 8);
5170       operands[3] = GEN_INT (3);
5171     }
5172   else if (pa_cint_ok_for_move (-intval))
5173     {
5174       emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5175       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5176       DONE;
5177     }
5178   else
5179     FAIL;
5182 (define_insn "addsi3"
5183   [(set (match_operand:SI 0 "register_operand" "=r,r")
5184         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5185                  (match_operand:SI 2 "arith14_operand" "r,J")))]
5186   ""
5187   "@
5188    {addl|add,l} %1,%2,%0
5189    ldo %2(%1),%0"
5190   [(set_attr "type" "binary,binary")
5191    (set_attr "pa_combine_type" "addmove")
5192    (set_attr "length" "4,4")])
5194 (define_insn "addvsi3"
5195   [(set (match_operand:SI 0 "register_operand" "=r,r")
5196         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5197                  (match_operand:SI 2 "arith11_operand" "r,I")))
5198    (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5199                          (sign_extend:DI (match_dup 2)))
5200                 (sign_extend:DI (plus:SI (match_dup 1)
5201                                          (match_dup 2))))
5202             (const_int 0))]
5203   ""
5204   "@
5205   {addo|add,tsv} %2,%1,%0
5206   {addio|addi,tsv} %2,%1,%0"
5207   [(set_attr "type" "binary,binary")
5208    (set_attr "length" "4,4")])
5210 (define_expand "subdi3"
5211   [(set (match_operand:DI 0 "register_operand" "")
5212         (minus:DI (match_operand:DI 1 "arith11_operand" "")
5213                   (match_operand:DI 2 "reg_or_0_operand" "")))]
5214   ""
5215   "")
5217 (define_insn ""
5218   [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5219         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5220                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5221   "TARGET_64BIT"
5222   "@
5223    sub %1,%2,%0
5224    subi %1,%2,%0
5225    mtsarcm %2"
5226   [(set_attr "type" "binary,binary,move")
5227   (set_attr "length" "4,4,4")])
5229 (define_insn ""
5230   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5231         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5232                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5233   "!TARGET_64BIT"
5234   "*
5236   if (GET_CODE (operands[1]) == CONST_INT)
5237     {
5238       if (INTVAL (operands[1]) >= 0)
5239         return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5240       else
5241         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5242     }
5243   else
5244     return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5246   [(set_attr "type" "binary")
5247    (set (attr "length")
5248         (if_then_else (eq_attr "alternative" "0")
5249           (const_int 8)
5250           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5251                             (const_int 0))
5252             (const_int 8)
5253             (const_int 12))))])
5255 (define_expand "subvdi3"
5256   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5257                    (minus:DI (match_operand:DI 1 "arith11_operand" "")
5258                              (match_operand:DI 2 "reg_or_0_operand" "")))
5259               (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5260                                      (sign_extend:TI (match_dup 2)))
5261                            (sign_extend:TI (minus:DI (match_dup 1)
5262                                                      (match_dup 2))))
5263                        (const_int 0))])]
5264   ""
5265   "")
5267 (define_insn ""
5268   [(set (match_operand:DI 0 "register_operand" "=r,r")
5269         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5270                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5271    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5272                           (sign_extend:TI (match_dup 2)))
5273                 (sign_extend:TI (minus:DI (match_dup 1)
5274                                           (match_dup 2))))
5275             (const_int 0))]
5276   "TARGET_64BIT"
5277   "@
5278   {subo|sub,tsv} %1,%2,%0
5279   {subio|subi,tsv} %1,%2,%0"
5280   [(set_attr "type" "binary,binary")
5281    (set_attr "length" "4,4")])
5283 (define_insn ""
5284   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5285         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5286                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5287    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5288                           (sign_extend:TI (match_dup 2)))
5289                 (sign_extend:TI (minus:DI (match_dup 1)
5290                                           (match_dup 2))))
5291             (const_int 0))]
5292   "!TARGET_64BIT"
5293   "*
5295   if (GET_CODE (operands[1]) == CONST_INT)
5296     {
5297       if (INTVAL (operands[1]) >= 0)
5298         return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5299       else
5300         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5301     }
5302   else
5303     return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5305   [(set_attr "type" "binary,binary")
5306    (set (attr "length")
5307         (if_then_else (eq_attr "alternative" "0")
5308           (const_int 8)
5309           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5310                             (const_int 0))
5311             (const_int 8)
5312             (const_int 12))))])
5314 (define_expand "subsi3"
5315   [(set (match_operand:SI 0 "register_operand" "")
5316         (minus:SI (match_operand:SI 1 "arith11_operand" "")
5317                   (match_operand:SI 2 "register_operand" "")))]
5318   ""
5319   "")
5321 (define_insn ""
5322   [(set (match_operand:SI 0 "register_operand" "=r,r")
5323         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5324                   (match_operand:SI 2 "register_operand" "r,r")))]
5325   "!TARGET_PA_20"
5326   "@
5327    sub %1,%2,%0
5328    subi %1,%2,%0"
5329   [(set_attr "type" "binary,binary")
5330    (set_attr "length" "4,4")])
5332 (define_insn ""
5333   [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5334         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5335                   (match_operand:SI 2 "register_operand" "r,r,!r")))]
5336   "TARGET_PA_20"
5337   "@
5338    sub %1,%2,%0
5339    subi %1,%2,%0
5340    mtsarcm %2"
5341   [(set_attr "type" "binary,binary,move")
5342    (set_attr "length" "4,4,4")])
5344 (define_insn "subvsi3"
5345   [(set (match_operand:SI 0 "register_operand" "=r,r")
5346         (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5347                   (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5348    (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5349                           (sign_extend:DI (match_dup 2)))
5350                 (sign_extend:DI (minus:SI (match_dup 1)
5351                                           (match_dup 2))))
5352             (const_int 0))]
5353   ""
5354   "@
5355   {subo|sub,tsv} %1,%2,%0
5356   {subio|subi,tsv} %1,%2,%0"
5357   [(set_attr "type" "binary,binary")
5358    (set_attr "length" "4,4")])
5360 ;; Trap instructions.
5362 (define_insn "trap"
5363   [(trap_if (const_int 1) (const_int 0))]
5364   ""
5365   "{addit|addi,tc},<> 1,%%r0,%%r0"
5366   [(set_attr "type" "trap")
5367    (set_attr "length" "4")])
5369 ;; Clobbering a "register_operand" instead of a match_scratch
5370 ;; in operand3 of millicode calls avoids spilling %r1 and
5371 ;; produces better code.
5373 ;; The mulsi3 insns set up registers for the millicode call.
5374 (define_expand "mulsi3"
5375   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5376    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5377    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5378               (clobber (match_dup 3))
5379               (clobber (reg:SI 26))
5380               (clobber (reg:SI 25))
5381               (clobber (match_dup 4))])
5382    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5383   ""
5384   "
5386   operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5387   if (TARGET_PA_11 && !TARGET_SOFT_FLOAT && !TARGET_SOFT_MULT)
5388     {
5389       rtx scratch = gen_reg_rtx (DImode);
5390       operands[1] = force_reg (SImode, operands[1]);
5391       operands[2] = force_reg (SImode, operands[2]);
5392       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5393       emit_insn (gen_movsi (operands[0],
5394                             gen_rtx_SUBREG (SImode, scratch,
5395                                             GET_MODE_SIZE (SImode))));
5396       DONE;
5397     }
5398   operands[3] = gen_reg_rtx (SImode);
5401 (define_insn "umulsidi3"
5402   [(set (match_operand:DI 0 "register_operand" "=f")
5403         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5404                  (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5405   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT"
5406   "xmpyu %1,%2,%0"
5407   [(set_attr "type" "fpmuldbl")
5408    (set_attr "length" "4")])
5410 (define_insn ""
5411   [(set (match_operand:DI 0 "register_operand" "=f")
5412         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5413                  (match_operand:DI 2 "uint32_operand" "f")))]
5414   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && !TARGET_64BIT"
5415   "xmpyu %1,%R2,%0"
5416   [(set_attr "type" "fpmuldbl")
5417    (set_attr "length" "4")])
5419 (define_insn ""
5420   [(set (match_operand:DI 0 "register_operand" "=f")
5421         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5422                  (match_operand:DI 2 "uint32_operand" "f")))]
5423   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && TARGET_64BIT"
5424   "xmpyu %1,%2R,%0"
5425   [(set_attr "type" "fpmuldbl")
5426    (set_attr "length" "4")])
5428 (define_insn ""
5429   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5430    (clobber (match_operand:SI 0 "register_operand" "=a"))
5431    (clobber (reg:SI 26))
5432    (clobber (reg:SI 25))
5433    (clobber (reg:SI 31))]
5434   "!TARGET_64BIT"
5435   "* return pa_output_mul_insn (0, insn);"
5436   [(set_attr "type" "milli")
5437    (set (attr "length")
5438         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5439               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5441 (define_insn ""
5442   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5443    (clobber (match_operand:SI 0 "register_operand" "=a"))
5444    (clobber (reg:SI 26))
5445    (clobber (reg:SI 25))
5446    (clobber (reg:SI 2))]
5447   "TARGET_64BIT"
5448   "* return pa_output_mul_insn (0, insn);"
5449   [(set_attr "type" "milli")
5450    (set (attr "length")
5451         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5452               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5454 (define_expand "muldi3"
5455   [(set (match_operand:DI 0 "register_operand" "")
5456         (mult:DI (match_operand:DI 1 "register_operand" "")
5457                  (match_operand:DI 2 "register_operand" "")))]
5458   "! optimize_size
5459    && TARGET_PA_11
5460    && ! TARGET_SOFT_FLOAT
5461    && ! TARGET_SOFT_MULT"
5462   "
5464   rtx low_product = gen_reg_rtx (DImode);
5465   rtx cross_product1 = gen_reg_rtx (DImode);
5466   rtx cross_product2 = gen_reg_rtx (DImode);
5467   rtx op1l, op1r, op2l, op2r;
5469   if (TARGET_64BIT)
5470     {
5471       rtx op1shifted = gen_reg_rtx (DImode);
5472       rtx op2shifted = gen_reg_rtx (DImode);
5474       emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5475                                                     GEN_INT (32)));
5476       emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5477                                                     GEN_INT (32)));
5478       op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5479       op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5480       op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5481       op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5482     }
5483   else
5484     {
5485       op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5486       op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5487       op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5488       op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5489     }
5491   /* Emit multiplies for the cross products.  */
5492   emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5493   emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5495   /* Emit a multiply for the low sub-word.  */
5496   emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5498   if (TARGET_64BIT)
5499     {
5500       rtx cross_scratch = gen_reg_rtx (DImode);
5501       rtx cross_product = gen_reg_rtx (DImode);
5503       /* Sum the cross products and shift them into proper position.  */
5504       emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5505       emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5507       /* Add the cross product to the low product and store the result
5508          into the output operand .  */
5509       emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5510     }
5511   else
5512     {
5513       rtx cross_scratch = gen_reg_rtx (SImode);
5515       /* Sum cross products.  */
5516       emit_move_insn (cross_scratch,
5517                       gen_rtx_PLUS (SImode,
5518                                     gen_lowpart (SImode, cross_product1),
5519                                     gen_lowpart (SImode, cross_product2)));
5520       emit_move_insn (gen_lowpart (SImode, operands[0]),
5521                       gen_lowpart (SImode, low_product));
5522       emit_move_insn (gen_highpart (SImode, operands[0]),
5523                       gen_rtx_PLUS (SImode,
5524                                     gen_highpart (SImode, low_product),
5525                                     cross_scratch));
5526     }
5527   DONE;
5530 ;;; Division and mod.
5531 (define_expand "divsi3"
5532   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5533    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5534    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5535               (clobber (match_dup 3))
5536               (clobber (match_dup 4))
5537               (clobber (reg:SI 26))
5538               (clobber (reg:SI 25))
5539               (clobber (match_dup 5))])
5540    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5541   ""
5542   "
5544   operands[3] = gen_reg_rtx (SImode);
5545   if (TARGET_64BIT)
5546     {
5547       operands[5] = gen_rtx_REG (SImode, 2);
5548       operands[4] = operands[5];
5549     }
5550   else
5551     {
5552       operands[5] = gen_rtx_REG (SImode, 31);
5553       operands[4] = gen_reg_rtx (SImode);
5554     }
5555   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5556     DONE;
5559 (define_insn ""
5560   [(set (reg:SI 29)
5561         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5562    (clobber (match_operand:SI 1 "register_operand" "=a"))
5563    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5564    (clobber (reg:SI 26))
5565    (clobber (reg:SI 25))
5566    (clobber (reg:SI 31))]
5567   "!TARGET_64BIT"
5568   "*
5569    return pa_output_div_insn (operands, 0, insn);"
5570   [(set_attr "type" "milli")
5571    (set (attr "length")
5572         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5573               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5575 (define_insn ""
5576   [(set (reg:SI 29)
5577         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5578    (clobber (match_operand:SI 1 "register_operand" "=a"))
5579    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5580    (clobber (reg:SI 26))
5581    (clobber (reg:SI 25))
5582    (clobber (reg:SI 2))]
5583   "TARGET_64BIT"
5584   "*
5585    return pa_output_div_insn (operands, 0, insn);"
5586   [(set_attr "type" "milli")
5587    (set (attr "length")
5588         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5589               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5591 (define_expand "udivsi3"
5592   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5593    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5594    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5595               (clobber (match_dup 3))
5596               (clobber (match_dup 4))
5597               (clobber (reg:SI 26))
5598               (clobber (reg:SI 25))
5599               (clobber (match_dup 5))])
5600    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5601   ""
5602   "
5604   operands[3] = gen_reg_rtx (SImode);
5606   if (TARGET_64BIT)
5607     {
5608       operands[5] = gen_rtx_REG (SImode, 2);
5609       operands[4] = operands[5];
5610     }
5611   else
5612     {
5613       operands[5] = gen_rtx_REG (SImode, 31);
5614       operands[4] = gen_reg_rtx (SImode);
5615     }
5616   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5617     DONE;
5620 (define_insn ""
5621   [(set (reg:SI 29)
5622         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5623    (clobber (match_operand:SI 1 "register_operand" "=a"))
5624    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5625    (clobber (reg:SI 26))
5626    (clobber (reg:SI 25))
5627    (clobber (reg:SI 31))]
5628   "!TARGET_64BIT"
5629   "*
5630    return pa_output_div_insn (operands, 1, insn);"
5631   [(set_attr "type" "milli")
5632    (set (attr "length")
5633         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5634               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5636 (define_insn ""
5637   [(set (reg:SI 29)
5638         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5639    (clobber (match_operand:SI 1 "register_operand" "=a"))
5640    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5641    (clobber (reg:SI 26))
5642    (clobber (reg:SI 25))
5643    (clobber (reg:SI 2))]
5644   "TARGET_64BIT"
5645   "*
5646    return pa_output_div_insn (operands, 1, insn);"
5647   [(set_attr "type" "milli")
5648    (set (attr "length")
5649         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5650               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5652 (define_expand "modsi3"
5653   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5654    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5655    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5656               (clobber (match_dup 3))
5657               (clobber (match_dup 4))
5658               (clobber (reg:SI 26))
5659               (clobber (reg:SI 25))
5660               (clobber (match_dup 5))])
5661    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5662   ""
5663   "
5665   if (TARGET_64BIT)
5666     {
5667       operands[5] = gen_rtx_REG (SImode, 2);
5668       operands[4] = operands[5];
5669     }
5670   else
5671     {
5672       operands[5] = gen_rtx_REG (SImode, 31);
5673       operands[4] = gen_reg_rtx (SImode);
5674     }
5675   operands[3] = gen_reg_rtx (SImode);
5678 (define_insn ""
5679   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5680    (clobber (match_operand:SI 0 "register_operand" "=a"))
5681    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5682    (clobber (reg:SI 26))
5683    (clobber (reg:SI 25))
5684    (clobber (reg:SI 31))]
5685   "!TARGET_64BIT"
5686   "*
5687   return pa_output_mod_insn (0, insn);"
5688   [(set_attr "type" "milli")
5689    (set (attr "length")
5690         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5691               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5693 (define_insn ""
5694   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5695    (clobber (match_operand:SI 0 "register_operand" "=a"))
5696    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5697    (clobber (reg:SI 26))
5698    (clobber (reg:SI 25))
5699    (clobber (reg:SI 2))]
5700   "TARGET_64BIT"
5701   "*
5702   return pa_output_mod_insn (0, insn);"
5703   [(set_attr "type" "milli")
5704    (set (attr "length")
5705         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5706               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5708 (define_expand "umodsi3"
5709   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5710    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5711    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5712               (clobber (match_dup 3))
5713               (clobber (match_dup 4))
5714               (clobber (reg:SI 26))
5715               (clobber (reg:SI 25))
5716               (clobber (match_dup 5))])
5717    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5718   ""
5719   "
5721   if (TARGET_64BIT)
5722     {
5723       operands[5] = gen_rtx_REG (SImode, 2);
5724       operands[4] = operands[5];
5725     }
5726   else
5727     {
5728       operands[5] = gen_rtx_REG (SImode, 31);
5729       operands[4] = gen_reg_rtx (SImode);
5730     }
5731   operands[3] = gen_reg_rtx (SImode);
5734 (define_insn ""
5735   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5736    (clobber (match_operand:SI 0 "register_operand" "=a"))
5737    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5738    (clobber (reg:SI 26))
5739    (clobber (reg:SI 25))
5740    (clobber (reg:SI 31))]
5741   "!TARGET_64BIT"
5742   "*
5743   return pa_output_mod_insn (1, insn);"
5744   [(set_attr "type" "milli")
5745    (set (attr "length")
5746         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5747               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5749 (define_insn ""
5750   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5751    (clobber (match_operand:SI 0 "register_operand" "=a"))
5752    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5753    (clobber (reg:SI 26))
5754    (clobber (reg:SI 25))
5755    (clobber (reg:SI 2))]
5756   "TARGET_64BIT"
5757   "*
5758   return pa_output_mod_insn (1, insn);"
5759   [(set_attr "type" "milli")
5760    (set (attr "length")
5761         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5762               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5764 ;;- and instructions
5765 ;; We define DImode `and` so with DImode `not` we can get
5766 ;; DImode `andn`.  Other combinations are possible.
5768 (define_expand "anddi3"
5769   [(set (match_operand:DI 0 "register_operand" "")
5770         (and:DI (match_operand:DI 1 "register_operand" "")
5771                 (match_operand:DI 2 "and_operand" "")))]
5772   "TARGET_64BIT"
5773   "")
5775 (define_insn ""
5776   [(set (match_operand:DI 0 "register_operand" "=r,r")
5777         (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5778                 (match_operand:DI 2 "and_operand" "rO,P")))]
5779   "TARGET_64BIT"
5780   "* return pa_output_64bit_and (operands); "
5781   [(set_attr "type" "binary")
5782    (set_attr "length" "4")])
5784 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5785 ; constant with ldil;ldo.
5786 (define_insn "andsi3"
5787   [(set (match_operand:SI 0 "register_operand" "=r,r")
5788         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5789                 (match_operand:SI 2 "and_operand" "rO,P")))]
5790   ""
5791   "* return pa_output_and (operands); "
5792   [(set_attr "type" "binary,shift")
5793    (set_attr "length" "4,4")])
5795 (define_insn ""
5796   [(set (match_operand:DI 0 "register_operand" "=r")
5797         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5798                 (match_operand:DI 2 "register_operand" "r")))]
5799   "TARGET_64BIT"
5800   "andcm %2,%1,%0"
5801   [(set_attr "type" "binary")
5802    (set_attr "length" "4")])
5804 (define_insn ""
5805   [(set (match_operand:SI 0 "register_operand" "=r")
5806         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5807                 (match_operand:SI 2 "register_operand" "r")))]
5808   ""
5809   "andcm %2,%1,%0"
5810   [(set_attr "type" "binary")
5811   (set_attr "length" "4")])
5813 (define_expand "iordi3"
5814   [(set (match_operand:DI 0 "register_operand" "")
5815         (ior:DI (match_operand:DI 1 "register_operand" "")
5816                 (match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5817   "TARGET_64BIT"
5818   "")
5820 (define_insn ""
5821   [(set (match_operand:DI 0 "register_operand" "=r,r")
5822         (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5823                 (match_operand:DI 2 "cint_ior_operand" "M,i")))]
5824   "TARGET_64BIT"
5825   "* return pa_output_64bit_ior (operands); "
5826   [(set_attr "type" "binary,shift")
5827    (set_attr "length" "4,4")])
5829 (define_insn ""
5830   [(set (match_operand:DI 0 "register_operand" "=r")
5831         (ior:DI (match_operand:DI 1 "register_operand" "%r")
5832                 (match_operand:DI 2 "register_operand" "r")))]
5833   "TARGET_64BIT"
5834   "or %1,%2,%0"
5835   [(set_attr "type" "binary")
5836    (set_attr "length" "4")])
5838 ;; Need a define_expand because we've run out of CONST_OK... characters.
5839 (define_expand "iorsi3"
5840   [(set (match_operand:SI 0 "register_operand" "")
5841         (ior:SI (match_operand:SI 1 "register_operand" "")
5842                 (match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5843   ""
5844   "")
5846 (define_insn ""
5847   [(set (match_operand:SI 0 "register_operand" "=r,r")
5848         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5849                 (match_operand:SI 2 "cint_ior_operand" "M,i")))]
5850   ""
5851   "* return pa_output_ior (operands); "
5852   [(set_attr "type" "binary,shift")
5853    (set_attr "length" "4,4")])
5855 (define_insn ""
5856   [(set (match_operand:SI 0 "register_operand" "=r")
5857         (ior:SI (match_operand:SI 1 "register_operand" "%r")
5858                 (match_operand:SI 2 "register_operand" "r")))]
5859   ""
5860   "or %1,%2,%0"
5861   [(set_attr "type" "binary")
5862    (set_attr "length" "4")])
5864 (define_expand "xordi3"
5865   [(set (match_operand:DI 0 "register_operand" "")
5866         (xor:DI (match_operand:DI 1 "register_operand" "")
5867                 (match_operand:DI 2 "register_operand" "")))]
5868   "TARGET_64BIT"
5869   "")
5871 (define_insn ""
5872   [(set (match_operand:DI 0 "register_operand" "=r")
5873         (xor:DI (match_operand:DI 1 "register_operand" "%r")
5874                 (match_operand:DI 2 "register_operand" "r")))]
5875   "TARGET_64BIT"
5876   "xor %1,%2,%0"
5877   [(set_attr "type" "binary")
5878    (set_attr "length" "4")])
5880 (define_insn "xorsi3"
5881   [(set (match_operand:SI 0 "register_operand" "=r")
5882         (xor:SI (match_operand:SI 1 "register_operand" "%r")
5883                 (match_operand:SI 2 "register_operand" "r")))]
5884   ""
5885   "xor %1,%2,%0"
5886   [(set_attr "type" "binary")
5887    (set_attr "length" "4")])
5889 (define_expand "negdi2"
5890   [(set (match_operand:DI 0 "register_operand" "")
5891         (neg:DI (match_operand:DI 1 "register_operand" "")))]
5892   ""
5893   "")
5895 (define_insn ""
5896   [(set (match_operand:DI 0 "register_operand" "=r")
5897         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5898   "!TARGET_64BIT"
5899   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5900   [(set_attr "type" "unary")
5901    (set_attr "length" "8")])
5903 (define_insn ""
5904   [(set (match_operand:DI 0 "register_operand" "=r")
5905         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5906   "TARGET_64BIT"
5907   "sub %%r0,%1,%0"
5908   [(set_attr "type" "unary")
5909    (set_attr "length" "4")])
5911 (define_expand "negvdi2"
5912   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5913                    (neg:DI (match_operand:DI 1 "register_operand" "")))
5914               (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5915                                    (sign_extend:TI (neg:DI (match_dup 1))))
5916                        (const_int 0))])]
5917   ""
5918   "")
5920 (define_insn ""
5921   [(set (match_operand:DI 0 "register_operand" "=r")
5922         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5923    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5924                 (sign_extend:TI (neg:DI (match_dup 1))))
5925             (const_int 0))]
5926   "!TARGET_64BIT"
5927   "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
5928   [(set_attr "type" "unary")
5929    (set_attr "length" "8")])
5931 (define_insn ""
5932   [(set (match_operand:DI 0 "register_operand" "=r")
5933         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5934    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
5935                 (sign_extend:TI (neg:DI (match_dup 1))))
5936             (const_int 0))]
5937   "TARGET_64BIT"
5938   "sub,tsv %%r0,%1,%0"
5939   [(set_attr "type" "unary")
5940    (set_attr "length" "4")])
5942 (define_insn "negsi2"
5943   [(set (match_operand:SI 0 "register_operand" "=r")
5944         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
5945   ""
5946   "sub %%r0,%1,%0"
5947   [(set_attr "type" "unary")
5948    (set_attr "length" "4")])
5950 (define_insn "negvsi2"
5951   [(set (match_operand:SI 0 "register_operand" "=r")
5952         (neg:SI (match_operand:SI 1 "register_operand" "r")))
5953    (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
5954                 (sign_extend:DI (neg:SI (match_dup 1))))
5955             (const_int 0))]
5956    ""
5957    "{subo|sub,tsv} %%r0,%1,%0"
5958   [(set_attr "type" "unary")
5959    (set_attr "length" "4")])
5961 (define_expand "one_cmpldi2"
5962   [(set (match_operand:DI 0 "register_operand" "")
5963         (not:DI (match_operand:DI 1 "register_operand" "")))]
5964   ""
5965   "
5969 (define_insn ""
5970   [(set (match_operand:DI 0 "register_operand" "=r")
5971         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5972   "!TARGET_64BIT"
5973   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5974   [(set_attr "type" "unary")
5975    (set_attr "length" "8")])
5977 (define_insn ""
5978   [(set (match_operand:DI 0 "register_operand" "=r")
5979         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5980   "TARGET_64BIT"
5981   "uaddcm %%r0,%1,%0"
5982   [(set_attr "type" "unary")
5983    (set_attr "length" "4")])
5985 (define_insn "one_cmplsi2"
5986   [(set (match_operand:SI 0 "register_operand" "=r")
5987         (not:SI (match_operand:SI 1 "register_operand" "r")))]
5988   ""
5989   "uaddcm %%r0,%1,%0"
5990   [(set_attr "type" "unary")
5991    (set_attr "length" "4")])
5993 ;; Floating point arithmetic instructions.
5995 (define_insn "adddf3"
5996   [(set (match_operand:DF 0 "register_operand" "=f")
5997         (plus:DF (match_operand:DF 1 "register_operand" "f")
5998                  (match_operand:DF 2 "register_operand" "f")))]
5999   "! TARGET_SOFT_FLOAT"
6000   "fadd,dbl %1,%2,%0"
6001   [(set_attr "type" "fpalu")
6002    (set_attr "pa_combine_type" "faddsub")
6003    (set_attr "length" "4")])
6005 (define_insn "addsf3"
6006   [(set (match_operand:SF 0 "register_operand" "=f")
6007         (plus:SF (match_operand:SF 1 "register_operand" "f")
6008                  (match_operand:SF 2 "register_operand" "f")))]
6009   "! TARGET_SOFT_FLOAT"
6010   "fadd,sgl %1,%2,%0"
6011   [(set_attr "type" "fpalu")
6012    (set_attr "pa_combine_type" "faddsub")
6013    (set_attr "length" "4")])
6015 (define_insn "subdf3"
6016   [(set (match_operand:DF 0 "register_operand" "=f")
6017         (minus:DF (match_operand:DF 1 "register_operand" "f")
6018                   (match_operand:DF 2 "register_operand" "f")))]
6019   "! TARGET_SOFT_FLOAT"
6020   "fsub,dbl %1,%2,%0"
6021   [(set_attr "type" "fpalu")
6022    (set_attr "pa_combine_type" "faddsub")
6023    (set_attr "length" "4")])
6025 (define_insn "subsf3"
6026   [(set (match_operand:SF 0 "register_operand" "=f")
6027         (minus:SF (match_operand:SF 1 "register_operand" "f")
6028                   (match_operand:SF 2 "register_operand" "f")))]
6029   "! TARGET_SOFT_FLOAT"
6030   "fsub,sgl %1,%2,%0"
6031   [(set_attr "type" "fpalu")
6032    (set_attr "pa_combine_type" "faddsub")
6033    (set_attr "length" "4")])
6035 (define_insn "muldf3"
6036   [(set (match_operand:DF 0 "register_operand" "=f")
6037         (mult:DF (match_operand:DF 1 "register_operand" "f")
6038                  (match_operand:DF 2 "register_operand" "f")))]
6039   "! TARGET_SOFT_FLOAT"
6040   "fmpy,dbl %1,%2,%0"
6041   [(set_attr "type" "fpmuldbl")
6042    (set_attr "pa_combine_type" "fmpy")
6043    (set_attr "length" "4")])
6045 (define_insn "mulsf3"
6046   [(set (match_operand:SF 0 "register_operand" "=f")
6047         (mult:SF (match_operand:SF 1 "register_operand" "f")
6048                  (match_operand:SF 2 "register_operand" "f")))]
6049   "! TARGET_SOFT_FLOAT"
6050   "fmpy,sgl %1,%2,%0"
6051   [(set_attr "type" "fpmulsgl")
6052    (set_attr "pa_combine_type" "fmpy")
6053    (set_attr "length" "4")])
6055 (define_insn "divdf3"
6056   [(set (match_operand:DF 0 "register_operand" "=f")
6057         (div:DF (match_operand:DF 1 "register_operand" "f")
6058                 (match_operand:DF 2 "register_operand" "f")))]
6059   "! TARGET_SOFT_FLOAT"
6060   "fdiv,dbl %1,%2,%0"
6061   [(set_attr "type" "fpdivdbl")
6062    (set_attr "length" "4")])
6064 (define_insn "divsf3"
6065   [(set (match_operand:SF 0 "register_operand" "=f")
6066         (div:SF (match_operand:SF 1 "register_operand" "f")
6067                 (match_operand:SF 2 "register_operand" "f")))]
6068   "! TARGET_SOFT_FLOAT"
6069   "fdiv,sgl %1,%2,%0"
6070   [(set_attr "type" "fpdivsgl")
6071    (set_attr "length" "4")])
6073 ;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6074 ;; negation can be done by subtracting from plus zero.  However, this
6075 ;; violates the IEEE standard when negating plus and minus zero.
6076 ;; The slow path toggles the sign bit in the general registers.
6077 (define_expand "negdf2"
6078   [(set (match_operand:DF 0 "register_operand" "")
6079         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6080   "!TARGET_SOFT_FLOAT"
6082   if (TARGET_PA_20 || !flag_signed_zeros)
6083     emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6084   else
6085     emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6086   DONE;
6089 (define_insn "negdf2_slow"
6090   [(set (match_operand:DF 0 "register_operand" "=r")
6091         (neg:DF (match_operand:DF 1 "register_operand" "r")))]
6092   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6093   "*
6095   if (rtx_equal_p (operands[0], operands[1]))
6096     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6097   else
6098     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6100   [(set_attr "type" "multi")
6101    (set (attr "length")
6102         (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6103             (const_int 12)
6104             (const_int 16)))])
6106 (define_insn "negdf2_fast"
6107   [(set (match_operand:DF 0 "register_operand" "=f")
6108         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
6109   "!TARGET_SOFT_FLOAT"
6110   "*
6112   if (TARGET_PA_20)
6113     return \"fneg,dbl %1,%0\";
6114   else
6115     return \"fsub,dbl %%fr0,%1,%0\";
6117   [(set_attr "type" "fpalu")
6118    (set_attr "length" "4")])
6120 (define_expand "negsf2"
6121   [(set (match_operand:SF 0 "register_operand" "")
6122         (neg:SF (match_operand:SF 1 "register_operand" "")))]
6123   "!TARGET_SOFT_FLOAT"
6125   if (TARGET_PA_20 || !flag_signed_zeros)
6126     emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6127   else
6128     emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6129   DONE;
6132 (define_insn "negsf2_slow"
6133   [(set (match_operand:SF 0 "register_operand" "=r")
6134         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
6135   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6136   "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6137   [(set_attr "type" "multi")
6138    (set_attr "length" "12")])
6140 (define_insn "negsf2_fast"
6141   [(set (match_operand:SF 0 "register_operand" "=f")
6142         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6143   "!TARGET_SOFT_FLOAT"
6144   "*
6146   if (TARGET_PA_20)
6147     return \"fneg,sgl %1,%0\";
6148   else
6149     return \"fsub,sgl %%fr0,%1,%0\";
6151   [(set_attr "type" "fpalu")
6152    (set_attr "length" "4")])
6154 (define_insn "absdf2"
6155   [(set (match_operand:DF 0 "register_operand" "=f")
6156         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
6157   "! TARGET_SOFT_FLOAT"
6158   "fabs,dbl %1,%0"
6159   [(set_attr "type" "fpalu")
6160    (set_attr "length" "4")])
6162 (define_insn "abssf2"
6163   [(set (match_operand:SF 0 "register_operand" "=f")
6164         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6165   "! TARGET_SOFT_FLOAT"
6166   "fabs,sgl %1,%0"
6167   [(set_attr "type" "fpalu")
6168    (set_attr "length" "4")])
6170 (define_insn "sqrtdf2"
6171   [(set (match_operand:DF 0 "register_operand" "=f")
6172         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6173   "! TARGET_SOFT_FLOAT"
6174   "fsqrt,dbl %1,%0"
6175   [(set_attr "type" "fpsqrtdbl")
6176    (set_attr "length" "4")])
6178 (define_insn "sqrtsf2"
6179   [(set (match_operand:SF 0 "register_operand" "=f")
6180         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6181   "! TARGET_SOFT_FLOAT"
6182   "fsqrt,sgl %1,%0"
6183   [(set_attr "type" "fpsqrtsgl")
6184    (set_attr "length" "4")])
6186 ;; PA 2.0 floating point instructions
6188 ; fmpyfadd patterns
6189 (define_insn "fmadf4"
6190   [(set (match_operand:DF 0 "register_operand" "=f")
6191         (fma:DF (match_operand:DF 1 "register_operand" "f")
6192                 (match_operand:DF 2 "register_operand" "f")
6193                 (match_operand:DF 3 "register_operand" "f")))]
6194   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6195   "fmpyfadd,dbl %1,%2,%3,%0"
6196   [(set_attr "type" "fpmuldbl")
6197    (set_attr "length" "4")])
6199 (define_insn "fmasf4"
6200   [(set (match_operand:SF 0 "register_operand" "=f")
6201         (fma:SF (match_operand:SF 1 "register_operand" "f")
6202                 (match_operand:SF 2 "register_operand" "f")
6203                 (match_operand:SF 3 "register_operand" "f")))]
6204   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6205   "fmpyfadd,sgl %1,%2,%3,%0"
6206   [(set_attr "type" "fpmulsgl")
6207    (set_attr "length" "4")])
6209 ; fmpynfadd patterns
6210 (define_insn "fnmadf4"
6211   [(set (match_operand:DF 0 "register_operand" "=f")
6212         (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6213                 (match_operand:DF 2 "register_operand" "f")
6214                 (match_operand:DF 3 "register_operand" "f")))]
6215   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6216   "fmpynfadd,dbl %1,%2,%3,%0"
6217   [(set_attr "type" "fpmuldbl")
6218    (set_attr "length" "4")])
6220 (define_insn "fnmasf4"
6221   [(set (match_operand:SF 0 "register_operand" "=f")
6222         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6223                 (match_operand:SF 2 "register_operand" "f")
6224                 (match_operand:SF 3 "register_operand" "f")))]
6225   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6226   "fmpynfadd,sgl %1,%2,%3,%0"
6227   [(set_attr "type" "fpmulsgl")
6228    (set_attr "length" "4")])
6230 ; fnegabs patterns
6231 (define_insn ""
6232   [(set (match_operand:DF 0 "register_operand" "=f")
6233         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6234   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6235   "fnegabs,dbl %1,%0"
6236   [(set_attr "type" "fpalu")
6237    (set_attr "length" "4")])
6239 (define_insn ""
6240   [(set (match_operand:SF 0 "register_operand" "=f")
6241         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6242   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6243   "fnegabs,sgl %1,%0"
6244   [(set_attr "type" "fpalu")
6245    (set_attr "length" "4")])
6247 (define_insn ""
6248   [(set (match_operand:DF 0 "register_operand" "=f")
6249         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6250    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6251   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6252     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6253   "#"
6254   [(set_attr "type" "fpalu")
6255    (set_attr "length" "8")])
6257 (define_split
6258   [(set (match_operand:DF 0 "register_operand" "")
6259         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6260    (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6261   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6262   [(set (match_dup 2) (abs:DF (match_dup 1)))
6263    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6264   "")
6266 (define_insn ""
6267   [(set (match_operand:SF 0 "register_operand" "=f")
6268         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6269    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6270   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6271     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6272   "#"
6273   [(set_attr "type" "fpalu")
6274    (set_attr "length" "8")])
6276 (define_split
6277   [(set (match_operand:SF 0 "register_operand" "")
6278         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6279    (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6280   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6281   [(set (match_dup 2) (abs:SF (match_dup 1)))
6282    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6283   "")
6285 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6286 ;; instruction if we can ignore the sign of zero.
6287 (define_insn ""
6288   [(set (match_operand:DF 0 "register_operand" "=f")
6289         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6290                          (match_operand:DF 2 "register_operand" "f"))))]
6291   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6292   "fmpynfadd,dbl %1,%2,%%fr0,%0"
6293   [(set_attr "type" "fpmuldbl")
6294    (set_attr "length" "4")])
6296 (define_insn ""
6297   [(set (match_operand:SF 0 "register_operand" "=f")
6298         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6299                          (match_operand:SF 2 "register_operand" "f"))))]
6300   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6301   "fmpynfadd,sgl %1,%2,%%fr0,%0"
6302   [(set_attr "type" "fpmuldbl")
6303    (set_attr "length" "4")])
6305 (define_insn ""
6306   [(set (match_operand:DF 0 "register_operand" "=f")
6307         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6308                          (match_operand:DF 2 "register_operand" "f"))))
6309    (set (match_operand:DF 3 "register_operand" "=&f")
6310         (mult:DF (match_dup 1) (match_dup 2)))]
6311   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6312     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6313           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6314   "#"
6315   [(set_attr "type" "fpmuldbl")
6316    (set_attr "length" "8")])
6318 (define_split
6319   [(set (match_operand:DF 0 "register_operand" "")
6320         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6321                          (match_operand:DF 2 "register_operand" ""))))
6322    (set (match_operand:DF 3 "register_operand" "")
6323         (mult:DF (match_dup 1) (match_dup 2)))]
6324   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6325   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6326    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6327   "")
6329 (define_insn ""
6330   [(set (match_operand:SF 0 "register_operand" "=f")
6331         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6332                          (match_operand:SF 2 "register_operand" "f"))))
6333    (set (match_operand:SF 3 "register_operand" "=&f")
6334         (mult:SF (match_dup 1) (match_dup 2)))]
6335   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6336     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6337           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6338   "#"
6339   [(set_attr "type" "fpmuldbl")
6340    (set_attr "length" "8")])
6342 (define_split
6343   [(set (match_operand:SF 0 "register_operand" "")
6344         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6345                          (match_operand:SF 2 "register_operand" ""))))
6346    (set (match_operand:SF 3 "register_operand" "")
6347         (mult:SF (match_dup 1) (match_dup 2)))]
6348   "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6349   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6350    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6351   "")
6353 ;;- Shift instructions
6355 ;; Optimized special case of shifting.
6357 (define_insn ""
6358   [(set (match_operand:SI 0 "register_operand" "=r")
6359         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6360                      (const_int 24)))]
6361   ""
6362   "ldb%M1 %1,%0"
6363   [(set_attr "type" "load")
6364    (set_attr "length" "4")])
6366 (define_insn ""
6367   [(set (match_operand:SI 0 "register_operand" "=r")
6368         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6369                      (const_int 16)))]
6370   ""
6371   "ldh%M1 %1,%0"
6372   [(set_attr "type" "load")
6373    (set_attr "length" "4")])
6375 (define_insn ""
6376   [(set (match_operand:SI 0 "register_operand" "=r")
6377         (plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6378                             (match_operand:SI 3 "shadd_operand" ""))
6379                  (match_operand:SI 1 "register_operand" "r")))]
6380   ""
6381   "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6382   [(set_attr "type" "binary")
6383    (set_attr "length" "4")])
6385 (define_insn ""
6386   [(set (match_operand:SI 0 "register_operand" "=r")
6387         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6388                           (match_operand:SI 3 "mem_shadd_operand" ""))
6389                  (match_operand:SI 1 "register_operand" "r")))]
6390   ""
6391   "*
6393   int shift_val = exact_log2 (INTVAL (operands[3]));
6394   operands[3] = GEN_INT (shift_val);
6395   return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6397   [(set_attr "type" "binary")
6398    (set_attr "length" "4")])
6400 (define_insn ""
6401   [(set (match_operand:DI 0 "register_operand" "=r")
6402         (plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6403                             (match_operand:DI 3 "shadd_operand" ""))
6404                  (match_operand:DI 1 "register_operand" "r")))]
6405   "TARGET_64BIT"
6406   "shladd,l %2,%o3,%1,%0"
6407   [(set_attr "type" "binary")
6408    (set_attr "length" "4")])
6410 (define_insn ""
6411   [(set (match_operand:DI 0 "register_operand" "=r")
6412         (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6413                           (match_operand:DI 3 "mem_shadd_operand" ""))
6414                  (match_operand:DI 1 "register_operand" "r")))]
6415   "TARGET_64BIT"
6416   "*
6418   int shift_val = exact_log2 (INTVAL (operands[3]));
6419   operands[3] = GEN_INT (shift_val);
6420   return \"shladd,l %2,%o3,%1,%0\";
6422   [(set_attr "type" "binary")
6423    (set_attr "length" "4")])
6425 (define_expand "ashlsi3"
6426   [(set (match_operand:SI 0 "register_operand" "")
6427         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6428                    (match_operand:SI 2 "arith32_operand" "")))]
6429   ""
6430   "
6432   if (GET_CODE (operands[2]) != CONST_INT)
6433     {
6434       rtx temp = gen_reg_rtx (SImode);
6435       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6436       if (GET_CODE (operands[1]) == CONST_INT)
6437         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6438       else
6439         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6440       DONE;
6441     }
6442   /* Make sure both inputs are not constants,
6443      there are no patterns for that.  */
6444   operands[1] = force_reg (SImode, operands[1]);
6447 (define_insn ""
6448   [(set (match_operand:SI 0 "register_operand" "=r")
6449         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6450                    (match_operand:SI 2 "const_int_operand" "n")))]
6451   ""
6452   "{zdep|depw,z} %1,%P2,%L2,%0"
6453   [(set_attr "type" "shift")
6454    (set_attr "length" "4")])
6456 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6457 ; Doing it like this makes slightly better code since reload can
6458 ; replace a register with a known value in range -16..15 with a
6459 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6460 ; but since we have no more CONST_OK... characters, that is not
6461 ; possible.
6462 (define_insn "zvdep32"
6463   [(set (match_operand:SI 0 "register_operand" "=r,r")
6464         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6465                    (minus:SI (const_int 31)
6466                              (match_operand:SI 2 "register_operand" "q,q"))))]
6467   ""
6468   "@
6469    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6470    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6471   [(set_attr "type" "shift,shift")
6472    (set_attr "length" "4,4")])
6474 (define_insn "zvdep_imm32"
6475   [(set (match_operand:SI 0 "register_operand" "=r")
6476         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6477                    (minus:SI (const_int 31)
6478                              (match_operand:SI 2 "register_operand" "q"))))]
6479   ""
6480   "*
6482   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6483   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6484   operands[1] = GEN_INT ((x & 0xf) - 0x10);
6485   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6487   [(set_attr "type" "shift")
6488    (set_attr "length" "4")])
6490 (define_insn "vdepi_ior"
6491   [(set (match_operand:SI 0 "register_operand" "=r")
6492         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6493                            (minus:SI (const_int 31)
6494                                      (match_operand:SI 2 "register_operand" "q")))
6495                 (match_operand:SI 3 "register_operand" "0")))]
6496   ; accept ...0001...1, can this be generalized?
6497   "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6498   "*
6500   HOST_WIDE_INT x = INTVAL (operands[1]);
6501   operands[2] = GEN_INT (exact_log2 (x + 1));
6502   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6504   [(set_attr "type" "shift")
6505    (set_attr "length" "4")])
6507 (define_insn "vdepi_and"
6508   [(set (match_operand:SI 0 "register_operand" "=r")
6509         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6510                            (minus:SI (const_int 31)
6511                                      (match_operand:SI 2 "register_operand" "q")))
6512                 (match_operand:SI 3 "register_operand" "0")))]
6513   ; this can be generalized...!
6514   "INTVAL (operands[1]) == -2"
6515   "*
6517   HOST_WIDE_INT x = INTVAL (operands[1]);
6518   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6519   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6521   [(set_attr "type" "shift")
6522    (set_attr "length" "4")])
6524 (define_expand "ashldi3"
6525   [(set (match_operand:DI 0 "register_operand" "")
6526         (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6527                    (match_operand:DI 2 "arith32_operand" "")))]
6528   ""
6529   "
6531   if (!TARGET_64BIT)
6532     {
6533       if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6534         {
6535           unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6536           if (shift >= 1 && shift <= 31)
6537             {
6538               rtx dst = operands[0];
6539               rtx src = force_reg (DImode, operands[1]);
6540               emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6541                                            gen_lowpart (SImode, src),
6542                                            GEN_INT (32-shift),
6543                                            gen_highpart (SImode, src),
6544                                            GEN_INT (shift)));
6545               emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6546                                       gen_lowpart (SImode, src),
6547                                       GEN_INT (shift)));
6548               DONE;
6549             }
6550         }
6551       /* Fallback to using optabs.c's expand_doubleword_shift.  */
6552       FAIL;
6553     }
6554   if (GET_CODE (operands[2]) != CONST_INT)
6555     {
6556       rtx temp = gen_reg_rtx (DImode);
6557       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6558       if (GET_CODE (operands[1]) == CONST_INT)
6559         emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6560       else
6561         emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6562       DONE;
6563     }
6564   /* Make sure both inputs are not constants,
6565      there are no patterns for that.  */
6566   operands[1] = force_reg (DImode, operands[1]);
6569 (define_insn ""
6570   [(set (match_operand:DI 0 "register_operand" "=r")
6571         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6572                    (match_operand:DI 2 "const_int_operand" "n")))]
6573   "TARGET_64BIT"
6574   "depd,z %1,%p2,%Q2,%0"
6575   [(set_attr "type" "shift")
6576    (set_attr "length" "4")])
6578 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6579 ; Doing it like this makes slightly better code since reload can
6580 ; replace a register with a known value in range -16..15 with a
6581 ; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6582 ; but since we have no more CONST_OK... characters, that is not
6583 ; possible.
6584 (define_insn "zvdep64"
6585   [(set (match_operand:DI 0 "register_operand" "=r,r")
6586         (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6587                    (minus:DI (const_int 63)
6588                              (match_operand:DI 2 "register_operand" "q,q"))))]
6589   "TARGET_64BIT"
6590   "@
6591    depd,z %1,%%sar,64,%0
6592    depdi,z %1,%%sar,64,%0"
6593   [(set_attr "type" "shift,shift")
6594    (set_attr "length" "4,4")])
6596 (define_insn "zvdep_imm64"
6597   [(set (match_operand:DI 0 "register_operand" "=r")
6598         (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6599                    (minus:DI (const_int 63)
6600                              (match_operand:DI 2 "register_operand" "q"))))]
6601   "TARGET_64BIT"
6602   "*
6604   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6605   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6606   operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6607   return \"depdi,z %1,%%sar,%2,%0\";
6609   [(set_attr "type" "shift")
6610    (set_attr "length" "4")])
6612 (define_insn ""
6613   [(set (match_operand:DI 0 "register_operand" "=r")
6614         (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6615                            (minus:DI (const_int 63)
6616                                      (match_operand:DI 2 "register_operand" "q")))
6617                 (match_operand:DI 3 "register_operand" "0")))]
6618   ; accept ...0001...1, can this be generalized?
6619   "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6620   "*
6622   HOST_WIDE_INT x = INTVAL (operands[1]);
6623   operands[2] = GEN_INT (exact_log2 (x + 1));
6624   return \"depdi -1,%%sar,%2,%0\";
6626   [(set_attr "type" "shift")
6627    (set_attr "length" "4")])
6629 (define_insn ""
6630   [(set (match_operand:DI 0 "register_operand" "=r")
6631         (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6632                            (minus:DI (const_int 63)
6633                                      (match_operand:DI 2 "register_operand" "q")))
6634                 (match_operand:DI 3 "register_operand" "0")))]
6635   ; this can be generalized...!
6636   "TARGET_64BIT && INTVAL (operands[1]) == -2"
6637   "*
6639   HOST_WIDE_INT x = INTVAL (operands[1]);
6640   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6641   return \"depdi 0,%%sar,%2,%0\";
6643   [(set_attr "type" "shift")
6644    (set_attr "length" "4")])
6646 (define_expand "ashrsi3"
6647   [(set (match_operand:SI 0 "register_operand" "")
6648         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6649                      (match_operand:SI 2 "arith32_operand" "")))]
6650   ""
6651   "
6653   if (GET_CODE (operands[2]) != CONST_INT)
6654     {
6655       rtx temp = gen_reg_rtx (SImode);
6656       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6657       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6658       DONE;
6659     }
6662 (define_insn ""
6663   [(set (match_operand:SI 0 "register_operand" "=r")
6664         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6665                      (match_operand:SI 2 "const_int_operand" "n")))]
6666   ""
6667   "{extrs|extrw,s} %1,%P2,%L2,%0"
6668   [(set_attr "type" "shift")
6669    (set_attr "length" "4")])
6671 (define_insn "vextrs32"
6672   [(set (match_operand:SI 0 "register_operand" "=r")
6673         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6674                      (minus:SI (const_int 31)
6675                                (match_operand:SI 2 "register_operand" "q"))))]
6676   ""
6677   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6678   [(set_attr "type" "shift")
6679    (set_attr "length" "4")])
6681 (define_expand "ashrdi3"
6682   [(set (match_operand:DI 0 "register_operand" "")
6683         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6684                      (match_operand:DI 2 "arith32_operand" "")))]
6685   "TARGET_64BIT"
6686   "
6688   if (GET_CODE (operands[2]) != CONST_INT)
6689     {
6690       rtx temp = gen_reg_rtx (DImode);
6691       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6692       emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6693       DONE;
6694     }
6697 (define_insn ""
6698   [(set (match_operand:DI 0 "register_operand" "=r")
6699         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6700                      (match_operand:DI 2 "const_int_operand" "n")))]
6701   "TARGET_64BIT"
6702   "extrd,s %1,%p2,%Q2,%0"
6703   [(set_attr "type" "shift")
6704    (set_attr "length" "4")])
6706 (define_insn "vextrs64"
6707   [(set (match_operand:DI 0 "register_operand" "=r")
6708         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6709                      (minus:DI (const_int 63)
6710                                (match_operand:DI 2 "register_operand" "q"))))]
6711   "TARGET_64BIT"
6712   "extrd,s %1,%%sar,64,%0"
6713   [(set_attr "type" "shift")
6714    (set_attr "length" "4")])
6716 (define_insn "lshrsi3"
6717   [(set (match_operand:SI 0 "register_operand" "=r,r")
6718         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6719                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6720   ""
6721   "@
6722    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6723    {extru|extrw,u} %1,%P2,%L2,%0"
6724   [(set_attr "type" "shift")
6725    (set_attr "length" "4")])
6727 (define_insn "lshrdi3"
6728   [(set (match_operand:DI 0 "register_operand" "=r,r")
6729         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6730                      (match_operand:DI 2 "shift6_operand" "q,n")))]
6731   "TARGET_64BIT"
6732   "@
6733    shrpd %%r0,%1,%%sar,%0
6734    extrd,u %1,%p2,%Q2,%0"
6735   [(set_attr "type" "shift")
6736    (set_attr "length" "4")])
6738 ; Shift right pair word 0 to 31 bits.
6739 (define_insn "*shrpsi4_1"
6740   [(set (match_operand:SI 0 "register_operand" "=r")
6741         (match_operator:SI 4 "plus_xor_ior_operator"
6742           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6743                       (minus:SI (const_int 32)
6744                                 (match_operand:SI 3 "register_operand" "q")))
6745            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6746                         (match_dup 3))]))]
6747   ""
6748   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6749   [(set_attr "type" "shift")
6750    (set_attr "length" "4")])
6752 (define_insn "*shrpsi4_2"
6753   [(set (match_operand:SI 0 "register_operand" "=r")
6754         (match_operator:SI 4 "plus_xor_ior_operator"
6755           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6756                         (match_operand:SI 3 "register_operand" "q"))
6757            (ashift:SI (match_operand:SI 1 "register_operand" "r")
6758                       (minus:SI (const_int 32)
6759                                 (match_dup 3)))]))]
6760   ""
6761   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6762   [(set_attr "type" "shift")
6763    (set_attr "length" "4")])
6765 ; Shift right pair doubleword 0 to 63 bits.
6766 (define_insn "*shrpdi4_1"
6767   [(set (match_operand:DI 0 "register_operand" "=r")
6768         (match_operator:DI 4 "plus_xor_ior_operator"
6769           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6770                       (minus:DI (const_int 64)
6771                                 (match_operand:DI 3 "register_operand" "q")))
6772            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6773                         (match_dup 3))]))]
6774   "TARGET_64BIT"
6775   "shrpd %1,%2,%%sar,%0"
6776   [(set_attr "type" "shift")
6777    (set_attr "length" "4")])
6779 (define_insn "*shrpdi4_2"
6780   [(set (match_operand:DI 0 "register_operand" "=r")
6781         (match_operator:DI 4 "plus_xor_ior_operator"
6782           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6783                         (match_operand:DI 3 "shift6_operand" "q"))
6784            (ashift:DI (match_operand:SI 1 "register_operand" "r")
6785                       (minus:DI (const_int 64)
6786                                 (match_dup 3)))]))]
6787   "TARGET_64BIT"
6788   "shrpd %1,%2,%%sar,%0"
6789   [(set_attr "type" "shift")
6790    (set_attr "length" "4")])
6792 (define_insn "*shrpdi4_3"
6793   [(set (match_operand:DI 0 "register_operand" "=r")
6794         (match_operator:DI 5 "plus_xor_ior_operator"
6795           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6796                       (match_operand:DI 3 "const_int_operand" "n"))
6797            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6798                         (match_operand:DI 4 "const_int_operand" "n"))]))]
6799   "TARGET_64BIT
6800    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6801   "shrpd %1,%2,%4,%0"
6802   [(set_attr "type" "shift")
6803    (set_attr "length" "4")])
6805 (define_insn "*shrpdi4_4"
6806   [(set (match_operand:DI 0 "register_operand" "=r")
6807         (match_operator:DI 5 "plus_xor_ior_operator"
6808           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6809                         (match_operand:DI 4 "const_int_operand" "n"))
6810            (ashift:DI (match_operand:DI 1 "register_operand" "r")
6811                       (match_operand:DI 3 "const_int_operand" "n"))]))]
6812   "TARGET_64BIT
6813    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6814   "shrpd %1,%2,%4,%0"
6815   [(set_attr "type" "shift")
6816    (set_attr "length" "4")])
6818 (define_insn "rotrsi3"
6819   [(set (match_operand:SI 0 "register_operand" "=r,r")
6820         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6821                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6822   ""
6823   "*
6825   if (GET_CODE (operands[2]) == CONST_INT)
6826     {
6827       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6828       return \"{shd|shrpw} %1,%1,%2,%0\";
6829     }
6830   else
6831     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6833   [(set_attr "type" "shift")
6834    (set_attr "length" "4")])
6836 (define_expand "rotlsi3"
6837   [(set (match_operand:SI 0 "register_operand" "")
6838         (rotate:SI (match_operand:SI 1 "register_operand" "")
6839                    (match_operand:SI 2 "arith32_operand" "")))]
6840   ""
6841   "
6843   if (GET_CODE (operands[2]) != CONST_INT)
6844     {
6845       rtx temp = gen_reg_rtx (SImode);
6846       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6847       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6848       DONE;
6849     }
6850   /* Else expand normally.  */
6853 (define_insn "*rotlsi3_internal"
6854   [(set (match_operand:SI 0 "register_operand" "=r")
6855         (rotate:SI (match_operand:SI 1 "register_operand" "r")
6856                    (match_operand:SI 2 "const_int_operand" "n")))]
6857   ""
6858   "*
6860   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6861   return \"{shd|shrpw} %1,%1,%2,%0\";
6863   [(set_attr "type" "shift")
6864    (set_attr "length" "4")])
6866 (define_insn "rotrdi3"
6867   [(set (match_operand:DI 0 "register_operand" "=r,r")
6868         (rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
6869                      (match_operand:DI 2 "shift6_operand" "q,n")))]
6870   "TARGET_64BIT"
6871   "*
6873   if (GET_CODE (operands[2]) == CONST_INT)
6874     {
6875       operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
6876       return \"shrpd %1,%1,%2,%0\";
6877     }
6878   else
6879     return \"shrpd %1,%1,%%sar,%0\";
6881   [(set_attr "type" "shift")
6882    (set_attr "length" "4")])
6884 (define_expand "rotldi3"
6885   [(set (match_operand:DI 0 "register_operand" "")
6886         (rotate:DI (match_operand:DI 1 "register_operand" "")
6887                    (match_operand:DI 2 "arith32_operand" "")))]
6888   "TARGET_64BIT"
6889   "
6891   if (GET_CODE (operands[2]) != CONST_INT)
6892     {
6893       rtx temp = gen_reg_rtx (DImode);
6894       emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
6895       emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
6896       DONE;
6897     }
6898   /* Else expand normally.  */
6901 (define_insn "*rotldi3_internal"
6902   [(set (match_operand:DI 0 "register_operand" "=r")
6903         (rotate:DI (match_operand:DI 1 "register_operand" "r")
6904                    (match_operand:DI 2 "const_int_operand" "n")))]
6905   "TARGET_64BIT"
6906   "*
6908   operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
6909   return \"shrpd %1,%1,%2,%0\";
6911   [(set_attr "type" "shift")
6912    (set_attr "length" "4")])
6914 (define_insn ""
6915   [(set (match_operand:SI 0 "register_operand" "=r")
6916         (match_operator:SI 5 "plus_xor_ior_operator"
6917           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6918                       (match_operand:SI 3 "const_int_operand" "n"))
6919            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6920                         (match_operand:SI 4 "const_int_operand" "n"))]))]
6921   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6922   "{shd|shrpw} %1,%2,%4,%0"
6923   [(set_attr "type" "shift")
6924    (set_attr "length" "4")])
6926 (define_insn ""
6927   [(set (match_operand:SI 0 "register_operand" "=r")
6928         (match_operator:SI 5 "plus_xor_ior_operator"
6929           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6930                         (match_operand:SI 4 "const_int_operand" "n"))
6931            (ashift:SI (match_operand:SI 1 "register_operand" "r")
6932                       (match_operand:SI 3 "const_int_operand" "n"))]))]
6933   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6934   "{shd|shrpw} %1,%2,%4,%0"
6935   [(set_attr "type" "shift")
6936    (set_attr "length" "4")])
6938 (define_expand "shd_internal"
6939   [(set (match_operand:SI 0 "register_operand")
6940         (ior:SI
6941           (lshiftrt:SI (match_operand:SI 1 "register_operand")
6942                        (match_operand:SI 2 "const_int_operand"))
6943           (ashift:SI (match_operand:SI 3 "register_operand")
6944                      (match_operand:SI 4 "const_int_operand"))))]
6945   "")
6947 (define_insn ""
6948   [(set (match_operand:SI 0 "register_operand" "=r")
6949         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6950                            (match_operand:SI 2 "const_int_operand" ""))
6951                 (match_operand:SI 3 "const_int_operand" "")))]
6952   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
6953   "*
6955   int cnt = INTVAL (operands[2]) & 31;
6956   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6957   operands[2] = GEN_INT (31 - cnt);
6958   return \"{zdep|depw,z} %1,%2,%3,%0\";
6960   [(set_attr "type" "shift")
6961    (set_attr "length" "4")])
6963 ;; Unconditional and other jump instructions.
6965 ;; Trivial return used when no epilogue is needed.
6966 (define_insn "return"
6967   [(return)
6968    (use (reg:SI 2))]
6969   "pa_can_use_return_insn ()"
6970   "*
6972   if (TARGET_PA_20)
6973     return \"bve%* (%%r2)\";
6974   return \"bv%* %%r0(%%r2)\";
6976   [(set_attr "type" "branch")
6977    (set_attr "length" "4")])
6979 ;; This is used for most returns.
6980 (define_insn "return_internal"
6981   [(return)
6982    (use (reg:SI 2))]
6983   ""
6984   "*
6986   if (TARGET_PA_20)
6987     return \"bve%* (%%r2)\";
6988   return \"bv%* %%r0(%%r2)\";
6990   [(set_attr "type" "branch")
6991    (set_attr "length" "4")])
6993 ;; This is used for eh returns which bypass the return stub.
6994 (define_insn "return_external_pic"
6995   [(return)
6996    (clobber (reg:SI 1))
6997    (use (reg:SI 2))]
6998   "!TARGET_NO_SPACE_REGS
6999    && !TARGET_PA_20
7000    && flag_pic && crtl->calls_eh_return"
7001   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7002   [(set_attr "type" "branch")
7003    (set_attr "length" "12")])
7005 (define_expand "prologue"
7006   [(const_int 0)]
7007   ""
7008   "pa_expand_prologue ();DONE;")
7010 (define_expand "sibcall_epilogue"
7011   [(return)]
7012   ""
7013   "
7015   pa_expand_epilogue ();
7016   DONE;
7019 (define_expand "epilogue"
7020   [(return)]
7021   ""
7022   "
7024   rtx x;
7026   /* Try to use the trivial return first.  Else use the full epilogue.  */
7027   if (pa_can_use_return_insn ())
7028     x = gen_return ();
7029   else
7030     {
7031       pa_expand_epilogue ();
7033       /* EH returns bypass the normal return stub.  Thus, we must do an
7034          interspace branch to return from functions that call eh_return.
7035          This is only a problem for returns from shared code on ports
7036          using space registers.  */
7037       if (!TARGET_NO_SPACE_REGS
7038           && !TARGET_PA_20
7039           && flag_pic && crtl->calls_eh_return)
7040         x = gen_return_external_pic ();
7041       else
7042         x = gen_return_internal ();
7043     }
7044   emit_jump_insn (x);
7045   DONE;
7048 ; Used by hppa_profile_hook to load the starting address of the current
7049 ; function; operand 1 contains the address of the label in operand 3
7050 (define_insn "load_offset_label_address"
7051   [(set (match_operand:SI 0 "register_operand" "=r")
7052         (plus:SI (match_operand:SI 1 "register_operand" "r")
7053                  (minus:SI (match_operand:SI 2 "" "")
7054                            (label_ref:SI (match_operand 3 "" "")))))]
7055   ""
7056   "ldo %2-%l3(%1),%0"
7057   [(set_attr "type" "multi")
7058    (set_attr "length" "4")])
7060 ; Output a code label and load its address.
7061 (define_insn "lcla1"
7062   [(set (match_operand:SI 0 "register_operand" "=r")
7063         (label_ref:SI (match_operand 1 "" "")))
7064    (const_int 0)]
7065   "!TARGET_PA_20"
7066   "*
7068   output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7069   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7070                                      CODE_LABEL_NUMBER (operands[1]));
7071   return \"\";
7073   [(set_attr "type" "multi")
7074    (set_attr "length" "8")])
7076 (define_insn "lcla2"
7077   [(set (match_operand:SI 0 "register_operand" "=r")
7078         (label_ref:SI (match_operand 1 "" "")))
7079    (const_int 0)]
7080   "TARGET_PA_20"
7081   "*
7083   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7084                                      CODE_LABEL_NUMBER (operands[1]));
7085   return \"mfia %0\";
7087   [(set_attr "type" "move")
7088    (set_attr "length" "4")])
7090 (define_insn "blockage"
7091   [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7092   ""
7093   ""
7094   [(set_attr "length" "0")])
7096 (define_insn "jump"
7097   [(set (pc) (label_ref (match_operand 0 "" "")))]
7098   ""
7099   "*
7101   /* An unconditional branch which can reach its target.  */
7102   if (get_attr_length (insn) < 16)
7103     return \"b%* %l0\";
7105   return pa_output_lbranch (operands[0], insn, 1);
7107   [(set_attr "type" "uncond_branch")
7108    (set_attr "pa_combine_type" "uncond_branch")
7109    (set (attr "length")
7110     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7111                (const_int MAX_17BIT_OFFSET))
7112            (const_int 4)
7113            (match_test "TARGET_PORTABLE_RUNTIME")
7114            (const_int 20)
7115            (not (match_test "flag_pic"))
7116            (const_int 16)]
7117           (const_int 24)))])
7119 ;;; Hope this is only within a function...
7120 (define_insn "indirect_jump"
7121   [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7122   ""
7123   "bv%* %%r0(%0)"
7124   [(set_attr "type" "branch")
7125    (set_attr "length" "4")])
7127 ;;; An indirect jump can be optimized to a direct jump.  GAS for the
7128 ;;; SOM target doesn't allow branching to a label inside a function.
7129 ;;; We also don't correctly compute branch distances for labels
7130 ;;; outside the current function.  Thus, we use an indirect jump can't
7131 ;;; be optimized to a direct jump for all targets.  We assume that
7132 ;;; the branch target is in the same space (i.e., nested function
7133 ;;; jumping to a label in an outer function in the same translation
7134 ;;; unit).
7135 (define_expand "nonlocal_goto"
7136   [(use (match_operand 0 "general_operand" ""))
7137    (use (match_operand 1 "general_operand" ""))
7138    (use (match_operand 2 "general_operand" ""))
7139    (use (match_operand 3 "general_operand" ""))]
7140   ""
7142   rtx lab = operands[1];
7143   rtx stack = operands[2];
7144   rtx fp = operands[3];
7146   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7147   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7149   lab = copy_to_reg (lab);
7151   /* Restore the stack and frame pointers.  */
7152   fp = copy_to_reg (fp);
7153   emit_stack_restore (SAVE_NONLOCAL, stack);
7155   /* Ensure the frame pointer move is not optimized.  */
7156   emit_insn (gen_blockage ());
7157   emit_clobber (hard_frame_pointer_rtx);
7158   emit_clobber (frame_pointer_rtx);
7159   emit_move_insn (hard_frame_pointer_rtx, fp);
7161   emit_use (hard_frame_pointer_rtx);
7162   emit_use (stack_pointer_rtx);
7164   /* Nonlocal goto jumps are only used between functions in the same
7165      translation unit.  Thus, we can avoid the extra overhead of an
7166      interspace jump.  */
7167   emit_jump_insn (gen_indirect_goto (lab));
7168   emit_barrier ();
7169   DONE;
7172 (define_insn "indirect_goto"
7173   [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7174   "GET_MODE (operands[0]) == word_mode"
7175   "bv%* %%r0(%0)"
7176   [(set_attr "type" "branch")
7177    (set_attr "length" "4")])
7179 ;; Subroutines of "casesi".
7180 ;; operand 0 is index
7181 ;; operand 1 is the minimum bound
7182 ;; operand 2 is the maximum bound - minimum bound + 1
7183 ;; operand 3 is CODE_LABEL for the table;
7184 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7186 (define_expand "casesi"
7187   [(match_operand:SI 0 "general_operand" "")
7188    (match_operand:SI 1 "const_int_operand" "")
7189    (match_operand:SI 2 "const_int_operand" "")
7190    (match_operand 3 "" "")
7191    (match_operand 4 "" "")]
7192   ""
7193   "
7195   if (GET_CODE (operands[0]) != REG)
7196     operands[0] = force_reg (SImode, operands[0]);
7198   if (operands[1] != const0_rtx)
7199     {
7200       rtx index = gen_reg_rtx (SImode);
7202       operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7203       if (!INT_14_BITS (operands[1]))
7204         operands[1] = force_reg (SImode, operands[1]);
7205       emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7206       operands[0] = index;
7207     }
7209   if (!INT_5_BITS (operands[2]))
7210     operands[2] = force_reg (SImode, operands[2]);
7212   /* This branch prevents us finding an insn for the delay slot of the
7213      following vectored branch.  It might be possible to use the delay
7214      slot if an index value of -1 was used to transfer to the out-of-range
7215      label.  In order to do this, we would have to output the -1 vector
7216      element after the delay insn.  The casesi output code would have to
7217      check if the casesi insn is in a delay branch sequence and output
7218      the delay insn if one is found.  If this was done, then it might
7219      then be worthwhile to split the casesi patterns to improve scheduling.
7220      However, it's not clear that all this extra complexity is worth
7221      the effort.  */
7222   {
7223     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7224     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7225   }
7227   /* In 64bit mode we must make sure to wipe the upper bits of the register
7228      just in case the addition overflowed or we had random bits in the
7229      high part of the register.  */
7230   if (TARGET_64BIT)
7231     {
7232       rtx index = gen_reg_rtx (DImode);
7234       emit_insn (gen_extendsidi2 (index, operands[0]));
7235       operands[0] = index;
7236     }
7238   if (TARGET_64BIT)
7239     emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7240   else if (flag_pic)
7241     emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7242   else
7243     emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7244   DONE;
7247 ;;; 32-bit code, absolute branch table.
7248 (define_insn "casesi32"
7249   [(set (pc) (mem:SI (plus:SI
7250                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7251                                 (const_int 4))
7252                        (label_ref (match_operand 1 "" "")))))
7253    (clobber (match_scratch:SI 2 "=&r"))]
7254   "!flag_pic"
7255   "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7256   [(set_attr "type" "multi")
7257    (set_attr "length" "16")])
7259 ;;; 32-bit code, relative branch table.
7260 (define_insn "casesi32p"
7261   [(set (pc) (mem:SI (plus:SI
7262                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7263                                 (const_int 4))
7264                        (label_ref (match_operand 1 "" "")))))
7265    (clobber (match_scratch:SI 2 "=&r"))
7266    (clobber (match_scratch:SI 3 "=&r"))]
7267   "flag_pic"
7268   "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7269 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7270   [(set_attr "type" "multi")
7271    (set (attr "length")
7272      (if_then_else (match_test "TARGET_PA_20")
7273         (const_int 20)
7274         (const_int 24)))])
7276 ;;; 64-bit code, 32-bit relative branch table.
7277 (define_insn "casesi64p"
7278   [(set (pc) (mem:DI (plus:DI
7279                        (mult:DI (match_operand:DI 0 "register_operand" "r")
7280                                 (const_int 8))
7281                        (label_ref (match_operand 1 "" "")))))
7282    (clobber (match_scratch:DI 2 "=&r"))
7283    (clobber (match_scratch:DI 3 "=&r"))]
7284   ""
7285   "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7286 add,l %2,%3,%3\;bv,n %%r0(%3)"
7287   [(set_attr "type" "multi")
7288    (set_attr "length" "24")])
7291 ;; Call patterns.
7292 ;;- jump to subroutine
7294 (define_expand "call"
7295   [(parallel [(call (match_operand:SI 0 "" "")
7296                     (match_operand 1 "" ""))
7297               (clobber (reg:SI 2))])]
7298   ""
7299   "
7301   rtx op;
7302   rtx nb = operands[1];
7304   if (TARGET_PORTABLE_RUNTIME)
7305     op = force_reg (SImode, XEXP (operands[0], 0));
7306   else
7307     {
7308       op = XEXP (operands[0], 0);
7310       /* Generate indirect long calls to non-local functions. */
7311       if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7312         {
7313           tree call_decl = SYMBOL_REF_DECL (op);
7314           if (!(call_decl && targetm.binds_local_p (call_decl)))
7315             op = force_reg (word_mode, op);
7316         }
7317     }
7319   if (TARGET_64BIT)
7320     {
7321       if (!virtuals_instantiated)
7322         emit_move_insn (arg_pointer_rtx,
7323                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7324                                       GEN_INT (64)));
7325       else
7326         {
7327           /* The loop pass can generate new libcalls after the virtual
7328              registers are instantiated when fpregs are disabled because
7329              the only method that we have for doing DImode multiplication
7330              is with a libcall.  This could be trouble if we haven't
7331              allocated enough space for the outgoing arguments.  */
7332           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7334           emit_move_insn (arg_pointer_rtx,
7335                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7336                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7337         }
7338     }
7340   /* Use two different patterns for calls to explicitly named functions
7341      and calls through function pointers.  This is necessary as these two
7342      types of calls use different calling conventions, and CSE might try
7343      to change the named call into an indirect call in some cases (using
7344      two patterns keeps CSE from performing this optimization).
7345      
7346      We now use even more call patterns as there was a subtle bug in
7347      attempting to restore the pic register after a call using a simple
7348      move insn.  During reload, a instruction involving a pseudo register
7349      with no explicit dependence on the PIC register can be converted
7350      to an equivalent load from memory using the PIC register.  If we
7351      emit a simple move to restore the PIC register in the initial rtl
7352      generation, then it can potentially be repositioned during scheduling.
7353      and an instruction that eventually uses the PIC register may end up
7354      between the call and the PIC register restore.
7355      
7356      This only worked because there is a post call group of instructions
7357      that are scheduled with the call.  These instructions are included
7358      in the same basic block as the call.  However, calls can throw in
7359      C++ code and a basic block has to terminate at the call if the call
7360      can throw.  This results in the PIC register restore being scheduled
7361      independently from the call.  So, we now hide the save and restore
7362      of the PIC register in the call pattern until after reload.  Then,
7363      we split the moves out.  A small side benefit is that we now don't
7364      need to have a use of the PIC register in the return pattern and
7365      the final save/restore operation is not needed.
7366      
7367      I elected to just use register %r4 in the PIC patterns instead
7368      of trying to force hppa_pic_save_rtx () to a callee saved register.
7369      This might have required a new register class and constraint.  It
7370      was also simpler to just handle the restore from a register than a
7371      generic pseudo.  */
7372   if (TARGET_64BIT)
7373     {
7374       rtx r4 = gen_rtx_REG (word_mode, 4);
7375       if (GET_CODE (op) == SYMBOL_REF)
7376         emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7377       else
7378         {
7379           op = force_reg (word_mode, op);
7380           emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7381         }
7382     }
7383   else
7384     {
7385       if (GET_CODE (op) == SYMBOL_REF)
7386         {
7387           if (flag_pic)
7388             {
7389               rtx r4 = gen_rtx_REG (word_mode, 4);
7390               emit_call_insn (gen_call_symref_pic (op, nb, r4));
7391             }
7392           else
7393             emit_call_insn (gen_call_symref (op, nb));
7394         }
7395       else
7396         {
7397           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7398           emit_move_insn (tmpreg, force_reg (word_mode, op));
7399           if (flag_pic)
7400             {
7401               rtx r4 = gen_rtx_REG (word_mode, 4);
7402               emit_call_insn (gen_call_reg_pic (nb, r4));
7403             }
7404           else
7405             emit_call_insn (gen_call_reg (nb));
7406         }
7407     }
7409   DONE;
7412 ;; We use function calls to set the attribute length of calls and millicode
7413 ;; calls.  This is necessary because of the large variety of call sequences.
7414 ;; Implementing the calculation in rtl is difficult as well as ugly.  As
7415 ;; we need the same calculation in several places, maintenance becomes a
7416 ;; nightmare.
7418 ;; However, this has a subtle impact on branch shortening.  When the
7419 ;; expression used to set the length attribute of an instruction depends
7420 ;; on a relative address (e.g., pc or a branch address), genattrtab
7421 ;; notes that the insn's length is variable, and attempts to determine a
7422 ;; worst-case default length and code to compute an insn's current length.
7424 ;; The use of a function call hides the variable dependence of our calls
7425 ;; and millicode calls.  The result is genattrtab doesn't treat the operation
7426 ;; as variable and it only generates code for the default case using our
7427 ;; function call.  Because of this, calls and millicode calls have a fixed
7428 ;; length in the branch shortening pass, and some branches will use a longer
7429 ;; code sequence than necessary.  However, the length of any given call
7430 ;; will still reflect its final code location and it may be shorter than
7431 ;; the initial length estimate.
7433 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7434 ;; in the set.  However, when genattrtab hits a function call in its attempt
7435 ;; to compute the default length, it marks the result as unknown and sets
7436 ;; the default result to MAX_INT ;-(  One possible fix that would allow
7437 ;; calls to participate in branch shortening would be to make the call to
7438 ;; insn_default_length a target option.  Then, we could massage unknown
7439 ;; results.  Another fix might be to change genattrtab so that it just does
7440 ;; the call in the variable case as it already does for the fixed case.
7442 (define_insn "call_symref"
7443   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7444          (match_operand 1 "" "i"))
7445    (clobber (reg:SI 1))
7446    (clobber (reg:SI 2))
7447    (use (const_int 0))]
7448   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7449   "*
7451   pa_output_arg_descriptor (insn);
7452   return pa_output_call (insn, operands[0], 0);
7454   [(set_attr "type" "call")
7455    (set (attr "length")
7456         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7457               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7459 (define_insn "call_symref_pic"
7460   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7461          (match_operand 1 "" "i"))
7462    (clobber (reg:SI 1))
7463    (clobber (reg:SI 2))
7464    (clobber (match_operand 2))
7465    (use (reg:SI 19))
7466    (use (const_int 0))]
7467   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7468   "#")
7470 ;; Split out the PIC register save and restore after reload.  As the
7471 ;; split is done after reload, there are some situations in which we
7472 ;; unnecessarily save and restore %r4.  This happens when there is a
7473 ;; single call and the PIC register is not used after the call.
7475 ;; The split has to be done since call_from_call_insn () can't handle
7476 ;; the pattern as is.  Noreturn calls are special because they have to
7477 ;; terminate the basic block.  The split has to contain more than one
7478 ;; insn.
7479 (define_split
7480   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7481                     (match_operand 1 "" ""))
7482               (clobber (reg:SI 1))
7483               (clobber (reg:SI 2))
7484               (clobber (match_operand 2))
7485               (use (reg:SI 19))
7486               (use (const_int 0))])]
7487   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7488    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7489   [(set (match_dup 2) (reg:SI 19))
7490    (parallel [(call (mem:SI (match_dup 0))
7491                     (match_dup 1))
7492               (clobber (reg:SI 1))
7493               (clobber (reg:SI 2))
7494               (use (reg:SI 19))
7495               (use (const_int 0))])]
7496   "")
7498 (define_split
7499   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7500                     (match_operand 1 "" ""))
7501               (clobber (reg:SI 1))
7502               (clobber (reg:SI 2))
7503               (clobber (match_operand 2))
7504               (use (reg:SI 19))
7505               (use (const_int 0))])]
7506   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7507   [(set (match_dup 2) (reg:SI 19))
7508    (parallel [(call (mem:SI (match_dup 0))
7509                     (match_dup 1))
7510               (clobber (reg:SI 1))
7511               (clobber (reg:SI 2))
7512               (use (reg:SI 19))
7513               (use (const_int 0))])
7514    (set (reg:SI 19) (match_dup 2))]
7515   "")
7517 (define_insn "*call_symref_pic_post_reload"
7518   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7519          (match_operand 1 "" "i"))
7520    (clobber (reg:SI 1))
7521    (clobber (reg:SI 2))
7522    (use (reg:SI 19))
7523    (use (const_int 0))]
7524   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7525   "*
7527   pa_output_arg_descriptor (insn);
7528   return pa_output_call (insn, operands[0], 0);
7530   [(set_attr "type" "call")
7531    (set (attr "length")
7532         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7533               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7535 ;; This pattern is split if it is necessary to save and restore the
7536 ;; PIC register.
7537 (define_insn "call_symref_64bit"
7538   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7539          (match_operand 1 "" "i"))
7540    (clobber (reg:DI 1))
7541    (clobber (reg:DI 2))
7542    (clobber (match_operand 2))
7543    (use (reg:DI 27))
7544    (use (reg:DI 29))
7545    (use (const_int 0))]
7546   "TARGET_64BIT"
7547   "#")
7549 ;; Split out the PIC register save and restore after reload.  As the
7550 ;; split is done after reload, there are some situations in which we
7551 ;; unnecessarily save and restore %r4.  This happens when there is a
7552 ;; single call and the PIC register is not used after the call.
7554 ;; The split has to be done since call_from_call_insn () can't handle
7555 ;; the pattern as is.  Noreturn calls are special because they have to
7556 ;; terminate the basic block.  The split has to contain more than one
7557 ;; insn.
7558 (define_split
7559   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7560                     (match_operand 1 "" ""))
7561               (clobber (reg:DI 1))
7562               (clobber (reg:DI 2))
7563               (clobber (match_operand 2))
7564               (use (reg:DI 27))
7565               (use (reg:DI 29))
7566               (use (const_int 0))])]
7567   "TARGET_64BIT && reload_completed
7568    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7569   [(set (match_dup 2) (reg:DI 27))
7570    (parallel [(call (mem:SI (match_dup 0))
7571                     (match_dup 1))
7572               (clobber (reg:DI 1))
7573               (clobber (reg:DI 2))
7574               (use (reg:DI 27))
7575               (use (reg:DI 29))
7576               (use (const_int 0))])]
7577   "")
7579 (define_split
7580   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7581                     (match_operand 1 "" ""))
7582               (clobber (reg:DI 1))
7583               (clobber (reg:DI 2))
7584               (clobber (match_operand 2))
7585               (use (reg:DI 27))
7586               (use (reg:DI 29))
7587               (use (const_int 0))])]
7588   "TARGET_64BIT && reload_completed"
7589   [(set (match_dup 2) (reg:DI 27))
7590    (parallel [(call (mem:SI (match_dup 0))
7591                     (match_dup 1))
7592               (clobber (reg:DI 1))
7593               (clobber (reg:DI 2))
7594               (use (reg:DI 27))
7595               (use (reg:DI 29))
7596               (use (const_int 0))])
7597    (set (reg:DI 27) (match_dup 2))]
7598   "")
7600 (define_insn "*call_symref_64bit_post_reload"
7601   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7602          (match_operand 1 "" "i"))
7603    (clobber (reg:DI 1))
7604    (clobber (reg:DI 2))
7605    (use (reg:DI 27))
7606    (use (reg:DI 29))
7607    (use (const_int 0))]
7608   "TARGET_64BIT"
7609   "*
7611   return pa_output_call (insn, operands[0], 0);
7613   [(set_attr "type" "call")
7614    (set (attr "length")
7615         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7616               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7618 (define_insn "call_reg"
7619   [(call (mem:SI (reg:SI 22))
7620          (match_operand 0 "" "i"))
7621    (clobber (reg:SI 1))
7622    (clobber (reg:SI 2))
7623    (use (const_int 1))]
7624   "!TARGET_64BIT"
7625   "*
7627   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7629   [(set_attr "type" "dyncall")
7630    (set (attr "length")
7631         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7632               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7634 ;; This pattern is split if it is necessary to save and restore the
7635 ;; PIC register.
7636 (define_insn "call_reg_pic"
7637   [(call (mem:SI (reg:SI 22))
7638          (match_operand 0 "" "i"))
7639    (clobber (reg:SI 1))
7640    (clobber (reg:SI 2))
7641    (clobber (match_operand 1))
7642    (use (reg:SI 19))
7643    (use (const_int 1))]
7644   "!TARGET_64BIT"
7645   "#")
7647 ;; Split out the PIC register save and restore after reload.  As the
7648 ;; split is done after reload, there are some situations in which we
7649 ;; unnecessarily save and restore %r4.  This happens when there is a
7650 ;; single call and the PIC register is not used after the call.
7652 ;; The split has to be done since call_from_call_insn () can't handle
7653 ;; the pattern as is.  Noreturn calls are special because they have to
7654 ;; terminate the basic block.  The split has to contain more than one
7655 ;; insn.
7656 (define_split
7657   [(parallel [(call (mem:SI (reg:SI 22))
7658                     (match_operand 0 "" ""))
7659               (clobber (reg:SI 1))
7660               (clobber (reg:SI 2))
7661               (clobber (match_operand 1))
7662               (use (reg:SI 19))
7663               (use (const_int 1))])]
7664   "!TARGET_64BIT && reload_completed
7665    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7666   [(set (match_dup 1) (reg:SI 19))
7667    (parallel [(call (mem:SI (reg:SI 22))
7668                     (match_dup 0))
7669               (clobber (reg:SI 1))
7670               (clobber (reg:SI 2))
7671               (use (reg:SI 19))
7672               (use (const_int 1))])]
7673   "")
7675 (define_split
7676   [(parallel [(call (mem:SI (reg:SI 22))
7677                     (match_operand 0 "" ""))
7678               (clobber (reg:SI 1))
7679               (clobber (reg:SI 2))
7680               (clobber (match_operand 1))
7681               (use (reg:SI 19))
7682               (use (const_int 1))])]
7683   "!TARGET_64BIT && reload_completed"
7684   [(set (match_dup 1) (reg:SI 19))
7685    (parallel [(call (mem:SI (reg:SI 22))
7686                     (match_dup 0))
7687               (clobber (reg:SI 1))
7688               (clobber (reg:SI 2))
7689               (use (reg:SI 19))
7690               (use (const_int 1))])
7691    (set (reg:SI 19) (match_dup 1))]
7692   "")
7694 (define_insn "*call_reg_pic_post_reload"
7695   [(call (mem:SI (reg:SI 22))
7696          (match_operand 0 "" "i"))
7697    (clobber (reg:SI 1))
7698    (clobber (reg:SI 2))
7699    (use (reg:SI 19))
7700    (use (const_int 1))]
7701   "!TARGET_64BIT"
7702   "*
7704   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7706   [(set_attr "type" "dyncall")
7707    (set (attr "length")
7708         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7709               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7711 ;; This pattern is split if it is necessary to save and restore the
7712 ;; PIC register.
7713 (define_insn "call_reg_64bit"
7714   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7715          (match_operand 1 "" "i"))
7716    (clobber (reg:DI 2))
7717    (clobber (match_operand 2))
7718    (use (reg:DI 27))
7719    (use (reg:DI 29))
7720    (use (const_int 1))]
7721   "TARGET_64BIT"
7722   "#")
7724 ;; Split out the PIC register save and restore after reload.  As the
7725 ;; split is done after reload, there are some situations in which we
7726 ;; unnecessarily save and restore %r4.  This happens when there is a
7727 ;; single call and the PIC register is not used after the call.
7729 ;; The split has to be done since call_from_call_insn () can't handle
7730 ;; the pattern as is.  Noreturn calls are special because they have to
7731 ;; terminate the basic block.  The split has to contain more than one
7732 ;; insn.
7733 (define_split
7734   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7735                     (match_operand 1 "" ""))
7736               (clobber (reg:DI 2))
7737               (clobber (match_operand 2))
7738               (use (reg:DI 27))
7739               (use (reg:DI 29))
7740               (use (const_int 1))])]
7741   "TARGET_64BIT && reload_completed
7742    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7743   [(set (match_dup 2) (reg:DI 27))
7744    (parallel [(call (mem:SI (match_dup 0))
7745                     (match_dup 1))
7746               (clobber (reg:DI 2))
7747               (use (reg:DI 27))
7748               (use (reg:DI 29))
7749               (use (const_int 1))])]
7750   "")
7752 (define_split
7753   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7754                     (match_operand 1 "" ""))
7755               (clobber (reg:DI 2))
7756               (clobber (match_operand 2))
7757               (use (reg:DI 27))
7758               (use (reg:DI 29))
7759               (use (const_int 1))])]
7760   "TARGET_64BIT && reload_completed"
7761   [(set (match_dup 2) (reg:DI 27))
7762    (parallel [(call (mem:SI (match_dup 0))
7763                     (match_dup 1))
7764               (clobber (reg:DI 2))
7765               (use (reg:DI 27))
7766               (use (reg:DI 29))
7767               (use (const_int 1))])
7768    (set (reg:DI 27) (match_dup 2))]
7769   "")
7771 (define_insn "*call_reg_64bit_post_reload"
7772   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7773          (match_operand 1 "" "i"))
7774    (clobber (reg:DI 2))
7775    (use (reg:DI 27))
7776    (use (reg:DI 29))
7777    (use (const_int 1))]
7778   "TARGET_64BIT"
7779   "*
7781   return pa_output_indirect_call (insn, operands[0]);
7783   [(set_attr "type" "dyncall")
7784    (set (attr "length")
7785         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7786               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7788 (define_expand "call_value"
7789   [(parallel [(set (match_operand 0 "" "")
7790                    (call (match_operand:SI 1 "" "")
7791                          (match_operand 2 "" "")))
7792               (clobber (reg:SI 2))])]
7793   ""
7795   rtx op;
7796   rtx dst = operands[0];
7797   rtx nb = operands[2];
7798   bool call_powf = false;
7800   if (TARGET_PORTABLE_RUNTIME)
7801     op = force_reg (SImode, XEXP (operands[1], 0));
7802   else
7803     {
7804       op = XEXP (operands[1], 0);
7805       if (GET_CODE (op) == SYMBOL_REF)
7806         {
7807           /* Handle special call to buggy powf function.  */
7808           if (TARGET_HPUX && !TARGET_SOFT_FLOAT
7809               && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7810             call_powf = true;
7812           /* Generate indirect long calls to non-local functions. */
7813           else if (TARGET_LONG_CALLS)
7814             {
7815               tree call_decl = SYMBOL_REF_DECL (op);
7816               if (!(call_decl && targetm.binds_local_p (call_decl)))
7817                 op = force_reg (word_mode, op);
7818             }
7819         }
7820     }
7822   if (TARGET_64BIT)
7823     {
7824       if (!virtuals_instantiated)
7825         emit_move_insn (arg_pointer_rtx,
7826                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7827                                       GEN_INT (64)));
7828       else
7829         {
7830           /* The loop pass can generate new libcalls after the virtual
7831              registers are instantiated when fpregs are disabled because
7832              the only method that we have for doing DImode multiplication
7833              is with a libcall.  This could be trouble if we haven't
7834              allocated enough space for the outgoing arguments.  */
7835           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7837           emit_move_insn (arg_pointer_rtx,
7838                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7839                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7840         }
7841     }
7843   /* Use two different patterns for calls to explicitly named functions
7844      and calls through function pointers.  This is necessary as these two
7845      types of calls use different calling conventions, and CSE might try
7846      to change the named call into an indirect call in some cases (using
7847      two patterns keeps CSE from performing this optimization).
7849      We now use even more call patterns as there was a subtle bug in
7850      attempting to restore the pic register after a call using a simple
7851      move insn.  During reload, a instruction involving a pseudo register
7852      with no explicit dependence on the PIC register can be converted
7853      to an equivalent load from memory using the PIC register.  If we
7854      emit a simple move to restore the PIC register in the initial rtl
7855      generation, then it can potentially be repositioned during scheduling.
7856      and an instruction that eventually uses the PIC register may end up
7857      between the call and the PIC register restore.
7858      
7859      This only worked because there is a post call group of instructions
7860      that are scheduled with the call.  These instructions are included
7861      in the same basic block as the call.  However, calls can throw in
7862      C++ code and a basic block has to terminate at the call if the call
7863      can throw.  This results in the PIC register restore being scheduled
7864      independently from the call.  So, we now hide the save and restore
7865      of the PIC register in the call pattern until after reload.  Then,
7866      we split the moves out.  A small side benefit is that we now don't
7867      need to have a use of the PIC register in the return pattern and
7868      the final save/restore operation is not needed.
7869      
7870      I elected to just use register %r4 in the PIC patterns instead
7871      of trying to force hppa_pic_save_rtx () to a callee saved register.
7872      This might have required a new register class and constraint.  It
7873      was also simpler to just handle the restore from a register than a
7874      generic pseudo.  */
7875   if (TARGET_64BIT)
7876     {
7877       rtx r4 = gen_rtx_REG (word_mode, 4);
7878       if (GET_CODE (op) == SYMBOL_REF)
7879         {
7880           if (call_powf)
7881             emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
7882           else
7883             emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
7884         }
7885       else
7886         {
7887           op = force_reg (word_mode, op);
7888           emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
7889         }
7890     }
7891   else
7892     {
7893       if (GET_CODE (op) == SYMBOL_REF)
7894         {
7895           if (flag_pic)
7896             {
7897               rtx r4 = gen_rtx_REG (word_mode, 4);
7899               if (call_powf)
7900                 emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
7901               else
7902                 emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
7903             }
7904           else
7905             {
7906               if (call_powf)
7907                 emit_call_insn (gen_call_val_powf (dst, op, nb));
7908               else
7909                 emit_call_insn (gen_call_val_symref (dst, op, nb));
7910             }
7911         }
7912       else
7913         {
7914           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7915           emit_move_insn (tmpreg, force_reg (word_mode, op));
7916           if (flag_pic)
7917             {
7918               rtx r4 = gen_rtx_REG (word_mode, 4);
7919               emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
7920             }
7921           else
7922             emit_call_insn (gen_call_val_reg (dst, nb));
7923         }
7924     }
7926   DONE;
7929 (define_insn "call_val_symref"
7930   [(set (match_operand 0 "" "")
7931         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7932               (match_operand 2 "" "i")))
7933    (clobber (reg:SI 1))
7934    (clobber (reg:SI 2))
7935    (use (const_int 0))]
7936   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7937   "*
7939   pa_output_arg_descriptor (insn);
7940   return pa_output_call (insn, operands[1], 0);
7942   [(set_attr "type" "call")
7943    (set (attr "length")
7944         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7945               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7947 ;; powf function clobbers %fr12
7948 (define_insn "call_val_powf"
7949   [(set (match_operand 0 "" "")
7950         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7951               (match_operand 2 "" "i")))
7952    (clobber (reg:SI 1))
7953    (clobber (reg:SI 2))
7954    (clobber (reg:DF 48))
7955    (use (const_int 1))]
7956   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7957   "*
7959   pa_output_arg_descriptor (insn);
7960   return pa_output_call (insn, operands[1], 0);
7962   [(set_attr "type" "call")
7963    (set (attr "length")
7964         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7965               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7967 (define_insn "call_val_symref_pic"
7968   [(set (match_operand 0 "" "")
7969         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7970               (match_operand 2 "" "i")))
7971    (clobber (reg:SI 1))
7972    (clobber (reg:SI 2))
7973    (clobber (match_operand 3))
7974    (use (reg:SI 19))
7975    (use (const_int 0))]
7976   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7977   "#")
7979 ;; Split out the PIC register save and restore after reload.  As the
7980 ;; split is done after reload, there are some situations in which we
7981 ;; unnecessarily save and restore %r4.  This happens when there is a
7982 ;; single call and the PIC register is not used after the call.
7984 ;; The split has to be done since call_from_call_insn () can't handle
7985 ;; the pattern as is.  Noreturn calls are special because they have to
7986 ;; terminate the basic block.  The split has to contain more than one
7987 ;; insn.
7988 (define_split
7989   [(parallel [(set (match_operand 0 "" "")
7990               (call (mem:SI (match_operand 1 "call_operand_address" ""))
7991                     (match_operand 2 "" "")))
7992               (clobber (reg:SI 1))
7993               (clobber (reg:SI 2))
7994               (clobber (match_operand 3))
7995               (use (reg:SI 19))
7996               (use (const_int 0))])]
7997   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7998    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7999   [(set (match_dup 3) (reg:SI 19))
8000    (parallel [(set (match_dup 0)
8001               (call (mem:SI (match_dup 1))
8002                     (match_dup 2)))
8003               (clobber (reg:SI 1))
8004               (clobber (reg:SI 2))
8005               (use (reg:SI 19))
8006               (use (const_int 0))])]
8007   "")
8009 (define_split
8010   [(parallel [(set (match_operand 0 "" "")
8011               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8012                     (match_operand 2 "" "")))
8013               (clobber (reg:SI 1))
8014               (clobber (reg:SI 2))
8015               (clobber (match_operand 3))
8016               (use (reg:SI 19))
8017               (use (const_int 0))])]
8018   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8019   [(set (match_dup 3) (reg:SI 19))
8020    (parallel [(set (match_dup 0)
8021               (call (mem:SI (match_dup 1))
8022                     (match_dup 2)))
8023               (clobber (reg:SI 1))
8024               (clobber (reg:SI 2))
8025               (use (reg:SI 19))
8026               (use (const_int 0))])
8027    (set (reg:SI 19) (match_dup 3))]
8028   "")
8030 (define_insn "*call_val_symref_pic_post_reload"
8031   [(set (match_operand 0 "" "")
8032         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8033               (match_operand 2 "" "i")))
8034    (clobber (reg:SI 1))
8035    (clobber (reg:SI 2))
8036    (use (reg:SI 19))
8037    (use (const_int 0))]
8038   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8039   "*
8041   pa_output_arg_descriptor (insn);
8042   return pa_output_call (insn, operands[1], 0);
8044   [(set_attr "type" "call")
8045    (set (attr "length")
8046         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8047               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8049 ;; powf function clobbers %fr12
8050 (define_insn "call_val_powf_pic"
8051   [(set (match_operand 0 "" "")
8052         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8053               (match_operand 2 "" "i")))
8054    (clobber (reg:SI 1))
8055    (clobber (reg:SI 2))
8056    (clobber (reg:DF 48))
8057    (clobber (match_operand 3))
8058    (use (reg:SI 19))
8059    (use (const_int 1))]
8060   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8061   "#")
8063 ;; Split out the PIC register save and restore after reload.  As the
8064 ;; split is done after reload, there are some situations in which we
8065 ;; unnecessarily save and restore %r4.  This happens when there is a
8066 ;; single call and the PIC register is not used after the call.
8068 ;; The split has to be done since call_from_call_insn () can't handle
8069 ;; the pattern as is.  Noreturn calls are special because they have to
8070 ;; terminate the basic block.  The split has to contain more than one
8071 ;; insn.
8072 (define_split
8073   [(parallel [(set (match_operand 0 "" "")
8074               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8075                     (match_operand 2 "" "")))
8076               (clobber (reg:SI 1))
8077               (clobber (reg:SI 2))
8078               (clobber (reg:DF 48))
8079               (clobber (match_operand 3))
8080               (use (reg:SI 19))
8081               (use (const_int 1))])]
8082   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8083    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8084   [(set (match_dup 3) (reg:SI 19))
8085    (parallel [(set (match_dup 0)
8086               (call (mem:SI (match_dup 1))
8087                     (match_dup 2)))
8088               (clobber (reg:SI 1))
8089               (clobber (reg:SI 2))
8090               (clobber (reg:DF 48))
8091               (use (reg:SI 19))
8092               (use (const_int 1))])]
8093   "")
8095 (define_split
8096   [(parallel [(set (match_operand 0 "" "")
8097               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8098                     (match_operand 2 "" "")))
8099               (clobber (reg:SI 1))
8100               (clobber (reg:SI 2))
8101               (clobber (reg:DF 48))
8102               (clobber (match_operand 3))
8103               (use (reg:SI 19))
8104               (use (const_int 1))])]
8105   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8106   [(set (match_dup 3) (reg:SI 19))
8107    (parallel [(set (match_dup 0)
8108               (call (mem:SI (match_dup 1))
8109                     (match_dup 2)))
8110               (clobber (reg:SI 1))
8111               (clobber (reg:SI 2))
8112               (clobber (reg:DF 48))
8113               (use (reg:SI 19))
8114               (use (const_int 1))])
8115    (set (reg:SI 19) (match_dup 3))]
8116   "")
8118 (define_insn "*call_val_powf_pic_post_reload"
8119   [(set (match_operand 0 "" "")
8120         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8121               (match_operand 2 "" "i")))
8122    (clobber (reg:SI 1))
8123    (clobber (reg:SI 2))
8124    (clobber (reg:DF 48))
8125    (use (reg:SI 19))
8126    (use (const_int 1))]
8127   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8128   "*
8130   pa_output_arg_descriptor (insn);
8131   return pa_output_call (insn, operands[1], 0);
8133   [(set_attr "type" "call")
8134    (set (attr "length")
8135         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8136               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8138 ;; This pattern is split if it is necessary to save and restore the
8139 ;; PIC register.
8140 (define_insn "call_val_symref_64bit"
8141   [(set (match_operand 0 "" "")
8142         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8143               (match_operand 2 "" "i")))
8144    (clobber (reg:DI 1))
8145    (clobber (reg:DI 2))
8146    (clobber (match_operand 3))
8147    (use (reg:DI 27))
8148    (use (reg:DI 29))
8149    (use (const_int 0))]
8150   "TARGET_64BIT"
8151   "#")
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:DI 1))
8167               (clobber (reg:DI 2))
8168               (clobber (match_operand 3))
8169               (use (reg:DI 27))
8170               (use (reg:DI 29))
8171               (use (const_int 0))])]
8172   "TARGET_64BIT && reload_completed
8173    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8174   [(set (match_dup 3) (reg:DI 27))
8175    (parallel [(set (match_dup 0)
8176               (call (mem:SI (match_dup 1))
8177                     (match_dup 2)))
8178               (clobber (reg:DI 1))
8179               (clobber (reg:DI 2))
8180               (use (reg:DI 27))
8181               (use (reg:DI 29))
8182               (use (const_int 0))])]
8183   "")
8185 (define_split
8186   [(parallel [(set (match_operand 0 "" "")
8187               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8188                     (match_operand 2 "" "")))
8189               (clobber (reg:DI 1))
8190               (clobber (reg:DI 2))
8191               (clobber (match_operand 3))
8192               (use (reg:DI 27))
8193               (use (reg:DI 29))
8194               (use (const_int 0))])]
8195   "TARGET_64BIT && reload_completed"
8196   [(set (match_dup 3) (reg:DI 27))
8197    (parallel [(set (match_dup 0)
8198               (call (mem:SI (match_dup 1))
8199                     (match_dup 2)))
8200               (clobber (reg:DI 1))
8201               (clobber (reg:DI 2))
8202               (use (reg:DI 27))
8203               (use (reg:DI 29))
8204               (use (const_int 0))])
8205    (set (reg:DI 27) (match_dup 3))]
8206   "")
8208 (define_insn "*call_val_symref_64bit_post_reload"
8209   [(set (match_operand 0 "" "")
8210         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8211               (match_operand 2 "" "i")))
8212    (clobber (reg:DI 1))
8213    (clobber (reg:DI 2))
8214    (use (reg:DI 27))
8215    (use (reg:DI 29))
8216    (use (const_int 0))]
8217   "TARGET_64BIT"
8218   "*
8220   return pa_output_call (insn, operands[1], 0);
8222   [(set_attr "type" "call")
8223    (set (attr "length")
8224         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8225               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8227 ;; powf function clobbers %fr12
8228 (define_insn "call_val_powf_64bit"
8229   [(set (match_operand 0 "" "")
8230         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8231               (match_operand 2 "" "i")))
8232    (clobber (reg:DI 1))
8233    (clobber (reg:DI 2))
8234    (clobber (reg:DF 40))
8235    (clobber (match_operand 3))
8236    (use (reg:DI 27))
8237    (use (reg:DI 29))
8238    (use (const_int 1))]
8239   "TARGET_64BIT && TARGET_HPUX"
8240   "#")
8242 ;; Split out the PIC register save and restore after reload.  As the
8243 ;; split is done after reload, there are some situations in which we
8244 ;; unnecessarily save and restore %r4.  This happens when there is a
8245 ;; single call and the PIC register is not used after the call.
8247 ;; The split has to be done since call_from_call_insn () can't handle
8248 ;; the pattern as is.  Noreturn calls are special because they have to
8249 ;; terminate the basic block.  The split has to contain more than one
8250 ;; insn.
8251 (define_split
8252   [(parallel [(set (match_operand 0 "" "")
8253               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8254                     (match_operand 2 "" "")))
8255               (clobber (reg:DI 1))
8256               (clobber (reg:DI 2))
8257               (clobber (reg:DF 40))
8258               (clobber (match_operand 3))
8259               (use (reg:DI 27))
8260               (use (reg:DI 29))
8261               (use (const_int 1))])]
8262   "TARGET_64BIT && TARGET_HPUX && reload_completed
8263    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8264   [(set (match_dup 3) (reg:DI 27))
8265    (parallel [(set (match_dup 0)
8266               (call (mem:SI (match_dup 1))
8267                     (match_dup 2)))
8268               (clobber (reg:DI 1))
8269               (clobber (reg:DI 2))
8270               (clobber (reg:DF 40))
8271               (use (reg:DI 27))
8272               (use (reg:DI 29))
8273               (use (const_int 1))])]
8274   "")
8276 (define_split
8277   [(parallel [(set (match_operand 0 "" "")
8278               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8279                     (match_operand 2 "" "")))
8280               (clobber (reg:DI 1))
8281               (clobber (reg:DI 2))
8282               (clobber (reg:DF 40))
8283               (clobber (match_operand 3))
8284               (use (reg:DI 27))
8285               (use (reg:DI 29))
8286               (use (const_int 1))])]
8287   "TARGET_64BIT && TARGET_HPUX && reload_completed"
8288   [(set (match_dup 3) (reg:DI 27))
8289    (parallel [(set (match_dup 0)
8290               (call (mem:SI (match_dup 1))
8291                     (match_dup 2)))
8292               (clobber (reg:DI 1))
8293               (clobber (reg:DI 2))
8294               (clobber (reg:DF 40))
8295               (use (reg:DI 27))
8296               (use (reg:DI 29))
8297               (use (const_int 1))])
8298    (set (reg:DI 27) (match_dup 3))]
8299   "")
8301 (define_insn "*call_val_powf_64bit_post_reload"
8302   [(set (match_operand 0 "" "")
8303         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8304               (match_operand 2 "" "i")))
8305    (clobber (reg:DI 1))
8306    (clobber (reg:DI 2))
8307    (clobber (reg:DF 40))
8308    (use (reg:DI 27))
8309    (use (reg:DI 29))
8310    (use (const_int 1))]
8311   "TARGET_64BIT && TARGET_HPUX"
8312   "*
8314   return pa_output_call (insn, operands[1], 0);
8316   [(set_attr "type" "call")
8317    (set (attr "length")
8318         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8319               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8321 (define_insn "call_val_reg"
8322   [(set (match_operand 0 "" "")
8323         (call (mem:SI (reg:SI 22))
8324               (match_operand 1 "" "i")))
8325    (clobber (reg:SI 1))
8326    (clobber (reg:SI 2))
8327    (use (const_int 1))]
8328   "!TARGET_64BIT"
8329   "*
8331   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8333   [(set_attr "type" "dyncall")
8334    (set (attr "length")
8335         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8336               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8338 ;; This pattern is split if it is necessary to save and restore the
8339 ;; PIC register.
8340 (define_insn "call_val_reg_pic"
8341   [(set (match_operand 0 "" "")
8342         (call (mem:SI (reg:SI 22))
8343               (match_operand 1 "" "i")))
8344    (clobber (reg:SI 1))
8345    (clobber (reg:SI 2))
8346    (clobber (match_operand 2))
8347    (use (reg:SI 19))
8348    (use (const_int 1))]
8349   "!TARGET_64BIT"
8350   "#")
8352 ;; Split out the PIC register save and restore after reload.  As the
8353 ;; split is done after reload, there are some situations in which we
8354 ;; unnecessarily save and restore %r4.  This happens when there is a
8355 ;; single call and the PIC register is not used after the call.
8357 ;; The split has to be done since call_from_call_insn () can't handle
8358 ;; the pattern as is.  Noreturn calls are special because they have to
8359 ;; terminate the basic block.  The split has to contain more than one
8360 ;; insn.
8361 (define_split
8362   [(parallel [(set (match_operand 0 "" "")
8363                    (call (mem:SI (reg:SI 22))
8364                          (match_operand 1 "" "")))
8365               (clobber (reg:SI 1))
8366               (clobber (reg:SI 2))
8367               (clobber (match_operand 2))
8368               (use (reg:SI 19))
8369               (use (const_int 1))])]
8370   "!TARGET_64BIT && reload_completed
8371    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8372   [(set (match_dup 2) (reg:SI 19))
8373    (parallel [(set (match_dup 0)
8374                    (call (mem:SI (reg:SI 22))
8375                          (match_dup 1)))
8376               (clobber (reg:SI 1))
8377               (clobber (reg:SI 2))
8378               (use (reg:SI 19))
8379               (use (const_int 1))])]
8380   "")
8382 (define_split
8383   [(parallel [(set (match_operand 0 "" "")
8384                    (call (mem:SI (reg:SI 22))
8385                          (match_operand 1 "" "")))
8386               (clobber (reg:SI 1))
8387               (clobber (reg:SI 2))
8388               (clobber (match_operand 2))
8389               (use (reg:SI 19))
8390               (use (const_int 1))])]
8391   "!TARGET_64BIT && reload_completed"
8392   [(set (match_dup 2) (reg:SI 19))
8393    (parallel [(set (match_dup 0)
8394                    (call (mem:SI (reg:SI 22))
8395                          (match_dup 1)))
8396               (clobber (reg:SI 1))
8397               (clobber (reg:SI 2))
8398               (use (reg:SI 19))
8399               (use (const_int 1))])
8400    (set (reg:SI 19) (match_dup 2))]
8401   "")
8403 (define_insn "*call_val_reg_pic_post_reload"
8404   [(set (match_operand 0 "" "")
8405         (call (mem:SI (reg:SI 22))
8406               (match_operand 1 "" "i")))
8407    (clobber (reg:SI 1))
8408    (clobber (reg:SI 2))
8409    (use (reg:SI 19))
8410    (use (const_int 1))]
8411   "!TARGET_64BIT"
8412   "*
8414   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8416   [(set_attr "type" "dyncall")
8417    (set (attr "length")
8418         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8419               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8421 ;; This pattern is split if it is necessary to save and restore the
8422 ;; PIC register.
8423 (define_insn "call_val_reg_64bit"
8424   [(set (match_operand 0 "" "")
8425         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8426               (match_operand 2 "" "i")))
8427    (clobber (reg:DI 2))
8428    (clobber (match_operand 3))
8429    (use (reg:DI 27))
8430    (use (reg:DI 29))
8431    (use (const_int 1))]
8432   "TARGET_64BIT"
8433   "#")
8435 ;; Split out the PIC register save and restore after reload.  As the
8436 ;; split is done after reload, there are some situations in which we
8437 ;; unnecessarily save and restore %r4.  This happens when there is a
8438 ;; single call and the PIC register is not used after the call.
8440 ;; The split has to be done since call_from_call_insn () can't handle
8441 ;; the pattern as is.  Noreturn calls are special because they have to
8442 ;; terminate the basic block.  The split has to contain more than one
8443 ;; insn.
8444 (define_split
8445   [(parallel [(set (match_operand 0 "" "")
8446                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8447                          (match_operand 2 "" "")))
8448               (clobber (reg:DI 2))
8449               (clobber (match_operand 3))
8450               (use (reg:DI 27))
8451               (use (reg:DI 29))
8452               (use (const_int 1))])]
8453   "TARGET_64BIT && reload_completed
8454    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8455   [(set (match_dup 3) (reg:DI 27))
8456    (parallel [(set (match_dup 0)
8457                    (call (mem:SI (match_dup 1))
8458                          (match_dup 2)))
8459               (clobber (reg:DI 2))
8460               (use (reg:DI 27))
8461               (use (reg:DI 29))
8462               (use (const_int 1))])]
8463   "")
8465 (define_split
8466   [(parallel [(set (match_operand 0 "" "")
8467                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8468                          (match_operand 2 "" "")))
8469               (clobber (reg:DI 2))
8470               (clobber (match_operand 3))
8471               (use (reg:DI 27))
8472               (use (reg:DI 29))
8473               (use (const_int 1))])]
8474   "TARGET_64BIT && reload_completed"
8475   [(set (match_dup 3) (reg:DI 27))
8476    (parallel [(set (match_dup 0)
8477                    (call (mem:SI (match_dup 1))
8478                          (match_dup 2)))
8479               (clobber (reg:DI 2))
8480               (use (reg:DI 27))
8481               (use (reg:DI 29))
8482               (use (const_int 1))])
8483    (set (reg:DI 27) (match_dup 3))]
8484   "")
8486 (define_insn "*call_val_reg_64bit_post_reload"
8487   [(set (match_operand 0 "" "")
8488         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8489               (match_operand 2 "" "i")))
8490    (clobber (reg:DI 2))
8491    (use (reg:DI 27))
8492    (use (reg:DI 29))
8493    (use (const_int 1))]
8494   "TARGET_64BIT"
8495   "*
8497   return pa_output_indirect_call (insn, operands[1]);
8499   [(set_attr "type" "dyncall")
8500    (set (attr "length")
8501         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8502               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8504 /* Expand special pc-relative call to _mcount.  */
8506 (define_expand "call_mcount"
8507   [(parallel [(call (match_operand:SI 0 "" "")
8508                     (match_operand 1 "" ""))
8509               (set (reg:SI 25)
8510                    (plus:SI (reg:SI 2)
8511                             (minus:SI (match_operand 2 "" "")
8512                                       (plus:SI (pc) (const_int 4)))))
8513               (clobber (reg:SI 2))])]
8514   "!TARGET_PORTABLE_RUNTIME"
8515   "
8517   rtx op = XEXP (operands[0], 0);
8518   rtx nb = operands[1];
8519   rtx lab = operands[2];
8521   if (TARGET_64BIT)
8522     {
8523       rtx r4 = gen_rtx_REG (word_mode, 4);
8524       emit_move_insn (arg_pointer_rtx,
8525                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8526                                     GEN_INT (64)));
8527       emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8528     }
8529   else
8530     {
8531       if (flag_pic)
8532         {
8533           rtx r4 = gen_rtx_REG (word_mode, 4);
8534           emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8535         }
8536       else
8537         emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8538     }
8540   DONE;
8543 (define_insn "call_mcount_nonpic"
8544   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8545          (match_operand 1 "" "i"))
8546    (set (reg:SI 25)
8547         (plus:SI (reg:SI 2)
8548                  (minus:SI (match_operand 2 "" "")
8549                            (plus:SI (pc) (const_int 4)))))
8550    (clobber (reg:SI 2))]
8551   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8552   "*
8554   pa_output_arg_descriptor (insn);
8555   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8557   [(set_attr "type" "multi")
8558    (set_attr "length" "8")])
8560 (define_insn "call_mcount_pic"
8561   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8562          (match_operand 1 "" "i"))
8563    (set (reg:SI 25)
8564         (plus:SI (reg:SI 2)
8565                  (minus:SI (match_operand 2 "" "")
8566                            (plus:SI (pc) (const_int 4)))))
8567    (clobber (reg:SI 2))
8568    (clobber (match_operand 3))
8569    (use (reg:SI 19))]
8570   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8571   "#")
8573 (define_split
8574   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8575                     (match_operand 1 "" ""))
8576               (set (reg:SI 25)
8577                    (plus:SI (reg:SI 2)
8578                             (minus:SI (match_operand 2 "" "")
8579                                       (plus:SI (pc) (const_int 4)))))
8580               (clobber (reg:SI 2))
8581               (clobber (match_operand 3))
8582               (use (reg:SI 19))])]
8583   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8584   [(set (match_dup 3) (reg:SI 19))
8585    (parallel [(call (mem:SI (match_dup 0))
8586                     (match_dup 1))
8587               (set (reg:SI 25)
8588                    (plus:SI (reg:SI 2)
8589                             (minus:SI (match_dup 2)
8590                                       (plus:SI (pc) (const_int 4)))))
8591               (clobber (reg:SI 2))
8592               (use (reg:SI 19))])
8593    (set (reg:SI 19) (match_dup 3))]
8594   "")
8596 (define_insn "*call_mcount_pic_post_reload"
8597   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8598          (match_operand 1 "" "i"))
8599    (set (reg:SI 25)
8600         (plus:SI (reg:SI 2)
8601                  (minus:SI (match_operand 2 "" "")
8602                            (plus:SI (pc) (const_int 4)))))
8603    (clobber (reg:SI 2))
8604    (use (reg:SI 19))]
8605   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8606   "*
8608   pa_output_arg_descriptor (insn);
8609   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8611   [(set_attr "type" "multi")
8612    (set_attr "length" "8")])
8614 (define_insn "call_mcount_64bit"
8615   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8616          (match_operand 1 "" "i"))
8617    (set (reg:SI 25)
8618         (plus:SI (reg:SI 2)
8619                  (minus:SI (match_operand 2 "" "")
8620                            (plus:SI (pc) (const_int 4)))))
8621    (clobber (reg:DI 2))
8622    (clobber (match_operand 3))
8623    (use (reg:DI 27))
8624    (use (reg:DI 29))]
8625   "TARGET_64BIT"
8626   "#")
8628 (define_split
8629   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8630                     (match_operand 1 "" ""))
8631               (set (reg:SI 25)
8632                    (plus:SI (reg:SI 2)
8633                             (minus:SI (match_operand 2 "" "")
8634                                       (plus:SI (pc) (const_int 4)))))
8635               (clobber (reg:DI 2))
8636               (clobber (match_operand 3))
8637               (use (reg:DI 27))
8638               (use (reg:DI 29))])]
8639   "TARGET_64BIT && reload_completed"
8640   [(set (match_dup 3) (reg:DI 27))
8641    (parallel [(call (mem:SI (match_dup 0))
8642                     (match_dup 1))
8643               (set (reg:SI 25)
8644                    (plus:SI (reg:SI 2)
8645                             (minus:SI (match_dup 2)
8646                                       (plus:SI (pc) (const_int 4)))))
8647               (clobber (reg:DI 2))
8648               (use (reg:DI 27))
8649               (use (reg:DI 29))])
8650    (set (reg:DI 27) (match_dup 3))]
8651   "")
8653 (define_insn "*call_mcount_64bit_post_reload"
8654   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8655          (match_operand 1 "" "i"))
8656    (set (reg:SI 25)
8657         (plus:SI (reg:SI 2)
8658                  (minus:SI (match_operand 2 "" "")
8659                            (plus:SI (pc) (const_int 4)))))
8660    (clobber (reg:DI 2))
8661    (use (reg:DI 27))
8662    (use (reg:DI 29))]
8663   "TARGET_64BIT"
8664   "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8665   [(set_attr "type" "multi")
8666    (set_attr "length" "8")])
8668 ;; Call subroutine returning any type.
8670 (define_expand "untyped_call"
8671   [(parallel [(call (match_operand 0 "" "")
8672                     (const_int 0))
8673               (match_operand 1 "" "")
8674               (match_operand 2 "" "")])]
8675   ""
8676   "
8678   int i;
8680   emit_call_insn (gen_call (operands[0], const0_rtx));
8682   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8683     {
8684       rtx set = XVECEXP (operands[2], 0, i);
8685       emit_move_insn (SET_DEST (set), SET_SRC (set));
8686     }
8688   /* The optimizer does not know that the call sets the function value
8689      registers we stored in the result block.  We avoid problems by
8690      claiming that all hard registers are used and clobbered at this
8691      point.  */
8692   emit_insn (gen_blockage ());
8694   DONE;
8697 (define_expand "sibcall"
8698   [(call (match_operand:SI 0 "" "")
8699          (match_operand 1 "" ""))]
8700   "!TARGET_PORTABLE_RUNTIME"
8701   "
8703   rtx op, call_insn;
8704   rtx nb = operands[1];
8706   op = XEXP (operands[0], 0);
8708   if (TARGET_64BIT)
8709     {
8710       if (!virtuals_instantiated)
8711         emit_move_insn (arg_pointer_rtx,
8712                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8713                                       GEN_INT (64)));
8714       else
8715         {
8716           /* The loop pass can generate new libcalls after the virtual
8717              registers are instantiated when fpregs are disabled because
8718              the only method that we have for doing DImode multiplication
8719              is with a libcall.  This could be trouble if we haven't
8720              allocated enough space for the outgoing arguments.  */
8721           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8723           emit_move_insn (arg_pointer_rtx,
8724                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8725                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8726         }
8727     }
8729   /* Indirect sibling calls are not allowed.  */
8730   if (TARGET_64BIT)
8731     call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8732   else
8733     call_insn = gen_sibcall_internal_symref (op, operands[1]);
8735   call_insn = emit_call_insn (call_insn);
8737   if (TARGET_64BIT)
8738     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8740   /* We don't have to restore the PIC register.  */
8741   if (flag_pic)
8742     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8744   DONE;
8747 (define_insn "sibcall_internal_symref"
8748   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8749          (match_operand 1 "" "i"))
8750    (clobber (reg:SI 1))
8751    (use (reg:SI 2))
8752    (use (const_int 0))]
8753   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8754   "*
8756   pa_output_arg_descriptor (insn);
8757   return pa_output_call (insn, operands[0], 1);
8759   [(set_attr "type" "sibcall")
8760    (set (attr "length")
8761         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8762               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8764 (define_insn "sibcall_internal_symref_64bit"
8765   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8766          (match_operand 1 "" "i"))
8767    (clobber (reg:DI 1))
8768    (use (reg:DI 2))
8769    (use (const_int 0))]
8770   "TARGET_64BIT"
8771   "*
8773   return pa_output_call (insn, operands[0], 1);
8775   [(set_attr "type" "sibcall")
8776    (set (attr "length")
8777         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8778               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8780 (define_expand "sibcall_value"
8781   [(set (match_operand 0 "" "")
8782                    (call (match_operand:SI 1 "" "")
8783                          (match_operand 2 "" "")))]
8784   "!TARGET_PORTABLE_RUNTIME"
8785   "
8787   rtx op, call_insn;
8788   rtx nb = operands[1];
8790   op = XEXP (operands[1], 0);
8792   if (TARGET_64BIT)
8793     {
8794       if (!virtuals_instantiated)
8795         emit_move_insn (arg_pointer_rtx,
8796                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8797                                       GEN_INT (64)));
8798       else
8799         {
8800           /* The loop pass can generate new libcalls after the virtual
8801              registers are instantiated when fpregs are disabled because
8802              the only method that we have for doing DImode multiplication
8803              is with a libcall.  This could be trouble if we haven't
8804              allocated enough space for the outgoing arguments.  */
8805           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8807           emit_move_insn (arg_pointer_rtx,
8808                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8809                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8810         }
8811     }
8813   /* Indirect sibling calls are not allowed.  */
8814   if (TARGET_64BIT)
8815     call_insn
8816       = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8817   else
8818     call_insn
8819       = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8821   call_insn = emit_call_insn (call_insn);
8823   if (TARGET_64BIT)
8824     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8826   /* We don't have to restore the PIC register.  */
8827   if (flag_pic)
8828     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8830   DONE;
8833 (define_insn "sibcall_value_internal_symref"
8834   [(set (match_operand 0 "" "")
8835         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8836               (match_operand 2 "" "i")))
8837    (clobber (reg:SI 1))
8838    (use (reg:SI 2))
8839    (use (const_int 0))]
8840   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8841   "*
8843   pa_output_arg_descriptor (insn);
8844   return pa_output_call (insn, operands[1], 1);
8846   [(set_attr "type" "sibcall")
8847    (set (attr "length")
8848         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8849               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8851 (define_insn "sibcall_value_internal_symref_64bit"
8852   [(set (match_operand 0 "" "")
8853         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8854               (match_operand 2 "" "i")))
8855    (clobber (reg:DI 1))
8856    (use (reg:DI 2))
8857    (use (const_int 0))]
8858   "TARGET_64BIT"
8859   "*
8861   return pa_output_call (insn, operands[1], 1);
8863   [(set_attr "type" "sibcall")
8864    (set (attr "length")
8865         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8866               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8868 (define_insn "nop"
8869   [(const_int 0)]
8870   ""
8871   "nop"
8872   [(set_attr "type" "move")
8873    (set_attr "length" "4")])
8875 ;;; EH does longjmp's from and within the data section.  Thus,
8876 ;;; an interspace branch is required for the longjmp implementation.
8877 ;;; Registers r1 and r2 are used as scratch registers for the jump
8878 ;;; when necessary.
8879 (define_expand "interspace_jump"
8880   [(parallel
8881      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8882       (clobber (match_dup 1))])]
8883   ""
8884   "
8886   operands[1] = gen_rtx_REG (word_mode, 2);
8889 (define_insn ""
8890   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8891   (clobber (reg:SI 2))]
8892   "TARGET_PA_20 && !TARGET_64BIT"
8893   "bve%* (%0)"
8894    [(set_attr "type" "branch")
8895     (set_attr "length" "4")])
8897 (define_insn ""
8898   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8899   (clobber (reg:SI 2))]
8900   "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8901   "be%* 0(%%sr4,%0)"
8902    [(set_attr "type" "branch")
8903     (set_attr "length" "4")])
8905 (define_insn ""
8906   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8907   (clobber (reg:SI 2))]
8908   "!TARGET_64BIT"
8909   "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8910    [(set_attr "type" "branch")
8911     (set_attr "length" "12")])
8913 (define_insn ""
8914   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8915   (clobber (reg:DI 2))]
8916   "TARGET_64BIT"
8917   "bve%* (%0)"
8918    [(set_attr "type" "branch")
8919     (set_attr "length" "4")])
8921 (define_expand "builtin_longjmp"
8922   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8923   ""
8924   "
8926   /* The elements of the buffer are, in order:  */
8927   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8928   rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8929                          POINTER_SIZE / BITS_PER_UNIT));
8930   rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
8931                            (POINTER_SIZE * 2) / BITS_PER_UNIT));
8932   rtx pv = gen_rtx_REG (Pmode, 1);
8934   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
8935   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
8937   /* Load the label we are jumping through into r1 so that we know
8938      where to look for it when we get back to setjmp's function for
8939      restoring the gp.  */
8940   emit_move_insn (pv, lab);
8942   /* Restore the stack and frame pointers.  */
8943   fp = copy_to_reg (fp);
8944   emit_stack_restore (SAVE_NONLOCAL, stack);
8946   /* Ensure the frame pointer move is not optimized.  */
8947   emit_insn (gen_blockage ());
8948   emit_clobber (hard_frame_pointer_rtx);
8949   emit_clobber (frame_pointer_rtx);
8950   emit_move_insn (hard_frame_pointer_rtx, fp);
8952   emit_use (hard_frame_pointer_rtx);
8953   emit_use (stack_pointer_rtx);
8955   /* Prevent the insns above from being scheduled into the delay slot
8956      of the interspace jump because the space register could change.  */
8957   emit_insn (gen_blockage ());
8959   emit_jump_insn (gen_interspace_jump (pv));
8960   emit_barrier ();
8961   DONE;
8964 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8965 (define_expand "extzvsi"
8966   [(set (match_operand:SI 0 "register_operand" "")
8967         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
8968                          (match_operand:SI 2 "uint5_operand" "")
8969                          (match_operand:SI 3 "uint5_operand" "")))]
8970   ""
8971   "
8973   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
8974   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
8976   /* PA extraction insns don't support zero length bitfields or fields
8977      extending beyond the left or right-most bits.  Also, the predicate
8978      rejects lengths equal to a word as they are better handled by
8979      the move patterns.  */
8980   if (len == 0 || pos + len > 32)
8981     FAIL;
8983   /* From mips.md: extract_bit_field doesn't verify that our source
8984      matches the predicate, so check it again here.  */
8985   if (!register_operand (operands[1], VOIDmode))
8986     FAIL;
8988   emit_insn (gen_extzv_32 (operands[0], operands[1],
8989                            operands[2], operands[3]));
8990   DONE;
8993 (define_insn "extzv_32"
8994   [(set (match_operand:SI 0 "register_operand" "=r")
8995         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8996                          (match_operand:SI 2 "uint5_operand" "")
8997                          (match_operand:SI 3 "uint5_operand" "")))]
8998   "UINTVAL (operands[2]) > 0
8999    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9000   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9001   [(set_attr "type" "shift")
9002    (set_attr "length" "4")])
9004 (define_insn ""
9005   [(set (match_operand:SI 0 "register_operand" "=r")
9006         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9007                          (const_int 1)
9008                          (match_operand:SI 2 "register_operand" "q")))]
9009   ""
9010   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9011   [(set_attr "type" "shift")
9012    (set_attr "length" "4")])
9014 (define_expand "extzvdi"
9015   [(set (match_operand:DI 0 "register_operand" "")
9016         (zero_extract:DI (match_operand:DI 1 "register_operand" "")
9017                          (match_operand:DI 2 "uint6_operand" "")
9018                          (match_operand:DI 3 "uint6_operand" "")))]
9019   "TARGET_64BIT"
9020   "
9022   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9023   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9025   /* PA extraction insns don't support zero length bitfields or fields
9026      extending beyond the left or right-most bits.  Also, the predicate
9027      rejects lengths equal to a doubleword as they are better handled by
9028      the move patterns.  */
9029   if (len == 0 || pos + len > 64)
9030     FAIL;
9032   /* From mips.md: extract_bit_field doesn't verify that our source
9033      matches the predicate, so check it again here.  */
9034   if (!register_operand (operands[1], VOIDmode))
9035     FAIL;
9037   emit_insn (gen_extzv_64 (operands[0], operands[1],
9038                            operands[2], operands[3]));
9039   DONE;
9042 (define_insn "extzv_64"
9043   [(set (match_operand:DI 0 "register_operand" "=r")
9044         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9045                          (match_operand:DI 2 "uint6_operand" "")
9046                          (match_operand:DI 3 "uint6_operand" "")))]
9047   "TARGET_64BIT
9048    && UINTVAL (operands[2]) > 0
9049    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9050   "extrd,u %1,%3+%2-1,%2,%0"
9051   [(set_attr "type" "shift")
9052    (set_attr "length" "4")])
9054 (define_insn ""
9055   [(set (match_operand:DI 0 "register_operand" "=r")
9056         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9057                          (const_int 1)
9058                          (match_operand:DI 2 "register_operand" "q")))]
9059   "TARGET_64BIT"
9060   "extrd,u %1,%%sar,1,%0"
9061   [(set_attr "type" "shift")
9062    (set_attr "length" "4")])
9064 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
9065 (define_expand "extvsi"
9066   [(set (match_operand:SI 0 "register_operand" "")
9067         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9068                          (match_operand:SI 2 "uint5_operand" "")
9069                          (match_operand:SI 3 "uint5_operand" "")))]
9070   ""
9071   "
9073   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9074   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9076   /* PA extraction insns don't support zero length bitfields or fields
9077      extending beyond the left or right-most bits.  Also, the predicate
9078      rejects lengths equal to a word as they are better handled by
9079      the move patterns.  */
9080   if (len == 0 || pos + len > 32)
9081     FAIL;
9083   /* From mips.md: extract_bit_field doesn't verify that our source
9084      matches the predicate, so check it again here.  */
9085   if (!register_operand (operands[1], VOIDmode))
9086     FAIL;
9088   emit_insn (gen_extv_32 (operands[0], operands[1],
9089                           operands[2], operands[3]));
9090   DONE;
9093 (define_insn "extv_32"
9094   [(set (match_operand:SI 0 "register_operand" "=r")
9095         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9096                          (match_operand:SI 2 "uint5_operand" "")
9097                          (match_operand:SI 3 "uint5_operand" "")))]
9098   "UINTVAL (operands[2]) > 0
9099    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9100   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9101   [(set_attr "type" "shift")
9102    (set_attr "length" "4")])
9104 (define_insn ""
9105   [(set (match_operand:SI 0 "register_operand" "=r")
9106         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9107                          (const_int 1)
9108                          (match_operand:SI 2 "register_operand" "q")))]
9109   "!TARGET_64BIT"
9110   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9111   [(set_attr "type" "shift")
9112    (set_attr "length" "4")])
9114 (define_expand "extvdi"
9115   [(set (match_operand:DI 0 "register_operand" "")
9116         (sign_extract:DI (match_operand:DI 1 "register_operand" "")
9117                          (match_operand:DI 2 "uint6_operand" "")
9118                          (match_operand:DI 3 "uint6_operand" "")))]
9119   "TARGET_64BIT"
9120   "
9122   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9123   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9125   /* PA extraction insns don't support zero length bitfields or fields
9126      extending beyond the left or right-most bits.  Also, the predicate
9127      rejects lengths equal to a doubleword as they are better handled by
9128      the move patterns.  */
9129   if (len == 0 || pos + len > 64)
9130     FAIL;
9132   /* From mips.md: extract_bit_field doesn't verify that our source
9133      matches the predicate, so check it again here.  */
9134   if (!register_operand (operands[1], VOIDmode))
9135     FAIL;
9137   emit_insn (gen_extv_64 (operands[0], operands[1],
9138                           operands[2], operands[3]));
9139   DONE;
9142 (define_insn "extv_64"
9143   [(set (match_operand:DI 0 "register_operand" "=r")
9144         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9145                          (match_operand:DI 2 "uint6_operand" "")
9146                          (match_operand:DI 3 "uint6_operand" "")))]
9147   "TARGET_64BIT
9148    && UINTVAL (operands[2]) > 0
9149    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9150   "extrd,s %1,%3+%2-1,%2,%0"
9151   [(set_attr "type" "shift")
9152    (set_attr "length" "4")])
9154 (define_insn ""
9155   [(set (match_operand:DI 0 "register_operand" "=r")
9156         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9157                          (const_int 1)
9158                          (match_operand:DI 2 "register_operand" "q")))]
9159   "TARGET_64BIT"
9160   "extrd,s %1,%%sar,1,%0"
9161   [(set_attr "type" "shift")
9162    (set_attr "length" "4")])
9164 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
9165 (define_expand "insvsi"
9166   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9167                          (match_operand:SI 1 "uint5_operand" "")
9168                          (match_operand:SI 2 "uint5_operand" ""))
9169         (match_operand:SI 3 "arith5_operand" ""))]
9170   ""
9171   "
9173   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9174   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9176   /* PA insertion insns don't support zero length bitfields or fields
9177      extending beyond the left or right-most bits.  Also, the predicate
9178      rejects lengths equal to a word as they are better handled by
9179      the move patterns.  */
9180   if (len <= 0 || pos + len > 32)
9181     FAIL;
9183   /* From mips.md: insert_bit_field doesn't verify that our destination
9184      matches the predicate, so check it again here.  */
9185   if (!register_operand (operands[0], VOIDmode))
9186     FAIL;
9188   emit_insn (gen_insv_32 (operands[0], operands[1],
9189                           operands[2], operands[3]));
9190   DONE;
9193 (define_insn "insv_32"
9194   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9195                          (match_operand:SI 1 "uint5_operand" "")
9196                          (match_operand:SI 2 "uint5_operand" ""))
9197         (match_operand:SI 3 "arith5_operand" "r,L"))]
9198   "UINTVAL (operands[1]) > 0
9199    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9200   "@
9201    {dep|depw} %3,%2+%1-1,%1,%0
9202    {depi|depwi} %3,%2+%1-1,%1,%0"
9203   [(set_attr "type" "shift,shift")
9204    (set_attr "length" "4,4")])
9206 ;; Optimize insertion of const_int values of type 1...1xxxx.
9207 (define_insn ""
9208   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9209                          (match_operand:SI 1 "uint5_operand" "")
9210                          (match_operand:SI 2 "uint5_operand" ""))
9211         (match_operand:SI 3 "const_int_operand" ""))]
9212   "(INTVAL (operands[3]) & 0x10) != 0 &&
9213    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9214   "*
9216   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9217   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9219   [(set_attr "type" "shift")
9220    (set_attr "length" "4")])
9222 (define_expand "insvdi"
9223   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9224                          (match_operand:DI 1 "uint6_operand" "")
9225                          (match_operand:DI 2 "uint6_operand" ""))
9226         (match_operand:DI 3 "arith5_operand" ""))]
9227   "TARGET_64BIT"
9228   "
9230   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9231   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9233   /* PA insertion insns don't support zero length bitfields or fields
9234      extending beyond the left or right-most bits.  Also, the predicate
9235      rejects lengths equal to a doubleword as they are better handled by
9236      the move patterns.  */
9237   if (len <= 0 || pos + len > 64)
9238     FAIL;
9240   /* From mips.md: insert_bit_field doesn't verify that our destination
9241      matches the predicate, so check it again here.  */
9242   if (!register_operand (operands[0], VOIDmode))
9243     FAIL;
9245   emit_insn (gen_insv_64 (operands[0], operands[1],
9246                           operands[2], operands[3]));
9247   DONE;
9250 (define_insn "insv_64"
9251   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9252                          (match_operand:DI 1 "uint6_operand" "")
9253                          (match_operand:DI 2 "uint6_operand" ""))
9254         (match_operand:DI 3 "arith5_operand" "r,L"))]
9255   "TARGET_64BIT
9256    && UINTVAL (operands[1]) > 0
9257    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9258   "@
9259    depd %3,%2+%1-1,%1,%0
9260    depdi %3,%2+%1-1,%1,%0"
9261   [(set_attr "type" "shift,shift")
9262    (set_attr "length" "4,4")])
9264 ;; Optimize insertion of const_int values of type 1...1xxxx.
9265 (define_insn ""
9266   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9267                          (match_operand:DI 1 "uint6_operand" "")
9268                          (match_operand:DI 2 "uint6_operand" ""))
9269         (match_operand:DI 3 "const_int_operand" ""))]
9270   "(INTVAL (operands[3]) & 0x10) != 0
9271    && TARGET_64BIT
9272    && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9273   "*
9275   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9276   return \"depdi %3,%2+%1-1,%1,%0\";
9278   [(set_attr "type" "shift")
9279    (set_attr "length" "4")])
9281 (define_insn ""
9282   [(set (match_operand:DI 0 "register_operand" "=r")
9283         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9284                    (const_int 32)))]
9285   "TARGET_64BIT"
9286   "depd,z %1,31,32,%0"
9287   [(set_attr "type" "shift")
9288    (set_attr "length" "4")])
9290 ;; This insn is used for some loop tests, typically loops reversed when
9291 ;; strength reduction is used.  It is actually created when the instruction
9292 ;; combination phase combines the special loop test.  Since this insn
9293 ;; is both a jump insn and has an output, it must deal with its own
9294 ;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9295 ;; to not choose the register alternatives in the event a reload is needed.
9296 (define_insn "decrement_and_branch_until_zero"
9297   [(set (pc)
9298         (if_then_else
9299           (match_operator 2 "ordered_comparison_operator"
9300            [(plus:SI
9301               (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9302               (match_operand:SI 1 "int5_operand" "L,L,L"))
9303             (const_int 0)])
9304           (label_ref (match_operand 3 "" ""))
9305           (pc)))
9306    (set (match_dup 0)
9307         (plus:SI (match_dup 0) (match_dup 1)))
9308    (clobber (match_scratch:SI 4 "=X,r,r"))]
9309   ""
9310   "* return pa_output_dbra (operands, insn, which_alternative); "
9311 ;; Do not expect to understand this the first time through.
9312 [(set_attr "type" "cbranch,multi,multi")
9313  (set (attr "length")
9314       (if_then_else (eq_attr "alternative" "0")
9315 ;; Loop counter in register case
9316 ;; Short branch has length of 4
9317 ;; Long branch has length of 8, 20, 24 or 28
9318         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9319                (const_int MAX_12BIT_OFFSET))
9320            (const_int 4)
9321            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9322                (const_int MAX_17BIT_OFFSET))
9323            (const_int 8)
9324            (match_test "TARGET_PORTABLE_RUNTIME")
9325            (const_int 24)
9326            (not (match_test "flag_pic"))
9327            (const_int 20)]
9328           (const_int 28))
9330 ;; Loop counter in FP reg case.
9331 ;; Extra goo to deal with additional reload insns.
9332         (if_then_else (eq_attr "alternative" "1")
9333           (if_then_else (lt (match_dup 3) (pc))
9334              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9335                       (const_int MAX_12BIT_OFFSET))
9336                     (const_int 24)
9337                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9338                       (const_int MAX_17BIT_OFFSET))
9339                     (const_int 28)
9340                     (match_test "TARGET_PORTABLE_RUNTIME")
9341                     (const_int 44)
9342                     (not (match_test "flag_pic"))
9343                     (const_int 40)]
9344                   (const_int 48))
9345              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9346                       (const_int MAX_12BIT_OFFSET))
9347                     (const_int 24)
9348                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9349                       (const_int MAX_17BIT_OFFSET))
9350                     (const_int 28)
9351                     (match_test "TARGET_PORTABLE_RUNTIME")
9352                     (const_int 44)
9353                     (not (match_test "flag_pic"))
9354                     (const_int 40)]
9355                   (const_int 48)))
9357 ;; Loop counter in memory case.
9358 ;; Extra goo to deal with additional reload insns.
9359         (if_then_else (lt (match_dup 3) (pc))
9360              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9361                       (const_int MAX_12BIT_OFFSET))
9362                     (const_int 12)
9363                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9364                       (const_int MAX_17BIT_OFFSET))
9365                     (const_int 16)
9366                     (match_test "TARGET_PORTABLE_RUNTIME")
9367                     (const_int 32)
9368                     (not (match_test "flag_pic"))
9369                     (const_int 28)]
9370                   (const_int 36))
9371              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9372                       (const_int MAX_12BIT_OFFSET))
9373                     (const_int 12)
9374                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9375                       (const_int MAX_17BIT_OFFSET))
9376                     (const_int 16)
9377                     (match_test "TARGET_PORTABLE_RUNTIME")
9378                     (const_int 32)
9379                     (not (match_test "flag_pic"))
9380                     (const_int 28)]
9381                   (const_int 36))))))])
9383 (define_insn ""
9384   [(set (pc)
9385         (if_then_else
9386           (match_operator 2 "movb_comparison_operator"
9387            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9388           (label_ref (match_operand 3 "" ""))
9389           (pc)))
9390    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9391         (match_dup 1))]
9392   ""
9393 "* return pa_output_movb (operands, insn, which_alternative, 0); "
9394 ;; Do not expect to understand this the first time through.
9395 [(set_attr "type" "cbranch,multi,multi,multi")
9396  (set (attr "length")
9397       (if_then_else (eq_attr "alternative" "0")
9398 ;; Loop counter in register case
9399 ;; Short branch has length of 4
9400 ;; Long branch has length of 8, 20, 24 or 28
9401         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9402                (const_int MAX_12BIT_OFFSET))
9403            (const_int 4)
9404            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9405                (const_int MAX_17BIT_OFFSET))
9406            (const_int 8)
9407            (match_test "TARGET_PORTABLE_RUNTIME")
9408            (const_int 24)
9409            (not (match_test "flag_pic"))
9410            (const_int 20)]
9411           (const_int 28))
9413 ;; Loop counter in FP reg case.
9414 ;; Extra goo to deal with additional reload insns.
9415         (if_then_else (eq_attr "alternative" "1")
9416           (if_then_else (lt (match_dup 3) (pc))
9417              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9418                       (const_int MAX_12BIT_OFFSET))
9419                     (const_int 12)
9420                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9421                       (const_int MAX_17BIT_OFFSET))
9422                     (const_int 16)
9423                     (match_test "TARGET_PORTABLE_RUNTIME")
9424                     (const_int 32)
9425                     (not (match_test "flag_pic"))
9426                     (const_int 28)]
9427                   (const_int 36))
9428              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9429                       (const_int MAX_12BIT_OFFSET))
9430                     (const_int 12)
9431                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9432                       (const_int MAX_17BIT_OFFSET))
9433                     (const_int 16)
9434                     (match_test "TARGET_PORTABLE_RUNTIME")
9435                     (const_int 32)
9436                     (not (match_test "flag_pic"))
9437                     (const_int 28)]
9438                   (const_int 36)))
9440 ;; Loop counter in memory or sar case.
9441 ;; Extra goo to deal with additional reload insns.
9442         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9443                    (const_int MAX_12BIT_OFFSET))
9444                 (const_int 8)
9445                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9446                   (const_int MAX_17BIT_OFFSET))
9447                 (const_int 12)
9448                 (match_test "TARGET_PORTABLE_RUNTIME")
9449                 (const_int 28)
9450                 (not (match_test "flag_pic"))
9451                 (const_int 24)]
9452               (const_int 32)))))])
9454 ;; Handle negated branch.
9455 (define_insn ""
9456   [(set (pc)
9457         (if_then_else
9458           (match_operator 2 "movb_comparison_operator"
9459            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9460           (pc)
9461           (label_ref (match_operand 3 "" ""))))
9462    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9463         (match_dup 1))]
9464   ""
9465 "* return pa_output_movb (operands, insn, which_alternative, 1); "
9466 ;; Do not expect to understand this the first time through.
9467 [(set_attr "type" "cbranch,multi,multi,multi")
9468  (set (attr "length")
9469       (if_then_else (eq_attr "alternative" "0")
9470 ;; Loop counter in register case
9471 ;; Short branch has length of 4
9472 ;; Long branch has length of 8
9473         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9474                (const_int MAX_12BIT_OFFSET))
9475            (const_int 4)
9476            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9477                (const_int MAX_17BIT_OFFSET))
9478            (const_int 8)
9479            (match_test "TARGET_PORTABLE_RUNTIME")
9480            (const_int 24)
9481            (not (match_test "flag_pic"))
9482            (const_int 20)]
9483           (const_int 28))
9485 ;; Loop counter in FP reg case.
9486 ;; Extra goo to deal with additional reload insns.
9487         (if_then_else (eq_attr "alternative" "1")
9488           (if_then_else (lt (match_dup 3) (pc))
9489              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9490                       (const_int MAX_12BIT_OFFSET))
9491                     (const_int 12)
9492                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9493                       (const_int MAX_17BIT_OFFSET))
9494                     (const_int 16)
9495                     (match_test "TARGET_PORTABLE_RUNTIME")
9496                     (const_int 32)
9497                     (not (match_test "flag_pic"))
9498                     (const_int 28)]
9499                   (const_int 36))
9500              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9501                       (const_int MAX_12BIT_OFFSET))
9502                     (const_int 12)
9503                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9504                       (const_int MAX_17BIT_OFFSET))
9505                     (const_int 16)
9506                     (match_test "TARGET_PORTABLE_RUNTIME")
9507                     (const_int 32)
9508                     (not (match_test "flag_pic"))
9509                     (const_int 28)]
9510                   (const_int 36)))
9512 ;; Loop counter in memory or SAR case.
9513 ;; Extra goo to deal with additional reload insns.
9514         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9515                    (const_int MAX_12BIT_OFFSET))
9516                 (const_int 8)
9517                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9518                   (const_int MAX_17BIT_OFFSET))
9519                 (const_int 12)
9520                 (match_test "TARGET_PORTABLE_RUNTIME")
9521                 (const_int 28)
9522                 (not (match_test "flag_pic"))
9523                 (const_int 24)]
9524               (const_int 32)))))])
9526 (define_insn ""
9527   [(set (pc) (label_ref (match_operand 3 "" "" )))
9528    (set (match_operand:SI 0 "ireg_operand" "=r")
9529         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
9530                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9531   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9532   "*
9534   return pa_output_parallel_addb (operands, insn);
9536 [(set_attr "type" "parallel_branch")
9537  (set (attr "length")
9538     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9539                (const_int MAX_12BIT_OFFSET))
9540            (const_int 4)
9541            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9542                (const_int MAX_17BIT_OFFSET))
9543            (const_int 8)
9544            (match_test "TARGET_PORTABLE_RUNTIME")
9545            (const_int 24)
9546            (not (match_test "flag_pic"))
9547            (const_int 20)]
9548           (const_int 28)))])
9550 (define_insn ""
9551   [(set (pc) (label_ref (match_operand 2 "" "" )))
9552    (set (match_operand:SF 0 "ireg_operand" "=r")
9553         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9554   "reload_completed"
9555   "*
9557   return pa_output_parallel_movb (operands, insn);
9559 [(set_attr "type" "parallel_branch")
9560  (set (attr "length")
9561     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9562                (const_int MAX_12BIT_OFFSET))
9563            (const_int 4)
9564            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9565                (const_int MAX_17BIT_OFFSET))
9566            (const_int 8)
9567            (match_test "TARGET_PORTABLE_RUNTIME")
9568            (const_int 24)
9569            (not (match_test "flag_pic"))
9570            (const_int 20)]
9571           (const_int 28)))])
9573 (define_insn ""
9574   [(set (pc) (label_ref (match_operand 2 "" "" )))
9575    (set (match_operand:SI 0 "ireg_operand" "=r")
9576         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9577   "reload_completed"
9578   "*
9580   return pa_output_parallel_movb (operands, insn);
9582 [(set_attr "type" "parallel_branch")
9583  (set (attr "length")
9584     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9585                (const_int MAX_12BIT_OFFSET))
9586            (const_int 4)
9587            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9588                (const_int MAX_17BIT_OFFSET))
9589            (const_int 8)
9590            (match_test "TARGET_PORTABLE_RUNTIME")
9591            (const_int 24)
9592            (not (match_test "flag_pic"))
9593            (const_int 20)]
9594           (const_int 28)))])
9596 (define_insn ""
9597   [(set (pc) (label_ref (match_operand 2 "" "" )))
9598    (set (match_operand:HI 0 "ireg_operand" "=r")
9599         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9600   "reload_completed"
9601   "*
9603   return pa_output_parallel_movb (operands, insn);
9605 [(set_attr "type" "parallel_branch")
9606  (set (attr "length")
9607     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9608                (const_int MAX_12BIT_OFFSET))
9609            (const_int 4)
9610            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9611                (const_int MAX_17BIT_OFFSET))
9612            (const_int 8)
9613            (match_test "TARGET_PORTABLE_RUNTIME")
9614            (const_int 24)
9615            (not (match_test "flag_pic"))
9616            (const_int 20)]
9617           (const_int 28)))])
9619 (define_insn ""
9620   [(set (pc) (label_ref (match_operand 2 "" "" )))
9621    (set (match_operand:QI 0 "ireg_operand" "=r")
9622         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9623   "reload_completed"
9624   "*
9626   return pa_output_parallel_movb (operands, insn);
9628 [(set_attr "type" "parallel_branch")
9629  (set (attr "length")
9630     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9631                (const_int MAX_12BIT_OFFSET))
9632            (const_int 4)
9633            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9634                (const_int MAX_17BIT_OFFSET))
9635            (const_int 8)
9636            (match_test "TARGET_PORTABLE_RUNTIME")
9637            (const_int 24)
9638            (not (match_test "flag_pic"))
9639            (const_int 20)]
9640           (const_int 28)))])
9642 (define_insn ""
9643   [(set (match_operand 0 "register_operand" "=f")
9644         (mult (match_operand 1 "register_operand" "f")
9645               (match_operand 2 "register_operand" "f")))
9646    (set (match_operand 3 "register_operand" "+f")
9647         (plus (match_operand 4 "register_operand" "f")
9648               (match_operand 5 "register_operand" "f")))]
9649   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9650    && reload_completed && pa_fmpyaddoperands (operands)"
9651   "*
9653   if (GET_MODE (operands[0]) == DFmode)
9654     {
9655       if (rtx_equal_p (operands[3], operands[5]))
9656         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9657       else
9658         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9659     }
9660   else
9661     {
9662       if (rtx_equal_p (operands[3], operands[5]))
9663         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9664       else
9665         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9666     }
9668   [(set_attr "type" "fpalu")
9669    (set_attr "length" "4")])
9671 (define_insn ""
9672   [(set (match_operand 3 "register_operand" "+f")
9673         (plus (match_operand 4 "register_operand" "f")
9674               (match_operand 5 "register_operand" "f")))
9675    (set (match_operand 0 "register_operand" "=f")
9676         (mult (match_operand 1 "register_operand" "f")
9677               (match_operand 2 "register_operand" "f")))]
9678   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9679    && reload_completed && pa_fmpyaddoperands (operands)"
9680   "*
9682   if (GET_MODE (operands[0]) == DFmode)
9683     {
9684       if (rtx_equal_p (operands[3], operands[5]))
9685         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9686       else
9687         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9688     }
9689   else
9690     {
9691       if (rtx_equal_p (operands[3], operands[5]))
9692         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9693       else
9694         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9695     }
9697   [(set_attr "type" "fpalu")
9698    (set_attr "length" "4")])
9700 (define_insn ""
9701   [(set (match_operand 0 "register_operand" "=f")
9702         (mult (match_operand 1 "register_operand" "f")
9703               (match_operand 2 "register_operand" "f")))
9704    (set (match_operand 3 "register_operand" "+f")
9705         (minus (match_operand 4 "register_operand" "f")
9706                (match_operand 5 "register_operand" "f")))]
9707   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9708    && reload_completed && pa_fmpysuboperands (operands)"
9709   "*
9711   if (GET_MODE (operands[0]) == DFmode)
9712     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9713   else
9714     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9716   [(set_attr "type" "fpalu")
9717    (set_attr "length" "4")])
9719 (define_insn ""
9720   [(set (match_operand 3 "register_operand" "+f")
9721         (minus (match_operand 4 "register_operand" "f")
9722                (match_operand 5 "register_operand" "f")))
9723    (set (match_operand 0 "register_operand" "=f")
9724         (mult (match_operand 1 "register_operand" "f")
9725               (match_operand 2 "register_operand" "f")))]
9726   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9727    && reload_completed && pa_fmpysuboperands (operands)"
9728   "*
9730   if (GET_MODE (operands[0]) == DFmode)
9731     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9732   else
9733     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9735   [(set_attr "type" "fpalu")
9736    (set_attr "length" "4")])
9738 ;; The following two patterns are used by the trampoline code for nested
9739 ;; functions.  They flush the I and D cache lines from the start address
9740 ;; (operand0) to the end address (operand1).  No lines are flushed if the
9741 ;; end address is less than the start address (unsigned).
9743 ;; Because the range of memory flushed is variable and the size of a MEM
9744 ;; can only be a CONST_INT, the patterns specify that they perform an
9745 ;; unspecified volatile operation on all memory.
9747 ;; The address range for an icache flush must lie within a single
9748 ;; space on targets with non-equivalent space registers.
9750 ;; Operand 0 contains the start address.
9751 ;; Operand 1 contains the end address.
9752 ;; Operand 2 contains the line length to use.
9753 (define_insn "dcacheflush<P:mode>"
9754   [(const_int 1)
9755    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9756    (use (match_operand 0 "pmode_register_operand" "r"))
9757    (use (match_operand 1 "pmode_register_operand" "r"))
9758    (use (match_operand 2 "pmode_register_operand" "r"))
9759    (clobber (match_scratch:P 3 "=&0"))]
9760   ""
9761   "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9762   [(set_attr "type" "multi")
9763    (set_attr "length" "12")])
9765 (define_insn "icacheflush<P:mode>"
9766   [(const_int 2)
9767    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9768    (use (match_operand 0 "pmode_register_operand" "r"))
9769    (use (match_operand 1 "pmode_register_operand" "r"))
9770    (use (match_operand 2 "pmode_register_operand" "r"))
9771    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9772    (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9773    (clobber (match_scratch:P 5 "=&0"))]
9774   ""
9775   "mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<dwc><<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
9776   [(set_attr "type" "multi")
9777    (set_attr "length" "52")])
9779 ;; An out-of-line prologue.
9780 (define_insn "outline_prologue_call"
9781   [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9782    (clobber (reg:SI 31))
9783    (clobber (reg:SI 22))
9784    (clobber (reg:SI 21))
9785    (clobber (reg:SI 20))
9786    (clobber (reg:SI 19))
9787    (clobber (reg:SI 1))]
9788   ""
9789   "*
9792   /* We need two different versions depending on whether or not we
9793      need a frame pointer.   Also note that we return to the instruction
9794      immediately after the branch rather than two instructions after the
9795      break as normally is the case.  */
9796   if (frame_pointer_needed)
9797     {
9798       /* Must import the magic millicode routine(s).  */
9799       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9801       if (TARGET_PORTABLE_RUNTIME)
9802         {
9803           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9804           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9805                            NULL);
9806         }
9807       else
9808         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9809     }
9810   else
9811     {
9812       /* Must import the magic millicode routine(s).  */
9813       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9815       if (TARGET_PORTABLE_RUNTIME)
9816         {
9817           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9818           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9819         }
9820       else
9821         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9822     }
9823   return \"\";
9825   [(set_attr "type" "multi")
9826    (set_attr "length" "8")])
9828 ;; An out-of-line epilogue.
9829 (define_insn "outline_epilogue_call"
9830   [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9831    (use (reg:SI 29))
9832    (use (reg:SI 28))
9833    (clobber (reg:SI 31))
9834    (clobber (reg:SI 22))
9835    (clobber (reg:SI 21))
9836    (clobber (reg:SI 20))
9837    (clobber (reg:SI 19))
9838    (clobber (reg:SI 2))
9839    (clobber (reg:SI 1))]
9840   ""
9841   "*
9844   /* We need two different versions depending on whether or not we
9845      need a frame pointer.   Also note that we return to the instruction
9846      immediately after the branch rather than two instructions after the
9847      break as normally is the case.  */
9848   if (frame_pointer_needed)
9849     {
9850       /* Must import the magic millicode routine.  */
9851       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9853       /* The out-of-line prologue will make sure we return to the right
9854          instruction.  */
9855       if (TARGET_PORTABLE_RUNTIME)
9856         {
9857           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9858           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9859                            NULL);
9860         }
9861       else
9862         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9863     }
9864   else
9865     {
9866       /* Must import the magic millicode routine.  */
9867       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9869       /* The out-of-line prologue will make sure we return to the right
9870          instruction.  */
9871       if (TARGET_PORTABLE_RUNTIME)
9872         {
9873           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9874           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9875         }
9876       else
9877         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9878     }
9879   return \"\";
9881   [(set_attr "type" "multi")
9882    (set_attr "length" "8")])
9884 ;; Given a function pointer, canonicalize it so it can be 
9885 ;; reliably compared to another function pointer.  */
9886 (define_expand "canonicalize_funcptr_for_compare"
9887   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9888    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9889               (clobber (match_dup 2))
9890               (clobber (reg:SI 26))
9891               (clobber (reg:SI 22))
9892               (clobber (reg:SI 31))])
9893    (set (match_operand:SI 0 "register_operand" "")
9894         (reg:SI 29))]
9895   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9896   "
9898   if (TARGET_ELF32)
9899     {
9900       rtx canonicalize_funcptr_for_compare_libfunc
9901         = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9903       emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9904                                operands[0], LCT_NORMAL, Pmode,
9905                                operands[1], Pmode);
9906       DONE;
9907     }
9909   operands[2] = gen_reg_rtx (SImode);
9910   if (GET_CODE (operands[1]) != REG)
9911     {
9912       rtx tmp = gen_reg_rtx (Pmode);
9913       emit_move_insn (tmp, operands[1]);
9914       operands[1] = tmp;
9915     }
9918 (define_insn "*$$sh_func_adrs"
9919   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9920    (clobber (match_operand:SI 0 "register_operand" "=a"))
9921    (clobber (reg:SI 26))
9922    (clobber (reg:SI 22))
9923    (clobber (reg:SI 31))]
9924   "!TARGET_64BIT"
9925   "*
9927   int length = get_attr_length (insn);
9928   rtx xoperands[2];
9930   xoperands[0] = GEN_INT (length - 8);
9931   xoperands[1] = GEN_INT (length - 16);
9933   /* Must import the magic millicode routine.  */
9934   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9936   /* This is absolutely amazing.
9938      First, copy our input parameter into %r29 just in case we don't
9939      need to call $$sh_func_adrs.  */
9940   output_asm_insn (\"copy %%r26,%%r29\", NULL);
9941   output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9943   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9944      we use %r26 unchanged.  */
9945   output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9946   output_asm_insn (\"ldi 4096,%%r31\", NULL);
9948   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9949      4096, then again we use %r26 unchanged.  */
9950   output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9952   /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
9953   return pa_output_millicode_call (insn,
9954                                    gen_rtx_SYMBOL_REF (SImode,
9955                                                        \"$$sh_func_adrs\"));
9957   [(set_attr "type" "sh_func_adrs")
9958    (set (attr "length")
9959         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
9960               (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
9961                     (const_int 20))))])
9963 ;; On the PA, the PIC register is call clobbered, so it must
9964 ;; be saved & restored around calls by the caller.  If the call
9965 ;; doesn't return normally (nonlocal goto, or an exception is
9966 ;; thrown), then the code at the exception handler label must
9967 ;; restore the PIC register.
9968 (define_expand "exception_receiver"
9969   [(const_int 4)]
9970   "flag_pic"
9971   "
9973   /* On the 64-bit port, we need a blockage because there is
9974      confusion regarding the dependence of the restore on the
9975      frame pointer.  As a result, the frame pointer and pic
9976      register restores sometimes are interchanged erroneously.  */
9977   if (TARGET_64BIT)
9978     emit_insn (gen_blockage ());
9979   /* Restore the PIC register using hppa_pic_save_rtx ().  The
9980      PIC register is not saved in the frame in 64-bit ABI.  */
9981   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9982   emit_insn (gen_blockage ());
9983   DONE;
9986 (define_expand "builtin_setjmp_receiver"
9987   [(label_ref (match_operand 0 "" ""))]
9988   "flag_pic"
9989   "
9991   if (TARGET_64BIT)
9992     emit_insn (gen_blockage ());
9993   /* Restore the PIC register.  Hopefully, this will always be from
9994      a stack slot.  The only registers that are valid after a
9995      builtin_longjmp are the stack and frame pointers.  */
9996   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9997   emit_insn (gen_blockage ());
9998   DONE;
10001 ;; Allocate new stack space and update the saved stack pointer in the
10002 ;; frame marker.  The HP C compilers also copy additional words in the
10003 ;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10004 ;; The 32-bit compiler copies the word at -16 (Static Link).  We
10005 ;; currently don't copy these values.
10007 ;; Since the copy of the frame marker can't be done atomically, I
10008 ;; suspect that using it for unwind purposes may be somewhat unreliable.
10009 ;; The HP compilers appear to raise the stack and copy the frame
10010 ;; marker in a strict instruction sequence.  This suggests that the
10011 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10012 ;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10013 ;; as GAS doesn't support it, or try to keep the instructions emitted
10014 ;; here in strict sequence.
10015 (define_expand "allocate_stack"
10016   [(match_operand 0 "" "")
10017    (match_operand 1 "" "")]
10018   ""
10019   "
10021   rtx addr;
10023   /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10024      in operand 0 before adjusting the stack.  */
10025   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10026   anti_adjust_stack (operands[1]);
10027   if (TARGET_HPUX_UNWIND_LIBRARY)
10028     {
10029       addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10030                            GEN_INT (TARGET_64BIT ? -8 : -4));
10031       emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10032     }
10033   if (!TARGET_64BIT && flag_pic)
10034     {
10035       rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10036       emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10037     }
10038   DONE;
10041 (define_expand "prefetch"
10042   [(match_operand 0 "address_operand" "")
10043    (match_operand 1 "const_int_operand" "")
10044    (match_operand 2 "const_int_operand" "")]
10045   "TARGET_PA_20"
10047   operands[0] = copy_addr_to_reg (operands[0]);
10048   emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10049   DONE;
10052 (define_insn "prefetch_20"
10053   [(prefetch (match_operand 0 "pmode_register_operand" "r")
10054              (match_operand:SI 1 "const_int_operand" "n")
10055              (match_operand:SI 2 "const_int_operand" "n"))]
10056   "TARGET_PA_20"
10058   /* The SL cache-control completer indicates good spatial locality but
10059      poor temporal locality.  The ldw instruction with a target of general
10060      register 0 prefetches a cache line for a read.  The ldd instruction
10061      prefetches a cache line for a write.  */
10062   static const char * const instr[2][2] = {
10063     {
10064       "ldw,sl 0(%0),%%r0",
10065       "ldd,sl 0(%0),%%r0"
10066     },
10067     {
10068       "ldw 0(%0),%%r0",
10069       "ldd 0(%0),%%r0"
10070     }
10071   };
10072   int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10073   int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10075   return instr [locality][read_or_write];
10077   [(set_attr "type" "load")
10078    (set_attr "length" "4")])
10080 ;; TLS Support
10081 (define_insn "tgd_load"
10082  [(set (match_operand:SI 0 "register_operand" "=r")
10083        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10084   (clobber (reg:SI 1))
10085   (use (reg:SI 27))]
10086   ""
10087   "*
10089   return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10091   [(set_attr "type" "multi")
10092    (set_attr "length" "8")])
10094 (define_insn "tgd_load_pic"
10095  [(set (match_operand:SI 0 "register_operand" "=r")
10096        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10097   (clobber (reg:SI 1))
10098   (use (reg:SI 19))]
10099   ""
10100   "*
10102   return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10104   [(set_attr "type" "multi")
10105    (set_attr "length" "8")])
10107 (define_insn "tld_load"
10108  [(set (match_operand:SI 0 "register_operand" "=r")
10109        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10110   (clobber (reg:SI 1))
10111   (use (reg:SI 27))]
10112   ""
10113   "*
10115   return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10117   [(set_attr "type" "multi")
10118    (set_attr "length" "8")])
10120 (define_insn "tld_load_pic"
10121  [(set (match_operand:SI 0 "register_operand" "=r")
10122        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10123   (clobber (reg:SI 1))
10124   (use (reg:SI 19))]
10125   ""
10126   "*
10128   return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10130   [(set_attr "type" "multi")
10131    (set_attr "length" "8")])
10133 (define_insn "tld_offset_load"
10134   [(set (match_operand:SI 0 "register_operand" "=r")
10135         (plus:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] 
10136                             UNSPEC_TLSLDO)
10137                  (match_operand:SI 2 "register_operand" "r")))
10138    (clobber (reg:SI 1))]
10139   ""
10140   "*
10142   return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\"; 
10144   [(set_attr "type" "multi")
10145    (set_attr "length" "8")])
10147 (define_insn "tp_load"
10148   [(set (match_operand:SI 0 "register_operand" "=r")
10149         (unspec:SI [(const_int 0)] UNSPEC_TP))]
10150   ""
10151   "mfctl %%cr27,%0"
10152   [(set_attr "type" "multi")
10153    (set_attr "length" "4")])
10155 (define_insn "tie_load"
10156   [(set (match_operand:SI 0 "register_operand" "=r")
10157         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10158    (clobber (reg:SI 1))
10159    (use (reg:SI 27))]
10160   ""
10161   "*
10163   return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10165   [(set_attr "type" "multi")
10166    (set_attr "length" "8")])
10168 (define_insn "tie_load_pic"
10169   [(set (match_operand:SI 0 "register_operand" "=r")
10170         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10171    (clobber (reg:SI 1))
10172    (use (reg:SI 19))]
10173   ""
10174   "*
10176   return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10178   [(set_attr "type" "multi")
10179    (set_attr "length" "8")])
10181 (define_insn "tle_load"
10182   [(set (match_operand:SI 0 "register_operand" "=r")
10183         (plus:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")] 
10184                             UNSPEC_TLSLE)
10185                  (match_operand:SI 2 "register_operand" "r")))
10186    (clobber (reg:SI 1))]
10187   ""
10188   "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10189   [(set_attr "type" "multi")
10190    (set_attr "length" "8")])
10192 ;; Atomic instructions
10194 ;; All memory loads and stores access storage atomically except
10195 ;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10196 ;; doubleword loads and stores are not guaranteed to be atomic
10197 ;; when referencing the I/O address space.
10199 ;; These patterns are at the bottom so the non atomic versions are preferred.
10201 (define_expand "atomic_storeqi"
10202   [(match_operand:QI 0 "memory_operand")                ;; memory
10203    (match_operand:QI 1 "register_operand")              ;; val out
10204    (match_operand:SI 2 "const_int_operand")]            ;; model
10205   ""
10207   if (TARGET_SYNC_LIBCALL)
10208     {
10209       rtx mem = operands[0];
10210       rtx val = operands[1];
10211       if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10212         DONE;
10213     }
10214   FAIL;
10217 ;; Implement atomic HImode stores using exchange.
10219 (define_expand "atomic_storehi"
10220   [(match_operand:HI 0 "memory_operand")                ;; memory
10221    (match_operand:HI 1 "register_operand")              ;; val out
10222    (match_operand:SI 2 "const_int_operand")]            ;; model
10223   ""
10225   if (TARGET_SYNC_LIBCALL)
10226     {
10227       rtx mem = operands[0];
10228       rtx val = operands[1];
10229       if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10230         DONE;
10231     }
10232   FAIL;
10235 ;; Implement atomic SImode store using exchange.
10237 (define_expand "atomic_storesi"
10238   [(match_operand:SI 0 "memory_operand")                ;; memory
10239    (match_operand:SI 1 "register_operand")              ;; val out
10240    (match_operand:SI 2 "const_int_operand")]            ;; model
10241   ""
10243   if (TARGET_SYNC_LIBCALL)
10244     {
10245       rtx mem = operands[0];
10246       rtx val = operands[1];
10247       if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10248         DONE;
10249     }
10250   FAIL;
10253 ;; Implement atomic DImode load.
10255 (define_expand "atomic_loaddi"
10256   [(match_operand:DI 0 "register_operand")              ;; val out
10257    (match_operand:DI 1 "memory_operand")                ;; memory
10258    (match_operand:SI 2 "const_int_operand")]            ;; model
10259   ""
10261   enum memmodel model;
10263   if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10264     FAIL;
10266   model = memmodel_from_int (INTVAL (operands[2]));
10267   operands[1] = force_reg (SImode, XEXP (operands[1], 0));
10268   if (is_mm_seq_cst (model))
10269     expand_mem_thread_fence (model);
10270   emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10271   expand_mem_thread_fence (model);
10272   DONE;
10275 (define_insn "atomic_loaddi_1"
10276   [(set (match_operand:DI 0 "register_operand" "=r")
10277         (mem:DI (match_operand:SI 1 "register_operand" "r")))
10278    (clobber (match_scratch:DI 2 "=f"))]
10279   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10280   "{fldds|fldd} 0(%1),%2\n\t{fstds|fstd} %2,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0\n\t{ldws|ldw} -12(%%sp),%R0"
10281   [(set_attr "type" "move")
10282    (set_attr "length" "16")])
10284 ;; Implement atomic DImode store.
10286 (define_expand "atomic_storedi"
10287   [(match_operand:DI 0 "memory_operand")                ;; memory
10288    (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10289    (match_operand:SI 2 "const_int_operand")]            ;; model
10290   ""
10292   enum memmodel model;
10294   if (TARGET_SYNC_LIBCALL)
10295     {
10296       rtx mem = operands[0];
10297       rtx val = operands[1];
10298       if (pa_maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val))
10299         DONE;
10300     }
10302   if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10303     FAIL;
10305   model = memmodel_from_int (INTVAL (operands[2]));
10306   operands[0] = force_reg (SImode, XEXP (operands[0], 0));
10307   if (operands[1] != CONST0_RTX (DImode))
10308     operands[1] = force_reg (DImode, operands[1]);
10309   expand_mem_thread_fence (model);
10310   emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10311   if (is_mm_seq_cst (model))
10312     expand_mem_thread_fence (model);
10313   DONE;
10316 (define_insn "atomic_storedi_1"
10317   [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10318         (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10319    (clobber (match_scratch:DI 2 "=X,f"))]
10320   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10321   "@
10322    {fstds|fstd} %%fr0,0(%0)
10323    {stws|stw} %1,-16(%%sp)\n\t{stws|stw} %R1,-12(%%sp)\n\t{fldds|fldd} -16(%%sp),%2\n\t{fstds|fstd} %2,0(%0)"
10324   [(set_attr "type" "move,move")
10325    (set_attr "length" "4,16")])
10327 ;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10328 ;; we need memory barriers to enforce program order for memory references
10329 ;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10330 ;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10331 ;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10332 ;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10334 ;; When barriers are needed, we use a strongly ordered ldcw instruction as
10335 ;; the barrier.  Most PA 2.0 targets are cache coherent.  In that case, we
10336 ;; can use the coherent cache control hint and avoid aligning the ldcw
10337 ;; address.  In spite of its description, it is not clear that the sync
10338 ;; instruction works as a barrier.
10340 (define_expand "memory_barrier"
10341   [(parallel
10342      [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10343       (clobber (match_dup 1))])]
10344   ""
10346   /* We don't need a barrier if the target uses ordered memory references.  */
10347   if (TARGET_ORDERED)
10348     FAIL;
10349   operands[1] = gen_reg_rtx (Pmode);
10350   operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10351   MEM_VOLATILE_P (operands[0]) = 1;
10354 (define_insn "*memory_barrier_coherent"
10355   [(set (match_operand:BLK 0 "" "")
10356         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10357    (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10358   "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10359   "ldcw,co 0(%%sp),%1"
10360   [(set_attr "type" "binary")
10361    (set_attr "length" "4")])
10363 (define_insn "*memory_barrier_64"
10364   [(set (match_operand:BLK 0 "" "")
10365         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10366     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10367   "TARGET_64BIT"
10368   "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw 0(%1),%1"
10369   [(set_attr "type" "binary")
10370    (set_attr "length" "12")])
10372 (define_insn "*memory_barrier_32"
10373   [(set (match_operand:BLK 0 "" "")
10374         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10375     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10376   ""
10377   "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\tldcw 0(%1),%1"
10378   [(set_attr "type" "binary")
10379    (set_attr "length" "12")])