hppa: Fix bug in atomic_storedi_1 pattern
[official-gcc.git] / gcc / config / pa / pa.md
blobaecdcc98b6a8a3ee8309e4eef539ab5ca53ca97a
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;;   Copyright (C) 1992-2024 Free Software Foundation, Inc.
3 ;;   Contributed by the Center for Software Science at the University
4 ;;   of Utah.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 ;; This machine description is inspired by sparc.md and to a lesser
23 ;; extent mips.md.
25 ;; Possible improvements:
27 ;; * With PA1.1, most computational instructions can conditionally nullify
28 ;;   the execution of the following instruction.  A nullified instruction
29 ;;   does not cause the instruction pipeline to stall, making it a very
30 ;;   efficient alternative to e.g. branching or conditional moves.
32 ;;   Nullification is performed conditionally based on the outcome of a
33 ;;   test specified in the opcode.  The test result is stored in PSW[N]
34 ;;   and can only be used to nullify the instruction following immediately
35 ;;   after the test.  For example:
37 ;;      ldi 10,%r26
38 ;;      ldi 5,%r25
39 ;;      sub,< %r26,%r25,%r28
40 ;;      sub   %r28,%r25,%r28    ; %r28 == 0
41 ;;      sub,> %r26,%r25,%r29
42 ;;      sub   %r29,%r25,%r29    ; %r29 == 5
44 ;;   This could be tricky to implement because the result of the test has
45 ;;   to be propagated one instruction forward, which, in the worst case,
46 ;;   would involve (1) adding a fake register for PSW[N]; (2) adding the
47 ;;   variants of the computational instructions that set or consume this
48 ;;   fake register.  The cond_exec infrastructure is probably not helpful
49 ;;   for this.
51 ;; * PA-RISC includes a set of conventions for branch instruction usage
52 ;;   to indicate whether a particular branch is more likely to be taken
53 ;;   or not taken.  For example, the prediction for CMPB instructions
54 ;;   (CMPB,cond,n r1,r2,target) depends on the direction of the branch
55 ;;   (forward or backward) and on the order of the operands:
57 ;;     | branch    | operand  | branch     |
58 ;;     | direction | compare  | prediction |
59 ;;     +-----------+----------+------------+
60 ;;     | backward  | r1 < r2  | taken      |
61 ;;     | backward  | r1 >= r2 | not taken  |
62 ;;     | forward   | r1 < r2  | not taken  |
63 ;;     | forward   | r1 >= r2 | taken      |
64 ;;    
65 ;;   By choosing instructions and operand order carefully, the compiler
66 ;;   could give the CPU branch predictor some help.
67 ;;   
69 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
71 ;; Uses of UNSPEC in this file:
73 (define_c_enum "unspec"
74   [UNSPEC_CFFC          ; canonicalize_funcptr_for_compare
75    UNSPEC_GOTO          ; indirect_goto
76    UNSPEC_DLTIND14R
77    UNSPEC_TP
78    UNSPEC_TLSGD
79    UNSPEC_TLSLDM
80    UNSPEC_TLSLDO
81    UNSPEC_TLSLDBASE
82    UNSPEC_TLSIE
83    UNSPEC_TLSLE 
84    UNSPEC_TLSGD_PIC
85    UNSPEC_TLSLDM_PIC
86    UNSPEC_TLSIE_PIC
87    UNSPEC_MEMORY_BARRIER
88   ])
90 ;; UNSPEC_VOLATILE:
92 (define_c_enum "unspecv"
93   [UNSPECV_BLOCKAGE     ; blockage
94    UNSPECV_DCACHE       ; dcacheflush
95    UNSPECV_ICACHE       ; icacheflush
96    UNSPECV_OPC          ; outline_prologue_call
97    UNSPECV_OEC          ; outline_epilogue_call
98    UNSPECV_LONGJMP      ; builtin_longjmp
99   ])
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 ;; Register numbers
113 (define_constants
114   [(R1_REGNUM            1)
115    (R19_REGNUM          19)
116    (R27_REGNUM          27)
117   ])
119 ;; Mode and code iterators
121 ;; This mode iterator allows :P to be used for patterns that operate on
122 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
123 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
125 ;; This attribute defines the condition prefix for word and double word
126 ;; add, compare, subtract and logical instructions.
127 (define_mode_attr dwc [(SI "") (DI "*")])
129 ;; Insn type.  Used to default other attribute values.
131 ;; type "unary" insns have one input operand (1) and one output operand (0)
132 ;; type "binary" insns have two input operands (1,2) and one output (0)
134 (define_attr "type"
135   "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"
136   (const_string "binary"))
138 (define_attr "pa_combine_type"
139   "fmpy,faddsub,uncond_branch,addmove,none"
140   (const_string "none"))
142 ;; Processor type (for scheduling, not code generation) -- this attribute
143 ;; must exactly match the processor_type enumeration in pa.h.
145 ;; FIXME: Add 800 scheduling for completeness?
147 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
149 ;; Length (in # of bytes).
150 (define_attr "length" ""
151   (cond [(eq_attr "type" "load,fpload")
152          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
153                        (const_int 8) (const_int 4))
155          (eq_attr "type" "store,fpstore")
156          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
157                        (const_int 8) (const_int 4))
159          (eq_attr "type" "binary,shift,nullshift")
160          (if_then_else (match_operand 2 "arith14_operand" "")
161                        (const_int 4) (const_int 12))
163          (eq_attr "type" "move,unary,shift,nullshift")
164          (if_then_else (match_operand 1 "arith14_operand" "")
165                        (const_int 4) (const_int 8))]
167         (const_int 4)))
169 (define_asm_attributes
170   [(set_attr "length" "4")
171    (set_attr "type" "multi")])
173 ;; Attributes for instruction and branch scheduling
175 ;; For conditional branches. Frame related instructions are not allowed
176 ;; because they confuse the unwind support.
177 (define_attr "in_branch_delay" "false,true"
178   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
179                      (eq_attr "length" "4")
180                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
181                 (const_string "true")
182                 (const_string "false")))
184 ;; Disallow instructions which use the FPU since they will tie up the FPU
185 ;; even if the instruction is nullified.
186 (define_attr "in_nullified_branch_delay" "false,true"
187   (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")
188                      (eq_attr "length" "4")
189                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
190                 (const_string "true")
191                 (const_string "false")))
193 ;; For calls and millicode calls.
194 (define_attr "in_call_delay" "false,true"
195   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
196                      (eq_attr "length" "4")
197                      (not (match_test "RTX_FRAME_RELATED_P (insn)")))
198                 (const_string "true")
199                 (const_string "false")))
201 ;; Call delay slot description.
202 (define_delay (eq_attr "type" "call")
203   [(eq_attr "in_call_delay" "true") (nil) (nil)])
205 ;; Sibcall delay slot description.
206 (define_delay (eq_attr "type" "sibcall")
207   [(eq_attr "in_call_delay" "true") (nil) (nil)])
209 ;; Millicode call delay slot description.
210 (define_delay (eq_attr "type" "milli")
211   [(eq_attr "in_call_delay" "true") (nil) (nil)])
213 ;; Return and other similar instructions.
214 (define_delay (eq_attr "type" "branch,parallel_branch")
215   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
217 ;; Floating point conditional branch delay slot description.
218 (define_delay (eq_attr "type" "fbranch")
219   [(eq_attr "in_branch_delay" "true")
220    (eq_attr "in_nullified_branch_delay" "true")
221    (nil)])
223 ;; Integer conditional branch delay slot description.
224 ;; Nullification of conditional branches on the PA is dependent on the
225 ;; direction of the branch.  Forward branches nullify true and
226 ;; backward branches nullify false.  If the direction is unknown
227 ;; then nullification is not allowed.
228 (define_delay (eq_attr "type" "cbranch")
229   [(eq_attr "in_branch_delay" "true")
230    (and (eq_attr "in_nullified_branch_delay" "true")
231         (attr_flag "forward"))
232    (and (eq_attr "in_nullified_branch_delay" "true")
233         (attr_flag "backward"))])
235 (define_delay (eq_attr "type" "uncond_branch")
236   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
238 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
239 ;; load: 2, fpload: 3
240 ;; store, fpstore: 3, no D-cache operations should be scheduled.
242 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
243 ;; Timings:
244 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
245 ;; fcpy         3       ALU     2
246 ;; fabs         3       ALU     2
247 ;; fadd         3       ALU     2
248 ;; fsub         3       ALU     2
249 ;; fcmp         3       ALU     2
250 ;; fcnv         3       ALU     2
251 ;; fmpyadd      3       ALU,MPY 2
252 ;; fmpysub      3       ALU,MPY 2
253 ;; fmpycfxt     3       ALU,MPY 2
254 ;; fmpy         3       MPY     2
255 ;; fmpyi        3       MPY     2
256 ;; fdiv,sgl     10      MPY     10
257 ;; fdiv,dbl     12      MPY     12
258 ;; fsqrt,sgl    14      MPY     14
259 ;; fsqrt,dbl    18      MPY     18
261 ;; We don't model fmpyadd/fmpysub properly as those instructions
262 ;; keep both the FP ALU and MPY units busy.  Given that these
263 ;; processors are obsolete, I'm not going to spend the time to
264 ;; model those instructions correctly.
266 (define_automaton "pa700")
267 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
269 (define_insn_reservation "W0" 4
270   (and (eq_attr "type" "fpcc")
271        (eq_attr "cpu" "700"))
272   "fpalu_700*2")
274 (define_insn_reservation "W1" 3
275   (and (eq_attr "type" "fpalu")
276        (eq_attr "cpu" "700"))
277   "fpalu_700*2")
279 (define_insn_reservation "W2" 3
280   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
281        (eq_attr "cpu" "700"))
282   "fpmpy_700*2")
284 (define_insn_reservation "W3" 10
285   (and (eq_attr "type" "fpdivsgl")
286        (eq_attr "cpu" "700"))
287   "fpmpy_700*10")
289 (define_insn_reservation "W4" 12
290   (and (eq_attr "type" "fpdivdbl")
291        (eq_attr "cpu" "700"))
292   "fpmpy_700*12")
294 (define_insn_reservation "W5" 14
295   (and (eq_attr "type" "fpsqrtsgl")
296        (eq_attr "cpu" "700"))
297   "fpmpy_700*14")
299 (define_insn_reservation "W6" 18
300   (and (eq_attr "type" "fpsqrtdbl")
301        (eq_attr "cpu" "700"))
302   "fpmpy_700*18")
304 (define_insn_reservation "W7" 2
305   (and (eq_attr "type" "load")
306        (eq_attr "cpu" "700"))
307   "mem_700")
309 (define_insn_reservation "W8" 2
310   (and (eq_attr "type" "fpload")
311        (eq_attr "cpu" "700"))
312   "mem_700")
314 (define_insn_reservation "W9" 3
315   (and (eq_attr "type" "store")
316        (eq_attr "cpu" "700"))
317   "mem_700*3")
319 (define_insn_reservation "W10" 3
320   (and (eq_attr "type" "fpstore")
321        (eq_attr "cpu" "700"))
322   "mem_700*3")
324 (define_insn_reservation "W11" 5
325   (and (eq_attr "type" "fpstore_load")
326        (eq_attr "cpu" "700"))
327   "mem_700*5")
329 (define_insn_reservation "W12" 6
330   (and (eq_attr "type" "store_fpload")
331        (eq_attr "cpu" "700"))
332   "mem_700*6")
334 (define_insn_reservation "W13" 1
335   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
336        (eq_attr "cpu" "700"))
337   "dummy_700")
339 ;; We have a bypass for all computations in the FP unit which feed an
340 ;; FP store as long as the sizes are the same.
341 (define_bypass 2 "W1,W2" "W10,W11" "pa_fpstore_bypass_p")
342 (define_bypass 9 "W3" "W10,W11" "pa_fpstore_bypass_p")
343 (define_bypass 11 "W4" "W10,W11" "pa_fpstore_bypass_p")
344 (define_bypass 13 "W5" "W10,W11" "pa_fpstore_bypass_p")
345 (define_bypass 17 "W6" "W10,W11" "pa_fpstore_bypass_p")
347 ;; We have an "anti-bypass" for FP loads which feed an FP store.
348 (define_bypass 4 "W8,W12" "W10,W11" "pa_fpstore_bypass_p")
350 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
351 ;; floating point computations with non-floating point computations (fp loads
352 ;; and stores are not fp computations).
354 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
355 ;; take two cycles, during which no Dcache operations should be scheduled.
356 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
357 ;; all have the same memory characteristics if one disregards cache misses.
359 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
360 ;; There's no value in modeling the ALU and MUL separately though
361 ;; since there can never be a functional unit conflict given the
362 ;; latency and issue rates for those units.
364 ;; Timings:
365 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
366 ;; fcpy         2       ALU     1
367 ;; fabs         2       ALU     1
368 ;; fadd         2       ALU     1
369 ;; fsub         2       ALU     1
370 ;; fcmp         2       ALU     1
371 ;; fcnv         2       ALU     1
372 ;; fmpyadd      2       ALU,MPY 1
373 ;; fmpysub      2       ALU,MPY 1
374 ;; fmpycfxt     2       ALU,MPY 1
375 ;; fmpy         2       MPY     1
376 ;; fmpyi        2       MPY     1
377 ;; fdiv,sgl     8       DIV     8
378 ;; fdiv,dbl     15      DIV     15
379 ;; fsqrt,sgl    8       DIV     8
380 ;; fsqrt,dbl    15      DIV     15
382 (define_automaton "pa7100")
383 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
385 (define_insn_reservation "X0" 2
386   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
387        (eq_attr "cpu" "7100"))
388   "f_7100,fpmac_7100")
390 (define_insn_reservation "X1" 8
391   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
392        (eq_attr "cpu" "7100"))
393   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
395 (define_insn_reservation "X2" 15
396   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
397        (eq_attr "cpu" "7100"))
398   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
400 (define_insn_reservation "X3" 2
401   (and (eq_attr "type" "load")
402        (eq_attr "cpu" "7100"))
403   "i_7100+mem_7100")
405 (define_insn_reservation "X4" 2
406   (and (eq_attr "type" "fpload")
407        (eq_attr "cpu" "7100"))
408   "i_7100+mem_7100")
410 (define_insn_reservation "X5" 2
411   (and (eq_attr "type" "store")
412        (eq_attr "cpu" "7100"))
413   "i_7100+mem_7100,mem_7100")
415 (define_insn_reservation "X6" 2
416   (and (eq_attr "type" "fpstore")
417        (eq_attr "cpu" "7100"))
418   "i_7100+mem_7100,mem_7100")
420 (define_insn_reservation "X7" 4
421   (and (eq_attr "type" "fpstore_load")
422        (eq_attr "cpu" "7100"))
423   "i_7100+mem_7100,mem_7100*3")
425 (define_insn_reservation "X8" 4
426   (and (eq_attr "type" "store_fpload")
427        (eq_attr "cpu" "7100"))
428   "i_7100+mem_7100,mem_7100*3")
430 (define_insn_reservation "X9" 1
431   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,fpstore_load,store_fpload")
432        (eq_attr "cpu" "7100"))
433   "i_7100")
435 ;; We have a bypass for all computations in the FP unit which feed an
436 ;; FP store as long as the sizes are the same.
437 (define_bypass 1 "X0" "X6,X7" "pa_fpstore_bypass_p")
438 (define_bypass 7 "X1" "X6,X7" "pa_fpstore_bypass_p")
439 (define_bypass 14 "X2" "X6,X7" "pa_fpstore_bypass_p")
441 ;; We have an "anti-bypass" for FP loads which feed an FP store.
442 (define_bypass 3 "X4,X8" "X6,X7" "pa_fpstore_bypass_p")
444 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
445 ;; There's no value in modeling the ALU and MUL separately though
446 ;; since there can never be a functional unit conflict that
447 ;; can be avoided given the latency, issue rates and mandatory
448 ;; one cycle cpu-wide lock for a double precision fp multiply.
450 ;; Timings:
451 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
452 ;; fcpy         2       ALU     1
453 ;; fabs         2       ALU     1
454 ;; fadd         2       ALU     1
455 ;; fsub         2       ALU     1
456 ;; fcmp         2       ALU     1
457 ;; fcnv         2       ALU     1
458 ;; fmpyadd,sgl  2       ALU,MPY 1
459 ;; fmpyadd,dbl  3       ALU,MPY 2
460 ;; fmpysub,sgl  2       ALU,MPY 1
461 ;; fmpysub,dbl  3       ALU,MPY 2
462 ;; fmpycfxt,sgl 2       ALU,MPY 1
463 ;; fmpycfxt,dbl 3       ALU,MPY 2
464 ;; fmpy,sgl     2       MPY     1
465 ;; fmpy,dbl     3       MPY     2
466 ;; fmpyi        3       MPY     2
467 ;; fdiv,sgl     8       DIV     8
468 ;; fdiv,dbl     15      DIV     15
469 ;; fsqrt,sgl    8       DIV     8
470 ;; fsqrt,dbl    15      DIV     15
472 ;; The PA7200 is just like the PA7100LC except that there is
473 ;; no store-store penalty.
475 ;; The PA7300 is just like the PA7200 except that there is
476 ;; no store-load penalty.
478 ;; Note there are some aspects of the 7100LC we are not modeling
479 ;; at the moment.  I'll be reviewing the 7100LC scheduling info
480 ;; shortly and updating this description.
482 ;;   load-load pairs
483 ;;   store-store pairs
484 ;;   other issue modeling
486 (define_automaton "pa7100lc")
487 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
488 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
489 (define_cpu_unit "mem_7100lc" "pa7100lc")
491 ;; Double precision multiplies lock the entire CPU for one
492 ;; cycle.  There is no way to avoid this lock and trying to
493 ;; schedule around the lock is pointless and thus there is no
494 ;; value in trying to model this lock.
496 ;; Not modeling the lock allows us to treat fp multiplies just
497 ;; like any other FP alu instruction.  It allows for a smaller
498 ;; DFA and may reduce register pressure.
499 (define_insn_reservation "Y0" 2
500   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
501        (eq_attr "cpu" "7100LC,7200,7300"))
502   "f_7100lc,fpmac_7100lc")
504 ;; fp division and sqrt instructions lock the entire CPU for
505 ;; 7 cycles (single precision) or 14 cycles (double precision).
506 ;; There is no way to avoid this lock and trying to schedule
507 ;; around the lock is pointless and thus there is no value in
508 ;; trying to model this lock.  Not modeling the lock allows
509 ;; for a smaller DFA and may reduce register pressure.
510 (define_insn_reservation "Y1" 1
511   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
512        (eq_attr "cpu" "7100LC,7200,7300"))
513   "f_7100lc")
515 (define_insn_reservation "Y2" 2
516   (and (eq_attr "type" "load")
517        (eq_attr "cpu" "7100LC,7200,7300"))
518   "i1_7100lc+mem_7100lc")
520 (define_insn_reservation "Y3" 2
521   (and (eq_attr "type" "fpload")
522        (eq_attr "cpu" "7100LC,7200,7300"))
523   "i1_7100lc+mem_7100lc")
525 (define_insn_reservation "Y4" 2
526   (and (eq_attr "type" "store")
527        (eq_attr "cpu" "7100LC"))
528   "i1_7100lc+mem_7100lc,mem_7100lc")
530 (define_insn_reservation "Y5" 2
531   (and (eq_attr "type" "fpstore")
532        (eq_attr "cpu" "7100LC"))
533   "i1_7100lc+mem_7100lc,mem_7100lc")
535 (define_insn_reservation "Y6" 4
536   (and (eq_attr "type" "fpstore_load")
537        (eq_attr "cpu" "7100LC"))
538   "i1_7100lc+mem_7100lc,mem_7100lc*3")
540 (define_insn_reservation "Y7" 4
541   (and (eq_attr "type" "store_fpload")
542        (eq_attr "cpu" "7100LC"))
543   "i1_7100lc+mem_7100lc,mem_7100lc*3")
545 (define_insn_reservation "Y8" 1
546   (and (eq_attr "type" "shift,nullshift")
547        (eq_attr "cpu" "7100LC,7200,7300"))
548   "i1_7100lc")
550 (define_insn_reservation "Y9" 1
551   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
552        (eq_attr "cpu" "7100LC,7200,7300"))
553   "(i0_7100lc|i1_7100lc)")
555 ;; The 7200 has a store-load penalty
556 (define_insn_reservation "Y10" 2
557   (and (eq_attr "type" "store")
558        (eq_attr "cpu" "7200"))
559   "i1_7100lc,mem_7100lc")
561 (define_insn_reservation "Y11" 2
562   (and (eq_attr "type" "fpstore")
563        (eq_attr "cpu" "7200"))
564   "i1_7100lc,mem_7100lc")
566 (define_insn_reservation "Y12" 4
567   (and (eq_attr "type" "fpstore_load")
568        (eq_attr "cpu" "7200"))
569   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
571 (define_insn_reservation "Y13" 4
572   (and (eq_attr "type" "store_fpload")
573        (eq_attr "cpu" "7200"))
574   "i1_7100lc,mem_7100lc,i1_7100lc+mem_7100lc")
576 ;; The 7300 has no penalty for store-store or store-load
577 (define_insn_reservation "Y14" 2
578   (and (eq_attr "type" "store")
579        (eq_attr "cpu" "7300"))
580   "i1_7100lc")
582 (define_insn_reservation "Y15" 2
583   (and (eq_attr "type" "fpstore")
584        (eq_attr "cpu" "7300"))
585   "i1_7100lc")
587 (define_insn_reservation "Y16" 4
588   (and (eq_attr "type" "fpstore_load")
589        (eq_attr "cpu" "7300"))
590   "i1_7100lc,i1_7100lc+mem_7100lc")
592 (define_insn_reservation "Y17" 4
593   (and (eq_attr "type" "store_fpload")
594        (eq_attr "cpu" "7300"))
595   "i1_7100lc,i1_7100lc+mem_7100lc")
597 ;; We have an "anti-bypass" for FP loads which feed an FP store.
598 (define_bypass 3 "Y3,Y7,Y13,Y17" "Y5,Y6,Y11,Y12,Y15,Y16" "pa_fpstore_bypass_p")
600 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
601 ;; traditional architecture.
603 ;; The PA8000 has a large (56) entry reorder buffer that is split between
604 ;; memory and non-memory operations.
606 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
607 ;; the function units, with the exception of branches and multi-output
608 ;; instructions.  The PA8000 can retire two non-memory operations per cycle
609 ;; and two memory operations per cycle, only one of which may be a store.
611 ;; Given the large reorder buffer, the processor can hide most latencies.
612 ;; According to HP, they've got the best results by scheduling for retirement
613 ;; bandwidth with limited latency scheduling for floating point operations.
614 ;; Latency for integer operations and memory references is ignored.
617 ;; We claim floating point operations have a 2 cycle latency and are
618 ;; fully pipelined, except for div and sqrt which are not pipelined and
619 ;; take from 17 to 31 cycles to complete.
621 ;; It's worth noting that there is no way to saturate all the functional
622 ;; units on the PA8000 as there is not enough issue bandwidth.
624 (define_automaton "pa8000")
625 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
626 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
627 (define_cpu_unit "store_8000" "pa8000")
628 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
629 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
630 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
631 (define_reservation "im_8000" "im0_8000 | im1_8000")
632 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
633 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
634 (define_reservation "f_8000" "f0_8000 | f1_8000")
635 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
637 ;; We can issue any two memops per cycle, but we can only retire
638 ;; one memory store per cycle.  We assume that the reorder buffer
639 ;; will hide any memory latencies per HP's recommendation.
640 (define_insn_reservation "Z0" 0
641   (and
642     (eq_attr "type" "load,fpload")
643     (eq_attr "cpu" "8000"))
644   "im_8000,rm_8000")
646 (define_insn_reservation "Z1" 0
647   (and
648     (eq_attr "type" "store,fpstore")
649     (eq_attr "cpu" "8000"))
650   "im_8000,rm_8000+store_8000")
652 (define_insn_reservation "Z2" 0
653   (and (eq_attr "type" "fpstore_load,store_fpload")
654        (eq_attr "cpu" "8000"))
655   "im_8000,rm_8000+store_8000,im_8000,rm_8000")
657 ;; We can issue and retire two non-memory operations per cycle with
658 ;; a few exceptions (branches).  This group catches those we want
659 ;; to assume have zero latency.
660 (define_insn_reservation "Z3" 0
661   (and
662     (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")
663     (eq_attr "cpu" "8000"))
664   "inm_8000,rnm_8000")
666 ;; Branches use both slots in the non-memory issue and
667 ;; retirement unit.
668 (define_insn_reservation "Z4" 0
669   (and
670     (eq_attr "type" "uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
671     (eq_attr "cpu" "8000"))
672   "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
674 ;; We partial latency schedule the floating point units.
675 ;; They can issue/retire two at a time in the non-memory
676 ;; units.  We fix their latency at 2 cycles and they
677 ;; are fully pipelined.
678 (define_insn_reservation "Z5" 1
679  (and
680    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
681    (eq_attr "cpu" "8000"))
682  "inm_8000,f_8000,rnm_8000")
684 ;; The fdivsqrt units are not pipelined and have a very long latency.  
685 ;; To keep the DFA from exploding, we do not show all the
686 ;; reservations for the divsqrt unit.
687 (define_insn_reservation "Z6" 17
688  (and
689    (eq_attr "type" "fpdivsgl,fpsqrtsgl")
690    (eq_attr "cpu" "8000"))
691  "inm_8000,fdivsqrt_8000*6,rnm_8000")
693 (define_insn_reservation "Z7" 31
694  (and
695    (eq_attr "type" "fpdivdbl,fpsqrtdbl")
696    (eq_attr "cpu" "8000"))
697  "inm_8000,fdivsqrt_8000*6,rnm_8000")
699 ;; Operand and operator predicates and constraints
701 (include "predicates.md")
702 (include "constraints.md")
704 ;; Compare instructions.
705 ;; This controls RTL generation and register allocation.
707 (define_insn ""
708   [(set (reg:CCFP 0)
709         (match_operator:CCFP 2 "comparison_operator"
710                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
711                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
712   "! TARGET_SOFT_FLOAT"
713   "fcmp,sgl,%Y2 %f0,%f1"
714   [(set_attr "length" "4")
715    (set_attr "type" "fpcc")])
717 (define_insn ""
718   [(set (reg:CCFP 0)
719         (match_operator:CCFP 2 "comparison_operator"
720                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
721                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
722   "! TARGET_SOFT_FLOAT"
723   "fcmp,dbl,%Y2 %f0,%f1"
724   [(set_attr "length" "4")
725    (set_attr "type" "fpcc")])
727 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
728 ;; placeholders.  This is necessary in rare situations when a
729 ;; placeholder is re-emitted (see PR 8705).
731 (define_expand "movccfp"
732   [(set (reg:CCFP 0)
733         (match_operand 0 "const_int_operand" ""))]
734   "! TARGET_SOFT_FLOAT"
735   "
737   if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
738     FAIL;
741 ;; The following patterns are optimization placeholders.  In almost
742 ;; all cases, the user of the condition code will be simplified and the
743 ;; original condition code setting insn should be eliminated.
745 (define_insn "*movccfp0"
746   [(set (reg:CCFP 0)
747         (const_int 0))]
748   "! TARGET_SOFT_FLOAT"
749   "fcmp,dbl,= %%fr0,%%fr0"
750   [(set_attr "length" "4")
751    (set_attr "type" "fpcc")])
753 (define_insn "*movccfp1"
754   [(set (reg:CCFP 0)
755         (const_int 1))]
756   "! TARGET_SOFT_FLOAT"
757   "fcmp,dbl,!= %%fr0,%%fr0"
758   [(set_attr "length" "4")
759    (set_attr "type" "fpcc")])
761 ;; scc insns.
763 (define_expand "cstoresi4"
764   [(set (match_operand:SI 0 "register_operand")
765         (match_operator:SI 1 "ordered_comparison_operator"
766          [(match_operand:SI 2 "reg_or_0_operand" "")
767           (match_operand:SI 3 "arith5_operand" "")]))]
768   "!TARGET_64BIT"
769   "")
771 ;; Instruction canonicalization puts immediate operands second, which
772 ;; is the reverse of what we want.
774 (define_insn "scc"
775   [(set (match_operand:SI 0 "register_operand" "=r")
776         (match_operator:SI 3 "ordered_comparison_operator"
777                            [(match_operand:SI 1 "reg_or_0_operand" "rM")
778                             (match_operand:SI 2 "arith11_operand" "rI")]))]
779   ""
780   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi 1,%0"
781   [(set_attr "type" "binary")
782    (set_attr "length" "8")])
784 (define_insn ""
785   [(set (match_operand:DI 0 "register_operand" "=r")
786         (match_operator:DI 3 "ordered_comparison_operator"
787                            [(match_operand:DI 1 "reg_or_0_operand" "rM")
788                             (match_operand:DI 2 "arith11_operand" "rI")]))]
789   "TARGET_64BIT"
790   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi 1,%0"
791   [(set_attr "type" "binary")
792    (set_attr "length" "8")])
794 (define_insn "iorscc"
795   [(set (match_operand:SI 0 "register_operand" "=r")
796         (ior:SI (match_operator:SI 3 "ordered_comparison_operator"
797                                    [(match_operand:SI 1 "reg_or_0_operand" "rM")
798                                     (match_operand:SI 2 "arith11_operand" "rI")])
799                 (match_operator:SI 6 "ordered_comparison_operator"
800                                    [(match_operand:SI 4 "reg_or_0_operand" "rM")
801                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
802   ""
803   "{com%I2clr|cmp%I2clr},%S3 %2,%r1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%r4,%0\;ldi 1,%0"
804   [(set_attr "type" "binary")
805    (set_attr "length" "12")])
807 (define_insn ""
808   [(set (match_operand:DI 0 "register_operand" "=r")
809         (ior:DI (match_operator:DI 3 "ordered_comparison_operator"
810                                    [(match_operand:DI 1 "reg_or_0_operand" "rM")
811                                     (match_operand:DI 2 "arith11_operand" "rI")])
812                 (match_operator:DI 6 "ordered_comparison_operator"
813                                    [(match_operand:DI 4 "reg_or_0_operand" "rM")
814                                     (match_operand:DI 5 "arith11_operand" "rI")])))]
815   "TARGET_64BIT"
816   "cmp%I2clr,*%S3 %2,%r1,%%r0\;cmp%I5clr,*%B6 %5,%r4,%0\;ldi 1,%0"
817   [(set_attr "type" "binary")
818    (set_attr "length" "12")])
820 ;; Combiner patterns for common operations performed with the output
821 ;; from an scc insn (negscc and incscc).
822 (define_insn "negscc"
823   [(set (match_operand:SI 0 "register_operand" "=r")
824         (neg:SI (match_operator:SI 3 "ordered_comparison_operator"
825                [(match_operand:SI 1 "reg_or_0_operand" "rM")
826                 (match_operand:SI 2 "arith11_operand" "rI")])))]
827   ""
828   "{com%I2clr|cmp%I2clr},%B3 %2,%r1,%0\;ldi -1,%0"
829   [(set_attr "type" "binary")
830    (set_attr "length" "8")])
832 (define_insn ""
833   [(set (match_operand:DI 0 "register_operand" "=r")
834         (neg:DI (match_operator:DI 3 "ordered_comparison_operator"
835                [(match_operand:DI 1 "reg_or_0_operand" "rM")
836                 (match_operand:DI 2 "arith11_operand" "rI")])))]
837   "TARGET_64BIT"
838   "cmp%I2clr,*%B3 %2,%r1,%0\;ldi -1,%0"
839   [(set_attr "type" "binary")
840    (set_attr "length" "8")])
842 ;; Patterns for adding/subtracting the result of a boolean expression from
843 ;; a register.  First we have special patterns that make use of the carry
844 ;; bit, and output only two instructions.  For the cases we can't in
845 ;; general do in two instructions, the incscc pattern at the end outputs
846 ;; two or three instructions.
848 (define_insn ""
849   [(set (match_operand:SI 0 "register_operand" "=r")
850         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
851                          (match_operand:SI 3 "arith11_operand" "rI"))
852                  (match_operand:SI 1 "register_operand" "r")))]
853   ""
854   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
855   [(set_attr "type" "binary")
856    (set_attr "length" "8")])
858 (define_insn ""
859   [(set (match_operand:DI 0 "register_operand" "=r")
860         (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
861                          (match_operand:DI 3 "arith11_operand" "rI"))
862                  (match_operand:DI 1 "register_operand" "r")))]
863   "TARGET_64BIT"
864   "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
865   [(set_attr "type" "binary")
866    (set_attr "length" "8")])
868 ; This need only accept registers for op3, since canonicalization
869 ; replaces geu with gtu when op3 is an integer.
870 (define_insn ""
871   [(set (match_operand:SI 0 "register_operand" "=r")
872         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
873                          (match_operand:SI 3 "register_operand" "r"))
874                  (match_operand:SI 1 "register_operand" "r")))]
875   ""
876   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
877   [(set_attr "type" "binary")
878    (set_attr "length" "8")])
880 (define_insn ""
881   [(set (match_operand:DI 0 "register_operand" "=r")
882         (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
883                          (match_operand:DI 3 "register_operand" "r"))
884                  (match_operand:DI 1 "register_operand" "r")))]
885   "TARGET_64BIT"
886   "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
887   [(set_attr "type" "binary")
888    (set_attr "length" "8")])
890 ; Match only integers for op3 here.  This is used as canonical form of the
891 ; geu pattern when op3 is an integer.  Don't match registers since we can't
892 ; make better code than the general incscc pattern.
893 (define_insn ""
894   [(set (match_operand:SI 0 "register_operand" "=r")
895         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
896                          (match_operand:SI 3 "int11_operand" "I"))
897                  (match_operand:SI 1 "register_operand" "r")))]
898   ""
899   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
900   [(set_attr "type" "binary")
901    (set_attr "length" "8")])
903 (define_insn ""
904   [(set (match_operand:DI 0 "register_operand" "=r")
905         (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
906                          (match_operand:DI 3 "int11_operand" "I"))
907                  (match_operand:DI 1 "register_operand" "r")))]
908   "TARGET_64BIT"
909   "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
910   [(set_attr "type" "binary")
911    (set_attr "length" "8")])
913 (define_insn "incscc"
914   [(set (match_operand:SI 0 "register_operand" "=r,r")
915         (plus:SI (match_operator:SI 4 "ordered_comparison_operator"
916                     [(match_operand:SI 2 "register_operand" "r,r")
917                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
918                  (match_operand:SI 1 "register_operand" "0,?r")))]
919   ""
920   "@
921    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
922    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
923   [(set_attr "type" "binary,binary")
924    (set_attr "length" "8,12")])
926 (define_insn ""
927   [(set (match_operand:DI 0 "register_operand" "=r,r")
928         (plus:DI (match_operator:DI 4 "ordered_comparison_operator"
929                     [(match_operand:DI 2 "register_operand" "r,r")
930                      (match_operand:DI 3 "arith11_operand" "rI,rI")])
931                  (match_operand:DI 1 "register_operand" "0,?r")))]
932   "TARGET_64BIT"
933   "@
934    cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
935    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
936   [(set_attr "type" "binary,binary")
937    (set_attr "length" "8,12")])
939 (define_insn ""
940   [(set (match_operand:SI 0 "register_operand" "=r")
941         (minus:SI (match_operand:SI 1 "register_operand" "r")
942                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
943                           (match_operand:SI 3 "arith11_operand" "rI"))))]
944   ""
945   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
946   [(set_attr "type" "binary")
947    (set_attr "length" "8")])
949 (define_insn ""
950   [(set (match_operand:DI 0 "register_operand" "=r")
951         (minus:DI (match_operand:DI 1 "register_operand" "r")
952                   (gtu:DI (match_operand:DI 2 "register_operand" "r")
953                           (match_operand:DI 3 "arith11_operand" "rI"))))]
954   "TARGET_64BIT"
955   "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
956   [(set_attr "type" "binary")
957    (set_attr "length" "8")])
959 (define_insn ""
960   [(set (match_operand:SI 0 "register_operand" "=r")
961         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
962                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
963                                     (match_operand:SI 3 "arith11_operand" "rI")))
964                   (match_operand:SI 4 "register_operand" "r")))]
965   ""
966   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
967   [(set_attr "type" "binary")
968    (set_attr "length" "8")])
970 (define_insn ""
971   [(set (match_operand:DI 0 "register_operand" "=r")
972         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
973                             (gtu:DI (match_operand:DI 2 "register_operand" "r")
974                                     (match_operand:DI 3 "arith11_operand" "rI")))
975                   (match_operand:DI 4 "register_operand" "r")))]
976   "TARGET_64BIT"
977   "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
978   [(set_attr "type" "binary")
979    (set_attr "length" "8")])
981 ; This need only accept registers for op3, since canonicalization
982 ; replaces ltu with leu when op3 is an integer.
983 (define_insn ""
984   [(set (match_operand:SI 0 "register_operand" "=r")
985         (minus:SI (match_operand:SI 1 "register_operand" "r")
986                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
987                           (match_operand:SI 3 "register_operand" "r"))))]
988   ""
989   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
990   [(set_attr "type" "binary")
991    (set_attr "length" "8")])
993 (define_insn ""
994   [(set (match_operand:DI 0 "register_operand" "=r")
995         (minus:DI (match_operand:DI 1 "register_operand" "r")
996                   (ltu:DI (match_operand:DI 2 "register_operand" "r")
997                           (match_operand:DI 3 "register_operand" "r"))))]
998   "TARGET_64BIT"
999   "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
1000   [(set_attr "type" "binary")
1001    (set_attr "length" "8")])
1003 (define_insn ""
1004   [(set (match_operand:SI 0 "register_operand" "=r")
1005         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1006                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
1007                                     (match_operand:SI 3 "register_operand" "r")))
1008                   (match_operand:SI 4 "register_operand" "r")))]
1009   ""
1010   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1011   [(set_attr "type" "binary")
1012    (set_attr "length" "8")])
1014 (define_insn ""
1015   [(set (match_operand:DI 0 "register_operand" "=r")
1016         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1017                             (ltu:DI (match_operand:DI 2 "register_operand" "r")
1018                                     (match_operand:DI 3 "register_operand" "r")))
1019                   (match_operand:DI 4 "register_operand" "r")))]
1020   "TARGET_64BIT"
1021   "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1022   [(set_attr "type" "binary")
1023    (set_attr "length" "8")])
1025 ; Match only integers for op3 here.  This is used as canonical form of the
1026 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
1027 ; make better code than the general incscc pattern.
1028 (define_insn ""
1029   [(set (match_operand:SI 0 "register_operand" "=r")
1030         (minus:SI (match_operand:SI 1 "register_operand" "r")
1031                   (leu:SI (match_operand:SI 2 "register_operand" "r")
1032                           (match_operand:SI 3 "int11_operand" "I"))))]
1033   ""
1034   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1035   [(set_attr "type" "binary")
1036    (set_attr "length" "8")])
1038 (define_insn ""
1039   [(set (match_operand:DI 0 "register_operand" "=r")
1040         (minus:DI (match_operand:DI 1 "register_operand" "r")
1041                   (leu:DI (match_operand:DI 2 "register_operand" "r")
1042                           (match_operand:DI 3 "int11_operand" "I"))))]
1043   "TARGET_64BIT"
1044   "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1045   [(set_attr "type" "binary")
1046    (set_attr "length" "8")])
1048 (define_insn ""
1049   [(set (match_operand:SI 0 "register_operand" "=r")
1050         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1051                             (leu:SI (match_operand:SI 2 "register_operand" "r")
1052                                     (match_operand:SI 3 "int11_operand" "I")))
1053                   (match_operand:SI 4 "register_operand" "r")))]
1054   ""
1055   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1056   [(set_attr "type" "binary")
1057    (set_attr "length" "8")])
1059 (define_insn ""
1060   [(set (match_operand:DI 0 "register_operand" "=r")
1061         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1062                             (leu:DI (match_operand:DI 2 "register_operand" "r")
1063                                     (match_operand:DI 3 "int11_operand" "I")))
1064                   (match_operand:DI 4 "register_operand" "r")))]
1065   "TARGET_64BIT"
1066   "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1067   [(set_attr "type" "binary")
1068    (set_attr "length" "8")])
1070 (define_insn "decscc"
1071   [(set (match_operand:SI 0 "register_operand" "=r,r")
1072         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1073                   (match_operator:SI 4 "ordered_comparison_operator"
1074                      [(match_operand:SI 2 "register_operand" "r,r")
1075                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1076   ""
1077   "@
1078    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1079    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1080   [(set_attr "type" "binary,binary")
1081    (set_attr "length" "8,12")])
1083 (define_insn ""
1084   [(set (match_operand:DI 0 "register_operand" "=r,r")
1085         (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1086                   (match_operator:DI 4 "ordered_comparison_operator"
1087                      [(match_operand:DI 2 "register_operand" "r,r")
1088                       (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1089   "TARGET_64BIT"
1090   "@
1091    cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1092    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1093   [(set_attr "type" "binary,binary")
1094    (set_attr "length" "8,12")])
1096 ; Patterns for max and min.  (There is no need for an earlyclobber in the
1097 ; last alternative since the middle alternative will match if op0 == op1.)
1099 (define_insn "sminsi3"
1100   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1101         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1102                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1103   ""
1104   "@
1105   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1106   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1107   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1108 [(set_attr "type" "multi,multi,multi")
1109  (set_attr "length" "8,8,8")])
1111 (define_insn "smindi3"
1112   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1113         (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1114                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1115   "TARGET_64BIT"
1116   "@
1117   cmpclr,*> %2,%0,%%r0\;copy %2,%0
1118   cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1119   cmpclr,*> %1,%r2,%0\;copy %1,%0"
1120 [(set_attr "type" "multi,multi,multi")
1121  (set_attr "length" "8,8,8")])
1123 (define_insn "uminsi3"
1124   [(set (match_operand:SI 0 "register_operand" "=r,r")
1125         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1126                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1127   ""
1128   "@
1129   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1130   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1131 [(set_attr "type" "multi,multi")
1132  (set_attr "length" "8,8")])
1134 (define_insn "umindi3"
1135   [(set (match_operand:DI 0 "register_operand" "=r,r")
1136         (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1137                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1138   "TARGET_64BIT"
1139   "@
1140   cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1141   cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1142 [(set_attr "type" "multi,multi")
1143  (set_attr "length" "8,8")])
1145 (define_insn "smaxsi3"
1146   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1147         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1148                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1149   ""
1150   "@
1151   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1152   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1153   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1154 [(set_attr "type" "multi,multi,multi")
1155  (set_attr "length" "8,8,8")])
1157 (define_insn "smaxdi3"
1158   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1159         (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1160                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1161   "TARGET_64BIT"
1162   "@
1163   cmpclr,*< %2,%0,%%r0\;copy %2,%0
1164   cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1165   cmpclr,*< %1,%r2,%0\;copy %1,%0"
1166 [(set_attr "type" "multi,multi,multi")
1167  (set_attr "length" "8,8,8")])
1169 (define_insn "umaxsi3"
1170   [(set (match_operand:SI 0 "register_operand" "=r,r")
1171         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1172                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1173   ""
1174   "@
1175   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1176   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1177 [(set_attr "type" "multi,multi")
1178  (set_attr "length" "8,8")])
1180 (define_insn "umaxdi3"
1181   [(set (match_operand:DI 0 "register_operand" "=r,r")
1182         (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1183                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1184   "TARGET_64BIT"
1185   "@
1186   cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1187   cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1188 [(set_attr "type" "multi,multi")
1189  (set_attr "length" "8,8")])
1191 (define_insn "absqi2"
1192   [(set (match_operand:QI 0 "register_operand" "=r")
1193         (abs:QI (match_operand:QI 1 "register_operand" "r")))]
1194   ""
1195   "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0"
1196   [(set_attr "type" "multi")
1197    (set_attr "length" "8")])
1199 (define_insn "abshi2"
1200   [(set (match_operand:HI 0 "register_operand" "=r")
1201         (abs:HI (match_operand:HI 1 "register_operand" "r")))]
1202   ""
1203   "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0"
1204   [(set_attr "type" "multi")
1205    (set_attr "length" "8")])
1207 (define_insn "abssi2"
1208   [(set (match_operand:SI 0 "register_operand" "=r")
1209         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1210   ""
1211   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1212   [(set_attr "type" "multi")
1213    (set_attr "length" "8")])
1215 (define_insn "absdi2"
1216   [(set (match_operand:DI 0 "register_operand" "=r")
1217         (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1218   "TARGET_64BIT"
1219   "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1220   [(set_attr "type" "multi")
1221    (set_attr "length" "8")])
1223 (define_insn "bswaphi2"
1224   [(set (match_operand:HI 0 "register_operand" "=&r")
1225         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
1226   ""
1227   "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0"
1228   [(set_attr "type" "multi")
1229    (set_attr "length" "8")])
1231 (define_insn "bswapsi2"
1232   [(set (match_operand:SI 0 "register_operand" "=&r")
1233         (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
1234   ""
1235   "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0"
1236   [(set_attr "type" "multi")
1237    (set_attr "length" "12")])
1239 (define_insn "bswapdi2"
1240   [(set (match_operand:DI 0 "register_operand" "=&r")
1241         (bswap:DI (match_operand:DI 1 "register_operand" "r")))
1242    (clobber (match_scratch:DI 2 "=r"))]
1243   "TARGET_64BIT"
1244   "permh,3210 %1,%2\;hshl %2,8,%0\;hshr,u %2,8,%2\;or %0,%2,%0"
1245   [(set_attr "type" "multi")
1246    (set_attr "length" "16")])
1248 ;;; Experimental conditional move patterns
1250 (define_expand "movsicc"
1251   [(set (match_operand:SI 0 "register_operand" "")
1252         (if_then_else:SI
1253          (match_operand 1 "ordered_comparison_operator" "")
1254          (match_operand:SI 2 "reg_or_cint_move_operand" "")
1255          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1256   ""
1257   "
1259   if (GET_MODE (XEXP (operands[1], 0)) != SImode
1260       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1261     FAIL;
1264 ;; We used to accept any register for op1.
1266 ;; However, it loses sometimes because the compiler will end up using
1267 ;; different registers for op0 and op1 in some critical cases.  local-alloc
1268 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1270 ;; If/when global register allocation supports tying we should allow any
1271 ;; register for op1 again.
1272 (define_insn ""
1273   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1274         (if_then_else:SI
1275          (match_operator 2 "ordered_comparison_operator"
1276             [(match_operand:SI 3 "register_operand" "r,r,r,r")
1277              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1278          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1279          (const_int 0)))]
1280   ""
1281   "@
1282    {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1283    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1284    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1285    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1286   [(set_attr "type" "multi,multi,multi,nullshift")
1287    (set_attr "length" "8,8,8,8")])
1289 (define_insn ""
1290   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1291         (if_then_else:SI
1292          (match_operator 5 "ordered_comparison_operator"
1293             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1294              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1295          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1296          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1297   ""
1298   "@
1299    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1300    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1301    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1302    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1303    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1304    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1305    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1306    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1307   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1308    (set_attr "length" "8,8,8,8,8,8,8,8")])
1310 (define_expand "movdicc"
1311   [(set (match_operand:DI 0 "register_operand" "")
1312         (if_then_else:DI
1313          (match_operand 1 "ordered_comparison_operator" "")
1314          (match_operand:DI 2 "reg_or_cint_move_operand" "")
1315          (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1316   "TARGET_64BIT"
1317   "
1319   if (GET_MODE (XEXP (operands[1], 0)) != DImode
1320       || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
1321     FAIL;
1324 ; We need the first constraint alternative in order to avoid
1325 ; earlyclobbers on all other alternatives.
1326 (define_insn ""
1327   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1328         (if_then_else:DI
1329          (match_operator 2 "ordered_comparison_operator"
1330             [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1331              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1332          (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1333          (const_int 0)))]
1334   "TARGET_64BIT"
1335   "@
1336    cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1337    cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1338    cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1339    cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1340    cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1341   [(set_attr "type" "multi,multi,multi,multi,nullshift")
1342    (set_attr "length" "8,8,8,8,8")])
1344 (define_insn ""
1345   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1346         (if_then_else:DI
1347          (match_operator 5 "ordered_comparison_operator"
1348             [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1349              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1350          (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1351          (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1352   "TARGET_64BIT"
1353   "@
1354    cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1355    cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1356    cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1357    cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1358    cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1359    cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1360    cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1361    cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1362   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1363    (set_attr "length" "8,8,8,8,8,8,8,8")])
1365 ;; Conditional Branches
1367 (define_expand "cbranchdi4"
1368   [(set (pc)
1369         (if_then_else (match_operator 0 "ordered_comparison_operator"
1370                        [(match_operand:DI 1 "reg_or_0_operand" "")
1371                         (match_operand:DI 2 "register_operand" "")])
1372                       (label_ref (match_operand 3 "" ""))
1373                       (pc)))]
1374   "TARGET_64BIT"
1375   "")
1377 (define_expand "cbranchsi4"
1378   [(set (pc)
1379         (if_then_else (match_operator 0 "ordered_comparison_operator"
1380                        [(match_operand:SI 1 "reg_or_0_operand" "")
1381                         (match_operand:SI 2 "arith5_operand" "")])
1382                       (label_ref (match_operand 3 "" ""))
1383                       (pc)))]
1384   ""
1385   "")
1387 (define_expand "cbranchsf4"
1388   [(set (pc)
1389         (if_then_else (match_operator 0 "comparison_operator"
1390                        [(match_operand:SF 1 "reg_or_0_operand" "")
1391                         (match_operand:SF 2 "reg_or_0_operand" "")])
1392                       (label_ref (match_operand 3 "" ""))
1393                       (pc)))]
1394   "! TARGET_SOFT_FLOAT"
1395   "
1397   pa_emit_bcond_fp (operands);
1398   DONE;
1402 (define_expand "cbranchdf4"
1403   [(set (pc)
1404         (if_then_else (match_operator 0 "comparison_operator"
1405                        [(match_operand:DF 1 "reg_or_0_operand" "")
1406                         (match_operand:DF 2 "reg_or_0_operand" "")])
1407                       (label_ref (match_operand 3 "" ""))
1408                       (pc)))]
1409   "! TARGET_SOFT_FLOAT"
1410   "
1412   pa_emit_bcond_fp (operands);
1413   DONE;
1416 ;; Match the branch patterns.
1419 ;; Note a long backward conditional branch with an annulled delay slot
1420 ;; has a length of 12.
1421 (define_insn ""
1422   [(set (pc)
1423         (if_then_else
1424          (match_operator 3 "ordered_comparison_operator"
1425                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1426                           (match_operand:SI 2 "arith5_operand" "rL")])
1427          (label_ref (match_operand 0 "" ""))
1428          (pc)))]
1429   ""
1430   "*
1432   return pa_output_cbranch (operands, 0, insn);
1434 [(set_attr "type" "cbranch")
1435  (set (attr "length")
1436     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1437                (const_int MAX_12BIT_OFFSET))
1438            (const_int 4)
1439            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1440                (const_int MAX_17BIT_OFFSET))
1441            (const_int 8)
1442            (match_test "TARGET_PORTABLE_RUNTIME")
1443            (const_int 24)
1444            (not (match_test "flag_pic"))
1445            (const_int 20)]
1446           (const_int 28)))])
1448 ;; Match the negated branch.
1450 (define_insn ""
1451   [(set (pc)
1452         (if_then_else
1453          (match_operator 3 "ordered_comparison_operator"
1454                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1455                           (match_operand:SI 2 "arith5_operand" "rL")])
1456          (pc)
1457          (label_ref (match_operand 0 "" ""))))]
1458   ""
1459   "*
1461   return pa_output_cbranch (operands, 1, insn);
1463 [(set_attr "type" "cbranch")
1464  (set (attr "length")
1465     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1466                (const_int MAX_12BIT_OFFSET))
1467            (const_int 4)
1468            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1469                (const_int MAX_17BIT_OFFSET))
1470            (const_int 8)
1471            (match_test "TARGET_PORTABLE_RUNTIME")
1472            (const_int 24)
1473            (not (match_test "flag_pic"))
1474            (const_int 20)]
1475           (const_int 28)))])
1477 (define_insn ""
1478   [(set (pc)
1479         (if_then_else
1480          (match_operator 3 "ordered_comparison_operator"
1481                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1482                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1483          (label_ref (match_operand 0 "" ""))
1484          (pc)))]
1485   "TARGET_64BIT"
1486   "*
1488   return pa_output_cbranch (operands, 0, insn);
1490 [(set_attr "type" "cbranch")
1491  (set (attr "length")
1492     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1493                (const_int MAX_12BIT_OFFSET))
1494            (const_int 4)
1495            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1496                (const_int MAX_17BIT_OFFSET))
1497            (const_int 8)
1498            (match_test "TARGET_PORTABLE_RUNTIME")
1499            (const_int 24)
1500            (not (match_test "flag_pic"))
1501            (const_int 20)]
1502           (const_int 28)))])
1504 ;; Match the negated branch.
1506 (define_insn ""
1507   [(set (pc)
1508         (if_then_else
1509          (match_operator 3 "ordered_comparison_operator"
1510                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1511                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1512          (pc)
1513          (label_ref (match_operand 0 "" ""))))]
1514   "TARGET_64BIT"
1515   "*
1517   return pa_output_cbranch (operands, 1, insn);
1519 [(set_attr "type" "cbranch")
1520  (set (attr "length")
1521     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1522                (const_int MAX_12BIT_OFFSET))
1523            (const_int 4)
1524            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1525                (const_int MAX_17BIT_OFFSET))
1526            (const_int 8)
1527            (match_test "TARGET_PORTABLE_RUNTIME")
1528            (const_int 24)
1529            (not (match_test "flag_pic"))
1530            (const_int 20)]
1531           (const_int 28)))])
1532 (define_insn ""
1533   [(set (pc)
1534         (if_then_else
1535          (match_operator 3 "cmpib_comparison_operator"
1536                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1537                           (match_operand:DI 2 "arith5_operand" "rL")])
1538          (label_ref (match_operand 0 "" ""))
1539          (pc)))]
1540   "TARGET_64BIT"
1541   "*
1543   return pa_output_cbranch (operands, 0, insn);
1545 [(set_attr "type" "cbranch")
1546  (set (attr "length")
1547     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1548                (const_int MAX_12BIT_OFFSET))
1549            (const_int 4)
1550            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1551                (const_int MAX_17BIT_OFFSET))
1552            (const_int 8)
1553            (match_test "TARGET_PORTABLE_RUNTIME")
1554            (const_int 24)
1555            (not (match_test "flag_pic"))
1556            (const_int 20)]
1557           (const_int 28)))])
1559 ;; Match the negated branch.
1561 (define_insn ""
1562   [(set (pc)
1563         (if_then_else
1564          (match_operator 3 "cmpib_comparison_operator"
1565                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1566                           (match_operand:DI 2 "arith5_operand" "rL")])
1567          (pc)
1568          (label_ref (match_operand 0 "" ""))))]
1569   "TARGET_64BIT"
1570   "*
1572   return pa_output_cbranch (operands, 1, insn);
1574 [(set_attr "type" "cbranch")
1575  (set (attr "length")
1576     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1577                (const_int MAX_12BIT_OFFSET))
1578            (const_int 4)
1579            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1580                (const_int MAX_17BIT_OFFSET))
1581            (const_int 8)
1582            (match_test "TARGET_PORTABLE_RUNTIME")
1583            (const_int 24)
1584            (not (match_test "flag_pic"))
1585            (const_int 20)]
1586           (const_int 28)))])
1588 ;; Branch on Bit patterns.
1589 (define_insn ""
1590   [(set (pc)
1591         (if_then_else
1592          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1593                               (const_int 1)
1594                               (match_operand:SI 1 "uint5_operand" ""))
1595              (const_int 0))
1596          (label_ref (match_operand 2 "" ""))
1597          (pc)))]
1598   ""
1599   "*
1601   return pa_output_bb (operands, 0, insn, 0);
1603 [(set_attr "type" "cbranch")
1604  (set (attr "length")
1605     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1606                (const_int MAX_12BIT_OFFSET))
1607            (const_int 4)
1608            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1609                (const_int MAX_17BIT_OFFSET))
1610            (const_int 8)
1611            (match_test "TARGET_PORTABLE_RUNTIME")
1612            (const_int 24)
1613            (not (match_test "flag_pic"))
1614            (const_int 20)]
1615           (const_int 28)))])
1617 (define_insn ""
1618   [(set (pc)
1619         (if_then_else
1620          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1621                               (const_int 1)
1622                               (match_operand:DI 1 "uint32_operand" ""))
1623              (const_int 0))
1624          (label_ref (match_operand 2 "" ""))
1625          (pc)))]
1626   "TARGET_64BIT"
1627   "*
1629   return pa_output_bb (operands, 0, insn, 0);
1631 [(set_attr "type" "cbranch")
1632  (set (attr "length")
1633     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1634                (const_int MAX_12BIT_OFFSET))
1635            (const_int 4)
1636            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1637                (const_int MAX_17BIT_OFFSET))
1638            (const_int 8)
1639            (match_test "TARGET_PORTABLE_RUNTIME")
1640            (const_int 24)
1641            (not (match_test "flag_pic"))
1642            (const_int 20)]
1643           (const_int 28)))])
1645 (define_insn ""
1646   [(set (pc)
1647         (if_then_else
1648          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1649                               (const_int 1)
1650                               (match_operand:SI 1 "uint5_operand" ""))
1651              (const_int 0))
1652          (pc)
1653          (label_ref (match_operand 2 "" ""))))]
1654   ""
1655   "*
1657   return pa_output_bb (operands, 1, insn, 0);
1659 [(set_attr "type" "cbranch")
1660  (set (attr "length")
1661     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1662                (const_int MAX_12BIT_OFFSET))
1663            (const_int 4)
1664            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1665                (const_int MAX_17BIT_OFFSET))
1666            (const_int 8)
1667            (match_test "TARGET_PORTABLE_RUNTIME")
1668            (const_int 24)
1669            (not (match_test "flag_pic"))
1670            (const_int 20)]
1671           (const_int 28)))])
1673 (define_insn ""
1674   [(set (pc)
1675         (if_then_else
1676          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1677                               (const_int 1)
1678                               (match_operand:DI 1 "uint32_operand" ""))
1679              (const_int 0))
1680          (pc)
1681          (label_ref (match_operand 2 "" ""))))]
1682   "TARGET_64BIT"
1683   "*
1685   return pa_output_bb (operands, 1, insn, 0);
1687 [(set_attr "type" "cbranch")
1688  (set (attr "length")
1689     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1690                (const_int MAX_12BIT_OFFSET))
1691            (const_int 4)
1692            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1693                (const_int MAX_17BIT_OFFSET))
1694            (const_int 8)
1695            (match_test "TARGET_PORTABLE_RUNTIME")
1696            (const_int 24)
1697            (not (match_test "flag_pic"))
1698            (const_int 20)]
1699           (const_int 28)))])
1701 (define_insn ""
1702   [(set (pc)
1703         (if_then_else
1704          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1705                               (const_int 1)
1706                               (match_operand:SI 1 "uint5_operand" ""))
1707              (const_int 0))
1708          (label_ref (match_operand 2 "" ""))
1709          (pc)))]
1710   ""
1711   "*
1713   return pa_output_bb (operands, 0, insn, 1);
1715 [(set_attr "type" "cbranch")
1716  (set (attr "length")
1717     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1718                (const_int MAX_12BIT_OFFSET))
1719            (const_int 4)
1720            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1721                (const_int MAX_17BIT_OFFSET))
1722            (const_int 8)
1723            (match_test "TARGET_PORTABLE_RUNTIME")
1724            (const_int 24)
1725            (not (match_test "flag_pic"))
1726            (const_int 20)]
1727           (const_int 28)))])
1729 (define_insn ""
1730   [(set (pc)
1731         (if_then_else
1732          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1733                               (const_int 1)
1734                               (match_operand:DI 1 "uint32_operand" ""))
1735              (const_int 0))
1736          (label_ref (match_operand 2 "" ""))
1737          (pc)))]
1738   "TARGET_64BIT"
1739   "*
1741   return pa_output_bb (operands, 0, insn, 1);
1743 [(set_attr "type" "cbranch")
1744  (set (attr "length")
1745     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1746                (const_int MAX_12BIT_OFFSET))
1747            (const_int 4)
1748            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1749                (const_int MAX_17BIT_OFFSET))
1750            (const_int 8)
1751            (match_test "TARGET_PORTABLE_RUNTIME")
1752            (const_int 24)
1753            (not (match_test "flag_pic"))
1754            (const_int 20)]
1755           (const_int 28)))])
1757 (define_insn ""
1758   [(set (pc)
1759         (if_then_else
1760          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1761                               (const_int 1)
1762                               (match_operand:SI 1 "uint5_operand" ""))
1763              (const_int 0))
1764          (pc)
1765          (label_ref (match_operand 2 "" ""))))]
1766   ""
1767   "*
1769   return pa_output_bb (operands, 1, insn, 1);
1771 [(set_attr "type" "cbranch")
1772  (set (attr "length")
1773     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1774                (const_int MAX_12BIT_OFFSET))
1775            (const_int 4)
1776            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1777                (const_int MAX_17BIT_OFFSET))
1778            (const_int 8)
1779            (match_test "TARGET_PORTABLE_RUNTIME")
1780            (const_int 24)
1781            (not (match_test "flag_pic"))
1782            (const_int 20)]
1783           (const_int 28)))])
1785 (define_insn ""
1786   [(set (pc)
1787         (if_then_else
1788          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1789                               (const_int 1)
1790                               (match_operand:DI 1 "uint32_operand" ""))
1791              (const_int 0))
1792          (pc)
1793          (label_ref (match_operand 2 "" ""))))]
1794   "TARGET_64BIT"
1795   "*
1797   return pa_output_bb (operands, 1, insn, 1);
1799 [(set_attr "type" "cbranch")
1800  (set (attr "length")
1801     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1802                (const_int MAX_12BIT_OFFSET))
1803            (const_int 4)
1804            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1805                (const_int MAX_17BIT_OFFSET))
1806            (const_int 8)
1807            (match_test "TARGET_PORTABLE_RUNTIME")
1808            (const_int 24)
1809            (not (match_test "flag_pic"))
1810            (const_int 20)]
1811           (const_int 28)))])
1813 ;; Branch on Variable Bit patterns.
1814 (define_insn ""
1815   [(set (pc)
1816         (if_then_else
1817          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1818                               (const_int 1)
1819                               (match_operand:SI 1 "register_operand" "q"))
1820              (const_int 0))
1821          (label_ref (match_operand 2 "" ""))
1822          (pc)))]
1823   ""
1824   "*
1826   return pa_output_bvb (operands, 0, insn, 0);
1828 [(set_attr "type" "cbranch")
1829  (set (attr "length")
1830     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1831                (const_int MAX_12BIT_OFFSET))
1832            (const_int 4)
1833            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1834                (const_int MAX_17BIT_OFFSET))
1835            (const_int 8)
1836            (match_test "TARGET_PORTABLE_RUNTIME")
1837            (const_int 24)
1838            (not (match_test "flag_pic"))
1839            (const_int 20)]
1840           (const_int 28)))])
1842 (define_insn ""
1843   [(set (pc)
1844         (if_then_else
1845          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1846                               (const_int 1)
1847                               (match_operand:DI 1 "register_operand" "q"))
1848              (const_int 0))
1849          (label_ref (match_operand 2 "" ""))
1850          (pc)))]
1851   "TARGET_64BIT"
1852   "*
1854   return pa_output_bvb (operands, 0, insn, 0);
1856 [(set_attr "type" "cbranch")
1857  (set (attr "length")
1858     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1859                (const_int MAX_12BIT_OFFSET))
1860            (const_int 4)
1861            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1862                (const_int MAX_17BIT_OFFSET))
1863            (const_int 8)
1864            (match_test "TARGET_PORTABLE_RUNTIME")
1865            (const_int 24)
1866            (not (match_test "flag_pic"))
1867            (const_int 20)]
1868           (const_int 28)))])
1870 (define_insn ""
1871   [(set (pc)
1872         (if_then_else
1873          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1874                               (const_int 1)
1875                               (match_operand:SI 1 "register_operand" "q"))
1876              (const_int 0))
1877          (pc)
1878          (label_ref (match_operand 2 "" ""))))]
1879   ""
1880   "*
1882   return pa_output_bvb (operands, 1, insn, 0);
1884 [(set_attr "type" "cbranch")
1885  (set (attr "length")
1886     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1887                (const_int MAX_12BIT_OFFSET))
1888            (const_int 4)
1889            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1890                (const_int MAX_17BIT_OFFSET))
1891            (const_int 8)
1892            (match_test "TARGET_PORTABLE_RUNTIME")
1893            (const_int 24)
1894            (not (match_test "flag_pic"))
1895            (const_int 20)]
1896           (const_int 28)))])
1898 (define_insn ""
1899   [(set (pc)
1900         (if_then_else
1901          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1902                               (const_int 1)
1903                               (match_operand:DI 1 "register_operand" "q"))
1904              (const_int 0))
1905          (pc)
1906          (label_ref (match_operand 2 "" ""))))]
1907   "TARGET_64BIT"
1908   "*
1910   return pa_output_bvb (operands, 1, insn, 0);
1912 [(set_attr "type" "cbranch")
1913  (set (attr "length")
1914     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1915                (const_int MAX_12BIT_OFFSET))
1916            (const_int 4)
1917            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1918                (const_int MAX_17BIT_OFFSET))
1919            (const_int 8)
1920            (match_test "TARGET_PORTABLE_RUNTIME")
1921            (const_int 24)
1922            (not (match_test "flag_pic"))
1923            (const_int 20)]
1924           (const_int 28)))])
1926 (define_insn ""
1927   [(set (pc)
1928         (if_then_else
1929          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1930                               (const_int 1)
1931                               (match_operand:SI 1 "register_operand" "q"))
1932              (const_int 0))
1933          (label_ref (match_operand 2 "" ""))
1934          (pc)))]
1935   ""
1936   "*
1938   return pa_output_bvb (operands, 0, insn, 1);
1940 [(set_attr "type" "cbranch")
1941  (set (attr "length")
1942     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1943                (const_int MAX_12BIT_OFFSET))
1944            (const_int 4)
1945            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1946                (const_int MAX_17BIT_OFFSET))
1947            (const_int 8)
1948            (match_test "TARGET_PORTABLE_RUNTIME")
1949            (const_int 24)
1950            (not (match_test "flag_pic"))
1951            (const_int 20)]
1952           (const_int 28)))])
1954 (define_insn ""
1955   [(set (pc)
1956         (if_then_else
1957          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1958                               (const_int 1)
1959                               (match_operand:DI 1 "register_operand" "q"))
1960              (const_int 0))
1961          (label_ref (match_operand 2 "" ""))
1962          (pc)))]
1963   "TARGET_64BIT"
1964   "*
1966   return pa_output_bvb (operands, 0, insn, 1);
1968 [(set_attr "type" "cbranch")
1969  (set (attr "length")
1970     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1971                (const_int MAX_12BIT_OFFSET))
1972            (const_int 4)
1973            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1974                (const_int MAX_17BIT_OFFSET))
1975            (const_int 8)
1976            (match_test "TARGET_PORTABLE_RUNTIME")
1977            (const_int 24)
1978            (not (match_test "flag_pic"))
1979            (const_int 20)]
1980           (const_int 28)))])
1982 (define_insn ""
1983   [(set (pc)
1984         (if_then_else
1985          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1986                               (const_int 1)
1987                               (match_operand:SI 1 "register_operand" "q"))
1988              (const_int 0))
1989          (pc)
1990          (label_ref (match_operand 2 "" ""))))]
1991   ""
1992   "*
1994   return pa_output_bvb (operands, 1, insn, 1);
1996 [(set_attr "type" "cbranch")
1997  (set (attr "length")
1998     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1999                (const_int MAX_12BIT_OFFSET))
2000            (const_int 4)
2001            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2002                (const_int MAX_17BIT_OFFSET))
2003            (const_int 8)
2004            (match_test "TARGET_PORTABLE_RUNTIME")
2005            (const_int 24)
2006            (not (match_test "flag_pic"))
2007            (const_int 20)]
2008           (const_int 28)))])
2010 (define_insn ""
2011   [(set (pc)
2012         (if_then_else
2013          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2014                               (const_int 1)
2015                               (match_operand:DI 1 "register_operand" "q"))
2016              (const_int 0))
2017          (pc)
2018          (label_ref (match_operand 2 "" ""))))]
2019   "TARGET_64BIT"
2020   "*
2022   return pa_output_bvb (operands, 1, insn, 1);
2024 [(set_attr "type" "cbranch")
2025  (set (attr "length")
2026     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2027                (const_int MAX_12BIT_OFFSET))
2028            (const_int 4)
2029            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2030                (const_int MAX_17BIT_OFFSET))
2031            (const_int 8)
2032            (match_test "TARGET_PORTABLE_RUNTIME")
2033            (const_int 24)
2034            (not (match_test "flag_pic"))
2035            (const_int 20)]
2036           (const_int 28)))])
2038 ;; Floating point branches
2040 ;; ??? Nullification is handled differently from other branches.
2041 ;; If nullification is specified, the delay slot is nullified on any
2042 ;; taken branch regardless of branch direction.
2043 (define_insn ""
2044   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2045                            (label_ref (match_operand 0 "" ""))
2046                            (pc)))]
2047   "!TARGET_SOFT_FLOAT"
2048   "*
2050   int length = get_attr_length (insn);
2051   rtx xoperands[1];
2052   int nullify, xdelay;
2054   if (length < 16)
2055     return \"ftest\;b%* %l0\";
2057   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2058     {
2059       nullify = 1;
2060       xdelay = 0;
2061       xoperands[0] = GEN_INT (length - 8);
2062     }
2063   else
2064     {
2065       nullify = 0;
2066       xdelay = 1;
2067       xoperands[0] = GEN_INT (length - 4);
2068     }
2070   if (nullify)
2071     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b,n .+%0\", xoperands);
2072   else
2073     output_asm_insn (\"ftest\;add,tr %%r0,%%r0,%%r0\;b .+%0\", xoperands);
2074   return pa_output_lbranch (operands[0], insn, xdelay);
2076 [(set_attr "type" "fbranch")
2077  (set (attr "length")
2078     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2079                (const_int MAX_17BIT_OFFSET))
2080            (const_int 8)
2081            (match_test "TARGET_PORTABLE_RUNTIME")
2082            (const_int 32)
2083            (not (match_test "flag_pic"))
2084            (const_int 28)]
2085           (const_int 36)))])
2087 (define_insn ""
2088   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2089                            (pc)
2090                            (label_ref (match_operand 0 "" ""))))]
2091   "!TARGET_SOFT_FLOAT"
2092   "*
2094   int length = get_attr_length (insn);
2095   rtx xoperands[1];
2096   int nullify, xdelay;
2098   if (length < 16)
2099     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2101   if (dbr_sequence_length () == 0 || INSN_ANNULLED_BRANCH_P (insn))
2102     {
2103       nullify = 1;
2104       xdelay = 0;
2105       xoperands[0] = GEN_INT (length - 4);
2106     }
2107   else
2108     {
2109       nullify = 0;
2110       xdelay = 1;
2111       xoperands[0] = GEN_INT (length);
2112     }
2114   if (nullify)
2115     output_asm_insn (\"ftest\;b,n .+%0\", xoperands);
2116   else
2117     output_asm_insn (\"ftest\;b .+%0\", xoperands);
2118   return pa_output_lbranch (operands[0], insn, xdelay);
2120 [(set_attr "type" "fbranch")
2121  (set (attr "length")
2122     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
2123                (const_int MAX_17BIT_OFFSET))
2124            (const_int 12)
2125            (match_test "TARGET_PORTABLE_RUNTIME")
2126            (const_int 28)
2127            (not (match_test "flag_pic"))
2128            (const_int 24)]
2129           (const_int 32)))])
2131 ;; Move instructions
2133 (define_expand "movsi"
2134   [(set (match_operand:SI 0 "general_operand" "")
2135         (match_operand:SI 1 "general_operand" ""))]
2136   ""
2137   "
2139   if (pa_emit_move_sequence (operands, SImode, 0))
2140     DONE;
2143 ;; Handle SImode input reloads requiring %r1 as a scratch register.
2144 (define_expand "reload_insi_r1"
2145   [(set (match_operand:SI 0 "register_operand" "=Z")
2146         (match_operand:SI 1 "non_hard_reg_operand" ""))
2147    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
2148   ""
2149   "
2151   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2152     DONE;
2154   /* We don't want the clobber emitted, so handle this ourselves.  */
2155   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2156   DONE;
2159 ;; Handle SImode input reloads requiring a general register as a
2160 ;; scratch register.
2161 (define_expand "reload_insi"
2162   [(set (match_operand:SI 0 "register_operand" "=Z")
2163         (match_operand:SI 1 "non_hard_reg_operand" ""))
2164    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2165   ""
2166   "
2168   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2169     DONE;
2171   /* We don't want the clobber emitted, so handle this ourselves.  */
2172   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2173   DONE;
2176 ;; Handle SImode output reloads requiring a general register as a
2177 ;; scratch register.
2178 (define_expand "reload_outsi"
2179   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2180         (match_operand:SI 1  "register_operand" "Z"))
2181    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2182   ""
2183   "
2185   if (pa_emit_move_sequence (operands, SImode, operands[2]))
2186     DONE;
2188   /* We don't want the clobber emitted, so handle this ourselves.  */
2189   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2190   DONE;
2193 (define_insn ""
2194   [(set (match_operand:SI 0 "move_dest_operand"
2195                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T,?r,?*f")
2196         (match_operand:SI 1 "move_src_operand"
2197                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f,*f,r"))]
2198   "(register_operand (operands[0], SImode)
2199     || reg_or_0_operand (operands[1], SImode))
2200    && !TARGET_SOFT_FLOAT
2201    && !TARGET_64BIT"
2202   "@
2203    ldw RT'%A1,%0
2204    copy %1,%0
2205    ldi %1,%0
2206    ldil L'%1,%0
2207    {zdepi|depwi,z} %Z1,%0
2208    ldw%M1 %1,%0
2209    stw%M0 %r1,%0
2210    mtsar %r1
2211    {mfctl|mfctl,w} %%sar,%0
2212    fcpy,sgl %f1,%0
2213    fldw%F1 %1,%0
2214    fstw%F0 %1,%0
2215    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
2216    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
2217   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore,fpstore_load,store_fpload")
2218    (set_attr "pa_combine_type" "addmove")
2219    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,8,8")])
2221 (define_insn ""
2222   [(set (match_operand:SI 0 "move_dest_operand"
2223                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2224         (match_operand:SI 1 "move_src_operand"
2225                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2226   "(register_operand (operands[0], SImode)
2227     || reg_or_0_operand (operands[1], SImode))
2228    && !TARGET_SOFT_FLOAT
2229    && TARGET_64BIT"
2230   "@
2231    ldw RT'%A1,%0
2232    copy %1,%0
2233    ldi %1,%0
2234    ldil L'%1,%0
2235    {zdepi|depwi,z} %Z1,%0
2236    ldw%M1 %1,%0
2237    stw%M0 %r1,%0
2238    mtsar %r1
2239    {mfctl|mfctl,w} %%sar,%0
2240    fcpy,sgl %f1,%0
2241    fldw%F1 %1,%0
2242    fstw%F0 %1,%0"
2243   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2244    (set_attr "pa_combine_type" "addmove")
2245    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2247 (define_insn ""
2248   [(set (match_operand:SI 0 "move_dest_operand"
2249                           "=r,r,r,r,r,r,Q,!*q,!r")
2250         (match_operand:SI 1 "move_src_operand"
2251                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2252   "(register_operand (operands[0], SImode)
2253     || reg_or_0_operand (operands[1], SImode))
2254    && TARGET_SOFT_FLOAT
2255    && TARGET_64BIT"
2256   "@
2257    ldw RT'%A1,%0
2258    copy %1,%0
2259    ldi %1,%0
2260    ldil L'%1,%0
2261    {zdepi|depwi,z} %Z1,%0
2262    ldw%M1 %1,%0
2263    stw%M0 %r1,%0
2264    mtsar %r1
2265    {mfctl|mfctl,w} %%sar,%0"
2266   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
2267    (set_attr "pa_combine_type" "addmove")
2268    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2270 (define_insn ""
2271   [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2272         (match_operand:SI 1 "register_operand" "f"))]
2273   "!TARGET_SOFT_FLOAT
2274    && !TARGET_DISABLE_INDEXING
2275    && reload_completed"
2276   "fstw%F0 %1,%0"
2277   [(set_attr "type" "fpstore")
2278    (set_attr "pa_combine_type" "addmove")
2279    (set_attr "length" "4")])
2281 ; Rewrite RTL using an indexed store.  This will allow the insn that
2282 ; computes the address to be deleted if the register it sets is dead.
2283 (define_peephole2
2284   [(set (match_operand:SI 0 "register_operand" "")
2285         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2286                             (const_int 2))
2287                  (match_operand:SI 2 "register_operand" "")))
2288    (set (mem:SI (match_dup 0))
2289         (match_operand:SI 3 "register_operand" ""))]
2290   "!TARGET_SOFT_FLOAT
2291    && !TARGET_DISABLE_INDEXING
2292    && REG_OK_FOR_BASE_P (operands[2])
2293    && FP_REGNO_P (REGNO (operands[3]))"
2294   [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2295         (match_dup 3))
2296    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
2297                                (match_dup 2)))]
2298   "")
2300 (define_peephole2
2301   [(set (match_operand:DI 0 "register_operand" "")
2302         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
2303                             (const_int 2))
2304                  (match_operand:DI 2 "register_operand" "")))
2305    (set (mem:SI (match_dup 0))
2306         (match_operand:SI 3 "register_operand" ""))]
2307   "!TARGET_SOFT_FLOAT
2308    && !TARGET_DISABLE_INDEXING
2309    && TARGET_64BIT
2310    && REG_OK_FOR_BASE_P (operands[2])
2311    && FP_REGNO_P (REGNO (operands[3]))"
2312   [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2313         (match_dup 3))
2314    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
2315                                (match_dup 2)))]
2316   "")
2318 (define_peephole2
2319   [(set (match_operand:SI 0 "register_operand" "")
2320         (plus:SI (match_operand:SI 1 "register_operand" "")
2321                  (match_operand:SI 2 "register_operand" "")))
2322    (set (mem:SI (match_dup 0))
2323         (match_operand:SI 3 "register_operand" ""))]
2324   "!TARGET_SOFT_FLOAT
2325    && !TARGET_DISABLE_INDEXING
2326    && TARGET_NO_SPACE_REGS
2327    && REG_OK_FOR_INDEX_P (operands[1])
2328    && REG_OK_FOR_BASE_P (operands[2])
2329    && FP_REGNO_P (REGNO (operands[3]))"
2330   [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2331         (match_dup 3))
2332    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2333   "")
2335 (define_peephole2
2336   [(set (match_operand:SI 0 "register_operand" "")
2337         (plus:SI (match_operand:SI 1 "register_operand" "")
2338                  (match_operand:SI 2 "register_operand" "")))
2339    (set (mem:SI (match_dup 0))
2340         (match_operand:SI 3 "register_operand" ""))]
2341   "!TARGET_SOFT_FLOAT
2342    && !TARGET_DISABLE_INDEXING
2343    && TARGET_NO_SPACE_REGS
2344    && REG_OK_FOR_BASE_P (operands[1])
2345    && REG_OK_FOR_INDEX_P (operands[2])
2346    && FP_REGNO_P (REGNO (operands[3]))"
2347   [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2348         (match_dup 3))
2349    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2350   "")
2352 (define_peephole2
2353   [(set (match_operand:DI 0 "register_operand" "")
2354         (plus:DI (match_operand:DI 1 "register_operand" "")
2355                  (match_operand:DI 2 "register_operand" "")))
2356    (set (mem:SI (match_dup 0))
2357         (match_operand:SI 3 "register_operand" ""))]
2358   "!TARGET_SOFT_FLOAT
2359    && !TARGET_DISABLE_INDEXING
2360    && TARGET_64BIT
2361    && TARGET_NO_SPACE_REGS
2362    && REG_OK_FOR_INDEX_P (operands[1])
2363    && REG_OK_FOR_BASE_P (operands[2])
2364    && FP_REGNO_P (REGNO (operands[3]))"
2365   [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2366         (match_dup 3))
2367    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2368   "")
2370 (define_peephole2
2371   [(set (match_operand:DI 0 "register_operand" "")
2372         (plus:DI (match_operand:DI 1 "register_operand" "")
2373                  (match_operand:DI 2 "register_operand" "")))
2374    (set (mem:SI (match_dup 0))
2375         (match_operand:SI 3 "register_operand" ""))]
2376   "!TARGET_SOFT_FLOAT
2377    && !TARGET_DISABLE_INDEXING
2378    && TARGET_64BIT
2379    && TARGET_NO_SPACE_REGS
2380    && REG_OK_FOR_BASE_P (operands[1])
2381    && REG_OK_FOR_INDEX_P (operands[2])
2382    && FP_REGNO_P (REGNO (operands[3]))"
2383   [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2384         (match_dup 3))
2385    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2386   "")
2388 (define_insn ""
2389   [(set (match_operand:SI 0 "move_dest_operand"
2390                           "=r,r,r,r,r,r,Q,!*q,!r")
2391         (match_operand:SI 1 "move_src_operand"
2392                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2393   "(register_operand (operands[0], SImode)
2394     || reg_or_0_operand (operands[1], SImode))
2395    && TARGET_SOFT_FLOAT"
2396   "@
2397    ldw RT'%A1,%0
2398    copy %1,%0
2399    ldi %1,%0
2400    ldil L'%1,%0
2401    {zdepi|depwi,z} %Z1,%0
2402    ldw%M1 %1,%0
2403    stw%M0 %r1,%0
2404    mtsar %r1
2405    {mfctl|mfctl,w} %%sar,%0"
2406   [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2407    (set_attr "pa_combine_type" "addmove")
2408    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2410 ;; Load or store with base-register modification.
2411 (define_insn ""
2412   [(set (match_operand:SI 0 "register_operand" "=r")
2413         (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2414                          (match_operand:DI 2 "int5_operand" "L"))))
2415    (set (match_dup 1)
2416         (plus:DI (match_dup 1) (match_dup 2)))]
2417   "TARGET_64BIT"
2418   "ldw,mb %2(%1),%0"
2419   [(set_attr "type" "load")
2420    (set_attr "length" "4")])
2422 ; And a zero extended variant.
2423 (define_insn ""
2424   [(set (match_operand:DI 0 "register_operand" "=r")
2425         (zero_extend:DI (mem:SI
2426                           (plus:DI
2427                             (match_operand:DI 1 "register_operand" "+r")
2428                             (match_operand:DI 2 "int5_operand" "L")))))
2429    (set (match_dup 1)
2430         (plus:DI (match_dup 1) (match_dup 2)))]
2431   "TARGET_64BIT"
2432   "ldw,mb %2(%1),%0"
2433   [(set_attr "type" "load")
2434    (set_attr "length" "4")])
2436 (define_expand "pre_load"
2437   [(parallel [(set (match_operand:SI 0 "register_operand" "")
2438               (mem (plus (match_operand 1 "register_operand" "")
2439                                (match_operand 2 "pre_cint_operand" ""))))
2440               (set (match_dup 1)
2441                    (plus (match_dup 1) (match_dup 2)))])]
2442   ""
2443   "
2445   if (TARGET_64BIT)
2446     {
2447       emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2448       DONE;
2449     }
2450   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2451   DONE;
2454 (define_insn "pre_ldw"
2455   [(set (match_operand:SI 0 "register_operand" "=r")
2456         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2457                          (match_operand:SI 2 "pre_cint_operand" ""))))
2458    (set (match_dup 1)
2459         (plus:SI (match_dup 1) (match_dup 2)))]
2460   ""
2461   "*
2463   if (INTVAL (operands[2]) < 0)
2464     return \"{ldwm|ldw,mb} %2(%1),%0\";
2465   return \"{ldws|ldw},mb %2(%1),%0\";
2467   [(set_attr "type" "load")
2468    (set_attr "length" "4")])
2470 (define_insn "pre_ldd"
2471   [(set (match_operand:DI 0 "register_operand" "=r")
2472         (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2473                          (match_operand:DI 2 "pre_cint_operand" ""))))
2474    (set (match_dup 1)
2475         (plus:DI (match_dup 1) (match_dup 2)))]
2476   "TARGET_64BIT"
2477   "ldd,mb %2(%1),%0"
2478   [(set_attr "type" "load")
2479    (set_attr "length" "4")])
2481 (define_insn ""
2482   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2483                          (match_operand:SI 1 "pre_cint_operand" "")))
2484         (match_operand:SI 2 "reg_or_0_operand" "rM"))
2485    (set (match_dup 0)
2486         (plus:SI (match_dup 0) (match_dup 1)))]
2487   ""
2488   "*
2490   if (INTVAL (operands[1]) < 0)
2491     return \"{stwm|stw,mb} %r2,%1(%0)\";
2492   return \"{stws|stw},mb %r2,%1(%0)\";
2494   [(set_attr "type" "store")
2495    (set_attr "length" "4")])
2497 (define_insn ""
2498   [(set (match_operand:SI 0 "register_operand" "=r")
2499         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2500    (set (match_dup 1)
2501         (plus:SI (match_dup 1)
2502                  (match_operand:SI 2 "post_cint_operand" "")))]
2503   ""
2504   "*
2506   if (INTVAL (operands[2]) > 0)
2507     return \"{ldwm|ldw,ma} %2(%1),%0\";
2508   return \"{ldws|ldw},ma %2(%1),%0\";
2510   [(set_attr "type" "load")
2511    (set_attr "length" "4")])
2513 (define_expand "post_store"
2514   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2515                    (match_operand 1 "reg_or_0_operand" ""))
2516               (set (match_dup 0)
2517                    (plus (match_dup 0)
2518                          (match_operand 2 "post_cint_operand" "")))])]
2519   ""
2520   "
2522   if (TARGET_64BIT)
2523     {
2524       emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2525       DONE;
2526     }
2527   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2528   DONE;
2531 (define_insn "post_stw"
2532   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2533         (match_operand:SI 1 "reg_or_0_operand" "rM"))
2534    (set (match_dup 0)
2535         (plus:SI (match_dup 0)
2536                  (match_operand:SI 2 "post_cint_operand" "")))]
2537   ""
2538   "*
2540   if (INTVAL (operands[2]) > 0)
2541     return \"{stwm|stw,ma} %r1,%2(%0)\";
2542   return \"{stws|stw},ma %r1,%2(%0)\";
2544   [(set_attr "type" "store")
2545    (set_attr "length" "4")])
2547 (define_insn "post_std"
2548   [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2549         (match_operand:DI 1 "reg_or_0_operand" "rM"))
2550    (set (match_dup 0)
2551         (plus:DI (match_dup 0)
2552                  (match_operand:DI 2 "post_cint_operand" "")))]
2553   "TARGET_64BIT"
2554   "std,ma %r1,%2(%0)"
2555   [(set_attr "type" "store")
2556    (set_attr "length" "4")])
2558 ;; For loading the address of a label while generating PIC code.
2559 ;; Note since this pattern can be created at reload time (via movsi), all
2560 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2561 (define_insn ""
2562   [(set (match_operand 0 "pmode_register_operand" "=a")
2563         (match_operand 1 "pic_label_operand" ""))]
2564   "TARGET_PA_20"
2565   "*
2567   rtx xoperands[3];
2569   xoperands[0] = operands[0];
2570   xoperands[1] = operands[1];
2572   if (GET_CODE (operands[1]) == LABEL_REF
2573       && !LABEL_REF_NONLOCAL_P (operands[1]))
2574     {
2575       xoperands[2] = gen_label_rtx ();
2576       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2577                                          CODE_LABEL_NUMBER (xoperands[2]));
2578       output_asm_insn (\"mfia %0\", xoperands);
2580       /* If we're trying to load the address of a label that happens to be
2581          close, then we can use a shorter sequence.  */
2582       if (INSN_ADDRESSES_SET_P ()
2583           && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2584                   - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2585         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2586       else
2587         {
2588           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2589           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2590         }
2591     }
2592   else
2593     {
2594       /* Load using linkage table.  */
2595       if (TARGET_64BIT)
2596         {
2597           output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
2598           output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
2599         }
2600       else
2601         {
2602           output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2603           output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2604         }
2605     }
2606   return \"\";
2608   [(set_attr "type" "multi")
2609    (set_attr "length" "12")])           ; 8 or 12
2611 (define_insn ""
2612   [(set (match_operand 0 "pmode_register_operand" "=a")
2613         (match_operand 1 "pic_label_operand" ""))]
2614   "!TARGET_PA_20"
2615   "*
2617   rtx xoperands[3];
2619   xoperands[0] = operands[0];
2620   xoperands[1] = operands[1];
2622   if (GET_CODE (operands[1]) == LABEL_REF
2623       && !LABEL_REF_NONLOCAL_P (operands[1]))
2624     {
2625       xoperands[2] = gen_label_rtx ();
2626       output_asm_insn (\"bl .+8,%0\", xoperands);
2627       output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2628       (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2629                                          CODE_LABEL_NUMBER (xoperands[2]));
2631       /* If we're trying to load the address of a label that happens to be
2632          close, then we can use a shorter sequence.  */
2633       if (INSN_ADDRESSES_SET_P ()
2634           && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2635                   - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2636         output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2637       else
2638         {
2639           output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2640           output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2641         }
2642     }
2643   else
2644     {
2645       /* Load using linkage table.  */
2646       output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
2647       output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
2648     }
2649   return \"\";
2651   [(set_attr "type" "multi")
2652    (set_attr "length" "16")])           ; 12 or 16
2654 (define_insn ""
2655   [(set (match_operand:SI 0 "register_operand" "=a")
2656         (plus:SI (match_operand:SI 1 "register_operand" "r")
2657                  (high:SI (match_operand 2 "" ""))))]
2658   "symbolic_operand (operands[2], Pmode)
2659    && ! function_label_operand (operands[2], Pmode)
2660    && flag_pic"
2661   "addil LT'%G2,%1"
2662   [(set_attr "type" "binary")
2663    (set_attr "length" "4")])
2665 (define_insn ""
2666   [(set (match_operand:DI 0 "register_operand" "=a")
2667         (plus:DI (match_operand:DI 1 "register_operand" "r")
2668                  (high:DI (match_operand 2 "" ""))))]
2669   "symbolic_operand (operands[2], Pmode)
2670    && ! function_label_operand (operands[2], Pmode)
2671    && TARGET_64BIT
2672    && flag_pic"
2673   "addil LT'%G2,%1"
2674   [(set_attr "type" "binary")
2675    (set_attr "length" "4")])
2677 (define_insn ""
2678  [(set (match_operand:SI 0 "register_operand" "=r")
2679        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2680                   (unspec:SI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2681   "symbolic_operand (operands[2], Pmode)
2682    && ! function_label_operand (operands[2], Pmode)
2683    && flag_pic"
2684   "ldo RT'%G2(%1),%0"
2685   [(set_attr "type" "binary")
2686    (set_attr "length" "4")])
2688 (define_insn ""
2689  [(set (match_operand:DI 0 "register_operand" "=r")
2690        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2691                   (unspec:DI [(match_operand 2 "" "")] UNSPEC_DLTIND14R)))]
2692   "symbolic_operand (operands[2], Pmode)
2693    && ! function_label_operand (operands[2], Pmode)
2694    && TARGET_64BIT
2695    && flag_pic"
2696   "ldo RT'%G2(%1),%0"
2697   [(set_attr "type" "binary")
2698    (set_attr "length" "4")])
2700 ;; Always use addil rather than ldil;add sequences.  This allows the
2701 ;; HP linker to eliminate the dp relocation if the symbolic operand
2702 ;; lives in the TEXT space.
2703 (define_insn ""
2704   [(set (match_operand:SI 0 "register_operand" "=a")
2705         (high:SI (match_operand 1 "" "")))]
2706   "symbolic_operand (operands[1], Pmode)
2707    && ! function_label_operand (operands[1], Pmode)
2708    && ! read_only_operand (operands[1], Pmode)
2709    && ! flag_pic"
2710   "*
2712   if (TARGET_LONG_LOAD_STORE)
2713     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2714   else
2715     return \"addil LR'%H1,%%r27\";
2717   [(set_attr "type" "binary")
2718    (set (attr "length")
2719       (if_then_else (not (match_test "TARGET_LONG_LOAD_STORE"))
2720                     (const_int 4)
2721                     (const_int 8)))])
2724 ;; This is for use in the prologue/epilogue code.  We need it
2725 ;; to add large constants to a stack pointer or frame pointer.
2726 ;; Because of the additional %r1 pressure, we probably do not
2727 ;; want to use this in general code, so make it available
2728 ;; only after reload.
2729 (define_insn ""
2730   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2731         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2732                  (high:SI (match_operand 2 "const_int_operand" ""))))]
2733   "reload_completed"
2734   "@
2735    addil L'%G2,%1
2736    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2737   [(set_attr "type" "binary,binary")
2738    (set_attr "length" "4,8")])
2740 (define_insn ""
2741   [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2742         (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2743                  (high:DI (match_operand 2 "const_int_operand" ""))))]
2744   "reload_completed && TARGET_64BIT"
2745   "@
2746    addil L'%G2,%1
2747    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2748   [(set_attr "type" "binary,binary")
2749    (set_attr "length" "4,8")])
2751 (define_insn ""
2752   [(set (match_operand:SI 0 "register_operand" "=r")
2753         (high:SI (match_operand 1 "" "")))]
2754   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2755     && !pa_is_function_label_plus_const (operands[1])"
2756   "*
2758   if (symbolic_operand (operands[1], Pmode))
2759     return \"ldil LR'%H1,%0\";
2760   else
2761     return \"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         (high:DI (match_operand 1 "const_int_operand" "")))]
2769   "TARGET_64BIT"
2770   "ldil L'%G1,%0";
2771   [(set_attr "type" "move")
2772    (set_attr "length" "4")])
2774 (define_insn ""
2775   [(set (match_operand:DI 0 "register_operand" "=r")
2776         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2777                    (match_operand:DI 2 "const_int_operand" "i")))]
2778   "TARGET_64BIT"
2779   "ldo R'%G2(%1),%0";
2780   [(set_attr "type" "move")
2781    (set_attr "length" "4")])
2783 (define_insn ""
2784   [(set (match_operand:SI 0 "register_operand" "=r")
2785         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2786                    (match_operand:SI 2 "immediate_operand" "i")))]
2787   "!pa_is_function_label_plus_const (operands[2])"
2788   "*
2790   gcc_assert (!flag_pic || !symbolic_operand (operands[2], Pmode));
2791   
2792   if (symbolic_operand (operands[2], Pmode))
2793     return \"ldo RR'%G2(%1),%0\";
2794   else
2795     return \"ldo R'%G2(%1),%0\";
2797   [(set_attr "type" "move")
2798    (set_attr "length" "4")])
2800 ;; Now that a symbolic_address plus a constant is broken up early
2801 ;; in the compilation phase (for better CSE) we need a special
2802 ;; combiner pattern to load the symbolic address plus the constant
2803 ;; in only 2 instructions. (For cases where the symbolic address
2804 ;; was not a common subexpression.)
2805 (define_split
2806   [(set (match_operand:SI 0 "register_operand" "")
2807         (match_operand:SI 1 "symbolic_operand" ""))
2808    (clobber (match_operand:SI 2 "register_operand" ""))]
2809   "! (flag_pic && pic_label_operand (operands[1], SImode))"
2810   [(set (match_dup 2) (high:SI (match_dup 1)))
2811    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2812   "")
2814 ;; hppa_legitimize_address goes to a great deal of trouble to
2815 ;; create addresses which use indexing.  In some cases, this
2816 ;; is a lose because there isn't any store instructions which
2817 ;; allow indexed addresses (with integer register source).
2819 ;; These define_splits try to turn a 3 insn store into
2820 ;; a 2 insn store with some creative RTL rewriting.
2821 (define_split
2822   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2823                                (match_operand:SI 1 "mem_shadd_operand" ""))
2824                    (plus:SI (match_operand:SI 2 "register_operand" "")
2825                             (match_operand:SI 3 "const_int_operand" ""))))
2826         (match_operand:SI 4 "register_operand" ""))
2827    (clobber (match_operand:SI 5 "register_operand" ""))]
2828   ""
2829   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2830                                (match_dup 2)))
2831    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2832   "
2834   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2838 (define_split
2839   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2840                                (match_operand:SI 1 "mem_shadd_operand" ""))
2841                    (plus:SI (match_operand:SI 2 "register_operand" "")
2842                             (match_operand:SI 3 "const_int_operand" ""))))
2843         (match_operand:HI 4 "register_operand" ""))
2844    (clobber (match_operand:SI 5 "register_operand" ""))]
2845   ""
2846   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2847                                (match_dup 2)))
2848    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2849   "
2851   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2855 (define_split
2856   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2857                                (match_operand:SI 1 "mem_shadd_operand" ""))
2858                    (plus:SI (match_operand:SI 2 "register_operand" "")
2859                             (match_operand:SI 3 "const_int_operand" ""))))
2860         (match_operand:QI 4 "register_operand" ""))
2861    (clobber (match_operand:SI 5 "register_operand" ""))]
2862   ""
2863   [(set (match_dup 5) (plus:SI (ashift:SI (match_dup 0) (match_dup 1))
2864                                (match_dup 2)))
2865    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2866   "
2868   operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));
2872 (define_expand "movhi"
2873   [(set (match_operand:HI 0 "general_operand" "")
2874         (match_operand:HI 1 "general_operand" ""))]
2875   ""
2876   "
2878   if (pa_emit_move_sequence (operands, HImode, 0))
2879     DONE;
2882 ;; Handle HImode input reloads requiring a general register as a
2883 ;; scratch register.
2884 (define_expand "reload_inhi"
2885   [(set (match_operand:HI 0 "register_operand" "=Z")
2886         (match_operand:HI 1 "non_hard_reg_operand" ""))
2887    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2888   ""
2889   "
2891   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2892     DONE;
2894   /* We don't want the clobber emitted, so handle this ourselves.  */
2895   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2896   DONE;
2899 ;; Handle HImode output reloads requiring a general register as a
2900 ;; scratch register.
2901 (define_expand "reload_outhi"
2902   [(set (match_operand:HI 0 "non_hard_reg_operand" "")
2903         (match_operand:HI 1  "register_operand" "Z"))
2904    (clobber (match_operand:HI 2 "register_operand" "=&r"))]
2905   ""
2906   "
2908   if (pa_emit_move_sequence (operands, HImode, operands[2]))
2909     DONE;
2911   /* We don't want the clobber emitted, so handle this ourselves.  */
2912   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2913   DONE;
2916 (define_insn ""
2917   [(set (match_operand:HI 0 "move_dest_operand"
2918                           "=r,r,r,r,r,Q,!*q,!r")
2919         (match_operand:HI 1 "move_src_operand"
2920                           "r,J,N,K,RQ,rM,!rM,!*q"))]
2921   "(register_operand (operands[0], HImode)
2922     || reg_or_0_operand (operands[1], HImode))"
2923   "@
2924    copy %1,%0
2925    ldi %1,%0
2926    ldil L'%1,%0
2927    {zdepi|depwi,z} %Z1,%0
2928    ldh%M1 %1,%0
2929    sth%M0 %r1,%0
2930    mtsar %r1
2931    {mfctl|mfctl,w} %sar,%0"
2932   [(set_attr "type" "move,move,move,shift,load,store,move,move")
2933    (set_attr "pa_combine_type" "addmove")
2934    (set_attr "length" "4,4,4,4,4,4,4,4")])
2936 (define_insn ""
2937   [(set (match_operand:HI 0 "register_operand" "=r")
2938         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2939                          (match_operand:SI 2 "int5_operand" "L"))))
2940    (set (match_dup 1)
2941         (plus:SI (match_dup 1) (match_dup 2)))]
2942   ""
2943   "{ldhs|ldh},mb %2(%1),%0"
2944   [(set_attr "type" "load")
2945    (set_attr "length" "4")])
2947 (define_insn ""
2948   [(set (match_operand:HI 0 "register_operand" "=r")
2949         (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2950                          (match_operand:DI 2 "int5_operand" "L"))))
2951    (set (match_dup 1)
2952         (plus:DI (match_dup 1) (match_dup 2)))]
2953   "TARGET_64BIT"
2954   "ldh,mb %2(%1),%0"
2955   [(set_attr "type" "load")
2956    (set_attr "length" "4")])
2958 ; And a zero extended variant.
2959 (define_insn ""
2960   [(set (match_operand:DI 0 "register_operand" "=r")
2961         (zero_extend:DI (mem:HI
2962                           (plus:DI
2963                             (match_operand:DI 1 "register_operand" "+r")
2964                             (match_operand:DI 2 "int5_operand" "L")))))
2965    (set (match_dup 1)
2966         (plus:DI (match_dup 1) (match_dup 2)))]
2967   "TARGET_64BIT"
2968   "ldh,mb %2(%1),%0"
2969   [(set_attr "type" "load")
2970    (set_attr "length" "4")])
2972 (define_insn ""
2973   [(set (match_operand:SI 0 "register_operand" "=r")
2974         (zero_extend:SI (mem:HI
2975                           (plus:SI
2976                             (match_operand:SI 1 "register_operand" "+r")
2977                             (match_operand:SI 2 "int5_operand" "L")))))
2978    (set (match_dup 1)
2979         (plus:SI (match_dup 1) (match_dup 2)))]
2980   ""
2981   "{ldhs|ldh},mb %2(%1),%0"
2982   [(set_attr "type" "load")
2983    (set_attr "length" "4")])
2985 (define_insn ""
2986   [(set (match_operand:SI 0 "register_operand" "=r")
2987         (zero_extend:SI (mem:HI
2988                           (plus:DI
2989                             (match_operand:DI 1 "register_operand" "+r")
2990                             (match_operand:DI 2 "int5_operand" "L")))))
2991    (set (match_dup 1)
2992         (plus:DI (match_dup 1) (match_dup 2)))]
2993   "TARGET_64BIT"
2994   "ldh,mb %2(%1),%0"
2995   [(set_attr "type" "load")
2996    (set_attr "length" "4")])
2998 (define_insn ""
2999   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3000                          (match_operand:SI 1 "int5_operand" "L")))
3001         (match_operand:HI 2 "reg_or_0_operand" "rM"))
3002    (set (match_dup 0)
3003         (plus:SI (match_dup 0) (match_dup 1)))]
3004   ""
3005   "{sths|sth},mb %r2,%1(%0)"
3006   [(set_attr "type" "store")
3007    (set_attr "length" "4")])
3009 (define_insn ""
3010   [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3011                          (match_operand:DI 1 "int5_operand" "L")))
3012         (match_operand:HI 2 "reg_or_0_operand" "rM"))
3013    (set (match_dup 0)
3014         (plus:DI (match_dup 0) (match_dup 1)))]
3015   "TARGET_64BIT"
3016   "sth,mb %r2,%1(%0)"
3017   [(set_attr "type" "store")
3018    (set_attr "length" "4")])
3020 (define_insn "addhi3"
3021   [(set (match_operand:HI 0 "register_operand" "=r,r")
3022         (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
3023                  (match_operand:HI 2 "arith14_operand" "r,J")))]
3024   ""
3025   "@
3026    {addl|add,l} %1,%2,%0
3027    ldo %2(%1),%0"
3028   [(set_attr "type" "binary,binary")
3029    (set_attr "pa_combine_type" "addmove")
3030    (set_attr "length" "4,4")])
3032 (define_expand "movqi"
3033   [(set (match_operand:QI 0 "general_operand" "")
3034         (match_operand:QI 1 "general_operand" ""))]
3035   ""
3036   "
3038   if (pa_emit_move_sequence (operands, QImode, 0))
3039     DONE;
3042 ;; Handle QImode input reloads requiring a general register as a
3043 ;; scratch register.
3044 (define_expand "reload_inqi"
3045   [(set (match_operand:QI 0 "register_operand" "=Z")
3046         (match_operand:QI 1 "non_hard_reg_operand" ""))
3047    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3048   ""
3049   "
3051   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3052     DONE;
3054   /* We don't want the clobber emitted, so handle this ourselves.  */
3055   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3056   DONE;
3059 ;; Handle QImode output reloads requiring a general register as a
3060 ;; scratch register.
3061 (define_expand "reload_outqi"
3062   [(set (match_operand:QI 0 "non_hard_reg_operand" "")
3063         (match_operand:QI 1  "register_operand" "Z"))
3064    (clobber (match_operand:QI 2 "register_operand" "=&r"))]
3065   ""
3066   "
3068   if (pa_emit_move_sequence (operands, QImode, operands[2]))
3069     DONE;
3071   /* We don't want the clobber emitted, so handle this ourselves.  */
3072   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3073   DONE;
3076 (define_insn ""
3077   [(set (match_operand:QI 0 "move_dest_operand"
3078                           "=r,r,r,r,r,Q,!*q,!r")
3079         (match_operand:QI 1 "move_src_operand"
3080                           "r,J,N,K,RQ,rM,!rM,!*q"))]
3081   "(register_operand (operands[0], QImode)
3082     || reg_or_0_operand (operands[1], QImode))"
3083   "@
3084    copy %1,%0
3085    ldi %1,%0
3086    ldil L'%1,%0
3087    {zdepi|depwi,z} %Z1,%0
3088    ldb%M1 %1,%0
3089    stb%M0 %r1,%0
3090    mtsar %r1
3091    {mfctl|mfctl,w} %%sar,%0"
3092   [(set_attr "type" "move,move,move,shift,load,store,move,move")
3093    (set_attr "pa_combine_type" "addmove")
3094    (set_attr "length" "4,4,4,4,4,4,4,4")])
3096 (define_insn ""
3097   [(set (match_operand:QI 0 "register_operand" "=r")
3098         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3099                          (match_operand:SI 2 "int5_operand" "L"))))
3100    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3101   ""
3102   "{ldbs|ldb},mb %2(%1),%0"
3103   [(set_attr "type" "load")
3104    (set_attr "length" "4")])
3106 (define_insn ""
3107   [(set (match_operand:QI 0 "register_operand" "=r")
3108         (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3109                          (match_operand:DI 2 "int5_operand" "L"))))
3110    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3111   "TARGET_64BIT"
3112   "ldb,mb %2(%1),%0"
3113   [(set_attr "type" "load")
3114    (set_attr "length" "4")])
3116 ; Now the same thing with zero extensions.
3117 (define_insn ""
3118   [(set (match_operand:DI 0 "register_operand" "=r")
3119         (zero_extend:DI (mem:QI (plus:DI
3120                                   (match_operand:DI 1 "register_operand" "+r")
3121                                   (match_operand:DI 2 "int5_operand" "L")))))
3122    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3123   "TARGET_64BIT"
3124   "ldb,mb %2(%1),%0"
3125   [(set_attr "type" "load")
3126    (set_attr "length" "4")])
3128 (define_insn ""
3129   [(set (match_operand:SI 0 "register_operand" "=r")
3130         (zero_extend:SI (mem:QI (plus:SI
3131                                   (match_operand:SI 1 "register_operand" "+r")
3132                                   (match_operand:SI 2 "int5_operand" "L")))))
3133    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3134   ""
3135   "{ldbs|ldb},mb %2(%1),%0"
3136   [(set_attr "type" "load")
3137    (set_attr "length" "4")])
3139 (define_insn ""
3140   [(set (match_operand:SI 0 "register_operand" "=r")
3141         (zero_extend:SI (mem:QI (plus:DI
3142                                   (match_operand:DI 1 "register_operand" "+r")
3143                                   (match_operand:DI 2 "int5_operand" "L")))))
3144    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3145   "TARGET_64BIT"
3146   "ldb,mb %2(%1),%0"
3147   [(set_attr "type" "load")
3148    (set_attr "length" "4")])
3150 (define_insn ""
3151   [(set (match_operand:HI 0 "register_operand" "=r")
3152         (zero_extend:HI (mem:QI (plus:SI
3153                                   (match_operand:SI 1 "register_operand" "+r")
3154                                   (match_operand:SI 2 "int5_operand" "L")))))
3155    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3156   ""
3157   "{ldbs|ldb},mb %2(%1),%0"
3158   [(set_attr "type" "load")
3159    (set_attr "length" "4")])
3161 (define_insn ""
3162   [(set (match_operand:HI 0 "register_operand" "=r")
3163         (zero_extend:HI (mem:QI (plus:DI
3164                                   (match_operand:DI 1 "register_operand" "+r")
3165                                   (match_operand:DI 2 "int5_operand" "L")))))
3166    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3167   "TARGET_64BIT"
3168   "ldb,mb %2(%1),%0"
3169   [(set_attr "type" "load")
3170    (set_attr "length" "4")])
3172 (define_insn ""
3173   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3174                          (match_operand:SI 1 "int5_operand" "L")))
3175         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3176    (set (match_dup 0)
3177         (plus:SI (match_dup 0) (match_dup 1)))]
3178   ""
3179   "{stbs|stb},mb %r2,%1(%0)"
3180   [(set_attr "type" "store")
3181    (set_attr "length" "4")])
3183 (define_insn ""
3184   [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3185                          (match_operand:DI 1 "int5_operand" "L")))
3186         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3187    (set (match_dup 0)
3188         (plus:DI (match_dup 0) (match_dup 1)))]
3189   "TARGET_64BIT"
3190   "stb,mb %r2,%1(%0)"
3191   [(set_attr "type" "store")
3192    (set_attr "length" "4")])
3194 ;; The definition of this insn does not really explain what it does,
3195 ;; but it should suffice that anything generated as this insn will be
3196 ;; recognized as a cpymemsi operation, and that it will not successfully
3197 ;; combine with anything.
3198 (define_expand "cpymemsi"
3199   [(parallel [(set (match_operand:BLK 0 "" "")
3200                    (match_operand:BLK 1 "" ""))
3201               (clobber (match_dup 4))
3202               (clobber (match_dup 5))
3203               (clobber (match_dup 6))
3204               (clobber (match_dup 7))
3205               (clobber (match_dup 8))
3206               (use (match_operand:SI 2 "arith14_operand" ""))
3207               (use (match_operand:SI 3 "const_int_operand" ""))])]
3208   "!TARGET_64BIT && optimize > 0"
3209   "
3211   int size, align;
3213   /* HP provides very fast block move library routine for the PA;
3214      this routine includes:
3216         4x4 byte at a time block moves,
3217         1x4 byte at a time with alignment checked at runtime with
3218             attempts to align the source and destination as needed
3219         1x1 byte loop
3221      With that in mind, here's the heuristics to try and guess when
3222      the inlined block move will be better than the library block
3223      move:
3225         If the size isn't constant, then always use the library routines.
3227         If the size is large in respect to the known alignment, then use
3228         the library routines.
3230         If the size is small in respect to the known alignment, then open
3231         code the copy (since that will lead to better scheduling).
3233         Else use the block move pattern.   */
3235   /* Undetermined size, use the library routine.  */
3236   if (GET_CODE (operands[2]) != CONST_INT)
3237     FAIL;
3239   size = INTVAL (operands[2]);
3240   align = INTVAL (operands[3]);
3241   align = align > 4 ? 4 : (align ? align : 1);
3243   /* If size/alignment is large, then use the library routines.  */
3244   if (size / align > 16)
3245     FAIL;
3247   /* This does happen, but not often enough to worry much about.  */
3248   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3249     FAIL;
3250   
3251   /* Fall through means we're going to use our block move pattern.  */
3252   operands[0]
3253     = replace_equiv_address (operands[0],
3254                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3255   operands[1]
3256     = replace_equiv_address (operands[1],
3257                              copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3258   operands[4] = gen_reg_rtx (SImode);
3259   operands[5] = gen_reg_rtx (SImode);
3260   operands[6] = gen_reg_rtx (SImode);
3261   operands[7] = gen_reg_rtx (SImode);
3262   operands[8] = gen_reg_rtx (SImode);
3265 ;; The operand constraints are written like this to support both compile-time
3266 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3267 ;; only support compile-time determined counts at this time.
3269 ;; If the count is run-time determined, the register with the byte count
3270 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3272 ;; We used to clobber operands 0 and 1.  However, a change to regrename.cc
3273 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3274 ;; as this requires two registers in the class R1_REGS when the MEMs for
3275 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3276 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3277 ;; respectively.  We then split or peephole optimize after reload.
3278 (define_insn "cpymemsi_prereload"
3279   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3280         (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3281    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3282    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3283    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3284    (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))   ;item tmp3
3285    (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))   ;item tmp4
3286    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3287    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3288   "!TARGET_64BIT"
3289   "#"
3290   [(set_attr "type" "multi,multi")])
3292 (define_split
3293   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3294                    (match_operand:BLK 1 "memory_operand" ""))
3295               (clobber (match_operand:SI 2 "register_operand" ""))
3296               (clobber (match_operand:SI 3 "register_operand" ""))
3297               (clobber (match_operand:SI 6 "register_operand" ""))
3298               (clobber (match_operand:SI 7 "register_operand" ""))
3299               (clobber (match_operand:SI 8 "register_operand" ""))
3300               (use (match_operand:SI 4 "arith14_operand" ""))
3301               (use (match_operand:SI 5 "const_int_operand" ""))])]
3302   "!TARGET_64BIT && reload_completed && !flag_peephole2
3303    && GET_CODE (operands[0]) == MEM
3304    && register_operand (XEXP (operands[0], 0), SImode)
3305    && GET_CODE (operands[1]) == MEM
3306    && register_operand (XEXP (operands[1], 0), SImode)"
3307   [(set (match_dup 7) (match_dup 9))
3308    (set (match_dup 8) (match_dup 10))
3309    (parallel [(set (match_dup 0) (match_dup 1))
3310               (clobber (match_dup 2))
3311               (clobber (match_dup 3))
3312               (clobber (match_dup 6))
3313               (clobber (match_dup 7))
3314               (clobber (match_dup 8))
3315               (use (match_dup 4))
3316               (use (match_dup 5))
3317               (const_int 0)])]
3318   "
3320   operands[9] = XEXP (operands[0], 0);
3321   operands[10] = XEXP (operands[1], 0);
3322   operands[0] = replace_equiv_address (operands[0], operands[7]);
3323   operands[1] = replace_equiv_address (operands[1], operands[8]);
3326 (define_peephole2
3327   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3328                    (match_operand:BLK 1 "memory_operand" ""))
3329               (clobber (match_operand:SI 2 "register_operand" ""))
3330               (clobber (match_operand:SI 3 "register_operand" ""))
3331               (clobber (match_operand:SI 6 "register_operand" ""))
3332               (clobber (match_operand:SI 7 "register_operand" ""))
3333               (clobber (match_operand:SI 8 "register_operand" ""))
3334               (use (match_operand:SI 4 "arith14_operand" ""))
3335               (use (match_operand:SI 5 "const_int_operand" ""))])]
3336   "!TARGET_64BIT
3337    && GET_CODE (operands[0]) == MEM
3338    && register_operand (XEXP (operands[0], 0), SImode)
3339    && GET_CODE (operands[1]) == MEM
3340    && register_operand (XEXP (operands[1], 0), SImode)"
3341   [(parallel [(set (match_dup 0) (match_dup 1))
3342               (clobber (match_dup 2))
3343               (clobber (match_dup 3))
3344               (clobber (match_dup 6))
3345               (clobber (match_dup 7))
3346               (clobber (match_dup 8))
3347               (use (match_dup 4))
3348               (use (match_dup 5))
3349               (const_int 0)])]
3350   "
3352   rtx addr = XEXP (operands[0], 0);
3353   if (dead_or_set_p (curr_insn, addr))
3354     operands[7] = addr;
3355   else
3356     {
3357       emit_insn (gen_rtx_SET (operands[7], addr));
3358       operands[0] = replace_equiv_address (operands[0], operands[7]);
3359     }
3361   addr = XEXP (operands[1], 0);
3362   if (dead_or_set_p (curr_insn, addr))
3363     operands[8] = addr;
3364   else
3365     {
3366       emit_insn (gen_rtx_SET (operands[8], addr));
3367       operands[1] = replace_equiv_address (operands[1], operands[8]);
3368     }
3371 (define_insn "cpymemsi_postreload"
3372   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3373         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3374    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3375    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3376    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3377    (clobber (match_dup 0))
3378    (clobber (match_dup 1))
3379    (use (match_operand:SI 4 "arith14_operand" "J,2"))    ;byte count
3380    (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3381    (const_int 0)]
3382   "!TARGET_64BIT && reload_completed"
3383   "* return pa_output_block_move (operands, !which_alternative);"
3384   [(set_attr "type" "multi,multi")])
3386 (define_expand "cpymemdi"
3387   [(parallel [(set (match_operand:BLK 0 "" "")
3388                    (match_operand:BLK 1 "" ""))
3389               (clobber (match_dup 4))
3390               (clobber (match_dup 5))
3391               (clobber (match_dup 6))
3392               (clobber (match_dup 7))
3393               (clobber (match_dup 8))
3394               (use (match_operand:DI 2 "arith14_operand" ""))
3395               (use (match_operand:DI 3 "const_int_operand" ""))])]
3396   "TARGET_64BIT && optimize > 0"
3397   "
3399   int size, align;
3401   /* HP provides very fast block move library routine for the PA;
3402      this routine includes:
3404         4x4 byte at a time block moves,
3405         1x4 byte at a time with alignment checked at runtime with
3406             attempts to align the source and destination as needed
3407         1x1 byte loop
3409      With that in mind, here's the heuristics to try and guess when
3410      the inlined block move will be better than the library block
3411      move:
3413         If the size isn't constant, then always use the library routines.
3415         If the size is large in respect to the known alignment, then use
3416         the library routines.
3418         If the size is small in respect to the known alignment, then open
3419         code the copy (since that will lead to better scheduling).
3421         Else use the block move pattern.   */
3423   /* Undetermined size, use the library routine.  */
3424   if (GET_CODE (operands[2]) != CONST_INT)
3425     FAIL;
3427   size = INTVAL (operands[2]);
3428   align = INTVAL (operands[3]);
3429   align = align > 8 ? 8 : (align ? align : 1);
3431   /* If size/alignment is large, then use the library routines.  */
3432   if (size / align > 16)
3433     FAIL;
3435   /* This does happen, but not often enough to worry much about.  */
3436   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3437     FAIL;
3438   
3439   /* Fall through means we're going to use our block move pattern.  */
3440   operands[0]
3441     = replace_equiv_address (operands[0],
3442                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3443   operands[1]
3444     = replace_equiv_address (operands[1],
3445                              copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3446   operands[4] = gen_reg_rtx (DImode);
3447   operands[5] = gen_reg_rtx (DImode);
3448   operands[6] = gen_reg_rtx (DImode);
3449   operands[7] = gen_reg_rtx (DImode);
3450   operands[8] = gen_reg_rtx (DImode);
3453 ;; The operand constraints are written like this to support both compile-time
3454 ;; and run-time determined byte counts.  The expander and pa_output_block_move
3455 ;; only support compile-time determined counts at this time.
3457 ;; If the count is run-time determined, the register with the byte count
3458 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3460 ;; We used to clobber operands 0 and 1.  However, a change to regrename.cc
3461 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3462 ;; as this requires two registers in the class R1_REGS when the MEMs for
3463 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3464 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3465 ;; respectively.  We then split or peephole optimize after reload.
3466 (define_insn "cpymemdi_prereload"
3467   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3468         (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3469    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3470    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3471    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3472    (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))   ;item tmp3
3473    (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))   ;item tmp4
3474    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3475    (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3476   "TARGET_64BIT"
3477   "#"
3478   [(set_attr "type" "multi,multi")])
3480 (define_split
3481   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3482                    (match_operand:BLK 1 "memory_operand" ""))
3483               (clobber (match_operand:DI 2 "register_operand" ""))
3484               (clobber (match_operand:DI 3 "register_operand" ""))
3485               (clobber (match_operand:DI 6 "register_operand" ""))
3486               (clobber (match_operand:DI 7 "register_operand" ""))
3487               (clobber (match_operand:DI 8 "register_operand" ""))
3488               (use (match_operand:DI 4 "arith14_operand" ""))
3489               (use (match_operand:DI 5 "const_int_operand" ""))])]
3490   "TARGET_64BIT && reload_completed && !flag_peephole2
3491    && GET_CODE (operands[0]) == MEM
3492    && register_operand (XEXP (operands[0], 0), DImode)
3493    && GET_CODE (operands[1]) == MEM
3494    && register_operand (XEXP (operands[1], 0), DImode)"
3495   [(set (match_dup 7) (match_dup 9))
3496    (set (match_dup 8) (match_dup 10))
3497    (parallel [(set (match_dup 0) (match_dup 1))
3498               (clobber (match_dup 2))
3499               (clobber (match_dup 3))
3500               (clobber (match_dup 6))
3501               (clobber (match_dup 7))
3502               (clobber (match_dup 8))
3503               (use (match_dup 4))
3504               (use (match_dup 5))
3505               (const_int 0)])]
3506   "
3508   operands[9] = XEXP (operands[0], 0);
3509   operands[10] = XEXP (operands[1], 0);
3510   operands[0] = replace_equiv_address (operands[0], operands[7]);
3511   operands[1] = replace_equiv_address (operands[1], operands[8]);
3514 (define_peephole2
3515   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3516                    (match_operand:BLK 1 "memory_operand" ""))
3517               (clobber (match_operand:DI 2 "register_operand" ""))
3518               (clobber (match_operand:DI 3 "register_operand" ""))
3519               (clobber (match_operand:DI 6 "register_operand" ""))
3520               (clobber (match_operand:DI 7 "register_operand" ""))
3521               (clobber (match_operand:DI 8 "register_operand" ""))
3522               (use (match_operand:DI 4 "arith14_operand" ""))
3523               (use (match_operand:DI 5 "const_int_operand" ""))])]
3524   "TARGET_64BIT
3525    && GET_CODE (operands[0]) == MEM
3526    && register_operand (XEXP (operands[0], 0), DImode)
3527    && GET_CODE (operands[1]) == MEM
3528    && register_operand (XEXP (operands[1], 0), DImode)"
3529   [(parallel [(set (match_dup 0) (match_dup 1))
3530               (clobber (match_dup 2))
3531               (clobber (match_dup 3))
3532               (clobber (match_dup 6))
3533               (clobber (match_dup 7))
3534               (clobber (match_dup 8))
3535               (use (match_dup 4))
3536               (use (match_dup 5))
3537               (const_int 0)])]
3538   "
3540   rtx addr = XEXP (operands[0], 0);
3541   if (dead_or_set_p (curr_insn, addr))
3542     operands[7] = addr;
3543   else
3544     {
3545       emit_insn (gen_rtx_SET (operands[7], addr));
3546       operands[0] = replace_equiv_address (operands[0], operands[7]);
3547     }
3549   addr = XEXP (operands[1], 0);
3550   if (dead_or_set_p (curr_insn, addr))
3551     operands[8] = addr;
3552   else
3553     {
3554       emit_insn (gen_rtx_SET (operands[8], addr));
3555       operands[1] = replace_equiv_address (operands[1], operands[8]);
3556     }
3559 (define_insn "cpymemdi_postreload"
3560   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3561         (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3562    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3563    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3564    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3565    (clobber (match_dup 0))
3566    (clobber (match_dup 1))
3567    (use (match_operand:DI 4 "arith14_operand" "J,2"))    ;byte count
3568    (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3569    (const_int 0)]
3570   "TARGET_64BIT && reload_completed"
3571   "* return pa_output_block_move (operands, !which_alternative);"
3572   [(set_attr "type" "multi,multi")])
3574 (define_expand "setmemsi"
3575   [(parallel [(set (match_operand:BLK 0 "" "")
3576                    (match_operand 2 "const_int_operand" ""))
3577               (clobber (match_dup 4))
3578               (clobber (match_dup 5))
3579               (use (match_operand:SI 1 "arith14_operand" ""))
3580               (use (match_operand:SI 3 "const_int_operand" ""))])]
3581   "!TARGET_64BIT && optimize > 0"
3582   "
3584   int size, align;
3586   /* If value to set is not zero, use the library routine.  */
3587   if (operands[2] != const0_rtx)
3588     FAIL;
3590   /* Undetermined size, use the library routine.  */
3591   if (GET_CODE (operands[1]) != CONST_INT)
3592     FAIL;
3594   size = INTVAL (operands[1]);
3595   align = INTVAL (operands[3]);
3596   align = align > 4 ? 4 : align;
3598   /* If size/alignment is large, then use the library routines.  */
3599   if (size / align > 16)
3600     FAIL;
3602   /* This does happen, but not often enough to worry much about.  */
3603   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3604     FAIL;
3605   
3606   /* Fall through means we're going to use our block clear pattern.  */
3607   operands[0]
3608     = replace_equiv_address (operands[0],
3609                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3610   operands[4] = gen_reg_rtx (SImode);
3611   operands[5] = gen_reg_rtx (SImode);
3614 (define_insn "clrmemsi_prereload"
3615   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3616         (const_int 0))
3617    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3618    (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))   ;tmp1
3619    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3620    (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3621   "!TARGET_64BIT"
3622   "#"
3623   [(set_attr "type" "multi,multi")])
3625 (define_split
3626   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3627                    (const_int 0))
3628               (clobber (match_operand:SI 1 "register_operand" ""))
3629               (clobber (match_operand:SI 4 "register_operand" ""))
3630               (use (match_operand:SI 2 "arith14_operand" ""))
3631               (use (match_operand:SI 3 "const_int_operand" ""))])]
3632   "!TARGET_64BIT && reload_completed && !flag_peephole2
3633    && GET_CODE (operands[0]) == MEM
3634    && register_operand (XEXP (operands[0], 0), SImode)"
3635   [(set (match_dup 4) (match_dup 5))
3636    (parallel [(set (match_dup 0) (const_int 0))
3637               (clobber (match_dup 1))
3638               (clobber (match_dup 4))
3639               (use (match_dup 2))
3640               (use (match_dup 3))
3641               (const_int 0)])]
3642   "
3644   operands[5] = XEXP (operands[0], 0);
3645   operands[0] = replace_equiv_address (operands[0], operands[4]);
3648 (define_peephole2
3649   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3650                    (const_int 0))
3651               (clobber (match_operand:SI 1 "register_operand" ""))
3652               (clobber (match_operand:SI 4 "register_operand" ""))
3653               (use (match_operand:SI 2 "arith14_operand" ""))
3654               (use (match_operand:SI 3 "const_int_operand" ""))])]
3655   "!TARGET_64BIT
3656    && GET_CODE (operands[0]) == MEM
3657    && register_operand (XEXP (operands[0], 0), SImode)"
3658   [(parallel [(set (match_dup 0) (const_int 0))
3659               (clobber (match_dup 1))
3660               (clobber (match_dup 4))
3661               (use (match_dup 2))
3662               (use (match_dup 3))
3663               (const_int 0)])]
3664   "
3666   rtx addr = XEXP (operands[0], 0);
3667   if (dead_or_set_p (curr_insn, addr))
3668     operands[4] = addr;
3669   else
3670     {
3671       emit_insn (gen_rtx_SET (operands[4], addr));
3672       operands[0] = replace_equiv_address (operands[0], operands[4]);
3673     }
3676 (define_insn "clrmemsi_postreload"
3677   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3678         (const_int 0))
3679    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3680    (clobber (match_dup 0))
3681    (use (match_operand:SI 2 "arith14_operand" "J,1"))    ;byte count
3682    (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3683    (const_int 0)]
3684   "!TARGET_64BIT && reload_completed"
3685   "* return pa_output_block_clear (operands, !which_alternative);"
3686   [(set_attr "type" "multi,multi")])
3688 (define_expand "setmemdi"
3689   [(parallel [(set (match_operand:BLK 0 "" "")
3690                    (match_operand 2 "const_int_operand" ""))
3691               (clobber (match_dup 4))
3692               (clobber (match_dup 5))
3693               (use (match_operand:DI 1 "arith14_operand" ""))
3694               (use (match_operand:DI 3 "const_int_operand" ""))])]
3695   "TARGET_64BIT && optimize > 0"
3696   "
3698   int size, align;
3700   /* If value to set is not zero, use the library routine.  */
3701   if (operands[2] != const0_rtx)
3702     FAIL;
3704   /* Undetermined size, use the library routine.  */
3705   if (GET_CODE (operands[1]) != CONST_INT)
3706     FAIL;
3708   size = INTVAL (operands[1]);
3709   align = INTVAL (operands[3]);
3710   align = align > 8 ? 8 : align;
3712   /* If size/alignment is large, then use the library routines.  */
3713   if (size / align > 16)
3714     FAIL;
3716   /* This does happen, but not often enough to worry much about.  */
3717   if (size / align < MOVE_RATIO (optimize_insn_for_speed_p ()))
3718     FAIL;
3719   
3720   /* Fall through means we're going to use our block clear pattern.  */
3721   operands[0]
3722     = replace_equiv_address (operands[0],
3723                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3724   operands[4] = gen_reg_rtx (DImode);
3725   operands[5] = gen_reg_rtx (DImode);
3728 (define_insn "clrmemdi_prereload"
3729   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3730         (const_int 0))
3731    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3732    (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))   ;item tmp1
3733    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3734    (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3735   "TARGET_64BIT"
3736   "#"
3737   [(set_attr "type" "multi,multi")])
3739 (define_split
3740   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3741                    (const_int 0))
3742               (clobber (match_operand:DI 1 "register_operand" ""))
3743               (clobber (match_operand:DI 4 "register_operand" ""))
3744               (use (match_operand:DI 2 "arith14_operand" ""))
3745               (use (match_operand:DI 3 "const_int_operand" ""))])]
3746   "TARGET_64BIT && reload_completed && !flag_peephole2
3747    && GET_CODE (operands[0]) == MEM
3748    && register_operand (XEXP (operands[0], 0), DImode)"
3749   [(set (match_dup 4) (match_dup 5))
3750    (parallel [(set (match_dup 0) (const_int 0))
3751               (clobber (match_dup 1))
3752               (clobber (match_dup 4))
3753               (use (match_dup 2))
3754               (use (match_dup 3))
3755               (const_int 0)])]
3756   "
3758   operands[5] = XEXP (operands[0], 0);
3759   operands[0] = replace_equiv_address (operands[0], operands[4]);
3762 (define_peephole2
3763   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3764                    (const_int 0))
3765               (clobber (match_operand:DI 1 "register_operand" ""))
3766               (clobber (match_operand:DI 4 "register_operand" ""))
3767               (use (match_operand:DI 2 "arith14_operand" ""))
3768               (use (match_operand:DI 3 "const_int_operand" ""))])]
3769   "TARGET_64BIT
3770    && GET_CODE (operands[0]) == MEM
3771    && register_operand (XEXP (operands[0], 0), DImode)"
3772   [(parallel [(set (match_dup 0) (const_int 0))
3773               (clobber (match_dup 1))
3774               (clobber (match_dup 4))
3775               (use (match_dup 2))
3776               (use (match_dup 3))
3777               (const_int 0)])]
3778   "
3779 {  
3780   rtx addr = XEXP (operands[0], 0);
3781   if (dead_or_set_p (curr_insn, addr))
3782     operands[4] = addr;
3783   else
3784     {
3785       emit_insn (gen_rtx_SET (operands[4], addr));
3786       operands[0] = replace_equiv_address (operands[0], operands[4]);
3787     }
3790 (define_insn "clrmemdi_postreload"
3791   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3792         (const_int 0))
3793    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3794    (clobber (match_dup 0))
3795    (use (match_operand:DI 2 "arith14_operand" "J,1"))    ;byte count
3796    (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3797    (const_int 0)]
3798   "TARGET_64BIT && reload_completed"
3799   "* return pa_output_block_clear (operands, !which_alternative);"
3800   [(set_attr "type" "multi,multi")])
3802 ;; Floating point move insns
3804 (define_expand "movdf"
3805   [(set (match_operand:DF 0 "general_operand" "")
3806         (match_operand:DF 1 "general_operand" ""))]
3807   ""
3808   "
3810   if (pa_emit_move_sequence (operands, DFmode, 0))
3811     DONE;
3814 ;; Handle DFmode input reloads requiring %r1 as a scratch register.
3815 (define_expand "reload_indf_r1"
3816   [(set (match_operand:DF 0 "register_operand" "=Z")
3817         (match_operand:DF 1 "non_hard_reg_operand" ""))
3818    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
3819   ""
3820   "
3822   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3823     DONE;
3825   /* We don't want the clobber emitted, so handle this ourselves.  */
3826   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3827   DONE;
3830 ;; Handle DFmode input reloads requiring a general register as a
3831 ;; scratch register.
3832 (define_expand "reload_indf"
3833   [(set (match_operand:DF 0 "register_operand" "=Z")
3834         (match_operand:DF 1 "non_hard_reg_operand" ""))
3835    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3836   ""
3837   "
3839   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3840     DONE;
3842   /* We don't want the clobber emitted, so handle this ourselves.  */
3843   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3844   DONE;
3847 ;; Handle DFmode output reloads requiring a general register as a
3848 ;; scratch register.
3849 (define_expand "reload_outdf" 
3850  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3851         (match_operand:DF 1  "register_operand" "Z"))
3852    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3853   ""
3854   "
3856   if (pa_emit_move_sequence (operands, DFmode, operands[2]))
3857     DONE;
3859   /* We don't want the clobber emitted, so handle this ourselves.  */
3860   emit_insn (gen_rtx_SET (operands[0], operands[1]));
3861   DONE;
3864 (define_insn ""
3865   [(set (match_operand:DF 0 "move_dest_operand"
3866                           "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f")
3867         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3868                           "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))]
3869   "(register_operand (operands[0], DFmode)
3870     || reg_or_0_operand (operands[1], DFmode))
3871    && !(GET_CODE (operands[1]) == CONST_DOUBLE
3872         && GET_CODE (operands[0]) == MEM)
3873    && !TARGET_64BIT
3874    && !TARGET_SOFT_FLOAT"
3875   "*
3877   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3878        || operands[1] == CONST0_RTX (DFmode))
3879       && !(REG_P (operands[0]) && REG_P (operands[1])
3880            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
3881     return pa_output_fp_move_double (operands);
3882   return pa_output_move_double (operands);
3884   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load,fpstore_load,store_fpload")
3885    (set_attr "length" "4,8,4,8,16,4,8,16,12,12")])
3887 (define_insn ""
3888   [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3889         (match_operand:DF 1 "reg_or_0_operand" "f"))]
3890   "!TARGET_SOFT_FLOAT
3891    && !TARGET_DISABLE_INDEXING
3892    && reload_completed"
3893   "fstd%F0 %1,%0"
3894   [(set_attr "type" "fpstore")
3895    (set_attr "pa_combine_type" "addmove")
3896    (set_attr "length" "4")])
3898 (define_peephole2
3899   [(set (match_operand:SI 0 "register_operand" "")
3900         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3901                             (const_int 3))
3902                  (match_operand:SI 2 "register_operand" "")))
3903    (set (mem:DF (match_dup 0))
3904         (match_operand:DF 3 "register_operand" ""))]
3905   "!TARGET_SOFT_FLOAT
3906    && !TARGET_DISABLE_INDEXING
3907    && REG_OK_FOR_BASE_P (operands[2])
3908    && FP_REGNO_P (REGNO (operands[3]))"
3909   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3910         (match_dup 3))
3911    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3912                                (match_dup 2)))]
3913   "")
3915 (define_peephole2
3916   [(set (match_operand:SI 0 "register_operand" "")
3917         (plus:SI (match_operand:SI 2 "register_operand" "")
3918                  (ashift:SI (match_operand:SI 1 "register_operand" "")
3919                             (const_int 3))))
3920    (set (mem:DF (match_dup 0))
3921         (match_operand:DF 3 "register_operand" ""))]
3922   "!TARGET_SOFT_FLOAT
3923    && !TARGET_DISABLE_INDEXING
3924    && REG_OK_FOR_BASE_P (operands[2])
3925    && FP_REGNO_P (REGNO (operands[3]))"
3926   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3927         (match_dup 3))
3928    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 3))
3929                                (match_dup 2)))]
3930   "")
3932 (define_peephole2
3933   [(set (match_operand:DI 0 "register_operand" "")
3934         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
3935                             (const_int 3))
3936                  (match_operand:DI 2 "register_operand" "")))
3937    (set (mem:DF (match_dup 0))
3938         (match_operand:DF 3 "register_operand" ""))]
3939   "!TARGET_SOFT_FLOAT
3940    && !TARGET_DISABLE_INDEXING
3941    && TARGET_64BIT
3942    && REG_OK_FOR_BASE_P (operands[2])
3943    && FP_REGNO_P (REGNO (operands[3]))"
3944   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3945         (match_dup 3))
3946    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3947                                (match_dup 2)))]
3948   "")
3950 (define_peephole2
3951   [(set (match_operand:DI 0 "register_operand" "")
3952         (plus:DI (match_operand:DI 2 "register_operand" "")
3953                  (ashift:DI (match_operand:DI 1 "register_operand" "")
3954                             (const_int 3))))
3955    (set (mem:DF (match_dup 0))
3956         (match_operand:DF 3 "register_operand" ""))]
3957   "!TARGET_SOFT_FLOAT
3958    && !TARGET_DISABLE_INDEXING
3959    && TARGET_64BIT
3960    && REG_OK_FOR_BASE_P (operands[2])
3961    && FP_REGNO_P (REGNO (operands[3]))"
3962   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3963         (match_dup 3))
3964    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
3965                                (match_dup 2)))]
3966   "")
3968 (define_peephole2
3969   [(set (match_operand:SI 0 "register_operand" "")
3970         (plus:SI (match_operand:SI 1 "register_operand" "")
3971                  (match_operand:SI 2 "register_operand" "")))
3972    (set (mem:DF (match_dup 0))
3973         (match_operand:DF 3 "register_operand" ""))]
3974   "!TARGET_SOFT_FLOAT
3975    && !TARGET_DISABLE_INDEXING
3976    && TARGET_NO_SPACE_REGS
3977    && REG_OK_FOR_INDEX_P (operands[1])
3978    && REG_OK_FOR_BASE_P (operands[2])
3979    && FP_REGNO_P (REGNO (operands[3]))"
3980   [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3981         (match_dup 3))
3982    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3983   "")
3985 (define_peephole2
3986   [(set (match_operand:SI 0 "register_operand" "")
3987         (plus:SI (match_operand:SI 1 "register_operand" "")
3988                  (match_operand:SI 2 "register_operand" "")))
3989    (set (mem:DF (match_dup 0))
3990         (match_operand:DF 3 "register_operand" ""))]
3991   "!TARGET_SOFT_FLOAT
3992    && !TARGET_DISABLE_INDEXING
3993    && TARGET_NO_SPACE_REGS
3994    && REG_OK_FOR_BASE_P (operands[1])
3995    && REG_OK_FOR_INDEX_P (operands[2])
3996    && FP_REGNO_P (REGNO (operands[3]))"
3997   [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3998         (match_dup 3))
3999    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4000   "")
4002 (define_peephole2
4003   [(set (match_operand:DI 0 "register_operand" "")
4004         (plus:DI (match_operand:DI 1 "register_operand" "")
4005                  (match_operand:DI 2 "register_operand" "")))
4006    (set (mem:DF (match_dup 0))
4007         (match_operand:DF 3 "register_operand" ""))]
4008   "!TARGET_SOFT_FLOAT
4009    && !TARGET_DISABLE_INDEXING
4010    && TARGET_64BIT
4011    && TARGET_NO_SPACE_REGS
4012    && REG_OK_FOR_INDEX_P (operands[1])
4013    && REG_OK_FOR_BASE_P (operands[2])
4014    && FP_REGNO_P (REGNO (operands[3]))"
4015   [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
4016         (match_dup 3))
4017    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4018   "")
4020 (define_peephole2
4021   [(set (match_operand:DI 0 "register_operand" "")
4022         (plus:DI (match_operand:DI 1 "register_operand" "")
4023                  (match_operand:DI 2 "register_operand" "")))
4024    (set (mem:DF (match_dup 0))
4025         (match_operand:DF 3 "register_operand" ""))]
4026   "!TARGET_SOFT_FLOAT
4027    && !TARGET_DISABLE_INDEXING
4028    && TARGET_64BIT
4029    && TARGET_NO_SPACE_REGS
4030    && REG_OK_FOR_BASE_P (operands[1])
4031    && REG_OK_FOR_INDEX_P (operands[2])
4032    && FP_REGNO_P (REGNO (operands[3]))"
4033   [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
4034         (match_dup 3))
4035    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4036   "")
4038 (define_insn ""
4039   [(set (match_operand:DF 0 "move_dest_operand"
4040                           "=r,?o,?Q,r,r")
4041         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
4042                           "rG,r,r,o,RQ"))]
4043   "(register_operand (operands[0], DFmode)
4044     || reg_or_0_operand (operands[1], DFmode))
4045    && !TARGET_64BIT
4046    && TARGET_SOFT_FLOAT"
4047   "*
4049   return pa_output_move_double (operands);
4051   [(set_attr "type" "move,store,store,load,load")
4052    (set_attr "length" "8,8,16,8,16")])
4054 (define_insn ""
4055   [(set (match_operand:DF 0 "move_dest_operand"
4056                           "=!*r,*r,*r,*r,*r,Q,f,f,T")
4057         (match_operand:DF 1 "move_src_operand"
4058                           "!*rG,J,N,K,RQ,*rG,fG,RT,f"))]
4059   "(register_operand (operands[0], DFmode)
4060     || reg_or_0_operand (operands[1], DFmode))
4061    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4062   "@
4063    copy %r1,%0
4064    ldi %1,%0
4065    ldil L'%1,%0
4066    depdi,z %z1,%0
4067    ldd%M1 %1,%0
4068    std%M0 %r1,%0
4069    fcpy,dbl %f1,%0
4070    fldd%F1 %1,%0
4071    fstd%F0 %1,%0"
4072   [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4073    (set_attr "pa_combine_type" "addmove")
4074    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4076 (define_insn ""
4077   [(set (match_operand:DF 0 "move_dest_operand"
4078                           "=!*r,*r,*r,*r,*r,Q")
4079         (match_operand:DF 1 "move_src_operand"
4080                           "!*rG,J,N,K,RQ,*rG"))]
4081   "(register_operand (operands[0], DFmode)
4082     || reg_or_0_operand (operands[1], DFmode))
4083    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4084   "@
4085    copy %r1,%0
4086    ldi %1,%0
4087    ldil L'%1,%0
4088    depdi,z %z1,%0
4089    ldd%M1 %1,%0
4090    std%M0 %r1,%0"
4091   [(set_attr "type" "move,move,move,shift,load,store")
4092    (set_attr "pa_combine_type" "addmove")
4093    (set_attr "length" "4,4,4,4,4,4")])
4096 (define_expand "movdi"
4097   [(set (match_operand:DI 0 "general_operand" "")
4098         (match_operand:DI 1 "general_operand" ""))]
4099   ""
4100   "
4102   if (pa_emit_move_sequence (operands, DImode, 0))
4103     DONE;
4106 ;; Handle DImode input reloads requiring %r1 as a scratch register.
4107 (define_expand "reload_indi_r1"
4108   [(set (match_operand:DI 0 "register_operand" "=Z")
4109         (match_operand:DI 1 "non_hard_reg_operand" ""))
4110    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4111   ""
4112   "
4114   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4115     DONE;
4117   /* We don't want the clobber emitted, so handle this ourselves.  */
4118   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4119   DONE;
4122 ;; Handle DImode input reloads requiring a general register as a
4123 ;; scratch register.
4124 (define_expand "reload_indi"
4125   [(set (match_operand:DI 0 "register_operand" "=Z")
4126         (match_operand:DI 1 "non_hard_reg_operand" ""))
4127    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4128   ""
4129   "
4131   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4132     DONE;
4134   /* We don't want the clobber emitted, so handle this ourselves.  */
4135   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4136   DONE;
4139 ;; Handle DImode output reloads requiring a general register as a
4140 ;; scratch register.
4141 (define_expand "reload_outdi"
4142   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4143         (match_operand:DI 1 "register_operand" "Z"))
4144    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4145   ""
4146   "
4148   if (pa_emit_move_sequence (operands, DImode, operands[2]))
4149     DONE;
4151   /* We don't want the clobber emitted, so handle this ourselves.  */
4152   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4153   DONE;
4156 (define_insn ""
4157   [(set (match_operand:DI 0 "register_operand" "=r")
4158         (high:DI (match_operand 1 "" "")))]
4159   "!TARGET_64BIT"
4160   "*
4162   rtx op0 = operands[0];
4163   rtx op1 = operands[1];
4165   switch (GET_CODE (op1))
4166     {
4167     case CONST_INT:
4168 #if HOST_BITS_PER_WIDE_INT <= 32
4169       operands[0] = operand_subword (op0, 1, 0, DImode);
4170       output_asm_insn (\"ldil L'%1,%0\", operands);
4172       operands[0] = operand_subword (op0, 0, 0, DImode);
4173       if (INTVAL (op1) < 0)
4174         output_asm_insn (\"ldi -1,%0\", operands);
4175       else
4176         output_asm_insn (\"ldi 0,%0\", operands);
4177 #else
4178       operands[0] = operand_subword (op0, 1, 0, DImode);
4179       operands[1] = GEN_INT (INTVAL (op1) & 0xffffffff);
4180       output_asm_insn (\"ldil L'%1,%0\", operands);
4182       operands[0] = operand_subword (op0, 0, 0, DImode);
4183       operands[1] = GEN_INT (INTVAL (op1) >> 32);
4184       output_asm_insn (pa_singlemove_string (operands), operands);
4185 #endif
4186       break;
4188     case CONST_DOUBLE:
4189       operands[0] = operand_subword (op0, 1, 0, DImode);
4190       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4191       output_asm_insn (\"ldil L'%1,%0\", operands);
4193       operands[0] = operand_subword (op0, 0, 0, DImode);
4194       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4195       output_asm_insn (pa_singlemove_string (operands), operands);
4196       break;
4198     default:
4199       gcc_unreachable ();
4200     }
4201   return \"\";
4203   [(set_attr "type" "move")
4204    (set_attr "length" "12")])
4206 (define_insn ""
4207   [(set (match_operand:DI 0 "move_dest_operand"
4208                           "=r,o,Q,r,r,r,*f,*f,T,?r,?*f")
4209         (match_operand:DI 1 "move_src_operand"
4210                           "rM,r,r,o*R,Q,i,*fM,RT,*f,*f,r"))]
4211   "(register_operand (operands[0], DImode)
4212     || reg_or_0_operand (operands[1], DImode))
4213    && !TARGET_64BIT
4214    && !TARGET_SOFT_FLOAT"
4215   "*
4217   if ((FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4218        || operands[1] == CONST0_RTX (DFmode))
4219       && !(REG_P (operands[0]) && REG_P (operands[1])
4220            && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1])))
4221     return pa_output_fp_move_double (operands);
4222   return pa_output_move_double (operands);
4224   [(set_attr "type"
4225     "move,store,store,load,load,multi,fpalu,fpload,fpstore,fpstore_load,store_fpload")
4226    (set_attr "length" "8,8,16,8,16,16,4,4,4,12,12")])
4228 (define_insn ""
4229   [(set (match_operand:DI 0 "move_dest_operand"
4230                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4231         (match_operand:DI 1 "move_src_operand"
4232                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4233   "(register_operand (operands[0], DImode)
4234     || reg_or_0_operand (operands[1], DImode))
4235    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4236   "@
4237    ldd RT'%A1,%0
4238    copy %1,%0
4239    ldi %1,%0
4240    ldil L'%1,%0
4241    depdi,z %z1,%0
4242    ldd%M1 %1,%0
4243    std%M0 %r1,%0
4244    mtsar %r1
4245    {mfctl|mfctl,w} %%sar,%0
4246    fcpy,dbl %f1,%0
4247    fldd%F1 %1,%0
4248    fstd%F0 %1,%0"
4249   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4250    (set_attr "pa_combine_type" "addmove")
4251    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4253 (define_insn ""
4254   [(set (match_operand:DI 0 "move_dest_operand"
4255                           "=r,r,r,r,r,r,Q,!*q,!r")
4256         (match_operand:DI 1 "move_src_operand"
4257                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
4258   "(register_operand (operands[0], DImode)
4259     || reg_or_0_operand (operands[1], DImode))
4260    && TARGET_SOFT_FLOAT && TARGET_64BIT"
4261   "@
4262    ldd RT'%A1,%0
4263    copy %1,%0
4264    ldi %1,%0
4265    ldil L'%1,%0
4266    depdi,z %z1,%0
4267    ldd%M1 %1,%0
4268    std%M0 %r1,%0
4269    mtsar %r1
4270    {mfctl|mfctl,w} %%sar,%0"
4271   [(set_attr "type" "load,move,move,move,shift,load,store,move,move")
4272    (set_attr "pa_combine_type" "addmove")
4273    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4275 (define_insn ""
4276   [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4277         (match_operand:DI 1 "register_operand" "f"))]
4278   "!TARGET_SOFT_FLOAT
4279    && TARGET_64BIT
4280    && !TARGET_DISABLE_INDEXING
4281    && reload_completed"
4282   "fstd%F0 %1,%0"
4283   [(set_attr "type" "fpstore")
4284    (set_attr "pa_combine_type" "addmove")
4285    (set_attr "length" "4")])
4287 (define_peephole2
4288   [(set (match_operand:DI 0 "register_operand" "")
4289         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4290                             (const_int 3))
4291                  (match_operand:DI 2 "register_operand" "")))
4292    (set (mem:DI (match_dup 0))
4293         (match_operand:DI 3 "register_operand" ""))]
4294   "!TARGET_SOFT_FLOAT
4295    && !TARGET_DISABLE_INDEXING
4296    && TARGET_64BIT
4297    && REG_OK_FOR_BASE_P (operands[2])
4298    && FP_REGNO_P (REGNO (operands[3]))"
4299   [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4300         (match_dup 3))
4301    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 3))
4302                                (match_dup 2)))]
4303   "")
4305 (define_peephole2
4306   [(set (match_operand:DI 0 "register_operand" "")
4307         (plus:DI (match_operand:DI 1 "register_operand" "")
4308                  (match_operand:DI 2 "register_operand" "")))
4309    (set (mem:DI (match_dup 0))
4310         (match_operand:DI 3 "register_operand" ""))]
4311   "!TARGET_SOFT_FLOAT
4312    && !TARGET_DISABLE_INDEXING
4313    && TARGET_64BIT
4314    && TARGET_NO_SPACE_REGS
4315    && REG_OK_FOR_INDEX_P (operands[1])
4316    && REG_OK_FOR_BASE_P (operands[2])
4317    && FP_REGNO_P (REGNO (operands[3]))"
4318   [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4319         (match_dup 3))
4320    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4321   "")
4323 (define_peephole2
4324   [(set (match_operand:DI 0 "register_operand" "")
4325         (plus:DI (match_operand:DI 1 "register_operand" "")
4326                  (match_operand:DI 2 "register_operand" "")))
4327    (set (mem:DI (match_dup 0))
4328         (match_operand:DI 3 "register_operand" ""))]
4329   "!TARGET_SOFT_FLOAT
4330    && !TARGET_DISABLE_INDEXING
4331    && TARGET_64BIT
4332    && TARGET_NO_SPACE_REGS
4333    && REG_OK_FOR_BASE_P (operands[1])
4334    && REG_OK_FOR_INDEX_P (operands[2])
4335    && FP_REGNO_P (REGNO (operands[3]))"
4336   [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4337         (match_dup 3))
4338    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4339   "")
4341 (define_insn ""
4342   [(set (match_operand:DI 0 "move_dest_operand"
4343                           "=r,o,Q,r,r,r")
4344         (match_operand:DI 1 "general_operand"
4345                           "rM,r,r,o,Q,i"))]
4346   "(register_operand (operands[0], DImode)
4347     || reg_or_0_operand (operands[1], DImode))
4348    && !TARGET_64BIT
4349    && TARGET_SOFT_FLOAT"
4350   "*
4352   return pa_output_move_double (operands);
4354   [(set_attr "type" "move,store,store,load,load,multi")
4355    (set_attr "length" "8,8,16,8,16,16")])
4357 (define_insn ""
4358   [(set (match_operand:DI 0 "register_operand" "=r,&r")
4359         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4360                    (match_operand:DI 2 "immediate_operand" "i,i")))]
4361   "!TARGET_64BIT"
4362   "*
4364   /* Don't output a 64-bit constant, since we can't trust the assembler to
4365      handle it correctly.  */
4366   if (GET_CODE (operands[2]) == CONST_DOUBLE)
4367     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4368   else if (HOST_BITS_PER_WIDE_INT > 32
4369            && GET_CODE (operands[2]) == CONST_INT)
4370     operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
4371   if (which_alternative == 1)
4372     output_asm_insn (\"copy %1,%0\", operands);
4373   return \"ldo R'%G2(%R1),%R0\";
4375   [(set_attr "type" "move,move")
4376    (set_attr "length" "4,8")])
4378 (define_expand "movsf"
4379   [(set (match_operand:SF 0 "general_operand" "")
4380         (match_operand:SF 1 "general_operand" ""))]
4381   ""
4382   "
4384   if (pa_emit_move_sequence (operands, SFmode, 0))
4385     DONE;
4388 ;; Handle SFmode input reloads requiring %r1 as a scratch register.
4389 (define_expand "reload_insf_r1"
4390   [(set (match_operand:SF 0 "register_operand" "=Z")
4391         (match_operand:SF 1 "non_hard_reg_operand" ""))
4392    (clobber (match_operand:SI 2 "register_operand" "=&a"))]
4393   ""
4394   "
4396   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4397     DONE;
4399   /* We don't want the clobber emitted, so handle this ourselves.  */
4400   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4401   DONE;
4404 ;; Handle SFmode input reloads requiring a general register as a
4405 ;; scratch register.
4406 (define_expand "reload_insf"
4407   [(set (match_operand:SF 0 "register_operand" "=Z")
4408         (match_operand:SF 1 "non_hard_reg_operand" ""))
4409    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4410   ""
4411   "
4413   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4414     DONE;
4416   /* We don't want the clobber emitted, so handle this ourselves.  */
4417   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4418   DONE;
4421 ;; Handle SFmode output reloads requiring a general register as a
4422 ;; scratch register.
4423 (define_expand "reload_outsf"
4424   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4425         (match_operand:SF 1  "register_operand" "Z"))
4426    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4427   ""
4428   "
4430   if (pa_emit_move_sequence (operands, SFmode, operands[2]))
4431     DONE;
4433   /* We don't want the clobber emitted, so handle this ourselves.  */
4434   emit_insn (gen_rtx_SET (operands[0], operands[1]));
4435   DONE;
4438 (define_insn ""
4439   [(set (match_operand:SF 0 "move_dest_operand"
4440                           "=f,!*r,f,*r,T,Q,?*r,?f")
4441         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4442                           "fG,!*rG,RT,RQ,f,*rG,f,*r"))]
4443   "(register_operand (operands[0], SFmode)
4444     || reg_or_0_operand (operands[1], SFmode))
4445    && !TARGET_SOFT_FLOAT
4446    && !TARGET_64BIT"
4447   "@
4448    fcpy,sgl %f1,%0
4449    copy %r1,%0
4450    fldw%F1 %1,%0
4451    ldw%M1 %1,%0
4452    fstw%F0 %1,%0
4453    stw%M0 %r1,%0
4454    {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
4455    {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
4456   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store,fpstore_load,store_fpload")
4457    (set_attr "pa_combine_type" "addmove")
4458    (set_attr "length" "4,4,4,4,4,4,8,8")])
4460 (define_insn ""
4461   [(set (match_operand:SF 0 "move_dest_operand"
4462                           "=f,!*r,f,*r,T,Q")
4463         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4464                           "fG,!*rG,RT,RQ,f,*rG"))]
4465   "(register_operand (operands[0], SFmode)
4466     || reg_or_0_operand (operands[1], SFmode))
4467    && !TARGET_SOFT_FLOAT
4468    && TARGET_64BIT"
4469   "@
4470    fcpy,sgl %f1,%0
4471    copy %r1,%0
4472    fldw%F1 %1,%0
4473    ldw%M1 %1,%0
4474    fstw%F0 %1,%0
4475    stw%M0 %r1,%0"
4476   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4477    (set_attr "pa_combine_type" "addmove")
4478    (set_attr "length" "4,4,4,4,4,4")])
4480 (define_insn ""
4481   [(set (match_operand:SF 0 "move_dest_operand"
4482                           "=!*r,*r,Q")
4483         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4484                           "!*rG,RQ,*rG"))]
4485   "(register_operand (operands[0], SFmode)
4486     || reg_or_0_operand (operands[1], SFmode))
4487    && TARGET_SOFT_FLOAT
4488    && TARGET_64BIT"
4489   "@
4490    copy %r1,%0
4491    ldw%M1 %1,%0
4492    stw%M0 %r1,%0"
4493   [(set_attr "type" "move,load,store")
4494    (set_attr "pa_combine_type" "addmove")
4495    (set_attr "length" "4,4,4")])
4497 (define_insn ""
4498   [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4499         (match_operand:SF 1 "register_operand" "f"))]
4500   "!TARGET_SOFT_FLOAT
4501    && !TARGET_DISABLE_INDEXING
4502    && reload_completed"
4503   "fstw%F0 %1,%0"
4504   [(set_attr "type" "fpstore")
4505    (set_attr "pa_combine_type" "addmove")
4506    (set_attr "length" "4")])
4508 (define_peephole2
4509   [(set (match_operand:SI 0 "register_operand" "")
4510         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4511                             (const_int 2))
4512                  (match_operand:SI 2 "register_operand" "")))
4513    (set (mem:SF (match_dup 0))
4514         (match_operand:SF 3 "register_operand" ""))]
4515   "!TARGET_SOFT_FLOAT
4516    && !TARGET_DISABLE_INDEXING
4517    && REG_OK_FOR_BASE_P (operands[2])
4518    && FP_REGNO_P (REGNO (operands[3]))"
4519   [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4520         (match_dup 3))
4521    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 1) (const_int 2))
4522                                (match_dup 2)))]
4523   "")
4525 (define_peephole2
4526   [(set (match_operand:DI 0 "register_operand" "")
4527         (plus:DI (ashift:DI (match_operand:DI 1 "register_operand" "")
4528                             (const_int 2))
4529                  (match_operand:DI 2 "register_operand" "")))
4530    (set (mem:SF (match_dup 0))
4531         (match_operand:SF 3 "register_operand" ""))]
4532   "!TARGET_SOFT_FLOAT
4533    && !TARGET_DISABLE_INDEXING
4534    && TARGET_64BIT
4535    && REG_OK_FOR_BASE_P (operands[2])
4536    && FP_REGNO_P (REGNO (operands[3]))"
4537   [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4538         (match_dup 3))
4539    (set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (const_int 2))
4540                                (match_dup 2)))]
4541   "")
4543 (define_peephole2
4544   [(set (match_operand:SI 0 "register_operand" "")
4545         (plus:SI (match_operand:SI 1 "register_operand" "")
4546                  (match_operand:SI 2 "register_operand" "")))
4547    (set (mem:SF (match_dup 0))
4548         (match_operand:SF 3 "register_operand" ""))]
4549   "!TARGET_SOFT_FLOAT
4550    && !TARGET_DISABLE_INDEXING
4551    && TARGET_NO_SPACE_REGS
4552    && REG_OK_FOR_INDEX_P (operands[1])
4553    && REG_OK_FOR_BASE_P (operands[2])
4554    && FP_REGNO_P (REGNO (operands[3]))"
4555   [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4556         (match_dup 3))
4557    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4558   "")
4560 (define_peephole2
4561   [(set (match_operand:SI 0 "register_operand" "")
4562         (plus:SI (match_operand:SI 1 "register_operand" "")
4563                  (match_operand:SI 2 "register_operand" "")))
4564    (set (mem:SF (match_dup 0))
4565         (match_operand:SF 3 "register_operand" ""))]
4566   "!TARGET_SOFT_FLOAT
4567    && !TARGET_DISABLE_INDEXING
4568    && TARGET_NO_SPACE_REGS
4569    && REG_OK_FOR_BASE_P (operands[1])
4570    && REG_OK_FOR_INDEX_P (operands[2])
4571    && FP_REGNO_P (REGNO (operands[3]))"
4572   [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4573         (match_dup 3))
4574    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4575   "")
4577 (define_peephole2
4578   [(set (match_operand:DI 0 "register_operand" "")
4579         (plus:DI (match_operand:DI 1 "register_operand" "")
4580                  (match_operand:DI 2 "register_operand" "")))
4581    (set (mem:SF (match_dup 0))
4582         (match_operand:SF 3 "register_operand" ""))]
4583   "!TARGET_SOFT_FLOAT
4584    && !TARGET_DISABLE_INDEXING
4585    && TARGET_64BIT
4586    && TARGET_NO_SPACE_REGS
4587    && REG_OK_FOR_INDEX_P (operands[1])
4588    && REG_OK_FOR_BASE_P (operands[2])
4589    && FP_REGNO_P (REGNO (operands[3]))"
4590   [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4591         (match_dup 3))
4592    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4593   "")
4595 (define_peephole2
4596   [(set (match_operand:DI 0 "register_operand" "")
4597         (plus:DI (match_operand:DI 1 "register_operand" "")
4598                  (match_operand:DI 2 "register_operand" "")))
4599    (set (mem:SF (match_dup 0))
4600         (match_operand:SF 3 "register_operand" ""))]
4601   "!TARGET_SOFT_FLOAT
4602    && !TARGET_DISABLE_INDEXING
4603    && TARGET_64BIT
4604    && TARGET_NO_SPACE_REGS
4605    && REG_OK_FOR_BASE_P (operands[1])
4606    && REG_OK_FOR_INDEX_P (operands[2])
4607    && FP_REGNO_P (REGNO (operands[3]))"
4608   [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4609         (match_dup 3))
4610    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4611   "")
4613 (define_insn ""
4614   [(set (match_operand:SF 0 "move_dest_operand"
4615                           "=r,r,Q")
4616         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4617                           "rG,RQ,rG"))]
4618   "(register_operand (operands[0], SFmode)
4619     || reg_or_0_operand (operands[1], SFmode))
4620    && TARGET_SOFT_FLOAT"
4621   "@
4622    copy %r1,%0
4623    ldw%M1 %1,%0
4624    stw%M0 %r1,%0"
4625   [(set_attr "type" "move,load,store")
4626    (set_attr "pa_combine_type" "addmove")
4627    (set_attr "length" "4,4,4")])
4631 ;;- zero extension instructions
4632 ;; We have define_expand for zero extension patterns to make sure the
4633 ;; operands get loaded into registers.  The define_insns accept
4634 ;; memory operands.  This gives us better overall code than just
4635 ;; having a pattern that does or does not accept memory operands.
4637 (define_expand "zero_extendqihi2"
4638   [(set (match_operand:HI 0 "register_operand" "")
4639         (zero_extend:HI
4640          (match_operand:QI 1 "register_operand" "")))]
4641   ""
4642   "")
4644 (define_insn ""
4645   [(set (match_operand:HI 0 "register_operand" "=r,r")
4646         (zero_extend:HI
4647          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4648   "GET_CODE (operands[1]) != CONST_INT"
4649   "@
4650    {extru|extrw,u} %1,31,8,%0
4651    ldb%M1 %1,%0"
4652   [(set_attr "type" "shift,load")
4653    (set_attr "length" "4,4")])
4655 (define_expand "zero_extendqisi2"
4656   [(set (match_operand:SI 0 "register_operand" "")
4657         (zero_extend:SI
4658          (match_operand:QI 1 "register_operand" "")))]
4659   ""
4660   "")
4662 (define_insn ""
4663   [(set (match_operand:SI 0 "register_operand" "=r,r")
4664         (zero_extend:SI
4665          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4666   "GET_CODE (operands[1]) != CONST_INT"
4667   "@
4668    {extru|extrw,u} %1,31,8,%0
4669    ldb%M1 %1,%0"
4670   [(set_attr "type" "shift,load")
4671    (set_attr "length" "4,4")])
4673 (define_expand "zero_extendhisi2"
4674   [(set (match_operand:SI 0 "register_operand" "")
4675         (zero_extend:SI
4676          (match_operand:HI 1 "register_operand" "")))]
4677   ""
4678   "")
4680 (define_insn ""
4681   [(set (match_operand:SI 0 "register_operand" "=r,r")
4682         (zero_extend:SI
4683          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4684   "GET_CODE (operands[1]) != CONST_INT"
4685   "@
4686    {extru|extrw,u} %1,31,16,%0
4687    ldh%M1 %1,%0"
4688   [(set_attr "type" "shift,load")
4689    (set_attr "length" "4,4")])
4691 (define_expand "zero_extendqidi2"
4692   [(set (match_operand:DI 0 "register_operand" "")
4693         (zero_extend:DI
4694          (match_operand:QI 1 "register_operand" "")))]
4695   "TARGET_64BIT"
4696   "")
4698 (define_insn ""
4699   [(set (match_operand:DI 0 "register_operand" "=r,r")
4700         (zero_extend:DI
4701          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4702   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4703   "@
4704    extrd,u %1,63,8,%0
4705    ldb%M1 %1,%0"
4706   [(set_attr "type" "shift,load")
4707    (set_attr "length" "4,4")])
4709 (define_expand "zero_extendhidi2"
4710   [(set (match_operand:DI 0 "register_operand" "")
4711         (zero_extend:DI
4712          (match_operand:HI 1 "register_operand" "")))]
4713   "TARGET_64BIT"
4714   "")
4716 (define_insn ""
4717   [(set (match_operand:DI 0 "register_operand" "=r,r")
4718         (zero_extend:DI
4719          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4720   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4721   "@
4722    extrd,u %1,63,16,%0
4723    ldh%M1 %1,%0"
4724   [(set_attr "type" "shift,load")
4725    (set_attr "length" "4,4")])
4727 (define_expand "zero_extendsidi2"
4728   [(set (match_operand:DI 0 "register_operand" "")
4729         (zero_extend:DI
4730          (match_operand:SI 1 "register_operand" "")))]
4731   "TARGET_64BIT"
4732   "")
4734 (define_insn ""
4735   [(set (match_operand:DI 0 "register_operand" "=r,r")
4736         (zero_extend:DI
4737          (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4738   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4739   "@
4740    extrd,u %1,63,32,%0
4741    ldw%M1 %1,%0"
4742   [(set_attr "type" "shift,load")
4743    (set_attr "length" "4,4")])
4745 ;;- sign extension instructions
4747 (define_insn "extendhisi2"
4748   [(set (match_operand:SI 0 "register_operand" "=r")
4749         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4750   ""
4751   "{extrs|extrw,s} %1,31,16,%0"
4752   [(set_attr "type" "shift")
4753    (set_attr "length" "4")])
4755 (define_insn "extendqihi2"
4756   [(set (match_operand:HI 0 "register_operand" "=r")
4757         (sign_extend:HI (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 "extendqisi2"
4764   [(set (match_operand:SI 0 "register_operand" "=r")
4765         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4766   ""
4767   "{extrs|extrw,s} %1,31,8,%0"
4768   [(set_attr "type" "shift")
4769    (set_attr "length" "4")])
4771 (define_insn "extendqidi2"
4772   [(set (match_operand:DI 0 "register_operand" "=r")
4773         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4774   "TARGET_64BIT"
4775   "extrd,s %1,63,8,%0"
4776   [(set_attr "type" "shift") 
4777   (set_attr "length" "4")])
4779 (define_insn "extendhidi2"
4780   [(set (match_operand:DI 0 "register_operand" "=r")
4781         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4782   "TARGET_64BIT"
4783   "extrd,s %1,63,16,%0"
4784   [(set_attr "type" "shift") 
4785   (set_attr "length" "4")])
4787 (define_insn "extendsidi2"
4788   [(set (match_operand:DI 0 "register_operand" "=r")
4789         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4790   "TARGET_64BIT"
4791   "extrd,s %1,63,32,%0"
4792   [(set_attr "type" "shift") 
4793   (set_attr "length" "4")])
4796 ;; Conversions between float and double.
4798 (define_insn "extendsfdf2"
4799   [(set (match_operand:DF 0 "register_operand" "=f")
4800         (float_extend:DF
4801          (match_operand:SF 1 "register_operand" "f")))]
4802   "! TARGET_SOFT_FLOAT"
4803   "{fcnvff|fcnv},sgl,dbl %1,%0"
4804   [(set_attr "type" "fpalu")
4805    (set_attr "length" "4")])
4807 (define_insn "truncdfsf2"
4808   [(set (match_operand:SF 0 "register_operand" "=f")
4809         (float_truncate:SF
4810          (match_operand:DF 1 "register_operand" "f")))]
4811   "! TARGET_SOFT_FLOAT"
4812   "{fcnvff|fcnv},dbl,sgl %1,%0"
4813   [(set_attr "type" "fpalu")
4814    (set_attr "length" "4")])
4816 ;; Conversion between fixed point and floating point.
4817 ;; Note that among the fix-to-float insns
4818 ;; the ones that start with SImode come first.
4819 ;; That is so that an operand that is a CONST_INT
4820 ;; (and therefore lacks a specific machine mode).
4821 ;; will be recognized as SImode (which is always valid)
4822 ;; rather than as QImode or HImode.
4824 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4825 ;; to be reloaded by putting the constant into memory.
4826 ;; It must come before the more general floatsisf2 pattern.
4827 (define_insn ""
4828   [(set (match_operand:SF 0 "register_operand" "=f")
4829         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4830   "! TARGET_SOFT_FLOAT"
4831   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4832   [(set_attr "type" "fpalu")
4833    (set_attr "length" "8")])
4835 (define_insn "floatsisf2"
4836   [(set (match_operand:SF 0 "register_operand" "=f")
4837         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4838   "! TARGET_SOFT_FLOAT"
4839   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4840   [(set_attr "type" "fpalu")
4841    (set_attr "length" "4")])
4843 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4844 ;; to be reloaded by putting the constant into memory.
4845 ;; It must come before the more general floatsidf2 pattern.
4846 (define_insn ""
4847   [(set (match_operand:DF 0 "register_operand" "=f")
4848         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4849   "! TARGET_SOFT_FLOAT"
4850   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4851   [(set_attr "type" "fpalu")
4852    (set_attr "length" "8")])
4854 (define_insn "floatsidf2"
4855   [(set (match_operand:DF 0 "register_operand" "=f")
4856         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4857   "! TARGET_SOFT_FLOAT"
4858   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4859   [(set_attr "type" "fpalu")
4860    (set_attr "length" "4")])
4862 (define_expand "floatunssisf2"
4863   [(set (subreg:SI (match_dup 2) 4)
4864         (match_operand:SI 1 "register_operand" ""))
4865    (set (subreg:SI (match_dup 2) 0)
4866         (const_int 0))
4867    (set (match_operand:SF 0 "register_operand" "")
4868         (float:SF (match_dup 2)))]
4869   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4870   "
4872   if (TARGET_PA_20)
4873     {
4874       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4875       DONE;
4876     }
4877   operands[2] = gen_reg_rtx (DImode);
4880 (define_expand "floatunssidf2"
4881   [(set (subreg:SI (match_dup 2) 4)
4882         (match_operand:SI 1 "register_operand" ""))
4883    (set (subreg:SI (match_dup 2) 0)
4884         (const_int 0))
4885    (set (match_operand:DF 0 "register_operand" "")
4886         (float:DF (match_dup 2)))]
4887   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4888   "
4890   if (TARGET_PA_20)
4891     {
4892       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4893       DONE;
4894     }
4895   operands[2] = gen_reg_rtx (DImode);
4898 (define_insn "floatdisf2"
4899   [(set (match_operand:SF 0 "register_operand" "=f")
4900         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4901   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4902   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4903   [(set_attr "type" "fpalu")
4904    (set_attr "length" "4")])
4906 (define_insn "floatdidf2"
4907   [(set (match_operand:DF 0 "register_operand" "=f")
4908         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4909   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4910   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4911   [(set_attr "type" "fpalu")
4912    (set_attr "length" "4")])
4914 ;; Convert a float to an actual integer.
4915 ;; Truncation is performed as part of the conversion.
4917 (define_insn "fix_truncsfsi2"
4918   [(set (match_operand:SI 0 "register_operand" "=f")
4919         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4920   "! TARGET_SOFT_FLOAT"
4921   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4922   [(set_attr "type" "fpalu")
4923    (set_attr "length" "4")])
4925 (define_insn "fix_truncdfsi2"
4926   [(set (match_operand:SI 0 "register_operand" "=f")
4927         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4928   "! TARGET_SOFT_FLOAT"
4929   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4930   [(set_attr "type" "fpalu")
4931    (set_attr "length" "4")])
4933 (define_insn "fix_truncsfdi2"
4934   [(set (match_operand:DI 0 "register_operand" "=f")
4935         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4936   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4937   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4938   [(set_attr "type" "fpalu")
4939    (set_attr "length" "4")])
4941 (define_insn "fix_truncdfdi2"
4942   [(set (match_operand:DI 0 "register_operand" "=f")
4943         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4944   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4945   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4946   [(set_attr "type" "fpalu")
4947    (set_attr "length" "4")])
4949 (define_insn "floatunssidf2_pa20"
4950   [(set (match_operand:DF 0 "register_operand" "=f")
4951         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4952   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4953   "fcnv,uw,dbl %1,%0"
4954   [(set_attr "type" "fpalu")
4955    (set_attr "length" "4")])
4957 (define_insn "floatunssisf2_pa20"
4958   [(set (match_operand:SF 0 "register_operand" "=f")
4959         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4960   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4961   "fcnv,uw,sgl %1,%0"
4962   [(set_attr "type" "fpalu")
4963    (set_attr "length" "4")])
4965 (define_insn "floatunsdisf2"
4966   [(set (match_operand:SF 0 "register_operand" "=f")
4967         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4968   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4969   "fcnv,udw,sgl %1,%0"
4970   [(set_attr "type" "fpalu")
4971    (set_attr "length" "4")])
4973 (define_insn "floatunsdidf2"
4974   [(set (match_operand:DF 0 "register_operand" "=f")
4975         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4976   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4977   "fcnv,udw,dbl %1,%0"
4978   [(set_attr "type" "fpalu")
4979    (set_attr "length" "4")])
4981 (define_insn "fixuns_truncsfsi2"
4982   [(set (match_operand:SI 0 "register_operand" "=f")
4983         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4984   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4985   "fcnv,t,sgl,uw %1,%0"
4986   [(set_attr "type" "fpalu")
4987    (set_attr "length" "4")])
4989 (define_insn "fixuns_truncdfsi2"
4990   [(set (match_operand:SI 0 "register_operand" "=f")
4991         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4992   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4993   "fcnv,t,dbl,uw %1,%0"
4994   [(set_attr "type" "fpalu")
4995    (set_attr "length" "4")])
4997 (define_insn "fixuns_truncsfdi2"
4998   [(set (match_operand:DI 0 "register_operand" "=f")
4999         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5000   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5001   "fcnv,t,sgl,udw %1,%0"
5002   [(set_attr "type" "fpalu")
5003    (set_attr "length" "4")])
5005 (define_insn "fixuns_truncdfdi2"
5006   [(set (match_operand:DI 0 "register_operand" "=f")
5007         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
5008   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5009   "fcnv,t,dbl,udw %1,%0"
5010   [(set_attr "type" "fpalu")
5011    (set_attr "length" "4")])
5013 ;;- arithmetic instructions
5015 (define_expand "adddi3"
5016   [(set (match_operand:DI 0 "register_operand" "")
5017         (plus:DI (match_operand:DI 1 "register_operand" "")
5018                  (match_operand:DI 2 "adddi3_operand" "")))]
5019   ""
5020   "")
5022 (define_insn ""
5023   [(set (match_operand:DI 0 "register_operand" "=r")
5024         (plus:DI (match_operand:DI 1 "register_operand" "%r")
5025                  (match_operand:DI 2 "arith11_operand" "rI")))]
5026   "!TARGET_64BIT"
5027   "*
5029   if (GET_CODE (operands[2]) == CONST_INT)
5030     {
5031       if (INTVAL (operands[2]) >= 0)
5032         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
5033       else
5034         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
5035     }
5036   else
5037     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
5039   [(set_attr "type" "binary")
5040    (set_attr "length" "8")])
5042 (define_insn ""
5043   [(set (match_operand:DI 0 "register_operand" "=r,r")
5044         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5045                  (match_operand:DI 2 "arith14_operand" "r,J")))]
5046   "TARGET_64BIT"
5047   "@
5048    add,l %1,%2,%0
5049    ldo %2(%1),%0"
5050   [(set_attr "type" "binary,binary")
5051    (set_attr "pa_combine_type" "addmove")
5052    (set_attr "length" "4,4")])
5054 (define_insn ""
5055   [(set (match_operand:DI 0 "register_operand" "=r")
5056         (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5057                  (match_operand:DI 2 "register_operand" "r")))]
5058   "TARGET_64BIT"
5059   "uaddcm %2,%1,%0"
5060   [(set_attr "type" "binary")
5061    (set_attr "length" "4")])
5063 (define_insn ""
5064   [(set (match_operand:SI 0 "register_operand" "=r")
5065         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5066                  (match_operand:SI 2 "register_operand" "r")))]
5067   ""
5068   "uaddcm %2,%1,%0"
5069   [(set_attr "type" "binary")
5070    (set_attr "length" "4")])
5072 (define_expand "addvdi3"
5073   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5074                    (plus:DI (match_operand:DI 1 "reg_or_0_operand" "")
5075                             (match_operand:DI 2 "arith11_operand" "")))
5076               (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5077                                     (sign_extend:TI (match_dup 2)))
5078                            (sign_extend:TI (plus:DI (match_dup 1)
5079                                                     (match_dup 2))))
5080                        (const_int 0))])]
5081   ""
5082   "
5084   if (TARGET_64BIT)
5085     operands[2] = force_reg (DImode, operands[2]);
5088 (define_insn ""
5089   [(set (match_operand:DI 0 "register_operand" "=r")
5090         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5091                  (match_operand:DI 2 "register_operand" "r")))
5092    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5093                          (sign_extend:TI (match_dup 2)))
5094                 (sign_extend:TI (plus:DI (match_dup 1)
5095                                          (match_dup 2))))
5096             (const_int 0))]
5097   "TARGET_64BIT"
5098   "add,tsv,* %2,%1,%0"
5099   [(set_attr "type" "binary")
5100    (set_attr "length" "4")])
5102 (define_insn ""
5103   [(set (match_operand:DI 0 "register_operand" "=r")
5104         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rM")
5105                  (match_operand:DI 2 "arith11_operand" "rI")))
5106    (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
5107                          (sign_extend:TI (match_dup 2)))
5108                 (sign_extend:TI (plus:DI (match_dup 1)
5109                                          (match_dup 2))))
5110             (const_int 0))]
5111   "!TARGET_64BIT"
5112   "*
5114   if (GET_CODE (operands[2]) == CONST_INT)
5115     {
5116       if (INTVAL (operands[2]) >= 0)
5117         return \"addi %2,%R1,%R0\;{addco|add,c,tsv} %1,%%r0,%0\";
5118       else
5119         return \"addi %2,%R1,%R0\;{subbo|sub,b,tsv} %1,%%r0,%0\";
5120     }
5121   else
5122     return \"add %R2,%R1,%R0\;{addco|add,c,tsv} %2,%1,%0\";
5124   [(set_attr "type" "binary")
5125    (set_attr "length" "8")])
5127 ;; define_splits to optimize cases of adding a constant integer
5128 ;; to a register when the constant does not fit in 14 bits.  */
5129 (define_split
5130   [(set (match_operand:SI 0 "register_operand" "")
5131         (plus:SI (match_operand:SI 1 "register_operand" "")
5132                  (match_operand:SI 2 "const_int_operand" "")))
5133    (clobber (match_operand:SI 4 "register_operand" ""))]
5134   "! pa_cint_ok_for_move (UINTVAL (operands[2]))
5135    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
5136   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
5137    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
5138   "
5140   int val = INTVAL (operands[2]);
5141   int low = (val < 0) ? -0x2000 : 0x1fff;
5142   int rest = val - low;
5144   operands[2] = GEN_INT (rest);
5145   operands[3] = GEN_INT (low);
5148 (define_split
5149   [(set (match_operand:SI 0 "register_operand" "")
5150         (plus:SI (match_operand:SI 1 "register_operand" "")
5151                  (match_operand:SI 2 "const_int_operand" "")))
5152    (clobber (match_operand:SI 4 "register_operand" ""))]
5153   "! pa_cint_ok_for_move (UINTVAL (operands[2]))"
5154   [(set (match_dup 4) (match_dup 2))
5155    (set (match_dup 0) (plus:SI (ashift:SI (match_dup 4) (match_dup 3))
5156                                (match_dup 1)))]
5157   "
5159   unsigned HOST_WIDE_INT intval = UINTVAL (operands[2]);
5161   /* Try dividing the constant by 2, then 4, and finally 8 to see
5162      if we can get a constant which can be loaded into a register
5163      in a single instruction (pa_cint_ok_for_move). 
5165      If that fails, try to negate the constant and subtract it
5166      from our input operand.  */
5167   if (intval % 2 == 0 && pa_cint_ok_for_move (intval / 2))
5168     {
5169       operands[2] = GEN_INT (intval / 2);
5170       operands[3] = const1_rtx;
5171     }
5172   else if (intval % 4 == 0 && pa_cint_ok_for_move (intval / 4))
5173     {
5174       operands[2] = GEN_INT (intval / 4);
5175       operands[3] = const2_rtx;
5176     }
5177   else if (intval % 8 == 0 && pa_cint_ok_for_move (intval / 8))
5178     {
5179       operands[2] = GEN_INT (intval / 8);
5180       operands[3] = GEN_INT (3);
5181     }
5182   else if (pa_cint_ok_for_move (-intval))
5183     {
5184       emit_insn (gen_rtx_SET (operands[4], GEN_INT (-intval)));
5185       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5186       DONE;
5187     }
5188   else
5189     FAIL;
5192 (define_insn "addsi3"
5193   [(set (match_operand:SI 0 "register_operand" "=r,r")
5194         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5195                  (match_operand:SI 2 "arith14_operand" "r,J")))]
5196   ""
5197   "@
5198    {addl|add,l} %1,%2,%0
5199    ldo %2(%1),%0"
5200   [(set_attr "type" "binary,binary")
5201    (set_attr "pa_combine_type" "addmove")
5202    (set_attr "length" "4,4")])
5204 (define_insn "addvsi3"
5205   [(set (match_operand:SI 0 "register_operand" "=r,r")
5206         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rM,rM")
5207                  (match_operand:SI 2 "arith11_operand" "r,I")))
5208    (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
5209                          (sign_extend:DI (match_dup 2)))
5210                 (sign_extend:DI (plus:SI (match_dup 1)
5211                                          (match_dup 2))))
5212             (const_int 0))]
5213   ""
5214   "@
5215   {addo|add,tsv} %2,%1,%0
5216   {addio|addi,tsv} %2,%1,%0"
5217   [(set_attr "type" "binary,binary")
5218    (set_attr "length" "4,4")])
5220 (define_expand "subdi3"
5221   [(set (match_operand:DI 0 "register_operand" "")
5222         (minus:DI (match_operand:DI 1 "arith11_operand" "")
5223                   (match_operand:DI 2 "reg_or_0_operand" "")))]
5224   ""
5225   "")
5227 (define_insn ""
5228   [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5229         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5230                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM,!rM")))]
5231   "TARGET_64BIT"
5232   "@
5233    sub %1,%2,%0
5234    subi %1,%2,%0
5235    mtsarcm %2"
5236   [(set_attr "type" "binary,binary,move")
5237   (set_attr "length" "4,4,4")])
5239 (define_insn ""
5240   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5241         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5242                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))]
5243   "!TARGET_64BIT"
5244   "*
5246   if (GET_CODE (operands[1]) == CONST_INT)
5247     {
5248       if (INTVAL (operands[1]) >= 0)
5249         return \"subi %1,%R2,%R0\;{subb|sub,b} %%r0,%2,%0\";
5250       else
5251         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subb|sub,b} %0,%2,%0\";
5252     }
5253   else
5254     return \"sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0\";
5256   [(set_attr "type" "binary")
5257    (set (attr "length")
5258         (if_then_else (eq_attr "alternative" "0")
5259           (const_int 8)
5260           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5261                             (const_int 0))
5262             (const_int 8)
5263             (const_int 12))))])
5265 (define_expand "subvdi3"
5266   [(parallel [(set (match_operand:DI 0 "register_operand" "")
5267                    (minus:DI (match_operand:DI 1 "arith11_operand" "")
5268                              (match_operand:DI 2 "reg_or_0_operand" "")))
5269               (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5270                                      (sign_extend:TI (match_dup 2)))
5271                            (sign_extend:TI (minus:DI (match_dup 1)
5272                                                      (match_dup 2))))
5273                        (const_int 0))])]
5274   ""
5275   "
5277   if (TARGET_64BIT)
5278     operands[1] = force_reg (DImode, operands[1]);
5281 (define_insn ""
5282   [(set (match_operand:DI 0 "register_operand" "=r")
5283         (minus:DI (match_operand:DI 1 "register_operand" "r")
5284                   (match_operand:DI 2 "reg_or_0_operand" "rM")))
5285    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5286                           (sign_extend:TI (match_dup 2)))
5287                 (sign_extend:TI (minus:DI (match_dup 1)
5288                                           (match_dup 2))))
5289             (const_int 0))]
5290   "TARGET_64BIT"
5291   "sub,tsv,* %1,%2,%0"
5292   [(set_attr "type" "binary")
5293    (set_attr "length" "4")])
5295 (define_insn ""
5296   [(set (match_operand:DI 0 "register_operand" "=r,&r")
5297         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I")
5298                   (match_operand:DI 2 "reg_or_0_operand" "rM,rM")))
5299    (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
5300                           (sign_extend:TI (match_dup 2)))
5301                 (sign_extend:TI (minus:DI (match_dup 1)
5302                                           (match_dup 2))))
5303             (const_int 0))]
5304   "!TARGET_64BIT"
5305   "*
5307   if (GET_CODE (operands[1]) == CONST_INT)
5308     {
5309       if (INTVAL (operands[1]) >= 0)
5310         return \"subi %1,%R2,%R0\;{subbo|sub,b,tsv} %%r0,%2,%0\";
5311       else
5312         return \"ldi -1,%0\;subi %1,%R2,%R0\;{subbo|sub,b,tsv} %0,%2,%0\";
5313     }
5314   else
5315     return \"sub %R1,%R2,%R0\;{subbo|sub,b,tsv} %1,%2,%0\";
5317   [(set_attr "type" "binary,binary")
5318    (set (attr "length")
5319         (if_then_else (eq_attr "alternative" "0")
5320           (const_int 8)
5321           (if_then_else (ge (symbol_ref "INTVAL (operands[1])")
5322                             (const_int 0))
5323             (const_int 8)
5324             (const_int 12))))])
5326 (define_expand "subsi3"
5327   [(set (match_operand:SI 0 "register_operand" "")
5328         (minus:SI (match_operand:SI 1 "arith11_operand" "")
5329                   (match_operand:SI 2 "register_operand" "")))]
5330   ""
5331   "")
5333 (define_insn ""
5334   [(set (match_operand:SI 0 "register_operand" "=r,r")
5335         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5336                   (match_operand:SI 2 "register_operand" "r,r")))]
5337   "!TARGET_PA_20"
5338   "@
5339    sub %1,%2,%0
5340    subi %1,%2,%0"
5341   [(set_attr "type" "binary,binary")
5342    (set_attr "length" "4,4")])
5344 (define_insn ""
5345   [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5346         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5347                   (match_operand:SI 2 "register_operand" "r,r,!r")))]
5348   "TARGET_PA_20"
5349   "@
5350    sub %1,%2,%0
5351    subi %1,%2,%0
5352    mtsarcm %2"
5353   [(set_attr "type" "binary,binary,move")
5354    (set_attr "length" "4,4,4")])
5356 (define_insn "subvsi3"
5357   [(set (match_operand:SI 0 "register_operand" "=r,r")
5358         (minus:SI (match_operand:SI 1 "arith11_operand" "rM,I")
5359                   (match_operand:SI 2 "reg_or_0_operand" "rM,rM")))
5360    (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
5361                           (sign_extend:DI (match_dup 2)))
5362                 (sign_extend:DI (minus:SI (match_dup 1)
5363                                           (match_dup 2))))
5364             (const_int 0))]
5365   ""
5366   "@
5367   {subo|sub,tsv} %1,%2,%0
5368   {subio|subi,tsv} %1,%2,%0"
5369   [(set_attr "type" "binary,binary")
5370    (set_attr "length" "4,4")])
5372 (define_insn "addti3"
5373   [(set (match_operand:TI 0 "register_operand" "=r")
5374         (plus:TI (match_operand:TI 1 "register_operand" "r")
5375                  (match_operand:TI 2 "register_operand" "r")))]
5376   "TARGET_64BIT"
5377   "*
5379   operands[3] = gen_lowpart (DImode, operands[0]);
5380   operands[4] = gen_lowpart (DImode, operands[1]);
5381   operands[5] = gen_lowpart (DImode, operands[2]);
5382   operands[0] = gen_highpart (DImode, operands[0]);
5383   operands[1] = gen_highpart (DImode, operands[1]);
5384   operands[2] = gen_highpart (DImode, operands[2]);
5385   return \"add %4,%5,%3\;add,dc %1,%2,%0\";
5387   [(set_attr "type" "multi")
5388    (set_attr "length" "8")])
5390 (define_insn "addvti3"
5391   [(set (match_operand:TI 0 "register_operand" "=r")
5392         (plus:TI (match_operand:TI 1 "register_operand" "r")
5393                  (match_operand:TI 2 "register_operand" "r")))
5394    (trap_if (ne (plus:OI (sign_extend:OI (match_dup 1))
5395                          (sign_extend:OI (match_dup 2)))
5396                 (sign_extend:OI (plus:TI (match_dup 1)
5397                                          (match_dup 2))))
5398             (const_int 0))]
5399   "TARGET_64BIT"
5400   "*
5402   operands[3] = gen_lowpart (DImode, operands[0]);
5403   operands[4] = gen_lowpart (DImode, operands[1]);
5404   operands[5] = gen_lowpart (DImode, operands[2]);
5405   operands[0] = gen_highpart (DImode, operands[0]);
5406   operands[1] = gen_highpart (DImode, operands[1]);
5407   operands[2] = gen_highpart (DImode, operands[2]);
5408   return \"add %4,%5,%3\;add,dc,tsv %1,%2,%0\";
5410   [(set_attr "type" "multi")
5411    (set_attr "length" "8")])
5413 (define_insn "subti3"
5414   [(set (match_operand:TI 0 "register_operand" "=r")
5415         (minus:TI (match_operand:TI 1 "register_operand" "r")
5416                   (match_operand:TI 2 "register_operand" "r")))]
5417   "TARGET_64BIT"
5418   "*
5420   operands[3] = gen_lowpart (DImode, operands[0]);
5421   operands[4] = gen_lowpart (DImode, operands[1]);
5422   operands[5] = gen_lowpart (DImode, operands[2]);
5423   operands[0] = gen_highpart (DImode, operands[0]);
5424   operands[1] = gen_highpart (DImode, operands[1]);
5425   operands[2] = gen_highpart (DImode, operands[2]);
5426   return \"sub %4,%5,%3\;sub,db %1,%2,%0\";
5428   [(set_attr "type" "multi")
5429    (set_attr "length" "8")])
5431 (define_insn "subvti3"
5432   [(set (match_operand:TI 0 "register_operand" "=r")
5433         (minus:TI (match_operand:TI 1 "register_operand" "r")
5434                   (match_operand:TI 2 "register_operand" "r")))
5435    (trap_if (ne (minus:OI (sign_extend:OI (match_dup 1))
5436                           (sign_extend:OI (match_dup 2)))
5437                 (sign_extend:OI (minus:TI (match_dup 1)
5438                                           (match_dup 2))))
5439             (const_int 0))]
5440   "TARGET_64BIT"
5441   "*
5443   operands[3] = gen_lowpart (DImode, operands[0]);
5444   operands[4] = gen_lowpart (DImode, operands[1]);
5445   operands[5] = gen_lowpart (DImode, operands[2]);
5446   operands[0] = gen_highpart (DImode, operands[0]);
5447   operands[1] = gen_highpart (DImode, operands[1]);
5448   operands[2] = gen_highpart (DImode, operands[2]);
5449   return \"sub %4,%5,%3\;sub,db,tsv %1,%2,%0\";
5451   [(set_attr "type" "multi")
5452    (set_attr "length" "8")])
5454 ;; Trap instructions.
5456 (define_insn "trap"
5457   [(trap_if (const_int 1) (const_int 0))]
5458   ""
5459   "{addit|addi,tc},<> 1,%%r0,%%r0"
5460   [(set_attr "type" "trap")
5461    (set_attr "length" "4")])
5463 ;; Clobbering a "register_operand" instead of a match_scratch
5464 ;; in operand3 of millicode calls avoids spilling %r1 and
5465 ;; produces better code.
5467 ;; The mulsi3 insns set up registers for the millicode call.
5468 (define_expand "mulsi3"
5469   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5470    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5471    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5472               (clobber (match_dup 3))
5473               (clobber (reg:SI 26))
5474               (clobber (reg:SI 25))
5475               (clobber (match_dup 4))])
5476    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5477   ""
5478   "
5480   operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5481   if (TARGET_PA_11 && !TARGET_SOFT_FLOAT && !TARGET_SOFT_MULT)
5482     {
5483       rtx scratch = gen_reg_rtx (DImode);
5484       operands[1] = force_reg (SImode, operands[1]);
5485       operands[2] = force_reg (SImode, operands[2]);
5486       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5487       emit_insn (gen_movsi (operands[0],
5488                             gen_rtx_SUBREG (SImode, scratch,
5489                                             GET_MODE_SIZE (SImode))));
5490       DONE;
5491     }
5492   operands[3] = gen_reg_rtx (SImode);
5495 (define_insn "umulsidi3"
5496   [(set (match_operand:DI 0 "register_operand" "=f")
5497         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5498                  (zero_extend:DI (match_operand:SI 2 "register_operand" "f"))))]
5499   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT"
5500   "xmpyu %1,%2,%0"
5501   [(set_attr "type" "fpmuldbl")
5502    (set_attr "length" "4")])
5504 (define_insn ""
5505   [(set (match_operand:DI 0 "register_operand" "=f")
5506         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5507                  (match_operand:DI 2 "uint32_operand" "f")))]
5508   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && !TARGET_64BIT"
5509   "xmpyu %1,%R2,%0"
5510   [(set_attr "type" "fpmuldbl")
5511    (set_attr "length" "4")])
5513 (define_insn ""
5514   [(set (match_operand:DI 0 "register_operand" "=f")
5515         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
5516                  (match_operand:DI 2 "uint32_operand" "f")))]
5517   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && TARGET_64BIT"
5518   "xmpyu %1,%2R,%0"
5519   [(set_attr "type" "fpmuldbl")
5520    (set_attr "length" "4")])
5522 (define_insn ""
5523   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5524    (clobber (match_operand:SI 0 "register_operand" "=a"))
5525    (clobber (reg:SI 26))
5526    (clobber (reg:SI 25))
5527    (clobber (reg:SI 31))]
5528   "!TARGET_64BIT"
5529   "* return pa_output_mul_insn (0, insn);"
5530   [(set_attr "type" "milli")
5531    (set (attr "length")
5532         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5533               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5535 (define_insn ""
5536   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5537    (clobber (match_operand:SI 0 "register_operand" "=a"))
5538    (clobber (reg:SI 26))
5539    (clobber (reg:SI 25))
5540    (clobber (reg:SI 2))]
5541   "TARGET_64BIT"
5542   "* return pa_output_mul_insn (0, insn);"
5543   [(set_attr "type" "milli")
5544    (set (attr "length")
5545         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5546               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5548 (define_expand "muldi3"
5549   [(set (match_operand:DI 0 "register_operand" "")
5550         (mult:DI (match_operand:DI 1 "register_operand" "")
5551                  (match_operand:DI 2 "register_operand" "")))]
5552   "! optimize_size
5553    && TARGET_PA_11
5554    && ! TARGET_SOFT_FLOAT
5555    && ! TARGET_SOFT_MULT"
5556   "
5558   rtx low_product = gen_reg_rtx (DImode);
5559   rtx cross_product1 = gen_reg_rtx (DImode);
5560   rtx cross_product2 = gen_reg_rtx (DImode);
5561   rtx op1l, op1r, op2l, op2r;
5563   if (TARGET_64BIT)
5564     {
5565       rtx op1shifted = gen_reg_rtx (DImode);
5566       rtx op2shifted = gen_reg_rtx (DImode);
5568       emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5569                                                     GEN_INT (32)));
5570       emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5571                                                     GEN_INT (32)));
5572       op1r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[1], 4));
5573       op2r = force_reg (SImode, gen_rtx_SUBREG (SImode, operands[2], 4));
5574       op1l = force_reg (SImode, gen_rtx_SUBREG (SImode, op1shifted, 4));
5575       op2l = force_reg (SImode, gen_rtx_SUBREG (SImode, op2shifted, 4));
5576     }
5577   else
5578     {
5579       op1r = force_reg (SImode, gen_lowpart (SImode, operands[1]));
5580       op2r = force_reg (SImode, gen_lowpart (SImode, operands[2]));
5581       op1l = force_reg (SImode, gen_highpart (SImode, operands[1]));
5582       op2l = force_reg (SImode, gen_highpart (SImode, operands[2]));
5583     }
5585   /* Emit multiplies for the cross products.  */
5586   emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5587   emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5589   /* Emit a multiply for the low sub-word.  */
5590   emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5592   if (TARGET_64BIT)
5593     {
5594       rtx cross_scratch = gen_reg_rtx (DImode);
5595       rtx cross_product = gen_reg_rtx (DImode);
5597       /* Sum the cross products and shift them into proper position.  */
5598       emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5599       emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5601       /* Add the cross product to the low product and store the result
5602          into the output operand .  */
5603       emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5604     }
5605   else
5606     {
5607       rtx cross_scratch = gen_reg_rtx (SImode);
5609       /* Sum cross products.  */
5610       emit_move_insn (cross_scratch,
5611                       gen_rtx_PLUS (SImode,
5612                                     gen_lowpart (SImode, cross_product1),
5613                                     gen_lowpart (SImode, cross_product2)));
5614       emit_move_insn (gen_lowpart (SImode, operands[0]),
5615                       gen_lowpart (SImode, low_product));
5616       emit_move_insn (gen_highpart (SImode, operands[0]),
5617                       gen_rtx_PLUS (SImode,
5618                                     gen_highpart (SImode, low_product),
5619                                     cross_scratch));
5620     }
5621   DONE;
5624 ;;; Division and mod.
5625 (define_expand "divsi3"
5626   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5627    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5628    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5629               (clobber (match_dup 3))
5630               (clobber (match_dup 4))
5631               (clobber (reg:SI 26))
5632               (clobber (reg:SI 25))
5633               (clobber (match_dup 5))])
5634    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5635   ""
5636   "
5638   operands[3] = gen_reg_rtx (SImode);
5639   if (TARGET_64BIT)
5640     {
5641       operands[5] = gen_rtx_REG (SImode, 2);
5642       operands[4] = operands[5];
5643     }
5644   else
5645     {
5646       operands[5] = gen_rtx_REG (SImode, 31);
5647       operands[4] = gen_reg_rtx (SImode);
5648     }
5649   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 0))
5650     DONE;
5653 (define_insn ""
5654   [(set (reg:SI 29)
5655         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5656    (clobber (match_operand:SI 1 "register_operand" "=a"))
5657    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5658    (clobber (reg:SI 26))
5659    (clobber (reg:SI 25))
5660    (clobber (reg:SI 31))]
5661   "!TARGET_64BIT"
5662   "*
5663    return pa_output_div_insn (operands, 0, insn);"
5664   [(set_attr "type" "milli")
5665    (set (attr "length")
5666         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5667               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5669 (define_insn ""
5670   [(set (reg:SI 29)
5671         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5672    (clobber (match_operand:SI 1 "register_operand" "=a"))
5673    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5674    (clobber (reg:SI 26))
5675    (clobber (reg:SI 25))
5676    (clobber (reg:SI 2))]
5677   "TARGET_64BIT"
5678   "*
5679    return pa_output_div_insn (operands, 0, insn);"
5680   [(set_attr "type" "milli")
5681    (set (attr "length")
5682         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5683               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5685 (define_expand "udivsi3"
5686   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5687    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5688    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5689               (clobber (match_dup 3))
5690               (clobber (match_dup 4))
5691               (clobber (reg:SI 26))
5692               (clobber (reg:SI 25))
5693               (clobber (match_dup 5))])
5694    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5695   ""
5696   "
5698   operands[3] = gen_reg_rtx (SImode);
5700   if (TARGET_64BIT)
5701     {
5702       operands[5] = gen_rtx_REG (SImode, 2);
5703       operands[4] = operands[5];
5704     }
5705   else
5706     {
5707       operands[5] = gen_rtx_REG (SImode, 31);
5708       operands[4] = gen_reg_rtx (SImode);
5709     }
5710   if (GET_CODE (operands[2]) == CONST_INT && pa_emit_hpdiv_const (operands, 1))
5711     DONE;
5714 (define_insn ""
5715   [(set (reg:SI 29)
5716         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5717    (clobber (match_operand:SI 1 "register_operand" "=a"))
5718    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5719    (clobber (reg:SI 26))
5720    (clobber (reg:SI 25))
5721    (clobber (reg:SI 31))]
5722   "!TARGET_64BIT"
5723   "*
5724    return pa_output_div_insn (operands, 1, insn);"
5725   [(set_attr "type" "milli")
5726    (set (attr "length")
5727         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5728               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5730 (define_insn ""
5731   [(set (reg:SI 29)
5732         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5733    (clobber (match_operand:SI 1 "register_operand" "=a"))
5734    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5735    (clobber (reg:SI 26))
5736    (clobber (reg:SI 25))
5737    (clobber (reg:SI 2))]
5738   "TARGET_64BIT"
5739   "*
5740    return pa_output_div_insn (operands, 1, insn);"
5741   [(set_attr "type" "milli")
5742    (set (attr "length")
5743         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5744               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5746 (define_expand "modsi3"
5747   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5748    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5749    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5750               (clobber (match_dup 3))
5751               (clobber (match_dup 4))
5752               (clobber (reg:SI 26))
5753               (clobber (reg:SI 25))
5754               (clobber (match_dup 5))])
5755    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5756   ""
5757   "
5759   if (TARGET_64BIT)
5760     {
5761       operands[5] = gen_rtx_REG (SImode, 2);
5762       operands[4] = operands[5];
5763     }
5764   else
5765     {
5766       operands[5] = gen_rtx_REG (SImode, 31);
5767       operands[4] = gen_reg_rtx (SImode);
5768     }
5769   operands[3] = gen_reg_rtx (SImode);
5772 (define_insn ""
5773   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5774    (clobber (match_operand:SI 0 "register_operand" "=a"))
5775    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5776    (clobber (reg:SI 26))
5777    (clobber (reg:SI 25))
5778    (clobber (reg:SI 31))]
5779   "!TARGET_64BIT"
5780   "*
5781   return pa_output_mod_insn (0, insn);"
5782   [(set_attr "type" "milli")
5783    (set (attr "length")
5784         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5785               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5787 (define_insn ""
5788   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5789    (clobber (match_operand:SI 0 "register_operand" "=a"))
5790    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5791    (clobber (reg:SI 26))
5792    (clobber (reg:SI 25))
5793    (clobber (reg:SI 2))]
5794   "TARGET_64BIT"
5795   "*
5796   return pa_output_mod_insn (0, insn);"
5797   [(set_attr "type" "milli")
5798    (set (attr "length")
5799         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5800               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5802 (define_expand "umodsi3"
5803   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5804    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5805    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5806               (clobber (match_dup 3))
5807               (clobber (match_dup 4))
5808               (clobber (reg:SI 26))
5809               (clobber (reg:SI 25))
5810               (clobber (match_dup 5))])
5811    (set (match_operand:SI 0 "move_dest_operand" "") (reg:SI 29))]
5812   ""
5813   "
5815   if (TARGET_64BIT)
5816     {
5817       operands[5] = gen_rtx_REG (SImode, 2);
5818       operands[4] = operands[5];
5819     }
5820   else
5821     {
5822       operands[5] = gen_rtx_REG (SImode, 31);
5823       operands[4] = gen_reg_rtx (SImode);
5824     }
5825   operands[3] = gen_reg_rtx (SImode);
5828 (define_insn ""
5829   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5830    (clobber (match_operand:SI 0 "register_operand" "=a"))
5831    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5832    (clobber (reg:SI 26))
5833    (clobber (reg:SI 25))
5834    (clobber (reg:SI 31))]
5835   "!TARGET_64BIT"
5836   "*
5837   return pa_output_mod_insn (1, insn);"
5838   [(set_attr "type" "milli")
5839    (set (attr "length")
5840         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5841               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5843 (define_insn ""
5844   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5845    (clobber (match_operand:SI 0 "register_operand" "=a"))
5846    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5847    (clobber (reg:SI 26))
5848    (clobber (reg:SI 25))
5849    (clobber (reg:SI 2))]
5850   "TARGET_64BIT"
5851   "*
5852   return pa_output_mod_insn (1, insn);"
5853   [(set_attr "type" "milli")
5854    (set (attr "length")
5855         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
5856               (symbol_ref "pa_attr_length_millicode_call (insn)")))])
5858 ;;- and instructions
5859 ;; We define DImode `and` so with DImode `not` we can get
5860 ;; DImode `andn`.  Other combinations are possible.
5862 (define_expand "anddi3"
5863   [(set (match_operand:DI 0 "register_operand" "")
5864         (and:DI (match_operand:DI 1 "register_operand" "")
5865                 (match_operand:DI 2 "and_operand" "")))]
5866   "TARGET_64BIT"
5867   "")
5869 (define_insn ""
5870   [(set (match_operand:DI 0 "register_operand" "=r,r")
5871         (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5872                 (match_operand:DI 2 "and_operand" "rO,P")))]
5873   "TARGET_64BIT"
5874   "* return pa_output_64bit_and (operands); "
5875   [(set_attr "type" "binary")
5876    (set_attr "length" "4")])
5878 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5879 ; constant with ldil;ldo.
5880 (define_insn "andsi3"
5881   [(set (match_operand:SI 0 "register_operand" "=r,r")
5882         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5883                 (match_operand:SI 2 "and_operand" "rO,P")))]
5884   ""
5885   "* return pa_output_and (operands); "
5886   [(set_attr "type" "binary,shift")
5887    (set_attr "length" "4,4")])
5889 (define_insn ""
5890   [(set (match_operand:DI 0 "register_operand" "=r")
5891         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5892                 (match_operand:DI 2 "register_operand" "r")))]
5893   "TARGET_64BIT"
5894   "andcm %2,%1,%0"
5895   [(set_attr "type" "binary")
5896    (set_attr "length" "4")])
5898 (define_insn ""
5899   [(set (match_operand:SI 0 "register_operand" "=r")
5900         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5901                 (match_operand:SI 2 "register_operand" "r")))]
5902   ""
5903   "andcm %2,%1,%0"
5904   [(set_attr "type" "binary")
5905   (set_attr "length" "4")])
5907 (define_expand "iordi3"
5908   [(set (match_operand:DI 0 "register_operand" "")
5909         (ior:DI (match_operand:DI 1 "register_operand" "")
5910                 (match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
5911   "TARGET_64BIT"
5912   "")
5914 (define_insn ""
5915   [(set (match_operand:DI 0 "register_operand" "=r,r")
5916         (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5917                 (match_operand:DI 2 "cint_ior_operand" "M,i")))]
5918   "TARGET_64BIT"
5919   "* return pa_output_64bit_ior (operands); "
5920   [(set_attr "type" "binary,shift")
5921    (set_attr "length" "4,4")])
5923 (define_insn ""
5924   [(set (match_operand:DI 0 "register_operand" "=r")
5925         (ior:DI (match_operand:DI 1 "register_operand" "%r")
5926                 (match_operand:DI 2 "register_operand" "r")))]
5927   "TARGET_64BIT"
5928   "or %1,%2,%0"
5929   [(set_attr "type" "binary")
5930    (set_attr "length" "4")])
5932 ;; Need a define_expand because we've run out of CONST_OK... characters.
5933 (define_expand "iorsi3"
5934   [(set (match_operand:SI 0 "register_operand" "")
5935         (ior:SI (match_operand:SI 1 "register_operand" "")
5936                 (match_operand:SI 2 "reg_or_cint_ior_operand" "")))]
5937   ""
5938   "")
5940 (define_insn ""
5941   [(set (match_operand:SI 0 "register_operand" "=r,r")
5942         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5943                 (match_operand:SI 2 "cint_ior_operand" "M,i")))]
5944   ""
5945   "* return pa_output_ior (operands); "
5946   [(set_attr "type" "binary,shift")
5947    (set_attr "length" "4,4")])
5949 (define_insn ""
5950   [(set (match_operand:SI 0 "register_operand" "=r")
5951         (ior:SI (match_operand:SI 1 "register_operand" "%r")
5952                 (match_operand:SI 2 "register_operand" "r")))]
5953   ""
5954   "or %1,%2,%0"
5955   [(set_attr "type" "binary")
5956    (set_attr "length" "4")])
5958 (define_expand "xordi3"
5959   [(set (match_operand:DI 0 "register_operand" "")
5960         (xor:DI (match_operand:DI 1 "register_operand" "")
5961                 (match_operand:DI 2 "register_operand" "")))]
5962   "TARGET_64BIT"
5963   "")
5965 (define_insn ""
5966   [(set (match_operand:DI 0 "register_operand" "=r")
5967         (xor:DI (match_operand:DI 1 "register_operand" "%r")
5968                 (match_operand:DI 2 "register_operand" "r")))]
5969   "TARGET_64BIT"
5970   "xor %1,%2,%0"
5971   [(set_attr "type" "binary")
5972    (set_attr "length" "4")])
5974 (define_insn "xorsi3"
5975   [(set (match_operand:SI 0 "register_operand" "=r")
5976         (xor:SI (match_operand:SI 1 "register_operand" "%r")
5977                 (match_operand:SI 2 "register_operand" "r")))]
5978   ""
5979   "xor %1,%2,%0"
5980   [(set_attr "type" "binary")
5981    (set_attr "length" "4")])
5983 (define_expand "negdi2"
5984   [(set (match_operand:DI 0 "register_operand" "")
5985         (neg:DI (match_operand:DI 1 "register_operand" "")))]
5986   ""
5987   "")
5989 (define_insn ""
5990   [(set (match_operand:DI 0 "register_operand" "=r")
5991         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5992   "!TARGET_64BIT"
5993   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5994   [(set_attr "type" "multi")
5995    (set_attr "length" "8")])
5997 (define_insn ""
5998   [(set (match_operand:DI 0 "register_operand" "=r")
5999         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6000   "TARGET_64BIT"
6001   "sub %%r0,%1,%0"
6002   [(set_attr "type" "unary")
6003    (set_attr "length" "4")])
6005 (define_insn "negti2"
6006   [(set (match_operand:TI 0 "register_operand" "=r")
6007         (neg:TI (match_operand:TI 1 "register_operand" "r")))]
6008   "TARGET_64BIT"
6009   "*
6011   operands[2] = gen_lowpart (DImode, operands[0]);
6012   operands[3] = gen_lowpart (DImode, operands[1]);
6013   operands[0] = gen_highpart (DImode, operands[0]);
6014   operands[1] = gen_highpart (DImode, operands[1]);
6015   return \"sub %%r0,%3,%2\;sub,db %%r0,%1,%0\";
6017   [(set_attr "type" "multi")
6018    (set_attr "length" "8")])
6020 (define_expand "negvdi2"
6021   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6022                    (neg:DI (match_operand:DI 1 "register_operand" "")))
6023               (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6024                                    (sign_extend:TI (neg:DI (match_dup 1))))
6025                        (const_int 0))])]
6026   ""
6027   "")
6029 (define_insn ""
6030   [(set (match_operand:DI 0 "register_operand" "=r")
6031         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6032    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6033                 (sign_extend:TI (neg:DI (match_dup 1))))
6034             (const_int 0))]
6035   "!TARGET_64BIT"
6036   "sub %%r0,%R1,%R0\;{subbo|sub,b,tsv} %%r0,%1,%0"
6037   [(set_attr "type" "multi")
6038    (set_attr "length" "8")])
6040 (define_insn ""
6041   [(set (match_operand:DI 0 "register_operand" "=r")
6042         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6043    (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
6044                 (sign_extend:TI (neg:DI (match_dup 1))))
6045             (const_int 0))]
6046   "TARGET_64BIT"
6047   "sub,tsv %%r0,%1,%0"
6048   [(set_attr "type" "unary")
6049    (set_attr "length" "4")])
6051 (define_insn "negvti2"
6052   [(set (match_operand:TI 0 "register_operand" "=r")
6053         (neg:TI (match_operand:TI 1 "register_operand" "r")))
6054    (trap_if (ne (neg:OI (sign_extend:OI (match_dup 1)))
6055                 (sign_extend:OI (neg:TI (match_dup 1))))
6056             (const_int 0))]
6057   "TARGET_64BIT"
6058   "*
6060   operands[2] = gen_lowpart (DImode, operands[0]);
6061   operands[3] = gen_lowpart (DImode, operands[1]);
6062   operands[0] = gen_highpart (DImode, operands[0]);
6063   operands[1] = gen_highpart (DImode, operands[1]);
6064   return \"sub %%r0,%3,%2\;sub,db,tsv %%r0,%1,%0\";
6066   [(set_attr "type" "multi")
6067    (set_attr "length" "8")])
6069 (define_insn "negsi2"
6070   [(set (match_operand:SI 0 "register_operand" "=r")
6071         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
6072   ""
6073   "sub %%r0,%1,%0"
6074   [(set_attr "type" "unary")
6075    (set_attr "length" "4")])
6077 (define_insn "negvsi2"
6078   [(set (match_operand:SI 0 "register_operand" "=r")
6079         (neg:SI (match_operand:SI 1 "register_operand" "r")))
6080    (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
6081                 (sign_extend:DI (neg:SI (match_dup 1))))
6082             (const_int 0))]
6083    ""
6084    "{subo|sub,tsv} %%r0,%1,%0"
6085   [(set_attr "type" "unary")
6086    (set_attr "length" "4")])
6088 (define_expand "one_cmpldi2"
6089   [(set (match_operand:DI 0 "register_operand" "")
6090         (not:DI (match_operand:DI 1 "register_operand" "")))]
6091   ""
6092   "
6096 (define_insn ""
6097   [(set (match_operand:DI 0 "register_operand" "=r")
6098         (not:DI (match_operand:DI 1 "register_operand" "r")))]
6099   "!TARGET_64BIT"
6100   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
6101   [(set_attr "type" "unary")
6102    (set_attr "length" "8")])
6104 (define_insn ""
6105   [(set (match_operand:DI 0 "register_operand" "=r")
6106         (not:DI (match_operand:DI 1 "register_operand" "r")))]
6107   "TARGET_64BIT"
6108   "uaddcm %%r0,%1,%0"
6109   [(set_attr "type" "unary")
6110    (set_attr "length" "4")])
6112 (define_insn "one_cmplsi2"
6113   [(set (match_operand:SI 0 "register_operand" "=r")
6114         (not:SI (match_operand:SI 1 "register_operand" "r")))]
6115   ""
6116   "uaddcm %%r0,%1,%0"
6117   [(set_attr "type" "unary")
6118    (set_attr "length" "4")])
6120 ;; Floating point arithmetic instructions.
6122 (define_insn "adddf3"
6123   [(set (match_operand:DF 0 "register_operand" "=f")
6124         (plus:DF (match_operand:DF 1 "register_operand" "f")
6125                  (match_operand:DF 2 "register_operand" "f")))]
6126   "! TARGET_SOFT_FLOAT"
6127   "fadd,dbl %1,%2,%0"
6128   [(set_attr "type" "fpalu")
6129    (set_attr "pa_combine_type" "faddsub")
6130    (set_attr "length" "4")])
6132 (define_insn "addsf3"
6133   [(set (match_operand:SF 0 "register_operand" "=f")
6134         (plus:SF (match_operand:SF 1 "register_operand" "f")
6135                  (match_operand:SF 2 "register_operand" "f")))]
6136   "! TARGET_SOFT_FLOAT"
6137   "fadd,sgl %1,%2,%0"
6138   [(set_attr "type" "fpalu")
6139    (set_attr "pa_combine_type" "faddsub")
6140    (set_attr "length" "4")])
6142 (define_insn "subdf3"
6143   [(set (match_operand:DF 0 "register_operand" "=f")
6144         (minus:DF (match_operand:DF 1 "register_operand" "f")
6145                   (match_operand:DF 2 "register_operand" "f")))]
6146   "! TARGET_SOFT_FLOAT"
6147   "fsub,dbl %1,%2,%0"
6148   [(set_attr "type" "fpalu")
6149    (set_attr "pa_combine_type" "faddsub")
6150    (set_attr "length" "4")])
6152 (define_insn "subsf3"
6153   [(set (match_operand:SF 0 "register_operand" "=f")
6154         (minus:SF (match_operand:SF 1 "register_operand" "f")
6155                   (match_operand:SF 2 "register_operand" "f")))]
6156   "! TARGET_SOFT_FLOAT"
6157   "fsub,sgl %1,%2,%0"
6158   [(set_attr "type" "fpalu")
6159    (set_attr "pa_combine_type" "faddsub")
6160    (set_attr "length" "4")])
6162 (define_insn "muldf3"
6163   [(set (match_operand:DF 0 "register_operand" "=f")
6164         (mult:DF (match_operand:DF 1 "register_operand" "f")
6165                  (match_operand:DF 2 "register_operand" "f")))]
6166   "! TARGET_SOFT_FLOAT"
6167   "fmpy,dbl %1,%2,%0"
6168   [(set_attr "type" "fpmuldbl")
6169    (set_attr "pa_combine_type" "fmpy")
6170    (set_attr "length" "4")])
6172 (define_insn "mulsf3"
6173   [(set (match_operand:SF 0 "register_operand" "=f")
6174         (mult:SF (match_operand:SF 1 "register_operand" "f")
6175                  (match_operand:SF 2 "register_operand" "f")))]
6176   "! TARGET_SOFT_FLOAT"
6177   "fmpy,sgl %1,%2,%0"
6178   [(set_attr "type" "fpmulsgl")
6179    (set_attr "pa_combine_type" "fmpy")
6180    (set_attr "length" "4")])
6182 (define_insn "divdf3"
6183   [(set (match_operand:DF 0 "register_operand" "=f")
6184         (div:DF (match_operand:DF 1 "register_operand" "f")
6185                 (match_operand:DF 2 "register_operand" "f")))]
6186   "! TARGET_SOFT_FLOAT"
6187   "fdiv,dbl %1,%2,%0"
6188   [(set_attr "type" "fpdivdbl")
6189    (set_attr "length" "4")])
6191 (define_insn "divsf3"
6192   [(set (match_operand:SF 0 "register_operand" "=f")
6193         (div:SF (match_operand:SF 1 "register_operand" "f")
6194                 (match_operand:SF 2 "register_operand" "f")))]
6195   "! TARGET_SOFT_FLOAT"
6196   "fdiv,sgl %1,%2,%0"
6197   [(set_attr "type" "fpdivsgl")
6198    (set_attr "length" "4")])
6200 ;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
6201 ;; negation can be done by subtracting from plus zero.  However, this
6202 ;; violates the IEEE standard when negating plus and minus zero.
6203 ;; The slow path toggles the sign bit in the general registers.
6204 (define_expand "negdf2"
6205   [(set (match_operand:DF 0 "register_operand" "")
6206         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6207   "!TARGET_SOFT_FLOAT"
6209   if (TARGET_PA_20 || !flag_signed_zeros)
6210     emit_insn (gen_negdf2_fast (operands[0], operands[1]));
6211   else
6212     emit_insn (gen_negdf2_slow (operands[0], operands[1]));
6213   DONE;
6216 (define_insn "negdf2_slow"
6217   [(set (match_operand:DF 0 "register_operand" "=r")
6218         (neg:DF (match_operand:DF 1 "register_operand" "r")))]
6219   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6220   "*
6222   if (rtx_equal_p (operands[0], operands[1]))
6223     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\";
6224   else
6225     return \"and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0\;copy %R1,%R0\";
6227   [(set_attr "type" "multi")
6228    (set (attr "length")
6229         (if_then_else (match_test "rtx_equal_p (operands[0], operands[1])")
6230             (const_int 12)
6231             (const_int 16)))])
6233 (define_insn "negdf2_fast"
6234   [(set (match_operand:DF 0 "register_operand" "=f")
6235         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
6236   "!TARGET_SOFT_FLOAT"
6237   "*
6239   if (TARGET_PA_20)
6240     return \"fneg,dbl %1,%0\";
6241   else
6242     return \"fsub,dbl %%fr0,%1,%0\";
6244   [(set_attr "type" "fpalu")
6245    (set_attr "length" "4")])
6247 (define_expand "negsf2"
6248   [(set (match_operand:SF 0 "register_operand" "")
6249         (neg:SF (match_operand:SF 1 "register_operand" "")))]
6250   "!TARGET_SOFT_FLOAT"
6252   if (TARGET_PA_20 || !flag_signed_zeros)
6253     emit_insn (gen_negsf2_fast (operands[0], operands[1]));
6254   else
6255     emit_insn (gen_negsf2_slow (operands[0], operands[1]));
6256   DONE;
6259 (define_insn "negsf2_slow"
6260   [(set (match_operand:SF 0 "register_operand" "=r")
6261         (neg:SF (match_operand:SF 1 "register_operand" "r")))]
6262   "!TARGET_SOFT_FLOAT && !TARGET_PA_20"
6263   "and,< %1,%1,%0\;depi,tr 1,0,1,%0\;depi 0,0,1,%0"
6264   [(set_attr "type" "multi")
6265    (set_attr "length" "12")])
6267 (define_insn "negsf2_fast"
6268   [(set (match_operand:SF 0 "register_operand" "=f")
6269         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6270   "!TARGET_SOFT_FLOAT"
6271   "*
6273   if (TARGET_PA_20)
6274     return \"fneg,sgl %1,%0\";
6275   else
6276     return \"fsub,sgl %%fr0,%1,%0\";
6278   [(set_attr "type" "fpalu")
6279    (set_attr "length" "4")])
6281 (define_insn "absdf2"
6282   [(set (match_operand:DF 0 "register_operand" "=f")
6283         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
6284   "! TARGET_SOFT_FLOAT"
6285   "fabs,dbl %1,%0"
6286   [(set_attr "type" "fpalu")
6287    (set_attr "length" "4")])
6289 (define_insn "abssf2"
6290   [(set (match_operand:SF 0 "register_operand" "=f")
6291         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6292   "! TARGET_SOFT_FLOAT"
6293   "fabs,sgl %1,%0"
6294   [(set_attr "type" "fpalu")
6295    (set_attr "length" "4")])
6297 (define_insn "sqrtdf2"
6298   [(set (match_operand:DF 0 "register_operand" "=f")
6299         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
6300   "! TARGET_SOFT_FLOAT"
6301   "fsqrt,dbl %1,%0"
6302   [(set_attr "type" "fpsqrtdbl")
6303    (set_attr "length" "4")])
6305 (define_insn "sqrtsf2"
6306   [(set (match_operand:SF 0 "register_operand" "=f")
6307         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6308   "! TARGET_SOFT_FLOAT"
6309   "fsqrt,sgl %1,%0"
6310   [(set_attr "type" "fpsqrtsgl")
6311    (set_attr "length" "4")])
6313 ;; PA 2.0 floating point instructions
6315 ; fmpyfadd patterns
6316 (define_insn "fmadf4"
6317   [(set (match_operand:DF 0 "register_operand" "=f")
6318         (fma:DF (match_operand:DF 1 "register_operand" "f")
6319                 (match_operand:DF 2 "register_operand" "f")
6320                 (match_operand:DF 3 "register_operand" "f")))]
6321   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6322   "fmpyfadd,dbl %1,%2,%3,%0"
6323   [(set_attr "type" "fpmuldbl")
6324    (set_attr "length" "4")])
6326 (define_insn "fmasf4"
6327   [(set (match_operand:SF 0 "register_operand" "=f")
6328         (fma:SF (match_operand:SF 1 "register_operand" "f")
6329                 (match_operand:SF 2 "register_operand" "f")
6330                 (match_operand:SF 3 "register_operand" "f")))]
6331   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6332   "fmpyfadd,sgl %1,%2,%3,%0"
6333   [(set_attr "type" "fpmulsgl")
6334    (set_attr "length" "4")])
6336 ; fmpynfadd patterns
6337 (define_insn "fnmadf4"
6338   [(set (match_operand:DF 0 "register_operand" "=f")
6339         (fma:DF (neg:DF (match_operand:DF 1 "register_operand" "f"))
6340                 (match_operand:DF 2 "register_operand" "f")
6341                 (match_operand:DF 3 "register_operand" "f")))]
6342   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6343   "fmpynfadd,dbl %1,%2,%3,%0"
6344   [(set_attr "type" "fpmuldbl")
6345    (set_attr "length" "4")])
6347 (define_insn "fnmasf4"
6348   [(set (match_operand:SF 0 "register_operand" "=f")
6349         (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
6350                 (match_operand:SF 2 "register_operand" "f")
6351                 (match_operand:SF 3 "register_operand" "f")))]
6352   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6353   "fmpynfadd,sgl %1,%2,%3,%0"
6354   [(set_attr "type" "fpmulsgl")
6355    (set_attr "length" "4")])
6357 ; fnegabs patterns
6358 (define_insn ""
6359   [(set (match_operand:DF 0 "register_operand" "=f")
6360         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
6361   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6362   "fnegabs,dbl %1,%0"
6363   [(set_attr "type" "fpalu")
6364    (set_attr "length" "4")])
6366 (define_insn ""
6367   [(set (match_operand:SF 0 "register_operand" "=f")
6368         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
6369   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
6370   "fnegabs,sgl %1,%0"
6371   [(set_attr "type" "fpalu")
6372    (set_attr "length" "4")])
6374 (define_insn ""
6375   [(set (match_operand:DF 0 "register_operand" "=f")
6376         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6377    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6378   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6379     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6380   "#"
6381   [(set_attr "type" "fpalu")
6382    (set_attr "length" "8")])
6384 (define_split
6385   [(set (match_operand:DF 0 "register_operand" "")
6386         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6387    (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6388   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6389   [(set (match_dup 2) (abs:DF (match_dup 1)))
6390    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6391   "")
6393 (define_insn ""
6394   [(set (match_operand:SF 0 "register_operand" "=f")
6395         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6396    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6397   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6398     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6399   "#"
6400   [(set_attr "type" "fpalu")
6401    (set_attr "length" "8")])
6403 (define_split
6404   [(set (match_operand:SF 0 "register_operand" "")
6405         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6406    (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6407   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6408   [(set (match_dup 2) (abs:SF (match_dup 1)))
6409    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6410   "")
6412 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6413 ;; instruction if we can ignore the sign of zero.
6414 (define_insn ""
6415   [(set (match_operand:DF 0 "register_operand" "=f")
6416         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6417                          (match_operand:DF 2 "register_operand" "f"))))]
6418   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6419   "fmpynfadd,dbl %1,%2,%%fr0,%0"
6420   [(set_attr "type" "fpmuldbl")
6421    (set_attr "length" "4")])
6423 (define_insn ""
6424   [(set (match_operand:SF 0 "register_operand" "=f")
6425         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6426                          (match_operand:SF 2 "register_operand" "f"))))]
6427   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6428   "fmpynfadd,sgl %1,%2,%%fr0,%0"
6429   [(set_attr "type" "fpmuldbl")
6430    (set_attr "length" "4")])
6432 (define_insn ""
6433   [(set (match_operand:DF 0 "register_operand" "=f")
6434         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6435                          (match_operand:DF 2 "register_operand" "f"))))
6436    (set (match_operand:DF 3 "register_operand" "=&f")
6437         (mult:DF (match_dup 1) (match_dup 2)))]
6438   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6439     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6440           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6441   "#"
6442   [(set_attr "type" "fpmuldbl")
6443    (set_attr "length" "8")])
6445 (define_split
6446   [(set (match_operand:DF 0 "register_operand" "")
6447         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6448                          (match_operand:DF 2 "register_operand" ""))))
6449    (set (match_operand:DF 3 "register_operand" "")
6450         (mult:DF (match_dup 1) (match_dup 2)))]
6451   "!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros"
6452   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6453    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6454   "")
6456 (define_insn ""
6457   [(set (match_operand:SF 0 "register_operand" "=f")
6458         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6459                          (match_operand:SF 2 "register_operand" "f"))))
6460    (set (match_operand:SF 3 "register_operand" "=&f")
6461         (mult:SF (match_dup 1) (match_dup 2)))]
6462   "(!TARGET_SOFT_FLOAT && TARGET_PA_20 && !flag_signed_zeros
6463     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6464           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6465   "#"
6466   [(set_attr "type" "fpmuldbl")
6467    (set_attr "length" "8")])
6469 (define_split
6470   [(set (match_operand:SF 0 "register_operand" "")
6471         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6472                          (match_operand:SF 2 "register_operand" ""))))
6473    (set (match_operand:SF 3 "register_operand" "")
6474         (mult:SF (match_dup 1) (match_dup 2)))]
6475   "!TARGET_SOFT_FLOAT && TARGET_PA_20&& !flag_signed_zeros"
6476   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6477    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6478   "")
6480 ;;- Shift instructions
6482 ;; Optimized special case of shifting.
6484 (define_insn ""
6485   [(set (match_operand:SI 0 "register_operand" "=r")
6486         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6487                      (const_int 24)))]
6488   ""
6489   "ldb%M1 %1,%0"
6490   [(set_attr "type" "load")
6491    (set_attr "length" "4")])
6493 (define_insn ""
6494   [(set (match_operand:SI 0 "register_operand" "=r")
6495         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6496                      (const_int 16)))]
6497   ""
6498   "ldh%M1 %1,%0"
6499   [(set_attr "type" "load")
6500    (set_attr "length" "4")])
6502 (define_insn ""
6503   [(set (match_operand:SI 0 "register_operand" "=r")
6504         (plus:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
6505                             (match_operand:SI 3 "shadd_operand" ""))
6506                  (match_operand:SI 1 "register_operand" "r")))]
6507   ""
6508   "{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0} "
6509   [(set_attr "type" "binary")
6510    (set_attr "length" "4")])
6512 (define_insn ""
6513   [(set (match_operand:SI 0 "register_operand" "=r")
6514         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6515                           (match_operand:SI 3 "mem_shadd_operand" ""))
6516                  (match_operand:SI 1 "register_operand" "r")))]
6517   ""
6518   "*
6520   int shift_val = exact_log2 (INTVAL (operands[3]));
6521   operands[3] = GEN_INT (shift_val);
6522   return \"{sh%o3addl %2,%1,%0|shladd,l %2,%o3,%1,%0}\";
6524   [(set_attr "type" "binary")
6525    (set_attr "length" "4")])
6527 (define_insn ""
6528   [(set (match_operand:DI 0 "register_operand" "=r")
6529         (plus:DI (ashift:DI (match_operand:DI 2 "register_operand" "r")
6530                             (match_operand:DI 3 "shadd_operand" ""))
6531                  (match_operand:DI 1 "register_operand" "r")))]
6532   "TARGET_64BIT"
6533   "shladd,l %2,%o3,%1,%0"
6534   [(set_attr "type" "binary")
6535    (set_attr "length" "4")])
6537 (define_insn ""
6538   [(set (match_operand:DI 0 "register_operand" "=r")
6539         (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6540                           (match_operand:DI 3 "mem_shadd_operand" ""))
6541                  (match_operand:DI 1 "register_operand" "r")))]
6542   "TARGET_64BIT"
6543   "*
6545   int shift_val = exact_log2 (INTVAL (operands[3]));
6546   operands[3] = GEN_INT (shift_val);
6547   return \"shladd,l %2,%o3,%1,%0\";
6549   [(set_attr "type" "binary")
6550    (set_attr "length" "4")])
6552 (define_expand "ashlsi3"
6553   [(set (match_operand:SI 0 "register_operand" "")
6554         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6555                    (match_operand:SI 2 "arith32_operand" "")))]
6556   ""
6557   "
6559   if (GET_CODE (operands[2]) != CONST_INT)
6560     {
6561       rtx temp = gen_reg_rtx (SImode);
6562       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6563       if (GET_CODE (operands[1]) == CONST_INT)
6564         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6565       else
6566         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6567       DONE;
6568     }
6569   /* Make sure both inputs are not constants,
6570      there are no patterns for that.  */
6571   operands[1] = force_reg (SImode, operands[1]);
6574 (define_insn ""
6575   [(set (match_operand:SI 0 "register_operand" "=r")
6576         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6577                    (match_operand:SI 2 "const_int_operand" "n")))]
6578   ""
6579   "{zdep|depw,z} %1,%P2,%L2,%0"
6580   [(set_attr "type" "shift")
6581    (set_attr "length" "4")])
6583 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6584 ; Doing it like this makes slightly better code since reload can
6585 ; replace a register with a known value in range -16..15 with a
6586 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6587 ; but since we have no more CONST_OK... characters, that is not
6588 ; possible.
6589 (define_insn "zvdep32"
6590   [(set (match_operand:SI 0 "register_operand" "=r,r")
6591         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6592                    (minus:SI (const_int 31)
6593                              (match_operand:SI 2 "register_operand" "q,q"))))]
6594   ""
6595   "@
6596    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6597    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6598   [(set_attr "type" "shift,shift")
6599    (set_attr "length" "4,4")])
6601 (define_insn "zvdep_imm32"
6602   [(set (match_operand:SI 0 "register_operand" "=r")
6603         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6604                    (minus:SI (const_int 31)
6605                              (match_operand:SI 2 "register_operand" "q"))))]
6606   ""
6607   "*
6609   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6610   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6611   operands[1] = GEN_INT ((x & 0xf) - 0x10);
6612   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6614   [(set_attr "type" "shift")
6615    (set_attr "length" "4")])
6617 (define_insn "vdepi_ior"
6618   [(set (match_operand:SI 0 "register_operand" "=r")
6619         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6620                            (minus:SI (const_int 31)
6621                                      (match_operand:SI 2 "register_operand" "q")))
6622                 (match_operand:SI 3 "register_operand" "0")))]
6623   ; accept ...0001...1, can this be generalized?
6624   "exact_log2 (INTVAL (operands[1]) + 1) > 0"
6625   "*
6627   HOST_WIDE_INT x = INTVAL (operands[1]);
6628   operands[2] = GEN_INT (exact_log2 (x + 1));
6629   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6631   [(set_attr "type" "shift")
6632    (set_attr "length" "4")])
6634 (define_insn "vdepi_and"
6635   [(set (match_operand:SI 0 "register_operand" "=r")
6636         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6637                            (minus:SI (const_int 31)
6638                                      (match_operand:SI 2 "register_operand" "q")))
6639                 (match_operand:SI 3 "register_operand" "0")))]
6640   ; this can be generalized...!
6641   "INTVAL (operands[1]) == -2"
6642   "*
6644   HOST_WIDE_INT x = INTVAL (operands[1]);
6645   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6646   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6648   [(set_attr "type" "shift")
6649    (set_attr "length" "4")])
6651 (define_expand "ashldi3"
6652   [(set (match_operand:DI 0 "register_operand" "")
6653         (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6654                    (match_operand:DI 2 "arith32_operand" "")))]
6655   ""
6656   "
6658   if (!TARGET_64BIT)
6659     {
6660       if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6661         {
6662           unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6663           if (shift >= 1 && shift <= 31)
6664             {
6665               rtx dst = operands[0];
6666               rtx src = force_reg (DImode, operands[1]);
6667               emit_insn (gen_shd_internal (gen_highpart (SImode, dst),
6668                                            gen_lowpart (SImode, src),
6669                                            GEN_INT (32-shift),
6670                                            gen_highpart (SImode, src),
6671                                            GEN_INT (shift)));
6672               emit_insn (gen_ashlsi3 (gen_lowpart (SImode, dst),
6673                                       gen_lowpart (SImode, src),
6674                                       GEN_INT (shift)));
6675               DONE;
6676             }
6677         }
6678       /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6679       FAIL;
6680     }
6681   if (GET_CODE (operands[2]) != CONST_INT)
6682     {
6683       rtx temp = gen_reg_rtx (DImode);
6684       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6685       if (GET_CODE (operands[1]) == CONST_INT)
6686         emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6687       else
6688         emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6689       DONE;
6690     }
6691   /* Make sure both inputs are not constants,
6692      there are no patterns for that.  */
6693   operands[1] = force_reg (DImode, operands[1]);
6696 (define_expand "ashlti3"
6697   [(set (match_operand:TI 0 "register_operand" "")
6698         (ashift:TI (match_operand:TI 1 "lhs_lshift_operand" "")
6699                    (match_operand:TI 2 "arith32_operand" "")))]
6700   "TARGET_64BIT"
6702   if (REG_P (operands[0]) && GET_CODE (operands[2]) == CONST_INT)
6703     {
6704       unsigned HOST_WIDE_INT shift = UINTVAL (operands[2]);
6705       rtx dst = operands[0];
6706       rtx src = force_reg (TImode, operands[1]);
6707       if (shift >= 1 && shift <= 63)
6708         {
6709           emit_insn (gen_shrpd_internal (gen_highpart (DImode, dst),
6710                                          gen_lowpart (DImode, src),
6711                                          GEN_INT (64-shift),
6712                                          gen_highpart (DImode, src),
6713                                          GEN_INT (shift)));
6714           emit_insn (gen_ashldi3 (gen_lowpart (DImode, dst),
6715                                   gen_lowpart (DImode, src),
6716                                   GEN_INT (shift)));
6717           DONE;
6718         }
6719       else if (shift >= 64 && shift <= 127)
6720         {
6721           emit_insn (gen_ashldi3 (gen_highpart (DImode, dst),
6722                                   gen_lowpart (DImode, src),
6723                                   GEN_INT (shift - 64)));
6724           emit_move_insn (gen_lowpart (DImode, dst), GEN_INT (0));
6725           DONE;
6726         }
6727     }
6728   /* Fallback to using optabs.cc's expand_doubleword_shift.  */
6729   FAIL;
6732 (define_insn ""
6733   [(set (match_operand:DI 0 "register_operand" "=r")
6734         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6735                    (match_operand:DI 2 "const_int_operand" "n")))]
6736   "TARGET_64BIT"
6737   "depd,z %1,%p2,%Q2,%0"
6738   [(set_attr "type" "shift")
6739    (set_attr "length" "4")])
6741 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6742 ; Doing it like this makes slightly better code since reload can
6743 ; replace a register with a known value in range -16..15 with a
6744 ; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6745 ; but since we have no more CONST_OK... characters, that is not
6746 ; possible.
6747 (define_insn "zvdep64"
6748   [(set (match_operand:DI 0 "register_operand" "=r,r")
6749         (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6750                    (minus:DI (const_int 63)
6751                              (match_operand:DI 2 "register_operand" "q,q"))))]
6752   "TARGET_64BIT"
6753   "@
6754    depd,z %1,%%sar,64,%0
6755    depdi,z %1,%%sar,64,%0"
6756   [(set_attr "type" "shift,shift")
6757    (set_attr "length" "4,4")])
6759 (define_insn "zvdep_imm64"
6760   [(set (match_operand:DI 0 "register_operand" "=r")
6761         (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6762                    (minus:DI (const_int 63)
6763                              (match_operand:DI 2 "register_operand" "q"))))]
6764   "TARGET_64BIT"
6765   "*
6767   unsigned HOST_WIDE_INT x = UINTVAL (operands[1]);
6768   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6769   operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6770   return \"depdi,z %1,%%sar,%2,%0\";
6772   [(set_attr "type" "shift")
6773    (set_attr "length" "4")])
6775 (define_insn ""
6776   [(set (match_operand:DI 0 "register_operand" "=r")
6777         (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6778                            (minus:DI (const_int 63)
6779                                      (match_operand:DI 2 "register_operand" "q")))
6780                 (match_operand:DI 3 "register_operand" "0")))]
6781   ; accept ...0001...1, can this be generalized?
6782   "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) > 0"
6783   "*
6785   HOST_WIDE_INT x = INTVAL (operands[1]);
6786   operands[2] = GEN_INT (exact_log2 (x + 1));
6787   return \"depdi -1,%%sar,%2,%0\";
6789   [(set_attr "type" "shift")
6790    (set_attr "length" "4")])
6792 (define_insn ""
6793   [(set (match_operand:DI 0 "register_operand" "=r")
6794         (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6795                            (minus:DI (const_int 63)
6796                                      (match_operand:DI 2 "register_operand" "q")))
6797                 (match_operand:DI 3 "register_operand" "0")))]
6798   ; this can be generalized...!
6799   "TARGET_64BIT && INTVAL (operands[1]) == -2"
6800   "*
6802   HOST_WIDE_INT x = INTVAL (operands[1]);
6803   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6804   return \"depdi 0,%%sar,%2,%0\";
6806   [(set_attr "type" "shift")
6807    (set_attr "length" "4")])
6809 (define_expand "ashrsi3"
6810   [(set (match_operand:SI 0 "register_operand" "")
6811         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6812                      (match_operand:SI 2 "arith32_operand" "")))]
6813   ""
6814   "
6816   if (GET_CODE (operands[2]) != CONST_INT)
6817     {
6818       rtx temp = gen_reg_rtx (SImode);
6819       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6820       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6821       DONE;
6822     }
6825 (define_insn ""
6826   [(set (match_operand:SI 0 "register_operand" "=r")
6827         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6828                      (match_operand:SI 2 "const_int_operand" "n")))]
6829   ""
6830   "{extrs|extrw,s} %1,%P2,%L2,%0"
6831   [(set_attr "type" "shift")
6832    (set_attr "length" "4")])
6834 (define_insn "vextrs32"
6835   [(set (match_operand:SI 0 "register_operand" "=r")
6836         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6837                      (minus:SI (const_int 31)
6838                                (match_operand:SI 2 "register_operand" "q"))))]
6839   ""
6840   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6841   [(set_attr "type" "shift")
6842    (set_attr "length" "4")])
6844 (define_expand "ashrdi3"
6845   [(set (match_operand:DI 0 "register_operand" "")
6846         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6847                      (match_operand:DI 2 "arith32_operand" "")))]
6848   "TARGET_64BIT"
6849   "
6851   if (GET_CODE (operands[2]) != CONST_INT)
6852     {
6853       rtx temp = gen_reg_rtx (DImode);
6854       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6855       emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6856       DONE;
6857     }
6860 (define_insn ""
6861   [(set (match_operand:DI 0 "register_operand" "=r")
6862         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6863                      (match_operand:DI 2 "const_int_operand" "n")))]
6864   "TARGET_64BIT"
6865   "extrd,s %1,%p2,%Q2,%0"
6866   [(set_attr "type" "shift")
6867    (set_attr "length" "4")])
6869 (define_insn "vextrs64"
6870   [(set (match_operand:DI 0 "register_operand" "=r")
6871         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6872                      (minus:DI (const_int 63)
6873                                (match_operand:DI 2 "register_operand" "q"))))]
6874   "TARGET_64BIT"
6875   "extrd,s %1,%%sar,64,%0"
6876   [(set_attr "type" "shift")
6877    (set_attr "length" "4")])
6879 (define_insn "lshrsi3"
6880   [(set (match_operand:SI 0 "register_operand" "=r,r")
6881         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6882                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6883   ""
6884   "@
6885    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6886    {extru|extrw,u} %1,%P2,%L2,%0"
6887   [(set_attr "type" "shift")
6888    (set_attr "length" "4")])
6890 (define_insn "lshrdi3"
6891   [(set (match_operand:DI 0 "register_operand" "=r,r")
6892         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6893                      (match_operand:DI 2 "shift6_operand" "q,n")))]
6894   "TARGET_64BIT"
6895   "@
6896    shrpd %%r0,%1,%%sar,%0
6897    extrd,u %1,%p2,%Q2,%0"
6898   [(set_attr "type" "shift")
6899    (set_attr "length" "4")])
6901 ; Shift right pair word 0 to 31 bits.
6902 (define_insn "*shrpsi4_1"
6903   [(set (match_operand:SI 0 "register_operand" "=r")
6904         (match_operator:SI 4 "plus_xor_ior_operator"
6905           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6906                       (minus:SI (const_int 32)
6907                                 (match_operand:SI 3 "register_operand" "q")))
6908            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6909                         (match_dup 3))]))]
6910   ""
6911   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6912   [(set_attr "type" "shift")
6913    (set_attr "length" "4")])
6915 (define_insn "*shrpsi4_2"
6916   [(set (match_operand:SI 0 "register_operand" "=r")
6917         (match_operator:SI 4 "plus_xor_ior_operator"
6918           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6919                         (match_operand:SI 3 "register_operand" "q"))
6920            (ashift:SI (match_operand:SI 1 "register_operand" "r")
6921                       (minus:SI (const_int 32)
6922                                 (match_dup 3)))]))]
6923   ""
6924   "{vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}"
6925   [(set_attr "type" "shift")
6926    (set_attr "length" "4")])
6928 ; Shift right pair doubleword 0 to 63 bits.
6929 (define_insn "*shrpdi4_1"
6930   [(set (match_operand:DI 0 "register_operand" "=r")
6931         (match_operator:DI 4 "plus_xor_ior_operator"
6932           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6933                       (minus:DI (const_int 64)
6934                                 (match_operand:DI 3 "register_operand" "q")))
6935            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6936                         (match_dup 3))]))]
6937   "TARGET_64BIT"
6938   "shrpd %1,%2,%%sar,%0"
6939   [(set_attr "type" "shift")
6940    (set_attr "length" "4")])
6942 (define_insn "*shrpdi4_2"
6943   [(set (match_operand:DI 0 "register_operand" "=r")
6944         (match_operator:DI 4 "plus_xor_ior_operator"
6945           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6946                         (match_operand:DI 3 "shift6_operand" "q"))
6947            (ashift:DI (match_operand:SI 1 "register_operand" "r")
6948                       (minus:DI (const_int 64)
6949                                 (match_dup 3)))]))]
6950   "TARGET_64BIT"
6951   "shrpd %1,%2,%%sar,%0"
6952   [(set_attr "type" "shift")
6953    (set_attr "length" "4")])
6955 (define_insn "*shrpdi4_3"
6956   [(set (match_operand:DI 0 "register_operand" "=r")
6957         (match_operator:DI 5 "plus_xor_ior_operator"
6958           [(ashift:DI (match_operand:DI 1 "register_operand" "r")
6959                       (match_operand:DI 3 "const_int_operand" "n"))
6960            (lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6961                         (match_operand:DI 4 "const_int_operand" "n"))]))]
6962   "TARGET_64BIT
6963    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6964   "shrpd %1,%2,%4,%0"
6965   [(set_attr "type" "shift")
6966    (set_attr "length" "4")])
6968 (define_insn "*shrpdi4_4"
6969   [(set (match_operand:DI 0 "register_operand" "=r")
6970         (match_operator:DI 5 "plus_xor_ior_operator"
6971           [(lshiftrt:DI (match_operand:DI 2 "register_operand" "r")
6972                         (match_operand:DI 4 "const_int_operand" "n"))
6973            (ashift:DI (match_operand:DI 1 "register_operand" "r")
6974                       (match_operand:DI 3 "const_int_operand" "n"))]))]
6975   "TARGET_64BIT
6976    && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
6977   "shrpd %1,%2,%4,%0"
6978   [(set_attr "type" "shift")
6979    (set_attr "length" "4")])
6981 (define_insn "rotrsi3"
6982   [(set (match_operand:SI 0 "register_operand" "=r,r")
6983         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6984                      (match_operand:SI 2 "shift5_operand" "q,n")))]
6985   ""
6986   "*
6988   if (GET_CODE (operands[2]) == CONST_INT)
6989     {
6990       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6991       return \"{shd|shrpw} %1,%1,%2,%0\";
6992     }
6993   else
6994     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6996   [(set_attr "type" "shift")
6997    (set_attr "length" "4")])
6999 (define_expand "rotlsi3"
7000   [(set (match_operand:SI 0 "register_operand" "")
7001         (rotate:SI (match_operand:SI 1 "register_operand" "")
7002                    (match_operand:SI 2 "arith32_operand" "")))]
7003   ""
7004   "
7006   if (GET_CODE (operands[2]) != CONST_INT)
7007     {
7008       rtx temp = gen_reg_rtx (SImode);
7009       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
7010       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
7011       DONE;
7012     }
7013   /* Else expand normally.  */
7016 (define_insn "*rotlsi3_internal"
7017   [(set (match_operand:SI 0 "register_operand" "=r")
7018         (rotate:SI (match_operand:SI 1 "register_operand" "r")
7019                    (match_operand:SI 2 "const_int_operand" "n")))]
7020   ""
7021   "*
7023   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
7024   return \"{shd|shrpw} %1,%1,%2,%0\";
7026   [(set_attr "type" "shift")
7027    (set_attr "length" "4")])
7029 (define_insn "rotrdi3"
7030   [(set (match_operand:DI 0 "register_operand" "=r,r")
7031         (rotatert:DI (match_operand:DI 1 "register_operand" "r,r")
7032                      (match_operand:DI 2 "shift6_operand" "q,n")))]
7033   "TARGET_64BIT"
7034   "*
7036   if (GET_CODE (operands[2]) == CONST_INT)
7037     {
7038       operands[2] = GEN_INT (INTVAL (operands[2]) & 63);
7039       return \"shrpd %1,%1,%2,%0\";
7040     }
7041   else
7042     return \"shrpd %1,%1,%%sar,%0\";
7044   [(set_attr "type" "shift")
7045    (set_attr "length" "4")])
7047 (define_expand "rotldi3"
7048   [(set (match_operand:DI 0 "register_operand" "")
7049         (rotate:DI (match_operand:DI 1 "register_operand" "")
7050                    (match_operand:DI 2 "arith32_operand" "")))]
7051   "TARGET_64BIT"
7052   "
7054   if (GET_CODE (operands[2]) != CONST_INT)
7055     {
7056       rtx temp = gen_reg_rtx (DImode);
7057       emit_insn (gen_subdi3 (temp, GEN_INT (64), operands[2]));
7058       emit_insn (gen_rotrdi3 (operands[0], operands[1], temp));
7059       DONE;
7060     }
7061   /* Else expand normally.  */
7064 (define_insn "*rotldi3_internal"
7065   [(set (match_operand:DI 0 "register_operand" "=r")
7066         (rotate:DI (match_operand:DI 1 "register_operand" "r")
7067                    (match_operand:DI 2 "const_int_operand" "n")))]
7068   "TARGET_64BIT"
7069   "*
7071   operands[2] = GEN_INT ((64 - INTVAL (operands[2])) & 63);
7072   return \"shrpd %1,%1,%2,%0\";
7074   [(set_attr "type" "shift")
7075    (set_attr "length" "4")])
7077 (define_insn ""
7078   [(set (match_operand:SI 0 "register_operand" "=r")
7079         (match_operator:SI 5 "plus_xor_ior_operator"
7080           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
7081                       (match_operand:SI 3 "const_int_operand" "n"))
7082            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7083                         (match_operand:SI 4 "const_int_operand" "n"))]))]
7084   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7085   "{shd|shrpw} %1,%2,%4,%0"
7086   [(set_attr "type" "shift")
7087    (set_attr "length" "4")])
7089 (define_insn ""
7090   [(set (match_operand:SI 0 "register_operand" "=r")
7091         (match_operator:SI 5 "plus_xor_ior_operator"
7092           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
7093                         (match_operand:SI 4 "const_int_operand" "n"))
7094            (ashift:SI (match_operand:SI 1 "register_operand" "r")
7095                       (match_operand:SI 3 "const_int_operand" "n"))]))]
7096   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
7097   "{shd|shrpw} %1,%2,%4,%0"
7098   [(set_attr "type" "shift")
7099    (set_attr "length" "4")])
7101 (define_expand "shd_internal"
7102   [(set (match_operand:SI 0 "register_operand")
7103         (ior:SI
7104           (lshiftrt:SI (match_operand:SI 1 "register_operand")
7105                        (match_operand:SI 2 "const_int_operand"))
7106           (ashift:SI (match_operand:SI 3 "register_operand")
7107                      (match_operand:SI 4 "const_int_operand"))))]
7108   "")
7110 (define_expand "shrpd_internal"
7111   [(set (match_operand:DI 0 "register_operand")
7112         (ior:DI
7113           (lshiftrt:DI (match_operand:DI 1 "register_operand")
7114                        (match_operand:DI 2 "const_int_operand"))
7115           (ashift:DI (match_operand:DI 3 "register_operand")
7116                      (match_operand:DI 4 "const_int_operand"))))]
7117   "TARGET_64BIT")
7119 (define_insn ""
7120   [(set (match_operand:SI 0 "register_operand" "=r")
7121         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
7122                            (match_operand:SI 2 "const_int_operand" ""))
7123                 (match_operand:SI 3 "const_int_operand" "")))]
7124   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) > 0"
7125   "*
7127   int cnt = INTVAL (operands[2]) & 31;
7128   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
7129   operands[2] = GEN_INT (31 - cnt);
7130   return \"{zdep|depw,z} %1,%2,%3,%0\";
7132   [(set_attr "type" "shift")
7133    (set_attr "length" "4")])
7135 ;; Unconditional and other jump instructions.
7137 ;; Trivial return used when no epilogue is needed.
7138 (define_insn "return"
7139   [(return)
7140    (use (reg:SI 2))]
7141   "pa_can_use_return_insn ()"
7142   "*
7144   if (TARGET_PA_20)
7145     return \"bve%* (%%r2)\";
7146   return \"bv%* %%r0(%%r2)\";
7148   [(set_attr "type" "branch")
7149    (set_attr "length" "4")])
7151 ;; This is used for most returns.
7152 (define_insn "return_internal"
7153   [(return)
7154    (use (reg:SI 2))]
7155   ""
7156   "*
7158   if (TARGET_PA_20)
7159     return \"bve%* (%%r2)\";
7160   return \"bv%* %%r0(%%r2)\";
7162   [(set_attr "type" "branch")
7163    (set_attr "length" "4")])
7165 ;; This is used for eh returns which bypass the return stub.
7166 (define_insn "return_external_pic"
7167   [(return)
7168    (clobber (reg:SI 1))
7169    (use (reg:SI 2))]
7170   "!TARGET_NO_SPACE_REGS
7171    && !TARGET_PA_20
7172    && flag_pic && crtl->calls_eh_return"
7173   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
7174   [(set_attr "type" "branch")
7175    (set_attr "length" "12")])
7177 (define_expand "prologue"
7178   [(const_int 0)]
7179   ""
7180   "pa_expand_prologue ();DONE;")
7182 (define_expand "sibcall_epilogue"
7183   [(return)]
7184   ""
7185   "
7187   pa_expand_epilogue ();
7188   DONE;
7191 (define_expand "epilogue"
7192   [(return)]
7193   ""
7194   "
7196   rtx x;
7198   /* Try to use the trivial return first.  Else use the full epilogue.  */
7199   if (pa_can_use_return_insn ())
7200     x = gen_return ();
7201   else
7202     {
7203       pa_expand_epilogue ();
7205       /* EH returns bypass the normal return stub.  Thus, we must do an
7206          interspace branch to return from functions that call eh_return.
7207          This is only a problem for returns from shared code on ports
7208          using space registers.  */
7209       if (!TARGET_NO_SPACE_REGS
7210           && !TARGET_PA_20
7211           && flag_pic && crtl->calls_eh_return)
7212         x = gen_return_external_pic ();
7213       else
7214         x = gen_return_internal ();
7215     }
7216   emit_jump_insn (x);
7217   DONE;
7220 ; Used by hppa_profile_hook to load the starting address of the current
7221 ; function; operand 1 contains the address of the label in operand 3
7222 (define_insn "load_offset_label_address"
7223   [(set (match_operand:SI 0 "register_operand" "=r")
7224         (plus:SI (match_operand:SI 1 "register_operand" "r")
7225                  (minus:SI (match_operand:SI 2 "" "")
7226                            (label_ref:SI (match_operand 3 "" "")))))]
7227   ""
7228   "ldo %2-%l3(%1),%0"
7229   [(set_attr "type" "multi")
7230    (set_attr "length" "4")])
7232 ; Output a code label and load its address.
7233 (define_insn "lcla1"
7234   [(set (match_operand:SI 0 "register_operand" "=r")
7235         (label_ref:SI (match_operand 1 "" "")))
7236    (const_int 0)]
7237   "!TARGET_PA_20"
7238   "*
7240   output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
7241   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7242                                      CODE_LABEL_NUMBER (operands[1]));
7243   return \"\";
7245   [(set_attr "type" "multi")
7246    (set_attr "length" "8")])
7248 (define_insn "lcla2"
7249   [(set (match_operand:SI 0 "register_operand" "=r")
7250         (label_ref:SI (match_operand 1 "" "")))
7251    (const_int 0)]
7252   "TARGET_PA_20"
7253   "*
7255   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
7256                                      CODE_LABEL_NUMBER (operands[1]));
7257   return \"mfia %0\";
7259   [(set_attr "type" "move")
7260    (set_attr "length" "4")])
7262 (define_insn "blockage"
7263   [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
7264   ""
7265   ""
7266   [(set_attr "length" "0")])
7268 (define_insn "jump"
7269   [(set (pc) (label_ref (match_operand 0 "" "")))]
7270   ""
7271   "*
7273   /* An unconditional branch which can reach its target.  */
7274   if (get_attr_length (insn) < 16)
7275     return \"b%* %l0\";
7277   return pa_output_lbranch (operands[0], insn, 1);
7279   [(set_attr "type" "uncond_branch")
7280    (set_attr "pa_combine_type" "uncond_branch")
7281    (set (attr "length")
7282     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
7283                (const_int MAX_17BIT_OFFSET))
7284            (const_int 4)
7285            (match_test "TARGET_PORTABLE_RUNTIME")
7286            (const_int 20)
7287            (not (match_test "flag_pic"))
7288            (const_int 16)]
7289           (const_int 24)))])
7291 ;;; Hope this is only within a function...
7292 (define_insn "indirect_jump"
7293   [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
7294   ""
7295   "bv%* %%r0(%0)"
7296   [(set_attr "type" "branch")
7297    (set_attr "length" "4")])
7299 ;;; An indirect jump can be optimized to a direct jump.  GAS for the
7300 ;;; SOM target doesn't allow branching to a label inside a function.
7301 ;;; We also don't correctly compute branch distances for labels
7302 ;;; outside the current function.  Thus, we use an indirect jump can't
7303 ;;; be optimized to a direct jump for all targets.  We assume that
7304 ;;; the branch target is in the same space (i.e., nested function
7305 ;;; jumping to a label in an outer function in the same translation
7306 ;;; unit).
7307 (define_expand "nonlocal_goto"
7308   [(use (match_operand 0 "general_operand" ""))
7309    (use (match_operand 1 "general_operand" ""))
7310    (use (match_operand 2 "general_operand" ""))
7311    (use (match_operand 3 "general_operand" ""))]
7312   ""
7314   rtx lab = operands[1];
7315   rtx stack = operands[2];
7316   rtx fp = operands[3];
7318   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7319   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7321   lab = copy_to_reg (lab);
7323   /* Restore the stack and frame pointers.  */
7324   fp = copy_to_reg (fp);
7325   emit_stack_restore (SAVE_NONLOCAL, stack);
7327   /* Ensure the frame pointer move is not optimized.  */
7328   emit_insn (gen_blockage ());
7329   emit_clobber (hard_frame_pointer_rtx);
7330   emit_clobber (frame_pointer_rtx);
7331   emit_move_insn (hard_frame_pointer_rtx, fp);
7333   emit_use (hard_frame_pointer_rtx);
7334   emit_use (stack_pointer_rtx);
7336   /* Nonlocal goto jumps are only used between functions in the same
7337      translation unit.  Thus, we can avoid the extra overhead of an
7338      interspace jump.  */
7339   emit_jump_insn (gen_indirect_goto (lab));
7340   emit_barrier ();
7341   DONE;
7344 (define_insn "indirect_goto"
7345   [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
7346   "GET_MODE (operands[0]) == word_mode"
7347   "bv%* %%r0(%0)"
7348   [(set_attr "type" "branch")
7349    (set_attr "length" "4")])
7351 ;; Subroutines of "casesi".
7352 ;; operand 0 is index
7353 ;; operand 1 is the minimum bound
7354 ;; operand 2 is the maximum bound - minimum bound + 1
7355 ;; operand 3 is CODE_LABEL for the table;
7356 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7358 (define_expand "casesi"
7359   [(match_operand:SI 0 "general_operand" "")
7360    (match_operand:SI 1 "const_int_operand" "")
7361    (match_operand:SI 2 "const_int_operand" "")
7362    (match_operand 3 "" "")
7363    (match_operand 4 "" "")]
7364   ""
7365   "
7367   if (GET_CODE (operands[0]) != REG)
7368     operands[0] = force_reg (SImode, operands[0]);
7370   if (operands[1] != const0_rtx)
7371     {
7372       rtx index = gen_reg_rtx (SImode);
7374       operands[1] = gen_int_mode (-INTVAL (operands[1]), SImode);
7375       if (!INT_14_BITS (operands[1]))
7376         operands[1] = force_reg (SImode, operands[1]);
7377       emit_insn (gen_addsi3 (index, operands[0], operands[1]));
7378       operands[0] = index;
7379     }
7381   if (!INT_5_BITS (operands[2]))
7382     operands[2] = force_reg (SImode, operands[2]);
7384   /* This branch prevents us finding an insn for the delay slot of the
7385      following vectored branch.  It might be possible to use the delay
7386      slot if an index value of -1 was used to transfer to the out-of-range
7387      label.  In order to do this, we would have to output the -1 vector
7388      element after the delay insn.  The casesi output code would have to
7389      check if the casesi insn is in a delay branch sequence and output
7390      the delay insn if one is found.  If this was done, then it might
7391      then be worthwhile to split the casesi patterns to improve scheduling.
7392      However, it's not clear that all this extra complexity is worth
7393      the effort.  */
7394   {
7395     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
7396     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
7397   }
7399   /* In 64bit mode we must make sure to wipe the upper bits of the register
7400      just in case the addition overflowed or we had random bits in the
7401      high part of the register.  */
7402   if (TARGET_64BIT)
7403     {
7404       rtx index = gen_reg_rtx (DImode);
7406       emit_insn (gen_extendsidi2 (index, operands[0]));
7407       operands[0] = index;
7408     }
7410   if (TARGET_64BIT)
7411     emit_jump_insn (gen_casesi64p (operands[0], operands[3]));
7412   else if (flag_pic)
7413     emit_jump_insn (gen_casesi32p (operands[0], operands[3]));
7414   else
7415     emit_jump_insn (gen_casesi32 (operands[0], operands[3]));
7416   DONE;
7419 ;;; 32-bit code, absolute branch table.
7420 (define_insn "casesi32"
7421   [(set (pc) (mem:SI (plus:SI
7422                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7423                                 (const_int 4))
7424                        (label_ref (match_operand 1 "" "")))))
7425    (clobber (match_scratch:SI 2 "=&r"))]
7426   "!flag_pic"
7427   "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7428   [(set_attr "type" "multi")
7429    (set_attr "length" "16")])
7431 ;;; 32-bit code, relative branch table.
7432 (define_insn "casesi32p"
7433   [(set (pc) (mem:SI (plus:SI
7434                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7435                                 (const_int 4))
7436                        (label_ref (match_operand 1 "" "")))))
7437    (clobber (match_scratch:SI 2 "=&r"))
7438    (clobber (match_scratch:SI 3 "=&r"))]
7439   "flag_pic"
7440   "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {%l1-.|%l1+4-.}(%2),%2\;\
7441 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7442   [(set_attr "type" "multi")
7443    (set (attr "length")
7444      (if_then_else (match_test "TARGET_PA_20")
7445         (const_int 20)
7446         (const_int 24)))])
7448 ;;; 64-bit code, 32-bit relative branch table.
7449 (define_insn "casesi64p"
7450   [(set (pc) (mem:DI (plus:DI
7451                        (mult:DI (match_operand:DI 0 "register_operand" "r")
7452                                 (const_int 8))
7453                        (label_ref (match_operand 1 "" "")))))
7454    (clobber (match_scratch:DI 2 "=&r"))
7455    (clobber (match_scratch:DI 3 "=&r"))]
7456   ""
7457   "mfia %2\;ldo %l1+4-.(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7458 add,l %2,%3,%3\;bv,n %%r0(%3)"
7459   [(set_attr "type" "multi")
7460    (set_attr "length" "24")])
7463 ;; Call patterns.
7464 ;;- jump to subroutine
7466 (define_expand "call"
7467   [(parallel [(call (match_operand:SI 0 "" "")
7468                     (match_operand 1 "" ""))
7469               (clobber (reg:SI 2))])]
7470   ""
7471   "
7473   rtx op;
7474   rtx nb = operands[1];
7476   if (TARGET_PORTABLE_RUNTIME)
7477     op = force_reg (SImode, XEXP (operands[0], 0));
7478   else
7479     {
7480       op = XEXP (operands[0], 0);
7482       /* Generate indirect long calls to non-local functions. */
7483       if (TARGET_LONG_CALLS && GET_CODE (op) == SYMBOL_REF)
7484         {
7485           tree call_decl = SYMBOL_REF_DECL (op);
7486           if (!(call_decl && targetm.binds_local_p (call_decl)))
7487             op = force_reg (word_mode, op);
7488         }
7489     }
7491   if (TARGET_64BIT)
7492     {
7493       if (!virtuals_instantiated)
7494         emit_move_insn (arg_pointer_rtx,
7495                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7496                                       GEN_INT (64)));
7497       else
7498         {
7499           /* The loop pass can generate new libcalls after the virtual
7500              registers are instantiated when fpregs are disabled because
7501              the only method that we have for doing DImode multiplication
7502              is with a libcall.  This could be trouble if we haven't
7503              allocated enough space for the outgoing arguments.  */
7504           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
7506           emit_move_insn (arg_pointer_rtx,
7507                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7508                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7509         }
7510     }
7512   /* Use two different patterns for calls to explicitly named functions
7513      and calls through function pointers.  This is necessary as these two
7514      types of calls use different calling conventions, and CSE might try
7515      to change the named call into an indirect call in some cases (using
7516      two patterns keeps CSE from performing this optimization).
7517      
7518      We now use even more call patterns as there was a subtle bug in
7519      attempting to restore the pic register after a call using a simple
7520      move insn.  During reload, a instruction involving a pseudo register
7521      with no explicit dependence on the PIC register can be converted
7522      to an equivalent load from memory using the PIC register.  If we
7523      emit a simple move to restore the PIC register in the initial rtl
7524      generation, then it can potentially be repositioned during scheduling.
7525      and an instruction that eventually uses the PIC register may end up
7526      between the call and the PIC register restore.
7527      
7528      This only worked because there is a post call group of instructions
7529      that are scheduled with the call.  These instructions are included
7530      in the same basic block as the call.  However, calls can throw in
7531      C++ code and a basic block has to terminate at the call if the call
7532      can throw.  This results in the PIC register restore being scheduled
7533      independently from the call.  So, we now hide the save and restore
7534      of the PIC register in the call pattern until after reload.  Then,
7535      we split the moves out.  A small side benefit is that we now don't
7536      need to have a use of the PIC register in the return pattern and
7537      the final save/restore operation is not needed.
7538      
7539      I elected to just use register %r4 in the PIC patterns instead
7540      of trying to force hppa_pic_save_rtx () to a callee saved register.
7541      This might have required a new register class and constraint.  It
7542      was also simpler to just handle the restore from a register than a
7543      generic pseudo.  */
7544   if (TARGET_64BIT)
7545     {
7546       rtx r4 = gen_rtx_REG (word_mode, 4);
7547       if (GET_CODE (op) == SYMBOL_REF)
7548         emit_call_insn (gen_call_symref_64bit (op, nb, r4));
7549       else
7550         {
7551           op = force_reg (word_mode, op);
7552           emit_call_insn (gen_call_reg_64bit (op, nb, r4));
7553         }
7554     }
7555   else
7556     {
7557       if (GET_CODE (op) == SYMBOL_REF)
7558         {
7559           if (flag_pic)
7560             {
7561               rtx r4 = gen_rtx_REG (word_mode, 4);
7562               emit_call_insn (gen_call_symref_pic (op, nb, r4));
7563             }
7564           else
7565             emit_call_insn (gen_call_symref (op, nb));
7566         }
7567       else
7568         {
7569           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7570           emit_move_insn (tmpreg, force_reg (word_mode, op));
7571           if (flag_pic)
7572             {
7573               rtx r4 = gen_rtx_REG (word_mode, 4);
7574               emit_call_insn (gen_call_reg_pic (nb, r4));
7575             }
7576           else
7577             emit_call_insn (gen_call_reg (nb));
7578         }
7579     }
7581   DONE;
7584 ;; We use function calls to set the attribute length of calls and millicode
7585 ;; calls.  This is necessary because of the large variety of call sequences.
7586 ;; Implementing the calculation in rtl is difficult as well as ugly.  As
7587 ;; we need the same calculation in several places, maintenance becomes a
7588 ;; nightmare.
7590 ;; However, this has a subtle impact on branch shortening.  When the
7591 ;; expression used to set the length attribute of an instruction depends
7592 ;; on a relative address (e.g., pc or a branch address), genattrtab
7593 ;; notes that the insn's length is variable, and attempts to determine a
7594 ;; worst-case default length and code to compute an insn's current length.
7596 ;; The use of a function call hides the variable dependence of our calls
7597 ;; and millicode calls.  The result is genattrtab doesn't treat the operation
7598 ;; as variable and it only generates code for the default case using our
7599 ;; function call.  Because of this, calls and millicode calls have a fixed
7600 ;; length in the branch shortening pass, and some branches will use a longer
7601 ;; code sequence than necessary.  However, the length of any given call
7602 ;; will still reflect its final code location and it may be shorter than
7603 ;; the initial length estimate.
7605 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7606 ;; in the set.  However, when genattrtab hits a function call in its attempt
7607 ;; to compute the default length, it marks the result as unknown and sets
7608 ;; the default result to MAX_INT ;-(  One possible fix that would allow
7609 ;; calls to participate in branch shortening would be to make the call to
7610 ;; insn_default_length a target option.  Then, we could massage unknown
7611 ;; results.  Another fix might be to change genattrtab so that it just does
7612 ;; the call in the variable case as it already does for the fixed case.
7614 (define_insn "call_symref"
7615   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7616          (match_operand 1 "" "i"))
7617    (clobber (reg:SI 1))
7618    (clobber (reg:SI 2))
7619    (use (const_int 0))]
7620   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7621   "*
7623   pa_output_arg_descriptor (insn);
7624   return pa_output_call (insn, operands[0], 0);
7626   [(set_attr "type" "call")
7627    (set (attr "length")
7628         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7629               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7631 (define_insn "call_symref_pic"
7632   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7633          (match_operand 1 "" "i"))
7634    (clobber (reg:SI 1))
7635    (clobber (reg:SI 2))
7636    (clobber (match_operand 2))
7637    (use (reg:SI 19))
7638    (use (const_int 0))]
7639   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7640   "#")
7642 ;; Split out the PIC register save and restore after reload.  As the
7643 ;; split is done after reload, there are some situations in which we
7644 ;; unnecessarily save and restore %r4.  This happens when there is a
7645 ;; single call and the PIC register is not used after the call.
7647 ;; The split has to be done since call_from_call_insn () can't handle
7648 ;; the pattern as is.  Noreturn calls are special because they have to
7649 ;; terminate the basic block.  The split has to contain more than one
7650 ;; insn.
7651 (define_split
7652   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7653                     (match_operand 1 "" ""))
7654               (clobber (reg:SI 1))
7655               (clobber (reg:SI 2))
7656               (clobber (match_operand 2))
7657               (use (reg:SI 19))
7658               (use (const_int 0))])]
7659   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
7660    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7661   [(set (match_dup 2) (reg:SI 19))
7662    (parallel [(call (mem:SI (match_dup 0))
7663                     (match_dup 1))
7664               (clobber (reg:SI 1))
7665               (clobber (reg:SI 2))
7666               (use (reg:SI 19))
7667               (use (const_int 0))])]
7668   "")
7670 (define_split
7671   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7672                     (match_operand 1 "" ""))
7673               (clobber (reg:SI 1))
7674               (clobber (reg:SI 2))
7675               (clobber (match_operand 2))
7676               (use (reg:SI 19))
7677               (use (const_int 0))])]
7678   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7679   [(set (match_dup 2) (reg:SI 19))
7680    (parallel [(call (mem:SI (match_dup 0))
7681                     (match_dup 1))
7682               (clobber (reg:SI 1))
7683               (clobber (reg:SI 2))
7684               (use (reg:SI 19))
7685               (use (const_int 0))])
7686    (set (reg:SI 19) (match_dup 2))]
7687   "")
7689 (define_insn "*call_symref_pic_post_reload"
7690   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7691          (match_operand 1 "" "i"))
7692    (clobber (reg:SI 1))
7693    (clobber (reg:SI 2))
7694    (use (reg:SI 19))
7695    (use (const_int 0))]
7696   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7697   "*
7699   pa_output_arg_descriptor (insn);
7700   return pa_output_call (insn, operands[0], 0);
7702   [(set_attr "type" "call")
7703    (set (attr "length")
7704         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7705               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7707 ;; This pattern is split if it is necessary to save and restore the
7708 ;; PIC register.
7709 (define_insn "call_symref_64bit"
7710   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7711          (match_operand 1 "" "i"))
7712    (clobber (reg:DI 1))
7713    (clobber (reg:DI 2))
7714    (clobber (match_operand 2))
7715    (use (reg:DI 27))
7716    (use (reg:DI 29))
7717    (use (const_int 0))]
7718   "TARGET_64BIT"
7719   "#")
7721 ;; Split out the PIC register save and restore after reload.  As the
7722 ;; split is done after reload, there are some situations in which we
7723 ;; unnecessarily save and restore %r4.  This happens when there is a
7724 ;; single call and the PIC register is not used after the call.
7726 ;; The split has to be done since call_from_call_insn () can't handle
7727 ;; the pattern as is.  Noreturn calls are special because they have to
7728 ;; terminate the basic block.  The split has to contain more than one
7729 ;; insn.
7730 (define_split
7731   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7732                     (match_operand 1 "" ""))
7733               (clobber (reg:DI 1))
7734               (clobber (reg:DI 2))
7735               (clobber (match_operand 2))
7736               (use (reg:DI 27))
7737               (use (reg:DI 29))
7738               (use (const_int 0))])]
7739   "TARGET_64BIT && reload_completed
7740    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7741   [(set (match_dup 2) (reg:DI 27))
7742    (parallel [(call (mem:SI (match_dup 0))
7743                     (match_dup 1))
7744               (clobber (reg:DI 1))
7745               (clobber (reg:DI 2))
7746               (use (reg:DI 27))
7747               (use (reg:DI 29))
7748               (use (const_int 0))])]
7749   "")
7751 (define_split
7752   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7753                     (match_operand 1 "" ""))
7754               (clobber (reg:DI 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 0))])]
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 1))
7765               (clobber (reg:DI 2))
7766               (use (reg:DI 27))
7767               (use (reg:DI 29))
7768               (use (const_int 0))])
7769    (set (reg:DI 27) (match_dup 2))]
7770   "")
7772 (define_insn "*call_symref_64bit_post_reload"
7773   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7774          (match_operand 1 "" "i"))
7775    (clobber (reg:DI 1))
7776    (clobber (reg:DI 2))
7777    (use (reg:DI 27))
7778    (use (reg:DI 29))
7779    (use (const_int 0))]
7780   "TARGET_64BIT"
7781   "*
7783   return pa_output_call (insn, operands[0], 0);
7785   [(set_attr "type" "call")
7786    (set (attr "length")
7787         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7788               (symbol_ref "pa_attr_length_call (insn, 0)")))])
7790 (define_insn "call_reg"
7791   [(call (mem:SI (reg:SI 22))
7792          (match_operand 0 "" "i"))
7793    (clobber (reg:SI 1))
7794    (clobber (reg:SI 2))
7795    (use (const_int 1))]
7796   "!TARGET_64BIT"
7797   "*
7799   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7801   [(set_attr "type" "dyncall")
7802    (set (attr "length")
7803         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7804               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7806 ;; This pattern is split if it is necessary to save and restore the
7807 ;; PIC register.
7808 (define_insn "call_reg_pic"
7809   [(call (mem:SI (reg:SI 22))
7810          (match_operand 0 "" "i"))
7811    (clobber (reg:SI 1))
7812    (clobber (reg:SI 2))
7813    (clobber (match_operand 1))
7814    (use (reg:SI 19))
7815    (use (const_int 1))]
7816   "!TARGET_64BIT"
7817   "#")
7819 ;; Split out the PIC register save and restore after reload.  As the
7820 ;; split is done after reload, there are some situations in which we
7821 ;; unnecessarily save and restore %r4.  This happens when there is a
7822 ;; single call and the PIC register is not used after the call.
7824 ;; The split has to be done since call_from_call_insn () can't handle
7825 ;; the pattern as is.  Noreturn calls are special because they have to
7826 ;; terminate the basic block.  The split has to contain more than one
7827 ;; insn.
7828 (define_split
7829   [(parallel [(call (mem:SI (reg:SI 22))
7830                     (match_operand 0 "" ""))
7831               (clobber (reg:SI 1))
7832               (clobber (reg:SI 2))
7833               (clobber (match_operand 1))
7834               (use (reg:SI 19))
7835               (use (const_int 1))])]
7836   "!TARGET_64BIT && reload_completed
7837    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7838   [(set (match_dup 1) (reg:SI 19))
7839    (parallel [(call (mem:SI (reg:SI 22))
7840                     (match_dup 0))
7841               (clobber (reg:SI 1))
7842               (clobber (reg:SI 2))
7843               (use (reg:SI 19))
7844               (use (const_int 1))])]
7845   "")
7847 (define_split
7848   [(parallel [(call (mem:SI (reg:SI 22))
7849                     (match_operand 0 "" ""))
7850               (clobber (reg:SI 1))
7851               (clobber (reg:SI 2))
7852               (clobber (match_operand 1))
7853               (use (reg:SI 19))
7854               (use (const_int 1))])]
7855   "!TARGET_64BIT && reload_completed"
7856   [(set (match_dup 1) (reg:SI 19))
7857    (parallel [(call (mem:SI (reg:SI 22))
7858                     (match_dup 0))
7859               (clobber (reg:SI 1))
7860               (clobber (reg:SI 2))
7861               (use (reg:SI 19))
7862               (use (const_int 1))])
7863    (set (reg:SI 19) (match_dup 1))]
7864   "")
7866 (define_insn "*call_reg_pic_post_reload"
7867   [(call (mem:SI (reg:SI 22))
7868          (match_operand 0 "" "i"))
7869    (clobber (reg:SI 1))
7870    (clobber (reg:SI 2))
7871    (use (reg:SI 19))
7872    (use (const_int 1))]
7873   "!TARGET_64BIT"
7874   "*
7876   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7878   [(set_attr "type" "dyncall")
7879    (set (attr "length")
7880         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
7881               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7883 ;; This pattern is split if it is necessary to save and restore the
7884 ;; PIC register.
7885 (define_insn "call_reg_64bit"
7886   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7887          (match_operand 1 "" "i"))
7888    (clobber (reg:DI 2))
7889    (clobber (match_operand 2))
7890    (use (reg:DI 27))
7891    (use (reg:DI 29))
7892    (use (const_int 1))]
7893   "TARGET_64BIT"
7894   "#")
7896 ;; Split out the PIC register save and restore after reload.  As the
7897 ;; split is done after reload, there are some situations in which we
7898 ;; unnecessarily save and restore %r4.  This happens when there is a
7899 ;; single call and the PIC register is not used after the call.
7901 ;; The split has to be done since call_from_call_insn () can't handle
7902 ;; the pattern as is.  Noreturn calls are special because they have to
7903 ;; terminate the basic block.  The split has to contain more than one
7904 ;; insn.
7905 (define_split
7906   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7907                     (match_operand 1 "" ""))
7908               (clobber (reg:DI 2))
7909               (clobber (match_operand 2))
7910               (use (reg:DI 27))
7911               (use (reg:DI 29))
7912               (use (const_int 1))])]
7913   "TARGET_64BIT && reload_completed
7914    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7915   [(set (match_dup 2) (reg:DI 27))
7916    (parallel [(call (mem:SI (match_dup 0))
7917                     (match_dup 1))
7918               (clobber (reg:DI 2))
7919               (use (reg:DI 27))
7920               (use (reg:DI 29))
7921               (use (const_int 1))])]
7922   "")
7924 (define_split
7925   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7926                     (match_operand 1 "" ""))
7927               (clobber (reg:DI 2))
7928               (clobber (match_operand 2))
7929               (use (reg:DI 27))
7930               (use (reg:DI 29))
7931               (use (const_int 1))])]
7932   "TARGET_64BIT && reload_completed"
7933   [(set (match_dup 2) (reg:DI 27))
7934    (parallel [(call (mem:SI (match_dup 0))
7935                     (match_dup 1))
7936               (clobber (reg:DI 2))
7937               (use (reg:DI 27))
7938               (use (reg:DI 29))
7939               (use (const_int 1))])
7940    (set (reg:DI 27) (match_dup 2))]
7941   "")
7943 (define_insn "*call_reg_64bit_post_reload"
7944   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7945          (match_operand 1 "" "i"))
7946    (clobber (reg:DI 2))
7947    (use (reg:DI 27))
7948    (use (reg:DI 29))
7949    (use (const_int 1))]
7950   "TARGET_64BIT"
7951   "*
7953   return pa_output_indirect_call (insn, operands[0]);
7955   [(set_attr "type" "dyncall")
7956    (set (attr "length")
7957         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
7958               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
7960 (define_expand "call_value"
7961   [(parallel [(set (match_operand 0 "" "")
7962                    (call (match_operand:SI 1 "" "")
7963                          (match_operand 2 "" "")))
7964               (clobber (reg:SI 2))])]
7965   ""
7967   rtx op;
7968   rtx dst = operands[0];
7969   rtx nb = operands[2];
7970   bool call_powf = false;
7972   if (TARGET_PORTABLE_RUNTIME)
7973     op = force_reg (SImode, XEXP (operands[1], 0));
7974   else
7975     {
7976       op = XEXP (operands[1], 0);
7977       if (GET_CODE (op) == SYMBOL_REF)
7978         {
7979           /* Handle special call to buggy powf function.  */
7980           if (TARGET_HPUX && !TARGET_SOFT_FLOAT
7981               && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
7982             call_powf = true;
7984           /* Generate indirect long calls to non-local functions. */
7985           else if (TARGET_LONG_CALLS)
7986             {
7987               tree call_decl = SYMBOL_REF_DECL (op);
7988               if (!(call_decl && targetm.binds_local_p (call_decl)))
7989                 op = force_reg (word_mode, op);
7990             }
7991         }
7992     }
7994   if (TARGET_64BIT)
7995     {
7996       if (!virtuals_instantiated)
7997         emit_move_insn (arg_pointer_rtx,
7998                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7999                                       GEN_INT (64)));
8000       else
8001         {
8002           /* The loop pass can generate new libcalls after the virtual
8003              registers are instantiated when fpregs are disabled because
8004              the only method that we have for doing DImode multiplication
8005              is with a libcall.  This could be trouble if we haven't
8006              allocated enough space for the outgoing arguments.  */
8007           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8009           emit_move_insn (arg_pointer_rtx,
8010                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8011                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8012         }
8013     }
8015   /* Use two different patterns for calls to explicitly named functions
8016      and calls through function pointers.  This is necessary as these two
8017      types of calls use different calling conventions, and CSE might try
8018      to change the named call into an indirect call in some cases (using
8019      two patterns keeps CSE from performing this optimization).
8021      We now use even more call patterns as there was a subtle bug in
8022      attempting to restore the pic register after a call using a simple
8023      move insn.  During reload, a instruction involving a pseudo register
8024      with no explicit dependence on the PIC register can be converted
8025      to an equivalent load from memory using the PIC register.  If we
8026      emit a simple move to restore the PIC register in the initial rtl
8027      generation, then it can potentially be repositioned during scheduling.
8028      and an instruction that eventually uses the PIC register may end up
8029      between the call and the PIC register restore.
8030      
8031      This only worked because there is a post call group of instructions
8032      that are scheduled with the call.  These instructions are included
8033      in the same basic block as the call.  However, calls can throw in
8034      C++ code and a basic block has to terminate at the call if the call
8035      can throw.  This results in the PIC register restore being scheduled
8036      independently from the call.  So, we now hide the save and restore
8037      of the PIC register in the call pattern until after reload.  Then,
8038      we split the moves out.  A small side benefit is that we now don't
8039      need to have a use of the PIC register in the return pattern and
8040      the final save/restore operation is not needed.
8041      
8042      I elected to just use register %r4 in the PIC patterns instead
8043      of trying to force hppa_pic_save_rtx () to a callee saved register.
8044      This might have required a new register class and constraint.  It
8045      was also simpler to just handle the restore from a register than a
8046      generic pseudo.  */
8047   if (TARGET_64BIT)
8048     {
8049       rtx r4 = gen_rtx_REG (word_mode, 4);
8050       if (GET_CODE (op) == SYMBOL_REF)
8051         {
8052           if (call_powf)
8053             emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
8054           else
8055             emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
8056         }
8057       else
8058         {
8059           op = force_reg (word_mode, op);
8060           emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
8061         }
8062     }
8063   else
8064     {
8065       if (GET_CODE (op) == SYMBOL_REF)
8066         {
8067           if (flag_pic)
8068             {
8069               rtx r4 = gen_rtx_REG (word_mode, 4);
8071               if (call_powf)
8072                 emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
8073               else
8074                 emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
8075             }
8076           else
8077             {
8078               if (call_powf)
8079                 emit_call_insn (gen_call_val_powf (dst, op, nb));
8080               else
8081                 emit_call_insn (gen_call_val_symref (dst, op, nb));
8082             }
8083         }
8084       else
8085         {
8086           rtx tmpreg = gen_rtx_REG (word_mode, 22);
8087           emit_move_insn (tmpreg, force_reg (word_mode, op));
8088           if (flag_pic)
8089             {
8090               rtx r4 = gen_rtx_REG (word_mode, 4);
8091               emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
8092             }
8093           else
8094             emit_call_insn (gen_call_val_reg (dst, nb));
8095         }
8096     }
8098   DONE;
8101 (define_insn "call_val_symref"
8102   [(set (match_operand 0 "" "")
8103         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8104               (match_operand 2 "" "i")))
8105    (clobber (reg:SI 1))
8106    (clobber (reg:SI 2))
8107    (use (const_int 0))]
8108   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8109   "*
8111   pa_output_arg_descriptor (insn);
8112   return pa_output_call (insn, operands[1], 0);
8114   [(set_attr "type" "call")
8115    (set (attr "length")
8116         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8117               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8119 ;; powf function clobbers %fr12
8120 (define_insn "call_val_powf"
8121   [(set (match_operand 0 "" "")
8122         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8123               (match_operand 2 "" "i")))
8124    (clobber (reg:SI 1))
8125    (clobber (reg:SI 2))
8126    (clobber (reg:DF 48))
8127    (use (const_int 1))]
8128   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8129   "*
8131   pa_output_arg_descriptor (insn);
8132   return pa_output_call (insn, operands[1], 0);
8134   [(set_attr "type" "call")
8135    (set (attr "length")
8136         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8137               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8139 (define_insn "call_val_symref_pic"
8140   [(set (match_operand 0 "" "")
8141         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8142               (match_operand 2 "" "i")))
8143    (clobber (reg:SI 1))
8144    (clobber (reg:SI 2))
8145    (clobber (match_operand 3))
8146    (use (reg:SI 19))
8147    (use (const_int 0))]
8148   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8149   "#")
8151 ;; Split out the PIC register save and restore after reload.  As the
8152 ;; split is done after reload, there are some situations in which we
8153 ;; unnecessarily save and restore %r4.  This happens when there is a
8154 ;; single call and the PIC register is not used after the call.
8156 ;; The split has to be done since call_from_call_insn () can't handle
8157 ;; the pattern as is.  Noreturn calls are special because they have to
8158 ;; terminate the basic block.  The split has to contain more than one
8159 ;; insn.
8160 (define_split
8161   [(parallel [(set (match_operand 0 "" "")
8162               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8163                     (match_operand 2 "" "")))
8164               (clobber (reg:SI 1))
8165               (clobber (reg:SI 2))
8166               (clobber (match_operand 3))
8167               (use (reg:SI 19))
8168               (use (const_int 0))])]
8169   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8170    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8171   [(set (match_dup 3) (reg:SI 19))
8172    (parallel [(set (match_dup 0)
8173               (call (mem:SI (match_dup 1))
8174                     (match_dup 2)))
8175               (clobber (reg:SI 1))
8176               (clobber (reg:SI 2))
8177               (use (reg:SI 19))
8178               (use (const_int 0))])]
8179   "")
8181 (define_split
8182   [(parallel [(set (match_operand 0 "" "")
8183               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8184                     (match_operand 2 "" "")))
8185               (clobber (reg:SI 1))
8186               (clobber (reg:SI 2))
8187               (clobber (match_operand 3))
8188               (use (reg:SI 19))
8189               (use (const_int 0))])]
8190   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8191   [(set (match_dup 3) (reg:SI 19))
8192    (parallel [(set (match_dup 0)
8193               (call (mem:SI (match_dup 1))
8194                     (match_dup 2)))
8195               (clobber (reg:SI 1))
8196               (clobber (reg:SI 2))
8197               (use (reg:SI 19))
8198               (use (const_int 0))])
8199    (set (reg:SI 19) (match_dup 3))]
8200   "")
8202 (define_insn "*call_val_symref_pic_post_reload"
8203   [(set (match_operand 0 "" "")
8204         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8205               (match_operand 2 "" "i")))
8206    (clobber (reg:SI 1))
8207    (clobber (reg:SI 2))
8208    (use (reg:SI 19))
8209    (use (const_int 0))]
8210   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8211   "*
8213   pa_output_arg_descriptor (insn);
8214   return pa_output_call (insn, operands[1], 0);
8216   [(set_attr "type" "call")
8217    (set (attr "length")
8218         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8219               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8221 ;; powf function clobbers %fr12
8222 (define_insn "call_val_powf_pic"
8223   [(set (match_operand 0 "" "")
8224         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8225               (match_operand 2 "" "i")))
8226    (clobber (reg:SI 1))
8227    (clobber (reg:SI 2))
8228    (clobber (reg:DF 48))
8229    (clobber (match_operand 3))
8230    (use (reg:SI 19))
8231    (use (const_int 1))]
8232   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8233   "#")
8235 ;; Split out the PIC register save and restore after reload.  As the
8236 ;; split is done after reload, there are some situations in which we
8237 ;; unnecessarily save and restore %r4.  This happens when there is a
8238 ;; single call and the PIC register is not used after the call.
8240 ;; The split has to be done since call_from_call_insn () can't handle
8241 ;; the pattern as is.  Noreturn calls are special because they have to
8242 ;; terminate the basic block.  The split has to contain more than one
8243 ;; insn.
8244 (define_split
8245   [(parallel [(set (match_operand 0 "" "")
8246               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8247                     (match_operand 2 "" "")))
8248               (clobber (reg:SI 1))
8249               (clobber (reg:SI 2))
8250               (clobber (reg:DF 48))
8251               (clobber (match_operand 3))
8252               (use (reg:SI 19))
8253               (use (const_int 1))])]
8254   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
8255    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8256   [(set (match_dup 3) (reg:SI 19))
8257    (parallel [(set (match_dup 0)
8258               (call (mem:SI (match_dup 1))
8259                     (match_dup 2)))
8260               (clobber (reg:SI 1))
8261               (clobber (reg:SI 2))
8262               (clobber (reg:DF 48))
8263               (use (reg:SI 19))
8264               (use (const_int 1))])]
8265   "")
8267 (define_split
8268   [(parallel [(set (match_operand 0 "" "")
8269               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8270                     (match_operand 2 "" "")))
8271               (clobber (reg:SI 1))
8272               (clobber (reg:SI 2))
8273               (clobber (reg:DF 48))
8274               (clobber (match_operand 3))
8275               (use (reg:SI 19))
8276               (use (const_int 1))])]
8277   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8278   [(set (match_dup 3) (reg:SI 19))
8279    (parallel [(set (match_dup 0)
8280               (call (mem:SI (match_dup 1))
8281                     (match_dup 2)))
8282               (clobber (reg:SI 1))
8283               (clobber (reg:SI 2))
8284               (clobber (reg:DF 48))
8285               (use (reg:SI 19))
8286               (use (const_int 1))])
8287    (set (reg:SI 19) (match_dup 3))]
8288   "")
8290 (define_insn "*call_val_powf_pic_post_reload"
8291   [(set (match_operand 0 "" "")
8292         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8293               (match_operand 2 "" "i")))
8294    (clobber (reg:SI 1))
8295    (clobber (reg:SI 2))
8296    (clobber (reg:DF 48))
8297    (use (reg:SI 19))
8298    (use (const_int 1))]
8299   "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8300   "*
8302   pa_output_arg_descriptor (insn);
8303   return pa_output_call (insn, operands[1], 0);
8305   [(set_attr "type" "call")
8306    (set (attr "length")
8307         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8308               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8310 ;; This pattern is split if it is necessary to save and restore the
8311 ;; PIC register.
8312 (define_insn "call_val_symref_64bit"
8313   [(set (match_operand 0 "" "")
8314         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8315               (match_operand 2 "" "i")))
8316    (clobber (reg:DI 1))
8317    (clobber (reg:DI 2))
8318    (clobber (match_operand 3))
8319    (use (reg:DI 27))
8320    (use (reg:DI 29))
8321    (use (const_int 0))]
8322   "TARGET_64BIT"
8323   "#")
8325 ;; Split out the PIC register save and restore after reload.  As the
8326 ;; split is done after reload, there are some situations in which we
8327 ;; unnecessarily save and restore %r4.  This happens when there is a
8328 ;; single call and the PIC register is not used after the call.
8330 ;; The split has to be done since call_from_call_insn () can't handle
8331 ;; the pattern as is.  Noreturn calls are special because they have to
8332 ;; terminate the basic block.  The split has to contain more than one
8333 ;; insn.
8334 (define_split
8335   [(parallel [(set (match_operand 0 "" "")
8336               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8337                     (match_operand 2 "" "")))
8338               (clobber (reg:DI 1))
8339               (clobber (reg:DI 2))
8340               (clobber (match_operand 3))
8341               (use (reg:DI 27))
8342               (use (reg:DI 29))
8343               (use (const_int 0))])]
8344   "TARGET_64BIT && reload_completed
8345    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8346   [(set (match_dup 3) (reg:DI 27))
8347    (parallel [(set (match_dup 0)
8348               (call (mem:SI (match_dup 1))
8349                     (match_dup 2)))
8350               (clobber (reg:DI 1))
8351               (clobber (reg:DI 2))
8352               (use (reg:DI 27))
8353               (use (reg:DI 29))
8354               (use (const_int 0))])]
8355   "")
8357 (define_split
8358   [(parallel [(set (match_operand 0 "" "")
8359               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8360                     (match_operand 2 "" "")))
8361               (clobber (reg:DI 1))
8362               (clobber (reg:DI 2))
8363               (clobber (match_operand 3))
8364               (use (reg:DI 27))
8365               (use (reg:DI 29))
8366               (use (const_int 0))])]
8367   "TARGET_64BIT && reload_completed"
8368   [(set (match_dup 3) (reg:DI 27))
8369    (parallel [(set (match_dup 0)
8370               (call (mem:SI (match_dup 1))
8371                     (match_dup 2)))
8372               (clobber (reg:DI 1))
8373               (clobber (reg:DI 2))
8374               (use (reg:DI 27))
8375               (use (reg:DI 29))
8376               (use (const_int 0))])
8377    (set (reg:DI 27) (match_dup 3))]
8378   "")
8380 (define_insn "*call_val_symref_64bit_post_reload"
8381   [(set (match_operand 0 "" "")
8382         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8383               (match_operand 2 "" "i")))
8384    (clobber (reg:DI 1))
8385    (clobber (reg:DI 2))
8386    (use (reg:DI 27))
8387    (use (reg:DI 29))
8388    (use (const_int 0))]
8389   "TARGET_64BIT"
8390   "*
8392   return pa_output_call (insn, operands[1], 0);
8394   [(set_attr "type" "call")
8395    (set (attr "length")
8396         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8397               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8399 ;; powf function clobbers %fr12
8400 (define_insn "call_val_powf_64bit"
8401   [(set (match_operand 0 "" "")
8402         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8403               (match_operand 2 "" "i")))
8404    (clobber (reg:DI 1))
8405    (clobber (reg:DI 2))
8406    (clobber (reg:DF 40))
8407    (clobber (match_operand 3))
8408    (use (reg:DI 27))
8409    (use (reg:DI 29))
8410    (use (const_int 1))]
8411   "TARGET_64BIT && TARGET_HPUX"
8412   "#")
8414 ;; Split out the PIC register save and restore after reload.  As the
8415 ;; split is done after reload, there are some situations in which we
8416 ;; unnecessarily save and restore %r4.  This happens when there is a
8417 ;; single call and the PIC register is not used after the call.
8419 ;; The split has to be done since call_from_call_insn () can't handle
8420 ;; the pattern as is.  Noreturn calls are special because they have to
8421 ;; terminate the basic block.  The split has to contain more than one
8422 ;; insn.
8423 (define_split
8424   [(parallel [(set (match_operand 0 "" "")
8425               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8426                     (match_operand 2 "" "")))
8427               (clobber (reg:DI 1))
8428               (clobber (reg:DI 2))
8429               (clobber (reg:DF 40))
8430               (clobber (match_operand 3))
8431               (use (reg:DI 27))
8432               (use (reg:DI 29))
8433               (use (const_int 1))])]
8434   "TARGET_64BIT && TARGET_HPUX && reload_completed
8435    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8436   [(set (match_dup 3) (reg:DI 27))
8437    (parallel [(set (match_dup 0)
8438               (call (mem:SI (match_dup 1))
8439                     (match_dup 2)))
8440               (clobber (reg:DI 1))
8441               (clobber (reg:DI 2))
8442               (clobber (reg:DF 40))
8443               (use (reg:DI 27))
8444               (use (reg:DI 29))
8445               (use (const_int 1))])]
8446   "")
8448 (define_split
8449   [(parallel [(set (match_operand 0 "" "")
8450               (call (mem:SI (match_operand 1 "call_operand_address" ""))
8451                     (match_operand 2 "" "")))
8452               (clobber (reg:DI 1))
8453               (clobber (reg:DI 2))
8454               (clobber (reg:DF 40))
8455               (clobber (match_operand 3))
8456               (use (reg:DI 27))
8457               (use (reg:DI 29))
8458               (use (const_int 1))])]
8459   "TARGET_64BIT && TARGET_HPUX && reload_completed"
8460   [(set (match_dup 3) (reg:DI 27))
8461    (parallel [(set (match_dup 0)
8462               (call (mem:SI (match_dup 1))
8463                     (match_dup 2)))
8464               (clobber (reg:DI 1))
8465               (clobber (reg:DI 2))
8466               (clobber (reg:DF 40))
8467               (use (reg:DI 27))
8468               (use (reg:DI 29))
8469               (use (const_int 1))])
8470    (set (reg:DI 27) (match_dup 3))]
8471   "")
8473 (define_insn "*call_val_powf_64bit_post_reload"
8474   [(set (match_operand 0 "" "")
8475         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8476               (match_operand 2 "" "i")))
8477    (clobber (reg:DI 1))
8478    (clobber (reg:DI 2))
8479    (clobber (reg:DF 40))
8480    (use (reg:DI 27))
8481    (use (reg:DI 29))
8482    (use (const_int 1))]
8483   "TARGET_64BIT && TARGET_HPUX"
8484   "*
8486   return pa_output_call (insn, operands[1], 0);
8488   [(set_attr "type" "call")
8489    (set (attr "length")
8490         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8491               (symbol_ref "pa_attr_length_call (insn, 0)")))])
8493 (define_insn "call_val_reg"
8494   [(set (match_operand 0 "" "")
8495         (call (mem:SI (reg:SI 22))
8496               (match_operand 1 "" "i")))
8497    (clobber (reg:SI 1))
8498    (clobber (reg:SI 2))
8499    (use (const_int 1))]
8500   "!TARGET_64BIT"
8501   "*
8503   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8505   [(set_attr "type" "dyncall")
8506    (set (attr "length")
8507         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8508               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8510 ;; This pattern is split if it is necessary to save and restore the
8511 ;; PIC register.
8512 (define_insn "call_val_reg_pic"
8513   [(set (match_operand 0 "" "")
8514         (call (mem:SI (reg:SI 22))
8515               (match_operand 1 "" "i")))
8516    (clobber (reg:SI 1))
8517    (clobber (reg:SI 2))
8518    (clobber (match_operand 2))
8519    (use (reg:SI 19))
8520    (use (const_int 1))]
8521   "!TARGET_64BIT"
8522   "#")
8524 ;; Split out the PIC register save and restore after reload.  As the
8525 ;; split is done after reload, there are some situations in which we
8526 ;; unnecessarily save and restore %r4.  This happens when there is a
8527 ;; single call and the PIC register is not used after the call.
8529 ;; The split has to be done since call_from_call_insn () can't handle
8530 ;; the pattern as is.  Noreturn calls are special because they have to
8531 ;; terminate the basic block.  The split has to contain more than one
8532 ;; insn.
8533 (define_split
8534   [(parallel [(set (match_operand 0 "" "")
8535                    (call (mem:SI (reg:SI 22))
8536                          (match_operand 1 "" "")))
8537               (clobber (reg:SI 1))
8538               (clobber (reg:SI 2))
8539               (clobber (match_operand 2))
8540               (use (reg:SI 19))
8541               (use (const_int 1))])]
8542   "!TARGET_64BIT && reload_completed
8543    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8544   [(set (match_dup 2) (reg:SI 19))
8545    (parallel [(set (match_dup 0)
8546                    (call (mem:SI (reg:SI 22))
8547                          (match_dup 1)))
8548               (clobber (reg:SI 1))
8549               (clobber (reg:SI 2))
8550               (use (reg:SI 19))
8551               (use (const_int 1))])]
8552   "")
8554 (define_split
8555   [(parallel [(set (match_operand 0 "" "")
8556                    (call (mem:SI (reg:SI 22))
8557                          (match_operand 1 "" "")))
8558               (clobber (reg:SI 1))
8559               (clobber (reg:SI 2))
8560               (clobber (match_operand 2))
8561               (use (reg:SI 19))
8562               (use (const_int 1))])]
8563   "!TARGET_64BIT && reload_completed"
8564   [(set (match_dup 2) (reg:SI 19))
8565    (parallel [(set (match_dup 0)
8566                    (call (mem:SI (reg:SI 22))
8567                          (match_dup 1)))
8568               (clobber (reg:SI 1))
8569               (clobber (reg:SI 2))
8570               (use (reg:SI 19))
8571               (use (const_int 1))])
8572    (set (reg:SI 19) (match_dup 2))]
8573   "")
8575 (define_insn "*call_val_reg_pic_post_reload"
8576   [(set (match_operand 0 "" "")
8577         (call (mem:SI (reg:SI 22))
8578               (match_operand 1 "" "i")))
8579    (clobber (reg:SI 1))
8580    (clobber (reg:SI 2))
8581    (use (reg:SI 19))
8582    (use (const_int 1))]
8583   "!TARGET_64BIT"
8584   "*
8586   return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
8588   [(set_attr "type" "dyncall")
8589    (set (attr "length")
8590         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8591               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8593 ;; This pattern is split if it is necessary to save and restore the
8594 ;; PIC register.
8595 (define_insn "call_val_reg_64bit"
8596   [(set (match_operand 0 "" "")
8597         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8598               (match_operand 2 "" "i")))
8599    (clobber (reg:DI 2))
8600    (clobber (match_operand 3))
8601    (use (reg:DI 27))
8602    (use (reg:DI 29))
8603    (use (const_int 1))]
8604   "TARGET_64BIT"
8605   "#")
8607 ;; Split out the PIC register save and restore after reload.  As the
8608 ;; split is done after reload, there are some situations in which we
8609 ;; unnecessarily save and restore %r4.  This happens when there is a
8610 ;; single call and the PIC register is not used after the call.
8612 ;; The split has to be done since call_from_call_insn () can't handle
8613 ;; the pattern as is.  Noreturn calls are special because they have to
8614 ;; terminate the basic block.  The split has to contain more than one
8615 ;; insn.
8616 (define_split
8617   [(parallel [(set (match_operand 0 "" "")
8618                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8619                          (match_operand 2 "" "")))
8620               (clobber (reg:DI 2))
8621               (clobber (match_operand 3))
8622               (use (reg:DI 27))
8623               (use (reg:DI 29))
8624               (use (const_int 1))])]
8625   "TARGET_64BIT && reload_completed
8626    && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
8627   [(set (match_dup 3) (reg:DI 27))
8628    (parallel [(set (match_dup 0)
8629                    (call (mem:SI (match_dup 1))
8630                          (match_dup 2)))
8631               (clobber (reg:DI 2))
8632               (use (reg:DI 27))
8633               (use (reg:DI 29))
8634               (use (const_int 1))])]
8635   "")
8637 (define_split
8638   [(parallel [(set (match_operand 0 "" "")
8639                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8640                          (match_operand 2 "" "")))
8641               (clobber (reg:DI 2))
8642               (clobber (match_operand 3))
8643               (use (reg:DI 27))
8644               (use (reg:DI 29))
8645               (use (const_int 1))])]
8646   "TARGET_64BIT && reload_completed"
8647   [(set (match_dup 3) (reg:DI 27))
8648    (parallel [(set (match_dup 0)
8649                    (call (mem:SI (match_dup 1))
8650                          (match_dup 2)))
8651               (clobber (reg:DI 2))
8652               (use (reg:DI 27))
8653               (use (reg:DI 29))
8654               (use (const_int 1))])
8655    (set (reg:DI 27) (match_dup 3))]
8656   "")
8658 (define_insn "*call_val_reg_64bit_post_reload"
8659   [(set (match_operand 0 "" "")
8660         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8661               (match_operand 2 "" "i")))
8662    (clobber (reg:DI 2))
8663    (use (reg:DI 27))
8664    (use (reg:DI 29))
8665    (use (const_int 1))]
8666   "TARGET_64BIT"
8667   "*
8669   return pa_output_indirect_call (insn, operands[1]);
8671   [(set_attr "type" "dyncall")
8672    (set (attr "length")
8673         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
8674               (symbol_ref "pa_attr_length_indirect_call (insn)")))])
8676 /* Expand special pc-relative call to _mcount.  */
8678 (define_expand "call_mcount"
8679   [(parallel [(call (match_operand:SI 0 "" "")
8680                     (match_operand 1 "" ""))
8681               (set (reg:SI 25)
8682                    (plus:SI (reg:SI 2)
8683                             (minus:SI (match_operand 2 "" "")
8684                                       (plus:SI (pc) (const_int 4)))))
8685               (clobber (reg:SI 2))])]
8686   "!TARGET_PORTABLE_RUNTIME"
8687   "
8689   rtx op = XEXP (operands[0], 0);
8690   rtx nb = operands[1];
8691   rtx lab = operands[2];
8693   if (TARGET_64BIT)
8694     {
8695       rtx r4 = gen_rtx_REG (word_mode, 4);
8696       emit_move_insn (arg_pointer_rtx,
8697                       gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8698                                     GEN_INT (64)));
8699       emit_call_insn (gen_call_mcount_64bit (op, nb, lab, r4));
8700     }
8701   else
8702     {
8703       if (flag_pic)
8704         {
8705           rtx r4 = gen_rtx_REG (word_mode, 4);
8706           emit_call_insn (gen_call_mcount_pic (op, nb, lab, r4));
8707         }
8708       else
8709         emit_call_insn (gen_call_mcount_nonpic (op, nb, lab));
8710     }
8712   DONE;
8715 (define_insn "call_mcount_nonpic"
8716   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8717          (match_operand 1 "" "i"))
8718    (set (reg:SI 25)
8719         (plus:SI (reg:SI 2)
8720                  (minus:SI (match_operand 2 "" "")
8721                            (plus:SI (pc) (const_int 4)))))
8722    (clobber (reg:SI 2))]
8723   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8724   "*
8726   pa_output_arg_descriptor (insn);
8727   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8729   [(set_attr "type" "multi")
8730    (set_attr "length" "8")])
8732 (define_insn "call_mcount_pic"
8733   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8734          (match_operand 1 "" "i"))
8735    (set (reg:SI 25)
8736         (plus:SI (reg:SI 2)
8737                  (minus:SI (match_operand 2 "" "")
8738                            (plus:SI (pc) (const_int 4)))))
8739    (clobber (reg:SI 2))
8740    (clobber (match_operand 3))
8741    (use (reg:SI 19))]
8742   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8743   "#")
8745 (define_split
8746   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8747                     (match_operand 1 "" ""))
8748               (set (reg:SI 25)
8749                    (plus:SI (reg:SI 2)
8750                             (minus:SI (match_operand 2 "" "")
8751                                       (plus:SI (pc) (const_int 4)))))
8752               (clobber (reg:SI 2))
8753               (clobber (match_operand 3))
8754               (use (reg:SI 19))])]
8755   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
8756   [(set (match_dup 3) (reg:SI 19))
8757    (parallel [(call (mem:SI (match_dup 0))
8758                     (match_dup 1))
8759               (set (reg:SI 25)
8760                    (plus:SI (reg:SI 2)
8761                             (minus:SI (match_dup 2)
8762                                       (plus:SI (pc) (const_int 4)))))
8763               (clobber (reg:SI 2))
8764               (use (reg:SI 19))])
8765    (set (reg:SI 19) (match_dup 3))]
8766   "")
8768 (define_insn "*call_mcount_pic_post_reload"
8769   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8770          (match_operand 1 "" "i"))
8771    (set (reg:SI 25)
8772         (plus:SI (reg:SI 2)
8773                  (minus:SI (match_operand 2 "" "")
8774                            (plus:SI (pc) (const_int 4)))))
8775    (clobber (reg:SI 2))
8776    (use (reg:SI 19))]
8777   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8778   "*
8780   pa_output_arg_descriptor (insn);
8781   return \"{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25\";
8783   [(set_attr "type" "multi")
8784    (set_attr "length" "8")])
8786 (define_insn "call_mcount_64bit"
8787   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8788          (match_operand 1 "" "i"))
8789    (set (reg:SI 25)
8790         (plus:SI (reg:SI 2)
8791                  (minus:SI (match_operand 2 "" "")
8792                            (plus:SI (pc) (const_int 4)))))
8793    (clobber (reg:DI 2))
8794    (clobber (match_operand 3))
8795    (use (reg:DI 27))
8796    (use (reg:DI 29))]
8797   "TARGET_64BIT"
8798   "#")
8800 (define_split
8801   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8802                     (match_operand 1 "" ""))
8803               (set (reg:SI 25)
8804                    (plus:SI (reg:SI 2)
8805                             (minus:SI (match_operand 2 "" "")
8806                                       (plus:SI (pc) (const_int 4)))))
8807               (clobber (reg:DI 2))
8808               (clobber (match_operand 3))
8809               (use (reg:DI 27))
8810               (use (reg:DI 29))])]
8811   "TARGET_64BIT && reload_completed"
8812   [(set (match_dup 3) (reg:DI 27))
8813    (parallel [(call (mem:SI (match_dup 0))
8814                     (match_dup 1))
8815               (set (reg:SI 25)
8816                    (plus:SI (reg:SI 2)
8817                             (minus:SI (match_dup 2)
8818                                       (plus:SI (pc) (const_int 4)))))
8819               (clobber (reg:DI 2))
8820               (use (reg:DI 27))
8821               (use (reg:DI 29))])
8822    (set (reg:DI 27) (match_dup 3))]
8823   "")
8825 (define_insn "*call_mcount_64bit_post_reload"
8826   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8827          (match_operand 1 "" "i"))
8828    (set (reg:SI 25)
8829         (plus:SI (reg:SI 2)
8830                  (minus:SI (match_operand 2 "" "")
8831                            (plus:SI (pc) (const_int 4)))))
8832    (clobber (reg:DI 2))
8833    (use (reg:DI 27))
8834    (use (reg:DI 29))]
8835   "TARGET_64BIT"
8836   "{bl|b,l} %0,%%r2\;ldo %2-.-4(%%r2),%%r25"
8837   [(set_attr "type" "multi")
8838    (set_attr "length" "8")])
8840 ;; Call subroutine returning any type.
8842 (define_expand "untyped_call"
8843   [(parallel [(call (match_operand 0 "" "")
8844                     (const_int 0))
8845               (match_operand 1 "" "")
8846               (match_operand 2 "" "")])]
8847   ""
8848   "
8850   int i;
8852   emit_call_insn (gen_call (operands[0], const0_rtx));
8854   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8855     {
8856       rtx set = XVECEXP (operands[2], 0, i);
8857       emit_move_insn (SET_DEST (set), SET_SRC (set));
8858     }
8860   /* The optimizer does not know that the call sets the function value
8861      registers we stored in the result block.  We avoid problems by
8862      claiming that all hard registers are used and clobbered at this
8863      point.  */
8864   emit_insn (gen_blockage ());
8866   DONE;
8869 (define_expand "sibcall"
8870   [(call (match_operand:SI 0 "" "")
8871          (match_operand 1 "" ""))]
8872   "!TARGET_PORTABLE_RUNTIME"
8873   "
8875   rtx op, call_insn;
8876   rtx nb = operands[1];
8878   op = XEXP (operands[0], 0);
8880   if (TARGET_64BIT)
8881     {
8882       if (!virtuals_instantiated)
8883         emit_move_insn (arg_pointer_rtx,
8884                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8885                                       GEN_INT (64)));
8886       else
8887         {
8888           /* The loop pass can generate new libcalls after the virtual
8889              registers are instantiated when fpregs are disabled because
8890              the only method that we have for doing DImode multiplication
8891              is with a libcall.  This could be trouble if we haven't
8892              allocated enough space for the outgoing arguments.  */
8893           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8895           emit_move_insn (arg_pointer_rtx,
8896                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8897                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8898         }
8899     }
8901   /* Indirect sibling calls are not allowed.  */
8902   if (TARGET_64BIT)
8903     call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8904   else
8905     call_insn = gen_sibcall_internal_symref (op, operands[1]);
8907   call_insn = emit_call_insn (call_insn);
8909   if (TARGET_64BIT)
8910     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8912   /* We don't have to restore the PIC register.  */
8913   if (flag_pic)
8914     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8916   DONE;
8919 (define_insn "sibcall_internal_symref"
8920   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8921          (match_operand 1 "" "i"))
8922    (clobber (reg:SI 1))
8923    (use (reg:SI 2))
8924    (use (const_int 0))]
8925   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8926   "*
8928   pa_output_arg_descriptor (insn);
8929   return pa_output_call (insn, operands[0], 1);
8931   [(set_attr "type" "sibcall")
8932    (set (attr "length")
8933         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8934               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8936 (define_insn "sibcall_internal_symref_64bit"
8937   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8938          (match_operand 1 "" "i"))
8939    (clobber (reg:DI 1))
8940    (use (reg:DI 2))
8941    (use (const_int 0))]
8942   "TARGET_64BIT"
8943   "*
8945   return pa_output_call (insn, operands[0], 1);
8947   [(set_attr "type" "sibcall")
8948    (set (attr "length")
8949         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
8950               (symbol_ref "pa_attr_length_call (insn, 1)")))])
8952 (define_expand "sibcall_value"
8953   [(set (match_operand 0 "" "")
8954                    (call (match_operand:SI 1 "" "")
8955                          (match_operand 2 "" "")))]
8956   "!TARGET_PORTABLE_RUNTIME"
8957   "
8959   rtx op, call_insn;
8960   rtx nb = operands[1];
8962   op = XEXP (operands[1], 0);
8964   if (TARGET_64BIT)
8965     {
8966       if (!virtuals_instantiated)
8967         emit_move_insn (arg_pointer_rtx,
8968                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8969                                       GEN_INT (64)));
8970       else
8971         {
8972           /* The loop pass can generate new libcalls after the virtual
8973              registers are instantiated when fpregs are disabled because
8974              the only method that we have for doing DImode multiplication
8975              is with a libcall.  This could be trouble if we haven't
8976              allocated enough space for the outgoing arguments.  */
8977           gcc_assert (INTVAL (nb) <= crtl->outgoing_args_size);
8979           emit_move_insn (arg_pointer_rtx,
8980                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8981                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8982         }
8983     }
8985   /* Indirect sibling calls are not allowed.  */
8986   if (TARGET_64BIT)
8987     call_insn
8988       = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8989   else
8990     call_insn
8991       = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8993   call_insn = emit_call_insn (call_insn);
8995   if (TARGET_64BIT)
8996     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8998   /* We don't have to restore the PIC register.  */
8999   if (flag_pic)
9000     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
9002   DONE;
9005 (define_insn "sibcall_value_internal_symref"
9006   [(set (match_operand 0 "" "")
9007         (call (mem:SI (match_operand 1 "call_operand_address" ""))
9008               (match_operand 2 "" "i")))
9009    (clobber (reg:SI 1))
9010    (use (reg:SI 2))
9011    (use (const_int 0))]
9012   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9013   "*
9015   pa_output_arg_descriptor (insn);
9016   return pa_output_call (insn, operands[1], 1);
9018   [(set_attr "type" "sibcall")
9019    (set (attr "length")
9020         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9021               (symbol_ref "pa_attr_length_call (insn, 1)")))])
9023 (define_insn "sibcall_value_internal_symref_64bit"
9024   [(set (match_operand 0 "" "")
9025         (call (mem:SI (match_operand 1 "call_operand_address" ""))
9026               (match_operand 2 "" "i")))
9027    (clobber (reg:DI 1))
9028    (use (reg:DI 2))
9029    (use (const_int 0))]
9030   "TARGET_64BIT"
9031   "*
9033   return pa_output_call (insn, operands[1], 1);
9035   [(set_attr "type" "sibcall")
9036    (set (attr "length")
9037         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
9038               (symbol_ref "pa_attr_length_call (insn, 1)")))])
9040 (define_insn "nop"
9041   [(const_int 0)]
9042   ""
9043   "nop"
9044   [(set_attr "type" "move")
9045    (set_attr "length" "4")])
9047 ;;; EH does longjmp's from and within the data section.  Thus,
9048 ;;; an interspace branch is required for the longjmp implementation.
9049 ;;; Registers r1 and r2 are used as scratch registers for the jump
9050 ;;; when necessary.
9051 (define_expand "interspace_jump"
9052   [(parallel
9053      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9054       (clobber (match_dup 1))])]
9055   ""
9056   "
9058   operands[1] = gen_rtx_REG (word_mode, 2);
9061 (define_insn ""
9062   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9063   (clobber (reg:SI 2))]
9064   "TARGET_PA_20 && !TARGET_64BIT"
9065   "bve%* (%0)"
9066    [(set_attr "type" "branch")
9067     (set_attr "length" "4")])
9069 (define_insn ""
9070   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9071   (clobber (reg:SI 2))]
9072   "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
9073   "be%* 0(%%sr4,%0)"
9074    [(set_attr "type" "branch")
9075     (set_attr "length" "4")])
9077 (define_insn ""
9078   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9079   (clobber (reg:SI 2))]
9080   "!TARGET_64BIT"
9081   "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
9082    [(set_attr "type" "branch")
9083     (set_attr "length" "12")])
9085 (define_insn ""
9086   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
9087   (clobber (reg:DI 2))]
9088   "TARGET_64BIT"
9089   "bve%* (%0)"
9090    [(set_attr "type" "branch")
9091     (set_attr "length" "4")])
9093 (define_expand "builtin_longjmp"
9094   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
9095   ""
9096   "
9098   /* The elements of the buffer are, in order:  */
9099   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
9100   rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9101                          POINTER_SIZE / BITS_PER_UNIT));
9102   rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
9103                            (POINTER_SIZE * 2) / BITS_PER_UNIT));
9104   rtx pv = gen_rtx_REG (Pmode, 1);
9106   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
9107   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
9109   /* Load the label we are jumping through into r1 so that we know
9110      where to look for it when we get back to setjmp's function for
9111      restoring the gp.  */
9112   emit_move_insn (pv, lab);
9114   /* Restore the stack and frame pointers.  */
9115   fp = copy_to_reg (fp);
9116   emit_stack_restore (SAVE_NONLOCAL, stack);
9118   /* Ensure the frame pointer move is not optimized.  */
9119   emit_insn (gen_blockage ());
9120   emit_clobber (hard_frame_pointer_rtx);
9121   emit_clobber (frame_pointer_rtx);
9122   emit_move_insn (hard_frame_pointer_rtx, fp);
9124   emit_use (hard_frame_pointer_rtx);
9125   emit_use (stack_pointer_rtx);
9127   /* Prevent the insns above from being scheduled into the delay slot
9128      of the interspace jump because the space register could change.  */
9129   emit_insn (gen_blockage ());
9131   emit_jump_insn (gen_interspace_jump (pv));
9132   emit_barrier ();
9133   DONE;
9136 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
9137 (define_expand "extzvsi"
9138   [(set (match_operand:SI 0 "register_operand" "")
9139         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
9140                          (match_operand:SI 2 "uint5_operand" "")
9141                          (match_operand:SI 3 "uint5_operand" "")))]
9142   ""
9143   "
9145   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9146   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9148   /* PA extraction insns don't support zero length bitfields or fields
9149      extending beyond the left or right-most bits.  Also, the predicate
9150      rejects lengths equal to a word as they are better handled by
9151      the move patterns.  */
9152   if (len == 0 || pos + len > 32)
9153     FAIL;
9155   /* From mips.md: extract_bit_field doesn't verify that our source
9156      matches the predicate, so check it again here.  */
9157   if (!register_operand (operands[1], VOIDmode))
9158     FAIL;
9160   emit_insn (gen_extzv_32 (operands[0], operands[1],
9161                            operands[2], operands[3]));
9162   DONE;
9165 (define_insn "extzv_32"
9166   [(set (match_operand:SI 0 "register_operand" "=r")
9167         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9168                          (match_operand:SI 2 "uint5_operand" "")
9169                          (match_operand:SI 3 "uint5_operand" "")))]
9170   "UINTVAL (operands[2]) > 0
9171    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9172   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
9173   [(set_attr "type" "shift")
9174    (set_attr "length" "4")])
9176 (define_insn ""
9177   [(set (match_operand:SI 0 "register_operand" "=r")
9178         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
9179                          (const_int 1)
9180                          (match_operand:SI 2 "register_operand" "q")))]
9181   ""
9182   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
9183   [(set_attr "type" "shift")
9184    (set_attr "length" "4")])
9186 (define_expand "extzvdi"
9187   [(set (match_operand:DI 0 "register_operand" "")
9188         (zero_extract:DI (match_operand:DI 1 "register_operand" "")
9189                          (match_operand:DI 2 "uint6_operand" "")
9190                          (match_operand:DI 3 "uint6_operand" "")))]
9191   "TARGET_64BIT"
9192   "
9194   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9195   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9197   /* PA extraction insns don't support zero length bitfields or fields
9198      extending beyond the left or right-most bits.  Also, the predicate
9199      rejects lengths equal to a doubleword as they are better handled by
9200      the move patterns.  */
9201   if (len == 0 || pos + len > 64)
9202     FAIL;
9204   /* From mips.md: extract_bit_field doesn't verify that our source
9205      matches the predicate, so check it again here.  */
9206   if (!register_operand (operands[1], VOIDmode))
9207     FAIL;
9209   emit_insn (gen_extzv_64 (operands[0], operands[1],
9210                            operands[2], operands[3]));
9211   DONE;
9214 (define_insn "extzv_64"
9215   [(set (match_operand:DI 0 "register_operand" "=r")
9216         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9217                          (match_operand:DI 2 "uint6_operand" "")
9218                          (match_operand:DI 3 "uint6_operand" "")))]
9219   "TARGET_64BIT
9220    && UINTVAL (operands[2]) > 0
9221    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9222   "extrd,u %1,%3+%2-1,%2,%0"
9223   [(set_attr "type" "shift")
9224    (set_attr "length" "4")])
9226 (define_insn ""
9227   [(set (match_operand:DI 0 "register_operand" "=r")
9228         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
9229                          (const_int 1)
9230                          (match_operand:DI 2 "register_operand" "q")))]
9231   "TARGET_64BIT"
9232   "extrd,u %1,%%sar,1,%0"
9233   [(set_attr "type" "shift")
9234    (set_attr "length" "4")])
9236 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
9237 (define_expand "extvsi"
9238   [(set (match_operand:SI 0 "register_operand" "")
9239         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9240                          (match_operand:SI 2 "uint5_operand" "")
9241                          (match_operand:SI 3 "uint5_operand" "")))]
9242   ""
9243   "
9245   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9246   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9248   /* PA extraction insns don't support zero length bitfields or fields
9249      extending beyond the left or right-most bits.  Also, the predicate
9250      rejects lengths equal to a word as they are better handled by
9251      the move patterns.  */
9252   if (len == 0 || pos + len > 32)
9253     FAIL;
9255   /* From mips.md: extract_bit_field doesn't verify that our source
9256      matches the predicate, so check it again here.  */
9257   if (!register_operand (operands[1], VOIDmode))
9258     FAIL;
9260   emit_insn (gen_extv_32 (operands[0], operands[1],
9261                           operands[2], operands[3]));
9262   DONE;
9265 (define_insn "extv_32"
9266   [(set (match_operand:SI 0 "register_operand" "=r")
9267         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9268                          (match_operand:SI 2 "uint5_operand" "")
9269                          (match_operand:SI 3 "uint5_operand" "")))]
9270   "UINTVAL (operands[2]) > 0
9271    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
9272   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
9273   [(set_attr "type" "shift")
9274    (set_attr "length" "4")])
9276 (define_insn ""
9277   [(set (match_operand:SI 0 "register_operand" "=r")
9278         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
9279                          (const_int 1)
9280                          (match_operand:SI 2 "register_operand" "q")))]
9281   "!TARGET_64BIT"
9282   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
9283   [(set_attr "type" "shift")
9284    (set_attr "length" "4")])
9286 (define_expand "extvdi"
9287   [(set (match_operand:DI 0 "register_operand" "")
9288         (sign_extract:DI (match_operand:DI 1 "register_operand" "")
9289                          (match_operand:DI 2 "uint6_operand" "")
9290                          (match_operand:DI 3 "uint6_operand" "")))]
9291   "TARGET_64BIT"
9292   "
9294   unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
9295   unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
9297   /* PA extraction insns don't support zero length bitfields or fields
9298      extending beyond the left or right-most bits.  Also, the predicate
9299      rejects lengths equal to a doubleword as they are better handled by
9300      the move patterns.  */
9301   if (len == 0 || pos + len > 64)
9302     FAIL;
9304   /* From mips.md: extract_bit_field doesn't verify that our source
9305      matches the predicate, so check it again here.  */
9306   if (!register_operand (operands[1], VOIDmode))
9307     FAIL;
9309   emit_insn (gen_extv_64 (operands[0], operands[1],
9310                           operands[2], operands[3]));
9311   DONE;
9314 (define_insn "extv_64"
9315   [(set (match_operand:DI 0 "register_operand" "=r")
9316         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9317                          (match_operand:DI 2 "uint6_operand" "")
9318                          (match_operand:DI 3 "uint6_operand" "")))]
9319   "TARGET_64BIT
9320    && UINTVAL (operands[2]) > 0
9321    && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
9322   "extrd,s %1,%3+%2-1,%2,%0"
9323   [(set_attr "type" "shift")
9324    (set_attr "length" "4")])
9326 (define_insn ""
9327   [(set (match_operand:DI 0 "register_operand" "=r")
9328         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
9329                          (const_int 1)
9330                          (match_operand:DI 2 "register_operand" "q")))]
9331   "TARGET_64BIT"
9332   "extrd,s %1,%%sar,1,%0"
9333   [(set_attr "type" "shift")
9334    (set_attr "length" "4")])
9336 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
9337 (define_expand "insvsi"
9338   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
9339                          (match_operand:SI 1 "uint5_operand" "")
9340                          (match_operand:SI 2 "uint5_operand" ""))
9341         (match_operand:SI 3 "arith5_operand" ""))]
9342   ""
9343   "
9345   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9346   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9348   /* PA insertion insns don't support zero length bitfields or fields
9349      extending beyond the left or right-most bits.  Also, the predicate
9350      rejects lengths equal to a word as they are better handled by
9351      the move patterns.  */
9352   if (len <= 0 || pos + len > 32)
9353     FAIL;
9355   /* From mips.md: insert_bit_field doesn't verify that our destination
9356      matches the predicate, so check it again here.  */
9357   if (!register_operand (operands[0], VOIDmode))
9358     FAIL;
9360   emit_insn (gen_insv_32 (operands[0], operands[1],
9361                           operands[2], operands[3]));
9362   DONE;
9365 (define_insn "insv_32"
9366   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
9367                          (match_operand:SI 1 "uint5_operand" "")
9368                          (match_operand:SI 2 "uint5_operand" ""))
9369         (match_operand:SI 3 "arith5_operand" "r,L"))]
9370   "UINTVAL (operands[1]) > 0
9371    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
9372   "@
9373    {dep|depw} %3,%2+%1-1,%1,%0
9374    {depi|depwi} %3,%2+%1-1,%1,%0"
9375   [(set_attr "type" "shift,shift")
9376    (set_attr "length" "4,4")])
9378 ;; Optimize insertion of const_int values of type 1...1xxxx.
9379 (define_insn ""
9380   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
9381                          (match_operand:SI 1 "uint5_operand" "")
9382                          (match_operand:SI 2 "uint5_operand" ""))
9383         (match_operand:SI 3 "const_int_operand" ""))]
9384   "(INTVAL (operands[3]) & 0x10) != 0 &&
9385    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9386   "*
9388   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9389   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
9391   [(set_attr "type" "shift")
9392    (set_attr "length" "4")])
9394 (define_expand "insvdi"
9395   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
9396                          (match_operand:DI 1 "uint6_operand" "")
9397                          (match_operand:DI 2 "uint6_operand" ""))
9398         (match_operand:DI 3 "arith5_operand" ""))]
9399   "TARGET_64BIT"
9400   "
9402   unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
9403   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
9405   /* PA insertion insns don't support zero length bitfields or fields
9406      extending beyond the left or right-most bits.  Also, the predicate
9407      rejects lengths equal to a doubleword as they are better handled by
9408      the move patterns.  */
9409   if (len <= 0 || pos + len > 64)
9410     FAIL;
9412   /* From mips.md: insert_bit_field doesn't verify that our destination
9413      matches the predicate, so check it again here.  */
9414   if (!register_operand (operands[0], VOIDmode))
9415     FAIL;
9417   emit_insn (gen_insv_64 (operands[0], operands[1],
9418                           operands[2], operands[3]));
9419   DONE;
9422 (define_insn "insv_64"
9423   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
9424                          (match_operand:DI 1 "uint6_operand" "")
9425                          (match_operand:DI 2 "uint6_operand" ""))
9426         (match_operand:DI 3 "arith5_operand" "r,L"))]
9427   "TARGET_64BIT
9428    && UINTVAL (operands[1]) > 0
9429    && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
9430   "@
9431    depd %3,%2+%1-1,%1,%0
9432    depdi %3,%2+%1-1,%1,%0"
9433   [(set_attr "type" "shift,shift")
9434    (set_attr "length" "4,4")])
9436 ;; Optimize insertion of const_int values of type 1...1xxxx.
9437 (define_insn ""
9438   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9439                          (match_operand:DI 1 "uint6_operand" "")
9440                          (match_operand:DI 2 "uint6_operand" ""))
9441         (match_operand:DI 3 "const_int_operand" ""))]
9442   "(INTVAL (operands[3]) & 0x10) != 0
9443    && TARGET_64BIT
9444    && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
9445   "*
9447   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
9448   return \"depdi %3,%2+%1-1,%1,%0\";
9450   [(set_attr "type" "shift")
9451    (set_attr "length" "4")])
9453 (define_insn ""
9454   [(set (match_operand:DI 0 "register_operand" "=r")
9455         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
9456                    (const_int 32)))]
9457   "TARGET_64BIT"
9458   "depd,z %1,31,32,%0"
9459   [(set_attr "type" "shift")
9460    (set_attr "length" "4")])
9462 ;; This insn is used for some loop tests, typically loops reversed when
9463 ;; strength reduction is used.  It is actually created when the instruction
9464 ;; combination phase combines the special loop test.  Since this insn
9465 ;; is both a jump insn and has an output, it must deal with its own
9466 ;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
9467 ;; to not choose the register alternatives in the event a reload is needed.
9468 (define_insn "decrement_and_branch_until_zero"
9469   [(set (pc)
9470         (if_then_else
9471           (match_operator 2 "ordered_comparison_operator"
9472            [(plus:SI
9473               (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
9474               (match_operand:SI 1 "int5_operand" "L,L,L"))
9475             (const_int 0)])
9476           (label_ref (match_operand 3 "" ""))
9477           (pc)))
9478    (set (match_dup 0)
9479         (plus:SI (match_dup 0) (match_dup 1)))
9480    (clobber (match_scratch:SI 4 "=X,r,r"))]
9481   ""
9482   "* return pa_output_dbra (operands, insn, which_alternative); "
9483 ;; Do not expect to understand this the first time through.
9484 [(set_attr "type" "cbranch,multi,multi")
9485  (set (attr "length")
9486       (if_then_else (eq_attr "alternative" "0")
9487 ;; Loop counter in register case
9488 ;; Short branch has length of 4
9489 ;; Long branch has length of 8, 20, 24 or 28
9490         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9491                (const_int MAX_12BIT_OFFSET))
9492            (const_int 4)
9493            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9494                (const_int MAX_17BIT_OFFSET))
9495            (const_int 8)
9496            (match_test "TARGET_PORTABLE_RUNTIME")
9497            (const_int 24)
9498            (not (match_test "flag_pic"))
9499            (const_int 20)]
9500           (const_int 28))
9502 ;; Loop counter in FP reg case.
9503 ;; Extra goo to deal with additional reload insns.
9504         (if_then_else (eq_attr "alternative" "1")
9505           (if_then_else (lt (match_dup 3) (pc))
9506              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9507                       (const_int MAX_12BIT_OFFSET))
9508                     (const_int 24)
9509                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
9510                       (const_int MAX_17BIT_OFFSET))
9511                     (const_int 28)
9512                     (match_test "TARGET_PORTABLE_RUNTIME")
9513                     (const_int 44)
9514                     (not (match_test "flag_pic"))
9515                     (const_int 40)]
9516                   (const_int 48))
9517              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9518                       (const_int MAX_12BIT_OFFSET))
9519                     (const_int 24)
9520                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9521                       (const_int MAX_17BIT_OFFSET))
9522                     (const_int 28)
9523                     (match_test "TARGET_PORTABLE_RUNTIME")
9524                     (const_int 44)
9525                     (not (match_test "flag_pic"))
9526                     (const_int 40)]
9527                   (const_int 48)))
9529 ;; Loop counter in memory case.
9530 ;; Extra goo to deal with additional reload insns.
9531         (if_then_else (lt (match_dup 3) (pc))
9532              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9533                       (const_int MAX_12BIT_OFFSET))
9534                     (const_int 12)
9535                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9536                       (const_int MAX_17BIT_OFFSET))
9537                     (const_int 16)
9538                     (match_test "TARGET_PORTABLE_RUNTIME")
9539                     (const_int 32)
9540                     (not (match_test "flag_pic"))
9541                     (const_int 28)]
9542                   (const_int 36))
9543              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9544                       (const_int MAX_12BIT_OFFSET))
9545                     (const_int 12)
9546                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9547                       (const_int MAX_17BIT_OFFSET))
9548                     (const_int 16)
9549                     (match_test "TARGET_PORTABLE_RUNTIME")
9550                     (const_int 32)
9551                     (not (match_test "flag_pic"))
9552                     (const_int 28)]
9553                   (const_int 36))))))])
9555 (define_insn ""
9556   [(set (pc)
9557         (if_then_else
9558           (match_operator 2 "movb_comparison_operator"
9559            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9560           (label_ref (match_operand 3 "" ""))
9561           (pc)))
9562    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9563         (match_dup 1))]
9564   ""
9565 "* return pa_output_movb (operands, insn, which_alternative, 0); "
9566 ;; Do not expect to understand this the first time through.
9567 [(set_attr "type" "cbranch,multi,multi,multi")
9568  (set (attr "length")
9569       (if_then_else (eq_attr "alternative" "0")
9570 ;; Loop counter in register case
9571 ;; Short branch has length of 4
9572 ;; Long branch has length of 8, 20, 24 or 28
9573         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9574                (const_int MAX_12BIT_OFFSET))
9575            (const_int 4)
9576            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9577                (const_int MAX_17BIT_OFFSET))
9578            (const_int 8)
9579            (match_test "TARGET_PORTABLE_RUNTIME")
9580            (const_int 24)
9581            (not (match_test "flag_pic"))
9582            (const_int 20)]
9583           (const_int 28))
9585 ;; Loop counter in FP reg case.
9586 ;; Extra goo to deal with additional reload insns.
9587         (if_then_else (eq_attr "alternative" "1")
9588           (if_then_else (lt (match_dup 3) (pc))
9589              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9590                       (const_int MAX_12BIT_OFFSET))
9591                     (const_int 12)
9592                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9593                       (const_int MAX_17BIT_OFFSET))
9594                     (const_int 16)
9595                     (match_test "TARGET_PORTABLE_RUNTIME")
9596                     (const_int 32)
9597                     (not (match_test "flag_pic"))
9598                     (const_int 28)]
9599                   (const_int 36))
9600              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9601                       (const_int MAX_12BIT_OFFSET))
9602                     (const_int 12)
9603                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9604                       (const_int MAX_17BIT_OFFSET))
9605                     (const_int 16)
9606                     (match_test "TARGET_PORTABLE_RUNTIME")
9607                     (const_int 32)
9608                     (not (match_test "flag_pic"))
9609                     (const_int 28)]
9610                   (const_int 36)))
9612 ;; Loop counter in memory or sar case.
9613 ;; Extra goo to deal with additional reload insns.
9614         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9615                    (const_int MAX_12BIT_OFFSET))
9616                 (const_int 8)
9617                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9618                   (const_int MAX_17BIT_OFFSET))
9619                 (const_int 12)
9620                 (match_test "TARGET_PORTABLE_RUNTIME")
9621                 (const_int 28)
9622                 (not (match_test "flag_pic"))
9623                 (const_int 24)]
9624               (const_int 32)))))])
9626 ;; Handle negated branch.
9627 (define_insn ""
9628   [(set (pc)
9629         (if_then_else
9630           (match_operator 2 "movb_comparison_operator"
9631            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
9632           (pc)
9633           (label_ref (match_operand 3 "" ""))))
9634    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
9635         (match_dup 1))]
9636   ""
9637 "* return pa_output_movb (operands, insn, which_alternative, 1); "
9638 ;; Do not expect to understand this the first time through.
9639 [(set_attr "type" "cbranch,multi,multi,multi")
9640  (set (attr "length")
9641       (if_then_else (eq_attr "alternative" "0")
9642 ;; Loop counter in register case
9643 ;; Short branch has length of 4
9644 ;; Long branch has length of 8
9645         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9646                (const_int MAX_12BIT_OFFSET))
9647            (const_int 4)
9648            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9649                (const_int MAX_17BIT_OFFSET))
9650            (const_int 8)
9651            (match_test "TARGET_PORTABLE_RUNTIME")
9652            (const_int 24)
9653            (not (match_test "flag_pic"))
9654            (const_int 20)]
9655           (const_int 28))
9657 ;; Loop counter in FP reg case.
9658 ;; Extra goo to deal with additional reload insns.
9659         (if_then_else (eq_attr "alternative" "1")
9660           (if_then_else (lt (match_dup 3) (pc))
9661              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9662                       (const_int MAX_12BIT_OFFSET))
9663                     (const_int 12)
9664                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
9665                       (const_int MAX_17BIT_OFFSET))
9666                     (const_int 16)
9667                     (match_test "TARGET_PORTABLE_RUNTIME")
9668                     (const_int 32)
9669                     (not (match_test "flag_pic"))
9670                     (const_int 28)]
9671                   (const_int 36))
9672              (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9673                       (const_int MAX_12BIT_OFFSET))
9674                     (const_int 12)
9675                     (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9676                       (const_int MAX_17BIT_OFFSET))
9677                     (const_int 16)
9678                     (match_test "TARGET_PORTABLE_RUNTIME")
9679                     (const_int 32)
9680                     (not (match_test "flag_pic"))
9681                     (const_int 28)]
9682                   (const_int 36)))
9684 ;; Loop counter in memory or SAR case.
9685 ;; Extra goo to deal with additional reload insns.
9686         (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9687                    (const_int MAX_12BIT_OFFSET))
9688                 (const_int 8)
9689                 (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9690                   (const_int MAX_17BIT_OFFSET))
9691                 (const_int 12)
9692                 (match_test "TARGET_PORTABLE_RUNTIME")
9693                 (const_int 28)
9694                 (not (match_test "flag_pic"))
9695                 (const_int 24)]
9696               (const_int 32)))))])
9698 (define_insn ""
9699   [(set (pc) (label_ref (match_operand 3 "" "" )))
9700    (set (match_operand:SI 0 "ireg_operand" "=r")
9701         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
9702                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
9703   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
9704   "*
9706   return pa_output_parallel_addb (operands, insn);
9708 [(set_attr "type" "parallel_branch")
9709  (set (attr "length")
9710     (cond [(lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9711                (const_int MAX_12BIT_OFFSET))
9712            (const_int 4)
9713            (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
9714                (const_int MAX_17BIT_OFFSET))
9715            (const_int 8)
9716            (match_test "TARGET_PORTABLE_RUNTIME")
9717            (const_int 24)
9718            (not (match_test "flag_pic"))
9719            (const_int 20)]
9720           (const_int 28)))])
9722 (define_insn ""
9723   [(set (pc) (label_ref (match_operand 2 "" "" )))
9724    (set (match_operand:SF 0 "ireg_operand" "=r")
9725         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
9726   "reload_completed"
9727   "*
9729   return pa_output_parallel_movb (operands, insn);
9731 [(set_attr "type" "parallel_branch")
9732  (set (attr "length")
9733     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9734                (const_int MAX_12BIT_OFFSET))
9735            (const_int 4)
9736            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9737                (const_int MAX_17BIT_OFFSET))
9738            (const_int 8)
9739            (match_test "TARGET_PORTABLE_RUNTIME")
9740            (const_int 24)
9741            (not (match_test "flag_pic"))
9742            (const_int 20)]
9743           (const_int 28)))])
9745 (define_insn ""
9746   [(set (pc) (label_ref (match_operand 2 "" "" )))
9747    (set (match_operand:SI 0 "ireg_operand" "=r")
9748         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
9749   "reload_completed"
9750   "*
9752   return pa_output_parallel_movb (operands, insn);
9754 [(set_attr "type" "parallel_branch")
9755  (set (attr "length")
9756     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9757                (const_int MAX_12BIT_OFFSET))
9758            (const_int 4)
9759            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9760                (const_int MAX_17BIT_OFFSET))
9761            (const_int 8)
9762            (match_test "TARGET_PORTABLE_RUNTIME")
9763            (const_int 24)
9764            (not (match_test "flag_pic"))
9765            (const_int 20)]
9766           (const_int 28)))])
9768 (define_insn ""
9769   [(set (pc) (label_ref (match_operand 2 "" "" )))
9770    (set (match_operand:HI 0 "ireg_operand" "=r")
9771         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
9772   "reload_completed"
9773   "*
9775   return pa_output_parallel_movb (operands, insn);
9777 [(set_attr "type" "parallel_branch")
9778  (set (attr "length")
9779     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9780                (const_int MAX_12BIT_OFFSET))
9781            (const_int 4)
9782            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9783                (const_int MAX_17BIT_OFFSET))
9784            (const_int 8)
9785            (match_test "TARGET_PORTABLE_RUNTIME")
9786            (const_int 24)
9787            (not (match_test "flag_pic"))
9788            (const_int 20)]
9789           (const_int 28)))])
9791 (define_insn ""
9792   [(set (pc) (label_ref (match_operand 2 "" "" )))
9793    (set (match_operand:QI 0 "ireg_operand" "=r")
9794         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
9795   "reload_completed"
9796   "*
9798   return pa_output_parallel_movb (operands, insn);
9800 [(set_attr "type" "parallel_branch")
9801  (set (attr "length")
9802     (cond [(lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9803                (const_int MAX_12BIT_OFFSET))
9804            (const_int 4)
9805            (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
9806                (const_int MAX_17BIT_OFFSET))
9807            (const_int 8)
9808            (match_test "TARGET_PORTABLE_RUNTIME")
9809            (const_int 24)
9810            (not (match_test "flag_pic"))
9811            (const_int 20)]
9812           (const_int 28)))])
9814 (define_insn ""
9815   [(set (match_operand 0 "register_operand" "=f")
9816         (mult (match_operand 1 "register_operand" "f")
9817               (match_operand 2 "register_operand" "f")))
9818    (set (match_operand 3 "register_operand" "+f")
9819         (plus (match_operand 4 "register_operand" "f")
9820               (match_operand 5 "register_operand" "f")))]
9821   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9822    && reload_completed && pa_fmpyaddoperands (operands)"
9823   "*
9825   if (GET_MODE (operands[0]) == DFmode)
9826     {
9827       if (rtx_equal_p (operands[3], operands[5]))
9828         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9829       else
9830         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9831     }
9832   else
9833     {
9834       if (rtx_equal_p (operands[3], operands[5]))
9835         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9836       else
9837         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9838     }
9840   [(set_attr "type" "fpalu")
9841    (set_attr "length" "4")])
9843 (define_insn ""
9844   [(set (match_operand 3 "register_operand" "+f")
9845         (plus (match_operand 4 "register_operand" "f")
9846               (match_operand 5 "register_operand" "f")))
9847    (set (match_operand 0 "register_operand" "=f")
9848         (mult (match_operand 1 "register_operand" "f")
9849               (match_operand 2 "register_operand" "f")))]
9850   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9851    && reload_completed && pa_fmpyaddoperands (operands)"
9852   "*
9854   if (GET_MODE (operands[0]) == DFmode)
9855     {
9856       if (rtx_equal_p (operands[3], operands[5]))
9857         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
9858       else
9859         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
9860     }
9861   else
9862     {
9863       if (rtx_equal_p (operands[3], operands[5]))
9864         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
9865       else
9866         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
9867     }
9869   [(set_attr "type" "fpalu")
9870    (set_attr "length" "4")])
9872 (define_insn ""
9873   [(set (match_operand 0 "register_operand" "=f")
9874         (mult (match_operand 1 "register_operand" "f")
9875               (match_operand 2 "register_operand" "f")))
9876    (set (match_operand 3 "register_operand" "+f")
9877         (minus (match_operand 4 "register_operand" "f")
9878                (match_operand 5 "register_operand" "f")))]
9879   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9880    && reload_completed && pa_fmpysuboperands (operands)"
9881   "*
9883   if (GET_MODE (operands[0]) == DFmode)
9884     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9885   else
9886     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9888   [(set_attr "type" "fpalu")
9889    (set_attr "length" "4")])
9891 (define_insn ""
9892   [(set (match_operand 3 "register_operand" "+f")
9893         (minus (match_operand 4 "register_operand" "f")
9894                (match_operand 5 "register_operand" "f")))
9895    (set (match_operand 0 "register_operand" "=f")
9896         (mult (match_operand 1 "register_operand" "f")
9897               (match_operand 2 "register_operand" "f")))]
9898   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
9899    && reload_completed && pa_fmpysuboperands (operands)"
9900   "*
9902   if (GET_MODE (operands[0]) == DFmode)
9903     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
9904   else
9905     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
9907   [(set_attr "type" "fpalu")
9908    (set_attr "length" "4")])
9910 ;; The following two patterns are used by the trampoline code for nested
9911 ;; functions.  They flush the I and D cache lines from the start address
9912 ;; (operand0) to the end address (operand1).  No lines are flushed if the
9913 ;; end address is less than the start address (unsigned).
9915 ;; Because the range of memory flushed is variable and the size of a MEM
9916 ;; can only be a CONST_INT, the patterns specify that they perform an
9917 ;; unspecified volatile operation on all memory.
9919 ;; The address range for an icache flush must lie within a single
9920 ;; space on targets with non-equivalent space registers.
9922 ;; Operand 0 contains the start address.
9923 ;; Operand 1 contains the end address.
9924 ;; Operand 2 contains the line length to use.
9925 (define_insn "dcacheflush<P:mode>"
9926   [(const_int 1)
9927    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
9928    (use (match_operand 0 "pmode_register_operand" "r"))
9929    (use (match_operand 1 "pmode_register_operand" "r"))
9930    (use (match_operand 2 "pmode_register_operand" "r"))
9931    (clobber (match_scratch:P 3 "=&0"))]
9932   ""
9933   "cmpb,<dwc><<=,n %3,%1,.\;fdc,m %2(%3)\;sync"
9934   [(set_attr "type" "multi")
9935    (set_attr "length" "12")])
9937 (define_insn "icacheflush<P:mode>"
9938   [(const_int 2)
9939    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
9940    (use (match_operand 0 "pmode_register_operand" "r"))
9941    (use (match_operand 1 "pmode_register_operand" "r"))
9942    (use (match_operand 2 "pmode_register_operand" "r"))
9943    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
9944    (clobber (match_operand 4 "pmode_register_operand" "=&r"))
9945    (clobber (match_scratch:P 5 "=&0"))]
9946   ""
9947   "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"
9948   [(set_attr "type" "multi")
9949    (set_attr "length" "52")])
9951 (define_expand "clear_cache"
9952   [(match_operand 0 "pmode_register_operand")
9953    (match_operand 1 "pmode_register_operand")]
9954   ""
9956   rtx line_length = gen_reg_rtx (Pmode);
9958   emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
9959   if (TARGET_64BIT)
9960     emit_insn (gen_icacheflushdi (operands[0], operands[1], line_length,
9961                                   gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));
9962   else
9963     emit_insn (gen_icacheflushsi (operands[0], operands[1], line_length,
9964                                   gen_reg_rtx (Pmode), gen_reg_rtx (Pmode)));
9965   DONE;
9968 ;; An out-of-line prologue.
9969 (define_insn "outline_prologue_call"
9970   [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
9971    (clobber (reg:SI 31))
9972    (clobber (reg:SI 22))
9973    (clobber (reg:SI 21))
9974    (clobber (reg:SI 20))
9975    (clobber (reg:SI 19))
9976    (clobber (reg:SI 1))]
9977   ""
9978   "*
9981   /* We need two different versions depending on whether or not we
9982      need a frame pointer.   Also note that we return to the instruction
9983      immediately after the branch rather than two instructions after the
9984      break as normally is the case.  */
9985   if (frame_pointer_needed)
9986     {
9987       /* Must import the magic millicode routine(s).  */
9988       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9990       if (TARGET_PORTABLE_RUNTIME)
9991         {
9992           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9993           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9994                            NULL);
9995         }
9996       else
9997         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9998     }
9999   else
10000     {
10001       /* Must import the magic millicode routine(s).  */
10002       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
10004       if (TARGET_PORTABLE_RUNTIME)
10005         {
10006           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
10007           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
10008         }
10009       else
10010         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
10011     }
10012   return \"\";
10014   [(set_attr "type" "multi")
10015    (set_attr "length" "8")])
10017 ;; An out-of-line epilogue.
10018 (define_insn "outline_epilogue_call"
10019   [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
10020    (use (reg:SI 29))
10021    (use (reg:SI 28))
10022    (clobber (reg:SI 31))
10023    (clobber (reg:SI 22))
10024    (clobber (reg:SI 21))
10025    (clobber (reg:SI 20))
10026    (clobber (reg:SI 19))
10027    (clobber (reg:SI 2))
10028    (clobber (reg:SI 1))]
10029   ""
10030   "*
10033   /* We need two different versions depending on whether or not we
10034      need a frame pointer.   Also note that we return to the instruction
10035      immediately after the branch rather than two instructions after the
10036      break as normally is the case.  */
10037   if (frame_pointer_needed)
10038     {
10039       /* Must import the magic millicode routine.  */
10040       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
10042       /* The out-of-line prologue will make sure we return to the right
10043          instruction.  */
10044       if (TARGET_PORTABLE_RUNTIME)
10045         {
10046           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
10047           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
10048                            NULL);
10049         }
10050       else
10051         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
10052     }
10053   else
10054     {
10055       /* Must import the magic millicode routine.  */
10056       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
10058       /* The out-of-line prologue will make sure we return to the right
10059          instruction.  */
10060       if (TARGET_PORTABLE_RUNTIME)
10061         {
10062           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
10063           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
10064         }
10065       else
10066         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
10067     }
10068   return \"\";
10070   [(set_attr "type" "multi")
10071    (set_attr "length" "8")])
10073 ;; Given a function pointer, canonicalize it so it can be 
10074 ;; reliably compared to another function pointer.  */
10075 (define_expand "canonicalize_funcptr_for_compare"
10076   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
10077    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10078               (clobber (match_dup 2))
10079               (clobber (reg:SI 26))
10080               (clobber (reg:SI 22))
10081               (clobber (reg:SI 31))])
10082    (set (match_operand:SI 0 "register_operand" "")
10083         (reg:SI 29))]
10084   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
10085   "
10087   if (TARGET_ELF32)
10088     {
10089       rtx canonicalize_funcptr_for_compare_libfunc
10090         = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
10092       emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
10093                                operands[0], LCT_NORMAL, Pmode,
10094                                operands[1], Pmode);
10095       DONE;
10096     }
10098   operands[2] = gen_reg_rtx (SImode);
10099   if (GET_CODE (operands[1]) != REG)
10100     {
10101       rtx tmp = gen_reg_rtx (Pmode);
10102       emit_move_insn (tmp, operands[1]);
10103       operands[1] = tmp;
10104     }
10107 (define_insn "*$$sh_func_adrs"
10108   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
10109    (clobber (match_operand:SI 0 "register_operand" "=a"))
10110    (clobber (reg:SI 26))
10111    (clobber (reg:SI 22))
10112    (clobber (reg:SI 31))]
10113   "!TARGET_64BIT"
10114   "*
10116   int length = get_attr_length (insn);
10117   rtx xoperands[2];
10119   xoperands[0] = GEN_INT (length - 8);
10120   xoperands[1] = GEN_INT (length - 16);
10122   /* Must import the magic millicode routine.  */
10123   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
10125   /* This is absolutely amazing.
10127      First, copy our input parameter into %r29 just in case we don't
10128      need to call $$sh_func_adrs.  */
10129   output_asm_insn (\"copy %%r26,%%r29\", NULL);
10130   output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
10132   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
10133      we use %r26 unchanged.  */
10134   output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
10135   output_asm_insn (\"ldi 4096,%%r31\", NULL);
10137   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
10138      4096, then again we use %r26 unchanged.  */
10139   output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
10141   /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
10142   return pa_output_millicode_call (insn,
10143                                    gen_rtx_SYMBOL_REF (SImode,
10144                                                        \"$$sh_func_adrs\"));
10146   [(set_attr "type" "sh_func_adrs")
10147    (set (attr "length")
10148         (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
10149               (plus (symbol_ref "pa_attr_length_millicode_call (insn)")
10150                     (const_int 20))))])
10152 ;; On the PA, the PIC register is call clobbered, so it must
10153 ;; be saved & restored around calls by the caller.  If the call
10154 ;; doesn't return normally (nonlocal goto, or an exception is
10155 ;; thrown), then the code at the exception handler label must
10156 ;; restore the PIC register.
10157 (define_expand "exception_receiver"
10158   [(const_int 4)]
10159   "flag_pic"
10160   "
10162   /* On the 64-bit port, we need a blockage because there is
10163      confusion regarding the dependence of the restore on the
10164      frame pointer.  As a result, the frame pointer and pic
10165      register restores sometimes are interchanged erroneously.  */
10166   if (TARGET_64BIT)
10167     emit_insn (gen_blockage ());
10168   /* Restore the PIC register using hppa_pic_save_rtx ().  The
10169      PIC register is not saved in the frame in 64-bit ABI.  */
10170   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10171   emit_insn (gen_blockage ());
10172   DONE;
10175 (define_expand "builtin_setjmp_receiver"
10176   [(label_ref (match_operand 0 "" ""))]
10177   "flag_pic"
10178   "
10180   if (TARGET_64BIT)
10181     emit_insn (gen_blockage ());
10182   /* Restore the PIC register.  Hopefully, this will always be from
10183      a stack slot.  The only registers that are valid after a
10184      builtin_longjmp are the stack and frame pointers.  */
10185   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
10186   emit_insn (gen_blockage ());
10187   DONE;
10190 ;; Allocate new stack space and update the saved stack pointer in the
10191 ;; frame marker.  The HP C compilers also copy additional words in the
10192 ;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
10193 ;; The 32-bit compiler copies the word at -16 (Static Link).  We
10194 ;; currently don't copy these values.
10196 ;; Since the copy of the frame marker can't be done atomically, I
10197 ;; suspect that using it for unwind purposes may be somewhat unreliable.
10198 ;; The HP compilers appear to raise the stack and copy the frame
10199 ;; marker in a strict instruction sequence.  This suggests that the
10200 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
10201 ;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
10202 ;; as GAS doesn't support it, or try to keep the instructions emitted
10203 ;; here in strict sequence.
10204 (define_expand "allocate_stack"
10205   [(match_operand 0 "" "")
10206    (match_operand 1 "" "")]
10207   ""
10208   "
10210   rtx addr;
10212   /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
10213      in operand 0 before adjusting the stack.  */
10214   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10215   anti_adjust_stack (operands[1]);
10216   if (TARGET_HPUX_UNWIND_LIBRARY)
10217     {
10218       addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
10219                            GEN_INT (TARGET_64BIT ? -8 : -4));
10220       emit_move_insn (gen_rtx_MEM (word_mode, addr), hard_frame_pointer_rtx);
10221     }
10222   if (!TARGET_64BIT && flag_pic)
10223     {
10224       rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
10225       emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
10226     }
10227   DONE;
10230 (define_expand "prefetch"
10231   [(match_operand 0 "address_operand" "")
10232    (match_operand 1 "const_int_operand" "")
10233    (match_operand 2 "const_int_operand" "")]
10234   "TARGET_PA_20"
10236   operands[0] = copy_addr_to_reg (operands[0]);
10237   emit_insn (gen_prefetch_20 (operands[0], operands[1], operands[2]));
10238   DONE;
10241 (define_insn "prefetch_20"
10242   [(prefetch (match_operand 0 "pmode_register_operand" "r")
10243              (match_operand:SI 1 "const_int_operand" "n")
10244              (match_operand:SI 2 "const_int_operand" "n"))]
10245   "TARGET_PA_20"
10247   /* The SL cache-control completer indicates good spatial locality but
10248      poor temporal locality.  The ldw instruction with a target of general
10249      register 0 prefetches a cache line for a read.  The ldd instruction
10250      prefetches a cache line for a write.  */
10251   static const char * const instr[2][2] = {
10252     {
10253       "ldw,sl 0(%0),%%r0",
10254       "ldd,sl 0(%0),%%r0"
10255     },
10256     {
10257       "ldw 0(%0),%%r0",
10258       "ldd 0(%0),%%r0"
10259     }
10260   };
10261   int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
10262   int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
10264   return instr [locality][read_or_write];
10266   [(set_attr "type" "load")
10267    (set_attr "length" "4")])
10269 ;; TLS Support
10270 (define_insn "tgd_load"
10271  [(set (match_operand:SI 0 "register_operand" "=r")
10272        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD))
10273   (clobber (reg:SI R1_REGNUM))
10274   (use (reg:SI R27_REGNUM))]
10275   "!TARGET_64BIT"
10276   "*
10278   return \"addil LR'%1-$tls_gdidx$,%%r27\;ldo RR'%1-$tls_gdidx$(%%r1),%0\";
10280   [(set_attr "type" "multi")
10281    (set_attr "length" "8")])
10283 (define_expand "tgd_load_pic"
10284  [(set (match_operand 0 "register_operand")
10285        (unspec [(match_operand 1 "tgd_symbolic_operand")] UNSPEC_TLSGD_PIC))
10286   (clobber (reg R1_REGNUM))]
10287   ""
10289   if (TARGET_64BIT)
10290     emit_insn (gen_tgd_load_picdi (operands[0], operands[1]));
10291   else
10292     emit_insn (gen_tgd_load_picsi (operands[0], operands[1]));
10293   DONE;
10296 (define_insn "tgd_load_picsi"
10297  [(set (match_operand:SI 0 "register_operand" "=r")
10298        (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10299   (clobber (reg:SI R1_REGNUM))
10300   (use (reg:SI R19_REGNUM))]
10301   "!TARGET_64BIT"
10302   "*
10304   return \"addil LT'%1-$tls_gdidx$,%%r19\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10306   [(set_attr "type" "multi")
10307    (set_attr "length" "8")])
10309 (define_insn "tgd_load_picdi"
10310  [(set (match_operand:DI 0 "register_operand" "=r")
10311        (unspec:DI [(match_operand 1 "tgd_symbolic_operand" "")] UNSPEC_TLSGD_PIC))
10312   (clobber (reg:DI R1_REGNUM))
10313   (use (reg:DI R27_REGNUM))]
10314   "TARGET_64BIT"
10315   "*
10317   return \"addil LT'%1-$tls_gdidx$,%%r27\;ldo RT'%1-$tls_gdidx$(%%r1),%0\";
10319   [(set_attr "type" "multi")
10320    (set_attr "length" "8")])
10322 (define_insn "tld_load"
10323  [(set (match_operand:SI 0 "register_operand" "=r")
10324        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM))
10325   (clobber (reg:SI R1_REGNUM))
10326   (use (reg:SI R27_REGNUM))]
10327   "!TARGET_64BIT"
10328   "*
10330   return \"addil LR'%1-$tls_ldidx$,%%r27\;ldo RR'%1-$tls_ldidx$(%%r1),%0\";
10332   [(set_attr "type" "multi")
10333    (set_attr "length" "8")])
10335 (define_expand "tld_load_pic"
10336  [(set (match_operand 0 "register_operand")
10337        (unspec [(match_operand 1 "tld_symbolic_operand")] UNSPEC_TLSLDM_PIC))
10338   (clobber (reg R1_REGNUM))]
10339   ""
10341   if (TARGET_64BIT)
10342     emit_insn (gen_tld_load_picdi (operands[0], operands[1]));
10343   else
10344     emit_insn (gen_tld_load_picsi (operands[0], operands[1]));
10345   DONE;
10348 (define_insn "tld_load_picsi"
10349  [(set (match_operand:SI 0 "register_operand" "=r")
10350        (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10351   (clobber (reg:SI R1_REGNUM))
10352   (use (reg:SI R19_REGNUM))]
10353   "!TARGET_64BIT"
10354   "*
10356   return \"addil LT'%1-$tls_ldidx$,%%r19\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10358   [(set_attr "type" "multi")
10359    (set_attr "length" "8")])
10361 (define_insn "tld_load_picdi"
10362  [(set (match_operand:DI 0 "register_operand" "=r")
10363        (unspec:DI [(match_operand 1 "tld_symbolic_operand" "")] UNSPEC_TLSLDM_PIC))
10364   (clobber (reg:DI R1_REGNUM))
10365   (use (reg:DI R27_REGNUM))]
10366   "TARGET_64BIT"
10367   "*
10369   return \"addil LT'%1-$tls_ldidx$,%%r27\;ldo RT'%1-$tls_ldidx$(%%r1),%0\";
10371   [(set_attr "type" "multi")
10372    (set_attr "length" "8")])
10374 (define_expand "tld_offset_load"
10375   [(set (match_operand 0 "register_operand")
10376         (plus (unspec [(match_operand 1 "tld_symbolic_operand")] 
10377                             UNSPEC_TLSLDO)
10378                  (match_operand 2 "register_operand")))
10379    (clobber (reg R1_REGNUM))]
10380   ""
10382   if (TARGET_64BIT)
10383     emit_insn (gen_tld_offset_loaddi (operands[0], operands[1], operands[2]));
10384   else
10385     emit_insn (gen_tld_offset_loadsi (operands[0], operands[1], operands[2]));
10386   DONE;
10389 (define_insn "tld_offset_load<P:mode>"
10390   [(set (match_operand:P 0 "register_operand" "=r")
10391         (plus:P (unspec:P [(match_operand 1 "tld_symbolic_operand" "")] 
10392                             UNSPEC_TLSLDO)
10393                 (match_operand:P 2 "register_operand" "r")))
10394    (clobber (reg:P R1_REGNUM))]
10395   ""
10396   "*
10398   return \"addil LR'%1-$tls_dtpoff$,%2\;ldo RR'%1-$tls_dtpoff$(%%r1),%0\"; 
10400   [(set_attr "type" "multi")
10401    (set_attr "length" "8")])
10403 (define_expand "tp_load"
10404   [(set (match_operand 0 "register_operand")
10405         (unspec [(const_int 0)] UNSPEC_TP))]
10406   ""
10408   if (TARGET_64BIT)
10409     emit_insn (gen_tp_loaddi (operands[0]));
10410   else
10411     emit_insn (gen_tp_loadsi (operands[0]));
10412   DONE;
10415 (define_insn "tp_load<P:mode>"
10416   [(set (match_operand:P 0 "register_operand" "=r")
10417         (unspec:P [(const_int 0)] UNSPEC_TP))]
10418   ""
10419   "mfctl %%cr27,%0"
10420   [(set_attr "type" "multi")
10421    (set_attr "length" "4")])
10423 (define_insn "tie_load"
10424   [(set (match_operand:SI 0 "register_operand" "=r")
10425         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE))
10426    (clobber (reg:SI R1_REGNUM))
10427    (use (reg:SI R27_REGNUM))]
10428   "!TARGET_64BIT"
10429   "*
10431   return \"addil LR'%1-$tls_ieoff$,%%r27\;ldw RR'%1-$tls_ieoff$(%%r1),%0\";
10433   [(set_attr "type" "multi")
10434    (set_attr "length" "8")])
10436 (define_expand "tie_load_pic"
10437   [(set (match_operand 0 "register_operand")
10438         (unspec [(match_operand 1 "tie_symbolic_operand")] UNSPEC_TLSIE_PIC))
10439    (clobber (reg R1_REGNUM))]
10440   ""
10442   if (TARGET_64BIT)
10443     emit_insn (gen_tie_load_picdi (operands[0], operands[1]));
10444   else
10445     emit_insn (gen_tie_load_picsi (operands[0], operands[1]));
10446   DONE;
10449 (define_insn "tie_load_picsi"
10450   [(set (match_operand:SI 0 "register_operand" "=r")
10451         (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10452    (clobber (reg:SI R1_REGNUM))
10453    (use (reg:SI R19_REGNUM))]
10454   "!TARGET_64BIT"
10455   "*
10457   return \"addil LT'%1-$tls_ieoff$,%%r19\;ldw RT'%1-$tls_ieoff$(%%r1),%0\";
10459   [(set_attr "type" "multi")
10460    (set_attr "length" "8")])
10462 (define_insn "tie_load_picdi"
10463   [(set (match_operand:DI 0 "register_operand" "=r")
10464         (unspec:DI [(match_operand 1 "tie_symbolic_operand" "")] UNSPEC_TLSIE_PIC))
10465    (clobber (reg:DI R1_REGNUM))
10466    (use (reg:DI R27_REGNUM))]
10467   "!TARGET_64BIT"
10468   "*
10470   return \"addil LT'%1-$tls_ieoff$,%%r27\;ldd RT'%1-$tls_ieoff$(%%r1),%0\";
10472   [(set_attr "type" "multi")
10473    (set_attr "length" "8")])
10475 (define_expand "tle_load"
10476   [(set (match_operand 0 "register_operand")
10477         (plus (unspec [(match_operand 1 "tle_symbolic_operand")] 
10478                             UNSPEC_TLSLE)
10479                 (match_operand 2 "register_operand")))
10480    (clobber (reg R1_REGNUM))]
10481   ""
10483   if (TARGET_64BIT)
10484     emit_insn (gen_tle_loaddi (operands[0], operands[1], operands[2]));
10485   else
10486     emit_insn (gen_tle_loadsi (operands[0], operands[1], operands[2]));
10487   DONE;
10490 (define_insn "tle_load<P:mode>"
10491   [(set (match_operand:P 0 "register_operand" "=r")
10492         (plus:P (unspec:P [(match_operand 1 "tle_symbolic_operand" "")] 
10493                             UNSPEC_TLSLE)
10494                  (match_operand:P 2 "register_operand" "r")))
10495    (clobber (reg:P R1_REGNUM))]
10496   ""
10497   "addil LR'%1-$tls_leoff$,%2\;ldo RR'%1-$tls_leoff$(%%r1),%0"
10498   [(set_attr "type" "multi")
10499    (set_attr "length" "8")])
10501 ;; Atomic instructions
10503 ;; All memory loads and stores access storage atomically except
10504 ;; for one exception.  The STORE BYTES, STORE DOUBLE BYTES, and
10505 ;; doubleword loads and stores are not guaranteed to be atomic
10506 ;; when referencing the I/O address space.
10508 ;; Atomic and sync libcalls use different lock sets.  Great care is
10509 ;; needed if both are used in a single application.
10511 ;; Atomic load and store libcalls are enabled by the -matomic-libcalls
10512 ;; option.  This option is not enabled by default as the generated
10513 ;; libcalls depend on libatomic which is not built until the end of
10514 ;; the gcc build.  For loads, we only need an atomic libcall for DImode.
10515 ;; Sync libcalls are not generated when atomic libcalls are enabled.
10517 ;; Sync libcalls are enabled by default when supported.  They can be
10518 ;; disabled by the -fno-sync-libcalls option.  Sync libcalls always
10519 ;; use a single memory store in their implementation, even for DImode.
10520 ;; DImode stores are done using either std or fstd.  Thus, we only
10521 ;; need a sync load libcall for DImode when we don't have an atomic
10522 ;; processor load available for the mode (TARGET_SOFT_FLOAT).
10524 ;; Implement atomic QImode store using exchange.
10526 (define_expand "atomic_storeqi"
10527   [(match_operand:QI 0 "memory_operand")                ;; memory
10528    (match_operand:QI 1 "register_operand")              ;; val out
10529    (match_operand:SI 2 "const_int_operand")]            ;; model
10530   ""
10532   rtx addr, libfunc;
10534   if (TARGET_SYNC_LIBCALLS)
10535     {
10536       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10537       libfunc = optab_libfunc (sync_lock_test_and_set_optab, QImode);
10538       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10539                          operands[1], QImode);
10540       DONE;
10541     }
10543   if (TARGET_ATOMIC_LIBCALLS)
10544     {
10545       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10546       libfunc = init_one_libfunc ("__atomic_exchange_1");
10547       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10548                          operands[1], QImode);
10549       DONE;
10550     }
10552   FAIL;
10555 ;; Implement atomic HImode store using exchange.
10557 (define_expand "atomic_storehi"
10558   [(match_operand:HI 0 "memory_operand")                ;; memory
10559    (match_operand:HI 1 "register_operand")              ;; val out
10560    (match_operand:SI 2 "const_int_operand")]            ;; model
10561   ""
10563   rtx addr, libfunc;
10565   if (TARGET_SYNC_LIBCALLS)
10566     {
10567       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10568       libfunc = optab_libfunc (sync_lock_test_and_set_optab, HImode);
10569       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10570                          operands[1], HImode);
10571       DONE;
10572     }
10574   if (TARGET_ATOMIC_LIBCALLS)
10575     {
10576       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10577       libfunc = init_one_libfunc ("__atomic_exchange_2");
10578       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10579                          operands[1], HImode);
10580       DONE;
10581     }
10583   FAIL;
10586 ;; Implement atomic SImode store using exchange.
10588 (define_expand "atomic_storesi"
10589   [(match_operand:SI 0 "memory_operand")                ;; memory
10590    (match_operand:SI 1 "register_operand")              ;; val out
10591    (match_operand:SI 2 "const_int_operand")]            ;; model
10592   ""
10594   rtx addr, libfunc;
10596   if (TARGET_SYNC_LIBCALLS)
10597     {
10598       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10599       libfunc = optab_libfunc (sync_lock_test_and_set_optab, SImode);
10600       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10601                          operands[1], SImode);
10602       DONE;
10603     }
10605   if (TARGET_ATOMIC_LIBCALLS)
10606     {
10607       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10608       libfunc = init_one_libfunc ("__atomic_exchange_4");
10609       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10610                          operands[1], SImode);
10611       DONE;
10612     }
10614   FAIL;
10617 ;; Implement atomic DImode load.
10619 ;; We need an atomic or sync libcall whenever the processor load or
10620 ;; store used for DImode is not atomic.  The 32-bit libatomic
10621 ;; implementation uses a pair of stw instructions.  They are not
10622 ;; atomic, so we need to call __atomic_load_8.  The linux libgcc
10623 ;; sync implementation uses a std or fstd instruction.  They are
10624 ;; atomic, so we only need to call __sync_load_8 when the load
10625 ;; operation would not be atomic (e.g., 32-bit TARGET_SOFT_FLOAT).
10627 (define_expand "atomic_loaddi"
10628   [(match_operand:DI 0 "register_operand")              ;; val out
10629    (match_operand:DI 1 "memory_operand")                ;; memory
10630    (match_operand:SI 2 "const_int_operand")]            ;; model
10631   ""
10633   enum memmodel model;
10634   rtx addr, libfunc;
10636   if (TARGET_64BIT)
10637     FAIL;
10639   if (TARGET_SYNC_LIBCALLS && MAX_SYNC_LIBFUNC_SIZE >= 8 && TARGET_SOFT_FLOAT)
10640     {
10641       addr = convert_memory_address (Pmode, XEXP (operands[1], 0));
10642       libfunc = init_one_libfunc ("__sync_load_8");
10643       emit_library_call_value (libfunc, operands[0], LCT_NORMAL, DImode,
10644                                addr, Pmode);
10645       DONE;
10646     }
10648   if (TARGET_ATOMIC_LIBCALLS && TARGET_SOFT_FLOAT)
10649     {
10650       addr = convert_memory_address (Pmode, XEXP (operands[1], 0));
10651       libfunc = init_one_libfunc ("__atomic_load_8");
10652       emit_library_call_value (libfunc, operands[0], LCT_NORMAL, DImode,
10653                                addr, Pmode);
10654       DONE;
10655     }
10657   if (TARGET_SOFT_FLOAT)
10658     FAIL;
10660   /* Fallback to processor load with barriers.  */
10661   model = memmodel_from_int (INTVAL (operands[2]));
10662   operands[1] = force_reg (Pmode, XEXP (operands[1], 0));
10663   if (is_mm_seq_cst (model))
10664     expand_mem_thread_fence (model);
10665   emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10666   expand_mem_thread_fence (model);
10667   DONE;
10670 (define_insn "atomic_loaddi_1"
10671   [(set (match_operand:DI 0 "register_operand" "=r")
10672         (mem:DI (match_operand:SI 1 "register_operand" "r")))
10673    (clobber (match_scratch:DI 2 "=f"))]
10674   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10675   "{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"
10676   [(set_attr "type" "move")
10677    (set_attr "length" "16")])
10679 ;; Implement atomic DImode store.
10681 (define_expand "atomic_storedi"
10682   [(match_operand:DI 0 "memory_operand")                ;; memory
10683    (match_operand:DI 1 "reg_or_cint_move_operand")      ;; val out
10684    (match_operand:SI 2 "const_int_operand")]            ;; model
10685   ""
10687   enum memmodel model;
10688   rtx addr, libfunc;
10690   if (TARGET_SYNC_LIBCALLS && MAX_SYNC_LIBFUNC_SIZE >= 8)
10691     {
10692       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10693       libfunc = optab_libfunc (sync_lock_test_and_set_optab, DImode);
10694       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10695                          operands[1], DImode);
10696       DONE;
10697     }
10699   if (TARGET_ATOMIC_LIBCALLS)
10700     {
10701       addr = convert_memory_address (Pmode, XEXP (operands[0], 0));
10702       libfunc = init_one_libfunc ("__atomic_exchange_8");
10703       emit_library_call (libfunc, LCT_NORMAL, VOIDmode, addr, Pmode,
10704                          operands[1], DImode);
10705       DONE;
10706     }
10708   if (TARGET_64BIT || TARGET_SOFT_FLOAT)
10709     FAIL;
10711   /* Fallback to processor store with barriers.  */
10712   model = memmodel_from_int (INTVAL (operands[2]));
10713   operands[0] = force_reg (Pmode, XEXP (operands[0], 0));
10714   if (operands[1] != CONST0_RTX (DImode))
10715     operands[1] = force_reg (DImode, operands[1]);
10716   expand_mem_thread_fence (model);
10717   emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10718   if (is_mm_seq_cst (model))
10719     expand_mem_thread_fence (model);
10720   DONE;
10723 (define_insn "atomic_storedi_1"
10724   [(set (mem:DI (match_operand:SI 0 "register_operand" "r,r"))
10725         (match_operand:DI 1 "reg_or_0_operand" "M,r"))
10726    (clobber (match_scratch:DI 2 "=f,f"))]
10727   "!TARGET_64BIT && !TARGET_SOFT_FLOAT"
10728   "@
10729    fcpy,dbl %%fr0,%2\n\t{fstds|fstd} %2,0(%0)
10730    {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)"
10731   [(set_attr "type" "move,move")
10732    (set_attr "length" "8,16")])
10734 ;; PA 2.0 hardware supports out-of-order execution of loads and stores, so
10735 ;; we need memory barriers to enforce program order for memory references
10736 ;; when the TLB and PSW O bits are not set.  We assume all PA 2.0 systems
10737 ;; are weakly ordered since neither HP-UX or Linux set the PSW O bit.  Since
10738 ;; we want PA 1.x code to be PA 2.0 compatible, we also need barriers when
10739 ;; generating PA 1.x code even though all PA 1.x systems are strongly ordered.
10741 ;; When barriers are needed, we use a strongly ordered ldcw instruction as
10742 ;; the barrier.  All PA 2.0 targets accept the "co" cache control hint but
10743 ;; only PA8800 and PA8900 processors implement the cacheable hint.  In
10744 ;; that case, we can avoid aligning the ldcw address.  In spite of its
10745 ;; description, it is not clear that the sync instruction works as a barrier.
10747 (define_expand "memory_barrier"
10748   [(parallel
10749      [(set (match_dup 0) (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10750       (clobber (match_dup 1))])]
10751   ""
10753   /* We don't need a barrier if the target uses ordered memory references.  */
10754   if (TARGET_ORDERED)
10755     FAIL;
10756   operands[1] = gen_reg_rtx (Pmode);
10757   operands[0] = gen_rtx_MEM (BLKmode, operands[1]);
10758   MEM_VOLATILE_P (operands[0]) = 1;
10761 (define_insn "*memory_barrier_coherent"
10762   [(set (match_operand:BLK 0 "" "")
10763         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10764    (clobber (match_operand 1 "pmode_register_operand" "=r"))]
10765   "TARGET_PA_20 && TARGET_COHERENT_LDCW"
10766   "ldcw,co 0(%%sp),%1"
10767   [(set_attr "type" "binary")
10768    (set_attr "length" "4")])
10770 (define_insn "*memory_barrier_64"
10771   [(set (match_operand:BLK 0 "" "")
10772         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10773     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10774   "TARGET_64BIT"
10775   "ldo 15(%%sp),%1\n\tdepd %%r0,63,3,%1\n\tldcw,co 0(%1),%1"
10776   [(set_attr "type" "binary")
10777    (set_attr "length" "12")])
10779 (define_insn "*memory_barrier_32"
10780   [(set (match_operand:BLK 0 "" "")
10781         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
10782     (clobber (match_operand 1 "pmode_register_operand" "=&r"))]
10783   ""
10784   "ldo 15(%%sp),%1\n\t{dep|depw} %%r0,31,3,%1\n\t{ldcw|ldcw,co} 0(%1),%1"
10785   [(set_attr "type" "binary")
10786    (set_attr "length" "12")])