Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / pa / pa.md
blob9a434a6095f8062cc6b225445b032468a6553759
1 ;;- Machine description for HP PA-RISC architecture for GCC compiler
2 ;;   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 ;;   2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;;   Contributed by the Center for Software Science at the University
5 ;;   of Utah.
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;; This gcc Version 2 machine description is inspired by sparc.md and
25 ;; mips.md.
27 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; Uses of UNSPEC in this file:
31 (define_constants
32   [(UNSPEC_CFFC         0)      ; canonicalize_funcptr_for_compare
33    (UNSPEC_GOTO         1)      ; indirect_goto
34    (UNSPEC_DLTIND14R    2)      ; 
35   ])
37 ;; UNSPEC_VOLATILE:
39 (define_constants
40   [(UNSPECV_BLOCKAGE    0)      ; blockage
41    (UNSPECV_DCACHE      1)      ; dcacheflush
42    (UNSPECV_ICACHE      2)      ; icacheflush
43    (UNSPECV_OPC         3)      ; outline_prologue_call
44    (UNSPECV_OEC         4)      ; outline_epilogue_call
45    (UNSPECV_LONGJMP     5)      ; builtin_longjmp
46   ])
48 ;; Insn type.  Used to default other attribute values.
50 ;; type "unary" insns have one input operand (1) and one output operand (0)
51 ;; type "binary" insns have two input operands (1,2) and one output (0)
53 (define_attr "type"
54   "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
55   (const_string "binary"))
57 (define_attr "pa_combine_type"
58   "fmpy,faddsub,uncond_branch,addmove,none"
59   (const_string "none"))
61 ;; Processor type (for scheduling, not code generation) -- this attribute
62 ;; must exactly match the processor_type enumeration in pa.h.
64 ;; FIXME: Add 800 scheduling for completeness?
66 (define_attr "cpu" "700,7100,7100LC,7200,7300,8000" (const (symbol_ref "pa_cpu_attr")))
68 ;; Length (in # of bytes).
69 (define_attr "length" ""
70   (cond [(eq_attr "type" "load,fpload")
71          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
72                        (const_int 8) (const_int 4))
74          (eq_attr "type" "store,fpstore")
75          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
76                        (const_int 8) (const_int 4))
78          (eq_attr "type" "binary,shift,nullshift")
79          (if_then_else (match_operand 2 "arith_operand" "")
80                        (const_int 4) (const_int 12))
82          (eq_attr "type" "move,unary,shift,nullshift")
83          (if_then_else (match_operand 1 "arith_operand" "")
84                        (const_int 4) (const_int 8))]
86         (const_int 4)))
88 (define_asm_attributes
89   [(set_attr "length" "4")
90    (set_attr "type" "multi")])
92 ;; Attributes for instruction and branch scheduling
94 ;; For conditional branches.
95 (define_attr "in_branch_delay" "false,true"
96   (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
97                      (eq_attr "length" "4"))
98                 (const_string "true")
99                 (const_string "false")))
101 ;; Disallow instructions which use the FPU since they will tie up the FPU
102 ;; even if the instruction is nullified.
103 (define_attr "in_nullified_branch_delay" "false,true"
104   (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
105                      (eq_attr "length" "4"))
106                 (const_string "true")
107                 (const_string "false")))
109 ;; For calls and millicode calls.  Allow unconditional branches in the
110 ;; delay slot.
111 (define_attr "in_call_delay" "false,true"
112   (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
113               (eq_attr "length" "4"))
114            (const_string "true")
115          (eq_attr "type" "uncond_branch")
116            (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
117                              (const_int 0))
118                          (const_string "true")
119                          (const_string "false"))]
120         (const_string "false")))
123 ;; Call delay slot description.
124 (define_delay (eq_attr "type" "call")
125   [(eq_attr "in_call_delay" "true") (nil) (nil)])
127 ;; Millicode call delay slot description.
128 (define_delay (eq_attr "type" "milli")
129   [(eq_attr "in_call_delay" "true") (nil) (nil)])
131 ;; Return and other similar instructions.
132 (define_delay (eq_attr "type" "btable_branch,branch,parallel_branch")
133   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
135 ;; Floating point conditional branch delay slot description and
136 (define_delay (eq_attr "type" "fbranch")
137   [(eq_attr "in_branch_delay" "true")
138    (eq_attr "in_nullified_branch_delay" "true")
139    (nil)])
141 ;; Integer conditional branch delay slot description.
142 ;; Nullification of conditional branches on the PA is dependent on the
143 ;; direction of the branch.  Forward branches nullify true and
144 ;; backward branches nullify false.  If the direction is unknown
145 ;; then nullification is not allowed.
146 (define_delay (eq_attr "type" "cbranch")
147   [(eq_attr "in_branch_delay" "true")
148    (and (eq_attr "in_nullified_branch_delay" "true")
149         (attr_flag "forward"))
150    (and (eq_attr "in_nullified_branch_delay" "true")
151         (attr_flag "backward"))])
153 (define_delay (and (eq_attr "type" "uncond_branch")
154                    (eq (symbol_ref "following_call (insn)")
155                        (const_int 0)))
156   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
158 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
159 ;; load: 2, fpload: 3
160 ;; store, fpstore: 3, no D-cache operations should be scheduled.
162 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
163 ;; Timings:
164 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
165 ;; fcpy         3       ALU     2
166 ;; fabs         3       ALU     2
167 ;; fadd         3       ALU     2
168 ;; fsub         3       ALU     2
169 ;; fcmp         3       ALU     2
170 ;; fcnv         3       ALU     2
171 ;; fmpyadd      3       ALU,MPY 2
172 ;; fmpysub      3       ALU,MPY 2
173 ;; fmpycfxt     3       ALU,MPY 2
174 ;; fmpy         3       MPY     2
175 ;; fmpyi        3       MPY     2
176 ;; fdiv,sgl     10      MPY     10
177 ;; fdiv,dbl     12      MPY     12
178 ;; fsqrt,sgl    14      MPY     14
179 ;; fsqrt,dbl    18      MPY     18
181 ;; We don't model fmpyadd/fmpysub properly as those instructions
182 ;; keep both the FP ALU and MPY units busy.  Given that these
183 ;; processors are obsolete, I'm not going to spend the time to
184 ;; model those instructions correctly.
186 (define_automaton "pa700")
187 (define_cpu_unit "dummy_700,mem_700,fpalu_700,fpmpy_700" "pa700")
189 (define_insn_reservation "W0" 4
190   (and (eq_attr "type" "fpcc")
191        (eq_attr "cpu" "700"))
192   "fpalu_700*2")
194 (define_insn_reservation "W1" 3
195   (and (eq_attr "type" "fpalu")
196        (eq_attr "cpu" "700"))
197   "fpalu_700*2")
199 (define_insn_reservation "W2" 3
200   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
201        (eq_attr "cpu" "700"))
202   "fpmpy_700*2")
204 (define_insn_reservation "W3" 10
205   (and (eq_attr "type" "fpdivsgl")
206        (eq_attr "cpu" "700"))
207   "fpmpy_700*10")
209 (define_insn_reservation "W4" 12
210   (and (eq_attr "type" "fpdivdbl")
211        (eq_attr "cpu" "700"))
212   "fpmpy_700*12")
214 (define_insn_reservation "W5" 14
215   (and (eq_attr "type" "fpsqrtsgl")
216        (eq_attr "cpu" "700"))
217   "fpmpy_700*14")
219 (define_insn_reservation "W6" 18
220   (and (eq_attr "type" "fpsqrtdbl")
221        (eq_attr "cpu" "700"))
222   "fpmpy_700*18")
224 (define_insn_reservation "W7" 2
225   (and (eq_attr "type" "load")
226        (eq_attr "cpu" "700"))
227   "mem_700")
229 (define_insn_reservation "W8" 2
230   (and (eq_attr "type" "fpload")
231        (eq_attr "cpu" "700"))
232   "mem_700")
234 (define_insn_reservation "W9" 3
235   (and (eq_attr "type" "store")
236        (eq_attr "cpu" "700"))
237   "mem_700*3")
239 (define_insn_reservation "W10" 3
240   (and (eq_attr "type" "fpstore")
241        (eq_attr "cpu" "700"))
242   "mem_700*3")
244 (define_insn_reservation "W11" 1
245   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,load,fpload,store,fpstore")
246        (eq_attr "cpu" "700"))
247   "dummy_700")
249 ;; We have a bypass for all computations in the FP unit which feed an
250 ;; FP store as long as the sizes are the same.
251 (define_bypass 2 "W1,W2" "W10" "hppa_fpstore_bypass_p")
252 (define_bypass 9 "W3" "W10" "hppa_fpstore_bypass_p")
253 (define_bypass 11 "W4" "W10" "hppa_fpstore_bypass_p")
254 (define_bypass 13 "W5" "W10" "hppa_fpstore_bypass_p")
255 (define_bypass 17 "W6" "W10" "hppa_fpstore_bypass_p")
257 ;; We have an "anti-bypass" for FP loads which feed an FP store.
258 (define_bypass 4 "W8" "W10" "hppa_fpstore_bypass_p")
260 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
261 ;; floating point computations with non-floating point computations (fp loads
262 ;; and stores are not fp computations).
264 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
265 ;; take two cycles, during which no Dcache operations should be scheduled.
266 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
267 ;; all have the same memory characteristics if one disregards cache misses.
269 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
270 ;; There's no value in modeling the ALU and MUL separately though
271 ;; since there can never be a functional unit conflict given the
272 ;; latency and issue rates for those units.
274 ;; Timings:
275 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
276 ;; fcpy         2       ALU     1
277 ;; fabs         2       ALU     1
278 ;; fadd         2       ALU     1
279 ;; fsub         2       ALU     1
280 ;; fcmp         2       ALU     1
281 ;; fcnv         2       ALU     1
282 ;; fmpyadd      2       ALU,MPY 1
283 ;; fmpysub      2       ALU,MPY 1
284 ;; fmpycfxt     2       ALU,MPY 1
285 ;; fmpy         2       MPY     1
286 ;; fmpyi        2       MPY     1
287 ;; fdiv,sgl     8       DIV     8
288 ;; fdiv,dbl     15      DIV     15
289 ;; fsqrt,sgl    8       DIV     8
290 ;; fsqrt,dbl    15      DIV     15
292 (define_automaton "pa7100")
293 (define_cpu_unit "i_7100, f_7100,fpmac_7100,fpdivsqrt_7100,mem_7100" "pa7100")
295 (define_insn_reservation "X0" 2
296   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
297        (eq_attr "cpu" "7100"))
298   "f_7100,fpmac_7100")
300 (define_insn_reservation "X1" 8
301   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
302        (eq_attr "cpu" "7100"))
303   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*7")
305 (define_insn_reservation "X2" 15
306   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
307        (eq_attr "cpu" "7100"))
308   "f_7100+fpdivsqrt_7100,fpdivsqrt_7100*14")
310 (define_insn_reservation "X3" 2
311   (and (eq_attr "type" "load")
312        (eq_attr "cpu" "7100"))
313   "i_7100+mem_7100")
315 (define_insn_reservation "X4" 2
316   (and (eq_attr "type" "fpload")
317        (eq_attr "cpu" "7100"))
318   "i_7100+mem_7100")
320 (define_insn_reservation "X5" 2
321   (and (eq_attr "type" "store")
322        (eq_attr "cpu" "7100"))
323   "i_7100+mem_7100,mem_7100")
325 (define_insn_reservation "X6" 2
326   (and (eq_attr "type" "fpstore")
327        (eq_attr "cpu" "7100"))
328   "i_7100+mem_7100,mem_7100")
330 (define_insn_reservation "X7" 1
331   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore")
332        (eq_attr "cpu" "7100"))
333   "i_7100")
335 ;; We have a bypass for all computations in the FP unit which feed an
336 ;; FP store as long as the sizes are the same.
337 (define_bypass 1 "X0" "X6" "hppa_fpstore_bypass_p")
338 (define_bypass 7 "X1" "X6" "hppa_fpstore_bypass_p")
339 (define_bypass 14 "X2" "X6" "hppa_fpstore_bypass_p")
341 ;; We have an "anti-bypass" for FP loads which feed an FP store.
342 (define_bypass 3 "X4" "X6" "hppa_fpstore_bypass_p")
344 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
345 ;; There's no value in modeling the ALU and MUL separately though
346 ;; since there can never be a functional unit conflict that
347 ;; can be avoided given the latency, issue rates and mandatory
348 ;; one cycle cpu-wide lock for a double precision fp multiply.
350 ;; Timings:
351 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
352 ;; fcpy         2       ALU     1
353 ;; fabs         2       ALU     1
354 ;; fadd         2       ALU     1
355 ;; fsub         2       ALU     1
356 ;; fcmp         2       ALU     1
357 ;; fcnv         2       ALU     1
358 ;; fmpyadd,sgl  2       ALU,MPY 1
359 ;; fmpyadd,dbl  3       ALU,MPY 2
360 ;; fmpysub,sgl  2       ALU,MPY 1
361 ;; fmpysub,dbl  3       ALU,MPY 2
362 ;; fmpycfxt,sgl 2       ALU,MPY 1
363 ;; fmpycfxt,dbl 3       ALU,MPY 2
364 ;; fmpy,sgl     2       MPY     1
365 ;; fmpy,dbl     3       MPY     2
366 ;; fmpyi        3       MPY     2
367 ;; fdiv,sgl     8       DIV     8
368 ;; fdiv,dbl     15      DIV     15
369 ;; fsqrt,sgl    8       DIV     8
370 ;; fsqrt,dbl    15      DIV     15
372 ;; The PA7200 is just like the PA7100LC except that there is
373 ;; no store-store penalty.
375 ;; The PA7300 is just like the PA7200 except that there is
376 ;; no store-load penalty.
378 ;; Note there are some aspects of the 7100LC we are not modeling
379 ;; at the moment.  I'll be reviewing the 7100LC scheduling info
380 ;; shortly and updating this description.
382 ;;   load-load pairs
383 ;;   store-store pairs
384 ;;   other issue modeling
386 (define_automaton "pa7100lc")
387 (define_cpu_unit "i0_7100lc, i1_7100lc, f_7100lc" "pa7100lc")
388 (define_cpu_unit "fpmac_7100lc" "pa7100lc")
389 (define_cpu_unit "mem_7100lc" "pa7100lc")
391 ;; Double precision multiplies lock the entire CPU for one
392 ;; cycle.  There is no way to avoid this lock and trying to
393 ;; schedule around the lock is pointless and thus there is no
394 ;; value in trying to model this lock.
396 ;; Not modeling the lock allows us to treat fp multiplies just
397 ;; like any other FP alu instruction.  It allows for a smaller
398 ;; DFA and may reduce register pressure.
399 (define_insn_reservation "Y0" 2
400   (and (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
401        (eq_attr "cpu" "7100LC,7200,7300"))
402   "f_7100lc,fpmac_7100lc")
404 ;; fp division and sqrt instructions lock the entire CPU for
405 ;; 7 cycles (single precision) or 14 cycles (double precision).
406 ;; There is no way to avoid this lock and trying to schedule
407 ;; around the lock is pointless and thus there is no value in
408 ;; trying to model this lock.  Not modeling the lock allows
409 ;; for a smaller DFA and may reduce register pressure.
410 (define_insn_reservation "Y1" 1
411   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
412        (eq_attr "cpu" "7100LC,7200,7300"))
413   "f_7100lc")
415 (define_insn_reservation "Y2" 2
416   (and (eq_attr "type" "load")
417        (eq_attr "cpu" "7100LC,7200,7300"))
418   "i1_7100lc+mem_7100lc")
420 (define_insn_reservation "Y3" 2
421   (and (eq_attr "type" "fpload")
422        (eq_attr "cpu" "7100LC,7200,7300"))
423   "i1_7100lc+mem_7100lc")
425 (define_insn_reservation "Y4" 2
426   (and (eq_attr "type" "store")
427        (eq_attr "cpu" "7100LC"))
428   "i1_7100lc+mem_7100lc,mem_7100lc")
430 (define_insn_reservation "Y5" 2
431   (and (eq_attr "type" "fpstore")
432        (eq_attr "cpu" "7100LC"))
433   "i1_7100lc+mem_7100lc,mem_7100lc")
435 (define_insn_reservation "Y6" 1
436   (and (eq_attr "type" "shift,nullshift")
437        (eq_attr "cpu" "7100LC,7200,7300"))
438   "i1_7100lc")
440 (define_insn_reservation "Y7" 1
441   (and (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
442        (eq_attr "cpu" "7100LC,7200,7300"))
443   "(i0_7100lc|i1_7100lc)")
445 ;; The 7200 has a store-load penalty
446 (define_insn_reservation "Y8" 2
447   (and (eq_attr "type" "store")
448        (eq_attr "cpu" "7200"))
449   "i1_7100lc,mem_7100lc")
451 (define_insn_reservation "Y9" 2
452   (and (eq_attr "type" "fpstore")
453        (eq_attr "cpu" "7200"))
454   "i1_7100lc,mem_7100lc")
456 ;; The 7300 has no penalty for store-store or store-load
457 (define_insn_reservation "Y10" 2
458   (and (eq_attr "type" "store")
459        (eq_attr "cpu" "7300"))
460   "i1_7100lc")
462 (define_insn_reservation "Y11" 2
463   (and (eq_attr "type" "fpstore")
464        (eq_attr "cpu" "7300"))
465   "i1_7100lc")
467 ;; We have an "anti-bypass" for FP loads which feed an FP store.
468 (define_bypass 3 "Y3" "Y5,Y9,Y11" "hppa_fpstore_bypass_p")
470 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
471 ;; traditional architecture.
473 ;; The PA8000 has a large (56) entry reorder buffer that is split between
474 ;; memory and non-memory operations.
476 ;; The PA8000 can issue two memory and two non-memory operations per cycle to
477 ;; the function units, with the exception of branches and multi-output
478 ;; instructions.  The PA8000 can retire two non-memory operations per cycle
479 ;; and two memory operations per cycle, only one of which may be a store.
481 ;; Given the large reorder buffer, the processor can hide most latencies.
482 ;; According to HP, they've got the best results by scheduling for retirement
483 ;; bandwidth with limited latency scheduling for floating point operations.
484 ;; Latency for integer operations and memory references is ignored.
487 ;; We claim floating point operations have a 2 cycle latency and are
488 ;; fully pipelined, except for div and sqrt which are not pipelined and
489 ;; take from 17 to 31 cycles to complete.
491 ;; It's worth noting that there is no way to saturate all the functional
492 ;; units on the PA8000 as there is not enough issue bandwidth.
494 (define_automaton "pa8000")
495 (define_cpu_unit "inm0_8000, inm1_8000, im0_8000, im1_8000" "pa8000")
496 (define_cpu_unit "rnm0_8000, rnm1_8000, rm0_8000, rm1_8000" "pa8000")
497 (define_cpu_unit "store_8000" "pa8000")
498 (define_cpu_unit "f0_8000, f1_8000" "pa8000")
499 (define_cpu_unit "fdivsqrt0_8000, fdivsqrt1_8000" "pa8000")
500 (define_reservation "inm_8000" "inm0_8000 | inm1_8000")
501 (define_reservation "im_8000" "im0_8000 | im1_8000")
502 (define_reservation "rnm_8000" "rnm0_8000 | rnm1_8000")
503 (define_reservation "rm_8000" "rm0_8000 | rm1_8000")
504 (define_reservation "f_8000" "f0_8000 | f1_8000")
505 (define_reservation "fdivsqrt_8000" "fdivsqrt0_8000 | fdivsqrt1_8000")
507 ;; We can issue any two memops per cycle, but we can only retire
508 ;; one memory store per cycle.  We assume that the reorder buffer
509 ;; will hide any memory latencies per HP's recommendation.
510 (define_insn_reservation "Z0" 0
511   (and
512     (eq_attr "type" "load,fpload")
513     (eq_attr "cpu" "8000"))
514   "im_8000,rm_8000")
516 (define_insn_reservation "Z1" 0
517   (and
518     (eq_attr "type" "store,fpstore")
519     (eq_attr "cpu" "8000"))
520   "im_8000,rm_8000+store_8000")
522 ;; We can issue and retire two non-memory operations per cycle with
523 ;; a few exceptions (branches).  This group catches those we want
524 ;; to assume have zero latency.
525 (define_insn_reservation "Z2" 0
526   (and
527     (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl")
528     (eq_attr "cpu" "8000"))
529   "inm_8000,rnm_8000")
531 ;; Branches use both slots in the non-memory issue and
532 ;; retirement unit.
533 (define_insn_reservation "Z3" 0
534   (and
535     (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
536     (eq_attr "cpu" "8000"))
537   "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000")
539 ;; We partial latency schedule the floating point units.
540 ;; They can issue/retire two at a time in the non-memory
541 ;; units.  We fix their latency at 2 cycles and they
542 ;; are fully pipelined.
543 (define_insn_reservation "Z4" 1
544  (and
545    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
546    (eq_attr "cpu" "8000"))
547  "inm_8000,f_8000,rnm_8000")
549 ;; The fdivsqrt units are not pipelined and have a very long latency.  
550 ;; To keep the DFA from exploding, we do not show all the
551 ;; reservations for the divsqrt unit.
552 (define_insn_reservation "Z5" 17
553  (and
554    (eq_attr "type" "fpdivsgl,fpsqrtsgl")
555    (eq_attr "cpu" "8000"))
556  "inm_8000,fdivsqrt_8000*6,rnm_8000")
558 (define_insn_reservation "Z6" 31
559  (and
560    (eq_attr "type" "fpdivdbl,fpsqrtdbl")
561    (eq_attr "cpu" "8000"))
562  "inm_8000,fdivsqrt_8000*6,rnm_8000")
566 ;; Compare instructions.
567 ;; This controls RTL generation and register allocation.
569 ;; We generate RTL for comparisons and branches by having the cmpxx
570 ;; patterns store away the operands.  Then, the scc and bcc patterns
571 ;; emit RTL for both the compare and the branch.
574 (define_expand "cmpdi"
575   [(set (reg:CC 0)
576         (compare:CC (match_operand:DI 0 "reg_or_0_operand" "")
577                     (match_operand:DI 1 "register_operand" "")))]
578   "TARGET_64BIT"
580   "
582  hppa_compare_op0 = operands[0];
583  hppa_compare_op1 = operands[1];
584  hppa_branch_type = CMP_SI;
585  DONE;
588 (define_expand "cmpsi"
589   [(set (reg:CC 0)
590         (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
591                     (match_operand:SI 1 "arith5_operand" "")))]
592   ""
593   "
595  hppa_compare_op0 = operands[0];
596  hppa_compare_op1 = operands[1];
597  hppa_branch_type = CMP_SI;
598  DONE;
601 (define_expand "cmpsf"
602   [(set (reg:CCFP 0)
603         (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
604                       (match_operand:SF 1 "reg_or_0_operand" "")))]
605   "! TARGET_SOFT_FLOAT"
606   "
608   hppa_compare_op0 = operands[0];
609   hppa_compare_op1 = operands[1];
610   hppa_branch_type = CMP_SF;
611   DONE;
614 (define_expand "cmpdf"
615   [(set (reg:CCFP 0)
616       (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
617                     (match_operand:DF 1 "reg_or_0_operand" "")))]
618   "! TARGET_SOFT_FLOAT"
619   "
621   hppa_compare_op0 = operands[0];
622   hppa_compare_op1 = operands[1];
623   hppa_branch_type = CMP_DF;
624   DONE;
627 (define_insn ""
628   [(set (reg:CCFP 0)
629         (match_operator:CCFP 2 "comparison_operator"
630                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
631                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
632   "! TARGET_SOFT_FLOAT"
633   "fcmp,sgl,%Y2 %f0,%f1"
634   [(set_attr "length" "4")
635    (set_attr "type" "fpcc")])
637 (define_insn ""
638   [(set (reg:CCFP 0)
639         (match_operator:CCFP 2 "comparison_operator"
640                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
641                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
642   "! TARGET_SOFT_FLOAT"
643   "fcmp,dbl,%Y2 %f0,%f1"
644   [(set_attr "length" "4")
645    (set_attr "type" "fpcc")])
647 ;; Provide a means to emit the movccfp0 and movccfp1 optimization
648 ;; placeholders.  This is necessary in rare situations when a
649 ;; placeholder is re-emitted (see PR 8705).
651 (define_expand "movccfp"
652   [(set (reg:CCFP 0)
653         (match_operand 0 "const_int_operand" ""))]
654   "! TARGET_SOFT_FLOAT"
655   "
657   if ((unsigned HOST_WIDE_INT) INTVAL (operands[0]) > 1)
658     FAIL;
661 ;; The following patterns are optimization placeholders.  In almost
662 ;; all cases, the user of the condition code will be simplified and the
663 ;; original condition code setting insn should be eliminated.
665 (define_insn "*movccfp0"
666   [(set (reg:CCFP 0)
667         (const_int 0))]
668   "! TARGET_SOFT_FLOAT"
669   "fcmp,dbl,= %%fr0,%%fr0"
670   [(set_attr "length" "4")
671    (set_attr "type" "fpcc")])
673 (define_insn "*movccfp1"
674   [(set (reg:CCFP 0)
675         (const_int 1))]
676   "! TARGET_SOFT_FLOAT"
677   "fcmp,dbl,!= %%fr0,%%fr0"
678   [(set_attr "length" "4")
679    (set_attr "type" "fpcc")])
681 ;; scc insns.
683 (define_expand "seq"
684   [(set (match_operand:SI 0 "register_operand" "")
685         (eq:SI (match_dup 1)
686                (match_dup 2)))]
687   "!TARGET_64BIT"
688   "
690   /* fp scc patterns rarely match, and are not a win on the PA.  */
691   if (hppa_branch_type != CMP_SI)
692     FAIL;
693   /* set up operands from compare.  */
694   operands[1] = hppa_compare_op0;
695   operands[2] = hppa_compare_op1;
696   /* fall through and generate default code */
699 (define_expand "sne"
700   [(set (match_operand:SI 0 "register_operand" "")
701         (ne:SI (match_dup 1)
702                (match_dup 2)))]
703   "!TARGET_64BIT"
704   "
706   /* fp scc patterns rarely match, and are not a win on the PA.  */
707   if (hppa_branch_type != CMP_SI)
708     FAIL;
709   operands[1] = hppa_compare_op0;
710   operands[2] = hppa_compare_op1;
713 (define_expand "slt"
714   [(set (match_operand:SI 0 "register_operand" "")
715         (lt:SI (match_dup 1)
716                (match_dup 2)))]
717   "!TARGET_64BIT"
718   "
720   /* fp scc patterns rarely match, and are not a win on the PA.  */
721   if (hppa_branch_type != CMP_SI)
722     FAIL;
723   operands[1] = hppa_compare_op0;
724   operands[2] = hppa_compare_op1;
727 (define_expand "sgt"
728   [(set (match_operand:SI 0 "register_operand" "")
729         (gt:SI (match_dup 1)
730                (match_dup 2)))]
731   "!TARGET_64BIT"
732   "
734   /* fp scc patterns rarely match, and are not a win on the PA.  */
735   if (hppa_branch_type != CMP_SI)
736     FAIL;
737   operands[1] = hppa_compare_op0;
738   operands[2] = hppa_compare_op1;
741 (define_expand "sle"
742   [(set (match_operand:SI 0 "register_operand" "")
743         (le:SI (match_dup 1)
744                (match_dup 2)))]
745   "!TARGET_64BIT"
746   "
748   /* fp scc patterns rarely match, and are not a win on the PA.  */
749   if (hppa_branch_type != CMP_SI)
750     FAIL;
751   operands[1] = hppa_compare_op0;
752   operands[2] = hppa_compare_op1;
755 (define_expand "sge"
756   [(set (match_operand:SI 0 "register_operand" "")
757         (ge:SI (match_dup 1)
758                (match_dup 2)))]
759   "!TARGET_64BIT"
760   "
762   /* fp scc patterns rarely match, and are not a win on the PA.  */
763   if (hppa_branch_type != CMP_SI)
764     FAIL;
765   operands[1] = hppa_compare_op0;
766   operands[2] = hppa_compare_op1;
769 (define_expand "sltu"
770   [(set (match_operand:SI 0 "register_operand" "")
771         (ltu:SI (match_dup 1)
772                 (match_dup 2)))]
773   "!TARGET_64BIT"
774   "
776   if (hppa_branch_type != CMP_SI)
777     FAIL;
778   operands[1] = hppa_compare_op0;
779   operands[2] = hppa_compare_op1;
782 (define_expand "sgtu"
783   [(set (match_operand:SI 0 "register_operand" "")
784         (gtu:SI (match_dup 1)
785                 (match_dup 2)))]
786   "!TARGET_64BIT"
787   "
789   if (hppa_branch_type != CMP_SI)
790     FAIL;
791   operands[1] = hppa_compare_op0;
792   operands[2] = hppa_compare_op1;
795 (define_expand "sleu"
796   [(set (match_operand:SI 0 "register_operand" "")
797         (leu:SI (match_dup 1)
798                 (match_dup 2)))]
799   "!TARGET_64BIT"
800   "
802   if (hppa_branch_type != CMP_SI)
803     FAIL;
804   operands[1] = hppa_compare_op0;
805   operands[2] = hppa_compare_op1;
808 (define_expand "sgeu"
809   [(set (match_operand:SI 0 "register_operand" "")
810         (geu:SI (match_dup 1)
811                 (match_dup 2)))]
812   "!TARGET_64BIT"
813   "
815   if (hppa_branch_type != CMP_SI)
816     FAIL;
817   operands[1] = hppa_compare_op0;
818   operands[2] = hppa_compare_op1;
821 ;; Instruction canonicalization puts immediate operands second, which
822 ;; is the reverse of what we want.
824 (define_insn "scc"
825   [(set (match_operand:SI 0 "register_operand" "=r")
826         (match_operator:SI 3 "comparison_operator"
827                            [(match_operand:SI 1 "register_operand" "r")
828                             (match_operand:SI 2 "arith11_operand" "rI")]))]
829   ""
830   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
831   [(set_attr "type" "binary")
832    (set_attr "length" "8")])
834 (define_insn ""
835   [(set (match_operand:DI 0 "register_operand" "=r")
836         (match_operator:DI 3 "comparison_operator"
837                            [(match_operand:DI 1 "register_operand" "r")
838                             (match_operand:DI 2 "arith11_operand" "rI")]))]
839   "TARGET_64BIT"
840   "cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
841   [(set_attr "type" "binary")
842    (set_attr "length" "8")])
844 (define_insn "iorscc"
845   [(set (match_operand:SI 0 "register_operand" "=r")
846         (ior:SI (match_operator:SI 3 "comparison_operator"
847                                    [(match_operand:SI 1 "register_operand" "r")
848                                     (match_operand:SI 2 "arith11_operand" "rI")])
849                 (match_operator:SI 6 "comparison_operator"
850                                    [(match_operand:SI 4 "register_operand" "r")
851                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
852   ""
853   "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
854   [(set_attr "type" "binary")
855    (set_attr "length" "12")])
857 (define_insn ""
858   [(set (match_operand:DI 0 "register_operand" "=r")
859         (ior:DI (match_operator:DI 3 "comparison_operator"
860                                    [(match_operand:DI 1 "register_operand" "r")
861                                     (match_operand:DI 2 "arith11_operand" "rI")])
862                 (match_operator:DI 6 "comparison_operator"
863                                    [(match_operand:DI 4 "register_operand" "r")
864                                     (match_operand:DI 5 "arith11_operand" "rI")])))]
865   "TARGET_64BIT"
866   "cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
867   [(set_attr "type" "binary")
868    (set_attr "length" "12")])
870 ;; Combiner patterns for common operations performed with the output
871 ;; from an scc insn (negscc and incscc).
872 (define_insn "negscc"
873   [(set (match_operand:SI 0 "register_operand" "=r")
874         (neg:SI (match_operator:SI 3 "comparison_operator"
875                [(match_operand:SI 1 "register_operand" "r")
876                 (match_operand:SI 2 "arith11_operand" "rI")])))]
877   ""
878   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
879   [(set_attr "type" "binary")
880    (set_attr "length" "8")])
882 (define_insn ""
883   [(set (match_operand:DI 0 "register_operand" "=r")
884         (neg:DI (match_operator:DI 3 "comparison_operator"
885                [(match_operand:DI 1 "register_operand" "r")
886                 (match_operand:DI 2 "arith11_operand" "rI")])))]
887   "TARGET_64BIT"
888   "cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
889   [(set_attr "type" "binary")
890    (set_attr "length" "8")])
892 ;; Patterns for adding/subtracting the result of a boolean expression from
893 ;; a register.  First we have special patterns that make use of the carry
894 ;; bit, and output only two instructions.  For the cases we can't in
895 ;; general do in two instructions, the incscc pattern at the end outputs
896 ;; two or three instructions.
898 (define_insn ""
899   [(set (match_operand:SI 0 "register_operand" "=r")
900         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
901                          (match_operand:SI 3 "arith11_operand" "rI"))
902                  (match_operand:SI 1 "register_operand" "r")))]
903   ""
904   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
905   [(set_attr "type" "binary")
906    (set_attr "length" "8")])
908 (define_insn ""
909   [(set (match_operand:DI 0 "register_operand" "=r")
910         (plus:DI (leu:DI (match_operand:DI 2 "register_operand" "r")
911                          (match_operand:DI 3 "arith11_operand" "rI"))
912                  (match_operand:DI 1 "register_operand" "r")))]
913   "TARGET_64BIT"
914   "sub%I3 %3,%2,%%r0\;add,dc %%r0,%1,%0"
915   [(set_attr "type" "binary")
916    (set_attr "length" "8")])
918 ; This need only accept registers for op3, since canonicalization
919 ; replaces geu with gtu when op3 is an integer.
920 (define_insn ""
921   [(set (match_operand:SI 0 "register_operand" "=r")
922         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
923                          (match_operand:SI 3 "register_operand" "r"))
924                  (match_operand:SI 1 "register_operand" "r")))]
925   ""
926   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
927   [(set_attr "type" "binary")
928    (set_attr "length" "8")])
930 (define_insn ""
931   [(set (match_operand:DI 0 "register_operand" "=r")
932         (plus:DI (geu:DI (match_operand:DI 2 "register_operand" "r")
933                          (match_operand:DI 3 "register_operand" "r"))
934                  (match_operand:DI 1 "register_operand" "r")))]
935   "TARGET_64BIT"
936   "sub %2,%3,%%r0\;add,dc %%r0,%1,%0"
937   [(set_attr "type" "binary")
938    (set_attr "length" "8")])
940 ; Match only integers for op3 here.  This is used as canonical form of the
941 ; geu pattern when op3 is an integer.  Don't match registers since we can't
942 ; make better code than the general incscc pattern.
943 (define_insn ""
944   [(set (match_operand:SI 0 "register_operand" "=r")
945         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
946                          (match_operand:SI 3 "int11_operand" "I"))
947                  (match_operand:SI 1 "register_operand" "r")))]
948   ""
949   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
950   [(set_attr "type" "binary")
951    (set_attr "length" "8")])
953 (define_insn ""
954   [(set (match_operand:DI 0 "register_operand" "=r")
955         (plus:DI (gtu:DI (match_operand:DI 2 "register_operand" "r")
956                          (match_operand:DI 3 "int11_operand" "I"))
957                  (match_operand:DI 1 "register_operand" "r")))]
958   "TARGET_64BIT"
959   "addi %k3,%2,%%r0\;add,dc %%r0,%1,%0"
960   [(set_attr "type" "binary")
961    (set_attr "length" "8")])
963 (define_insn "incscc"
964   [(set (match_operand:SI 0 "register_operand" "=r,r")
965         (plus:SI (match_operator:SI 4 "comparison_operator"
966                     [(match_operand:SI 2 "register_operand" "r,r")
967                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
968                  (match_operand:SI 1 "register_operand" "0,?r")))]
969   ""
970   "@
971    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
972    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
973   [(set_attr "type" "binary,binary")
974    (set_attr "length" "8,12")])
976 (define_insn ""
977   [(set (match_operand:DI 0 "register_operand" "=r,r")
978         (plus:DI (match_operator:DI 4 "comparison_operator"
979                     [(match_operand:DI 2 "register_operand" "r,r")
980                      (match_operand:DI 3 "arith11_operand" "rI,rI")])
981                  (match_operand:DI 1 "register_operand" "0,?r")))]
982   "TARGET_64BIT"
983   "@
984    cmp%I3clr,*%B4 %3,%2,%%r0\;addi 1,%0,%0
985    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
986   [(set_attr "type" "binary,binary")
987    (set_attr "length" "8,12")])
989 (define_insn ""
990   [(set (match_operand:SI 0 "register_operand" "=r")
991         (minus:SI (match_operand:SI 1 "register_operand" "r")
992                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
993                           (match_operand:SI 3 "arith11_operand" "rI"))))]
994   ""
995   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
996   [(set_attr "type" "binary")
997    (set_attr "length" "8")])
999 (define_insn ""
1000   [(set (match_operand:DI 0 "register_operand" "=r")
1001         (minus:DI (match_operand:DI 1 "register_operand" "r")
1002                   (gtu:DI (match_operand:DI 2 "register_operand" "r")
1003                           (match_operand:DI 3 "arith11_operand" "rI"))))]
1004   "TARGET_64BIT"
1005   "sub%I3 %3,%2,%%r0\;sub,db %1,%%r0,%0"
1006   [(set_attr "type" "binary")
1007    (set_attr "length" "8")])
1009 (define_insn ""
1010   [(set (match_operand:SI 0 "register_operand" "=r")
1011         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1012                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
1013                                     (match_operand:SI 3 "arith11_operand" "rI")))
1014                   (match_operand:SI 4 "register_operand" "r")))]
1015   ""
1016   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1017   [(set_attr "type" "binary")
1018    (set_attr "length" "8")])
1020 (define_insn ""
1021   [(set (match_operand:DI 0 "register_operand" "=r")
1022         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1023                             (gtu:DI (match_operand:DI 2 "register_operand" "r")
1024                                     (match_operand:DI 3 "arith11_operand" "rI")))
1025                   (match_operand:DI 4 "register_operand" "r")))]
1026   "TARGET_64BIT"
1027   "sub%I3 %3,%2,%%r0\;sub,db %1,%4,%0"
1028   [(set_attr "type" "binary")
1029    (set_attr "length" "8")])
1031 ; This need only accept registers for op3, since canonicalization
1032 ; replaces ltu with leu when op3 is an integer.
1033 (define_insn ""
1034   [(set (match_operand:SI 0 "register_operand" "=r")
1035         (minus:SI (match_operand:SI 1 "register_operand" "r")
1036                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
1037                           (match_operand:SI 3 "register_operand" "r"))))]
1038   ""
1039   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
1040   [(set_attr "type" "binary")
1041    (set_attr "length" "8")])
1043 (define_insn ""
1044   [(set (match_operand:DI 0 "register_operand" "=r")
1045         (minus:DI (match_operand:DI 1 "register_operand" "r")
1046                   (ltu:DI (match_operand:DI 2 "register_operand" "r")
1047                           (match_operand:DI 3 "register_operand" "r"))))]
1048   "TARGET_64BIT"
1049   "sub %2,%3,%%r0\;sub,db %1,%%r0,%0"
1050   [(set_attr "type" "binary")
1051    (set_attr "length" "8")])
1053 (define_insn ""
1054   [(set (match_operand:SI 0 "register_operand" "=r")
1055         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1056                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
1057                                     (match_operand:SI 3 "register_operand" "r")))
1058                   (match_operand:SI 4 "register_operand" "r")))]
1059   ""
1060   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
1061   [(set_attr "type" "binary")
1062    (set_attr "length" "8")])
1064 (define_insn ""
1065   [(set (match_operand:DI 0 "register_operand" "=r")
1066         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1067                             (ltu:DI (match_operand:DI 2 "register_operand" "r")
1068                                     (match_operand:DI 3 "register_operand" "r")))
1069                   (match_operand:DI 4 "register_operand" "r")))]
1070   "TARGET_64BIT"
1071   "sub %2,%3,%%r0\;sub,db %1,%4,%0"
1072   [(set_attr "type" "binary")
1073    (set_attr "length" "8")])
1075 ; Match only integers for op3 here.  This is used as canonical form of the
1076 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
1077 ; make better code than the general incscc pattern.
1078 (define_insn ""
1079   [(set (match_operand:SI 0 "register_operand" "=r")
1080         (minus:SI (match_operand:SI 1 "register_operand" "r")
1081                   (leu:SI (match_operand:SI 2 "register_operand" "r")
1082                           (match_operand:SI 3 "int11_operand" "I"))))]
1083   ""
1084   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
1085   [(set_attr "type" "binary")
1086    (set_attr "length" "8")])
1088 (define_insn ""
1089   [(set (match_operand:DI 0 "register_operand" "=r")
1090         (minus:DI (match_operand:DI 1 "register_operand" "r")
1091                   (leu:DI (match_operand:DI 2 "register_operand" "r")
1092                           (match_operand:DI 3 "int11_operand" "I"))))]
1093   "TARGET_64BIT"
1094   "addi %k3,%2,%%r0\;sub,db %1,%%r0,%0"
1095   [(set_attr "type" "binary")
1096    (set_attr "length" "8")])
1098 (define_insn ""
1099   [(set (match_operand:SI 0 "register_operand" "=r")
1100         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1101                             (leu:SI (match_operand:SI 2 "register_operand" "r")
1102                                     (match_operand:SI 3 "int11_operand" "I")))
1103                   (match_operand:SI 4 "register_operand" "r")))]
1104   ""
1105   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
1106   [(set_attr "type" "binary")
1107    (set_attr "length" "8")])
1109 (define_insn ""
1110   [(set (match_operand:DI 0 "register_operand" "=r")
1111         (minus:DI (minus:DI (match_operand:DI 1 "register_operand" "r")
1112                             (leu:DI (match_operand:DI 2 "register_operand" "r")
1113                                     (match_operand:DI 3 "int11_operand" "I")))
1114                   (match_operand:DI 4 "register_operand" "r")))]
1115   "TARGET_64BIT"
1116   "addi %k3,%2,%%r0\;sub,db %1,%4,%0"
1117   [(set_attr "type" "binary")
1118    (set_attr "length" "8")])
1120 (define_insn "decscc"
1121   [(set (match_operand:SI 0 "register_operand" "=r,r")
1122         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
1123                   (match_operator:SI 4 "comparison_operator"
1124                      [(match_operand:SI 2 "register_operand" "r,r")
1125                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
1126   ""
1127   "@
1128    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
1129    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1130   [(set_attr "type" "binary,binary")
1131    (set_attr "length" "8,12")])
1133 (define_insn ""
1134   [(set (match_operand:DI 0 "register_operand" "=r,r")
1135         (minus:DI (match_operand:DI 1 "register_operand" "0,?r")
1136                   (match_operator:DI 4 "comparison_operator"
1137                      [(match_operand:DI 2 "register_operand" "r,r")
1138                       (match_operand:DI 3 "arith11_operand" "rI,rI")])))]
1139   "TARGET_64BIT"
1140   "@
1141    cmp%I3clr,*%B4 %3,%2,%%r0\;addi -1,%0,%0
1142    cmp%I3clr,*%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
1143   [(set_attr "type" "binary,binary")
1144    (set_attr "length" "8,12")])
1146 ; Patterns for max and min.  (There is no need for an earlyclobber in the
1147 ; last alternative since the middle alternative will match if op0 == op1.)
1149 (define_insn "sminsi3"
1150   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1151         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1152                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1153   ""
1154   "@
1155   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
1156   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
1157   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
1158 [(set_attr "type" "multi,multi,multi")
1159  (set_attr "length" "8,8,8")])
1161 (define_insn "smindi3"
1162   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1163         (smin:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1164                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1165   "TARGET_64BIT"
1166   "@
1167   cmpclr,*> %2,%0,%%r0\;copy %2,%0
1168   cmpiclr,*> %2,%0,%%r0\;ldi %2,%0
1169   cmpclr,*> %1,%r2,%0\;copy %1,%0"
1170 [(set_attr "type" "multi,multi,multi")
1171  (set_attr "length" "8,8,8")])
1173 (define_insn "uminsi3"
1174   [(set (match_operand:SI 0 "register_operand" "=r,r")
1175         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
1176                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1177   ""
1178   "@
1179   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
1180   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
1181 [(set_attr "type" "multi,multi")
1182  (set_attr "length" "8,8")])
1184 (define_insn "umindi3"
1185   [(set (match_operand:DI 0 "register_operand" "=r,r")
1186         (umin:DI (match_operand:DI 1 "register_operand" "%0,0")
1187                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1188   "TARGET_64BIT"
1189   "@
1190   cmpclr,*>> %2,%0,%%r0\;copy %2,%0
1191   cmpiclr,*>> %2,%0,%%r0\;ldi %2,%0"
1192 [(set_attr "type" "multi,multi")
1193  (set_attr "length" "8,8")])
1195 (define_insn "smaxsi3"
1196   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1197         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
1198                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
1199   ""
1200   "@
1201   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
1202   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
1203   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
1204 [(set_attr "type" "multi,multi,multi")
1205  (set_attr "length" "8,8,8")])
1207 (define_insn "smaxdi3"
1208   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1209         (smax:DI (match_operand:DI 1 "register_operand" "%0,0,r")
1210                  (match_operand:DI 2 "arith11_operand" "r,I,M")))]
1211   "TARGET_64BIT"
1212   "@
1213   cmpclr,*< %2,%0,%%r0\;copy %2,%0
1214   cmpiclr,*< %2,%0,%%r0\;ldi %2,%0
1215   cmpclr,*< %1,%r2,%0\;copy %1,%0"
1216 [(set_attr "type" "multi,multi,multi")
1217  (set_attr "length" "8,8,8")])
1219 (define_insn "umaxsi3"
1220   [(set (match_operand:SI 0 "register_operand" "=r,r")
1221         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
1222                  (match_operand:SI 2 "arith11_operand" "r,I")))]
1223   ""
1224   "@
1225   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
1226   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
1227 [(set_attr "type" "multi,multi")
1228  (set_attr "length" "8,8")])
1230 (define_insn "umaxdi3"
1231   [(set (match_operand:DI 0 "register_operand" "=r,r")
1232         (umax:DI (match_operand:DI 1 "register_operand" "%0,0")
1233                  (match_operand:DI 2 "arith11_operand" "r,I")))]
1234   "TARGET_64BIT"
1235   "@
1236   cmpclr,*<< %2,%0,%%r0\;copy %2,%0
1237   cmpiclr,*<< %2,%0,%%r0\;ldi %2,%0"
1238 [(set_attr "type" "multi,multi")
1239  (set_attr "length" "8,8")])
1241 (define_insn "abssi2"
1242   [(set (match_operand:SI 0 "register_operand" "=r")
1243         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
1244   ""
1245   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
1246   [(set_attr "type" "multi")
1247    (set_attr "length" "8")])
1249 (define_insn "absdi2"
1250   [(set (match_operand:DI 0 "register_operand" "=r")
1251         (abs:DI (match_operand:DI 1 "register_operand" "r")))]
1252   "TARGET_64BIT"
1253   "or,*>= %%r0,%1,%0\;subi 0,%0,%0"
1254   [(set_attr "type" "multi")
1255    (set_attr "length" "8")])
1257 ;;; Experimental conditional move patterns
1259 (define_expand "movsicc"
1260   [(set (match_operand:SI 0 "register_operand" "")
1261         (if_then_else:SI
1262          (match_operator 1 "comparison_operator"
1263             [(match_dup 4)
1264              (match_dup 5)])
1265          (match_operand:SI 2 "reg_or_cint_move_operand" "")
1266          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
1267   ""
1268   "
1270   enum rtx_code code = GET_CODE (operands[1]);
1272   if (hppa_branch_type != CMP_SI)
1273     FAIL;
1275   if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1276       || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1277     FAIL;
1279   /* operands[1] is currently the result of compare_from_rtx.  We want to
1280      emit a compare of the original operands.  */
1281   operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
1282   operands[4] = hppa_compare_op0;
1283   operands[5] = hppa_compare_op1;
1286 ;; We used to accept any register for op1.
1288 ;; However, it loses sometimes because the compiler will end up using
1289 ;; different registers for op0 and op1 in some critical cases.  local-alloc
1290 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
1292 ;; If/when global register allocation supports tying we should allow any
1293 ;; register for op1 again.
1294 (define_insn ""
1295   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1296         (if_then_else:SI
1297          (match_operator 2 "comparison_operator"
1298             [(match_operand:SI 3 "register_operand" "r,r,r,r")
1299              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
1300          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
1301          (const_int 0)))]
1302   ""
1303   "@
1304    {com%I4clr|cmp%I4clr},%S2 %4,%3,%%r0\;ldi 0,%0
1305    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldi %1,%0
1306    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;ldil L'%1,%0
1307    {com%I4clr|cmp%I4clr},%B2 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
1308   [(set_attr "type" "multi,multi,multi,nullshift")
1309    (set_attr "length" "8,8,8,8")])
1311 (define_insn ""
1312   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1313         (if_then_else:SI
1314          (match_operator 5 "comparison_operator"
1315             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
1316              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1317          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1318          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1319   ""
1320   "@
1321    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
1322    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
1323    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
1324    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
1325    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
1326    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
1327    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
1328    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
1329   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1330    (set_attr "length" "8,8,8,8,8,8,8,8")])
1332 (define_expand "movdicc"
1333   [(set (match_operand:DI 0 "register_operand" "")
1334         (if_then_else:DI
1335          (match_operator 1 "comparison_operator"
1336             [(match_dup 4)
1337              (match_dup 5)])
1338          (match_operand:DI 2 "reg_or_cint_move_operand" "")
1339          (match_operand:DI 3 "reg_or_cint_move_operand" "")))]
1340   "TARGET_64BIT"
1341   "
1343   enum rtx_code code = GET_CODE (operands[1]);
1345   if (hppa_branch_type != CMP_SI)
1346     FAIL;
1348   if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
1349       || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
1350     FAIL;
1352   /* operands[1] is currently the result of compare_from_rtx.  We want to
1353      emit a compare of the original operands.  */
1354   operands[1] = gen_rtx_fmt_ee (code, DImode, hppa_compare_op0, hppa_compare_op1);
1355   operands[4] = hppa_compare_op0;
1356   operands[5] = hppa_compare_op1;
1359 ; We need the first constraint alternative in order to avoid
1360 ; earlyclobbers on all other alternatives.
1361 (define_insn ""
1362   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r")
1363         (if_then_else:DI
1364          (match_operator 2 "comparison_operator"
1365             [(match_operand:DI 3 "register_operand" "r,r,r,r,r")
1366              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
1367          (match_operand:DI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
1368          (const_int 0)))]
1369   "TARGET_64BIT"
1370   "@
1371    cmp%I4clr,*%S2 %4,%3,%%r0\;ldi 0,%0
1372    cmp%I4clr,*%B2 %4,%3,%0\;copy %1,%0
1373    cmp%I4clr,*%B2 %4,%3,%0\;ldi %1,%0
1374    cmp%I4clr,*%B2 %4,%3,%0\;ldil L'%1,%0
1375    cmp%I4clr,*%B2 %4,%3,%0\;depdi,z %z1,%0"
1376   [(set_attr "type" "multi,multi,multi,multi,nullshift")
1377    (set_attr "length" "8,8,8,8,8")])
1379 (define_insn ""
1380   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r,r")
1381         (if_then_else:DI
1382          (match_operator 5 "comparison_operator"
1383             [(match_operand:DI 3 "register_operand" "r,r,r,r,r,r,r,r")
1384              (match_operand:DI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
1385          (match_operand:DI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
1386          (match_operand:DI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
1387   "TARGET_64BIT"
1388   "@
1389    cmp%I4clr,*%S5 %4,%3,%%r0\;copy %2,%0
1390    cmp%I4clr,*%S5 %4,%3,%%r0\;ldi %2,%0
1391    cmp%I4clr,*%S5 %4,%3,%%r0\;ldil L'%2,%0
1392    cmp%I4clr,*%S5 %4,%3,%%r0\;depdi,z %z2,%0
1393    cmp%I4clr,*%B5 %4,%3,%%r0\;copy %1,%0
1394    cmp%I4clr,*%B5 %4,%3,%%r0\;ldi %1,%0
1395    cmp%I4clr,*%B5 %4,%3,%%r0\;ldil L'%1,%0
1396    cmp%I4clr,*%B5 %4,%3,%%r0\;depdi,z %z1,%0"
1397   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
1398    (set_attr "length" "8,8,8,8,8,8,8,8")])
1400 ;; Conditional Branches
1402 (define_expand "beq"
1403   [(set (pc)
1404         (if_then_else (eq (match_dup 1) (match_dup 2))
1405                       (label_ref (match_operand 0 "" ""))
1406                       (pc)))]
1407   ""
1408   "
1410   if (hppa_branch_type != CMP_SI)
1411     {
1412       emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
1413       emit_bcond_fp (NE, operands[0]);
1414       DONE;
1415     }
1416   /* set up operands from compare.  */
1417   operands[1] = hppa_compare_op0;
1418   operands[2] = hppa_compare_op1;
1419   /* fall through and generate default code */
1422 (define_expand "bne"
1423   [(set (pc)
1424         (if_then_else (ne (match_dup 1) (match_dup 2))
1425                       (label_ref (match_operand 0 "" ""))
1426                       (pc)))]
1427   ""
1428   "
1430   if (hppa_branch_type != CMP_SI)
1431     {
1432       emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
1433       emit_bcond_fp (NE, operands[0]);
1434       DONE;
1435     }
1436   operands[1] = hppa_compare_op0;
1437   operands[2] = hppa_compare_op1;
1440 (define_expand "bgt"
1441   [(set (pc)
1442         (if_then_else (gt (match_dup 1) (match_dup 2))
1443                       (label_ref (match_operand 0 "" ""))
1444                       (pc)))]
1445   ""
1446   "
1448   if (hppa_branch_type != CMP_SI)
1449     {
1450       emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
1451       emit_bcond_fp (NE, operands[0]);
1452       DONE;
1453     }
1454   operands[1] = hppa_compare_op0;
1455   operands[2] = hppa_compare_op1;
1458 (define_expand "blt"
1459   [(set (pc)
1460         (if_then_else (lt (match_dup 1) (match_dup 2))
1461                       (label_ref (match_operand 0 "" ""))
1462                       (pc)))]
1463   ""
1464   "
1466   if (hppa_branch_type != CMP_SI)
1467     {
1468       emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
1469       emit_bcond_fp (NE, operands[0]);
1470       DONE;
1471     }
1472   operands[1] = hppa_compare_op0;
1473   operands[2] = hppa_compare_op1;
1476 (define_expand "bge"
1477   [(set (pc)
1478         (if_then_else (ge (match_dup 1) (match_dup 2))
1479                       (label_ref (match_operand 0 "" ""))
1480                       (pc)))]
1481   ""
1482   "
1484   if (hppa_branch_type != CMP_SI)
1485     {
1486       emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
1487       emit_bcond_fp (NE, operands[0]);
1488       DONE;
1489     }
1490   operands[1] = hppa_compare_op0;
1491   operands[2] = hppa_compare_op1;
1494 (define_expand "ble"
1495   [(set (pc)
1496         (if_then_else (le (match_dup 1) (match_dup 2))
1497                       (label_ref (match_operand 0 "" ""))
1498                       (pc)))]
1499   ""
1500   "
1502   if (hppa_branch_type != CMP_SI)
1503     {
1504       emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
1505       emit_bcond_fp (NE, operands[0]);
1506       DONE;
1507     }
1508   operands[1] = hppa_compare_op0;
1509   operands[2] = hppa_compare_op1;
1512 (define_expand "bgtu"
1513   [(set (pc)
1514         (if_then_else (gtu (match_dup 1) (match_dup 2))
1515                       (label_ref (match_operand 0 "" ""))
1516                       (pc)))]
1517   ""
1518   "
1520   if (hppa_branch_type != CMP_SI)
1521     FAIL;
1522   operands[1] = hppa_compare_op0;
1523   operands[2] = hppa_compare_op1;
1526 (define_expand "bltu"
1527   [(set (pc)
1528         (if_then_else (ltu (match_dup 1) (match_dup 2))
1529                       (label_ref (match_operand 0 "" ""))
1530                       (pc)))]
1531   ""
1532   "
1534   if (hppa_branch_type != CMP_SI)
1535     FAIL;
1536   operands[1] = hppa_compare_op0;
1537   operands[2] = hppa_compare_op1;
1540 (define_expand "bgeu"
1541   [(set (pc)
1542         (if_then_else (geu (match_dup 1) (match_dup 2))
1543                       (label_ref (match_operand 0 "" ""))
1544                       (pc)))]
1545   ""
1546   "
1548   if (hppa_branch_type != CMP_SI)
1549     FAIL;
1550   operands[1] = hppa_compare_op0;
1551   operands[2] = hppa_compare_op1;
1554 (define_expand "bleu"
1555   [(set (pc)
1556         (if_then_else (leu (match_dup 1) (match_dup 2))
1557                       (label_ref (match_operand 0 "" ""))
1558                       (pc)))]
1559   ""
1560   "
1562   if (hppa_branch_type != CMP_SI)
1563     FAIL;
1564   operands[1] = hppa_compare_op0;
1565   operands[2] = hppa_compare_op1;
1568 (define_expand "bltgt"
1569   [(set (pc)
1570         (if_then_else (ltgt (match_dup 1) (match_dup 2))
1571                       (label_ref (match_operand 0 "" ""))
1572                       (pc)))]
1573   ""
1574   "
1576   if (hppa_branch_type == CMP_SI)
1577     FAIL;
1578   emit_insn (gen_cmp_fp (LTGT, hppa_compare_op0, hppa_compare_op1));
1579   emit_bcond_fp (NE, operands[0]);
1580   DONE;
1583 (define_expand "bunle"
1584   [(set (pc)
1585         (if_then_else (unle (match_dup 1) (match_dup 2))
1586                       (label_ref (match_operand 0 "" ""))
1587                       (pc)))]
1588   ""
1589   "
1591   if (hppa_branch_type == CMP_SI)
1592     FAIL;
1593   emit_insn (gen_cmp_fp (UNLE, hppa_compare_op0, hppa_compare_op1));
1594   emit_bcond_fp (NE, operands[0]);
1595   DONE;
1598 (define_expand "bunlt"
1599   [(set (pc)
1600         (if_then_else (unlt (match_dup 1) (match_dup 2))
1601                       (label_ref (match_operand 0 "" ""))
1602                       (pc)))]
1603   ""
1604   "
1606   if (hppa_branch_type == CMP_SI)
1607     FAIL;
1608   emit_insn (gen_cmp_fp (UNLT, hppa_compare_op0, hppa_compare_op1));
1609   emit_bcond_fp (NE, operands[0]);
1610   DONE;
1613 (define_expand "bunge"
1614   [(set (pc)
1615         (if_then_else (unge (match_dup 1) (match_dup 2))
1616                       (label_ref (match_operand 0 "" ""))
1617                       (pc)))]
1618   ""
1619   "
1621   if (hppa_branch_type == CMP_SI)
1622     FAIL;
1623   emit_insn (gen_cmp_fp (UNGE, hppa_compare_op0, hppa_compare_op1));
1624   emit_bcond_fp (NE, operands[0]);
1625   DONE;
1628 (define_expand "bungt"
1629   [(set (pc)
1630         (if_then_else (ungt (match_dup 1) (match_dup 2))
1631                       (label_ref (match_operand 0 "" ""))
1632                       (pc)))]
1633   ""
1634   "
1636   if (hppa_branch_type == CMP_SI)
1637     FAIL;
1638   emit_insn (gen_cmp_fp (UNGT, hppa_compare_op0, hppa_compare_op1));
1639   emit_bcond_fp (NE, operands[0]);
1640   DONE;
1643 (define_expand "buneq"
1644   [(set (pc)
1645         (if_then_else (uneq (match_dup 1) (match_dup 2))
1646                       (label_ref (match_operand 0 "" ""))
1647                       (pc)))]
1648   ""
1649   "
1651   if (hppa_branch_type == CMP_SI)
1652     FAIL;
1653   emit_insn (gen_cmp_fp (UNEQ, hppa_compare_op0, hppa_compare_op1));
1654   emit_bcond_fp (NE, operands[0]);
1655   DONE;
1658 (define_expand "bunordered"
1659   [(set (pc)
1660         (if_then_else (unordered (match_dup 1) (match_dup 2))
1661                       (label_ref (match_operand 0 "" ""))
1662                       (pc)))]
1663   ""
1664   "
1666   if (hppa_branch_type == CMP_SI)
1667     FAIL;
1668   emit_insn (gen_cmp_fp (UNORDERED, hppa_compare_op0, hppa_compare_op1));
1669   emit_bcond_fp (NE, operands[0]);
1670   DONE;
1673 (define_expand "bordered"
1674   [(set (pc)
1675         (if_then_else (ordered (match_dup 1) (match_dup 2))
1676                       (label_ref (match_operand 0 "" ""))
1677                       (pc)))]
1678   ""
1679   "
1681   if (hppa_branch_type == CMP_SI)
1682     FAIL;
1683   emit_insn (gen_cmp_fp (ORDERED, hppa_compare_op0, hppa_compare_op1));
1684   emit_bcond_fp (NE, operands[0]);
1685   DONE;
1688 ;; Match the branch patterns.
1691 ;; Note a long backward conditional branch with an annulled delay slot
1692 ;; has a length of 12.
1693 (define_insn ""
1694   [(set (pc)
1695         (if_then_else
1696          (match_operator 3 "comparison_operator"
1697                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1698                           (match_operand:SI 2 "arith5_operand" "rL")])
1699          (label_ref (match_operand 0 "" ""))
1700          (pc)))]
1701   ""
1702   "*
1704   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1705                          get_attr_length (insn), 0, insn);
1707 [(set_attr "type" "cbranch")
1708  (set (attr "length")
1709     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1710                (const_int 8184))
1711            (const_int 4)
1712            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1713                (const_int 262100))
1714            (const_int 8)
1715            (eq (symbol_ref "flag_pic") (const_int 0))
1716            (const_int 20)]
1717           (const_int 28)))])
1719 ;; Match the negated branch.
1721 (define_insn ""
1722   [(set (pc)
1723         (if_then_else
1724          (match_operator 3 "comparison_operator"
1725                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1726                           (match_operand:SI 2 "arith5_operand" "rL")])
1727          (pc)
1728          (label_ref (match_operand 0 "" ""))))]
1729   ""
1730   "*
1732   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1733                          get_attr_length (insn), 1, insn);
1735 [(set_attr "type" "cbranch")
1736  (set (attr "length")
1737     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1738                (const_int 8184))
1739            (const_int 4)
1740            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1741                (const_int 262100))
1742            (const_int 8)
1743            (eq (symbol_ref "flag_pic") (const_int 0))
1744            (const_int 20)]
1745           (const_int 28)))])
1747 (define_insn ""
1748   [(set (pc)
1749         (if_then_else
1750          (match_operator 3 "comparison_operator"
1751                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1752                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1753          (label_ref (match_operand 0 "" ""))
1754          (pc)))]
1755   "TARGET_64BIT"
1756   "*
1758   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1759                          get_attr_length (insn), 0, insn);
1761 [(set_attr "type" "cbranch")
1762  (set (attr "length")
1763     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1764                (const_int 8184))
1765            (const_int 4)
1766            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1767                (const_int 262100))
1768            (const_int 8)
1769            (eq (symbol_ref "flag_pic") (const_int 0))
1770            (const_int 20)]
1771           (const_int 28)))])
1773 ;; Match the negated branch.
1775 (define_insn ""
1776   [(set (pc)
1777         (if_then_else
1778          (match_operator 3 "comparison_operator"
1779                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1780                           (match_operand:DI 2 "reg_or_0_operand" "rM")])
1781          (pc)
1782          (label_ref (match_operand 0 "" ""))))]
1783   "TARGET_64BIT"
1784   "*
1786   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1787                          get_attr_length (insn), 1, insn);
1789 [(set_attr "type" "cbranch")
1790  (set (attr "length")
1791     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1792                (const_int 8184))
1793            (const_int 4)
1794            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1795                (const_int 262100))
1796            (const_int 8)
1797            (eq (symbol_ref "flag_pic") (const_int 0))
1798            (const_int 20)]
1799           (const_int 28)))])
1800 (define_insn ""
1801   [(set (pc)
1802         (if_then_else
1803          (match_operator 3 "cmpib_comparison_operator"
1804                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1805                           (match_operand:DI 2 "arith5_operand" "rL")])
1806          (label_ref (match_operand 0 "" ""))
1807          (pc)))]
1808   "TARGET_64BIT"
1809   "*
1811   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1812                          get_attr_length (insn), 0, insn);
1814 [(set_attr "type" "cbranch")
1815  (set (attr "length")
1816     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1817                (const_int 8184))
1818            (const_int 4)
1819            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1820                (const_int 262100))
1821            (const_int 8)
1822            (eq (symbol_ref "flag_pic") (const_int 0))
1823            (const_int 20)]
1824           (const_int 28)))])
1826 ;; Match the negated branch.
1828 (define_insn ""
1829   [(set (pc)
1830         (if_then_else
1831          (match_operator 3 "cmpib_comparison_operator"
1832                          [(match_operand:DI 1 "reg_or_0_operand" "rM")
1833                           (match_operand:DI 2 "arith5_operand" "rL")])
1834          (pc)
1835          (label_ref (match_operand 0 "" ""))))]
1836   "TARGET_64BIT"
1837   "*
1839   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1840                          get_attr_length (insn), 1, insn);
1842 [(set_attr "type" "cbranch")
1843  (set (attr "length")
1844     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1845                (const_int 8184))
1846            (const_int 4)
1847            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1848                (const_int 262100))
1849            (const_int 8)
1850            (eq (symbol_ref "flag_pic") (const_int 0))
1851            (const_int 20)]
1852           (const_int 28)))])
1854 ;; Branch on Bit patterns.
1855 (define_insn ""
1856   [(set (pc)
1857         (if_then_else
1858          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1859                               (const_int 1)
1860                               (match_operand:SI 1 "uint5_operand" ""))
1861              (const_int 0))
1862          (label_ref (match_operand 2 "" ""))
1863          (pc)))]
1864   ""
1865   "*
1867   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1868                          get_attr_length (insn), 0, insn, 0);
1870 [(set_attr "type" "cbranch")
1871  (set (attr "length")
1872     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1873                       (const_int 8184))
1874            (const_int 4)
1875            (const_int 8)))])
1877 (define_insn ""
1878   [(set (pc)
1879         (if_then_else
1880          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1881                               (const_int 1)
1882                               (match_operand:DI 1 "uint32_operand" ""))
1883              (const_int 0))
1884          (label_ref (match_operand 2 "" ""))
1885          (pc)))]
1886   "TARGET_64BIT"
1887   "*
1889   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1890                          get_attr_length (insn), 0, insn, 0);
1892 [(set_attr "type" "cbranch")
1893  (set (attr "length")
1894     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1895                       (const_int 8184))
1896            (const_int 4)
1897            (const_int 8)))])
1899 (define_insn ""
1900   [(set (pc)
1901         (if_then_else
1902          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1903                               (const_int 1)
1904                               (match_operand:SI 1 "uint5_operand" ""))
1905              (const_int 0))
1906          (pc)
1907          (label_ref (match_operand 2 "" ""))))]
1908   ""
1909   "*
1911   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1912                          get_attr_length (insn), 1, insn, 0);
1914 [(set_attr "type" "cbranch")
1915  (set (attr "length")
1916     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1917                       (const_int 8184))
1918            (const_int 4)
1919            (const_int 8)))])
1921 (define_insn ""
1922   [(set (pc)
1923         (if_then_else
1924          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1925                               (const_int 1)
1926                               (match_operand:DI 1 "uint32_operand" ""))
1927              (const_int 0))
1928          (pc)
1929          (label_ref (match_operand 2 "" ""))))]
1930   "TARGET_64BIT"
1931   "*
1933   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1934                          get_attr_length (insn), 1, insn, 0);
1936 [(set_attr "type" "cbranch")
1937  (set (attr "length")
1938     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1939                       (const_int 8184))
1940            (const_int 4)
1941            (const_int 8)))])
1943 (define_insn ""
1944   [(set (pc)
1945         (if_then_else
1946          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1947                               (const_int 1)
1948                               (match_operand:SI 1 "uint5_operand" ""))
1949              (const_int 0))
1950          (label_ref (match_operand 2 "" ""))
1951          (pc)))]
1952   ""
1953   "*
1955   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1956                          get_attr_length (insn), 0, insn, 1);
1958 [(set_attr "type" "cbranch")
1959  (set (attr "length")
1960     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1961                       (const_int 8184))
1962            (const_int 4)
1963            (const_int 8)))])
1965 (define_insn ""
1966   [(set (pc)
1967         (if_then_else
1968          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
1969                               (const_int 1)
1970                               (match_operand:DI 1 "uint32_operand" ""))
1971              (const_int 0))
1972          (label_ref (match_operand 2 "" ""))
1973          (pc)))]
1974   "TARGET_64BIT"
1975   "*
1977   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1978                          get_attr_length (insn), 0, insn, 1);
1980 [(set_attr "type" "cbranch")
1981  (set (attr "length")
1982     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1983                       (const_int 8184))
1984            (const_int 4)
1985            (const_int 8)))])
1987 (define_insn ""
1988   [(set (pc)
1989         (if_then_else
1990          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1991                               (const_int 1)
1992                               (match_operand:SI 1 "uint5_operand" ""))
1993              (const_int 0))
1994          (pc)
1995          (label_ref (match_operand 2 "" ""))))]
1996   ""
1997   "*
1999   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
2000                          get_attr_length (insn), 1, insn, 1);
2002 [(set_attr "type" "cbranch")
2003  (set (attr "length")
2004     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2005                       (const_int 8184))
2006            (const_int 4)
2007            (const_int 8)))])
2009 (define_insn ""
2010   [(set (pc)
2011         (if_then_else
2012          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2013                               (const_int 1)
2014                               (match_operand:DI 1 "uint32_operand" ""))
2015              (const_int 0))
2016          (pc)
2017          (label_ref (match_operand 2 "" ""))))]
2018   "TARGET_64BIT"
2019   "*
2021   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
2022                          get_attr_length (insn), 1, insn, 1);
2024 [(set_attr "type" "cbranch")
2025  (set (attr "length")
2026     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2027                       (const_int 8184))
2028            (const_int 4)
2029            (const_int 8)))])
2031 ;; Branch on Variable Bit patterns.
2032 (define_insn ""
2033   [(set (pc)
2034         (if_then_else
2035          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2036                               (const_int 1)
2037                               (match_operand:SI 1 "register_operand" "q"))
2038              (const_int 0))
2039          (label_ref (match_operand 2 "" ""))
2040          (pc)))]
2041   ""
2042   "*
2044   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2045                      get_attr_length (insn), 0, insn, 0);
2047 [(set_attr "type" "cbranch")
2048  (set (attr "length")
2049     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2050                       (const_int 8184))
2051            (const_int 4)
2052            (const_int 8)))])
2054 (define_insn ""
2055   [(set (pc)
2056         (if_then_else
2057          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2058                               (const_int 1)
2059                               (match_operand:DI 1 "register_operand" "q"))
2060              (const_int 0))
2061          (label_ref (match_operand 2 "" ""))
2062          (pc)))]
2063   "TARGET_64BIT"
2064   "*
2066   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2067                      get_attr_length (insn), 0, insn, 0);
2069 [(set_attr "type" "cbranch")
2070  (set (attr "length")
2071     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2072                       (const_int 8184))
2073            (const_int 4)
2074            (const_int 8)))])
2076 (define_insn ""
2077   [(set (pc)
2078         (if_then_else
2079          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2080                               (const_int 1)
2081                               (match_operand:SI 1 "register_operand" "q"))
2082              (const_int 0))
2083          (pc)
2084          (label_ref (match_operand 2 "" ""))))]
2085   ""
2086   "*
2088   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2089                      get_attr_length (insn), 1, insn, 0);
2091 [(set_attr "type" "cbranch")
2092  (set (attr "length")
2093     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2094                       (const_int 8184))
2095            (const_int 4)
2096            (const_int 8)))])
2098 (define_insn ""
2099   [(set (pc)
2100         (if_then_else
2101          (ne (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2102                               (const_int 1)
2103                               (match_operand:DI 1 "register_operand" "q"))
2104              (const_int 0))
2105          (pc)
2106          (label_ref (match_operand 2 "" ""))))]
2107   "TARGET_64BIT"
2108   "*
2110   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2111                      get_attr_length (insn), 1, insn, 0);
2113 [(set_attr "type" "cbranch")
2114  (set (attr "length")
2115     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2116                       (const_int 8184))
2117            (const_int 4)
2118            (const_int 8)))])
2120 (define_insn ""
2121   [(set (pc)
2122         (if_then_else
2123          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2124                               (const_int 1)
2125                               (match_operand:SI 1 "register_operand" "q"))
2126              (const_int 0))
2127          (label_ref (match_operand 2 "" ""))
2128          (pc)))]
2129   ""
2130   "*
2132   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2133                      get_attr_length (insn), 0, insn, 1);
2135 [(set_attr "type" "cbranch")
2136  (set (attr "length")
2137     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2138                       (const_int 8184))
2139            (const_int 4)
2140            (const_int 8)))])
2142 (define_insn ""
2143   [(set (pc)
2144         (if_then_else
2145          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2146                               (const_int 1)
2147                               (match_operand:DI 1 "register_operand" "q"))
2148              (const_int 0))
2149          (label_ref (match_operand 2 "" ""))
2150          (pc)))]
2151   "TARGET_64BIT"
2152   "*
2154   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2155                      get_attr_length (insn), 0, insn, 1);
2157 [(set_attr "type" "cbranch")
2158  (set (attr "length")
2159     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2160                       (const_int 8184))
2161            (const_int 4)
2162            (const_int 8)))])
2164 (define_insn ""
2165   [(set (pc)
2166         (if_then_else
2167          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2168                               (const_int 1)
2169                               (match_operand:SI 1 "register_operand" "q"))
2170              (const_int 0))
2171          (pc)
2172          (label_ref (match_operand 2 "" ""))))]
2173   ""
2174   "*
2176   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2177                      get_attr_length (insn), 1, insn, 1);
2179 [(set_attr "type" "cbranch")
2180  (set (attr "length")
2181     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2182                       (const_int 8184))
2183            (const_int 4)
2184            (const_int 8)))])
2186 (define_insn ""
2187   [(set (pc)
2188         (if_then_else
2189          (eq (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2190                               (const_int 1)
2191                               (match_operand:DI 1 "register_operand" "q"))
2192              (const_int 0))
2193          (pc)
2194          (label_ref (match_operand 2 "" ""))))]
2195   "TARGET_64BIT"
2196   "*
2198   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
2199                      get_attr_length (insn), 1, insn, 1);
2201 [(set_attr "type" "cbranch")
2202  (set (attr "length")
2203     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
2204                       (const_int 8184))
2205            (const_int 4)
2206            (const_int 8)))])
2208 ;; Floating point branches
2209 (define_insn ""
2210   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2211                            (label_ref (match_operand 0 "" ""))
2212                            (pc)))]
2213   "! TARGET_SOFT_FLOAT"
2214   "*
2216   if (INSN_ANNULLED_BRANCH_P (insn))
2217     return \"ftest\;b,n %0\";
2218   else
2219     return \"ftest\;b%* %0\";
2221   [(set_attr "type" "fbranch")
2222    (set_attr "length" "8")])
2224 (define_insn ""
2225   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
2226                            (pc)
2227                            (label_ref (match_operand 0 "" ""))))]
2228   "! TARGET_SOFT_FLOAT"
2229   "*
2231   if (INSN_ANNULLED_BRANCH_P (insn))
2232     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
2233   else
2234     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
2236   [(set_attr "type" "fbranch")
2237    (set_attr "length" "12")])
2239 ;; Move instructions
2241 (define_expand "movsi"
2242   [(set (match_operand:SI 0 "general_operand" "")
2243         (match_operand:SI 1 "general_operand" ""))]
2244   ""
2245   "
2247   if (emit_move_sequence (operands, SImode, 0))
2248     DONE;
2251 ;; Reloading an SImode or DImode value requires a scratch register if
2252 ;; going in to or out of float point registers.
2254 (define_expand "reload_insi"
2255   [(set (match_operand:SI 0 "register_operand" "=Z")
2256         (match_operand:SI 1 "non_hard_reg_operand" ""))
2257    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2258   ""
2259   "
2261   if (emit_move_sequence (operands, SImode, operands[2]))
2262     DONE;
2264   /* We don't want the clobber emitted, so handle this ourselves.  */
2265   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2266   DONE;
2269 (define_expand "reload_outsi"
2270   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
2271         (match_operand:SI 1  "register_operand" "Z"))
2272    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2273   ""
2274   "
2276   if (emit_move_sequence (operands, SImode, operands[2]))
2277     DONE;
2279   /* We don't want the clobber emitted, so handle this ourselves.  */
2280   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2281   DONE;
2284 (define_insn ""
2285   [(set (match_operand:SI 0 "move_dest_operand"
2286                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
2287         (match_operand:SI 1 "move_src_operand"
2288                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
2289   "(register_operand (operands[0], SImode)
2290     || reg_or_0_operand (operands[1], SImode))
2291    && !TARGET_SOFT_FLOAT"
2292   "@
2293    ldw RT'%A1,%0
2294    copy %1,%0
2295    ldi %1,%0
2296    ldil L'%1,%0
2297    {zdepi|depwi,z} %Z1,%0
2298    ldw%M1 %1,%0
2299    stw%M0 %r1,%0
2300    mtsar %r1
2301    {mfctl|mfctl,w} %%sar,%0
2302    fcpy,sgl %f1,%0
2303    fldw%F1 %1,%0
2304    fstw%F0 %1,%0"
2305   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
2306    (set_attr "pa_combine_type" "addmove")
2307    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
2309 (define_insn ""
2310   [(set (match_operand:SI 0 "indexed_memory_operand" "=R")
2311         (match_operand:SI 1 "register_operand" "f"))]
2312   "!TARGET_SOFT_FLOAT
2313    && !TARGET_DISABLE_INDEXING
2314    && reload_completed"
2315   "fstw%F0 %1,%0"
2316   [(set_attr "type" "fpstore")
2317    (set_attr "pa_combine_type" "addmove")
2318    (set_attr "length" "4")])
2320 ; Rewrite RTL using an indexed store.  This will allow the insn that
2321 ; computes the address to be deleted if the register it sets is dead.
2322 (define_peephole2
2323   [(set (match_operand:SI 0 "register_operand" "")
2324         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
2325                           (const_int 4))
2326                  (match_operand:SI 2 "register_operand" "")))
2327    (set (mem:SI (match_dup 0))
2328         (match_operand:SI 3 "register_operand" ""))]
2329   "!TARGET_SOFT_FLOAT
2330    && !TARGET_DISABLE_INDEXING
2331    && REG_OK_FOR_BASE_P (operands[2])
2332    && FP_REGNO_P (REGNO (operands[3]))"
2333   [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2334         (match_dup 3))
2335    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2336                                (match_dup 2)))]
2337   "")
2339 (define_peephole2
2340   [(set (match_operand:SI 0 "register_operand" "")
2341         (plus:SI (match_operand:SI 2 "register_operand" "")
2342                  (mult:SI (match_operand:SI 1 "register_operand" "")
2343                           (const_int 4))))
2344    (set (mem:SI (match_dup 0))
2345         (match_operand:SI 3 "register_operand" ""))]
2346   "!TARGET_SOFT_FLOAT
2347    && !TARGET_DISABLE_INDEXING
2348    && REG_OK_FOR_BASE_P (operands[2])
2349    && FP_REGNO_P (REGNO (operands[3]))"
2350   [(set (mem:SI (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
2351         (match_dup 3))
2352    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
2353                                (match_dup 2)))]
2354   "")
2356 (define_peephole2
2357   [(set (match_operand:DI 0 "register_operand" "")
2358         (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2359                           (const_int 4))
2360                  (match_operand:DI 2 "register_operand" "")))
2361    (set (mem:SI (match_dup 0))
2362         (match_operand:SI 3 "register_operand" ""))]
2363   "!TARGET_SOFT_FLOAT
2364    && !TARGET_DISABLE_INDEXING
2365    && TARGET_64BIT
2366    && REG_OK_FOR_BASE_P (operands[2])
2367    && FP_REGNO_P (REGNO (operands[3]))"
2368   [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2369         (match_dup 3))
2370    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2371                                (match_dup 2)))]
2372   "")
2374 (define_peephole2
2375   [(set (match_operand:DI 0 "register_operand" "")
2376         (plus:DI (match_operand:DI 2 "register_operand" "")
2377                  (mult:DI (match_operand:DI 1 "register_operand" "")
2378                           (const_int 4))))
2379    (set (mem:SI (match_dup 0))
2380         (match_operand:SI 3 "register_operand" ""))]
2381   "!TARGET_SOFT_FLOAT
2382    && !TARGET_DISABLE_INDEXING
2383    && TARGET_64BIT
2384    && REG_OK_FOR_BASE_P (operands[2])
2385    && FP_REGNO_P (REGNO (operands[3]))"
2386   [(set (mem:SI (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
2387         (match_dup 3))
2388    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
2389                                (match_dup 2)))]
2390   "")
2392 (define_peephole2
2393   [(set (match_operand:SI 0 "register_operand" "")
2394         (plus:SI (match_operand:SI 1 "register_operand" "")
2395                  (match_operand:SI 2 "register_operand" "")))
2396    (set (mem:SI (match_dup 0))
2397         (match_operand:SI 3 "register_operand" ""))]
2398   "!TARGET_SOFT_FLOAT
2399    && !TARGET_DISABLE_INDEXING
2400    && REG_OK_FOR_BASE_P (operands[1])
2401    && (TARGET_NO_SPACE_REGS
2402        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
2403    && FP_REGNO_P (REGNO (operands[3]))"
2404   [(set (mem:SI (plus:SI (match_dup 1) (match_dup 2)))
2405         (match_dup 3))
2406    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2407   "")
2409 (define_peephole2
2410   [(set (match_operand:SI 0 "register_operand" "")
2411         (plus:SI (match_operand:SI 1 "register_operand" "")
2412                  (match_operand:SI 2 "register_operand" "")))
2413    (set (mem:SI (match_dup 0))
2414         (match_operand:SI 3 "register_operand" ""))]
2415   "!TARGET_SOFT_FLOAT
2416    && !TARGET_DISABLE_INDEXING
2417    && REG_OK_FOR_BASE_P (operands[2])
2418    && (TARGET_NO_SPACE_REGS
2419        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
2420    && FP_REGNO_P (REGNO (operands[3]))"
2421   [(set (mem:SI (plus:SI (match_dup 2) (match_dup 1)))
2422         (match_dup 3))
2423    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
2424   "")
2426 (define_peephole2
2427   [(set (match_operand:DI 0 "register_operand" "")
2428         (plus:DI (match_operand:DI 1 "register_operand" "")
2429                  (match_operand:DI 2 "register_operand" "")))
2430    (set (mem:SI (match_dup 0))
2431         (match_operand:SI 3 "register_operand" ""))]
2432   "!TARGET_SOFT_FLOAT
2433    && !TARGET_DISABLE_INDEXING
2434    && TARGET_64BIT
2435    && REG_OK_FOR_BASE_P (operands[1])
2436    && (TARGET_NO_SPACE_REGS
2437        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
2438    && FP_REGNO_P (REGNO (operands[3]))"
2439   [(set (mem:SI (plus:DI (match_dup 1) (match_dup 2)))
2440         (match_dup 3))
2441    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2442   "")
2444 (define_peephole2
2445   [(set (match_operand:DI 0 "register_operand" "")
2446         (plus:DI (match_operand:DI 1 "register_operand" "")
2447                  (match_operand:DI 2 "register_operand" "")))
2448    (set (mem:SI (match_dup 0))
2449         (match_operand:SI 3 "register_operand" ""))]
2450   "!TARGET_SOFT_FLOAT
2451    && !TARGET_DISABLE_INDEXING
2452    && TARGET_64BIT
2453    && REG_OK_FOR_BASE_P (operands[2])
2454    && (TARGET_NO_SPACE_REGS
2455        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
2456    && FP_REGNO_P (REGNO (operands[3]))"
2457   [(set (mem:SI (plus:DI (match_dup 2) (match_dup 1)))
2458         (match_dup 3))
2459    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
2460   "")
2462 (define_insn ""
2463   [(set (match_operand:SI 0 "move_dest_operand"
2464                           "=r,r,r,r,r,r,Q,!*q,!r")
2465         (match_operand:SI 1 "move_src_operand"
2466                           "A,r,J,N,K,RQ,rM,!rM,!*q"))]
2467   "(register_operand (operands[0], SImode)
2468     || reg_or_0_operand (operands[1], SImode))
2469    && TARGET_SOFT_FLOAT"
2470   "@
2471    ldw RT'%A1,%0
2472    copy %1,%0
2473    ldi %1,%0
2474    ldil L'%1,%0
2475    {zdepi|depwi,z} %Z1,%0
2476    ldw%M1 %1,%0
2477    stw%M0 %r1,%0
2478    mtsar %r1
2479    {mfctl|mfctl,w} %%sar,%0"
2480   [(set_attr "type" "load,move,move,move,move,load,store,move,move")
2481    (set_attr "pa_combine_type" "addmove")
2482    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2484 ;; Load or store with base-register modification.
2485 (define_insn ""
2486   [(set (match_operand:SI 0 "register_operand" "=r")
2487         (mem:SI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2488                          (match_operand:DI 2 "int5_operand" "L"))))
2489    (set (match_dup 1)
2490         (plus:DI (match_dup 1) (match_dup 2)))]
2491   "TARGET_64BIT"
2492   "ldw,mb %2(%1),%0"
2493   [(set_attr "type" "load")
2494    (set_attr "length" "4")])
2496 ; And a zero extended variant.
2497 (define_insn ""
2498   [(set (match_operand:DI 0 "register_operand" "=r")
2499         (zero_extend:DI (mem:SI
2500                           (plus:DI
2501                             (match_operand:DI 1 "register_operand" "+r")
2502                             (match_operand:DI 2 "int5_operand" "L")))))
2503    (set (match_dup 1)
2504         (plus:DI (match_dup 1) (match_dup 2)))]
2505   "TARGET_64BIT"
2506   "ldw,mb %2(%1),%0"
2507   [(set_attr "type" "load")
2508    (set_attr "length" "4")])
2510 (define_expand "pre_load"
2511   [(parallel [(set (match_operand:SI 0 "register_operand" "")
2512               (mem (plus (match_operand 1 "register_operand" "")
2513                                (match_operand 2 "pre_cint_operand" ""))))
2514               (set (match_dup 1)
2515                    (plus (match_dup 1) (match_dup 2)))])]
2516   ""
2517   "
2519   if (TARGET_64BIT)
2520     {
2521       emit_insn (gen_pre_ldd (operands[0], operands[1], operands[2]));
2522       DONE;
2523     }
2524   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
2525   DONE;
2528 (define_insn "pre_ldw"
2529   [(set (match_operand:SI 0 "register_operand" "=r")
2530         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2531                          (match_operand:SI 2 "pre_cint_operand" ""))))
2532    (set (match_dup 1)
2533         (plus:SI (match_dup 1) (match_dup 2)))]
2534   ""
2535   "*
2537   if (INTVAL (operands[2]) < 0)
2538     return \"{ldwm|ldw,mb} %2(%1),%0\";
2539   return \"{ldws|ldw},mb %2(%1),%0\";
2541   [(set_attr "type" "load")
2542    (set_attr "length" "4")])
2544 (define_insn "pre_ldd"
2545   [(set (match_operand:DI 0 "register_operand" "=r")
2546         (mem:DI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2547                          (match_operand:DI 2 "pre_cint_operand" ""))))
2548    (set (match_dup 1)
2549         (plus:DI (match_dup 1) (match_dup 2)))]
2550   "TARGET_64BIT"
2551   "ldd,mb %2(%1),%0"
2552   [(set_attr "type" "load")
2553    (set_attr "length" "4")])
2555 (define_insn ""
2556   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2557                          (match_operand:SI 1 "pre_cint_operand" "")))
2558         (match_operand:SI 2 "reg_or_0_operand" "rM"))
2559    (set (match_dup 0)
2560         (plus:SI (match_dup 0) (match_dup 1)))]
2561   ""
2562   "*
2564   if (INTVAL (operands[1]) < 0)
2565     return \"{stwm|stw,mb} %r2,%1(%0)\";
2566   return \"{stws|stw},mb %r2,%1(%0)\";
2568   [(set_attr "type" "store")
2569    (set_attr "length" "4")])
2571 (define_insn ""
2572   [(set (match_operand:SI 0 "register_operand" "=r")
2573         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
2574    (set (match_dup 1)
2575         (plus:SI (match_dup 1)
2576                  (match_operand:SI 2 "post_cint_operand" "")))]
2577   ""
2578   "*
2580   if (INTVAL (operands[2]) > 0)
2581     return \"{ldwm|ldw,ma} %2(%1),%0\";
2582   return \"{ldws|ldw},ma %2(%1),%0\";
2584   [(set_attr "type" "load")
2585    (set_attr "length" "4")])
2587 (define_expand "post_store"
2588   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
2589                    (match_operand 1 "reg_or_0_operand" ""))
2590               (set (match_dup 0)
2591                    (plus (match_dup 0)
2592                          (match_operand 2 "post_cint_operand" "")))])]
2593   ""
2594   "
2596   if (TARGET_64BIT)
2597     {
2598       emit_insn (gen_post_std (operands[0], operands[1], operands[2]));
2599       DONE;
2600     }
2601   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
2602   DONE;
2605 (define_insn "post_stw"
2606   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
2607         (match_operand:SI 1 "reg_or_0_operand" "rM"))
2608    (set (match_dup 0)
2609         (plus:SI (match_dup 0)
2610                  (match_operand:SI 2 "post_cint_operand" "")))]
2611   ""
2612   "*
2614   if (INTVAL (operands[2]) > 0)
2615     return \"{stwm|stw,ma} %r1,%2(%0)\";
2616   return \"{stws|stw},ma %r1,%2(%0)\";
2618   [(set_attr "type" "store")
2619    (set_attr "length" "4")])
2621 (define_insn "post_std"
2622   [(set (mem:DI (match_operand:DI 0 "register_operand" "+r"))
2623         (match_operand:DI 1 "reg_or_0_operand" "rM"))
2624    (set (match_dup 0)
2625         (plus:DI (match_dup 0)
2626                  (match_operand:DI 2 "post_cint_operand" "")))]
2627   "TARGET_64BIT"
2628   "std,ma %r1,%2(%0)"
2629   [(set_attr "type" "store")
2630    (set_attr "length" "4")])
2632 ;; For loading the address of a label while generating PIC code.
2633 ;; Note since this pattern can be created at reload time (via movsi), all
2634 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
2635 (define_insn ""
2636   [(set (match_operand 0 "pmode_register_operand" "=a")
2637         (match_operand 1 "pic_label_operand" ""))]
2638   "TARGET_PA_20"
2639   "*
2641   rtx xoperands[3];
2643   xoperands[0] = operands[0];
2644   xoperands[1] = operands[1];
2645   xoperands[2] = gen_label_rtx ();
2647   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2648                                      CODE_LABEL_NUMBER (xoperands[2]));
2649   output_asm_insn (\"mfia %0\", xoperands);
2651   /* If we're trying to load the address of a label that happens to be
2652      close, then we can use a shorter sequence.  */
2653   if (GET_CODE (operands[1]) == LABEL_REF
2654       && !LABEL_REF_NONLOCAL_P (operands[1])
2655       && INSN_ADDRESSES_SET_P ()
2656       && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2657                 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2658     output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2659   else
2660     {
2661       output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2662       output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2663     }
2664   return \"\";
2666   [(set_attr "type" "multi")
2667    (set_attr "length" "12")])           ; 8 or 12
2669 (define_insn ""
2670   [(set (match_operand 0 "pmode_register_operand" "=a")
2671         (match_operand 1 "pic_label_operand" ""))]
2672   "!TARGET_PA_20"
2673   "*
2675   rtx xoperands[3];
2677   xoperands[0] = operands[0];
2678   xoperands[1] = operands[1];
2679   xoperands[2] = gen_label_rtx ();
2681   output_asm_insn (\"bl .+8,%0\", xoperands);
2682   output_asm_insn (\"depi 0,31,2,%0\", xoperands);
2683   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
2684                                      CODE_LABEL_NUMBER (xoperands[2]));
2686   /* If we're trying to load the address of a label that happens to be
2687      close, then we can use a shorter sequence.  */
2688   if (GET_CODE (operands[1]) == LABEL_REF
2689       && !LABEL_REF_NONLOCAL_P (operands[1])
2690       && INSN_ADDRESSES_SET_P ()
2691       && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
2692                 - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
2693     output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
2694   else
2695     {
2696       output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
2697       output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
2698     }
2699   return \"\";
2701   [(set_attr "type" "multi")
2702    (set_attr "length" "16")])           ; 12 or 16
2704 (define_insn ""
2705   [(set (match_operand:SI 0 "register_operand" "=a")
2706         (plus:SI (match_operand:SI 1 "register_operand" "r")
2707                  (high:SI (match_operand 2 "" ""))))]
2708   "symbolic_operand (operands[2], Pmode)
2709    && ! function_label_operand (operands[2], Pmode)
2710    && flag_pic"
2711   "addil LT'%G2,%1"
2712   [(set_attr "type" "binary")
2713    (set_attr "length" "4")])
2715 (define_insn ""
2716   [(set (match_operand:DI 0 "register_operand" "=a")
2717         (plus:DI (match_operand:DI 1 "register_operand" "r")
2718                  (high:DI (match_operand 2 "" ""))))]
2719   "symbolic_operand (operands[2], Pmode)
2720    && ! function_label_operand (operands[2], Pmode)
2721    && TARGET_64BIT
2722    && flag_pic"
2723   "addil LT'%G2,%1"
2724   [(set_attr "type" "binary")
2725    (set_attr "length" "4")])
2727 ;; Always use addil rather than ldil;add sequences.  This allows the
2728 ;; HP linker to eliminate the dp relocation if the symbolic operand
2729 ;; lives in the TEXT space.
2730 (define_insn ""
2731   [(set (match_operand:SI 0 "register_operand" "=a")
2732         (high:SI (match_operand 1 "" "")))]
2733   "symbolic_operand (operands[1], Pmode)
2734    && ! function_label_operand (operands[1], Pmode)
2735    && ! read_only_operand (operands[1], Pmode)
2736    && ! flag_pic"
2737   "*
2739   if (TARGET_LONG_LOAD_STORE)
2740     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
2741   else
2742     return \"addil LR'%H1,%%r27\";
2744   [(set_attr "type" "binary")
2745    (set (attr "length")
2746       (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
2747                     (const_int 4)
2748                     (const_int 8)))])
2751 ;; This is for use in the prologue/epilogue code.  We need it
2752 ;; to add large constants to a stack pointer or frame pointer.
2753 ;; Because of the additional %r1 pressure, we probably do not
2754 ;; want to use this in general code, so make it available
2755 ;; only after reload.
2756 (define_insn ""
2757   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
2758         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
2759                  (high:SI (match_operand 2 "const_int_operand" ""))))]
2760   "reload_completed"
2761   "@
2762    addil L'%G2,%1
2763    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2764   [(set_attr "type" "binary,binary")
2765    (set_attr "length" "4,8")])
2767 (define_insn ""
2768   [(set (match_operand:DI 0 "register_operand" "=!a,*r")
2769         (plus:DI (match_operand:DI 1 "register_operand" "r,r")
2770                  (high:DI (match_operand 2 "const_int_operand" ""))))]
2771   "reload_completed && TARGET_64BIT"
2772   "@
2773    addil L'%G2,%1
2774    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
2775   [(set_attr "type" "binary,binary")
2776    (set_attr "length" "4,8")])
2778 (define_insn ""
2779   [(set (match_operand:SI 0 "register_operand" "=r")
2780         (high:SI (match_operand 1 "" "")))]
2781   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
2782     && !is_function_label_plus_const (operands[1])"
2783   "*
2785   if (symbolic_operand (operands[1], Pmode))
2786     return \"ldil LR'%H1,%0\";
2787   else
2788     return \"ldil L'%G1,%0\";
2790   [(set_attr "type" "move")
2791    (set_attr "length" "4")])
2793 (define_insn ""
2794   [(set (match_operand:DI 0 "register_operand" "=r")
2795         (high:DI (match_operand 1 "const_int_operand" "")))]
2796   "TARGET_64BIT"
2797   "ldil L'%G1,%0";
2798   [(set_attr "type" "move")
2799    (set_attr "length" "4")])
2801 (define_insn ""
2802   [(set (match_operand:DI 0 "register_operand" "=r")
2803         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2804                    (match_operand:DI 2 "const_int_operand" "i")))]
2805   "TARGET_64BIT"
2806   "ldo R'%G2(%1),%0";
2807   [(set_attr "type" "move")
2808    (set_attr "length" "4")])
2810 (define_insn ""
2811   [(set (match_operand:SI 0 "register_operand" "=r")
2812         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2813                    (match_operand:SI 2 "immediate_operand" "i")))]
2814   "!is_function_label_plus_const (operands[2])"
2815   "*
2817   if (flag_pic && symbolic_operand (operands[2], Pmode))
2818     abort ();
2819   else if (symbolic_operand (operands[2], Pmode))
2820     return \"ldo RR'%G2(%1),%0\";
2821   else
2822     return \"ldo R'%G2(%1),%0\";
2824   [(set_attr "type" "move")
2825    (set_attr "length" "4")])
2827 ;; Now that a symbolic_address plus a constant is broken up early
2828 ;; in the compilation phase (for better CSE) we need a special
2829 ;; combiner pattern to load the symbolic address plus the constant
2830 ;; in only 2 instructions. (For cases where the symbolic address
2831 ;; was not a common subexpression.)
2832 (define_split
2833   [(set (match_operand:SI 0 "register_operand" "")
2834         (match_operand:SI 1 "symbolic_operand" ""))
2835    (clobber (match_operand:SI 2 "register_operand" ""))]
2836   "! (flag_pic && pic_label_operand (operands[1], SImode))"
2837   [(set (match_dup 2) (high:SI (match_dup 1)))
2838    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
2839   "")
2841 ;; hppa_legitimize_address goes to a great deal of trouble to
2842 ;; create addresses which use indexing.  In some cases, this
2843 ;; is a lose because there isn't any store instructions which
2844 ;; allow indexed addresses (with integer register source).
2846 ;; These define_splits try to turn a 3 insn store into
2847 ;; a 2 insn store with some creative RTL rewriting.
2848 (define_split
2849   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2850                                (match_operand:SI 1 "shadd_operand" ""))
2851                    (plus:SI (match_operand:SI 2 "register_operand" "")
2852                             (match_operand:SI 3 "const_int_operand" ""))))
2853         (match_operand:SI 4 "register_operand" ""))
2854    (clobber (match_operand:SI 5 "register_operand" ""))]
2855   ""
2856   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2857                                (match_dup 2)))
2858    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2859   "")
2861 (define_split
2862   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2863                                (match_operand:SI 1 "shadd_operand" ""))
2864                    (plus:SI (match_operand:SI 2 "register_operand" "")
2865                             (match_operand:SI 3 "const_int_operand" ""))))
2866         (match_operand:HI 4 "register_operand" ""))
2867    (clobber (match_operand:SI 5 "register_operand" ""))]
2868   ""
2869   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2870                                (match_dup 2)))
2871    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2872   "")
2874 (define_split
2875   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
2876                                (match_operand:SI 1 "shadd_operand" ""))
2877                    (plus:SI (match_operand:SI 2 "register_operand" "")
2878                             (match_operand:SI 3 "const_int_operand" ""))))
2879         (match_operand:QI 4 "register_operand" ""))
2880    (clobber (match_operand:SI 5 "register_operand" ""))]
2881   ""
2882   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
2883                                (match_dup 2)))
2884    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
2885   "")
2887 (define_expand "movhi"
2888   [(set (match_operand:HI 0 "general_operand" "")
2889         (match_operand:HI 1 "general_operand" ""))]
2890   ""
2891   "
2893   if (emit_move_sequence (operands, HImode, 0))
2894     DONE;
2897 (define_insn ""
2898   [(set (match_operand:HI 0 "move_dest_operand"
2899                           "=r,r,r,r,r,Q,!*q,!r,!*f")
2900         (match_operand:HI 1 "move_src_operand"
2901                           "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
2902   "register_operand (operands[0], HImode)
2903    || reg_or_0_operand (operands[1], HImode)"
2904   "@
2905    copy %1,%0
2906    ldi %1,%0
2907    ldil L'%1,%0
2908    {zdepi|depwi,z} %Z1,%0
2909    ldh%M1 %1,%0
2910    sth%M0 %r1,%0
2911    mtsar %r1
2912    {mfctl|mfctl,w} %sar,%0
2913    fcpy,sgl %f1,%0"
2914   [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
2915    (set_attr "pa_combine_type" "addmove")
2916    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
2918 (define_insn ""
2919   [(set (match_operand:HI 0 "register_operand" "=r")
2920         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2921                          (match_operand:SI 2 "int5_operand" "L"))))
2922    (set (match_dup 1)
2923         (plus:SI (match_dup 1) (match_dup 2)))]
2924   ""
2925   "{ldhs|ldh},mb %2(%1),%0"
2926   [(set_attr "type" "load")
2927    (set_attr "length" "4")])
2929 (define_insn ""
2930   [(set (match_operand:HI 0 "register_operand" "=r")
2931         (mem:HI (plus:DI (match_operand:DI 1 "register_operand" "+r")
2932                          (match_operand:DI 2 "int5_operand" "L"))))
2933    (set (match_dup 1)
2934         (plus:DI (match_dup 1) (match_dup 2)))]
2935   "TARGET_64BIT"
2936   "ldh,mb %2(%1),%0"
2937   [(set_attr "type" "load")
2938    (set_attr "length" "4")])
2940 ; And a zero extended variant.
2941 (define_insn ""
2942   [(set (match_operand:DI 0 "register_operand" "=r")
2943         (zero_extend:DI (mem:HI
2944                           (plus:DI
2945                             (match_operand:DI 1 "register_operand" "+r")
2946                             (match_operand:DI 2 "int5_operand" "L")))))
2947    (set (match_dup 1)
2948         (plus:DI (match_dup 1) (match_dup 2)))]
2949   "TARGET_64BIT"
2950   "ldh,mb %2(%1),%0"
2951   [(set_attr "type" "load")
2952    (set_attr "length" "4")])
2954 (define_insn ""
2955   [(set (match_operand:SI 0 "register_operand" "=r")
2956         (zero_extend:SI (mem:HI
2957                           (plus:SI
2958                             (match_operand:SI 1 "register_operand" "+r")
2959                             (match_operand:SI 2 "int5_operand" "L")))))
2960    (set (match_dup 1)
2961         (plus:SI (match_dup 1) (match_dup 2)))]
2962   ""
2963   "{ldhs|ldh},mb %2(%1),%0"
2964   [(set_attr "type" "load")
2965    (set_attr "length" "4")])
2967 (define_insn ""
2968   [(set (match_operand:SI 0 "register_operand" "=r")
2969         (zero_extend:SI (mem:HI
2970                           (plus:DI
2971                             (match_operand:DI 1 "register_operand" "+r")
2972                             (match_operand:DI 2 "int5_operand" "L")))))
2973    (set (match_dup 1)
2974         (plus:DI (match_dup 1) (match_dup 2)))]
2975   "TARGET_64BIT"
2976   "ldh,mb %2(%1),%0"
2977   [(set_attr "type" "load")
2978    (set_attr "length" "4")])
2980 (define_insn ""
2981   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2982                          (match_operand:SI 1 "int5_operand" "L")))
2983         (match_operand:HI 2 "reg_or_0_operand" "rM"))
2984    (set (match_dup 0)
2985         (plus:SI (match_dup 0) (match_dup 1)))]
2986   ""
2987   "{sths|sth},mb %r2,%1(%0)"
2988   [(set_attr "type" "store")
2989    (set_attr "length" "4")])
2991 (define_insn ""
2992   [(set (mem:HI (plus:DI (match_operand:DI 0 "register_operand" "+r")
2993                          (match_operand:DI 1 "int5_operand" "L")))
2994         (match_operand:HI 2 "reg_or_0_operand" "rM"))
2995    (set (match_dup 0)
2996         (plus:DI (match_dup 0) (match_dup 1)))]
2997   "TARGET_64BIT"
2998   "sth,mb %r2,%1(%0)"
2999   [(set_attr "type" "store")
3000    (set_attr "length" "4")])
3002 (define_insn ""
3003   [(set (match_operand:HI 0 "register_operand" "=r")
3004         (plus:HI (match_operand:HI 1 "register_operand" "r")
3005                  (match_operand 2 "const_int_operand" "J")))]
3006   ""
3007   "ldo %2(%1),%0"
3008   [(set_attr "type" "binary")
3009    (set_attr "pa_combine_type" "addmove")
3010    (set_attr "length" "4")])
3012 (define_expand "movqi"
3013   [(set (match_operand:QI 0 "general_operand" "")
3014         (match_operand:QI 1 "general_operand" ""))]
3015   ""
3016   "
3018   if (emit_move_sequence (operands, QImode, 0))
3019     DONE;
3022 (define_insn ""
3023   [(set (match_operand:QI 0 "move_dest_operand"
3024                           "=r,r,r,r,r,Q,!*q,!r,!*f")
3025         (match_operand:QI 1 "move_src_operand"
3026                           "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
3027   "register_operand (operands[0], QImode)
3028    || reg_or_0_operand (operands[1], QImode)"
3029   "@
3030    copy %1,%0
3031    ldi %1,%0
3032    ldil L'%1,%0
3033    {zdepi|depwi,z} %Z1,%0
3034    ldb%M1 %1,%0
3035    stb%M0 %r1,%0
3036    mtsar %r1
3037    {mfctl|mfctl,w} %%sar,%0
3038    fcpy,sgl %f1,%0"
3039   [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
3040    (set_attr "pa_combine_type" "addmove")
3041    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
3043 (define_insn ""
3044   [(set (match_operand:QI 0 "register_operand" "=r")
3045         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
3046                          (match_operand:SI 2 "int5_operand" "L"))))
3047    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3048   ""
3049   "{ldbs|ldb},mb %2(%1),%0"
3050   [(set_attr "type" "load")
3051    (set_attr "length" "4")])
3053 (define_insn ""
3054   [(set (match_operand:QI 0 "register_operand" "=r")
3055         (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "+r")
3056                          (match_operand:DI 2 "int5_operand" "L"))))
3057    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3058   "TARGET_64BIT"
3059   "ldb,mb %2(%1),%0"
3060   [(set_attr "type" "load")
3061    (set_attr "length" "4")])
3063 ; Now the same thing with zero extensions.
3064 (define_insn ""
3065   [(set (match_operand:DI 0 "register_operand" "=r")
3066         (zero_extend:DI (mem:QI (plus:DI
3067                                   (match_operand:DI 1 "register_operand" "+r")
3068                                   (match_operand:DI 2 "int5_operand" "L")))))
3069    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3070   "TARGET_64BIT"
3071   "ldb,mb %2(%1),%0"
3072   [(set_attr "type" "load")
3073    (set_attr "length" "4")])
3075 (define_insn ""
3076   [(set (match_operand:SI 0 "register_operand" "=r")
3077         (zero_extend:SI (mem:QI (plus:SI
3078                                   (match_operand:SI 1 "register_operand" "+r")
3079                                   (match_operand:SI 2 "int5_operand" "L")))))
3080    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3081   ""
3082   "{ldbs|ldb},mb %2(%1),%0"
3083   [(set_attr "type" "load")
3084    (set_attr "length" "4")])
3086 (define_insn ""
3087   [(set (match_operand:SI 0 "register_operand" "=r")
3088         (zero_extend:SI (mem:QI (plus:DI
3089                                   (match_operand:DI 1 "register_operand" "+r")
3090                                   (match_operand:DI 2 "int5_operand" "L")))))
3091    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3092   "TARGET_64BIT"
3093   "ldb,mb %2(%1),%0"
3094   [(set_attr "type" "load")
3095    (set_attr "length" "4")])
3097 (define_insn ""
3098   [(set (match_operand:HI 0 "register_operand" "=r")
3099         (zero_extend:HI (mem:QI (plus:SI
3100                                   (match_operand:SI 1 "register_operand" "+r")
3101                                   (match_operand:SI 2 "int5_operand" "L")))))
3102    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
3103   ""
3104   "{ldbs|ldb},mb %2(%1),%0"
3105   [(set_attr "type" "load")
3106    (set_attr "length" "4")])
3108 (define_insn ""
3109   [(set (match_operand:HI 0 "register_operand" "=r")
3110         (zero_extend:HI (mem:QI (plus:DI
3111                                   (match_operand:DI 1 "register_operand" "+r")
3112                                   (match_operand:DI 2 "int5_operand" "L")))))
3113    (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 2)))]
3114   "TARGET_64BIT"
3115   "ldb,mb %2(%1),%0"
3116   [(set_attr "type" "load")
3117    (set_attr "length" "4")])
3119 (define_insn ""
3120   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
3121                          (match_operand:SI 1 "int5_operand" "L")))
3122         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3123    (set (match_dup 0)
3124         (plus:SI (match_dup 0) (match_dup 1)))]
3125   ""
3126   "{stbs|stb},mb %r2,%1(%0)"
3127   [(set_attr "type" "store")
3128    (set_attr "length" "4")])
3130 (define_insn ""
3131   [(set (mem:QI (plus:DI (match_operand:DI 0 "register_operand" "+r")
3132                          (match_operand:DI 1 "int5_operand" "L")))
3133         (match_operand:QI 2 "reg_or_0_operand" "rM"))
3134    (set (match_dup 0)
3135         (plus:DI (match_dup 0) (match_dup 1)))]
3136   "TARGET_64BIT"
3137   "stb,mb %r2,%1(%0)"
3138   [(set_attr "type" "store")
3139    (set_attr "length" "4")])
3141 ;; The definition of this insn does not really explain what it does,
3142 ;; but it should suffice that anything generated as this insn will be
3143 ;; recognized as a movmemsi operation, and that it will not successfully
3144 ;; combine with anything.
3145 (define_expand "movmemsi"
3146   [(parallel [(set (match_operand:BLK 0 "" "")
3147                    (match_operand:BLK 1 "" ""))
3148               (clobber (match_dup 4))
3149               (clobber (match_dup 5))
3150               (clobber (match_dup 6))
3151               (clobber (match_dup 7))
3152               (clobber (match_dup 8))
3153               (use (match_operand:SI 2 "arith_operand" ""))
3154               (use (match_operand:SI 3 "const_int_operand" ""))])]
3155   "!TARGET_64BIT && optimize > 0"
3156   "
3158   int size, align;
3160   /* HP provides very fast block move library routine for the PA;
3161      this routine includes:
3163         4x4 byte at a time block moves,
3164         1x4 byte at a time with alignment checked at runtime with
3165             attempts to align the source and destination as needed
3166         1x1 byte loop
3168      With that in mind, here's the heuristics to try and guess when
3169      the inlined block move will be better than the library block
3170      move:
3172         If the size isn't constant, then always use the library routines.
3174         If the size is large in respect to the known alignment, then use
3175         the library routines.
3177         If the size is small in respect to the known alignment, then open
3178         code the copy (since that will lead to better scheduling).
3180         Else use the block move pattern.   */
3182   /* Undetermined size, use the library routine.  */
3183   if (GET_CODE (operands[2]) != CONST_INT)
3184     FAIL;
3186   size = INTVAL (operands[2]);
3187   align = INTVAL (operands[3]);
3188   align = align > 4 ? 4 : align;
3190   /* If size/alignment is large, then use the library routines.  */
3191   if (size / align > 16)
3192     FAIL;
3194   /* This does happen, but not often enough to worry much about.  */
3195   if (size / align < MOVE_RATIO)
3196     FAIL;
3197   
3198   /* Fall through means we're going to use our block move pattern.  */
3199   operands[0]
3200     = replace_equiv_address (operands[0],
3201                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3202   operands[1]
3203     = replace_equiv_address (operands[1],
3204                              copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
3205   operands[4] = gen_reg_rtx (SImode);
3206   operands[5] = gen_reg_rtx (SImode);
3207   operands[6] = gen_reg_rtx (SImode);
3208   operands[7] = gen_reg_rtx (SImode);
3209   operands[8] = gen_reg_rtx (SImode);
3212 ;; The operand constraints are written like this to support both compile-time
3213 ;; and run-time determined byte counts.  The expander and output_block_move
3214 ;; only support compile-time determined counts at this time.
3216 ;; If the count is run-time determined, the register with the byte count
3217 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3219 ;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3220 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3221 ;; as this requires two registers in the class R1_REGS when the MEMs for
3222 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3223 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3224 ;; respectively.  We then split or peephole optimize after reload.
3225 (define_insn "movmemsi_prereload"
3226   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3227         (mem:BLK (match_operand:SI 1 "register_operand" "r,r")))
3228    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3229    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3230    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3231    (clobber (match_operand:SI 7 "register_operand" "=&r,&r"))   ;item tmp3
3232    (clobber (match_operand:SI 8 "register_operand" "=&r,&r"))   ;item tmp4
3233    (use (match_operand:SI 4 "arith_operand" "J,2"))      ;byte count
3234    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
3235   "!TARGET_64BIT"
3236   "#"
3237   [(set_attr "type" "multi,multi")])
3239 (define_split
3240   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3241                    (match_operand:BLK 1 "memory_operand" ""))
3242               (clobber (match_operand:SI 2 "register_operand" ""))
3243               (clobber (match_operand:SI 3 "register_operand" ""))
3244               (clobber (match_operand:SI 6 "register_operand" ""))
3245               (clobber (match_operand:SI 7 "register_operand" ""))
3246               (clobber (match_operand:SI 8 "register_operand" ""))
3247               (use (match_operand:SI 4 "arith_operand" ""))
3248               (use (match_operand:SI 5 "const_int_operand" ""))])]
3249   "!TARGET_64BIT && reload_completed && !flag_peephole2
3250    && GET_CODE (operands[0]) == MEM
3251    && register_operand (XEXP (operands[0], 0), SImode)
3252    && GET_CODE (operands[1]) == MEM
3253    && register_operand (XEXP (operands[1], 0), SImode)"
3254   [(set (match_dup 7) (match_dup 9))
3255    (set (match_dup 8) (match_dup 10))
3256    (parallel [(set (match_dup 0) (match_dup 1))
3257               (clobber (match_dup 2))
3258               (clobber (match_dup 3))
3259               (clobber (match_dup 6))
3260               (clobber (match_dup 7))
3261               (clobber (match_dup 8))
3262               (use (match_dup 4))
3263               (use (match_dup 5))
3264               (const_int 0)])]
3265   "
3267   operands[9] = XEXP (operands[0], 0);
3268   operands[10] = XEXP (operands[1], 0);
3269   operands[0] = replace_equiv_address (operands[0], operands[7]);
3270   operands[1] = replace_equiv_address (operands[1], operands[8]);
3273 (define_peephole2
3274   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3275                    (match_operand:BLK 1 "memory_operand" ""))
3276               (clobber (match_operand:SI 2 "register_operand" ""))
3277               (clobber (match_operand:SI 3 "register_operand" ""))
3278               (clobber (match_operand:SI 6 "register_operand" ""))
3279               (clobber (match_operand:SI 7 "register_operand" ""))
3280               (clobber (match_operand:SI 8 "register_operand" ""))
3281               (use (match_operand:SI 4 "arith_operand" ""))
3282               (use (match_operand:SI 5 "const_int_operand" ""))])]
3283   "!TARGET_64BIT
3284    && GET_CODE (operands[0]) == MEM
3285    && register_operand (XEXP (operands[0], 0), SImode)
3286    && GET_CODE (operands[1]) == MEM
3287    && register_operand (XEXP (operands[1], 0), SImode)"
3288   [(parallel [(set (match_dup 0) (match_dup 1))
3289               (clobber (match_dup 2))
3290               (clobber (match_dup 3))
3291               (clobber (match_dup 6))
3292               (clobber (match_dup 7))
3293               (clobber (match_dup 8))
3294               (use (match_dup 4))
3295               (use (match_dup 5))
3296               (const_int 0)])]
3297   "
3299   rtx addr = XEXP (operands[0], 0);
3300   if (dead_or_set_p (curr_insn, addr))
3301     operands[7] = addr;
3302   else
3303     {
3304       emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3305       operands[0] = replace_equiv_address (operands[0], operands[7]);
3306     }
3308   addr = XEXP (operands[1], 0);
3309   if (dead_or_set_p (curr_insn, addr))
3310     operands[8] = addr;
3311   else
3312     {
3313       emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3314       operands[1] = replace_equiv_address (operands[1], operands[8]);
3315     }
3318 (define_insn "movmemsi_postreload"
3319   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3320         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
3321    (clobber (match_operand:SI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3322    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp1
3323    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
3324    (clobber (match_dup 0))
3325    (clobber (match_dup 1))
3326    (use (match_operand:SI 4 "arith_operand" "J,2"))      ;byte count
3327    (use (match_operand:SI 5 "const_int_operand" "n,n"))  ;alignment
3328    (const_int 0)]
3329   "!TARGET_64BIT && reload_completed"
3330   "* return output_block_move (operands, !which_alternative);"
3331   [(set_attr "type" "multi,multi")])
3333 (define_expand "movmemdi"
3334   [(parallel [(set (match_operand:BLK 0 "" "")
3335                    (match_operand:BLK 1 "" ""))
3336               (clobber (match_dup 4))
3337               (clobber (match_dup 5))
3338               (clobber (match_dup 6))
3339               (clobber (match_dup 7))
3340               (clobber (match_dup 8))
3341               (use (match_operand:DI 2 "arith_operand" ""))
3342               (use (match_operand:DI 3 "const_int_operand" ""))])]
3343   "TARGET_64BIT && optimize > 0"
3344   "
3346   int size, align;
3348   /* HP provides very fast block move library routine for the PA;
3349      this routine includes:
3351         4x4 byte at a time block moves,
3352         1x4 byte at a time with alignment checked at runtime with
3353             attempts to align the source and destination as needed
3354         1x1 byte loop
3356      With that in mind, here's the heuristics to try and guess when
3357      the inlined block move will be better than the library block
3358      move:
3360         If the size isn't constant, then always use the library routines.
3362         If the size is large in respect to the known alignment, then use
3363         the library routines.
3365         If the size is small in respect to the known alignment, then open
3366         code the copy (since that will lead to better scheduling).
3368         Else use the block move pattern.   */
3370   /* Undetermined size, use the library routine.  */
3371   if (GET_CODE (operands[2]) != CONST_INT)
3372     FAIL;
3374   size = INTVAL (operands[2]);
3375   align = INTVAL (operands[3]);
3376   align = align > 8 ? 8 : align;
3378   /* If size/alignment is large, then use the library routines.  */
3379   if (size / align > 16)
3380     FAIL;
3382   /* This does happen, but not often enough to worry much about.  */
3383   if (size / align < MOVE_RATIO)
3384     FAIL;
3385   
3386   /* Fall through means we're going to use our block move pattern.  */
3387   operands[0]
3388     = replace_equiv_address (operands[0],
3389                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3390   operands[1]
3391     = replace_equiv_address (operands[1],
3392                              copy_to_mode_reg (DImode, XEXP (operands[1], 0)));
3393   operands[4] = gen_reg_rtx (DImode);
3394   operands[5] = gen_reg_rtx (DImode);
3395   operands[6] = gen_reg_rtx (DImode);
3396   operands[7] = gen_reg_rtx (DImode);
3397   operands[8] = gen_reg_rtx (DImode);
3400 ;; The operand constraints are written like this to support both compile-time
3401 ;; and run-time determined byte counts.  The expander and output_block_move
3402 ;; only support compile-time determined counts at this time.
3404 ;; If the count is run-time determined, the register with the byte count
3405 ;; is clobbered by the copying code, and therefore it is forced to operand 2.
3407 ;; We used to clobber operands 0 and 1.  However, a change to regrename.c
3408 ;; broke this semantic for pseudo registers.  We can't use match_scratch
3409 ;; as this requires two registers in the class R1_REGS when the MEMs for
3410 ;; operands 0 and 1 are both equivalent to symbolic MEMs.  Thus, we are
3411 ;; forced to internally copy operands 0 and 1 to operands 7 and 8,
3412 ;; respectively.  We then split or peephole optimize after reload.
3413 (define_insn "movmemdi_prereload"
3414   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3415         (mem:BLK (match_operand:DI 1 "register_operand" "r,r")))
3416    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3417    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3418    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3419    (clobber (match_operand:DI 7 "register_operand" "=&r,&r"))   ;item tmp3
3420    (clobber (match_operand:DI 8 "register_operand" "=&r,&r"))   ;item tmp4
3421    (use (match_operand:DI 4 "arith_operand" "J,2"))      ;byte count
3422    (use (match_operand:DI 5 "const_int_operand" "n,n"))] ;alignment
3423   "TARGET_64BIT"
3424   "#"
3425   [(set_attr "type" "multi,multi")])
3427 (define_split
3428   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3429                    (match_operand:BLK 1 "memory_operand" ""))
3430               (clobber (match_operand:DI 2 "register_operand" ""))
3431               (clobber (match_operand:DI 3 "register_operand" ""))
3432               (clobber (match_operand:DI 6 "register_operand" ""))
3433               (clobber (match_operand:DI 7 "register_operand" ""))
3434               (clobber (match_operand:DI 8 "register_operand" ""))
3435               (use (match_operand:DI 4 "arith_operand" ""))
3436               (use (match_operand:DI 5 "const_int_operand" ""))])]
3437   "TARGET_64BIT && reload_completed && !flag_peephole2
3438    && GET_CODE (operands[0]) == MEM
3439    && register_operand (XEXP (operands[0], 0), DImode)
3440    && GET_CODE (operands[1]) == MEM
3441    && register_operand (XEXP (operands[1], 0), DImode)"
3442   [(set (match_dup 7) (match_dup 9))
3443    (set (match_dup 8) (match_dup 10))
3444    (parallel [(set (match_dup 0) (match_dup 1))
3445               (clobber (match_dup 2))
3446               (clobber (match_dup 3))
3447               (clobber (match_dup 6))
3448               (clobber (match_dup 7))
3449               (clobber (match_dup 8))
3450               (use (match_dup 4))
3451               (use (match_dup 5))
3452               (const_int 0)])]
3453   "
3455   operands[9] = XEXP (operands[0], 0);
3456   operands[10] = XEXP (operands[1], 0);
3457   operands[0] = replace_equiv_address (operands[0], operands[7]);
3458   operands[1] = replace_equiv_address (operands[1], operands[8]);
3461 (define_peephole2
3462   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3463                    (match_operand:BLK 1 "memory_operand" ""))
3464               (clobber (match_operand:DI 2 "register_operand" ""))
3465               (clobber (match_operand:DI 3 "register_operand" ""))
3466               (clobber (match_operand:DI 6 "register_operand" ""))
3467               (clobber (match_operand:DI 7 "register_operand" ""))
3468               (clobber (match_operand:DI 8 "register_operand" ""))
3469               (use (match_operand:DI 4 "arith_operand" ""))
3470               (use (match_operand:DI 5 "const_int_operand" ""))])]
3471   "TARGET_64BIT
3472    && GET_CODE (operands[0]) == MEM
3473    && register_operand (XEXP (operands[0], 0), DImode)
3474    && GET_CODE (operands[1]) == MEM
3475    && register_operand (XEXP (operands[1], 0), DImode)"
3476   [(parallel [(set (match_dup 0) (match_dup 1))
3477               (clobber (match_dup 2))
3478               (clobber (match_dup 3))
3479               (clobber (match_dup 6))
3480               (clobber (match_dup 7))
3481               (clobber (match_dup 8))
3482               (use (match_dup 4))
3483               (use (match_dup 5))
3484               (const_int 0)])]
3485   "
3487   rtx addr = XEXP (operands[0], 0);
3488   if (dead_or_set_p (curr_insn, addr))
3489     operands[7] = addr;
3490   else
3491     {
3492       emit_insn (gen_rtx_SET (VOIDmode, operands[7], addr));
3493       operands[0] = replace_equiv_address (operands[0], operands[7]);
3494     }
3496   addr = XEXP (operands[1], 0);
3497   if (dead_or_set_p (curr_insn, addr))
3498     operands[8] = addr;
3499   else
3500     {
3501       emit_insn (gen_rtx_SET (VOIDmode, operands[8], addr));
3502       operands[1] = replace_equiv_address (operands[1], operands[8]);
3503     }
3506 (define_insn "movmemdi_postreload"
3507   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3508         (mem:BLK (match_operand:DI 1 "register_operand" "+r,r")))
3509    (clobber (match_operand:DI 2 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3510    (clobber (match_operand:DI 3 "register_operand" "=&r,&r"))   ;item tmp1
3511    (clobber (match_operand:DI 6 "register_operand" "=&r,&r"))   ;item tmp2
3512    (clobber (match_dup 0))
3513    (clobber (match_dup 1))
3514    (use (match_operand:DI 4 "arith_operand" "J,2"))      ;byte count
3515    (use (match_operand:DI 5 "const_int_operand" "n,n"))  ;alignment
3516    (const_int 0)]
3517   "TARGET_64BIT && reload_completed"
3518   "* return output_block_move (operands, !which_alternative);"
3519   [(set_attr "type" "multi,multi")])
3521 (define_expand "clrmemsi"
3522   [(parallel [(set (match_operand:BLK 0 "" "")
3523                    (const_int 0))
3524               (clobber (match_dup 3))
3525               (clobber (match_dup 4))
3526               (use (match_operand:SI 1 "arith_operand" ""))
3527               (use (match_operand:SI 2 "const_int_operand" ""))])]
3528   "!TARGET_64BIT && optimize > 0"
3529   "
3531   int size, align;
3533   /* Undetermined size, use the library routine.  */
3534   if (GET_CODE (operands[1]) != CONST_INT)
3535     FAIL;
3537   size = INTVAL (operands[1]);
3538   align = INTVAL (operands[2]);
3539   align = align > 4 ? 4 : align;
3541   /* If size/alignment is large, then use the library routines.  */
3542   if (size / align > 16)
3543     FAIL;
3545   /* This does happen, but not often enough to worry much about.  */
3546   if (size / align < MOVE_RATIO)
3547     FAIL;
3548   
3549   /* Fall through means we're going to use our block clear pattern.  */
3550   operands[0]
3551     = replace_equiv_address (operands[0],
3552                              copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
3553   operands[3] = gen_reg_rtx (SImode);
3554   operands[4] = gen_reg_rtx (SImode);
3557 (define_insn "clrmemsi_prereload"
3558   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r,r"))
3559         (const_int 0))
3560    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3561    (clobber (match_operand:SI 4 "register_operand" "=&r,&r"))   ;tmp1
3562    (use (match_operand:SI 2 "arith_operand" "J,1"))      ;byte count
3563    (use (match_operand:SI 3 "const_int_operand" "n,n"))] ;alignment
3564   "!TARGET_64BIT"
3565   "#"
3566   [(set_attr "type" "multi,multi")])
3568 (define_split
3569   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3570                    (const_int 0))
3571               (clobber (match_operand:SI 1 "register_operand" ""))
3572               (clobber (match_operand:SI 4 "register_operand" ""))
3573               (use (match_operand:SI 2 "arith_operand" ""))
3574               (use (match_operand:SI 3 "const_int_operand" ""))])]
3575   "!TARGET_64BIT && reload_completed && !flag_peephole2
3576    && GET_CODE (operands[0]) == MEM
3577    && register_operand (XEXP (operands[0], 0), SImode)"
3578   [(set (match_dup 4) (match_dup 5))
3579    (parallel [(set (match_dup 0) (const_int 0))
3580               (clobber (match_dup 1))
3581               (clobber (match_dup 4))
3582               (use (match_dup 2))
3583               (use (match_dup 3))
3584               (const_int 0)])]
3585   "
3587   operands[5] = XEXP (operands[0], 0);
3588   operands[0] = replace_equiv_address (operands[0], operands[4]);
3591 (define_peephole2
3592   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3593                    (const_int 0))
3594               (clobber (match_operand:SI 1 "register_operand" ""))
3595               (clobber (match_operand:SI 4 "register_operand" ""))
3596               (use (match_operand:SI 2 "arith_operand" ""))
3597               (use (match_operand:SI 3 "const_int_operand" ""))])]
3598   "!TARGET_64BIT
3599    && GET_CODE (operands[0]) == MEM
3600    && register_operand (XEXP (operands[0], 0), SImode)"
3601   [(parallel [(set (match_dup 0) (const_int 0))
3602               (clobber (match_dup 1))
3603               (clobber (match_dup 4))
3604               (use (match_dup 2))
3605               (use (match_dup 3))
3606               (const_int 0)])]
3607   "
3609   rtx addr = XEXP (operands[0], 0);
3610   if (dead_or_set_p (curr_insn, addr))
3611     operands[4] = addr;
3612   else
3613     {
3614       emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3615       operands[0] = replace_equiv_address (operands[0], operands[4]);
3616     }
3619 (define_insn "clrmemsi_postreload"
3620   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
3621         (const_int 0))
3622    (clobber (match_operand:SI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3623    (clobber (match_dup 0))
3624    (use (match_operand:SI 2 "arith_operand" "J,1"))      ;byte count
3625    (use (match_operand:SI 3 "const_int_operand" "n,n"))  ;alignment
3626    (const_int 0)]
3627   "!TARGET_64BIT && reload_completed"
3628   "* return output_block_clear (operands, !which_alternative);"
3629   [(set_attr "type" "multi,multi")])
3631 (define_expand "clrmemdi"
3632   [(parallel [(set (match_operand:BLK 0 "" "")
3633                    (const_int 0))
3634               (clobber (match_dup 3))
3635               (clobber (match_dup 4))
3636               (use (match_operand:DI 1 "arith_operand" ""))
3637               (use (match_operand:DI 2 "const_int_operand" ""))])]
3638   "TARGET_64BIT && optimize > 0"
3639   "
3641   int size, align;
3643   /* Undetermined size, use the library routine.  */
3644   if (GET_CODE (operands[1]) != CONST_INT)
3645     FAIL;
3647   size = INTVAL (operands[1]);
3648   align = INTVAL (operands[2]);
3649   align = align > 8 ? 8 : align;
3651   /* If size/alignment is large, then use the library routines.  */
3652   if (size / align > 16)
3653     FAIL;
3655   /* This does happen, but not often enough to worry much about.  */
3656   if (size / align < MOVE_RATIO)
3657     FAIL;
3658   
3659   /* Fall through means we're going to use our block clear pattern.  */
3660   operands[0]
3661     = replace_equiv_address (operands[0],
3662                              copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
3663   operands[3] = gen_reg_rtx (DImode);
3664   operands[4] = gen_reg_rtx (DImode);
3667 (define_insn "clrmemdi_prereload"
3668   [(set (mem:BLK (match_operand:DI 0 "register_operand" "r,r"))
3669         (const_int 0))
3670    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3671    (clobber (match_operand:DI 4 "register_operand" "=&r,&r"))   ;item tmp1
3672    (use (match_operand:DI 2 "arith_operand" "J,1"))      ;byte count
3673    (use (match_operand:DI 3 "const_int_operand" "n,n"))] ;alignment
3674   "TARGET_64BIT"
3675   "#"
3676   [(set_attr "type" "multi,multi")])
3678 (define_split
3679   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3680                    (const_int 0))
3681               (clobber (match_operand:DI 1 "register_operand" ""))
3682               (clobber (match_operand:DI 4 "register_operand" ""))
3683               (use (match_operand:DI 2 "arith_operand" ""))
3684               (use (match_operand:DI 3 "const_int_operand" ""))])]
3685   "TARGET_64BIT && reload_completed && !flag_peephole2
3686    && GET_CODE (operands[0]) == MEM
3687    && register_operand (XEXP (operands[0], 0), DImode)"
3688   [(set (match_dup 4) (match_dup 5))
3689    (parallel [(set (match_dup 0) (const_int 0))
3690               (clobber (match_dup 1))
3691               (clobber (match_dup 4))
3692               (use (match_dup 2))
3693               (use (match_dup 3))
3694               (const_int 0)])]
3695   "
3697   operands[5] = XEXP (operands[0], 0);
3698   operands[0] = replace_equiv_address (operands[0], operands[4]);
3701 (define_peephole2
3702   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
3703                    (const_int 0))
3704               (clobber (match_operand:DI 1 "register_operand" ""))
3705               (clobber (match_operand:DI 4 "register_operand" ""))
3706               (use (match_operand:DI 2 "arith_operand" ""))
3707               (use (match_operand:DI 3 "const_int_operand" ""))])]
3708   "TARGET_64BIT
3709    && GET_CODE (operands[0]) == MEM
3710    && register_operand (XEXP (operands[0], 0), DImode)"
3711   [(parallel [(set (match_dup 0) (const_int 0))
3712               (clobber (match_dup 1))
3713               (clobber (match_dup 4))
3714               (use (match_dup 2))
3715               (use (match_dup 3))
3716               (const_int 0)])]
3717   "
3718 {  
3719   rtx addr = XEXP (operands[0], 0);
3720   if (dead_or_set_p (curr_insn, addr))
3721     operands[4] = addr;
3722   else
3723     {
3724       emit_insn (gen_rtx_SET (VOIDmode, operands[4], addr));
3725       operands[0] = replace_equiv_address (operands[0], operands[4]);
3726     }
3729 (define_insn "clrmemdi_postreload"
3730   [(set (mem:BLK (match_operand:DI 0 "register_operand" "+r,r"))
3731         (const_int 0))
3732    (clobber (match_operand:DI 1 "register_operand" "=&r,&r"))   ;loop cnt/tmp
3733    (clobber (match_dup 0))
3734    (use (match_operand:DI 2 "arith_operand" "J,1"))      ;byte count
3735    (use (match_operand:DI 3 "const_int_operand" "n,n"))  ;alignment
3736    (const_int 0)]
3737   "TARGET_64BIT && reload_completed"
3738   "* return output_block_clear (operands, !which_alternative);"
3739   [(set_attr "type" "multi,multi")])
3741 ;; Floating point move insns
3743 ;; This pattern forces (set (reg:DF ...) (const_double ...))
3744 ;; to be reloaded by putting the constant into memory when
3745 ;; reg is a floating point register.
3747 ;; For integer registers we use ldil;ldo to set the appropriate
3748 ;; value.
3750 ;; This must come before the movdf pattern, and it must be present
3751 ;; to handle obscure reloading cases.
3752 (define_insn ""
3753   [(set (match_operand:DF 0 "register_operand" "=?r,f")
3754         (match_operand:DF 1 "" "?F,m"))]
3755   "GET_CODE (operands[1]) == CONST_DOUBLE
3756    && operands[1] != CONST0_RTX (DFmode)
3757    && !TARGET_64BIT
3758    && !TARGET_SOFT_FLOAT"
3759   "* return (which_alternative == 0 ? output_move_double (operands)
3760                                     : \"fldd%F1 %1,%0\");"
3761   [(set_attr "type" "move,fpload")
3762    (set_attr "length" "16,4")])
3764 (define_expand "movdf"
3765   [(set (match_operand:DF 0 "general_operand" "")
3766         (match_operand:DF 1 "general_operand" ""))]
3767   ""
3768   "
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
3771     operands[1] = force_const_mem (DFmode, operands[1]);
3773   if (emit_move_sequence (operands, DFmode, 0))
3774     DONE;
3777 ;; Reloading an SImode or DImode value requires a scratch register if
3778 ;; going in to or out of float point registers.
3780 (define_expand "reload_indf"
3781   [(set (match_operand:DF 0 "register_operand" "=Z")
3782         (match_operand:DF 1 "non_hard_reg_operand" ""))
3783    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3784   ""
3785   "
3787   if (emit_move_sequence (operands, DFmode, operands[2]))
3788     DONE;
3790   /* We don't want the clobber emitted, so handle this ourselves.  */
3791   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3792   DONE;
3795 (define_expand "reload_outdf" 
3796  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
3797         (match_operand:DF 1  "register_operand" "Z"))
3798    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
3799   ""
3800   "
3802   if (emit_move_sequence (operands, DFmode, operands[2]))
3803     DONE;
3805   /* We don't want the clobber emitted, so handle this ourselves.  */
3806   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3807   DONE;
3810 (define_insn ""
3811   [(set (match_operand:DF 0 "move_dest_operand"
3812                           "=f,*r,Q,?o,?Q,f,*r,*r")
3813         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3814                           "fG,*rG,f,*r,*r,RQ,o,RQ"))]
3815   "(register_operand (operands[0], DFmode)
3816     || reg_or_0_operand (operands[1], DFmode))
3817    && !(GET_CODE (operands[1]) == CONST_DOUBLE
3818         && GET_CODE (operands[0]) == MEM)
3819    && !TARGET_64BIT
3820    && !TARGET_SOFT_FLOAT"
3821   "*
3823   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
3824       || operands[1] == CONST0_RTX (DFmode))
3825     return output_fp_move_double (operands);
3826   return output_move_double (operands);
3828   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
3829    (set_attr "length" "4,8,4,8,16,4,8,16")])
3831 (define_insn ""
3832   [(set (match_operand:DF 0 "indexed_memory_operand" "=R")
3833         (match_operand:DF 1 "reg_or_0_operand" "f"))]
3834   "!TARGET_SOFT_FLOAT
3835    && !TARGET_DISABLE_INDEXING
3836    && reload_completed"
3837   "fstd%F0 %1,%0"
3838   [(set_attr "type" "fpstore")
3839    (set_attr "pa_combine_type" "addmove")
3840    (set_attr "length" "4")])
3842 (define_peephole2
3843   [(set (match_operand:SI 0 "register_operand" "")
3844         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
3845                           (const_int 8))
3846                  (match_operand:SI 2 "register_operand" "")))
3847    (set (mem:DF (match_dup 0))
3848         (match_operand:DF 3 "register_operand" ""))]
3849   "!TARGET_SOFT_FLOAT
3850    && !TARGET_DISABLE_INDEXING
3851    && REG_OK_FOR_BASE_P (operands[2])
3852    && FP_REGNO_P (REGNO (operands[3]))"
3853   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3854         (match_dup 3))
3855    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3856                                (match_dup 2)))]
3857   "")
3859 (define_peephole2
3860   [(set (match_operand:SI 0 "register_operand" "")
3861         (plus:SI (match_operand:SI 2 "register_operand" "")
3862                  (mult:SI (match_operand:SI 1 "register_operand" "")
3863                           (const_int 8))))
3864    (set (mem:DF (match_dup 0))
3865         (match_operand:DF 3 "register_operand" ""))]
3866   "!TARGET_SOFT_FLOAT
3867    && !TARGET_DISABLE_INDEXING
3868    && REG_OK_FOR_BASE_P (operands[2])
3869    && FP_REGNO_P (REGNO (operands[3]))"
3870   [(set (mem:DF (plus:SI (mult:SI (match_dup 1) (const_int 8)) (match_dup 2)))
3871         (match_dup 3))
3872    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
3873                                (match_dup 2)))]
3874   "")
3876 (define_peephole2
3877   [(set (match_operand:DI 0 "register_operand" "")
3878         (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
3879                           (const_int 8))
3880                  (match_operand:DI 2 "register_operand" "")))
3881    (set (mem:DF (match_dup 0))
3882         (match_operand:DF 3 "register_operand" ""))]
3883   "!TARGET_SOFT_FLOAT
3884    && !TARGET_DISABLE_INDEXING
3885    && TARGET_64BIT
3886    && REG_OK_FOR_BASE_P (operands[2])
3887    && FP_REGNO_P (REGNO (operands[3]))"
3888   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3889         (match_dup 3))
3890    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3891                                (match_dup 2)))]
3892   "")
3894 (define_peephole2
3895   [(set (match_operand:DI 0 "register_operand" "")
3896         (plus:DI (match_operand:DI 2 "register_operand" "")
3897                  (mult:DI (match_operand:DI 1 "register_operand" "")
3898                           (const_int 8))))
3899    (set (mem:DF (match_dup 0))
3900         (match_operand:DF 3 "register_operand" ""))]
3901   "!TARGET_SOFT_FLOAT
3902    && !TARGET_DISABLE_INDEXING
3903    && TARGET_64BIT
3904    && REG_OK_FOR_BASE_P (operands[2])
3905    && FP_REGNO_P (REGNO (operands[3]))"
3906   [(set (mem:DF (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
3907         (match_dup 3))
3908    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
3909                                (match_dup 2)))]
3910   "")
3912 (define_peephole2
3913   [(set (match_operand:SI 0 "register_operand" "")
3914         (plus:SI (match_operand:SI 1 "register_operand" "")
3915                  (match_operand:SI 2 "register_operand" "")))
3916    (set (mem:DF (match_dup 0))
3917         (match_operand:DF 3 "register_operand" ""))]
3918   "!TARGET_SOFT_FLOAT
3919    && !TARGET_DISABLE_INDEXING
3920    && REG_OK_FOR_BASE_P (operands[1])
3921    && (TARGET_NO_SPACE_REGS
3922        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
3923    && FP_REGNO_P (REGNO (operands[3]))"
3924   [(set (mem:DF (plus:SI (match_dup 1) (match_dup 2)))
3925         (match_dup 3))
3926    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
3927   "")
3929 (define_peephole2
3930   [(set (match_operand:SI 0 "register_operand" "")
3931         (plus:SI (match_operand:SI 1 "register_operand" "")
3932                  (match_operand:SI 2 "register_operand" "")))
3933    (set (mem:DF (match_dup 0))
3934         (match_operand:DF 3 "register_operand" ""))]
3935   "!TARGET_SOFT_FLOAT
3936    && !TARGET_DISABLE_INDEXING
3937    && REG_OK_FOR_BASE_P (operands[2])
3938    && (TARGET_NO_SPACE_REGS
3939        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
3940    && FP_REGNO_P (REGNO (operands[3]))"
3941   [(set (mem:DF (plus:SI (match_dup 2) (match_dup 1)))
3942         (match_dup 3))
3943    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
3944   "")
3946 (define_peephole2
3947   [(set (match_operand:DI 0 "register_operand" "")
3948         (plus:DI (match_operand:DI 1 "register_operand" "")
3949                  (match_operand:DI 2 "register_operand" "")))
3950    (set (mem:DF (match_dup 0))
3951         (match_operand:DF 3 "register_operand" ""))]
3952   "!TARGET_SOFT_FLOAT
3953    && !TARGET_DISABLE_INDEXING
3954    && TARGET_64BIT
3955    && REG_OK_FOR_BASE_P (operands[1])
3956    && (TARGET_NO_SPACE_REGS
3957        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
3958    && FP_REGNO_P (REGNO (operands[3]))"
3959   [(set (mem:DF (plus:DI (match_dup 1) (match_dup 2)))
3960         (match_dup 3))
3961    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
3962   "")
3964 (define_peephole2
3965   [(set (match_operand:DI 0 "register_operand" "")
3966         (plus:DI (match_operand:DI 1 "register_operand" "")
3967                  (match_operand:DI 2 "register_operand" "")))
3968    (set (mem:DF (match_dup 0))
3969         (match_operand:DF 3 "register_operand" ""))]
3970   "!TARGET_SOFT_FLOAT
3971    && !TARGET_DISABLE_INDEXING
3972    && TARGET_64BIT
3973    && REG_OK_FOR_BASE_P (operands[2])
3974    && (TARGET_NO_SPACE_REGS
3975        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
3976    && FP_REGNO_P (REGNO (operands[3]))"
3977   [(set (mem:DF (plus:DI (match_dup 2) (match_dup 1)))
3978         (match_dup 3))
3979    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
3980   "")
3982 (define_insn ""
3983   [(set (match_operand:DF 0 "move_dest_operand"
3984                           "=r,?o,?Q,r,r")
3985         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
3986                           "rG,r,r,o,RQ"))]
3987   "(register_operand (operands[0], DFmode)
3988     || reg_or_0_operand (operands[1], DFmode))
3989    && !TARGET_64BIT
3990    && TARGET_SOFT_FLOAT"
3991   "*
3993   return output_move_double (operands);
3995   [(set_attr "type" "move,store,store,load,load")
3996    (set_attr "length" "8,8,16,8,16")])
3998 (define_insn ""
3999   [(set (match_operand:DF 0 "move_dest_operand"
4000                           "=!*r,*r,*r,*r,*r,Q,f,f,T")
4001         (match_operand:DF 1 "move_src_operand"
4002                           "!*r,J,N,K,RQ,*rM,fM,RT,f"))]
4003   "(register_operand (operands[0], DFmode)
4004     || reg_or_0_operand (operands[1], DFmode))
4005    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4006   "@
4007    copy %1,%0
4008    ldi %1,%0
4009    ldil L'%1,%0
4010    depdi,z %z1,%0
4011    ldd%M1 %1,%0
4012    std%M0 %r1,%0
4013    fcpy,dbl %f1,%0
4014    fldd%F1 %1,%0
4015    fstd%F0 %1,%0"
4016   [(set_attr "type" "move,move,move,shift,load,store,fpalu,fpload,fpstore")
4017    (set_attr "pa_combine_type" "addmove")
4018    (set_attr "length" "4,4,4,4,4,4,4,4,4")])
4021 (define_expand "movdi"
4022   [(set (match_operand:DI 0 "general_operand" "")
4023         (match_operand:DI 1 "general_operand" ""))]
4024   ""
4025   "
4027   if (GET_CODE (operands[1]) == CONST_DOUBLE && TARGET_64BIT)
4028     operands[1] = force_const_mem (DImode, operands[1]);
4030   if (emit_move_sequence (operands, DImode, 0))
4031     DONE;
4034 (define_expand "reload_indi"
4035   [(set (match_operand:DI 0 "register_operand" "=Z")
4036         (match_operand:DI 1 "non_hard_reg_operand" ""))
4037    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4038   ""
4039   "
4041   if (emit_move_sequence (operands, DImode, operands[2]))
4042     DONE;
4044   /* We don't want the clobber emitted, so handle this ourselves.  */
4045   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4046   DONE;
4049 (define_expand "reload_outdi"
4050   [(set (match_operand:DI 0 "non_hard_reg_operand" "")
4051         (match_operand:DI 1 "register_operand" "Z"))
4052    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
4053   ""
4054   "
4056   if (emit_move_sequence (operands, DImode, operands[2]))
4057     DONE;
4059   /* We don't want the clobber emitted, so handle this ourselves.  */
4060   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4061   DONE;
4064 (define_insn ""
4065   [(set (match_operand:DI 0 "register_operand" "=r")
4066         (high:DI (match_operand 1 "" "")))]
4067   "!TARGET_64BIT"
4068   "*
4070   rtx op0 = operands[0];
4071   rtx op1 = operands[1];
4073   if (GET_CODE (op1) == CONST_INT)
4074     {
4075       operands[0] = operand_subword (op0, 1, 0, DImode);
4076       output_asm_insn (\"ldil L'%1,%0\", operands);
4078       operands[0] = operand_subword (op0, 0, 0, DImode);
4079       if (INTVAL (op1) < 0)
4080         output_asm_insn (\"ldi -1,%0\", operands);
4081       else
4082         output_asm_insn (\"ldi 0,%0\", operands);
4083       return \"\";
4084     }
4085   else if (GET_CODE (op1) == CONST_DOUBLE)
4086     {
4087       operands[0] = operand_subword (op0, 1, 0, DImode);
4088       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
4089       output_asm_insn (\"ldil L'%1,%0\", operands);
4091       operands[0] = operand_subword (op0, 0, 0, DImode);
4092       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
4093       output_asm_insn (singlemove_string (operands), operands);
4094       return \"\";
4095     }
4096   else
4097     abort ();
4099   [(set_attr "type" "move")
4100    (set_attr "length" "8")])
4102 (define_insn ""
4103   [(set (match_operand:DI 0 "move_dest_operand"
4104                           "=r,o,Q,r,r,r,*f,*f,T")
4105         (match_operand:DI 1 "general_operand"
4106                           "rM,r,r,o*R,Q,i,*fM,RT,*f"))]
4107   "(register_operand (operands[0], DImode)
4108     || reg_or_0_operand (operands[1], DImode))
4109    && !TARGET_64BIT
4110    && !TARGET_SOFT_FLOAT"
4111   "*
4113   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
4114       || (operands[1] == CONST0_RTX (DImode)))
4115     return output_fp_move_double (operands);
4116   return output_move_double (operands);
4118   [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
4119    (set_attr "length" "8,8,16,8,16,16,4,4,4")])
4121 (define_insn ""
4122   [(set (match_operand:DI 0 "move_dest_operand"
4123                           "=r,r,r,r,r,r,Q,!*q,!r,!*f,*f,T")
4124         (match_operand:DI 1 "move_src_operand"
4125                           "A,r,J,N,K,RQ,rM,!rM,!*q,!*fM,RT,*f"))]
4126   "(register_operand (operands[0], DImode)
4127     || reg_or_0_operand (operands[1], DImode))
4128    && !TARGET_SOFT_FLOAT && TARGET_64BIT"
4129   "@
4130    ldd RT'%A1,%0
4131    copy %1,%0
4132    ldi %1,%0
4133    ldil L'%1,%0
4134    depdi,z %z1,%0
4135    ldd%M1 %1,%0
4136    std%M0 %r1,%0
4137    mtsar %r1
4138    {mfctl|mfctl,w} %%sar,%0
4139    fcpy,dbl %f1,%0
4140    fldd%F1 %1,%0
4141    fstd%F0 %1,%0"
4142   [(set_attr "type" "load,move,move,move,shift,load,store,move,move,fpalu,fpload,fpstore")
4143    (set_attr "pa_combine_type" "addmove")
4144    (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4")])
4146 (define_insn ""
4147   [(set (match_operand:DI 0 "indexed_memory_operand" "=R")
4148         (match_operand:DI 1 "register_operand" "f"))]
4149   "!TARGET_SOFT_FLOAT
4150    && TARGET_64BIT
4151    && !TARGET_DISABLE_INDEXING
4152    && reload_completed"
4153   "fstd%F0 %1,%0"
4154   [(set_attr "type" "fpstore")
4155    (set_attr "pa_combine_type" "addmove")
4156    (set_attr "length" "4")])
4158 (define_peephole2
4159   [(set (match_operand:DI 0 "register_operand" "")
4160         (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4161                           (const_int 8))
4162                  (match_operand:DI 2 "register_operand" "")))
4163    (set (mem:DI (match_dup 0))
4164         (match_operand:DI 3 "register_operand" ""))]
4165   "!TARGET_SOFT_FLOAT
4166    && !TARGET_DISABLE_INDEXING
4167    && TARGET_64BIT
4168    && REG_OK_FOR_BASE_P (operands[2])
4169    && FP_REGNO_P (REGNO (operands[3]))"
4170   [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4171         (match_dup 3))
4172    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4173                                (match_dup 2)))]
4174   "")
4176 (define_peephole2
4177   [(set (match_operand:DI 0 "register_operand" "")
4178         (plus:DI (match_operand:DI 2 "register_operand" "")
4179                  (mult:DI (match_operand:DI 1 "register_operand" "")
4180                           (const_int 8))))
4181    (set (mem:DI (match_dup 0))
4182         (match_operand:DI 3 "register_operand" ""))]
4183   "!TARGET_SOFT_FLOAT
4184    && !TARGET_DISABLE_INDEXING
4185    && TARGET_64BIT
4186    && REG_OK_FOR_BASE_P (operands[2])
4187    && FP_REGNO_P (REGNO (operands[3]))"
4188   [(set (mem:DI (plus:DI (mult:DI (match_dup 1) (const_int 8)) (match_dup 2)))
4189         (match_dup 3))
4190    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 8))
4191                                (match_dup 2)))]
4192   "")
4194 (define_peephole2
4195   [(set (match_operand:DI 0 "register_operand" "")
4196         (plus:DI (match_operand:DI 1 "register_operand" "")
4197                  (match_operand:DI 2 "register_operand" "")))
4198    (set (mem:DI (match_dup 0))
4199         (match_operand:DI 3 "register_operand" ""))]
4200   "!TARGET_SOFT_FLOAT
4201    && !TARGET_DISABLE_INDEXING
4202    && TARGET_64BIT
4203    && REG_OK_FOR_BASE_P (operands[1])
4204    && (TARGET_NO_SPACE_REGS
4205        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
4206    && FP_REGNO_P (REGNO (operands[3]))"
4207   [(set (mem:DI (plus:DI (match_dup 1) (match_dup 2)))
4208         (match_dup 3))
4209    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4210   "")
4212 (define_peephole2
4213   [(set (match_operand:DI 0 "register_operand" "")
4214         (plus:DI (match_operand:DI 1 "register_operand" "")
4215                  (match_operand:DI 2 "register_operand" "")))
4216    (set (mem:DI (match_dup 0))
4217         (match_operand:DI 3 "register_operand" ""))]
4218   "!TARGET_SOFT_FLOAT
4219    && !TARGET_DISABLE_INDEXING
4220    && TARGET_64BIT
4221    && REG_OK_FOR_BASE_P (operands[2])
4222    && (TARGET_NO_SPACE_REGS
4223        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
4224    && FP_REGNO_P (REGNO (operands[3]))"
4225   [(set (mem:DI (plus:DI (match_dup 2) (match_dup 1)))
4226         (match_dup 3))
4227    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4228   "")
4230 (define_insn ""
4231   [(set (match_operand:DI 0 "move_dest_operand"
4232                           "=r,o,Q,r,r,r")
4233         (match_operand:DI 1 "general_operand"
4234                           "rM,r,r,o,Q,i"))]
4235   "(register_operand (operands[0], DImode)
4236     || reg_or_0_operand (operands[1], DImode))
4237    && !TARGET_64BIT
4238    && TARGET_SOFT_FLOAT"
4239   "*
4241   return output_move_double (operands);
4243   [(set_attr "type" "move,store,store,load,load,multi")
4244    (set_attr "length" "8,8,16,8,16,16")])
4246 (define_insn ""
4247   [(set (match_operand:DI 0 "register_operand" "=r,&r")
4248         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
4249                    (match_operand:DI 2 "immediate_operand" "i,i")))]
4250   "!TARGET_64BIT"
4251   "*
4253   /* Don't output a 64 bit constant, since we can't trust the assembler to
4254      handle it correctly.  */
4255   if (GET_CODE (operands[2]) == CONST_DOUBLE)
4256     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
4257   if (which_alternative == 1)
4258     output_asm_insn (\"copy %1,%0\", operands);
4259   return \"ldo R'%G2(%R1),%R0\";
4261   [(set_attr "type" "move,move")
4262    (set_attr "length" "4,8")])
4264 ;; This pattern forces (set (reg:SF ...) (const_double ...))
4265 ;; to be reloaded by putting the constant into memory when
4266 ;; reg is a floating point register.
4268 ;; For integer registers we use ldil;ldo to set the appropriate
4269 ;; value.
4271 ;; This must come before the movsf pattern, and it must be present
4272 ;; to handle obscure reloading cases.
4273 (define_insn ""
4274   [(set (match_operand:SF 0 "register_operand" "=?r,f")
4275         (match_operand:SF 1 "" "?F,m"))]
4276   "GET_CODE (operands[1]) == CONST_DOUBLE
4277    && operands[1] != CONST0_RTX (SFmode)
4278    && ! TARGET_SOFT_FLOAT"
4279   "* return (which_alternative == 0 ? singlemove_string (operands)
4280                                     : \" fldw%F1 %1,%0\");"
4281   [(set_attr "type" "move,fpload")
4282    (set_attr "length" "8,4")])
4284 (define_expand "movsf"
4285   [(set (match_operand:SF 0 "general_operand" "")
4286         (match_operand:SF 1 "general_operand" ""))]
4287   ""
4288   "
4290   if (emit_move_sequence (operands, SFmode, 0))
4291     DONE;
4294 ;; Reloading an SImode or DImode value requires a scratch register if
4295 ;; going in to or out of float point registers.
4297 (define_expand "reload_insf"
4298   [(set (match_operand:SF 0 "register_operand" "=Z")
4299         (match_operand:SF 1 "non_hard_reg_operand" ""))
4300    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4301   ""
4302   "
4304   if (emit_move_sequence (operands, SFmode, operands[2]))
4305     DONE;
4307   /* We don't want the clobber emitted, so handle this ourselves.  */
4308   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4309   DONE;
4312 (define_expand "reload_outsf"
4313   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
4314         (match_operand:SF 1  "register_operand" "Z"))
4315    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
4316   ""
4317   "
4319   if (emit_move_sequence (operands, SFmode, operands[2]))
4320     DONE;
4322   /* We don't want the clobber emitted, so handle this ourselves.  */
4323   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4324   DONE;
4327 (define_insn ""
4328   [(set (match_operand:SF 0 "move_dest_operand"
4329                           "=f,!*r,f,*r,Q,Q")
4330         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4331                           "fG,!*rG,RQ,RQ,f,*rG"))]
4332   "(register_operand (operands[0], SFmode)
4333     || reg_or_0_operand (operands[1], SFmode))
4334    && !TARGET_SOFT_FLOAT"
4335   "@
4336    fcpy,sgl %f1,%0
4337    copy %r1,%0
4338    fldw%F1 %1,%0
4339    ldw%M1 %1,%0
4340    fstw%F0 %1,%0
4341    stw%M0 %r1,%0"
4342   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
4343    (set_attr "pa_combine_type" "addmove")
4344    (set_attr "length" "4,4,4,4,4,4")])
4346 (define_insn ""
4347   [(set (match_operand:SF 0 "indexed_memory_operand" "=R")
4348         (match_operand:SF 1 "register_operand" "f"))]
4349   "!TARGET_SOFT_FLOAT
4350    && !TARGET_DISABLE_INDEXING
4351    && reload_completed"
4352   "fstw%F0 %1,%0"
4353   [(set_attr "type" "fpstore")
4354    (set_attr "pa_combine_type" "addmove")
4355    (set_attr "length" "4")])
4357 (define_peephole2
4358   [(set (match_operand:SI 0 "register_operand" "")
4359         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4360                           (const_int 4))
4361                  (match_operand:SI 2 "register_operand" "")))
4362    (set (mem:SF (match_dup 0))
4363         (match_operand:SF 3 "register_operand" ""))]
4364   "!TARGET_SOFT_FLOAT
4365    && !TARGET_DISABLE_INDEXING
4366    && REG_OK_FOR_BASE_P (operands[2])
4367    && FP_REGNO_P (REGNO (operands[3]))"
4368   [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4369         (match_dup 3))
4370    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4371                                (match_dup 2)))]
4372   "")
4374 (define_peephole2
4375   [(set (match_operand:SI 0 "register_operand" "")
4376         (plus:SI (match_operand:SI 2 "register_operand" "")
4377                  (mult:SI (match_operand:SI 1 "register_operand" "")
4378                           (const_int 4))))
4379    (set (mem:SF (match_dup 0))
4380         (match_operand:SF 3 "register_operand" ""))]
4381   "!TARGET_SOFT_FLOAT
4382    && !TARGET_DISABLE_INDEXING
4383    && REG_OK_FOR_BASE_P (operands[2])
4384    && FP_REGNO_P (REGNO (operands[3]))"
4385   [(set (mem:SF (plus:SI (mult:SI (match_dup 1) (const_int 4)) (match_dup 2)))
4386         (match_dup 3))
4387    (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
4388                                (match_dup 2)))]
4389   "")
4391 (define_peephole2
4392   [(set (match_operand:DI 0 "register_operand" "")
4393         (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
4394                           (const_int 4))
4395                  (match_operand:DI 2 "register_operand" "")))
4396    (set (mem:SF (match_dup 0))
4397         (match_operand:SF 3 "register_operand" ""))]
4398   "!TARGET_SOFT_FLOAT
4399    && !TARGET_DISABLE_INDEXING
4400    && TARGET_64BIT
4401    && REG_OK_FOR_BASE_P (operands[2])
4402    && FP_REGNO_P (REGNO (operands[3]))"
4403   [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4404         (match_dup 3))
4405    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4406                                (match_dup 2)))]
4407   "")
4409 (define_peephole2
4410   [(set (match_operand:DI 0 "register_operand" "")
4411         (plus:DI (match_operand:DI 2 "register_operand" "")
4412                  (mult:DI (match_operand:DI 1 "register_operand" "")
4413                           (const_int 4))))
4414    (set (mem:SF (match_dup 0))
4415         (match_operand:SF 3 "register_operand" ""))]
4416   "!TARGET_SOFT_FLOAT
4417    && !TARGET_DISABLE_INDEXING
4418    && TARGET_64BIT
4419    && REG_OK_FOR_BASE_P (operands[2])
4420    && FP_REGNO_P (REGNO (operands[3]))"
4421   [(set (mem:SF (plus:DI (mult:DI (match_dup 1) (const_int 4)) (match_dup 2)))
4422         (match_dup 3))
4423    (set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (const_int 4))
4424                                (match_dup 2)))]
4425   "")
4427 (define_peephole2
4428   [(set (match_operand:SI 0 "register_operand" "")
4429         (plus:SI (match_operand:SI 1 "register_operand" "")
4430                  (match_operand:SI 2 "register_operand" "")))
4431    (set (mem:SF (match_dup 0))
4432         (match_operand:SF 3 "register_operand" ""))]
4433   "!TARGET_SOFT_FLOAT
4434    && !TARGET_DISABLE_INDEXING
4435    && REG_OK_FOR_BASE_P (operands[1])
4436    && (TARGET_NO_SPACE_REGS
4437        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
4438    && FP_REGNO_P (REGNO (operands[3]))"
4439   [(set (mem:SF (plus:SI (match_dup 1) (match_dup 2)))
4440         (match_dup 3))
4441    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
4442   "")
4444 (define_peephole2
4445   [(set (match_operand:SI 0 "register_operand" "")
4446         (plus:SI (match_operand:SI 1 "register_operand" "")
4447                  (match_operand:SI 2 "register_operand" "")))
4448    (set (mem:SF (match_dup 0))
4449         (match_operand:SF 3 "register_operand" ""))]
4450   "!TARGET_SOFT_FLOAT
4451    && !TARGET_DISABLE_INDEXING
4452    && REG_OK_FOR_BASE_P (operands[2])
4453    && (TARGET_NO_SPACE_REGS
4454        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
4455    && FP_REGNO_P (REGNO (operands[3]))"
4456   [(set (mem:SF (plus:SI (match_dup 2) (match_dup 1)))
4457         (match_dup 3))
4458    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))]
4459   "")
4461 (define_peephole2
4462   [(set (match_operand:DI 0 "register_operand" "")
4463         (plus:DI (match_operand:DI 1 "register_operand" "")
4464                  (match_operand:DI 2 "register_operand" "")))
4465    (set (mem:SF (match_dup 0))
4466         (match_operand:SF 3 "register_operand" ""))]
4467   "!TARGET_SOFT_FLOAT
4468    && !TARGET_DISABLE_INDEXING
4469    && TARGET_64BIT
4470    && REG_OK_FOR_BASE_P (operands[1])
4471    && (TARGET_NO_SPACE_REGS
4472        || (!REG_POINTER (operands[1]) && REG_POINTER (operands[2])))
4473    && FP_REGNO_P (REGNO (operands[3]))"
4474   [(set (mem:SF (plus:DI (match_dup 1) (match_dup 2)))
4475         (match_dup 3))
4476    (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
4477   "")
4479 (define_peephole2
4480   [(set (match_operand:DI 0 "register_operand" "")
4481         (plus:DI (match_operand:DI 1 "register_operand" "")
4482                  (match_operand:DI 2 "register_operand" "")))
4483    (set (mem:SF (match_dup 0))
4484         (match_operand:SF 3 "register_operand" ""))]
4485   "!TARGET_SOFT_FLOAT
4486    && !TARGET_DISABLE_INDEXING
4487    && TARGET_64BIT
4488    && REG_OK_FOR_BASE_P (operands[2])
4489    && (TARGET_NO_SPACE_REGS
4490        || (REG_POINTER (operands[1]) && !REG_POINTER (operands[2])))
4491    && FP_REGNO_P (REGNO (operands[3]))"
4492   [(set (mem:SF (plus:DI (match_dup 2) (match_dup 1)))
4493         (match_dup 3))
4494    (set (match_dup 0) (plus:DI (match_dup 2) (match_dup 1)))]
4495   "")
4497 (define_insn ""
4498   [(set (match_operand:SF 0 "move_dest_operand"
4499                           "=r,r,Q")
4500         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
4501                           "rG,RQ,rG"))]
4502   "(register_operand (operands[0], SFmode)
4503     || reg_or_0_operand (operands[1], SFmode))
4504    && TARGET_SOFT_FLOAT"
4505   "@
4506    copy %r1,%0
4507    ldw%M1 %1,%0
4508    stw%M0 %r1,%0"
4509   [(set_attr "type" "move,load,store")
4510    (set_attr "pa_combine_type" "addmove")
4511    (set_attr "length" "4,4,4")])
4515 ;;- zero extension instructions
4516 ;; We have define_expand for zero extension patterns to make sure the
4517 ;; operands get loaded into registers.  The define_insns accept
4518 ;; memory operands.  This gives us better overall code than just
4519 ;; having a pattern that does or does not accept memory operands.
4521 (define_expand "zero_extendqihi2"
4522   [(set (match_operand:HI 0 "register_operand" "")
4523         (zero_extend:HI
4524          (match_operand:QI 1 "register_operand" "")))]
4525   ""
4526   "")
4528 (define_insn ""
4529   [(set (match_operand:HI 0 "register_operand" "=r,r")
4530         (zero_extend:HI
4531          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4532   "GET_CODE (operands[1]) != CONST_INT"
4533   "@
4534    {extru|extrw,u} %1,31,8,%0
4535    ldb%M1 %1,%0"
4536   [(set_attr "type" "shift,load")
4537    (set_attr "length" "4,4")])
4539 (define_expand "zero_extendqisi2"
4540   [(set (match_operand:SI 0 "register_operand" "")
4541         (zero_extend:SI
4542          (match_operand:QI 1 "register_operand" "")))]
4543   ""
4544   "")
4546 (define_insn ""
4547   [(set (match_operand:SI 0 "register_operand" "=r,r")
4548         (zero_extend:SI
4549          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4550   "GET_CODE (operands[1]) != CONST_INT"
4551   "@
4552    {extru|extrw,u} %1,31,8,%0
4553    ldb%M1 %1,%0"
4554   [(set_attr "type" "shift,load")
4555    (set_attr "length" "4,4")])
4557 (define_expand "zero_extendhisi2"
4558   [(set (match_operand:SI 0 "register_operand" "")
4559         (zero_extend:SI
4560          (match_operand:HI 1 "register_operand" "")))]
4561   ""
4562   "")
4564 (define_insn ""
4565   [(set (match_operand:SI 0 "register_operand" "=r,r")
4566         (zero_extend:SI
4567          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4568   "GET_CODE (operands[1]) != CONST_INT"
4569   "@
4570    {extru|extrw,u} %1,31,16,%0
4571    ldh%M1 %1,%0"
4572   [(set_attr "type" "shift,load")
4573    (set_attr "length" "4,4")])
4575 (define_expand "zero_extendqidi2"
4576   [(set (match_operand:DI 0 "register_operand" "")
4577         (zero_extend:DI
4578          (match_operand:QI 1 "register_operand" "")))]
4579   "TARGET_64BIT"
4580   "")
4582 (define_insn ""
4583   [(set (match_operand:DI 0 "register_operand" "=r,r")
4584         (zero_extend:DI
4585          (match_operand:QI 1 "move_src_operand" "r,RQ")))]
4586   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4587   "@
4588    extrd,u %1,63,8,%0
4589    ldb%M1 %1,%0"
4590   [(set_attr "type" "shift,load")
4591    (set_attr "length" "4,4")])
4593 (define_expand "zero_extendhidi2"
4594   [(set (match_operand:DI 0 "register_operand" "")
4595         (zero_extend:DI
4596          (match_operand:HI 1 "register_operand" "")))]
4597   "TARGET_64BIT"
4598   "")
4600 (define_insn ""
4601   [(set (match_operand:DI 0 "register_operand" "=r,r")
4602         (zero_extend:DI
4603          (match_operand:HI 1 "move_src_operand" "r,RQ")))]
4604   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4605   "@
4606    extrd,u %1,63,16,%0
4607    ldh%M1 %1,%0"
4608   [(set_attr "type" "shift,load")
4609    (set_attr "length" "4,4")])
4611 (define_expand "zero_extendsidi2"
4612   [(set (match_operand:DI 0 "register_operand" "")
4613         (zero_extend:DI
4614          (match_operand:SI 1 "register_operand" "")))]
4615   "TARGET_64BIT"
4616   "")
4618 (define_insn ""
4619   [(set (match_operand:DI 0 "register_operand" "=r,r")
4620         (zero_extend:DI
4621          (match_operand:SI 1 "move_src_operand" "r,RQ")))]
4622   "TARGET_64BIT && GET_CODE (operands[1]) != CONST_INT"
4623   "@
4624    extrd,u %1,63,32,%0
4625    ldw%M1 %1,%0"
4626   [(set_attr "type" "shift,load")
4627    (set_attr "length" "4,4")])
4629 ;;- sign extension instructions
4631 (define_insn "extendhisi2"
4632   [(set (match_operand:SI 0 "register_operand" "=r")
4633         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
4634   ""
4635   "{extrs|extrw,s} %1,31,16,%0"
4636   [(set_attr "type" "shift")
4637    (set_attr "length" "4")])
4639 (define_insn "extendqihi2"
4640   [(set (match_operand:HI 0 "register_operand" "=r")
4641         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
4642   ""
4643   "{extrs|extrw,s} %1,31,8,%0"
4644   [(set_attr "type" "shift") 
4645   (set_attr "length" "4")])
4647 (define_insn "extendqisi2"
4648   [(set (match_operand:SI 0 "register_operand" "=r")
4649         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
4650   ""
4651   "{extrs|extrw,s} %1,31,8,%0"
4652   [(set_attr "type" "shift")
4653    (set_attr "length" "4")])
4655 (define_insn "extendqidi2"
4656   [(set (match_operand:DI 0 "register_operand" "=r")
4657         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4658   "TARGET_64BIT"
4659   "extrd,s %1,63,8,%0"
4660   [(set_attr "type" "shift") 
4661   (set_attr "length" "4")])
4663 (define_insn "extendhidi2"
4664   [(set (match_operand:DI 0 "register_operand" "=r")
4665         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4666   "TARGET_64BIT"
4667   "extrd,s %1,63,16,%0"
4668   [(set_attr "type" "shift") 
4669   (set_attr "length" "4")])
4671 (define_insn "extendsidi2"
4672   [(set (match_operand:DI 0 "register_operand" "=r")
4673         (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4674   "TARGET_64BIT"
4675   "extrd,s %1,63,32,%0"
4676   [(set_attr "type" "shift") 
4677   (set_attr "length" "4")])
4680 ;; Conversions between float and double.
4682 (define_insn "extendsfdf2"
4683   [(set (match_operand:DF 0 "register_operand" "=f")
4684         (float_extend:DF
4685          (match_operand:SF 1 "register_operand" "f")))]
4686   "! TARGET_SOFT_FLOAT"
4687   "{fcnvff|fcnv},sgl,dbl %1,%0"
4688   [(set_attr "type" "fpalu")
4689    (set_attr "length" "4")])
4691 (define_insn "truncdfsf2"
4692   [(set (match_operand:SF 0 "register_operand" "=f")
4693         (float_truncate:SF
4694          (match_operand:DF 1 "register_operand" "f")))]
4695   "! TARGET_SOFT_FLOAT"
4696   "{fcnvff|fcnv},dbl,sgl %1,%0"
4697   [(set_attr "type" "fpalu")
4698    (set_attr "length" "4")])
4700 ;; Conversion between fixed point and floating point.
4701 ;; Note that among the fix-to-float insns
4702 ;; the ones that start with SImode come first.
4703 ;; That is so that an operand that is a CONST_INT
4704 ;; (and therefore lacks a specific machine mode).
4705 ;; will be recognized as SImode (which is always valid)
4706 ;; rather than as QImode or HImode.
4708 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
4709 ;; to be reloaded by putting the constant into memory.
4710 ;; It must come before the more general floatsisf2 pattern.
4711 (define_insn ""
4712   [(set (match_operand:SF 0 "register_operand" "=f")
4713         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
4714   "! TARGET_SOFT_FLOAT"
4715   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
4716   [(set_attr "type" "fpalu")
4717    (set_attr "length" "8")])
4719 (define_insn "floatsisf2"
4720   [(set (match_operand:SF 0 "register_operand" "=f")
4721         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4722   "! TARGET_SOFT_FLOAT"
4723   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
4724   [(set_attr "type" "fpalu")
4725    (set_attr "length" "4")])
4727 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
4728 ;; to be reloaded by putting the constant into memory.
4729 ;; It must come before the more general floatsidf2 pattern.
4730 (define_insn ""
4731   [(set (match_operand:DF 0 "register_operand" "=f")
4732         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
4733   "! TARGET_SOFT_FLOAT"
4734   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
4735   [(set_attr "type" "fpalu")
4736    (set_attr "length" "8")])
4738 (define_insn "floatsidf2"
4739   [(set (match_operand:DF 0 "register_operand" "=f")
4740         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4741   "! TARGET_SOFT_FLOAT"
4742   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
4743   [(set_attr "type" "fpalu")
4744    (set_attr "length" "4")])
4746 (define_expand "floatunssisf2"
4747   [(set (subreg:SI (match_dup 2) 4)
4748         (match_operand:SI 1 "register_operand" ""))
4749    (set (subreg:SI (match_dup 2) 0)
4750         (const_int 0))
4751    (set (match_operand:SF 0 "register_operand" "")
4752         (float:SF (match_dup 2)))]
4753   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4754   "
4756   if (TARGET_PA_20)
4757     {
4758       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
4759       DONE;
4760     }
4761   operands[2] = gen_reg_rtx (DImode);
4764 (define_expand "floatunssidf2"
4765   [(set (subreg:SI (match_dup 2) 4)
4766         (match_operand:SI 1 "register_operand" ""))
4767    (set (subreg:SI (match_dup 2) 0)
4768         (const_int 0))
4769    (set (match_operand:DF 0 "register_operand" "")
4770         (float:DF (match_dup 2)))]
4771   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4772   "
4774   if (TARGET_PA_20)
4775     {
4776       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
4777       DONE;
4778     }
4779   operands[2] = gen_reg_rtx (DImode);
4782 (define_insn "floatdisf2"
4783   [(set (match_operand:SF 0 "register_operand" "=f")
4784         (float:SF (match_operand:DI 1 "register_operand" "f")))]
4785   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4786   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
4787   [(set_attr "type" "fpalu")
4788    (set_attr "length" "4")])
4790 (define_insn "floatdidf2"
4791   [(set (match_operand:DF 0 "register_operand" "=f")
4792         (float:DF (match_operand:DI 1 "register_operand" "f")))]
4793   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4794   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
4795   [(set_attr "type" "fpalu")
4796    (set_attr "length" "4")])
4798 ;; Convert a float to an actual integer.
4799 ;; Truncation is performed as part of the conversion.
4801 (define_insn "fix_truncsfsi2"
4802   [(set (match_operand:SI 0 "register_operand" "=f")
4803         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4804   "! TARGET_SOFT_FLOAT"
4805   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
4806   [(set_attr "type" "fpalu")
4807    (set_attr "length" "4")])
4809 (define_insn "fix_truncdfsi2"
4810   [(set (match_operand:SI 0 "register_operand" "=f")
4811         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4812   "! TARGET_SOFT_FLOAT"
4813   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
4814   [(set_attr "type" "fpalu")
4815    (set_attr "length" "4")])
4817 (define_insn "fix_truncsfdi2"
4818   [(set (match_operand:DI 0 "register_operand" "=f")
4819         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4820   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4821   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
4822   [(set_attr "type" "fpalu")
4823    (set_attr "length" "4")])
4825 (define_insn "fix_truncdfdi2"
4826   [(set (match_operand:DI 0 "register_operand" "=f")
4827         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4828   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
4829   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
4830   [(set_attr "type" "fpalu")
4831    (set_attr "length" "4")])
4833 (define_insn "floatunssidf2_pa20"
4834   [(set (match_operand:DF 0 "register_operand" "=f")
4835         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
4836   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4837   "fcnv,uw,dbl %1,%0"
4838   [(set_attr "type" "fpalu")
4839    (set_attr "length" "4")])
4841 (define_insn "floatunssisf2_pa20"
4842   [(set (match_operand:SF 0 "register_operand" "=f")
4843         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
4844   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4845   "fcnv,uw,sgl %1,%0"
4846   [(set_attr "type" "fpalu")
4847    (set_attr "length" "4")])
4849 (define_insn "floatunsdisf2"
4850   [(set (match_operand:SF 0 "register_operand" "=f")
4851         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
4852   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4853   "fcnv,udw,sgl %1,%0"
4854   [(set_attr "type" "fpalu")
4855    (set_attr "length" "4")])
4857 (define_insn "floatunsdidf2"
4858   [(set (match_operand:DF 0 "register_operand" "=f")
4859         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
4860   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4861   "fcnv,udw,dbl %1,%0"
4862   [(set_attr "type" "fpalu")
4863    (set_attr "length" "4")])
4865 (define_insn "fixuns_truncsfsi2"
4866   [(set (match_operand:SI 0 "register_operand" "=f")
4867         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4868   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4869   "fcnv,t,sgl,uw %1,%0"
4870   [(set_attr "type" "fpalu")
4871    (set_attr "length" "4")])
4873 (define_insn "fixuns_truncdfsi2"
4874   [(set (match_operand:SI 0 "register_operand" "=f")
4875         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4876   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4877   "fcnv,t,dbl,uw %1,%0"
4878   [(set_attr "type" "fpalu")
4879    (set_attr "length" "4")])
4881 (define_insn "fixuns_truncsfdi2"
4882   [(set (match_operand:DI 0 "register_operand" "=f")
4883         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4884   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4885   "fcnv,t,sgl,udw %1,%0"
4886   [(set_attr "type" "fpalu")
4887    (set_attr "length" "4")])
4889 (define_insn "fixuns_truncdfdi2"
4890   [(set (match_operand:DI 0 "register_operand" "=f")
4891         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
4892   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4893   "fcnv,t,dbl,udw %1,%0"
4894   [(set_attr "type" "fpalu")
4895    (set_attr "length" "4")])
4897 ;;- arithmetic instructions
4899 (define_expand "adddi3"
4900   [(set (match_operand:DI 0 "register_operand" "")
4901         (plus:DI (match_operand:DI 1 "register_operand" "")
4902                  (match_operand:DI 2 "adddi3_operand" "")))]
4903   ""
4904   "")
4906 (define_insn ""
4907   [(set (match_operand:DI 0 "register_operand" "=r")
4908         (plus:DI (match_operand:DI 1 "register_operand" "%r")
4909                  (match_operand:DI 2 "arith11_operand" "rI")))]
4910   "!TARGET_64BIT"
4911   "*
4913   if (GET_CODE (operands[2]) == CONST_INT)
4914     {
4915       if (INTVAL (operands[2]) >= 0)
4916         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
4917       else
4918         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
4919     }
4920   else
4921     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
4923   [(set_attr "type" "binary")
4924    (set_attr "length" "8")])
4926 (define_insn ""
4927   [(set (match_operand:DI 0 "register_operand" "=r,r")
4928         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4929                  (match_operand:DI 2 "arith_operand" "r,J")))]
4930   "TARGET_64BIT"
4931   "@
4932    add,l %1,%2,%0
4933    ldo %2(%1),%0"
4934   [(set_attr "type" "binary,binary")
4935    (set_attr "pa_combine_type" "addmove")
4936    (set_attr "length" "4,4")])
4938 (define_insn ""
4939   [(set (match_operand:DI 0 "register_operand" "=r")
4940         (plus:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4941                  (match_operand:DI 2 "register_operand" "r")))]
4942   "TARGET_64BIT"
4943   "uaddcm %2,%1,%0"
4944   [(set_attr "type" "binary")
4945    (set_attr "length" "4")])
4947 (define_insn ""
4948   [(set (match_operand:SI 0 "register_operand" "=r")
4949         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4950                  (match_operand:SI 2 "register_operand" "r")))]
4951   ""
4952   "uaddcm %2,%1,%0"
4953   [(set_attr "type" "binary")
4954    (set_attr "length" "4")])
4956 ;; define_splits to optimize cases of adding a constant integer
4957 ;; to a register when the constant does not fit in 14 bits.  */
4958 (define_split
4959   [(set (match_operand:SI 0 "register_operand" "")
4960         (plus:SI (match_operand:SI 1 "register_operand" "")
4961                  (match_operand:SI 2 "const_int_operand" "")))
4962    (clobber (match_operand:SI 4 "register_operand" ""))]
4963   "! cint_ok_for_move (INTVAL (operands[2]))
4964    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
4965   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
4966    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
4967   "
4969   int val = INTVAL (operands[2]);
4970   int low = (val < 0) ? -0x2000 : 0x1fff;
4971   int rest = val - low;
4973   operands[2] = GEN_INT (rest);
4974   operands[3] = GEN_INT (low);
4977 (define_split
4978   [(set (match_operand:SI 0 "register_operand" "")
4979         (plus:SI (match_operand:SI 1 "register_operand" "")
4980                  (match_operand:SI 2 "const_int_operand" "")))
4981    (clobber (match_operand:SI 4 "register_operand" ""))]
4982   "! cint_ok_for_move (INTVAL (operands[2]))"
4983   [(set (match_dup 4) (match_dup 2))
4984    (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
4985                                (match_dup 1)))]
4986   "
4988   HOST_WIDE_INT intval = INTVAL (operands[2]);
4990   /* Try dividing the constant by 2, then 4, and finally 8 to see
4991      if we can get a constant which can be loaded into a register
4992      in a single instruction (cint_ok_for_move). 
4994      If that fails, try to negate the constant and subtract it
4995      from our input operand.  */
4996   if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
4997     {
4998       operands[2] = GEN_INT (intval / 2);
4999       operands[3] = const2_rtx;
5000     }
5001   else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
5002     {
5003       operands[2] = GEN_INT (intval / 4);
5004       operands[3] = GEN_INT (4);
5005     }
5006   else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
5007     {
5008       operands[2] = GEN_INT (intval / 8);
5009       operands[3] = GEN_INT (8);
5010     }
5011   else if (cint_ok_for_move (-intval))
5012     {
5013       emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
5014       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
5015       DONE;
5016     }
5017   else
5018     FAIL;
5021 (define_insn "addsi3"
5022   [(set (match_operand:SI 0 "register_operand" "=r,r")
5023         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
5024                  (match_operand:SI 2 "arith_operand" "r,J")))]
5025   ""
5026   "@
5027    {addl|add,l} %1,%2,%0
5028    ldo %2(%1),%0"
5029   [(set_attr "type" "binary,binary")
5030    (set_attr "pa_combine_type" "addmove")
5031    (set_attr "length" "4,4")])
5033 (define_expand "subdi3"
5034   [(set (match_operand:DI 0 "register_operand" "")
5035         (minus:DI (match_operand:DI 1 "register_operand" "")
5036                   (match_operand:DI 2 "register_operand" "")))]
5037   ""
5038   "")
5040 (define_insn ""
5041   [(set (match_operand:DI 0 "register_operand" "=r")
5042         (minus:DI (match_operand:DI 1 "register_operand" "r")
5043                   (match_operand:DI 2 "register_operand" "r")))]
5044   "!TARGET_64BIT"
5045   "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
5046   [(set_attr "type" "binary")
5047   (set_attr "length" "8")])
5049 (define_insn ""
5050   [(set (match_operand:DI 0 "register_operand" "=r,r,!q")
5051         (minus:DI (match_operand:DI 1 "arith11_operand" "r,I,!U")
5052                   (match_operand:DI 2 "register_operand" "r,r,!r")))]
5053   "TARGET_64BIT"
5054   "@
5055    sub %1,%2,%0
5056    subi %1,%2,%0
5057    mtsarcm %2"
5058   [(set_attr "type" "binary,binary,move")
5059   (set_attr "length" "4,4,4")])
5061 (define_expand "subsi3"
5062   [(set (match_operand:SI 0 "register_operand" "")
5063         (minus:SI (match_operand:SI 1 "arith11_operand" "")
5064                   (match_operand:SI 2 "register_operand" "")))]
5065   ""
5066   "")
5068 (define_insn ""
5069   [(set (match_operand:SI 0 "register_operand" "=r,r")
5070         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
5071                   (match_operand:SI 2 "register_operand" "r,r")))]
5072   "!TARGET_PA_20"
5073   "@
5074    sub %1,%2,%0
5075    subi %1,%2,%0"
5076   [(set_attr "type" "binary,binary")
5077    (set_attr "length" "4,4")])
5079 (define_insn ""
5080   [(set (match_operand:SI 0 "register_operand" "=r,r,!q")
5081         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,!S")
5082                   (match_operand:SI 2 "register_operand" "r,r,!r")))]
5083   "TARGET_PA_20"
5084   "@
5085    sub %1,%2,%0
5086    subi %1,%2,%0
5087    mtsarcm %2"
5088   [(set_attr "type" "binary,binary,move")
5089    (set_attr "length" "4,4,4")])
5091 ;; Clobbering a "register_operand" instead of a match_scratch
5092 ;; in operand3 of millicode calls avoids spilling %r1 and
5093 ;; produces better code.
5095 ;; The mulsi3 insns set up registers for the millicode call.
5096 (define_expand "mulsi3"
5097   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5098    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5099    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5100               (clobber (match_dup 3))
5101               (clobber (reg:SI 26))
5102               (clobber (reg:SI 25))
5103               (clobber (match_dup 4))])
5104    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
5105   ""
5106   "
5108   operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
5109   if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
5110     {
5111       rtx scratch = gen_reg_rtx (DImode);
5112       operands[1] = force_reg (SImode, operands[1]);
5113       operands[2] = force_reg (SImode, operands[2]);
5114       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
5115       emit_insn (gen_movsi (operands[0],
5116                             gen_rtx_SUBREG (SImode, scratch,
5117                                             GET_MODE_SIZE (SImode))));
5118       DONE;
5119     }
5120   operands[3] = gen_reg_rtx (SImode);
5123 (define_insn "umulsidi3"
5124   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5125         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5126                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
5127   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5128   "xmpyu %1,%2,%0"
5129   [(set_attr "type" "fpmuldbl")
5130    (set_attr "length" "4")])
5132 (define_insn ""
5133   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5134         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5135                  (match_operand:DI 2 "uint32_operand" "f")))]
5136   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && !TARGET_64BIT"
5137   "xmpyu %1,%R2,%0"
5138   [(set_attr "type" "fpmuldbl")
5139    (set_attr "length" "4")])
5141 (define_insn ""
5142   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
5143         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
5144                  (match_operand:DI 2 "uint32_operand" "f")))]
5145   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT && TARGET_64BIT"
5146   "xmpyu %1,%2R,%0"
5147   [(set_attr "type" "fpmuldbl")
5148    (set_attr "length" "4")])
5150 (define_insn ""
5151   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5152    (clobber (match_operand:SI 0 "register_operand" "=a"))
5153    (clobber (reg:SI 26))
5154    (clobber (reg:SI 25))
5155    (clobber (reg:SI 31))]
5156   "!TARGET_64BIT"
5157   "* return output_mul_insn (0, insn);"
5158   [(set_attr "type" "milli")
5159    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5161 (define_insn ""
5162   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
5163    (clobber (match_operand:SI 0 "register_operand" "=a"))
5164    (clobber (reg:SI 26))
5165    (clobber (reg:SI 25))
5166    (clobber (reg:SI 2))]
5167   "TARGET_64BIT"
5168   "* return output_mul_insn (0, insn);"
5169   [(set_attr "type" "milli")
5170    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5172 (define_expand "muldi3"
5173   [(set (match_operand:DI 0 "register_operand" "")
5174         (mult:DI (match_operand:DI 1 "register_operand" "")
5175                  (match_operand:DI 2 "register_operand" "")))]
5176   "TARGET_64BIT && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
5177   "
5179   rtx low_product = gen_reg_rtx (DImode);
5180   rtx cross_product1 = gen_reg_rtx (DImode);
5181   rtx cross_product2 = gen_reg_rtx (DImode);
5182   rtx cross_scratch = gen_reg_rtx (DImode);
5183   rtx cross_product = gen_reg_rtx (DImode);
5184   rtx op1l, op1r, op2l, op2r;
5185   rtx op1shifted, op2shifted;
5187   op1shifted = gen_reg_rtx (DImode);
5188   op2shifted = gen_reg_rtx (DImode);
5189   op1l = gen_reg_rtx (SImode);
5190   op1r = gen_reg_rtx (SImode);
5191   op2l = gen_reg_rtx (SImode);
5192   op2r = gen_reg_rtx (SImode);
5194   emit_move_insn (op1shifted, gen_rtx_LSHIFTRT (DImode, operands[1],
5195                                                 GEN_INT (32)));
5196   emit_move_insn (op2shifted, gen_rtx_LSHIFTRT (DImode, operands[2],
5197                                                 GEN_INT (32)));
5198   op1r = gen_rtx_SUBREG (SImode, operands[1], 4);
5199   op2r = gen_rtx_SUBREG (SImode, operands[2], 4);
5200   op1l = gen_rtx_SUBREG (SImode, op1shifted, 4);
5201   op2l = gen_rtx_SUBREG (SImode, op2shifted, 4);
5203   /* Emit multiplies for the cross products.  */
5204   emit_insn (gen_umulsidi3 (cross_product1, op2r, op1l));
5205   emit_insn (gen_umulsidi3 (cross_product2, op2l, op1r));
5207   /* Emit a multiply for the low sub-word.  */
5208   emit_insn (gen_umulsidi3 (low_product, copy_rtx (op2r), copy_rtx (op1r)));
5210   /* Sum the cross products and shift them into proper position.  */
5211   emit_insn (gen_adddi3 (cross_scratch, cross_product1, cross_product2));
5212   emit_insn (gen_ashldi3 (cross_product, cross_scratch, GEN_INT (32)));
5214   /* Add the cross product to the low product and store the result
5215      into the output operand .  */
5216   emit_insn (gen_adddi3 (operands[0], cross_product, low_product));
5217   DONE;
5220 ;;; Division and mod.
5221 (define_expand "divsi3"
5222   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5223    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5224    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
5225               (clobber (match_dup 3))
5226               (clobber (match_dup 4))
5227               (clobber (reg:SI 26))
5228               (clobber (reg:SI 25))
5229               (clobber (match_dup 5))])
5230    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
5231   ""
5232   "
5234   operands[3] = gen_reg_rtx (SImode);
5235   if (TARGET_64BIT)
5236     {
5237       operands[5] = gen_rtx_REG (SImode, 2);
5238       operands[4] = operands[5];
5239     }
5240   else
5241     {
5242       operands[5] = gen_rtx_REG (SImode, 31);
5243       operands[4] = gen_reg_rtx (SImode);
5244     }
5245   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
5246     DONE;
5249 (define_insn ""
5250   [(set (reg:SI 29)
5251         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5252    (clobber (match_operand:SI 1 "register_operand" "=a"))
5253    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5254    (clobber (reg:SI 26))
5255    (clobber (reg:SI 25))
5256    (clobber (reg:SI 31))]
5257   "!TARGET_64BIT"
5258   "*
5259    return output_div_insn (operands, 0, insn);"
5260   [(set_attr "type" "milli")
5261    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5263 (define_insn ""
5264   [(set (reg:SI 29)
5265         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5266    (clobber (match_operand:SI 1 "register_operand" "=a"))
5267    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5268    (clobber (reg:SI 26))
5269    (clobber (reg:SI 25))
5270    (clobber (reg:SI 2))]
5271   "TARGET_64BIT"
5272   "*
5273    return output_div_insn (operands, 0, insn);"
5274   [(set_attr "type" "milli")
5275    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5277 (define_expand "udivsi3"
5278   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5279    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5280    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
5281               (clobber (match_dup 3))
5282               (clobber (match_dup 4))
5283               (clobber (reg:SI 26))
5284               (clobber (reg:SI 25))
5285               (clobber (match_dup 5))])
5286    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
5287   ""
5288   "
5290   operands[3] = gen_reg_rtx (SImode);
5292   if (TARGET_64BIT)
5293     {
5294       operands[5] = gen_rtx_REG (SImode, 2);
5295       operands[4] = operands[5];
5296     }
5297   else
5298     {
5299       operands[5] = gen_rtx_REG (SImode, 31);
5300       operands[4] = gen_reg_rtx (SImode);
5301     }
5302   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
5303     DONE;
5306 (define_insn ""
5307   [(set (reg:SI 29)
5308         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5309    (clobber (match_operand:SI 1 "register_operand" "=a"))
5310    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5311    (clobber (reg:SI 26))
5312    (clobber (reg:SI 25))
5313    (clobber (reg:SI 31))]
5314   "!TARGET_64BIT"
5315   "*
5316    return output_div_insn (operands, 1, insn);"
5317   [(set_attr "type" "milli")
5318    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5320 (define_insn ""
5321   [(set (reg:SI 29)
5322         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
5323    (clobber (match_operand:SI 1 "register_operand" "=a"))
5324    (clobber (match_operand:SI 2 "register_operand" "=&r"))
5325    (clobber (reg:SI 26))
5326    (clobber (reg:SI 25))
5327    (clobber (reg:SI 2))]
5328   "TARGET_64BIT"
5329   "*
5330    return output_div_insn (operands, 1, insn);"
5331   [(set_attr "type" "milli")
5332    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5334 (define_expand "modsi3"
5335   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5336    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5337    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5338               (clobber (match_dup 3))
5339               (clobber (match_dup 4))
5340               (clobber (reg:SI 26))
5341               (clobber (reg:SI 25))
5342               (clobber (match_dup 5))])
5343    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
5344   ""
5345   "
5347   if (TARGET_64BIT)
5348     {
5349       operands[5] = gen_rtx_REG (SImode, 2);
5350       operands[4] = operands[5];
5351     }
5352   else
5353     {
5354       operands[5] = gen_rtx_REG (SImode, 31);
5355       operands[4] = gen_reg_rtx (SImode);
5356     }
5357   operands[3] = gen_reg_rtx (SImode);
5360 (define_insn ""
5361   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5362    (clobber (match_operand:SI 0 "register_operand" "=a"))
5363    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5364    (clobber (reg:SI 26))
5365    (clobber (reg:SI 25))
5366    (clobber (reg:SI 31))]
5367   "!TARGET_64BIT"
5368   "*
5369   return output_mod_insn (0, insn);"
5370   [(set_attr "type" "milli")
5371    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5373 (define_insn ""
5374   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
5375    (clobber (match_operand:SI 0 "register_operand" "=a"))
5376    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5377    (clobber (reg:SI 26))
5378    (clobber (reg:SI 25))
5379    (clobber (reg:SI 2))]
5380   "TARGET_64BIT"
5381   "*
5382   return output_mod_insn (0, insn);"
5383   [(set_attr "type" "milli")
5384    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5386 (define_expand "umodsi3"
5387   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
5388    (set (reg:SI 25) (match_operand:SI 2 "move_src_operand" ""))
5389    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5390               (clobber (match_dup 3))
5391               (clobber (match_dup 4))
5392               (clobber (reg:SI 26))
5393               (clobber (reg:SI 25))
5394               (clobber (match_dup 5))])
5395    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
5396   ""
5397   "
5399   if (TARGET_64BIT)
5400     {
5401       operands[5] = gen_rtx_REG (SImode, 2);
5402       operands[4] = operands[5];
5403     }
5404   else
5405     {
5406       operands[5] = gen_rtx_REG (SImode, 31);
5407       operands[4] = gen_reg_rtx (SImode);
5408     }
5409   operands[3] = gen_reg_rtx (SImode);
5412 (define_insn ""
5413   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5414    (clobber (match_operand:SI 0 "register_operand" "=a"))
5415    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5416    (clobber (reg:SI 26))
5417    (clobber (reg:SI 25))
5418    (clobber (reg:SI 31))]
5419   "!TARGET_64BIT"
5420   "*
5421   return output_mod_insn (1, insn);"
5422   [(set_attr "type" "milli")
5423    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5425 (define_insn ""
5426   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
5427    (clobber (match_operand:SI 0 "register_operand" "=a"))
5428    (clobber (match_operand:SI 1 "register_operand" "=&r"))
5429    (clobber (reg:SI 26))
5430    (clobber (reg:SI 25))
5431    (clobber (reg:SI 2))]
5432   "TARGET_64BIT"
5433   "*
5434   return output_mod_insn (1, insn);"
5435   [(set_attr "type" "milli")
5436    (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
5438 ;;- and instructions
5439 ;; We define DImode `and` so with DImode `not` we can get
5440 ;; DImode `andn`.  Other combinations are possible.
5442 (define_expand "anddi3"
5443   [(set (match_operand:DI 0 "register_operand" "")
5444         (and:DI (match_operand:DI 1 "register_operand" "")
5445                 (match_operand:DI 2 "and_operand" "")))]
5446   ""
5447   "
5449   /* Both operands must be register operands.  */
5450   if (!TARGET_64BIT && !register_operand (operands[2], DImode))
5451     FAIL;
5454 (define_insn ""
5455   [(set (match_operand:DI 0 "register_operand" "=r")
5456         (and:DI (match_operand:DI 1 "register_operand" "%r")
5457                 (match_operand:DI 2 "register_operand" "r")))]
5458   "!TARGET_64BIT"
5459   "and %1,%2,%0\;and %R1,%R2,%R0"
5460   [(set_attr "type" "binary")
5461    (set_attr "length" "8")])
5463 (define_insn ""
5464   [(set (match_operand:DI 0 "register_operand" "=r,r")
5465         (and:DI (match_operand:DI 1 "register_operand" "%?r,0")
5466                 (match_operand:DI 2 "and_operand" "rO,P")))]
5467   "TARGET_64BIT"
5468   "* return output_64bit_and (operands); "
5469   [(set_attr "type" "binary")
5470    (set_attr "length" "4")])
5472 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
5473 ; constant with ldil;ldo.
5474 (define_insn "andsi3"
5475   [(set (match_operand:SI 0 "register_operand" "=r,r")
5476         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
5477                 (match_operand:SI 2 "and_operand" "rO,P")))]
5478   ""
5479   "* return output_and (operands); "
5480   [(set_attr "type" "binary,shift")
5481    (set_attr "length" "4,4")])
5483 (define_insn ""
5484   [(set (match_operand:DI 0 "register_operand" "=r")
5485         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5486                 (match_operand:DI 2 "register_operand" "r")))]
5487   "!TARGET_64BIT"
5488   "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
5489   [(set_attr "type" "binary")
5490    (set_attr "length" "8")])
5492 (define_insn ""
5493   [(set (match_operand:DI 0 "register_operand" "=r")
5494         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5495                 (match_operand:DI 2 "register_operand" "r")))]
5496   "TARGET_64BIT"
5497   "andcm %2,%1,%0"
5498   [(set_attr "type" "binary")
5499    (set_attr "length" "4")])
5501 (define_insn ""
5502   [(set (match_operand:SI 0 "register_operand" "=r")
5503         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5504                 (match_operand:SI 2 "register_operand" "r")))]
5505   ""
5506   "andcm %2,%1,%0"
5507   [(set_attr "type" "binary")
5508   (set_attr "length" "4")])
5510 (define_expand "iordi3"
5511   [(set (match_operand:DI 0 "register_operand" "")
5512         (ior:DI (match_operand:DI 1 "register_operand" "")
5513                 (match_operand:DI 2 "ior_operand" "")))]
5514   ""
5515   "
5517   /* Both operands must be register operands.  */
5518   if (!TARGET_64BIT && !register_operand (operands[2], DImode))
5519     FAIL;
5522 (define_insn ""
5523   [(set (match_operand:DI 0 "register_operand" "=r")
5524         (ior:DI (match_operand:DI 1 "register_operand" "%r")
5525                 (match_operand:DI 2 "register_operand" "r")))]
5526   "!TARGET_64BIT"
5527   "or %1,%2,%0\;or %R1,%R2,%R0"
5528   [(set_attr "type" "binary")
5529    (set_attr "length" "8")])
5531 (define_insn ""
5532   [(set (match_operand:DI 0 "register_operand" "=r,r")
5533         (ior:DI (match_operand:DI 1 "register_operand" "0,0")
5534                 (match_operand:DI 2 "ior_operand" "M,i")))]
5535   "TARGET_64BIT"
5536   "* return output_64bit_ior (operands); "
5537   [(set_attr "type" "binary,shift")
5538    (set_attr "length" "4,4")])
5540 (define_insn ""
5541   [(set (match_operand:DI 0 "register_operand" "=r")
5542         (ior:DI (match_operand:DI 1 "register_operand" "%r")
5543                 (match_operand:DI 2 "register_operand" "r")))]
5544   "TARGET_64BIT"
5545   "or %1,%2,%0"
5546   [(set_attr "type" "binary")
5547    (set_attr "length" "4")])
5549 ;; Need a define_expand because we've run out of CONST_OK... characters.
5550 (define_expand "iorsi3"
5551   [(set (match_operand:SI 0 "register_operand" "")
5552         (ior:SI (match_operand:SI 1 "register_operand" "")
5553                 (match_operand:SI 2 "arith32_operand" "")))]
5554   ""
5555   "
5557   if (! (ior_operand (operands[2], SImode)
5558          || register_operand (operands[2], SImode)))
5559     operands[2] = force_reg (SImode, operands[2]);
5562 (define_insn ""
5563   [(set (match_operand:SI 0 "register_operand" "=r,r")
5564         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
5565                 (match_operand:SI 2 "ior_operand" "M,i")))]
5566   ""
5567   "* return output_ior (operands); "
5568   [(set_attr "type" "binary,shift")
5569    (set_attr "length" "4,4")])
5571 (define_insn ""
5572   [(set (match_operand:SI 0 "register_operand" "=r")
5573         (ior:SI (match_operand:SI 1 "register_operand" "%r")
5574                 (match_operand:SI 2 "register_operand" "r")))]
5575   ""
5576   "or %1,%2,%0"
5577   [(set_attr "type" "binary")
5578    (set_attr "length" "4")])
5580 (define_expand "xordi3"
5581   [(set (match_operand:DI 0 "register_operand" "")
5582         (xor:DI (match_operand:DI 1 "register_operand" "")
5583                 (match_operand:DI 2 "register_operand" "")))]
5584   ""
5585   "
5589 (define_insn ""
5590   [(set (match_operand:DI 0 "register_operand" "=r")
5591         (xor:DI (match_operand:DI 1 "register_operand" "%r")
5592                 (match_operand:DI 2 "register_operand" "r")))]
5593   "!TARGET_64BIT"
5594   "xor %1,%2,%0\;xor %R1,%R2,%R0"
5595   [(set_attr "type" "binary")
5596    (set_attr "length" "8")])
5598 (define_insn ""
5599   [(set (match_operand:DI 0 "register_operand" "=r")
5600         (xor:DI (match_operand:DI 1 "register_operand" "%r")
5601                 (match_operand:DI 2 "register_operand" "r")))]
5602   "TARGET_64BIT"
5603   "xor %1,%2,%0"
5604   [(set_attr "type" "binary")
5605    (set_attr "length" "4")])
5607 (define_insn "xorsi3"
5608   [(set (match_operand:SI 0 "register_operand" "=r")
5609         (xor:SI (match_operand:SI 1 "register_operand" "%r")
5610                 (match_operand:SI 2 "register_operand" "r")))]
5611   ""
5612   "xor %1,%2,%0"
5613   [(set_attr "type" "binary")
5614    (set_attr "length" "4")])
5616 (define_expand "negdi2"
5617   [(set (match_operand:DI 0 "register_operand" "")
5618         (neg:DI (match_operand:DI 1 "register_operand" "")))]
5619   ""
5620   "")
5622 (define_insn ""
5623   [(set (match_operand:DI 0 "register_operand" "=r")
5624         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5625   "!TARGET_64BIT"
5626   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
5627   [(set_attr "type" "unary")
5628    (set_attr "length" "8")])
5630 (define_insn ""
5631   [(set (match_operand:DI 0 "register_operand" "=r")
5632         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5633   "TARGET_64BIT"
5634   "sub %%r0,%1,%0"
5635   [(set_attr "type" "unary")
5636    (set_attr "length" "4")])
5638 (define_insn "negsi2"
5639   [(set (match_operand:SI 0 "register_operand" "=r")
5640         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
5641   ""
5642   "sub %%r0,%1,%0"
5643   [(set_attr "type" "unary")
5644    (set_attr "length" "4")])
5646 (define_expand "one_cmpldi2"
5647   [(set (match_operand:DI 0 "register_operand" "")
5648         (not:DI (match_operand:DI 1 "register_operand" "")))]
5649   ""
5650   "
5654 (define_insn ""
5655   [(set (match_operand:DI 0 "register_operand" "=r")
5656         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5657   "!TARGET_64BIT"
5658   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
5659   [(set_attr "type" "unary")
5660    (set_attr "length" "8")])
5662 (define_insn ""
5663   [(set (match_operand:DI 0 "register_operand" "=r")
5664         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5665   "TARGET_64BIT"
5666   "uaddcm %%r0,%1,%0"
5667   [(set_attr "type" "unary")
5668    (set_attr "length" "4")])
5670 (define_insn "one_cmplsi2"
5671   [(set (match_operand:SI 0 "register_operand" "=r")
5672         (not:SI (match_operand:SI 1 "register_operand" "r")))]
5673   ""
5674   "uaddcm %%r0,%1,%0"
5675   [(set_attr "type" "unary")
5676    (set_attr "length" "4")])
5678 ;; Floating point arithmetic instructions.
5680 (define_insn "adddf3"
5681   [(set (match_operand:DF 0 "register_operand" "=f")
5682         (plus:DF (match_operand:DF 1 "register_operand" "f")
5683                  (match_operand:DF 2 "register_operand" "f")))]
5684   "! TARGET_SOFT_FLOAT"
5685   "fadd,dbl %1,%2,%0"
5686   [(set_attr "type" "fpalu")
5687    (set_attr "pa_combine_type" "faddsub")
5688    (set_attr "length" "4")])
5690 (define_insn "addsf3"
5691   [(set (match_operand:SF 0 "register_operand" "=f")
5692         (plus:SF (match_operand:SF 1 "register_operand" "f")
5693                  (match_operand:SF 2 "register_operand" "f")))]
5694   "! TARGET_SOFT_FLOAT"
5695   "fadd,sgl %1,%2,%0"
5696   [(set_attr "type" "fpalu")
5697    (set_attr "pa_combine_type" "faddsub")
5698    (set_attr "length" "4")])
5700 (define_insn "subdf3"
5701   [(set (match_operand:DF 0 "register_operand" "=f")
5702         (minus:DF (match_operand:DF 1 "register_operand" "f")
5703                   (match_operand:DF 2 "register_operand" "f")))]
5704   "! TARGET_SOFT_FLOAT"
5705   "fsub,dbl %1,%2,%0"
5706   [(set_attr "type" "fpalu")
5707    (set_attr "pa_combine_type" "faddsub")
5708    (set_attr "length" "4")])
5710 (define_insn "subsf3"
5711   [(set (match_operand:SF 0 "register_operand" "=f")
5712         (minus:SF (match_operand:SF 1 "register_operand" "f")
5713                   (match_operand:SF 2 "register_operand" "f")))]
5714   "! TARGET_SOFT_FLOAT"
5715   "fsub,sgl %1,%2,%0"
5716   [(set_attr "type" "fpalu")
5717    (set_attr "pa_combine_type" "faddsub")
5718    (set_attr "length" "4")])
5720 (define_insn "muldf3"
5721   [(set (match_operand:DF 0 "register_operand" "=f")
5722         (mult:DF (match_operand:DF 1 "register_operand" "f")
5723                  (match_operand:DF 2 "register_operand" "f")))]
5724   "! TARGET_SOFT_FLOAT"
5725   "fmpy,dbl %1,%2,%0"
5726   [(set_attr "type" "fpmuldbl")
5727    (set_attr "pa_combine_type" "fmpy")
5728    (set_attr "length" "4")])
5730 (define_insn "mulsf3"
5731   [(set (match_operand:SF 0 "register_operand" "=f")
5732         (mult:SF (match_operand:SF 1 "register_operand" "f")
5733                  (match_operand:SF 2 "register_operand" "f")))]
5734   "! TARGET_SOFT_FLOAT"
5735   "fmpy,sgl %1,%2,%0"
5736   [(set_attr "type" "fpmulsgl")
5737    (set_attr "pa_combine_type" "fmpy")
5738    (set_attr "length" "4")])
5740 (define_insn "divdf3"
5741   [(set (match_operand:DF 0 "register_operand" "=f")
5742         (div:DF (match_operand:DF 1 "register_operand" "f")
5743                 (match_operand:DF 2 "register_operand" "f")))]
5744   "! TARGET_SOFT_FLOAT"
5745   "fdiv,dbl %1,%2,%0"
5746   [(set_attr "type" "fpdivdbl")
5747    (set_attr "length" "4")])
5749 (define_insn "divsf3"
5750   [(set (match_operand:SF 0 "register_operand" "=f")
5751         (div:SF (match_operand:SF 1 "register_operand" "f")
5752                 (match_operand:SF 2 "register_operand" "f")))]
5753   "! TARGET_SOFT_FLOAT"
5754   "fdiv,sgl %1,%2,%0"
5755   [(set_attr "type" "fpdivsgl")
5756    (set_attr "length" "4")])
5758 ;; Processors prior to PA 2.0 don't have a fneg instruction.  Fast
5759 ;; negation can be done by subtracting from plus zero.  However, this
5760 ;; violates the IEEE standard when negating plus and minus zero.
5761 (define_expand "negdf2"
5762   [(parallel [(set (match_operand:DF 0 "register_operand" "")
5763                    (neg:DF (match_operand:DF 1 "register_operand" "")))
5764               (use (match_dup 2))])]
5765   "! TARGET_SOFT_FLOAT"
5767   if (TARGET_PA_20 || flag_unsafe_math_optimizations)
5768     emit_insn (gen_negdf2_fast (operands[0], operands[1]));
5769   else
5770     {
5771       operands[2] = force_reg (DFmode,
5772         CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, DFmode));
5773       emit_insn (gen_muldf3 (operands[0], operands[1], operands[2]));
5774     }
5775   DONE;
5778 (define_insn "negdf2_fast"
5779   [(set (match_operand:DF 0 "register_operand" "=f")
5780         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
5781   "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
5782   "*
5784   if (TARGET_PA_20)
5785     return \"fneg,dbl %1,%0\";
5786   else
5787     return \"fsub,dbl %%fr0,%1,%0\";
5789   [(set_attr "type" "fpalu")
5790    (set_attr "length" "4")])
5792 (define_expand "negsf2"
5793   [(parallel [(set (match_operand:SF 0 "register_operand" "")
5794                    (neg:SF (match_operand:SF 1 "register_operand" "")))
5795               (use (match_dup 2))])]
5796   "! TARGET_SOFT_FLOAT"
5798   if (TARGET_PA_20 || flag_unsafe_math_optimizations)
5799     emit_insn (gen_negsf2_fast (operands[0], operands[1]));
5800   else
5801     {
5802       operands[2] = force_reg (SFmode,
5803         CONST_DOUBLE_FROM_REAL_VALUE (dconstm1, SFmode));
5804       emit_insn (gen_mulsf3 (operands[0], operands[1], operands[2]));
5805     }
5806   DONE;
5809 (define_insn "negsf2_fast"
5810   [(set (match_operand:SF 0 "register_operand" "=f")
5811         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5812   "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
5813   "*
5815   if (TARGET_PA_20)
5816     return \"fneg,sgl %1,%0\";
5817   else
5818     return \"fsub,sgl %%fr0,%1,%0\";
5820   [(set_attr "type" "fpalu")
5821    (set_attr "length" "4")])
5823 (define_insn "absdf2"
5824   [(set (match_operand:DF 0 "register_operand" "=f")
5825         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
5826   "! TARGET_SOFT_FLOAT"
5827   "fabs,dbl %1,%0"
5828   [(set_attr "type" "fpalu")
5829    (set_attr "length" "4")])
5831 (define_insn "abssf2"
5832   [(set (match_operand:SF 0 "register_operand" "=f")
5833         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5834   "! TARGET_SOFT_FLOAT"
5835   "fabs,sgl %1,%0"
5836   [(set_attr "type" "fpalu")
5837    (set_attr "length" "4")])
5839 (define_insn "sqrtdf2"
5840   [(set (match_operand:DF 0 "register_operand" "=f")
5841         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
5842   "! TARGET_SOFT_FLOAT"
5843   "fsqrt,dbl %1,%0"
5844   [(set_attr "type" "fpsqrtdbl")
5845    (set_attr "length" "4")])
5847 (define_insn "sqrtsf2"
5848   [(set (match_operand:SF 0 "register_operand" "=f")
5849         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5850   "! TARGET_SOFT_FLOAT"
5851   "fsqrt,sgl %1,%0"
5852   [(set_attr "type" "fpsqrtsgl")
5853    (set_attr "length" "4")])
5855 ;; PA 2.0 floating point instructions
5857 ; fmpyfadd patterns
5858 (define_insn ""
5859   [(set (match_operand:DF 0 "register_operand" "=f")
5860         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5861                           (match_operand:DF 2 "register_operand" "f"))
5862                  (match_operand:DF 3 "register_operand" "f")))]
5863   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5864   "fmpyfadd,dbl %1,%2,%3,%0"
5865   [(set_attr "type" "fpmuldbl")
5866    (set_attr "length" "4")])
5868 (define_insn ""
5869   [(set (match_operand:DF 0 "register_operand" "=f")
5870         (plus:DF (match_operand:DF 1 "register_operand" "f")
5871                  (mult:DF (match_operand:DF 2 "register_operand" "f")
5872                           (match_operand:DF 3 "register_operand" "f"))))]
5873   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5874   "fmpyfadd,dbl %2,%3,%1,%0"
5875   [(set_attr "type" "fpmuldbl")
5876    (set_attr "length" "4")])
5878 (define_insn ""
5879   [(set (match_operand:SF 0 "register_operand" "=f")
5880         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5881                           (match_operand:SF 2 "register_operand" "f"))
5882                  (match_operand:SF 3 "register_operand" "f")))]
5883   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5884   "fmpyfadd,sgl %1,%2,%3,%0"
5885   [(set_attr "type" "fpmulsgl")
5886    (set_attr "length" "4")])
5888 (define_insn ""
5889   [(set (match_operand:SF 0 "register_operand" "=f")
5890         (plus:SF (match_operand:SF 1 "register_operand" "f")
5891                  (mult:SF (match_operand:SF 2 "register_operand" "f")
5892                           (match_operand:SF 3 "register_operand" "f"))))]
5893   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5894   "fmpyfadd,sgl %2,%3,%1,%0"
5895   [(set_attr "type" "fpmulsgl")
5896    (set_attr "length" "4")])
5898 ; fmpynfadd patterns
5899 (define_insn ""
5900   [(set (match_operand:DF 0 "register_operand" "=f")
5901         (minus:DF (match_operand:DF 1 "register_operand" "f")
5902                   (mult:DF (match_operand:DF 2 "register_operand" "f")
5903                            (match_operand:DF 3 "register_operand" "f"))))]
5904   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5905   "fmpynfadd,dbl %2,%3,%1,%0"
5906   [(set_attr "type" "fpmuldbl")
5907    (set_attr "length" "4")])
5909 (define_insn ""
5910   [(set (match_operand:SF 0 "register_operand" "=f")
5911         (minus:SF (match_operand:SF 1 "register_operand" "f")
5912                   (mult:SF (match_operand:SF 2 "register_operand" "f")
5913                            (match_operand:SF 3 "register_operand" "f"))))]
5914   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5915   "fmpynfadd,sgl %2,%3,%1,%0"
5916   [(set_attr "type" "fpmulsgl")
5917    (set_attr "length" "4")])
5919 ; fnegabs patterns
5920 (define_insn ""
5921   [(set (match_operand:DF 0 "register_operand" "=f")
5922         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
5923   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5924   "fnegabs,dbl %1,%0"
5925   [(set_attr "type" "fpalu")
5926    (set_attr "length" "4")])
5928 (define_insn ""
5929   [(set (match_operand:SF 0 "register_operand" "=f")
5930         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
5931   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
5932   "fnegabs,sgl %1,%0"
5933   [(set_attr "type" "fpalu")
5934    (set_attr "length" "4")])
5936 ;; Generating a fused multiply sequence is a win for this case as it will
5937 ;; reduce the latency for the fused case without impacting the plain
5938 ;; multiply case.
5940 ;; Similar possibilities exist for fnegabs, shadd and other insns which
5941 ;; perform two operations with the result of the first feeding the second.
5942 (define_insn ""
5943   [(set (match_operand:DF 0 "register_operand" "=f")
5944         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
5945                           (match_operand:DF 2 "register_operand" "f"))
5946                  (match_operand:DF 3 "register_operand" "f")))
5947    (set (match_operand:DF 4 "register_operand" "=&f")
5948         (mult:DF (match_dup 1) (match_dup 2)))]
5949   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5950     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5951           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5952   "#"
5953   [(set_attr "type" "fpmuldbl")
5954    (set_attr "length" "8")])
5956 ;; We want to split this up during scheduling since we want both insns
5957 ;; to schedule independently.
5958 (define_split
5959   [(set (match_operand:DF 0 "register_operand" "")
5960         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "")
5961                           (match_operand:DF 2 "register_operand" ""))
5962                  (match_operand:DF 3 "register_operand" "")))
5963    (set (match_operand:DF 4 "register_operand" "")
5964         (mult:DF (match_dup 1) (match_dup 2)))]
5965   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5966   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
5967    (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
5968                                (match_dup 3)))]
5969   "")
5971 (define_insn ""
5972   [(set (match_operand:SF 0 "register_operand" "=f")
5973         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
5974                           (match_operand:SF 2 "register_operand" "f"))
5975                  (match_operand:SF 3 "register_operand" "f")))
5976    (set (match_operand:SF 4 "register_operand" "=&f")
5977         (mult:SF (match_dup 1) (match_dup 2)))]
5978   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
5979     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
5980           || reg_overlap_mentioned_p (operands[4], operands[2])))"
5981   "#"
5982   [(set_attr "type" "fpmuldbl")
5983    (set_attr "length" "8")])
5985 ;; We want to split this up during scheduling since we want both insns
5986 ;; to schedule independently.
5987 (define_split
5988   [(set (match_operand:SF 0 "register_operand" "")
5989         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "")
5990                           (match_operand:SF 2 "register_operand" ""))
5991                  (match_operand:SF 3 "register_operand" "")))
5992    (set (match_operand:SF 4 "register_operand" "")
5993         (mult:SF (match_dup 1) (match_dup 2)))]
5994   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
5995   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
5996    (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
5997                                (match_dup 3)))]
5998   "")
6000 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
6001 ;; instruction.
6002 (define_insn ""
6003   [(set (match_operand:DF 0 "register_operand" "=f")
6004         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6005                          (match_operand:DF 2 "register_operand" "f"))))]
6006   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6007   "fmpynfadd,dbl %1,%2,%%fr0,%0"
6008   [(set_attr "type" "fpmuldbl")
6009    (set_attr "length" "4")])
6011 (define_insn ""
6012   [(set (match_operand:SF 0 "register_operand" "=f")
6013         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6014                          (match_operand:SF 2 "register_operand" "f"))))]
6015   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6016   "fmpynfadd,sgl %1,%2,%%fr0,%0"
6017   [(set_attr "type" "fpmuldbl")
6018    (set_attr "length" "4")])
6020 (define_insn ""
6021   [(set (match_operand:DF 0 "register_operand" "=f")
6022         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6023                          (match_operand:DF 2 "register_operand" "f"))))
6024    (set (match_operand:DF 3 "register_operand" "=&f")
6025         (mult:DF (match_dup 1) (match_dup 2)))]
6026   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6027     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6028           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6029   "#"
6030   [(set_attr "type" "fpmuldbl")
6031    (set_attr "length" "8")])
6033 (define_split
6034   [(set (match_operand:DF 0 "register_operand" "")
6035         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6036                          (match_operand:DF 2 "register_operand" ""))))
6037    (set (match_operand:DF 3 "register_operand" "")
6038         (mult:DF (match_dup 1) (match_dup 2)))]
6039   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6040   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
6041    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
6042   "")
6044 (define_insn ""
6045   [(set (match_operand:SF 0 "register_operand" "=f")
6046         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6047                          (match_operand:SF 2 "register_operand" "f"))))
6048    (set (match_operand:SF 3 "register_operand" "=&f")
6049         (mult:SF (match_dup 1) (match_dup 2)))]
6050   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6051     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
6052           || reg_overlap_mentioned_p (operands[3], operands[2])))"
6053   "#"
6054   [(set_attr "type" "fpmuldbl")
6055    (set_attr "length" "8")])
6057 (define_split
6058   [(set (match_operand:SF 0 "register_operand" "")
6059         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6060                          (match_operand:SF 2 "register_operand" ""))))
6061    (set (match_operand:SF 3 "register_operand" "")
6062         (mult:SF (match_dup 1) (match_dup 2)))]
6063   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6064   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
6065    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
6066   "")
6068 ;; Now fused multiplies with the result of the multiply negated.
6069 (define_insn ""
6070   [(set (match_operand:DF 0 "register_operand" "=f")
6071         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6072                                   (match_operand:DF 2 "register_operand" "f")))
6073                  (match_operand:DF 3 "register_operand" "f")))]
6074   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6075   "fmpynfadd,dbl %1,%2,%3,%0"
6076   [(set_attr "type" "fpmuldbl")
6077    (set_attr "length" "4")])
6079 (define_insn ""
6080   [(set (match_operand:SF 0 "register_operand" "=f")
6081         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6082                          (match_operand:SF 2 "register_operand" "f")))
6083                  (match_operand:SF 3 "register_operand" "f")))]
6084   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6085   "fmpynfadd,sgl %1,%2,%3,%0"
6086   [(set_attr "type" "fpmuldbl")
6087    (set_attr "length" "4")])
6089 (define_insn ""
6090   [(set (match_operand:DF 0 "register_operand" "=f")
6091         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
6092                                   (match_operand:DF 2 "register_operand" "f")))
6093                  (match_operand:DF 3 "register_operand" "f")))
6094    (set (match_operand:DF 4 "register_operand" "=&f")
6095         (mult:DF (match_dup 1) (match_dup 2)))]
6096   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6097     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
6098           || reg_overlap_mentioned_p (operands[4], operands[2])))"
6099   "#"
6100   [(set_attr "type" "fpmuldbl")
6101    (set_attr "length" "8")])
6103 (define_split
6104   [(set (match_operand:DF 0 "register_operand" "")
6105         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "")
6106                                   (match_operand:DF 2 "register_operand" "")))
6107                  (match_operand:DF 3 "register_operand" "")))
6108    (set (match_operand:DF 4 "register_operand" "")
6109         (mult:DF (match_dup 1) (match_dup 2)))]
6110   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6111   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
6112    (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
6113                                (match_dup 3)))]
6114   "")
6116 (define_insn ""
6117   [(set (match_operand:SF 0 "register_operand" "=f")
6118         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
6119                                   (match_operand:SF 2 "register_operand" "f")))
6120                  (match_operand:SF 3 "register_operand" "f")))
6121    (set (match_operand:SF 4 "register_operand" "=&f")
6122         (mult:SF (match_dup 1) (match_dup 2)))]
6123   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6124     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
6125           || reg_overlap_mentioned_p (operands[4], operands[2])))"
6126   "#"
6127   [(set_attr "type" "fpmuldbl")
6128    (set_attr "length" "8")])
6130 (define_split
6131   [(set (match_operand:SF 0 "register_operand" "")
6132         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "")
6133                                   (match_operand:SF 2 "register_operand" "")))
6134                  (match_operand:SF 3 "register_operand" "")))
6135    (set (match_operand:SF 4 "register_operand" "")
6136         (mult:SF (match_dup 1) (match_dup 2)))]
6137   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6138   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
6139    (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
6140                                (match_dup 3)))]
6141   "")
6143 (define_insn ""
6144   [(set (match_operand:DF 0 "register_operand" "=f")
6145         (minus:DF (match_operand:DF 3 "register_operand" "f")
6146                   (mult:DF (match_operand:DF 1 "register_operand" "f")
6147                            (match_operand:DF 2 "register_operand" "f"))))
6148    (set (match_operand:DF 4 "register_operand" "=&f")
6149         (mult:DF (match_dup 1) (match_dup 2)))]
6150   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6151     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
6152           || reg_overlap_mentioned_p (operands[4], operands[2])))"
6153   "#"
6154   [(set_attr "type" "fpmuldbl")
6155    (set_attr "length" "8")])
6157 (define_split
6158   [(set (match_operand:DF 0 "register_operand" "")
6159         (minus:DF (match_operand:DF 3 "register_operand" "")
6160                   (mult:DF (match_operand:DF 1 "register_operand" "")
6161                            (match_operand:DF 2 "register_operand" ""))))
6162    (set (match_operand:DF 4 "register_operand" "")
6163         (mult:DF (match_dup 1) (match_dup 2)))]
6164   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6165   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
6166    (set (match_dup 0) (minus:DF (match_dup 3)
6167                                 (mult:DF (match_dup 1) (match_dup 2))))]
6168   "")
6170 (define_insn ""
6171   [(set (match_operand:SF 0 "register_operand" "=f")
6172         (minus:SF (match_operand:SF 3 "register_operand" "f")
6173                   (mult:SF (match_operand:SF 1 "register_operand" "f")
6174                            (match_operand:SF 2 "register_operand" "f"))))
6175    (set (match_operand:SF 4 "register_operand" "=&f")
6176         (mult:SF (match_dup 1) (match_dup 2)))]
6177   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6178     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
6179           || reg_overlap_mentioned_p (operands[4], operands[2])))"
6180   "#"
6181   [(set_attr "type" "fpmuldbl")
6182    (set_attr "length" "8")])
6184 (define_split
6185   [(set (match_operand:SF 0 "register_operand" "")
6186         (minus:SF (match_operand:SF 3 "register_operand" "")
6187                   (mult:SF (match_operand:SF 1 "register_operand" "")
6188                            (match_operand:SF 2 "register_operand" ""))))
6189    (set (match_operand:SF 4 "register_operand" "")
6190         (mult:SF (match_dup 1) (match_dup 2)))]
6191   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6192   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
6193    (set (match_dup 0) (minus:SF (match_dup 3)
6194                                 (mult:SF (match_dup 1) (match_dup 2))))]
6195   "")
6197 (define_insn ""
6198   [(set (match_operand:DF 0 "register_operand" "=f")
6199         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
6200    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
6201   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6202     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6203   "#"
6204   [(set_attr "type" "fpalu")
6205    (set_attr "length" "8")])
6207 (define_split
6208   [(set (match_operand:DF 0 "register_operand" "")
6209         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" ""))))
6210    (set (match_operand:DF 2 "register_operand" "") (abs:DF (match_dup 1)))]
6211   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6212   [(set (match_dup 2) (abs:DF (match_dup 1)))
6213    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
6214   "")
6216 (define_insn ""
6217   [(set (match_operand:SF 0 "register_operand" "=f")
6218         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
6219    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
6220   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
6221     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
6222   "#"
6223   [(set_attr "type" "fpalu")
6224    (set_attr "length" "8")])
6226 (define_split
6227   [(set (match_operand:SF 0 "register_operand" "")
6228         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" ""))))
6229    (set (match_operand:SF 2 "register_operand" "") (abs:SF (match_dup 1)))]
6230   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
6231   [(set (match_dup 2) (abs:SF (match_dup 1)))
6232    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
6233   "")
6235 ;;- Shift instructions
6237 ;; Optimized special case of shifting.
6239 (define_insn ""
6240   [(set (match_operand:SI 0 "register_operand" "=r")
6241         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6242                      (const_int 24)))]
6243   ""
6244   "ldb%M1 %1,%0"
6245   [(set_attr "type" "load")
6246    (set_attr "length" "4")])
6248 (define_insn ""
6249   [(set (match_operand:SI 0 "register_operand" "=r")
6250         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
6251                      (const_int 16)))]
6252   ""
6253   "ldh%M1 %1,%0"
6254   [(set_attr "type" "load")
6255    (set_attr "length" "4")])
6257 (define_insn ""
6258   [(set (match_operand:SI 0 "register_operand" "=r")
6259         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
6260                           (match_operand:SI 3 "shadd_operand" ""))
6261                  (match_operand:SI 1 "register_operand" "r")))]
6262   ""
6263   "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
6264   [(set_attr "type" "binary")
6265    (set_attr "length" "4")])
6267 (define_insn ""
6268   [(set (match_operand:DI 0 "register_operand" "=r")
6269         (plus:DI (mult:DI (match_operand:DI 2 "register_operand" "r")
6270                           (match_operand:DI 3 "shadd_operand" ""))
6271                  (match_operand:DI 1 "register_operand" "r")))]
6272   "TARGET_64BIT"
6273   "shladd,l %2,%O3,%1,%0"
6274   [(set_attr "type" "binary")
6275    (set_attr "length" "4")])
6277 (define_expand "ashlsi3"
6278   [(set (match_operand:SI 0 "register_operand" "")
6279         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
6280                    (match_operand:SI 2 "arith32_operand" "")))]
6281   ""
6282   "
6284   if (GET_CODE (operands[2]) != CONST_INT)
6285     {
6286       rtx temp = gen_reg_rtx (SImode);
6287       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6288       if (GET_CODE (operands[1]) == CONST_INT)
6289         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
6290       else
6291         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
6292       DONE;
6293     }
6294   /* Make sure both inputs are not constants,
6295      there are no patterns for that.  */
6296   operands[1] = force_reg (SImode, operands[1]);
6299 (define_insn ""
6300   [(set (match_operand:SI 0 "register_operand" "=r")
6301         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6302                    (match_operand:SI 2 "const_int_operand" "n")))]
6303   ""
6304   "{zdep|depw,z} %1,%P2,%L2,%0"
6305   [(set_attr "type" "shift")
6306    (set_attr "length" "4")])
6308 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
6309 ; Doing it like this makes slightly better code since reload can
6310 ; replace a register with a known value in range -16..15 with a
6311 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
6312 ; but since we have no more CONST_OK... characters, that is not
6313 ; possible.
6314 (define_insn "zvdep32"
6315   [(set (match_operand:SI 0 "register_operand" "=r,r")
6316         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
6317                    (minus:SI (const_int 31)
6318                              (match_operand:SI 2 "register_operand" "q,q"))))]
6319   ""
6320   "@
6321    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
6322    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
6323   [(set_attr "type" "shift,shift")
6324    (set_attr "length" "4,4")])
6326 (define_insn "zvdep_imm32"
6327   [(set (match_operand:SI 0 "register_operand" "=r")
6328         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
6329                    (minus:SI (const_int 31)
6330                              (match_operand:SI 2 "register_operand" "q"))))]
6331   ""
6332   "*
6334   int x = INTVAL (operands[1]);
6335   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6336   operands[1] = GEN_INT ((x & 0xf) - 0x10);
6337   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
6339   [(set_attr "type" "shift")
6340    (set_attr "length" "4")])
6342 (define_insn "vdepi_ior"
6343   [(set (match_operand:SI 0 "register_operand" "=r")
6344         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
6345                            (minus:SI (const_int 31)
6346                                      (match_operand:SI 2 "register_operand" "q")))
6347                 (match_operand:SI 3 "register_operand" "0")))]
6348   ; accept ...0001...1, can this be generalized?
6349   "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
6350   "*
6352   int x = INTVAL (operands[1]);
6353   operands[2] = GEN_INT (exact_log2 (x + 1));
6354   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
6356   [(set_attr "type" "shift")
6357    (set_attr "length" "4")])
6359 (define_insn "vdepi_and"
6360   [(set (match_operand:SI 0 "register_operand" "=r")
6361         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
6362                            (minus:SI (const_int 31)
6363                                      (match_operand:SI 2 "register_operand" "q")))
6364                 (match_operand:SI 3 "register_operand" "0")))]
6365   ; this can be generalized...!
6366   "INTVAL (operands[1]) == -2"
6367   "*
6369   int x = INTVAL (operands[1]);
6370   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6371   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
6373   [(set_attr "type" "shift")
6374    (set_attr "length" "4")])
6376 (define_expand "ashldi3"
6377   [(set (match_operand:DI 0 "register_operand" "")
6378         (ashift:DI (match_operand:DI 1 "lhs_lshift_operand" "")
6379                    (match_operand:DI 2 "arith32_operand" "")))]
6380   "TARGET_64BIT"
6381   "
6383   if (GET_CODE (operands[2]) != CONST_INT)
6384     {
6385       rtx temp = gen_reg_rtx (DImode);
6386       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6387       if (GET_CODE (operands[1]) == CONST_INT)
6388         emit_insn (gen_zvdep_imm64 (operands[0], operands[1], temp));
6389       else
6390         emit_insn (gen_zvdep64 (operands[0], operands[1], temp));
6391       DONE;
6392     }
6393   /* Make sure both inputs are not constants,
6394      there are no patterns for that.  */
6395   operands[1] = force_reg (DImode, operands[1]);
6398 (define_insn ""
6399   [(set (match_operand:DI 0 "register_operand" "=r")
6400         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6401                    (match_operand:DI 2 "const_int_operand" "n")))]
6402   "TARGET_64BIT"
6403   "depd,z %1,%p2,%Q2,%0"
6404   [(set_attr "type" "shift")
6405    (set_attr "length" "4")])
6407 ; Match cases of op1 a CONST_INT here that zvdep_imm64 doesn't handle.
6408 ; Doing it like this makes slightly better code since reload can
6409 ; replace a register with a known value in range -16..15 with a
6410 ; constant.  Ideally, we would like to merge zvdep64 and zvdep_imm64,
6411 ; but since we have no more CONST_OK... characters, that is not
6412 ; possible.
6413 (define_insn "zvdep64"
6414   [(set (match_operand:DI 0 "register_operand" "=r,r")
6415         (ashift:DI (match_operand:DI 1 "arith5_operand" "r,L")
6416                    (minus:DI (const_int 63)
6417                              (match_operand:DI 2 "register_operand" "q,q"))))]
6418   "TARGET_64BIT"
6419   "@
6420    depd,z %1,%%sar,64,%0
6421    depdi,z %1,%%sar,64,%0"
6422   [(set_attr "type" "shift,shift")
6423    (set_attr "length" "4,4")])
6425 (define_insn "zvdep_imm64"
6426   [(set (match_operand:DI 0 "register_operand" "=r")
6427         (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "")
6428                    (minus:DI (const_int 63)
6429                              (match_operand:DI 2 "register_operand" "q"))))]
6430   "TARGET_64BIT"
6431   "*
6433   int x = INTVAL (operands[1]);
6434   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
6435   operands[1] = GEN_INT ((x & 0x1f) - 0x20);
6436   return \"depdi,z %1,%%sar,%2,%0\";
6438   [(set_attr "type" "shift")
6439    (set_attr "length" "4")])
6441 (define_insn ""
6442   [(set (match_operand:DI 0 "register_operand" "=r")
6443         (ior:DI (ashift:DI (match_operand:DI 1 "const_int_operand" "")
6444                            (minus:DI (const_int 63)
6445                                      (match_operand:DI 2 "register_operand" "q")))
6446                 (match_operand:DI 3 "register_operand" "0")))]
6447   ; accept ...0001...1, can this be generalized?
6448   "TARGET_64BIT && exact_log2 (INTVAL (operands[1]) + 1) >= 0"
6449   "*
6451   int x = INTVAL (operands[1]);
6452   operands[2] = GEN_INT (exact_log2 (x + 1));
6453   return \"depdi -1,%%sar,%2,%0\";
6455   [(set_attr "type" "shift")
6456    (set_attr "length" "4")])
6458 (define_insn ""
6459   [(set (match_operand:DI 0 "register_operand" "=r")
6460         (and:DI (rotate:DI (match_operand:DI 1 "const_int_operand" "")
6461                            (minus:DI (const_int 63)
6462                                      (match_operand:DI 2 "register_operand" "q")))
6463                 (match_operand:DI 3 "register_operand" "0")))]
6464   ; this can be generalized...!
6465   "TARGET_64BIT && INTVAL (operands[1]) == -2"
6466   "*
6468   int x = INTVAL (operands[1]);
6469   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
6470   return \"depdi 0,%%sar,%2,%0\";
6472   [(set_attr "type" "shift")
6473    (set_attr "length" "4")])
6475 (define_expand "ashrsi3"
6476   [(set (match_operand:SI 0 "register_operand" "")
6477         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
6478                      (match_operand:SI 2 "arith32_operand" "")))]
6479   ""
6480   "
6482   if (GET_CODE (operands[2]) != CONST_INT)
6483     {
6484       rtx temp = gen_reg_rtx (SImode);
6485       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
6486       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
6487       DONE;
6488     }
6491 (define_insn ""
6492   [(set (match_operand:SI 0 "register_operand" "=r")
6493         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6494                      (match_operand:SI 2 "const_int_operand" "n")))]
6495   ""
6496   "{extrs|extrw,s} %1,%P2,%L2,%0"
6497   [(set_attr "type" "shift")
6498    (set_attr "length" "4")])
6500 (define_insn "vextrs32"
6501   [(set (match_operand:SI 0 "register_operand" "=r")
6502         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6503                      (minus:SI (const_int 31)
6504                                (match_operand:SI 2 "register_operand" "q"))))]
6505   ""
6506   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
6507   [(set_attr "type" "shift")
6508    (set_attr "length" "4")])
6510 (define_expand "ashrdi3"
6511   [(set (match_operand:DI 0 "register_operand" "")
6512         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
6513                      (match_operand:DI 2 "arith32_operand" "")))]
6514   "TARGET_64BIT"
6515   "
6517   if (GET_CODE (operands[2]) != CONST_INT)
6518     {
6519       rtx temp = gen_reg_rtx (DImode);
6520       emit_insn (gen_subdi3 (temp, GEN_INT (63), operands[2]));
6521       emit_insn (gen_vextrs64 (operands[0], operands[1], temp));
6522       DONE;
6523     }
6526 (define_insn ""
6527   [(set (match_operand:DI 0 "register_operand" "=r")
6528         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6529                      (match_operand:DI 2 "const_int_operand" "n")))]
6530   "TARGET_64BIT"
6531   "extrd,s %1,%p2,%Q2,%0"
6532   [(set_attr "type" "shift")
6533    (set_attr "length" "4")])
6535 (define_insn "vextrs64"
6536   [(set (match_operand:DI 0 "register_operand" "=r")
6537         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6538                      (minus:DI (const_int 63)
6539                                (match_operand:DI 2 "register_operand" "q"))))]
6540   "TARGET_64BIT"
6541   "extrd,s %1,%%sar,64,%0"
6542   [(set_attr "type" "shift")
6543    (set_attr "length" "4")])
6545 (define_insn "lshrsi3"
6546   [(set (match_operand:SI 0 "register_operand" "=r,r")
6547         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
6548                      (match_operand:SI 2 "arith32_operand" "q,n")))]
6549   ""
6550   "@
6551    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
6552    {extru|extrw,u} %1,%P2,%L2,%0"
6553   [(set_attr "type" "shift")
6554    (set_attr "length" "4")])
6556 (define_insn "lshrdi3"
6557   [(set (match_operand:DI 0 "register_operand" "=r,r")
6558         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
6559                      (match_operand:DI 2 "arith32_operand" "q,n")))]
6560   "TARGET_64BIT"
6561   "@
6562    shrpd %%r0,%1,%%sar,%0
6563    extrd,u %1,%p2,%Q2,%0"
6564   [(set_attr "type" "shift")
6565    (set_attr "length" "4")])
6567 (define_insn "rotrsi3"
6568   [(set (match_operand:SI 0 "register_operand" "=r,r")
6569         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
6570                      (match_operand:SI 2 "arith32_operand" "q,n")))]
6571   ""
6572   "*
6574   if (GET_CODE (operands[2]) == CONST_INT)
6575     {
6576       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
6577       return \"{shd|shrpw} %1,%1,%2,%0\";
6578     }
6579   else
6580     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
6582   [(set_attr "type" "shift")
6583    (set_attr "length" "4")])
6585 (define_expand "rotlsi3"
6586   [(set (match_operand:SI 0 "register_operand" "")
6587         (rotate:SI (match_operand:SI 1 "register_operand" "")
6588                    (match_operand:SI 2 "arith32_operand" "")))]
6589   ""
6590   "
6592   if (GET_CODE (operands[2]) != CONST_INT)
6593     {
6594       rtx temp = gen_reg_rtx (SImode);
6595       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
6596       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
6597       DONE;
6598     }
6599   /* Else expand normally.  */
6602 (define_insn ""
6603   [(set (match_operand:SI 0 "register_operand" "=r")
6604         (rotate:SI (match_operand:SI 1 "register_operand" "r")
6605                    (match_operand:SI 2 "const_int_operand" "n")))]
6606   ""
6607   "*
6609   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
6610   return \"{shd|shrpw} %1,%1,%2,%0\";
6612   [(set_attr "type" "shift")
6613    (set_attr "length" "4")])
6615 (define_insn ""
6616   [(set (match_operand:SI 0 "register_operand" "=r")
6617         (match_operator:SI 5 "plus_xor_ior_operator"
6618           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
6619                       (match_operand:SI 3 "const_int_operand" "n"))
6620            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6621                         (match_operand:SI 4 "const_int_operand" "n"))]))]
6622   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6623   "{shd|shrpw} %1,%2,%4,%0"
6624   [(set_attr "type" "shift")
6625    (set_attr "length" "4")])
6627 (define_insn ""
6628   [(set (match_operand:SI 0 "register_operand" "=r")
6629         (match_operator:SI 5 "plus_xor_ior_operator"
6630           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
6631                         (match_operand:SI 4 "const_int_operand" "n"))
6632            (ashift:SI (match_operand:SI 1 "register_operand" "r")
6633                       (match_operand:SI 3 "const_int_operand" "n"))]))]
6634   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
6635   "{shd|shrpw} %1,%2,%4,%0"
6636   [(set_attr "type" "shift")
6637    (set_attr "length" "4")])
6639 (define_insn ""
6640   [(set (match_operand:SI 0 "register_operand" "=r")
6641         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
6642                            (match_operand:SI 2 "const_int_operand" ""))
6643                 (match_operand:SI 3 "const_int_operand" "")))]
6644   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
6645   "*
6647   int cnt = INTVAL (operands[2]) & 31;
6648   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
6649   operands[2] = GEN_INT (31 - cnt);
6650   return \"{zdep|depw,z} %1,%2,%3,%0\";
6652   [(set_attr "type" "shift")
6653    (set_attr "length" "4")])
6655 ;; Unconditional and other jump instructions.
6657 ;; This can only be used in a leaf function, so we do
6658 ;; not need to use the PIC register when generating PIC code.
6659 (define_insn "return"
6660   [(return)
6661    (use (reg:SI 2))
6662    (const_int 0)]
6663   "hppa_can_use_return_insn_p ()"
6664   "*
6666   if (TARGET_PA_20)
6667     return \"bve%* (%%r2)\";
6668   return \"bv%* %%r0(%%r2)\";
6670   [(set_attr "type" "branch")
6671    (set_attr "length" "4")])
6673 ;; Emit a different pattern for functions which have non-trivial
6674 ;; epilogues so as not to confuse jump and reorg.
6675 (define_insn "return_internal"
6676   [(return)
6677    (use (reg:SI 2))
6678    (const_int 1)]
6679   ""
6680   "*
6682   if (TARGET_PA_20)
6683     return \"bve%* (%%r2)\";
6684   return \"bv%* %%r0(%%r2)\";
6686   [(set_attr "type" "branch")
6687    (set_attr "length" "4")])
6689 ;; This is used for eh returns which bypass the return stub.
6690 (define_insn "return_external_pic"
6691   [(return)
6692    (clobber (reg:SI 1))
6693    (use (reg:SI 2))]
6694   "!TARGET_NO_SPACE_REGS
6695    && !TARGET_PA_20
6696    && flag_pic && current_function_calls_eh_return"
6697   "ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
6698   [(set_attr "type" "branch")
6699    (set_attr "length" "12")])
6701 (define_expand "prologue"
6702   [(const_int 0)]
6703   ""
6704   "hppa_expand_prologue ();DONE;")
6706 (define_expand "sibcall_epilogue"
6707   [(return)]
6708   ""
6709   "
6711   hppa_expand_epilogue ();
6712   DONE;
6715 (define_expand "epilogue"
6716   [(return)]
6717   ""
6718   "
6720   /* Try to use the trivial return first.  Else use the full
6721      epilogue.  */
6722   if (hppa_can_use_return_insn_p ())
6723     emit_jump_insn (gen_return ());
6724   else
6725     {
6726       rtx x;
6728       hppa_expand_epilogue ();
6730       /* EH returns bypass the normal return stub.  Thus, we must do an
6731          interspace branch to return from functions that call eh_return.
6732          This is only a problem for returns from shared code on ports
6733          using space registers.  */
6734       if (!TARGET_NO_SPACE_REGS
6735           && !TARGET_PA_20
6736           && flag_pic && current_function_calls_eh_return)
6737         x = gen_return_external_pic ();
6738       else
6739         x = gen_return_internal ();
6741       emit_jump_insn (x);
6742     }
6743   DONE;
6746 ; Used by hppa_profile_hook to load the starting address of the current
6747 ; function; operand 1 contains the address of the label in operand 3
6748 (define_insn "load_offset_label_address"
6749   [(set (match_operand:SI 0 "register_operand" "=r")
6750         (plus:SI (match_operand:SI 1 "register_operand" "r")
6751                  (minus:SI (match_operand:SI 2 "" "")
6752                            (label_ref:SI (match_operand 3 "" "")))))]
6753   ""
6754   "ldo %2-%l3(%1),%0"
6755   [(set_attr "type" "multi")
6756    (set_attr "length" "4")])
6758 ; Output a code label and load its address.
6759 (define_insn "lcla1"
6760   [(set (match_operand:SI 0 "register_operand" "=r")
6761         (label_ref:SI (match_operand 1 "" "")))
6762    (const_int 0)]
6763   "!TARGET_PA_20"
6764   "*
6766   output_asm_insn (\"bl .+8,%0\;depi 0,31,2,%0\", operands);
6767   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6768                                      CODE_LABEL_NUMBER (operands[1]));
6769   return \"\";
6771   [(set_attr "type" "multi")
6772    (set_attr "length" "8")])
6774 (define_insn "lcla2"
6775   [(set (match_operand:SI 0 "register_operand" "=r")
6776         (label_ref:SI (match_operand 1 "" "")))
6777    (const_int 0)]
6778   "TARGET_PA_20"
6779   "*
6781   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
6782                                      CODE_LABEL_NUMBER (operands[1]));
6783   return \"mfia %0\";
6785   [(set_attr "type" "move")
6786    (set_attr "length" "4")])
6788 (define_insn "blockage"
6789   [(unspec_volatile [(const_int 2)] UNSPECV_BLOCKAGE)]
6790   ""
6791   ""
6792   [(set_attr "length" "0")])
6794 (define_insn "jump"
6795   [(set (pc) (label_ref (match_operand 0 "" "")))]
6796   ""
6797   "*
6799   /* An unconditional branch which can reach its target.  */
6800   if (get_attr_length (insn) != 24
6801       && get_attr_length (insn) != 16)
6802     return \"b%* %l0\";
6804   return output_lbranch (operands[0], insn);
6806   [(set_attr "type" "uncond_branch")
6807    (set_attr "pa_combine_type" "uncond_branch")
6808    (set (attr "length")
6809     (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
6810            (if_then_else (lt (abs (minus (match_dup 0)
6811                                          (plus (pc) (const_int 8))))
6812                              (const_int 8184))
6813                          (const_int 4)
6814                          (const_int 8))
6815            (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
6816                (const_int 262100))
6817            (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6818                          (const_int 16)
6819                          (const_int 24))]
6820           (const_int 4)))])
6822 ;;; Hope this is only within a function...
6823 (define_insn "indirect_jump"
6824   [(set (pc) (match_operand 0 "register_operand" "r"))]
6825   "GET_MODE (operands[0]) == word_mode"
6826   "bv%* %%r0(%0)"
6827   [(set_attr "type" "branch")
6828    (set_attr "length" "4")])
6830 ;;; An indirect jump can be optimized to a direct jump.  GAS for the
6831 ;;; SOM target doesn't allow branching to a label inside a function.
6832 ;;; We also don't correctly compute branch distances for labels
6833 ;;; outside the current function.  Thus, we use an indirect jump can't
6834 ;;; be optimized to a direct jump for all targets.  We assume that
6835 ;;; the branch target is in the same space (i.e., nested function
6836 ;;; jumping to a label in an outer function in the same translation
6837 ;;; unit).
6838 (define_expand "nonlocal_goto"
6839   [(use (match_operand 0 "general_operand" ""))
6840    (use (match_operand 1 "general_operand" ""))
6841    (use (match_operand 2 "general_operand" ""))
6842    (use (match_operand 3 "general_operand" ""))]
6843   ""
6845   rtx lab = operands[1];
6846   rtx stack = operands[2];
6847   rtx fp = operands[3];
6849   lab = copy_to_reg (lab);
6851   emit_insn (gen_rtx_CLOBBER (VOIDmode,
6852                               gen_rtx_MEM (BLKmode,
6853                                            gen_rtx_SCRATCH (VOIDmode))));
6854   emit_insn (gen_rtx_CLOBBER (VOIDmode,
6855                               gen_rtx_MEM (BLKmode,
6856                                            hard_frame_pointer_rtx)));
6858   /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
6859      instead of the hard_frame_pointer_rtx in the save area.  As a
6860      result, an extra instruction is needed to adjust for the offset
6861      of the virtual stack variables and the frame pointer.  */
6862   if (GET_CODE (fp) != REG)
6863     fp = force_reg (Pmode, fp);
6864   emit_move_insn (virtual_stack_vars_rtx, fp);
6866   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6868   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6869   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6871   /* Nonlocal goto jumps are only used between functions in the same
6872      translation unit.  Thus, we can avoid the extra overhead of an
6873      interspace jump.  */
6874   emit_jump_insn (gen_indirect_goto (lab));
6875   emit_barrier ();
6876   DONE;
6879 (define_insn "indirect_goto"
6880   [(unspec [(match_operand 0 "register_operand" "=r")] UNSPEC_GOTO)]
6881   "GET_MODE (operands[0]) == word_mode"
6882   "bv%* %%r0(%0)"
6883   [(set_attr "type" "branch")
6884    (set_attr "length" "4")])
6886 ;;; This jump is used in branch tables where the insn length is fixed.
6887 ;;; The length of this insn is adjusted if the delay slot is not filled.
6888 (define_insn "short_jump"
6889   [(set (pc) (label_ref (match_operand 0 "" "")))
6890    (const_int 0)]
6891   ""
6892   "b%* %l0%#"
6893   [(set_attr "type" "btable_branch")
6894    (set_attr "length" "4")])
6896 ;; Subroutines of "casesi".
6897 ;; operand 0 is index
6898 ;; operand 1 is the minimum bound
6899 ;; operand 2 is the maximum bound - minimum bound + 1
6900 ;; operand 3 is CODE_LABEL for the table;
6901 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6903 (define_expand "casesi"
6904   [(match_operand:SI 0 "general_operand" "")
6905    (match_operand:SI 1 "const_int_operand" "")
6906    (match_operand:SI 2 "const_int_operand" "")
6907    (match_operand 3 "" "")
6908    (match_operand 4 "" "")]
6909   ""
6910   "
6912   if (GET_CODE (operands[0]) != REG)
6913     operands[0] = force_reg (SImode, operands[0]);
6915   if (operands[1] != const0_rtx)
6916     {
6917       rtx index = gen_reg_rtx (SImode);
6919       operands[1] = GEN_INT (-INTVAL (operands[1]));
6920       if (!INT_14_BITS (operands[1]))
6921         operands[1] = force_reg (SImode, operands[1]);
6922       emit_insn (gen_addsi3 (index, operands[0], operands[1]));
6923       operands[0] = index;
6924     }
6926   /* In 64bit mode we must make sure to wipe the upper bits of the register
6927      just in case the addition overflowed or we had random bits in the
6928      high part of the register.  */
6929   if (TARGET_64BIT)
6930     {
6931       rtx index = gen_reg_rtx (DImode);
6933       emit_insn (gen_extendsidi2 (index, operands[0]));
6934       operands[0] = gen_rtx_SUBREG (SImode, index, 4);
6935     }
6937   if (!INT_5_BITS (operands[2]))
6938     operands[2] = force_reg (SImode, operands[2]);
6940   /* This branch prevents us finding an insn for the delay slot of the
6941      following vectored branch.  It might be possible to use the delay
6942      slot if an index value of -1 was used to transfer to the out-of-range
6943      label.  In order to do this, we would have to output the -1 vector
6944      element after the delay insn.  The casesi output code would have to
6945      check if the casesi insn is in a delay branch sequence and output
6946      the delay insn if one is found.  If this was done, then it might
6947      then be worthwhile to split the casesi patterns to improve scheduling.
6948      However, it's not clear that all this extra complexity is worth
6949      the effort.  */
6950   emit_insn (gen_cmpsi (operands[0], operands[2]));
6951   emit_jump_insn (gen_bgtu (operands[4]));
6953   if (TARGET_BIG_SWITCH)
6954     {
6955       if (TARGET_64BIT)
6956         {
6957           rtx tmp1 = gen_reg_rtx (DImode);
6958           rtx tmp2 = gen_reg_rtx (DImode);
6960           emit_jump_insn (gen_casesi64p (operands[0], operands[3],
6961                                          tmp1, tmp2));
6962         }
6963       else
6964         {
6965           rtx tmp1 = gen_reg_rtx (SImode);
6967           if (flag_pic)
6968             {
6969               rtx tmp2 = gen_reg_rtx (SImode);
6971               emit_jump_insn (gen_casesi32p (operands[0], operands[3],
6972                                              tmp1, tmp2));
6973             }
6974           else
6975             emit_jump_insn (gen_casesi32 (operands[0], operands[3], tmp1));
6976         }
6977     }
6978   else
6979     emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
6980   DONE;
6983 ;;; The rtl for this pattern doesn't accurately describe what the insn
6984 ;;; actually does, particularly when case-vector elements are exploded
6985 ;;; in pa_reorg.  However, the initial SET in these patterns must show
6986 ;;; the connection of the insn to the following jump table.
6987 (define_insn "casesi0"
6988   [(set (pc) (mem:SI (plus:SI
6989                        (mult:SI (match_operand:SI 0 "register_operand" "r")
6990                                 (const_int 4))
6991                        (label_ref (match_operand 1 "" "")))))]
6992   ""
6993   "blr,n %0,%%r0\;nop"
6994   [(set_attr "type" "multi")
6995    (set_attr "length" "8")])
6997 ;;; 32-bit code, absolute branch table.
6998 (define_insn "casesi32"
6999   [(set (pc) (mem:SI (plus:SI
7000                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7001                                 (const_int 4))
7002                        (label_ref (match_operand 1 "" "")))))
7003    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
7004   "!TARGET_64BIT && TARGET_BIG_SWITCH"
7005   "ldil L'%l1,%2\;ldo R'%l1(%2),%2\;{ldwx|ldw},s %0(%2),%2\;bv,n %%r0(%2)"
7006   [(set_attr "type" "multi")
7007    (set_attr "length" "16")])
7009 ;;; 32-bit code, relative branch table.
7010 (define_insn "casesi32p"
7011   [(set (pc) (mem:SI (plus:SI
7012                        (mult:SI (match_operand:SI 0 "register_operand" "r")
7013                                 (const_int 4))
7014                        (label_ref (match_operand 1 "" "")))))
7015    (clobber (match_operand:SI 2 "register_operand" "=&a"))
7016    (clobber (match_operand:SI 3 "register_operand" "=&r"))]
7017   "!TARGET_64BIT && TARGET_BIG_SWITCH"
7018   "{bl .+8,%2\;depi 0,31,2,%2|mfia %2}\;ldo {16|20}(%2),%2\;\
7019 {ldwx|ldw},s %0(%2),%3\;{addl|add,l} %2,%3,%3\;bv,n %%r0(%3)"
7020   [(set_attr "type" "multi")
7021    (set (attr "length")
7022      (if_then_else (ne (symbol_ref "TARGET_PA_20") (const_int 0))
7023         (const_int 20)
7024         (const_int 24)))])
7026 ;;; 64-bit code, 32-bit relative branch table.
7027 (define_insn "casesi64p"
7028   [(set (pc) (mem:DI (plus:DI
7029                        (mult:DI (sign_extend:DI
7030                                   (match_operand:SI 0 "register_operand" "r"))
7031                                 (const_int 8))
7032                        (label_ref (match_operand 1 "" "")))))
7033    (clobber (match_operand:DI 2 "register_operand" "=&r"))
7034    (clobber (match_operand:DI 3 "register_operand" "=&r"))]
7035   "TARGET_64BIT && TARGET_BIG_SWITCH"
7036   "mfia %2\;ldo 24(%2),%2\;ldw,s %0(%2),%3\;extrd,s %3,63,32,%3\;\
7037 add,l %2,%3,%3\;bv,n %%r0(%3)"
7038   [(set_attr "type" "multi")
7039    (set_attr "length" "24")])
7042 ;; Call patterns.
7043 ;;- jump to subroutine
7045 (define_expand "call"
7046   [(parallel [(call (match_operand:SI 0 "" "")
7047                     (match_operand 1 "" ""))
7048               (clobber (reg:SI 2))])]
7049   ""
7050   "
7052   rtx op, call_insn;
7053   rtx nb = operands[1];
7055   if (TARGET_PORTABLE_RUNTIME)
7056     op = force_reg (SImode, XEXP (operands[0], 0));
7057   else
7058     op = XEXP (operands[0], 0);
7060   if (TARGET_64BIT)
7061     {
7062       if (!virtuals_instantiated)
7063         emit_move_insn (arg_pointer_rtx,
7064                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7065                                       GEN_INT (64)));
7066       else
7067         {
7068           /* The loop pass can generate new libcalls after the virtual
7069              registers are instantiated when fpregs are disabled because
7070              the only method that we have for doing DImode multiplication
7071              is with a libcall.  This could be trouble if we haven't
7072              allocated enough space for the outgoing arguments.  */
7073           if (INTVAL (nb) > current_function_outgoing_args_size)
7074             abort ();
7076           emit_move_insn (arg_pointer_rtx,
7077                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7078                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7079         }
7080     }
7082   /* Use two different patterns for calls to explicitly named functions
7083      and calls through function pointers.  This is necessary as these two
7084      types of calls use different calling conventions, and CSE might try
7085      to change the named call into an indirect call in some cases (using
7086      two patterns keeps CSE from performing this optimization).
7087      
7088      We now use even more call patterns as there was a subtle bug in
7089      attempting to restore the pic register after a call using a simple
7090      move insn.  During reload, a instruction involving a pseudo register
7091      with no explicit dependence on the PIC register can be converted
7092      to an equivalent load from memory using the PIC register.  If we
7093      emit a simple move to restore the PIC register in the initial rtl
7094      generation, then it can potentially be repositioned during scheduling.
7095      and an instruction that eventually uses the PIC register may end up
7096      between the call and the PIC register restore.
7097      
7098      This only worked because there is a post call group of instructions
7099      that are scheduled with the call.  These instructions are included
7100      in the same basic block as the call.  However, calls can throw in
7101      C++ code and a basic block has to terminate at the call if the call
7102      can throw.  This results in the PIC register restore being scheduled
7103      independently from the call.  So, we now hide the save and restore
7104      of the PIC register in the call pattern until after reload.  Then,
7105      we split the moves out.  A small side benefit is that we now don't
7106      need to have a use of the PIC register in the return pattern and
7107      the final save/restore operation is not needed.
7108      
7109      I elected to just clobber %r4 in the PIC patterns and use it instead
7110      of trying to force hppa_pic_save_rtx () to a callee saved register.
7111      This might have required a new register class and constraint.  It
7112      was also simpler to just handle the restore from a register than a
7113      generic pseudo.  */
7114   if (TARGET_64BIT)
7115     {
7116       if (GET_CODE (op) == SYMBOL_REF)
7117         call_insn = emit_call_insn (gen_call_symref_64bit (op, nb));
7118       else
7119         {
7120           op = force_reg (word_mode, op);
7121           call_insn = emit_call_insn (gen_call_reg_64bit (op, nb));
7122         }
7123     }
7124   else
7125     {
7126       if (GET_CODE (op) == SYMBOL_REF)
7127         {
7128           if (flag_pic)
7129             call_insn = emit_call_insn (gen_call_symref_pic (op, nb));
7130           else
7131             call_insn = emit_call_insn (gen_call_symref (op, nb));
7132         }
7133       else
7134         {
7135           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7137           emit_move_insn (tmpreg, force_reg (word_mode, op));
7138           if (flag_pic)
7139             call_insn = emit_call_insn (gen_call_reg_pic (nb));
7140           else
7141             call_insn = emit_call_insn (gen_call_reg (nb));
7142         }
7143     }
7145   DONE;
7148 ;; We use function calls to set the attribute length of calls and millicode
7149 ;; calls.  This is necessary because of the large variety of call sequences.
7150 ;; Implementing the calculation in rtl is difficult as well as ugly.  As
7151 ;; we need the same calculation in several places, maintenance becomes a
7152 ;; nightmare.
7154 ;; However, this has a subtle impact on branch shortening.  When the
7155 ;; expression used to set the length attribute of an instruction depends
7156 ;; on a relative address (e.g., pc or a branch address), genattrtab
7157 ;; notes that the insn's length is variable, and attempts to determine a
7158 ;; worst-case default length and code to compute an insn's current length.
7160 ;; The use of a function call hides the variable dependence of our calls
7161 ;; and millicode calls.  The result is genattrtab doesn't treat the operation
7162 ;; as variable and it only generates code for the default case using our
7163 ;; function call.  Because of this, calls and millicode calls have a fixed
7164 ;; length in the branch shortening pass, and some branches will use a longer
7165 ;; code sequence than necessary.  However, the length of any given call
7166 ;; will still reflect its final code location and it may be shorter than
7167 ;; the initial length estimate.
7169 ;; It's possible to trick genattrtab by adding an expression involving `pc'
7170 ;; in the set.  However, when genattrtab hits a function call in its attempt
7171 ;; to compute the default length, it marks the result as unknown and sets
7172 ;; the default result to MAX_INT ;-(  One possible fix that would allow
7173 ;; calls to participate in branch shortening would be to make the call to
7174 ;; insn_default_length a target option.  Then, we could massage unknown
7175 ;; results.  Another fix might be to change genattrtab so that it just does
7176 ;; the call in the variable case as it already does for the fixed case.
7178 (define_insn "call_symref"
7179   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7180          (match_operand 1 "" "i"))
7181    (clobber (reg:SI 1))
7182    (clobber (reg:SI 2))
7183    (use (const_int 0))]
7184   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7185   "*
7187   output_arg_descriptor (insn);
7188   return output_call (insn, operands[0], 0);
7190   [(set_attr "type" "call")
7191    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7193 (define_insn "call_symref_pic"
7194   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7195          (match_operand 1 "" "i"))
7196    (clobber (reg:SI 1))
7197    (clobber (reg:SI 2))
7198    (clobber (reg:SI 4))
7199    (use (reg:SI 19))
7200    (use (const_int 0))]
7201   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7202   "*
7204   output_arg_descriptor (insn);
7205   return output_call (insn, operands[0], 0);
7207   [(set_attr "type" "call")
7208    (set (attr "length")
7209         (plus (symbol_ref "attr_length_call (insn, 0)")
7210               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7212 ;; Split out the PIC register save and restore after reload.  This is
7213 ;; done only if the function returns.  As the split is done after reload,
7214 ;; there are some situations in which we unnecessarily save and restore
7215 ;; %r4.  This happens when there is a single call and the PIC register
7216 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7217 ;; the PIC register isn't completely determined until the reload pass.
7218 (define_split
7219   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7220                     (match_operand 1 "" ""))
7221               (clobber (reg:SI 1))
7222               (clobber (reg:SI 2))
7223               (clobber (reg:SI 4))
7224               (use (reg:SI 19))
7225               (use (const_int 0))])]
7226   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT
7227    && reload_completed
7228    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7229   [(set (reg:SI 4) (reg:SI 19))
7230    (parallel [(call (mem:SI (match_dup 0))
7231                     (match_dup 1))
7232               (clobber (reg:SI 1))
7233               (clobber (reg:SI 2))
7234               (use (reg:SI 19))
7235               (use (const_int 0))])
7236    (set (reg:SI 19) (reg:SI 4))]
7237   "")
7239 ;; Remove the clobber of register 4 when optimizing.  This has to be
7240 ;; done with a peephole optimization rather than a split because the
7241 ;; split sequence for a call must be longer than one instruction.
7242 (define_peephole2
7243   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7244                     (match_operand 1 "" ""))
7245               (clobber (reg:SI 1))
7246               (clobber (reg:SI 2))
7247               (clobber (reg:SI 4))
7248               (use (reg:SI 19))
7249               (use (const_int 0))])]
7250   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7251   [(parallel [(call (mem:SI (match_dup 0))
7252                     (match_dup 1))
7253               (clobber (reg:SI 1))
7254               (clobber (reg:SI 2))
7255               (use (reg:SI 19))
7256               (use (const_int 0))])]
7257   "")
7259 (define_insn "*call_symref_pic_post_reload"
7260   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7261          (match_operand 1 "" "i"))
7262    (clobber (reg:SI 1))
7263    (clobber (reg:SI 2))
7264    (use (reg:SI 19))
7265    (use (const_int 0))]
7266   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7267   "*
7269   output_arg_descriptor (insn);
7270   return output_call (insn, operands[0], 0);
7272   [(set_attr "type" "call")
7273    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7275 ;; This pattern is split if it is necessary to save and restore the
7276 ;; PIC register.
7277 (define_insn "call_symref_64bit"
7278   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7279          (match_operand 1 "" "i"))
7280    (clobber (reg:DI 1))
7281    (clobber (reg:DI 2))
7282    (clobber (reg:DI 4))
7283    (use (reg:DI 27))
7284    (use (reg:DI 29))
7285    (use (const_int 0))]
7286   "TARGET_64BIT"
7287   "*
7289   output_arg_descriptor (insn);
7290   return output_call (insn, operands[0], 0);
7292   [(set_attr "type" "call")
7293    (set (attr "length")
7294         (plus (symbol_ref "attr_length_call (insn, 0)")
7295               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7297 ;; Split out the PIC register save and restore after reload.  This is
7298 ;; done only if the function returns.  As the split is done after reload,
7299 ;; there are some situations in which we unnecessarily save and restore
7300 ;; %r4.  This happens when there is a single call and the PIC register
7301 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7302 ;; the PIC register isn't completely determined until the reload pass.
7303 (define_split
7304   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7305                     (match_operand 1 "" ""))
7306               (clobber (reg:DI 1))
7307               (clobber (reg:DI 2))
7308               (clobber (reg:DI 4))
7309               (use (reg:DI 27))
7310               (use (reg:DI 29))
7311               (use (const_int 0))])]
7312   "TARGET_64BIT
7313    && reload_completed
7314    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7315   [(set (reg:DI 4) (reg:DI 27))
7316    (parallel [(call (mem:SI (match_dup 0))
7317                     (match_dup 1))
7318               (clobber (reg:DI 1))
7319               (clobber (reg:DI 2))
7320               (use (reg:DI 27))
7321               (use (reg:DI 29))
7322               (use (const_int 0))])
7323    (set (reg:DI 27) (reg:DI 4))]
7324   "")
7326 ;; Remove the clobber of register 4 when optimizing.  This has to be
7327 ;; done with a peephole optimization rather than a split because the
7328 ;; split sequence for a call must be longer than one instruction.
7329 (define_peephole2
7330   [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7331                     (match_operand 1 "" ""))
7332               (clobber (reg:DI 1))
7333               (clobber (reg:DI 2))
7334               (clobber (reg:DI 4))
7335               (use (reg:DI 27))
7336               (use (reg:DI 29))
7337               (use (const_int 0))])]
7338   "TARGET_64BIT && reload_completed"
7339   [(parallel [(call (mem:SI (match_dup 0))
7340                     (match_dup 1))
7341               (clobber (reg:DI 1))
7342               (clobber (reg:DI 2))
7343               (use (reg:DI 27))
7344               (use (reg:DI 29))
7345               (use (const_int 0))])]
7346   "")
7348 (define_insn "*call_symref_64bit_post_reload"
7349   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
7350          (match_operand 1 "" "i"))
7351    (clobber (reg:DI 1))
7352    (clobber (reg:DI 2))
7353    (use (reg:DI 27))
7354    (use (reg:DI 29))
7355    (use (const_int 0))]
7356   "TARGET_64BIT"
7357   "*
7359   output_arg_descriptor (insn);
7360   return output_call (insn, operands[0], 0);
7362   [(set_attr "type" "call")
7363    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7365 (define_insn "call_reg"
7366   [(call (mem:SI (reg:SI 22))
7367          (match_operand 0 "" "i"))
7368    (clobber (reg:SI 1))
7369    (clobber (reg:SI 2))
7370    (use (const_int 1))]
7371   "!TARGET_64BIT"
7372   "*
7374   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7376   [(set_attr "type" "dyncall")
7377    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
7379 ;; This pattern is split if it is necessary to save and restore the
7380 ;; PIC register.
7381 (define_insn "call_reg_pic"
7382   [(call (mem:SI (reg:SI 22))
7383          (match_operand 0 "" "i"))
7384    (clobber (reg:SI 1))
7385    (clobber (reg:SI 2))
7386    (clobber (reg:SI 4))
7387    (use (reg:SI 19))
7388    (use (const_int 1))]
7389   "!TARGET_64BIT"
7390   "*
7392   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7394   [(set_attr "type" "dyncall")
7395    (set (attr "length")
7396         (plus (symbol_ref "attr_length_indirect_call (insn)")
7397               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7399 ;; Split out the PIC register save and restore after reload.  This is
7400 ;; done only if the function returns.  As the split is done after reload,
7401 ;; there are some situations in which we unnecessarily save and restore
7402 ;; %r4.  This happens when there is a single call and the PIC register
7403 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7404 ;; the PIC register isn't completely determined until the reload pass.
7405 (define_split
7406   [(parallel [(call (mem:SI (reg:SI 22))
7407                     (match_operand 0 "" ""))
7408               (clobber (reg:SI 1))
7409               (clobber (reg:SI 2))
7410               (clobber (reg:SI 4))
7411               (use (reg:SI 19))
7412               (use (const_int 1))])]
7413   "!TARGET_64BIT
7414    && reload_completed
7415    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7416   [(set (reg:SI 4) (reg:SI 19))
7417    (parallel [(call (mem:SI (reg:SI 22))
7418                     (match_dup 0))
7419               (clobber (reg:SI 1))
7420               (clobber (reg:SI 2))
7421               (use (reg:SI 19))
7422               (use (const_int 1))])
7423    (set (reg:SI 19) (reg:SI 4))]
7424   "")
7426 ;; Remove the clobber of register 4 when optimizing.  This has to be
7427 ;; done with a peephole optimization rather than a split because the
7428 ;; split sequence for a call must be longer than one instruction.
7429 (define_peephole2
7430   [(parallel [(call (mem:SI (reg:SI 22))
7431                     (match_operand 0 "" ""))
7432               (clobber (reg:SI 1))
7433               (clobber (reg:SI 2))
7434               (clobber (reg:SI 4))
7435               (use (reg:SI 19))
7436               (use (const_int 1))])]
7437   "!TARGET_64BIT && reload_completed"
7438   [(parallel [(call (mem:SI (reg:SI 22))
7439                     (match_dup 0))
7440               (clobber (reg:SI 1))
7441               (clobber (reg:SI 2))
7442               (use (reg:SI 19))
7443               (use (const_int 1))])]
7444   "")
7446 (define_insn "*call_reg_pic_post_reload"
7447   [(call (mem:SI (reg:SI 22))
7448          (match_operand 0 "" "i"))
7449    (clobber (reg:SI 1))
7450    (clobber (reg:SI 2))
7451    (use (reg:SI 19))
7452    (use (const_int 1))]
7453   "!TARGET_64BIT"
7454   "*
7456   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7458   [(set_attr "type" "dyncall")
7459    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
7461 ;; This pattern is split if it is necessary to save and restore the
7462 ;; PIC register.
7463 (define_insn "call_reg_64bit"
7464   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7465          (match_operand 1 "" "i"))
7466    (clobber (reg:DI 2))
7467    (clobber (reg:DI 4))
7468    (use (reg:DI 27))
7469    (use (reg:DI 29))
7470    (use (const_int 1))]
7471   "TARGET_64BIT"
7472   "*
7474   return output_indirect_call (insn, operands[0]);
7476   [(set_attr "type" "dyncall")
7477    (set (attr "length")
7478         (plus (symbol_ref "attr_length_indirect_call (insn)")
7479               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7481 ;; Split out the PIC register save and restore after reload.  This is
7482 ;; done only if the function returns.  As the split is done after reload,
7483 ;; there are some situations in which we unnecessarily save and restore
7484 ;; %r4.  This happens when there is a single call and the PIC register
7485 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7486 ;; the PIC register isn't completely determined until the reload pass.
7487 (define_split
7488   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7489                     (match_operand 1 "" ""))
7490               (clobber (reg:DI 2))
7491               (clobber (reg:DI 4))
7492               (use (reg:DI 27))
7493               (use (reg:DI 29))
7494               (use (const_int 1))])]
7495   "TARGET_64BIT
7496    && reload_completed
7497    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7498   [(set (reg:DI 4) (reg:DI 27))
7499    (parallel [(call (mem:SI (match_dup 0))
7500                     (match_dup 1))
7501               (clobber (reg:DI 2))
7502               (use (reg:DI 27))
7503               (use (reg:DI 29))
7504               (use (const_int 1))])
7505    (set (reg:DI 27) (reg:DI 4))]
7506   "")
7508 ;; Remove the clobber of register 4 when optimizing.  This has to be
7509 ;; done with a peephole optimization rather than a split because the
7510 ;; split sequence for a call must be longer than one instruction.
7511 (define_peephole2
7512   [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
7513                     (match_operand 1 "" ""))
7514               (clobber (reg:DI 2))
7515               (clobber (reg:DI 4))
7516               (use (reg:DI 27))
7517               (use (reg:DI 29))
7518               (use (const_int 1))])]
7519   "TARGET_64BIT && reload_completed"
7520   [(parallel [(call (mem:SI (match_dup 0))
7521                     (match_dup 1))
7522               (clobber (reg:DI 2))
7523               (use (reg:DI 27))
7524               (use (reg:DI 29))
7525               (use (const_int 1))])]
7526   "")
7528 (define_insn "*call_reg_64bit_post_reload"
7529   [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
7530          (match_operand 1 "" "i"))
7531    (clobber (reg:DI 2))
7532    (use (reg:DI 27))
7533    (use (reg:DI 29))
7534    (use (const_int 1))]
7535   "TARGET_64BIT"
7536   "*
7538   return output_indirect_call (insn, operands[0]);
7540   [(set_attr "type" "dyncall")
7541    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
7543 (define_expand "call_value"
7544   [(parallel [(set (match_operand 0 "" "")
7545                    (call (match_operand:SI 1 "" "")
7546                          (match_operand 2 "" "")))
7547               (clobber (reg:SI 2))])]
7548   ""
7549   "
7551   rtx op, call_insn;
7552   rtx dst = operands[0];
7553   rtx nb = operands[2];
7555   if (TARGET_PORTABLE_RUNTIME)
7556     op = force_reg (SImode, XEXP (operands[1], 0));
7557   else
7558     op = XEXP (operands[1], 0);
7560   if (TARGET_64BIT)
7561     {
7562       if (!virtuals_instantiated)
7563         emit_move_insn (arg_pointer_rtx,
7564                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
7565                                       GEN_INT (64)));
7566       else
7567         {
7568           /* The loop pass can generate new libcalls after the virtual
7569              registers are instantiated when fpregs are disabled because
7570              the only method that we have for doing DImode multiplication
7571              is with a libcall.  This could be trouble if we haven't
7572              allocated enough space for the outgoing arguments.  */
7573           if (INTVAL (nb) > current_function_outgoing_args_size)
7574             abort ();
7576           emit_move_insn (arg_pointer_rtx,
7577                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
7578                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
7579         }
7580     }
7582   /* Use two different patterns for calls to explicitly named functions
7583      and calls through function pointers.  This is necessary as these two
7584      types of calls use different calling conventions, and CSE might try
7585      to change the named call into an indirect call in some cases (using
7586      two patterns keeps CSE from performing this optimization).
7588      We now use even more call patterns as there was a subtle bug in
7589      attempting to restore the pic register after a call using a simple
7590      move insn.  During reload, a instruction involving a pseudo register
7591      with no explicit dependence on the PIC register can be converted
7592      to an equivalent load from memory using the PIC register.  If we
7593      emit a simple move to restore the PIC register in the initial rtl
7594      generation, then it can potentially be repositioned during scheduling.
7595      and an instruction that eventually uses the PIC register may end up
7596      between the call and the PIC register restore.
7597      
7598      This only worked because there is a post call group of instructions
7599      that are scheduled with the call.  These instructions are included
7600      in the same basic block as the call.  However, calls can throw in
7601      C++ code and a basic block has to terminate at the call if the call
7602      can throw.  This results in the PIC register restore being scheduled
7603      independently from the call.  So, we now hide the save and restore
7604      of the PIC register in the call pattern until after reload.  Then,
7605      we split the moves out.  A small side benefit is that we now don't
7606      need to have a use of the PIC register in the return pattern and
7607      the final save/restore operation is not needed.
7608      
7609      I elected to just clobber %r4 in the PIC patterns and use it instead
7610      of trying to force hppa_pic_save_rtx () to a callee saved register.
7611      This might have required a new register class and constraint.  It
7612      was also simpler to just handle the restore from a register than a
7613      generic pseudo.  */
7614   if (TARGET_64BIT)
7615     {
7616       if (GET_CODE (op) == SYMBOL_REF)
7617         call_insn = emit_call_insn (gen_call_val_symref_64bit (dst, op, nb));
7618       else
7619         {
7620           op = force_reg (word_mode, op);
7621           call_insn = emit_call_insn (gen_call_val_reg_64bit (dst, op, nb));
7622         }
7623     }
7624   else
7625     {
7626       if (GET_CODE (op) == SYMBOL_REF)
7627         {
7628           if (flag_pic)
7629             call_insn = emit_call_insn (gen_call_val_symref_pic (dst, op, nb));
7630           else
7631             call_insn = emit_call_insn (gen_call_val_symref (dst, op, nb));
7632         }
7633       else
7634         {
7635           rtx tmpreg = gen_rtx_REG (word_mode, 22);
7637           emit_move_insn (tmpreg, force_reg (word_mode, op));
7638           if (flag_pic)
7639             call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb));
7640           else
7641             call_insn = emit_call_insn (gen_call_val_reg (dst, nb));
7642         }
7643     }
7645   DONE;
7648 (define_insn "call_val_symref"
7649   [(set (match_operand 0 "" "")
7650         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7651               (match_operand 2 "" "i")))
7652    (clobber (reg:SI 1))
7653    (clobber (reg:SI 2))
7654    (use (const_int 0))]
7655   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7656   "*
7658   output_arg_descriptor (insn);
7659   return output_call (insn, operands[1], 0);
7661   [(set_attr "type" "call")
7662    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7664 (define_insn "call_val_symref_pic"
7665   [(set (match_operand 0 "" "")
7666         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7667               (match_operand 2 "" "i")))
7668    (clobber (reg:SI 1))
7669    (clobber (reg:SI 2))
7670    (clobber (reg:SI 4))
7671    (use (reg:SI 19))
7672    (use (const_int 0))]
7673   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7674   "*
7676   output_arg_descriptor (insn);
7677   return output_call (insn, operands[1], 0);
7679   [(set_attr "type" "call")
7680    (set (attr "length")
7681         (plus (symbol_ref "attr_length_call (insn, 0)")
7682               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7684 ;; Split out the PIC register save and restore after reload.  This is
7685 ;; done only if the function returns.  As the split is done after reload,
7686 ;; there are some situations in which we unnecessarily save and restore
7687 ;; %r4.  This happens when there is a single call and the PIC register
7688 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7689 ;; the PIC register isn't completely determined until the reload pass.
7690 (define_split
7691   [(parallel [(set (match_operand 0 "" "")
7692               (call (mem:SI (match_operand 1 "call_operand_address" ""))
7693                     (match_operand 2 "" "")))
7694               (clobber (reg:SI 1))
7695               (clobber (reg:SI 2))
7696               (clobber (reg:SI 4))
7697               (use (reg:SI 19))
7698               (use (const_int 0))])]
7699   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT
7700    && reload_completed
7701    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7702   [(set (reg:SI 4) (reg:SI 19))
7703    (parallel [(set (match_dup 0)
7704               (call (mem:SI (match_dup 1))
7705                     (match_dup 2)))
7706               (clobber (reg:SI 1))
7707               (clobber (reg:SI 2))
7708               (use (reg:SI 19))
7709               (use (const_int 0))])
7710    (set (reg:SI 19) (reg:SI 4))]
7711   "")
7713 ;; Remove the clobber of register 4 when optimizing.  This has to be
7714 ;; done with a peephole optimization rather than a split because the
7715 ;; split sequence for a call must be longer than one instruction.
7716 (define_peephole2
7717   [(parallel [(set (match_operand 0 "" "")
7718               (call (mem:SI (match_operand 1 "call_operand_address" ""))
7719                     (match_operand 2 "" "")))
7720               (clobber (reg:SI 1))
7721               (clobber (reg:SI 2))
7722               (clobber (reg:SI 4))
7723               (use (reg:SI 19))
7724               (use (const_int 0))])]
7725   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
7726   [(parallel [(set (match_dup 0)
7727               (call (mem:SI (match_dup 1))
7728                     (match_dup 2)))
7729               (clobber (reg:SI 1))
7730               (clobber (reg:SI 2))
7731               (use (reg:SI 19))
7732               (use (const_int 0))])]
7733   "")
7735 (define_insn "*call_val_symref_pic_post_reload"
7736   [(set (match_operand 0 "" "")
7737         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7738               (match_operand 2 "" "i")))
7739    (clobber (reg:SI 1))
7740    (clobber (reg:SI 2))
7741    (use (reg:SI 19))
7742    (use (const_int 0))]
7743   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
7744   "*
7746   output_arg_descriptor (insn);
7747   return output_call (insn, operands[1], 0);
7749   [(set_attr "type" "call")
7750    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7752 ;; This pattern is split if it is necessary to save and restore the
7753 ;; PIC register.
7754 (define_insn "call_val_symref_64bit"
7755   [(set (match_operand 0 "" "")
7756         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7757               (match_operand 2 "" "i")))
7758    (clobber (reg:DI 1))
7759    (clobber (reg:DI 2))
7760    (clobber (reg:DI 4))
7761    (use (reg:DI 27))
7762    (use (reg:DI 29))
7763    (use (const_int 0))]
7764   "TARGET_64BIT"
7765   "*
7767   output_arg_descriptor (insn);
7768   return output_call (insn, operands[1], 0);
7770   [(set_attr "type" "call")
7771    (set (attr "length")
7772         (plus (symbol_ref "attr_length_call (insn, 0)")
7773               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7775 ;; Split out the PIC register save and restore after reload.  This is
7776 ;; done only if the function returns.  As the split is done after reload,
7777 ;; there are some situations in which we unnecessarily save and restore
7778 ;; %r4.  This happens when there is a single call and the PIC register
7779 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7780 ;; the PIC register isn't completely determined until the reload pass.
7781 (define_split
7782   [(parallel [(set (match_operand 0 "" "")
7783               (call (mem:SI (match_operand 1 "call_operand_address" ""))
7784                     (match_operand 2 "" "")))
7785               (clobber (reg:DI 1))
7786               (clobber (reg:DI 2))
7787               (clobber (reg:DI 4))
7788               (use (reg:DI 27))
7789               (use (reg:DI 29))
7790               (use (const_int 0))])]
7791   "TARGET_64BIT
7792    && reload_completed
7793    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7794   [(set (reg:DI 4) (reg:DI 27))
7795    (parallel [(set (match_dup 0)
7796               (call (mem:SI (match_dup 1))
7797                     (match_dup 2)))
7798               (clobber (reg:DI 1))
7799               (clobber (reg:DI 2))
7800               (use (reg:DI 27))
7801               (use (reg:DI 29))
7802               (use (const_int 0))])
7803    (set (reg:DI 27) (reg:DI 4))]
7804   "")
7806 ;; Remove the clobber of register 4 when optimizing.  This has to be
7807 ;; done with a peephole optimization rather than a split because the
7808 ;; split sequence for a call must be longer than one instruction.
7809 (define_peephole2
7810   [(parallel [(set (match_operand 0 "" "")
7811               (call (mem:SI (match_operand 1 "call_operand_address" ""))
7812                     (match_operand 2 "" "")))
7813               (clobber (reg:DI 1))
7814               (clobber (reg:DI 2))
7815               (clobber (reg:DI 4))
7816               (use (reg:DI 27))
7817               (use (reg:DI 29))
7818               (use (const_int 0))])]
7819   "TARGET_64BIT && reload_completed"
7820   [(parallel [(set (match_dup 0)
7821               (call (mem:SI (match_dup 1))
7822                     (match_dup 2)))
7823               (clobber (reg:DI 1))
7824               (clobber (reg:DI 2))
7825               (use (reg:DI 27))
7826               (use (reg:DI 29))
7827               (use (const_int 0))])]
7828   "")
7830 (define_insn "*call_val_symref_64bit_post_reload"
7831   [(set (match_operand 0 "" "")
7832         (call (mem:SI (match_operand 1 "call_operand_address" ""))
7833               (match_operand 2 "" "i")))
7834    (clobber (reg:DI 1))
7835    (clobber (reg:DI 2))
7836    (use (reg:DI 27))
7837    (use (reg:DI 29))
7838    (use (const_int 0))]
7839   "TARGET_64BIT"
7840   "*
7842   output_arg_descriptor (insn);
7843   return output_call (insn, operands[1], 0);
7845   [(set_attr "type" "call")
7846    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
7848 (define_insn "call_val_reg"
7849   [(set (match_operand 0 "" "")
7850         (call (mem:SI (reg:SI 22))
7851               (match_operand 1 "" "i")))
7852    (clobber (reg:SI 1))
7853    (clobber (reg:SI 2))
7854    (use (const_int 1))]
7855   "!TARGET_64BIT"
7856   "*
7858   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7860   [(set_attr "type" "dyncall")
7861    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
7863 ;; This pattern is split if it is necessary to save and restore the
7864 ;; PIC register.
7865 (define_insn "call_val_reg_pic"
7866   [(set (match_operand 0 "" "")
7867         (call (mem:SI (reg:SI 22))
7868               (match_operand 1 "" "i")))
7869    (clobber (reg:SI 1))
7870    (clobber (reg:SI 2))
7871    (clobber (reg:SI 4))
7872    (use (reg:SI 19))
7873    (use (const_int 1))]
7874   "!TARGET_64BIT"
7875   "*
7877   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7879   [(set_attr "type" "dyncall")
7880    (set (attr "length")
7881         (plus (symbol_ref "attr_length_indirect_call (insn)")
7882               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7884 ;; Split out the PIC register save and restore after reload.  This is
7885 ;; done only if the function returns.  As the split is done after reload,
7886 ;; there are some situations in which we unnecessarily save and restore
7887 ;; %r4.  This happens when there is a single call and the PIC register
7888 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7889 ;; the PIC register isn't completely determined until the reload pass.
7890 (define_split
7891   [(parallel [(set (match_operand 0 "" "")
7892                    (call (mem:SI (reg:SI 22))
7893                          (match_operand 1 "" "")))
7894               (clobber (reg:SI 1))
7895               (clobber (reg:SI 2))
7896               (clobber (reg:SI 4))
7897               (use (reg:SI 19))
7898               (use (const_int 1))])]
7899   "!TARGET_64BIT
7900    && reload_completed
7901    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7902   [(set (reg:SI 4) (reg:SI 19))
7903    (parallel [(set (match_dup 0)
7904                    (call (mem:SI (reg:SI 22))
7905                          (match_dup 1)))
7906               (clobber (reg:SI 1))
7907               (clobber (reg:SI 2))
7908               (use (reg:SI 19))
7909               (use (const_int 1))])
7910    (set (reg:SI 19) (reg:SI 4))]
7911   "")
7913 ;; Remove the clobber of register 4 when optimizing.  This has to be
7914 ;; done with a peephole optimization rather than a split because the
7915 ;; split sequence for a call must be longer than one instruction.
7916 (define_peephole2
7917   [(parallel [(set (match_operand 0 "" "")
7918                    (call (mem:SI (reg:SI 22))
7919                          (match_operand 1 "" "")))
7920               (clobber (reg:SI 1))
7921               (clobber (reg:SI 2))
7922               (clobber (reg:SI 4))
7923               (use (reg:SI 19))
7924               (use (const_int 1))])]
7925   "!TARGET_64BIT && reload_completed"
7926   [(parallel [(set (match_dup 0)
7927                    (call (mem:SI (reg:SI 22))
7928                          (match_dup 1)))
7929               (clobber (reg:SI 1))
7930               (clobber (reg:SI 2))
7931               (use (reg:SI 19))
7932               (use (const_int 1))])]
7933   "")
7935 (define_insn "*call_val_reg_pic_post_reload"
7936   [(set (match_operand 0 "" "")
7937         (call (mem:SI (reg:SI 22))
7938               (match_operand 1 "" "i")))
7939    (clobber (reg:SI 1))
7940    (clobber (reg:SI 2))
7941    (use (reg:SI 19))
7942    (use (const_int 1))]
7943   "!TARGET_64BIT"
7944   "*
7946   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
7948   [(set_attr "type" "dyncall")
7949    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
7951 ;; This pattern is split if it is necessary to save and restore the
7952 ;; PIC register.
7953 (define_insn "call_val_reg_64bit"
7954   [(set (match_operand 0 "" "")
7955         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
7956               (match_operand 2 "" "i")))
7957    (clobber (reg:DI 2))
7958    (clobber (reg:DI 4))
7959    (use (reg:DI 27))
7960    (use (reg:DI 29))
7961    (use (const_int 1))]
7962   "TARGET_64BIT"
7963   "*
7965   return output_indirect_call (insn, operands[1]);
7967   [(set_attr "type" "dyncall")
7968    (set (attr "length")
7969         (plus (symbol_ref "attr_length_indirect_call (insn)")
7970               (symbol_ref "attr_length_save_restore_dltp (insn)")))])
7972 ;; Split out the PIC register save and restore after reload.  This is
7973 ;; done only if the function returns.  As the split is done after reload,
7974 ;; there are some situations in which we unnecessarily save and restore
7975 ;; %r4.  This happens when there is a single call and the PIC register
7976 ;; is "dead" after the call.  This isn't easy to fix as the usage of
7977 ;; the PIC register isn't completely determined until the reload pass.
7978 (define_split
7979   [(parallel [(set (match_operand 0 "" "")
7980                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
7981                          (match_operand 2 "" "")))
7982               (clobber (reg:DI 2))
7983               (clobber (reg:DI 4))
7984               (use (reg:DI 27))
7985               (use (reg:DI 29))
7986               (use (const_int 1))])]
7987   "TARGET_64BIT
7988    && reload_completed
7989    && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7990   [(set (reg:DI 4) (reg:DI 27))
7991    (parallel [(set (match_dup 0)
7992                    (call (mem:SI (match_dup 1))
7993                          (match_dup 2)))
7994               (clobber (reg:DI 2))
7995               (use (reg:DI 27))
7996               (use (reg:DI 29))
7997               (use (const_int 1))])
7998    (set (reg:DI 27) (reg:DI 4))]
7999   "")
8001 ;; Remove the clobber of register 4 when optimizing.  This has to be
8002 ;; done with a peephole optimization rather than a split because the
8003 ;; split sequence for a call must be longer than one instruction.
8004 (define_peephole2
8005   [(parallel [(set (match_operand 0 "" "")
8006                    (call (mem:SI (match_operand:DI 1 "register_operand" ""))
8007                          (match_operand 2 "" "")))
8008               (clobber (reg:DI 2))
8009               (clobber (reg:DI 4))
8010               (use (reg:DI 27))
8011               (use (reg:DI 29))
8012               (use (const_int 1))])]
8013   "TARGET_64BIT && reload_completed"
8014   [(parallel [(set (match_dup 0)
8015                    (call (mem:SI (match_dup 1))
8016                          (match_dup 2)))
8017               (clobber (reg:DI 2))
8018               (use (reg:DI 27))
8019               (use (reg:DI 29))
8020               (use (const_int 1))])]
8021   "")
8023 (define_insn "*call_val_reg_64bit_post_reload"
8024   [(set (match_operand 0 "" "")
8025         (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
8026               (match_operand 2 "" "i")))
8027    (clobber (reg:DI 2))
8028    (use (reg:DI 27))
8029    (use (reg:DI 29))
8030    (use (const_int 1))]
8031   "TARGET_64BIT"
8032   "*
8034   return output_indirect_call (insn, operands[1]);
8036   [(set_attr "type" "dyncall")
8037    (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
8039 ;; Call subroutine returning any type.
8041 (define_expand "untyped_call"
8042   [(parallel [(call (match_operand 0 "" "")
8043                     (const_int 0))
8044               (match_operand 1 "" "")
8045               (match_operand 2 "" "")])]
8046   ""
8047   "
8049   int i;
8051   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
8053   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8054     {
8055       rtx set = XVECEXP (operands[2], 0, i);
8056       emit_move_insn (SET_DEST (set), SET_SRC (set));
8057     }
8059   /* The optimizer does not know that the call sets the function value
8060      registers we stored in the result block.  We avoid problems by
8061      claiming that all hard registers are used and clobbered at this
8062      point.  */
8063   emit_insn (gen_blockage ());
8065   DONE;
8068 (define_expand "sibcall"
8069   [(call (match_operand:SI 0 "" "")
8070          (match_operand 1 "" ""))]
8071   "!TARGET_PORTABLE_RUNTIME"
8072   "
8074   rtx op, call_insn;
8075   rtx nb = operands[1];
8077   op = XEXP (operands[0], 0);
8079   if (TARGET_64BIT)
8080     {
8081       if (!virtuals_instantiated)
8082         emit_move_insn (arg_pointer_rtx,
8083                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8084                                       GEN_INT (64)));
8085       else
8086         {
8087           /* The loop pass can generate new libcalls after the virtual
8088              registers are instantiated when fpregs are disabled because
8089              the only method that we have for doing DImode multiplication
8090              is with a libcall.  This could be trouble if we haven't
8091              allocated enough space for the outgoing arguments.  */
8092           if (INTVAL (nb) > current_function_outgoing_args_size)
8093             abort ();
8095           emit_move_insn (arg_pointer_rtx,
8096                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8097                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8098         }
8099     }
8101   /* Indirect sibling calls are not allowed.  */
8102   if (TARGET_64BIT)
8103     call_insn = gen_sibcall_internal_symref_64bit (op, operands[1]);
8104   else
8105     call_insn = gen_sibcall_internal_symref (op, operands[1]);
8107   call_insn = emit_call_insn (call_insn);
8109   if (TARGET_64BIT)
8110     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8112   /* We don't have to restore the PIC register.  */
8113   if (flag_pic)
8114     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8116   DONE;
8119 (define_insn "sibcall_internal_symref"
8120   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8121          (match_operand 1 "" "i"))
8122    (clobber (reg:SI 1))
8123    (use (reg:SI 2))
8124    (use (const_int 0))]
8125   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8126   "*
8128   output_arg_descriptor (insn);
8129   return output_call (insn, operands[0], 1);
8131   [(set_attr "type" "call")
8132    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
8134 (define_insn "sibcall_internal_symref_64bit"
8135   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
8136          (match_operand 1 "" "i"))
8137    (clobber (reg:DI 1))
8138    (use (reg:DI 2))
8139    (use (const_int 0))]
8140   "TARGET_64BIT"
8141   "*
8143   output_arg_descriptor (insn);
8144   return output_call (insn, operands[0], 1);
8146   [(set_attr "type" "call")
8147    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
8149 (define_expand "sibcall_value"
8150   [(set (match_operand 0 "" "")
8151                    (call (match_operand:SI 1 "" "")
8152                          (match_operand 2 "" "")))]
8153   "!TARGET_PORTABLE_RUNTIME"
8154   "
8156   rtx op, call_insn;
8157   rtx nb = operands[1];
8159   op = XEXP (operands[1], 0);
8161   if (TARGET_64BIT)
8162     {
8163       if (!virtuals_instantiated)
8164         emit_move_insn (arg_pointer_rtx,
8165                         gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
8166                                       GEN_INT (64)));
8167       else
8168         {
8169           /* The loop pass can generate new libcalls after the virtual
8170              registers are instantiated when fpregs are disabled because
8171              the only method that we have for doing DImode multiplication
8172              is with a libcall.  This could be trouble if we haven't
8173              allocated enough space for the outgoing arguments.  */
8174           if (INTVAL (nb) > current_function_outgoing_args_size)
8175             abort ();
8177           emit_move_insn (arg_pointer_rtx,
8178                           gen_rtx_PLUS (word_mode, stack_pointer_rtx,
8179                                         GEN_INT (STACK_POINTER_OFFSET + 64)));
8180         }
8181     }
8183   /* Indirect sibling calls are not allowed.  */
8184   if (TARGET_64BIT)
8185     call_insn
8186       = gen_sibcall_value_internal_symref_64bit (operands[0], op, operands[2]);
8187   else
8188     call_insn
8189       = gen_sibcall_value_internal_symref (operands[0], op, operands[2]);
8191   call_insn = emit_call_insn (call_insn);
8193   if (TARGET_64BIT)
8194     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
8196   /* We don't have to restore the PIC register.  */
8197   if (flag_pic)
8198     use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
8200   DONE;
8203 (define_insn "sibcall_value_internal_symref"
8204   [(set (match_operand 0 "" "")
8205         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8206               (match_operand 2 "" "i")))
8207    (clobber (reg:SI 1))
8208    (use (reg:SI 2))
8209    (use (const_int 0))]
8210   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
8211   "*
8213   output_arg_descriptor (insn);
8214   return output_call (insn, operands[1], 1);
8216   [(set_attr "type" "call")
8217    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
8219 (define_insn "sibcall_value_internal_symref_64bit"
8220   [(set (match_operand 0 "" "")
8221         (call (mem:SI (match_operand 1 "call_operand_address" ""))
8222               (match_operand 2 "" "i")))
8223    (clobber (reg:DI 1))
8224    (use (reg:DI 2))
8225    (use (const_int 0))]
8226   "TARGET_64BIT"
8227   "*
8229   output_arg_descriptor (insn);
8230   return output_call (insn, operands[1], 1);
8232   [(set_attr "type" "call")
8233    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
8235 (define_insn "nop"
8236   [(const_int 0)]
8237   ""
8238   "nop"
8239   [(set_attr "type" "move")
8240    (set_attr "length" "4")])
8242 ;; These are just placeholders so we know where branch tables
8243 ;; begin and end.
8244 (define_insn "begin_brtab"
8245   [(const_int 1)]
8246   ""
8247   "*
8249   /* Only GAS actually supports this pseudo-op.  */
8250   if (TARGET_GAS)
8251     return \".begin_brtab\";
8252   else
8253     return \"\";
8255   [(set_attr "type" "move")
8256    (set_attr "length" "0")])
8258 (define_insn "end_brtab"
8259   [(const_int 2)]
8260   ""
8261   "*
8263   /* Only GAS actually supports this pseudo-op.  */
8264   if (TARGET_GAS)
8265     return \".end_brtab\";
8266   else
8267     return \"\";
8269   [(set_attr "type" "move")
8270    (set_attr "length" "0")])
8272 ;;; EH does longjmp's from and within the data section.  Thus,
8273 ;;; an interspace branch is required for the longjmp implementation.
8274 ;;; Registers r1 and r2 are used as scratch registers for the jump
8275 ;;; when necessary.
8276 (define_expand "interspace_jump"
8277   [(parallel
8278      [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8279       (clobber (match_dup 1))])]
8280   ""
8281   "
8283   operands[1] = gen_rtx_REG (word_mode, 2);
8286 (define_insn ""
8287   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8288   (clobber (reg:SI 2))]
8289   "TARGET_PA_20 && !TARGET_64BIT"
8290   "bve%* (%0)"
8291    [(set_attr "type" "branch")
8292     (set_attr "length" "4")])
8294 (define_insn ""
8295   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8296   (clobber (reg:SI 2))]
8297   "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
8298   "be%* 0(%%sr4,%0)"
8299    [(set_attr "type" "branch")
8300     (set_attr "length" "4")])
8302 (define_insn ""
8303   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8304   (clobber (reg:SI 2))]
8305   "!TARGET_64BIT"
8306   "ldsid (%%sr0,%0),%%r2\;mtsp %%r2,%%sr0\;be%* 0(%%sr0,%0)"
8307    [(set_attr "type" "branch")
8308     (set_attr "length" "12")])
8310 (define_insn ""
8311   [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
8312   (clobber (reg:DI 2))]
8313   "TARGET_64BIT"
8314   "bve%* (%0)"
8315    [(set_attr "type" "branch")
8316     (set_attr "length" "4")])
8318 (define_expand "builtin_longjmp"
8319   [(unspec_volatile [(match_operand 0 "register_operand" "r")] UNSPECV_LONGJMP)]
8320   ""
8321   "
8323   /* The elements of the buffer are, in order:  */
8324   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
8325   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0],
8326                          POINTER_SIZE / BITS_PER_UNIT));
8327   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0],
8328                            (POINTER_SIZE * 2) / BITS_PER_UNIT));
8329   rtx pv = gen_rtx_REG (Pmode, 1);
8331   emit_insn (gen_rtx_CLOBBER (VOIDmode,
8332                               gen_rtx_MEM (BLKmode,
8333                                            gen_rtx_SCRATCH (VOIDmode))));
8334   emit_insn (gen_rtx_CLOBBER (VOIDmode,
8335                               gen_rtx_MEM (BLKmode,
8336                                            hard_frame_pointer_rtx)));
8338   /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
8339      instead of the hard_frame_pointer_rtx in the save area.  We need
8340      to adjust for the offset between these two values when we have
8341      a nonlocal_goto pattern.  When we don't have a nonlocal_goto
8342      pattern, the receiver performs the adjustment.  */
8343 #ifdef HAVE_nonlocal_goto
8344   if (HAVE_nonlocal_goto)
8345     emit_move_insn (virtual_stack_vars_rtx, force_reg (Pmode, fp));
8346   else
8347 #endif
8348     emit_move_insn (hard_frame_pointer_rtx, fp);
8350   /* This bit is the same as expand_builtin_longjmp.  */
8351   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
8352   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
8353   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8355   /* Load the label we are jumping through into r1 so that we know
8356      where to look for it when we get back to setjmp's function for
8357      restoring the gp.  */
8358   emit_move_insn (pv, lab);
8360   /* Prevent the insns above from being scheduled into the delay slot
8361      of the interspace jump because the space register could change.  */
8362   emit_insn (gen_blockage ());
8364   emit_jump_insn (gen_interspace_jump (pv));
8365   emit_barrier ();
8366   DONE;
8369 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8370 (define_expand "extzv"
8371   [(set (match_operand 0 "register_operand" "")
8372         (zero_extract (match_operand 1 "register_operand" "")
8373                       (match_operand 2 "uint32_operand" "")
8374                       (match_operand 3 "uint32_operand" "")))]
8375   ""
8376   "
8378   HOST_WIDE_INT len = INTVAL (operands[2]);
8379   HOST_WIDE_INT pos = INTVAL (operands[3]);
8381   /* PA extraction insns don't support zero length bitfields or fields
8382      extending beyond the left or right-most bits.  Also, we reject lengths
8383      equal to a word as they are better handled by the move patterns.  */
8384   if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8385     FAIL;
8387   /* From mips.md: extract_bit_field doesn't verify that our source
8388      matches the predicate, so check it again here.  */
8389   if (!register_operand (operands[1], VOIDmode))
8390     FAIL;
8392   if (TARGET_64BIT)
8393     emit_insn (gen_extzv_64 (operands[0], operands[1],
8394                              operands[2], operands[3]));
8395   else
8396     emit_insn (gen_extzv_32 (operands[0], operands[1],
8397                              operands[2], operands[3]));
8398   DONE;
8401 (define_insn "extzv_32"
8402   [(set (match_operand:SI 0 "register_operand" "=r")
8403         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8404                          (match_operand:SI 2 "uint5_operand" "")
8405                          (match_operand:SI 3 "uint5_operand" "")))]
8406   ""
8407   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
8408   [(set_attr "type" "shift")
8409    (set_attr "length" "4")])
8411 (define_insn ""
8412   [(set (match_operand:SI 0 "register_operand" "=r")
8413         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
8414                          (const_int 1)
8415                          (match_operand:SI 2 "register_operand" "q")))]
8416   ""
8417   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
8418   [(set_attr "type" "shift")
8419    (set_attr "length" "4")])
8421 (define_insn "extzv_64"
8422   [(set (match_operand:DI 0 "register_operand" "=r")
8423         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8424                          (match_operand:DI 2 "uint32_operand" "")
8425                          (match_operand:DI 3 "uint32_operand" "")))]
8426   "TARGET_64BIT"
8427   "extrd,u %1,%3+%2-1,%2,%0"
8428   [(set_attr "type" "shift")
8429    (set_attr "length" "4")])
8431 (define_insn ""
8432   [(set (match_operand:DI 0 "register_operand" "=r")
8433         (zero_extract:DI (match_operand:DI 1 "register_operand" "r")
8434                          (const_int 1)
8435                          (match_operand:DI 2 "register_operand" "q")))]
8436   "TARGET_64BIT"
8437   "extrd,u %1,%%sar,1,%0"
8438   [(set_attr "type" "shift")
8439    (set_attr "length" "4")])
8441 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
8442 (define_expand "extv"
8443   [(set (match_operand 0 "register_operand" "")
8444         (sign_extract (match_operand 1 "register_operand" "")
8445                       (match_operand 2 "uint32_operand" "")
8446                       (match_operand 3 "uint32_operand" "")))]
8447   ""
8448   "
8450   HOST_WIDE_INT len = INTVAL (operands[2]);
8451   HOST_WIDE_INT pos = INTVAL (operands[3]);
8453   /* PA extraction insns don't support zero length bitfields or fields
8454      extending beyond the left or right-most bits.  Also, we reject lengths
8455      equal to a word as they are better handled by the move patterns.  */
8456   if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8457     FAIL;
8459   /* From mips.md: extract_bit_field doesn't verify that our source
8460      matches the predicate, so check it again here.  */
8461   if (!register_operand (operands[1], VOIDmode))
8462     FAIL;
8464   if (TARGET_64BIT)
8465     emit_insn (gen_extv_64 (operands[0], operands[1],
8466                             operands[2], operands[3]));
8467   else
8468     emit_insn (gen_extv_32 (operands[0], operands[1],
8469                             operands[2], operands[3]));
8470   DONE;
8473 (define_insn "extv_32"
8474   [(set (match_operand:SI 0 "register_operand" "=r")
8475         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8476                          (match_operand:SI 2 "uint5_operand" "")
8477                          (match_operand:SI 3 "uint5_operand" "")))]
8478   ""
8479   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
8480   [(set_attr "type" "shift")
8481    (set_attr "length" "4")])
8483 (define_insn ""
8484   [(set (match_operand:SI 0 "register_operand" "=r")
8485         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
8486                          (const_int 1)
8487                          (match_operand:SI 2 "register_operand" "q")))]
8488   "!TARGET_64BIT"
8489   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
8490   [(set_attr "type" "shift")
8491    (set_attr "length" "4")])
8493 (define_insn "extv_64"
8494   [(set (match_operand:DI 0 "register_operand" "=r")
8495         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8496                          (match_operand:DI 2 "uint32_operand" "")
8497                          (match_operand:DI 3 "uint32_operand" "")))]
8498   "TARGET_64BIT"
8499   "extrd,s %1,%3+%2-1,%2,%0"
8500   [(set_attr "type" "shift")
8501    (set_attr "length" "4")])
8503 (define_insn ""
8504   [(set (match_operand:DI 0 "register_operand" "=r")
8505         (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
8506                          (const_int 1)
8507                          (match_operand:DI 2 "register_operand" "q")))]
8508   "TARGET_64BIT"
8509   "extrd,s %1,%%sar,1,%0"
8510   [(set_attr "type" "shift")
8511    (set_attr "length" "4")])
8513 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
8514 (define_expand "insv"
8515   [(set (zero_extract (match_operand 0 "register_operand" "")
8516                       (match_operand 1 "uint32_operand" "")
8517                       (match_operand 2 "uint32_operand" ""))
8518         (match_operand 3 "arith5_operand" ""))]
8519   ""
8520   "
8522   HOST_WIDE_INT len = INTVAL (operands[1]);
8523   HOST_WIDE_INT pos = INTVAL (operands[2]);
8525   /* PA insertion insns don't support zero length bitfields or fields
8526      extending beyond the left or right-most bits.  Also, we reject lengths
8527      equal to a word as they are better handled by the move patterns.  */
8528   if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
8529     FAIL;
8531   /* From mips.md: insert_bit_field doesn't verify that our destination
8532      matches the predicate, so check it again here.  */
8533   if (!register_operand (operands[0], VOIDmode))
8534     FAIL;
8536   if (TARGET_64BIT)
8537     emit_insn (gen_insv_64 (operands[0], operands[1],
8538                             operands[2], operands[3]));
8539   else
8540     emit_insn (gen_insv_32 (operands[0], operands[1],
8541                             operands[2], operands[3]));
8542   DONE;
8545 (define_insn "insv_32"
8546   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
8547                          (match_operand:SI 1 "uint5_operand" "")
8548                          (match_operand:SI 2 "uint5_operand" ""))
8549         (match_operand:SI 3 "arith5_operand" "r,L"))]
8550   ""
8551   "@
8552    {dep|depw} %3,%2+%1-1,%1,%0
8553    {depi|depwi} %3,%2+%1-1,%1,%0"
8554   [(set_attr "type" "shift,shift")
8555    (set_attr "length" "4,4")])
8557 ;; Optimize insertion of const_int values of type 1...1xxxx.
8558 (define_insn ""
8559   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
8560                          (match_operand:SI 1 "uint5_operand" "")
8561                          (match_operand:SI 2 "uint5_operand" ""))
8562         (match_operand:SI 3 "const_int_operand" ""))]
8563   "(INTVAL (operands[3]) & 0x10) != 0 &&
8564    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8565   "*
8567   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8568   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
8570   [(set_attr "type" "shift")
8571    (set_attr "length" "4")])
8573 (define_insn "insv_64"
8574   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
8575                          (match_operand:DI 1 "uint32_operand" "")
8576                          (match_operand:DI 2 "uint32_operand" ""))
8577         (match_operand:DI 3 "arith32_operand" "r,L"))]
8578   "TARGET_64BIT"
8579   "@
8580    depd %3,%2+%1-1,%1,%0
8581    depdi %3,%2+%1-1,%1,%0"
8582   [(set_attr "type" "shift,shift")
8583    (set_attr "length" "4,4")])
8585 ;; Optimize insertion of const_int values of type 1...1xxxx.
8586 (define_insn ""
8587   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
8588                          (match_operand:DI 1 "uint32_operand" "")
8589                          (match_operand:DI 2 "uint32_operand" ""))
8590         (match_operand:DI 3 "const_int_operand" ""))]
8591   "(INTVAL (operands[3]) & 0x10) != 0
8592    && TARGET_64BIT
8593    && (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
8594   "*
8596   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
8597   return \"depdi %3,%2+%1-1,%1,%0\";
8599   [(set_attr "type" "shift")
8600    (set_attr "length" "4")])
8602 (define_insn ""
8603   [(set (match_operand:DI 0 "register_operand" "=r")
8604         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
8605                    (const_int 32)))]
8606   "TARGET_64BIT"
8607   "depd,z %1,31,32,%0"
8608   [(set_attr "type" "shift")
8609    (set_attr "length" "4")])
8611 ;; This insn is used for some loop tests, typically loops reversed when
8612 ;; strength reduction is used.  It is actually created when the instruction
8613 ;; combination phase combines the special loop test.  Since this insn
8614 ;; is both a jump insn and has an output, it must deal with its own
8615 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
8616 ;; to not choose the register alternatives in the event a reload is needed.
8617 (define_insn "decrement_and_branch_until_zero"
8618   [(set (pc)
8619         (if_then_else
8620           (match_operator 2 "comparison_operator"
8621            [(plus:SI
8622               (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
8623               (match_operand:SI 1 "int5_operand" "L,L,L"))
8624             (const_int 0)])
8625           (label_ref (match_operand 3 "" ""))
8626           (pc)))
8627    (set (match_dup 0)
8628         (plus:SI (match_dup 0) (match_dup 1)))
8629    (clobber (match_scratch:SI 4 "=X,r,r"))]
8630   ""
8631   "* return output_dbra (operands, insn, which_alternative); "
8632 ;; Do not expect to understand this the first time through.
8633 [(set_attr "type" "cbranch,multi,multi")
8634  (set (attr "length")
8635       (if_then_else (eq_attr "alternative" "0")
8636 ;; Loop counter in register case
8637 ;; Short branch has length of 4
8638 ;; Long branch has length of 8
8639         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8640                       (const_int 8184))
8641            (const_int 4)
8642            (const_int 8))
8644 ;; Loop counter in FP reg case.
8645 ;; Extra goo to deal with additional reload insns.
8646         (if_then_else (eq_attr "alternative" "1")
8647           (if_then_else (lt (match_dup 3) (pc))
8648             (if_then_else
8649               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
8650                   (const_int 8184))
8651               (const_int 24)
8652               (const_int 28))
8653             (if_then_else
8654               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8655                   (const_int 8184))
8656               (const_int 24)
8657               (const_int 28)))
8658 ;; Loop counter in memory case.
8659 ;; Extra goo to deal with additional reload insns.
8660         (if_then_else (lt (match_dup 3) (pc))
8661           (if_then_else
8662             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8663                 (const_int 8184))
8664             (const_int 12)
8665             (const_int 16))
8666           (if_then_else
8667             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8668                 (const_int 8184))
8669             (const_int 12)
8670             (const_int 16))))))])
8672 (define_insn ""
8673   [(set (pc)
8674         (if_then_else
8675           (match_operator 2 "movb_comparison_operator"
8676            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
8677           (label_ref (match_operand 3 "" ""))
8678           (pc)))
8679    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
8680         (match_dup 1))]
8681   ""
8682 "* return output_movb (operands, insn, which_alternative, 0); "
8683 ;; Do not expect to understand this the first time through.
8684 [(set_attr "type" "cbranch,multi,multi,multi")
8685  (set (attr "length")
8686       (if_then_else (eq_attr "alternative" "0")
8687 ;; Loop counter in register case
8688 ;; Short branch has length of 4
8689 ;; Long branch has length of 8
8690         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8691                       (const_int 8184))
8692            (const_int 4)
8693            (const_int 8))
8695 ;; Loop counter in FP reg case.
8696 ;; Extra goo to deal with additional reload insns.
8697         (if_then_else (eq_attr "alternative" "1")
8698           (if_then_else (lt (match_dup 3) (pc))
8699             (if_then_else
8700               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8701                   (const_int 8184))
8702               (const_int 12)
8703               (const_int 16))
8704             (if_then_else
8705               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8706                   (const_int 8184))
8707               (const_int 12)
8708               (const_int 16)))
8709 ;; Loop counter in memory or sar case.
8710 ;; Extra goo to deal with additional reload insns.
8711         (if_then_else
8712           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8713               (const_int 8184))
8714           (const_int 8)
8715           (const_int 12)))))])
8717 ;; Handle negated branch.
8718 (define_insn ""
8719   [(set (pc)
8720         (if_then_else
8721           (match_operator 2 "movb_comparison_operator"
8722            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
8723           (pc)
8724           (label_ref (match_operand 3 "" ""))))
8725    (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
8726         (match_dup 1))]
8727   ""
8728 "* return output_movb (operands, insn, which_alternative, 1); "
8729 ;; Do not expect to understand this the first time through.
8730 [(set_attr "type" "cbranch,multi,multi,multi")
8731  (set (attr "length")
8732       (if_then_else (eq_attr "alternative" "0")
8733 ;; Loop counter in register case
8734 ;; Short branch has length of 4
8735 ;; Long branch has length of 8
8736         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8737                       (const_int 8184))
8738            (const_int 4)
8739            (const_int 8))
8741 ;; Loop counter in FP reg case.
8742 ;; Extra goo to deal with additional reload insns.
8743         (if_then_else (eq_attr "alternative" "1")
8744           (if_then_else (lt (match_dup 3) (pc))
8745             (if_then_else
8746               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
8747                   (const_int 8184))
8748               (const_int 12)
8749               (const_int 16))
8750             (if_then_else
8751               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8752                   (const_int 8184))
8753               (const_int 12)
8754               (const_int 16)))
8755 ;; Loop counter in memory or SAR case.
8756 ;; Extra goo to deal with additional reload insns.
8757         (if_then_else
8758           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8759               (const_int 8184))
8760           (const_int 8)
8761           (const_int 12)))))])
8763 (define_insn ""
8764   [(set (pc) (label_ref (match_operand 3 "" "" )))
8765    (set (match_operand:SI 0 "ireg_operand" "=r")
8766         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
8767                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
8768   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
8769   "*
8771   return output_parallel_addb (operands, get_attr_length (insn));
8773   [(set_attr "type" "parallel_branch")
8774    (set (attr "length")
8775     (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
8776                       (const_int 8184))
8777            (const_int 4)
8778            (const_int 8)))])
8780 (define_insn ""
8781   [(set (pc) (label_ref (match_operand 2 "" "" )))
8782    (set (match_operand:SF 0 "ireg_operand" "=r")
8783         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
8784   "reload_completed"
8785   "*
8787   return output_parallel_movb (operands, get_attr_length (insn));
8789   [(set_attr "type" "parallel_branch")
8790    (set (attr "length")
8791     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8792                       (const_int 8184))
8793            (const_int 4)
8794            (const_int 8)))])
8796 (define_insn ""
8797   [(set (pc) (label_ref (match_operand 2 "" "" )))
8798    (set (match_operand:SI 0 "ireg_operand" "=r")
8799         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
8800   "reload_completed"
8801   "*
8803   return output_parallel_movb (operands, get_attr_length (insn));
8805   [(set_attr "type" "parallel_branch")
8806    (set (attr "length")
8807     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8808                       (const_int 8184))
8809            (const_int 4)
8810            (const_int 8)))])
8812 (define_insn ""
8813   [(set (pc) (label_ref (match_operand 2 "" "" )))
8814    (set (match_operand:HI 0 "ireg_operand" "=r")
8815         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
8816   "reload_completed"
8817   "*
8819   return output_parallel_movb (operands, get_attr_length (insn));
8821   [(set_attr "type" "parallel_branch")
8822    (set (attr "length")
8823     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8824                       (const_int 8184))
8825            (const_int 4)
8826            (const_int 8)))])
8828 (define_insn ""
8829   [(set (pc) (label_ref (match_operand 2 "" "" )))
8830    (set (match_operand:QI 0 "ireg_operand" "=r")
8831         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
8832   "reload_completed"
8833   "*
8835   return output_parallel_movb (operands, get_attr_length (insn));
8837   [(set_attr "type" "parallel_branch")
8838    (set (attr "length")
8839     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
8840                       (const_int 8184))
8841            (const_int 4)
8842            (const_int 8)))])
8844 (define_insn ""
8845   [(set (match_operand 0 "register_operand" "=f")
8846         (mult (match_operand 1 "register_operand" "f")
8847               (match_operand 2 "register_operand" "f")))
8848    (set (match_operand 3 "register_operand" "+f")
8849         (plus (match_operand 4 "register_operand" "f")
8850               (match_operand 5 "register_operand" "f")))]
8851   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8852    && reload_completed && fmpyaddoperands (operands)"
8853   "*
8855   if (GET_MODE (operands[0]) == DFmode)
8856     {
8857       if (rtx_equal_p (operands[3], operands[5]))
8858         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
8859       else
8860         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
8861     }
8862   else
8863     {
8864       if (rtx_equal_p (operands[3], operands[5]))
8865         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
8866       else
8867         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
8868     }
8870   [(set_attr "type" "fpalu")
8871    (set_attr "length" "4")])
8873 (define_insn ""
8874   [(set (match_operand 3 "register_operand" "+f")
8875         (plus (match_operand 4 "register_operand" "f")
8876               (match_operand 5 "register_operand" "f")))
8877    (set (match_operand 0 "register_operand" "=f")
8878         (mult (match_operand 1 "register_operand" "f")
8879               (match_operand 2 "register_operand" "f")))]
8880   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8881    && reload_completed && fmpyaddoperands (operands)"
8882   "*
8884   if (GET_MODE (operands[0]) == DFmode)
8885     {
8886       if (rtx_equal_p (operands[3], operands[5]))
8887         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
8888       else
8889         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
8890     }
8891   else
8892     {
8893       if (rtx_equal_p (operands[3], operands[5]))
8894         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
8895       else
8896         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
8897     }
8899   [(set_attr "type" "fpalu")
8900    (set_attr "length" "4")])
8902 (define_insn ""
8903   [(set (match_operand 0 "register_operand" "=f")
8904         (mult (match_operand 1 "register_operand" "f")
8905               (match_operand 2 "register_operand" "f")))
8906    (set (match_operand 3 "register_operand" "+f")
8907         (minus (match_operand 4 "register_operand" "f")
8908                (match_operand 5 "register_operand" "f")))]
8909   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8910    && reload_completed && fmpysuboperands (operands)"
8911   "*
8913   if (GET_MODE (operands[0]) == DFmode)
8914     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
8915   else
8916     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
8918   [(set_attr "type" "fpalu")
8919    (set_attr "length" "4")])
8921 (define_insn ""
8922   [(set (match_operand 3 "register_operand" "+f")
8923         (minus (match_operand 4 "register_operand" "f")
8924                (match_operand 5 "register_operand" "f")))
8925    (set (match_operand 0 "register_operand" "=f")
8926         (mult (match_operand 1 "register_operand" "f")
8927               (match_operand 2 "register_operand" "f")))]
8928   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
8929    && reload_completed && fmpysuboperands (operands)"
8930   "*
8932   if (GET_MODE (operands[0]) == DFmode)
8933     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
8934   else
8935     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
8937   [(set_attr "type" "fpalu")
8938    (set_attr "length" "4")])
8940 ;; Flush the I and D cache lines from the start address (operand0)
8941 ;; to the end address (operand1).  No lines are flushed if the end
8942 ;; address is less than the start address (unsigned).
8944 ;; Because the range of memory flushed is variable and the size of
8945 ;; a MEM can only be a CONST_INT, the patterns specify that they
8946 ;; perform an unspecified volatile operation on all memory.
8948 ;; The address range for an icache flush must lie within a single
8949 ;; space on targets with non-equivalent space registers.
8951 ;; This is used by the trampoline code for nested functions.
8953 ;; Operand 0 contains the start address.
8954 ;; Operand 1 contains the end address.
8955 ;; Operand 2 contains the line length to use.
8956 ;; Operands 3 and 4 (icacheflush) are clobbered scratch registers.
8957 (define_insn "dcacheflush"
8958   [(const_int 1)
8959    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_DCACHE)
8960    (use (match_operand 0 "pmode_register_operand" "r"))
8961    (use (match_operand 1 "pmode_register_operand" "r"))
8962    (use (match_operand 2 "pmode_register_operand" "r"))
8963    (clobber (match_scratch 3 "=&0"))]
8964   ""
8965   "*
8967   if (TARGET_64BIT)
8968     return \"cmpb,*<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
8969   else
8970     return \"cmpb,<<=,n %3,%1,.\;fdc,m %2(%3)\;sync\";
8972   [(set_attr "type" "multi")
8973    (set_attr "length" "12")])
8975 (define_insn "icacheflush"
8976   [(const_int 2)
8977    (unspec_volatile [(mem:BLK (scratch))] UNSPECV_ICACHE)
8978    (use (match_operand 0 "pmode_register_operand" "r"))
8979    (use (match_operand 1 "pmode_register_operand" "r"))
8980    (use (match_operand 2 "pmode_register_operand" "r"))
8981    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
8982    (clobber (match_operand 4 "pmode_register_operand" "=&r"))
8983    (clobber (match_scratch 5 "=&0"))]
8984   ""
8985   "*
8987   if (TARGET_64BIT)
8988     return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,*<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
8989   else
8990     return \"mfsp %%sr0,%4\;ldsid (%5),%3\;mtsp %3,%%sr0\;cmpb,<<=,n %5,%1,.\;fic,m %2(%%sr0,%5)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop\";
8992   [(set_attr "type" "multi")
8993    (set_attr "length" "52")])
8995 ;; An out-of-line prologue.
8996 (define_insn "outline_prologue_call"
8997   [(unspec_volatile [(const_int 0)] UNSPECV_OPC)
8998    (clobber (reg:SI 31))
8999    (clobber (reg:SI 22))
9000    (clobber (reg:SI 21))
9001    (clobber (reg:SI 20))
9002    (clobber (reg:SI 19))
9003    (clobber (reg:SI 1))]
9004   ""
9005   "*
9007   extern int frame_pointer_needed;
9009   /* We need two different versions depending on whether or not we
9010      need a frame pointer.   Also note that we return to the instruction
9011      immediately after the branch rather than two instructions after the
9012      break as normally is the case.  */
9013   if (frame_pointer_needed)
9014     {
9015       /* Must import the magic millicode routine(s).  */
9016       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
9018       if (TARGET_PORTABLE_RUNTIME)
9019         {
9020           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
9021           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
9022                            NULL);
9023         }
9024       else
9025         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
9026     }
9027   else
9028     {
9029       /* Must import the magic millicode routine(s).  */
9030       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
9032       if (TARGET_PORTABLE_RUNTIME)
9033         {
9034           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
9035           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
9036         }
9037       else
9038         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
9039     }
9040   return \"\";
9042   [(set_attr "type" "multi")
9043    (set_attr "length" "8")])
9045 ;; An out-of-line epilogue.
9046 (define_insn "outline_epilogue_call"
9047   [(unspec_volatile [(const_int 1)] UNSPECV_OEC)
9048    (use (reg:SI 29))
9049    (use (reg:SI 28))
9050    (clobber (reg:SI 31))
9051    (clobber (reg:SI 22))
9052    (clobber (reg:SI 21))
9053    (clobber (reg:SI 20))
9054    (clobber (reg:SI 19))
9055    (clobber (reg:SI 2))
9056    (clobber (reg:SI 1))]
9057   ""
9058   "*
9060   extern int frame_pointer_needed;
9062   /* We need two different versions depending on whether or not we
9063      need a frame pointer.   Also note that we return to the instruction
9064      immediately after the branch rather than two instructions after the
9065      break as normally is the case.  */
9066   if (frame_pointer_needed)
9067     {
9068       /* Must import the magic millicode routine.  */
9069       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
9071       /* The out-of-line prologue will make sure we return to the right
9072          instruction.  */
9073       if (TARGET_PORTABLE_RUNTIME)
9074         {
9075           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
9076           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
9077                            NULL);
9078         }
9079       else
9080         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
9081     }
9082   else
9083     {
9084       /* Must import the magic millicode routine.  */
9085       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
9087       /* The out-of-line prologue will make sure we return to the right
9088          instruction.  */
9089       if (TARGET_PORTABLE_RUNTIME)
9090         {
9091           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
9092           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
9093         }
9094       else
9095         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
9096     }
9097   return \"\";
9099   [(set_attr "type" "multi")
9100    (set_attr "length" "8")])
9102 ;; Given a function pointer, canonicalize it so it can be 
9103 ;; reliably compared to another function pointer.  */
9104 (define_expand "canonicalize_funcptr_for_compare"
9105   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
9106    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9107               (clobber (match_dup 2))
9108               (clobber (reg:SI 26))
9109               (clobber (reg:SI 22))
9110               (clobber (reg:SI 31))])
9111    (set (match_operand:SI 0 "register_operand" "")
9112         (reg:SI 29))]
9113   "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
9114   "
9116   if (TARGET_ELF32)
9117     {
9118       rtx canonicalize_funcptr_for_compare_libfunc
9119         = init_one_libfunc (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL);
9121       emit_library_call_value (canonicalize_funcptr_for_compare_libfunc,
9122                                operands[0], LCT_NORMAL, Pmode,
9123                                1, operands[1], Pmode);
9124       DONE;
9125     }
9127   operands[2] = gen_reg_rtx (SImode);
9128   if (GET_CODE (operands[1]) != REG)
9129     {
9130       rtx tmp = gen_reg_rtx (Pmode);
9131       emit_move_insn (tmp, operands[1]);
9132       operands[1] = tmp;
9133     }
9136 (define_insn "*$$sh_func_adrs"
9137   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] UNSPEC_CFFC))
9138    (clobber (match_operand:SI 0 "register_operand" "=a"))
9139    (clobber (reg:SI 26))
9140    (clobber (reg:SI 22))
9141    (clobber (reg:SI 31))]
9142   "!TARGET_64BIT"
9143   "*
9145   int length = get_attr_length (insn);
9146   rtx xoperands[2];
9148   xoperands[0] = GEN_INT (length - 8);
9149   xoperands[1] = GEN_INT (length - 16);
9151   /* Must import the magic millicode routine.  */
9152   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
9154   /* This is absolutely amazing.
9156      First, copy our input parameter into %r29 just in case we don't
9157      need to call $$sh_func_adrs.  */
9158   output_asm_insn (\"copy %%r26,%%r29\", NULL);
9159   output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\", NULL);
9161   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
9162      we use %r26 unchanged.  */
9163   output_asm_insn (\"{comib|cmpib},<>,n 2,%%r31,.+%0\", xoperands);
9164   output_asm_insn (\"ldi 4096,%%r31\", NULL);
9166   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
9167      4096, then again we use %r26 unchanged.  */
9168   output_asm_insn (\"{comb|cmpb},<<,n %%r26,%%r31,.+%1\", xoperands);
9170   /* Finally, call $$sh_func_adrs to extract the function's real add24.  */
9171   return output_millicode_call (insn,
9172                                 gen_rtx_SYMBOL_REF (SImode,
9173                                                     \"$$sh_func_adrs\"));
9175   [(set_attr "type" "multi")
9176    (set (attr "length")
9177         (plus (symbol_ref "attr_length_millicode_call (insn)")
9178               (const_int 20)))])
9180 ;; On the PA, the PIC register is call clobbered, so it must
9181 ;; be saved & restored around calls by the caller.  If the call
9182 ;; doesn't return normally (nonlocal goto, or an exception is
9183 ;; thrown), then the code at the exception handler label must
9184 ;; restore the PIC register.
9185 (define_expand "exception_receiver"
9186   [(const_int 4)]
9187   "flag_pic"
9188   "
9190   /* On the 64-bit port, we need a blockage because there is
9191      confusion regarding the dependence of the restore on the
9192      frame pointer.  As a result, the frame pointer and pic
9193      register restores sometimes are interchanged erroneously.  */
9194   if (TARGET_64BIT)
9195     emit_insn (gen_blockage ());
9196   /* Restore the PIC register using hppa_pic_save_rtx ().  The
9197      PIC register is not saved in the frame in 64-bit ABI.  */
9198   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9199   emit_insn (gen_blockage ());
9200   DONE;
9203 (define_expand "builtin_setjmp_receiver"
9204   [(label_ref (match_operand 0 "" ""))]
9205   "flag_pic"
9206   "
9208   if (TARGET_64BIT)
9209     emit_insn (gen_blockage ());
9210   /* Restore the PIC register.  Hopefully, this will always be from
9211      a stack slot.  The only registers that are valid after a
9212      builtin_longjmp are the stack and frame pointers.  */
9213   emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
9214   emit_insn (gen_blockage ());
9215   DONE;
9218 ;; Allocate new stack space and update the saved stack pointer in the
9219 ;; frame marker.  The HP C compilers also copy additional words in the
9220 ;; frame marker.  The 64-bit compiler copies words at -48, -32 and -24.
9221 ;; The 32-bit compiler copies the word at -16 (Static Link).  We
9222 ;; currently don't copy these values.
9224 ;; Since the copy of the frame marker can't be done atomically, I
9225 ;; suspect that using it for unwind purposes may be somewhat unreliable.
9226 ;; The HP compilers appear to raise the stack and copy the frame
9227 ;; marker in a strict instruction sequence.  This suggests that the
9228 ;; unwind library may check for an alloca sequence when ALLOCA_FRAME
9229 ;; is set in the callinfo data.  We currently don't set ALLOCA_FRAME
9230 ;; as GAS doesn't support it, or try to keep the instructions emitted
9231 ;; here in strict sequence.
9232 (define_expand "allocate_stack"
9233   [(match_operand 0 "" "")
9234    (match_operand 1 "" "")]
9235   ""
9236   "
9238   rtx addr;
9240   /* Since the stack grows upward, we need to store virtual_stack_dynamic_rtx
9241      in operand 0 before adjusting the stack.  */
9242   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9243   anti_adjust_stack (operands[1]);
9244   if (TARGET_HPUX_UNWIND_LIBRARY)
9245     {
9246       addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
9247                            GEN_INT (TARGET_64BIT ? -8 : -4));
9248       emit_move_insn (gen_rtx_MEM (word_mode, addr), frame_pointer_rtx);
9249     }
9250   if (!TARGET_64BIT && flag_pic)
9251     {
9252       rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));
9253       emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);
9254     }
9255   DONE;
9258 (define_expand "prefetch"
9259   [(match_operand 0 "address_operand" "")
9260    (match_operand 1 "const_int_operand" "")
9261    (match_operand 2 "const_int_operand" "")]
9262   "TARGET_PA_20"
9264   int locality = INTVAL (operands[2]);
9266   if (locality < 0 || locality > 3)
9267     abort ();
9269   /* Change operand[0] to a MEM as we don't have the infrastructure
9270      to output all the supported address modes for ldw/ldd when we use
9271      the address directly.  However, we do have it for MEMs.  */
9272   operands[0] = gen_rtx_MEM (QImode, operands[0]);
9274   /* If the address isn't valid for the prefetch, replace it.  */
9275   if (locality)
9276     {
9277       if (!prefetch_nocc_operand (operands[0], QImode))
9278         operands[0]
9279           = replace_equiv_address (operands[0],
9280                                    copy_to_mode_reg (Pmode,
9281                                                      XEXP (operands[0], 0)));
9282       emit_insn (gen_prefetch_nocc (operands[0], operands[1], operands[2]));
9283     }
9284   else
9285     {
9286       if (!prefetch_cc_operand (operands[0], QImode))
9287         operands[0]
9288           = replace_equiv_address (operands[0],
9289                                    copy_to_mode_reg (Pmode,
9290                                                      XEXP (operands[0], 0)));
9291       emit_insn (gen_prefetch_cc (operands[0], operands[1], operands[2]));
9292     }
9293   DONE;
9296 (define_insn "prefetch_cc"
9297   [(prefetch (match_operand:QI 0 "prefetch_cc_operand" "RW")
9298              (match_operand:SI 1 "const_int_operand" "n")
9299              (match_operand:SI 2 "const_int_operand" "n"))]
9300   "TARGET_PA_20 && operands[2] == const0_rtx"
9302   /* The SL cache-control completor indicates good spatial locality but
9303      poor temporal locality.  The ldw instruction with a target of general
9304      register 0 prefetches a cache line for a read.  The ldd instruction
9305      prefetches a cache line for a write.  */
9306   static const char * const instr[2] = {
9307     "ldw%M0,sl %0,%%r0",
9308     "ldd%M0,sl %0,%%r0"
9309   };
9310   int read_or_write = INTVAL (operands[1]);
9312   if (read_or_write < 0 || read_or_write > 1)
9313     abort ();
9315   return instr [read_or_write];
9317   [(set_attr "type" "load")
9318    (set_attr "length" "4")])
9320 (define_insn "prefetch_nocc"
9321   [(prefetch (match_operand:QI 0 "prefetch_nocc_operand" "A,RQ")
9322              (match_operand:SI 1 "const_int_operand" "n,n")
9323              (match_operand:SI 2 "const_int_operand" "n,n"))]
9324   "TARGET_PA_20 && operands[2] != const0_rtx"
9326   /* The ldw instruction with a target of general register 0 prefetches
9327      a cache line for a read.  The ldd instruction prefetches a cache line
9328      for a write.  */
9329   static const char * const instr[2][2] = {
9330     {
9331       "ldw RT'%A0,%%r0",
9332       "ldd RT'%A0,%%r0",
9333     },
9334     {
9335       "ldw%M0 %0,%%r0",
9336       "ldd%M0 %0,%%r0",
9337     }
9338   };
9339   int read_or_write = INTVAL (operands[1]);
9341   if ((which_alternative != 0 && which_alternative != 1)
9342       || (read_or_write < 0 || read_or_write > 1))
9343     abort ();
9345   return instr [which_alternative][read_or_write];
9347   [(set_attr "type" "load")
9348    (set_attr "length" "4")])