update copyrights in config dir.
[official-gcc.git] / gcc / config / pa / pa.md
blob29bbac0a10a88654d58a313065ccd83246b878df
1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;;   Copyright (C) 1992, 93-99, 2000 Free Software Foundation, Inc.
3 ;;   Contributed by the Center for Software Science at the University
4 ;;   of Utah.
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;; This gcc Version 2 machine description is inspired by sparc.md and
24 ;; mips.md.
26 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;; Insn type.  Used to default other attribute values.
30 ;; type "unary" insns have one input operand (1) and one output operand (0)
31 ;; type "binary" insns have two input operands (1,2) and one output (0)
33 (define_attr "type"
34   "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
35   (const_string "binary"))
37 (define_attr "pa_combine_type"
38   "fmpy,faddsub,uncond_branch,addmove,none"
39   (const_string "none"))
41 ;; Processor type (for scheduling, not code generation) -- this attribute
42 ;; must exactly match the processor_type enumeration in pa.h.
44 ;; FIXME: Add 800 scheduling for completeness?
46 (define_attr "cpu" "700,7100,7100LC,7200,8000" (const (symbol_ref "pa_cpu_attr")))
48 ;; Length (in # of bytes).
49 (define_attr "length" ""
50   (cond [(eq_attr "type" "load,fpload")
51          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
52                        (const_int 8) (const_int 4))
54          (eq_attr "type" "store,fpstore")
55          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
56                        (const_int 8) (const_int 4))
58          (eq_attr "type" "binary,shift,nullshift")
59          (if_then_else (match_operand 2 "arith_operand" "")
60                        (const_int 4) (const_int 12))
62          (eq_attr "type" "move,unary,shift,nullshift")
63          (if_then_else (match_operand 1 "arith_operand" "")
64                        (const_int 4) (const_int 8))]
66         (const_int 4)))
68 (define_asm_attributes
69   [(set_attr "length" "4")
70    (set_attr "type" "multi")])
72 ;; Attributes for instruction and branch scheduling
74 ;; For conditional branches.
75 (define_attr "in_branch_delay" "false,true"
76   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
77                      (eq_attr "length" "4"))
78                 (const_string "true")
79                 (const_string "false")))
81 ;; Disallow instructions which use the FPU since they will tie up the FPU
82 ;; even if the instruction is nullified.
83 (define_attr "in_nullified_branch_delay" "false,true"
84   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
85                      (eq_attr "length" "4"))
86                 (const_string "true")
87                 (const_string "false")))
89 ;; For calls and millicode calls.  Allow unconditional branches in the
90 ;; delay slot.
91 (define_attr "in_call_delay" "false,true"
92   (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
93               (eq_attr "length" "4"))
94            (const_string "true")
95          (eq_attr "type" "uncond_branch")
96            (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
97                              (const_int 0))
98                          (const_string "true")
99                          (const_string "false"))]
100         (const_string "false")))
103 ;; Call delay slot description.
104 (define_delay (eq_attr "type" "call")
105   [(eq_attr "in_call_delay" "true") (nil) (nil)])
107 ;; millicode call delay slot description.  Note it disallows delay slot
108 ;; when TARGET_PORTABLE_RUNTIME is true.
109 (define_delay (eq_attr "type" "milli")
110   [(and (eq_attr "in_call_delay" "true")
111         (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
112    (nil) (nil)])
114 ;; Return and other similar instructions.
115 (define_delay (eq_attr "type" "branch,parallel_branch")
116   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
118 ;; Floating point conditional branch delay slot description and
119 (define_delay (eq_attr "type" "fbranch")
120   [(eq_attr "in_branch_delay" "true")
121    (eq_attr "in_nullified_branch_delay" "true")
122    (nil)])
124 ;; Integer conditional branch delay slot description.
125 ;; Nullification of conditional branches on the PA is dependent on the
126 ;; direction of the branch.  Forward branches nullify true and
127 ;; backward branches nullify false.  If the direction is unknown
128 ;; then nullification is not allowed.
129 (define_delay (eq_attr "type" "cbranch")
130   [(eq_attr "in_branch_delay" "true")
131    (and (eq_attr "in_nullified_branch_delay" "true")
132         (attr_flag "forward"))
133    (and (eq_attr "in_nullified_branch_delay" "true")
134         (attr_flag "backward"))])
136 (define_delay (and (eq_attr "type" "uncond_branch")
137                    (eq (symbol_ref "following_call (insn)")
138                        (const_int 0)))
139   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
141 ;; Function units of the HPPA. The following data is for the 700 CPUs
142 ;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
143 ;; Scheduling instructions for PA-83 machines according to the Snake
144 ;; constraints shouldn't hurt.
146 ;; (define_function_unit {name} {num-units} {n-users} {test}
147 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
149 ;; The integer ALU.
150 ;; (Noted only for documentation; units that take one cycle do not need to
151 ;; be specified.)
153 ;; (define_function_unit "alu" 1 0
154 ;;  (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
155 ;;       (eq_attr "cpu" "700"))
156 ;;  1 0)
159 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
160 ;; load: 2, fpload: 3
161 ;; store, fpstore: 3, no D-cache operations should be scheduled.
163 (define_function_unit "pa700memory" 1 0
164   (and (eq_attr "type" "load,fpload")
165        (eq_attr "cpu" "700")) 2 0)
166 (define_function_unit "pa700memory" 1 0 
167   (and (eq_attr "type" "store,fpstore")
168        (eq_attr "cpu" "700")) 3 3)
170 ;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
171 ;; Timings:
172 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
173 ;; fcpy         3       ALU     2
174 ;; fabs         3       ALU     2
175 ;; fadd         3       ALU     2
176 ;; fsub         3       ALU     2
177 ;; fcmp         3       ALU     2
178 ;; fcnv         3       ALU     2
179 ;; fmpyadd      3       ALU,MPY 2
180 ;; fmpysub      3       ALU,MPY 2
181 ;; fmpycfxt     3       ALU,MPY 2
182 ;; fmpy         3       MPY     2
183 ;; fmpyi        3       MPY     2
184 ;; fdiv,sgl     10      MPY     10
185 ;; fdiv,dbl     12      MPY     12
186 ;; fsqrt,sgl    14      MPY     14
187 ;; fsqrt,dbl    18      MPY     18
189 (define_function_unit "pa700fp_alu" 1 0
190   (and (eq_attr "type" "fpcc")
191        (eq_attr "cpu" "700")) 4 2)
192 (define_function_unit "pa700fp_alu" 1 0
193   (and (eq_attr "type" "fpalu")
194        (eq_attr "cpu" "700")) 3 2)
195 (define_function_unit "pa700fp_mpy" 1 0
196   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
197        (eq_attr "cpu" "700")) 3 2)
198 (define_function_unit "pa700fp_mpy" 1 0
199   (and (eq_attr "type" "fpdivsgl")
200        (eq_attr "cpu" "700")) 10 10)
201 (define_function_unit "pa700fp_mpy" 1 0
202   (and (eq_attr "type" "fpdivdbl")
203        (eq_attr "cpu" "700")) 12 12)
204 (define_function_unit "pa700fp_mpy" 1 0
205   (and (eq_attr "type" "fpsqrtsgl")
206        (eq_attr "cpu" "700")) 14 14)
207 (define_function_unit "pa700fp_mpy" 1 0
208   (and (eq_attr "type" "fpsqrtdbl")
209        (eq_attr "cpu" "700")) 18 18)
211 ;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
212 ;; floating point computations with non-floating point computations (fp loads
213 ;; and stores are not fp computations).
216 ;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
217 ;; take two cycles, during which no Dcache operations should be scheduled.
218 ;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
219 ;; all have the same memory characteristics if one disregards cache misses.
220 (define_function_unit "pa7100memory" 1 0
221   (and (eq_attr "type" "load,fpload")
222        (eq_attr "cpu" "7100,7100LC")) 2 0)
223 (define_function_unit "pa7100memory" 1 0 
224   (and (eq_attr "type" "store,fpstore")
225        (eq_attr "cpu" "7100,7100LC")) 2 2)
227 ;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
228 ;; Timings:
229 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
230 ;; fcpy         2       ALU     1
231 ;; fabs         2       ALU     1
232 ;; fadd         2       ALU     1
233 ;; fsub         2       ALU     1
234 ;; fcmp         2       ALU     1
235 ;; fcnv         2       ALU     1
236 ;; fmpyadd      2       ALU,MPY 1
237 ;; fmpysub      2       ALU,MPY 1
238 ;; fmpycfxt     2       ALU,MPY 1
239 ;; fmpy         2       MPY     1
240 ;; fmpyi        2       MPY     1
241 ;; fdiv,sgl     8       DIV     8
242 ;; fdiv,dbl     15      DIV     15
243 ;; fsqrt,sgl    8       DIV     8
244 ;; fsqrt,dbl    15      DIV     15
246 (define_function_unit "pa7100fp_alu" 1 0
247   (and (eq_attr "type" "fpcc,fpalu")
248        (eq_attr "cpu" "7100")) 2 1)
249 (define_function_unit "pa7100fp_mpy" 1 0
250   (and (eq_attr "type" "fpmulsgl,fpmuldbl")
251        (eq_attr "cpu" "7100")) 2 1)
252 (define_function_unit "pa7100fp_div" 1 0
253   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
254        (eq_attr "cpu" "7100")) 8 8)
255 (define_function_unit "pa7100fp_div" 1 0
256   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
257        (eq_attr "cpu" "7100")) 15 15)
259 ;; To encourage dual issue we define function units corresponding to
260 ;; the instructions which can be dual issued.    This is a rather crude
261 ;; approximation, the "pa7100nonflop" test in particular could be refined.
262 (define_function_unit "pa7100flop" 1 1
263   (and
264     (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
265     (eq_attr "cpu" "7100")) 1 1)
267 (define_function_unit "pa7100nonflop" 1 1
268   (and
269     (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
270     (eq_attr "cpu" "7100")) 1 1)
273 ;; Memory subsystem works just like 7100/7150 (except for cache miss times which
274 ;; we don't model here).  
276 ;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
277 ;; Note divides and sqrt flops lock the cpu until the flop is
278 ;; finished.  fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
279 ;; There's no way to avoid the penalty.
280 ;; Timings:
281 ;; Instruction  Time    Unit    Minimum Distance (unit contention)
282 ;; fcpy         2       ALU     1
283 ;; fabs         2       ALU     1
284 ;; fadd         2       ALU     1
285 ;; fsub         2       ALU     1
286 ;; fcmp         2       ALU     1
287 ;; fcnv         2       ALU     1
288 ;; fmpyadd,sgl  2       ALU,MPY 1
289 ;; fmpyadd,dbl  3       ALU,MPY 2
290 ;; fmpysub,sgl  2       ALU,MPY 1
291 ;; fmpysub,dbl  3       ALU,MPY 2
292 ;; fmpycfxt,sgl 2       ALU,MPY 1
293 ;; fmpycfxt,dbl 3       ALU,MPY 2
294 ;; fmpy,sgl     2       MPY     1
295 ;; fmpy,dbl     3       MPY     2
296 ;; fmpyi        3       MPY     2
297 ;; fdiv,sgl     8       DIV     8
298 ;; fdiv,dbl     15      DIV     15
299 ;; fsqrt,sgl    8       DIV     8
300 ;; fsqrt,dbl    15      DIV     15
302 (define_function_unit "pa7100LCfp_alu" 1 0
303   (and (eq_attr "type" "fpcc,fpalu")
304        (eq_attr "cpu" "7100LC,7200")) 2 1)
305 (define_function_unit "pa7100LCfp_mpy" 1 0
306   (and (eq_attr "type" "fpmulsgl")
307        (eq_attr "cpu" "7100LC,7200")) 2 1)
308 (define_function_unit "pa7100LCfp_mpy" 1 0
309   (and (eq_attr "type" "fpmuldbl")
310        (eq_attr "cpu" "7100LC,7200")) 3 2)
311 (define_function_unit "pa7100LCfp_div" 1 0
312   (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
313        (eq_attr "cpu" "7100LC,7200")) 8 8)
314 (define_function_unit "pa7100LCfp_div" 1 0
315   (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
316        (eq_attr "cpu" "7100LC,7200")) 15 15)
318 ;; Define the various functional units for dual-issue.
320 ;; There's only one floating point unit.
321 (define_function_unit "pa7100LCflop" 1 1
322   (and
323     (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
324     (eq_attr "cpu" "7100LC,7200")) 1 1)
326 ;; Shifts and memory ops execute in only one of the integer ALUs
327 (define_function_unit "pa7100LCshiftmem" 1 1
328   (and
329     (eq_attr "type" "shift,nullshift,load,fpload,store,fpstore")
330     (eq_attr "cpu" "7100LC,7200")) 1 1)
332 ;; We have two basic ALUs.
333 (define_function_unit "pa7100LCalu" 2 1
334   (and
335     (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
336    (eq_attr "cpu" "7100LC,7200")) 1 1)
338 ;; I don't have complete information on the PA7200; however, most of
339 ;; what I've heard makes it look like a 7100LC without the store-store
340 ;; penalty.  So that's how we'll model it.
342 ;; Memory. Disregarding Cache misses, memory loads and stores take
343 ;; two cycles.  Any special cases are handled in pa_adjust_cost.
344 (define_function_unit "pa7200memory" 1 0
345   (and (eq_attr "type" "load,fpload,store,fpstore")
346        (eq_attr "cpu" "7200")) 2 0)
348 ;; I don't have detailed information on the PA7200 FP pipeline, so I
349 ;; treat it just like the 7100LC pipeline.
350 ;; Similarly for the multi-issue fake units.
352 ;; 
353 ;; Scheduling for the PA8000 is somewhat different than scheduling for a
354 ;; traditional architecture.
356 ;; The PA8000 has a large (56) entry reorder buffer that is split between
357 ;; memory and non-memory operations.
359 ;; The PA800 can issue two memory and two non-memory operations per cycle to
360 ;; the function units.  Similarly, the PA8000 can retire two memory and two
361 ;; non-memory operations per cycle.
363 ;; Given the large reorder buffer, the processor can hide most latencies.
364 ;; According to HP, they've got the best results by scheduling for retirement
365 ;; bandwidth with limited latency scheduling for floating point operations.
366 ;; Latency for integer operations and memory references is ignored.
368 ;; We claim floating point operations have a 2 cycle latency and are
369 ;; fully pipelined, except for div and sqrt which are not pipelined.
371 ;; It is not necessary to define the shifter and integer alu units.
373 ;; These first two define_unit_unit descriptions model retirement from
374 ;; the reorder buffer.
375 (define_function_unit "pa8000lsu" 2 1
376   (and
377     (eq_attr "type" "load,fpload,store,fpstore")
378     (eq_attr "cpu" "8000")) 1 1)
380 (define_function_unit "pa8000alu" 2 1
381   (and
382     (eq_attr "type" "!load,fpload,store,fpstore")
383     (eq_attr "cpu" "8000")) 1 1)
385 ;; Claim floating point ops have a 2 cycle latency, excluding div and
386 ;; sqrt, which are not pipelined and issue to different units.
387 (define_function_unit "pa8000fmac" 2 0
388   (and
389     (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
390     (eq_attr "cpu" "8000")) 2 1)
392 (define_function_unit "pa8000fdiv" 2 1
393   (and
394     (eq_attr "type" "fpdivsgl,fpsqrtsgl")
395     (eq_attr "cpu" "8000")) 17 17)
397 (define_function_unit "pa8000fdiv" 2 1
398   (and
399     (eq_attr "type" "fpdivdbl,fpsqrtdbl")
400     (eq_attr "cpu" "8000")) 31 31)
403 ;; Compare instructions.
404 ;; This controls RTL generation and register allocation.
406 ;; We generate RTL for comparisons and branches by having the cmpxx
407 ;; patterns store away the operands.  Then, the scc and bcc patterns
408 ;; emit RTL for both the compare and the branch.
411 (define_expand "cmpsi"
412   [(set (reg:CC 0)
413         (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
414                     (match_operand:SI 1 "arith5_operand" "")))]
415   ""
416   "
418  hppa_compare_op0 = operands[0];
419  hppa_compare_op1 = operands[1];
420  hppa_branch_type = CMP_SI;
421  DONE;
424 (define_expand "cmpsf"
425   [(set (reg:CCFP 0)
426         (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
427                       (match_operand:SF 1 "reg_or_0_operand" "")))]
428   "! TARGET_SOFT_FLOAT"
429   "
431   hppa_compare_op0 = operands[0];
432   hppa_compare_op1 = operands[1];
433   hppa_branch_type = CMP_SF;
434   DONE;
437 (define_expand "cmpdf"
438   [(set (reg:CCFP 0)
439       (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
440                     (match_operand:DF 1 "reg_or_0_operand" "")))]
441   "! TARGET_SOFT_FLOAT"
442   "
444   hppa_compare_op0 = operands[0];
445   hppa_compare_op1 = operands[1];
446   hppa_branch_type = CMP_DF;
447   DONE;
450 (define_insn ""
451   [(set (reg:CCFP 0)
452         (match_operator:CCFP 2 "comparison_operator"
453                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
454                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
455   "! TARGET_SOFT_FLOAT"
456   "fcmp,sgl,%Y2 %f0,%f1"
457   [(set_attr "length" "4")
458    (set_attr "type" "fpcc")])
460 (define_insn ""
461   [(set (reg:CCFP 0)
462         (match_operator:CCFP 2 "comparison_operator"
463                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
464                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
465   "! TARGET_SOFT_FLOAT"
466   "fcmp,dbl,%Y2 %f0,%f1"
467   [(set_attr "length" "4")
468    (set_attr "type" "fpcc")])
470 ;; scc insns.
472 (define_expand "seq"
473   [(set (match_operand:SI 0 "register_operand" "")
474         (eq:SI (match_dup 1)
475                (match_dup 2)))]
476   ""
477   "
479   /* fp scc patterns rarely match, and are not a win on the PA.  */
480   if (hppa_branch_type != CMP_SI)
481     FAIL;
482   /* set up operands from compare.  */
483   operands[1] = hppa_compare_op0;
484   operands[2] = hppa_compare_op1;
485   /* fall through and generate default code */
488 (define_expand "sne"
489   [(set (match_operand:SI 0 "register_operand" "")
490         (ne:SI (match_dup 1)
491                (match_dup 2)))]
492   ""
493   "
495   /* fp scc patterns rarely match, and are not a win on the PA.  */
496   if (hppa_branch_type != CMP_SI)
497     FAIL;
498   operands[1] = hppa_compare_op0;
499   operands[2] = hppa_compare_op1;
502 (define_expand "slt"
503   [(set (match_operand:SI 0 "register_operand" "")
504         (lt:SI (match_dup 1)
505                (match_dup 2)))]
506   ""
507   "
509   /* fp scc patterns rarely match, and are not a win on the PA.  */
510   if (hppa_branch_type != CMP_SI)
511     FAIL;
512   operands[1] = hppa_compare_op0;
513   operands[2] = hppa_compare_op1;
516 (define_expand "sgt"
517   [(set (match_operand:SI 0 "register_operand" "")
518         (gt:SI (match_dup 1)
519                (match_dup 2)))]
520   ""
521   "
523   /* fp scc patterns rarely match, and are not a win on the PA.  */
524   if (hppa_branch_type != CMP_SI)
525     FAIL;
526   operands[1] = hppa_compare_op0;
527   operands[2] = hppa_compare_op1;
530 (define_expand "sle"
531   [(set (match_operand:SI 0 "register_operand" "")
532         (le:SI (match_dup 1)
533                (match_dup 2)))]
534   ""
535   "
537   /* fp scc patterns rarely match, and are not a win on the PA.  */
538   if (hppa_branch_type != CMP_SI)
539     FAIL;
540   operands[1] = hppa_compare_op0;
541   operands[2] = hppa_compare_op1;
544 (define_expand "sge"
545   [(set (match_operand:SI 0 "register_operand" "")
546         (ge:SI (match_dup 1)
547                (match_dup 2)))]
548   ""
549   "
551   /* fp scc patterns rarely match, and are not a win on the PA.  */
552   if (hppa_branch_type != CMP_SI)
553     FAIL;
554   operands[1] = hppa_compare_op0;
555   operands[2] = hppa_compare_op1;
558 (define_expand "sltu"
559   [(set (match_operand:SI 0 "register_operand" "")
560         (ltu:SI (match_dup 1)
561                 (match_dup 2)))]
562   ""
563   "
565   if (hppa_branch_type != CMP_SI)
566     FAIL;
567   operands[1] = hppa_compare_op0;
568   operands[2] = hppa_compare_op1;
571 (define_expand "sgtu"
572   [(set (match_operand:SI 0 "register_operand" "")
573         (gtu:SI (match_dup 1)
574                 (match_dup 2)))]
575   ""
576   "
578   if (hppa_branch_type != CMP_SI)
579     FAIL;
580   operands[1] = hppa_compare_op0;
581   operands[2] = hppa_compare_op1;
584 (define_expand "sleu"
585   [(set (match_operand:SI 0 "register_operand" "")
586         (leu:SI (match_dup 1)
587                 (match_dup 2)))]
588   ""
589   "
591   if (hppa_branch_type != CMP_SI)
592     FAIL;
593   operands[1] = hppa_compare_op0;
594   operands[2] = hppa_compare_op1;
597 (define_expand "sgeu"
598   [(set (match_operand:SI 0 "register_operand" "")
599         (geu:SI (match_dup 1)
600                 (match_dup 2)))]
601   ""
602   "
604   if (hppa_branch_type != CMP_SI)
605     FAIL;
606   operands[1] = hppa_compare_op0;
607   operands[2] = hppa_compare_op1;
610 ;; Instruction canonicalization puts immediate operands second, which
611 ;; is the reverse of what we want.
613 (define_insn "scc"
614   [(set (match_operand:SI 0 "register_operand" "=r")
615         (match_operator:SI 3 "comparison_operator"
616                            [(match_operand:SI 1 "register_operand" "r")
617                             (match_operand:SI 2 "arith11_operand" "rI")]))]
618   ""
619   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
620   [(set_attr "type" "binary")
621    (set_attr "length" "8")])
623 (define_insn "iorscc"
624   [(set (match_operand:SI 0 "register_operand" "=r")
625         (ior:SI (match_operator:SI 3 "comparison_operator"
626                                    [(match_operand:SI 1 "register_operand" "r")
627                                     (match_operand:SI 2 "arith11_operand" "rI")])
628                 (match_operator:SI 6 "comparison_operator"
629                                    [(match_operand:SI 4 "register_operand" "r")
630                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
631   ""
632   "{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
633   [(set_attr "type" "binary")
634    (set_attr "length" "12")])
636 ;; Combiner patterns for common operations performed with the output
637 ;; from an scc insn (negscc and incscc).
638 (define_insn "negscc"
639   [(set (match_operand:SI 0 "register_operand" "=r")
640         (neg:SI (match_operator:SI 3 "comparison_operator"
641                [(match_operand:SI 1 "register_operand" "r")
642                 (match_operand:SI 2 "arith11_operand" "rI")])))]
643   ""
644   "{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
645   [(set_attr "type" "binary")
646    (set_attr "length" "8")])
648 ;; Patterns for adding/subtracting the result of a boolean expression from
649 ;; a register.  First we have special patterns that make use of the carry
650 ;; bit, and output only two instructions.  For the cases we can't in
651 ;; general do in two instructions, the incscc pattern at the end outputs
652 ;; two or three instructions.
654 (define_insn ""
655   [(set (match_operand:SI 0 "register_operand" "=r")
656         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
657                          (match_operand:SI 3 "arith11_operand" "rI"))
658                  (match_operand:SI 1 "register_operand" "r")))]
659   ""
660   "sub%I3 %3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
661   [(set_attr "type" "binary")
662    (set_attr "length" "8")])
664 ; This need only accept registers for op3, since canonicalization
665 ; replaces geu with gtu when op3 is an integer.
666 (define_insn ""
667   [(set (match_operand:SI 0 "register_operand" "=r")
668         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
669                          (match_operand:SI 3 "register_operand" "r"))
670                  (match_operand:SI 1 "register_operand" "r")))]
671   ""
672   "sub %2,%3,%%r0\;{addc|add,c} %%r0,%1,%0"
673   [(set_attr "type" "binary")
674    (set_attr "length" "8")])
676 ; Match only integers for op3 here.  This is used as canonical form of the
677 ; geu pattern when op3 is an integer.  Don't match registers since we can't
678 ; make better code than the general incscc pattern.
679 (define_insn ""
680   [(set (match_operand:SI 0 "register_operand" "=r")
681         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
682                          (match_operand:SI 3 "int11_operand" "I"))
683                  (match_operand:SI 1 "register_operand" "r")))]
684   ""
685   "addi %k3,%2,%%r0\;{addc|add,c} %%r0,%1,%0"
686   [(set_attr "type" "binary")
687    (set_attr "length" "8")])
689 (define_insn "incscc"
690   [(set (match_operand:SI 0 "register_operand" "=r,r")
691         (plus:SI (match_operator:SI 4 "comparison_operator"
692                     [(match_operand:SI 2 "register_operand" "r,r")
693                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
694                  (match_operand:SI 1 "register_operand" "0,?r")))]
695   ""
696   "@
697    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi 1,%0,%0
698    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr 1,%1,%0\;copy %1,%0"
699   [(set_attr "type" "binary,binary")
700    (set_attr "length" "8,12")])
702 (define_insn ""
703   [(set (match_operand:SI 0 "register_operand" "=r")
704         (minus:SI (match_operand:SI 1 "register_operand" "r")
705                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
706                           (match_operand:SI 3 "arith11_operand" "rI"))))]
707   ""
708   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
709   [(set_attr "type" "binary")
710    (set_attr "length" "8")])
712 (define_insn ""
713   [(set (match_operand:SI 0 "register_operand" "=r")
714         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
715                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
716                                     (match_operand:SI 3 "arith11_operand" "rI")))
717                   (match_operand:SI 4 "register_operand" "r")))]
718   ""
719   "sub%I3 %3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
720   [(set_attr "type" "binary")
721    (set_attr "length" "8")])
723 ; This need only accept registers for op3, since canonicalization
724 ; replaces ltu with leu when op3 is an integer.
725 (define_insn ""
726   [(set (match_operand:SI 0 "register_operand" "=r")
727         (minus:SI (match_operand:SI 1 "register_operand" "r")
728                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
729                           (match_operand:SI 3 "register_operand" "r"))))]
730   ""
731   "sub %2,%3,%%r0\;{subb|sub,b} %1,%%r0,%0"
732   [(set_attr "type" "binary")
733    (set_attr "length" "8")])
735 (define_insn ""
736   [(set (match_operand:SI 0 "register_operand" "=r")
737         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
738                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
739                                     (match_operand:SI 3 "register_operand" "r")))
740                   (match_operand:SI 4 "register_operand" "r")))]
741   ""
742   "sub %2,%3,%%r0\;{subb|sub,b} %1,%4,%0"
743   [(set_attr "type" "binary")
744    (set_attr "length" "8")])
746 ; Match only integers for op3 here.  This is used as canonical form of the
747 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
748 ; make better code than the general incscc pattern.
749 (define_insn ""
750   [(set (match_operand:SI 0 "register_operand" "=r")
751         (minus:SI (match_operand:SI 1 "register_operand" "r")
752                   (leu:SI (match_operand:SI 2 "register_operand" "r")
753                           (match_operand:SI 3 "int11_operand" "I"))))]
754   ""
755   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%%r0,%0"
756   [(set_attr "type" "binary")
757    (set_attr "length" "8")])
759 (define_insn ""
760   [(set (match_operand:SI 0 "register_operand" "=r")
761         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
762                             (leu:SI (match_operand:SI 2 "register_operand" "r")
763                                     (match_operand:SI 3 "int11_operand" "I")))
764                   (match_operand:SI 4 "register_operand" "r")))]
765   ""
766   "addi %k3,%2,%%r0\;{subb|sub,b} %1,%4,%0"
767   [(set_attr "type" "binary")
768    (set_attr "length" "8")])
770 (define_insn "decscc"
771   [(set (match_operand:SI 0 "register_operand" "=r,r")
772         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
773                   (match_operator:SI 4 "comparison_operator"
774                      [(match_operand:SI 2 "register_operand" "r,r")
775                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
776   ""
777   "@
778    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi -1,%0,%0
779    {com%I3clr|cmp%I3clr},%B4 %3,%2,%%r0\;addi,tr -1,%1,%0\;copy %1,%0"
780   [(set_attr "type" "binary,binary")
781    (set_attr "length" "8,12")])
783 ; Patterns for max and min.  (There is no need for an earlyclobber in the
784 ; last alternative since the middle alternative will match if op0 == op1.)
786 (define_insn "sminsi3"
787   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
788         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
789                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
790   ""
791   "@
792   {comclr|cmpclr},> %2,%0,%%r0\;copy %2,%0
793   {comiclr|cmpiclr},> %2,%0,%%r0\;ldi %2,%0
794   {comclr|cmpclr},> %1,%r2,%0\;copy %1,%0"
795 [(set_attr "type" "multi,multi,multi")
796  (set_attr "length" "8,8,8")])
798 (define_insn "uminsi3"
799   [(set (match_operand:SI 0 "register_operand" "=r,r")
800         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
801                  (match_operand:SI 2 "arith11_operand" "r,I")))]
802   ""
803   "@
804   {comclr|cmpclr},>> %2,%0,%%r0\;copy %2,%0
805   {comiclr|cmpiclr},>> %2,%0,%%r0\;ldi %2,%0"
806 [(set_attr "type" "multi,multi")
807  (set_attr "length" "8,8")])
809 (define_insn "smaxsi3"
810   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
811         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
812                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
813   ""
814   "@
815   {comclr|cmpclr},< %2,%0,%%r0\;copy %2,%0
816   {comiclr|cmpiclr},< %2,%0,%%r0\;ldi %2,%0
817   {comclr|cmpclr},< %1,%r2,%0\;copy %1,%0"
818 [(set_attr "type" "multi,multi,multi")
819  (set_attr "length" "8,8,8")])
821 (define_insn "umaxsi3"
822   [(set (match_operand:SI 0 "register_operand" "=r,r")
823         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
824                  (match_operand:SI 2 "arith11_operand" "r,I")))]
825   ""
826   "@
827   {comclr|cmpclr},<< %2,%0,%%r0\;copy %2,%0
828   {comiclr|cmpiclr},<< %2,%0,%%r0\;ldi %2,%0"
829 [(set_attr "type" "multi,multi")
830  (set_attr "length" "8,8")])
832 (define_insn "abssi2"
833   [(set (match_operand:SI 0 "register_operand" "=r")
834         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
835   ""
836   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
837   [(set_attr "type" "multi")
838    (set_attr "length" "8")])
840 ;;; Experimental conditional move patterns
842 (define_expand "movsicc"
843   [(set (match_operand:SI 0 "register_operand" "")
844         (if_then_else:SI
845          (match_operator 1 "comparison_operator"
846             [(match_dup 4)
847              (match_dup 5)])
848          (match_operand:SI 2 "reg_or_cint_move_operand" "")
849          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
850   ""
851   "
853   enum rtx_code code = GET_CODE (operands[1]);
855   if (hppa_branch_type != CMP_SI)
856     FAIL;
858   /* operands[1] is currently the result of compare_from_rtx.  We want to
859      emit a compare of the original operands.  */
860   operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
861   operands[4] = hppa_compare_op0;
862   operands[5] = hppa_compare_op1;
865 ;; We used to accept any register for op1.
867 ;; However, it loses sometimes because the compiler will end up using
868 ;; different registers for op0 and op1 in some critical cases.  local-alloc
869 ;; will  not tie op0 and op1 because op0 is used in multiple basic blocks.
871 ;; If/when global register allocation supports tying we should allow any
872 ;; register for op1 again.
873 (define_insn ""
874   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
875         (if_then_else:SI
876          (match_operator 5 "comparison_operator"
877             [(match_operand:SI 3 "register_operand" "r,r,r,r")
878              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI")])
879          (match_operand:SI 1 "reg_or_cint_move_operand" "0,J,N,K")
880          (const_int 0)))]
881   ""
882   "@
883    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi 0,%0
884    {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;ldi %1,%0
885    {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;ldil L'%1,%0
886    {com%I4clr|cmp%I4clr},%B5 %4,%3,%0\;{zdepi|depwi,z} %Z1,%0"
887   [(set_attr "type" "multi,multi,multi,nullshift")
888    (set_attr "length" "8,8,8,8")])
890 (define_insn ""
891   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
892         (if_then_else:SI
893          (match_operator 5 "comparison_operator"
894             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
895              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
896          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
897          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
898   ""
899   "@
900    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;copy %2,%0
901    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldi %2,%0
902    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;ldil L'%2,%0
903    {com%I4clr|cmp%I4clr},%S5 %4,%3,%%r0\;{zdepi|depwi,z} %Z2,%0
904    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;copy %1,%0
905    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldi %1,%0
906    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;ldil L'%1,%0
907    {com%I4clr|cmp%I4clr},%B5 %4,%3,%%r0\;{zdepi|depwi,z} %Z1,%0"
908   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
909    (set_attr "length" "8,8,8,8,8,8,8,8")])
911 ;; Conditional Branches
913 (define_expand "beq"
914   [(set (pc)
915         (if_then_else (eq (match_dup 1) (match_dup 2))
916                       (label_ref (match_operand 0 "" ""))
917                       (pc)))]
918   ""
919   "
921   if (hppa_branch_type != CMP_SI)
922     {
923       emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
924       emit_bcond_fp (NE, operands[0]);
925       DONE;
926     }
927   /* set up operands from compare.  */
928   operands[1] = hppa_compare_op0;
929   operands[2] = hppa_compare_op1;
930   /* fall through and generate default code */
933 (define_expand "bne"
934   [(set (pc)
935         (if_then_else (ne (match_dup 1) (match_dup 2))
936                       (label_ref (match_operand 0 "" ""))
937                       (pc)))]
938   ""
939   "
941   if (hppa_branch_type != CMP_SI)
942     {
943       emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
944       emit_bcond_fp (NE, operands[0]);
945       DONE;
946     }
947   operands[1] = hppa_compare_op0;
948   operands[2] = hppa_compare_op1;
951 (define_expand "bgt"
952   [(set (pc)
953         (if_then_else (gt (match_dup 1) (match_dup 2))
954                       (label_ref (match_operand 0 "" ""))
955                       (pc)))]
956   ""
957   "
959   if (hppa_branch_type != CMP_SI)
960     {
961       emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
962       emit_bcond_fp (NE, operands[0]);
963       DONE;
964     }
965   operands[1] = hppa_compare_op0;
966   operands[2] = hppa_compare_op1;
969 (define_expand "blt"
970   [(set (pc)
971         (if_then_else (lt (match_dup 1) (match_dup 2))
972                       (label_ref (match_operand 0 "" ""))
973                       (pc)))]
974   ""
975   "
977   if (hppa_branch_type != CMP_SI)
978     {
979       emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
980       emit_bcond_fp (NE, operands[0]);
981       DONE;
982     }
983   operands[1] = hppa_compare_op0;
984   operands[2] = hppa_compare_op1;
987 (define_expand "bge"
988   [(set (pc)
989         (if_then_else (ge (match_dup 1) (match_dup 2))
990                       (label_ref (match_operand 0 "" ""))
991                       (pc)))]
992   ""
993   "
995   if (hppa_branch_type != CMP_SI)
996     {
997       emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
998       emit_bcond_fp (NE, operands[0]);
999       DONE;
1000     }
1001   operands[1] = hppa_compare_op0;
1002   operands[2] = hppa_compare_op1;
1005 (define_expand "ble"
1006   [(set (pc)
1007         (if_then_else (le (match_dup 1) (match_dup 2))
1008                       (label_ref (match_operand 0 "" ""))
1009                       (pc)))]
1010   ""
1011   "
1013   if (hppa_branch_type != CMP_SI)
1014     {
1015       emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
1016       emit_bcond_fp (NE, operands[0]);
1017       DONE;
1018     }
1019   operands[1] = hppa_compare_op0;
1020   operands[2] = hppa_compare_op1;
1023 (define_expand "bgtu"
1024   [(set (pc)
1025         (if_then_else (gtu (match_dup 1) (match_dup 2))
1026                       (label_ref (match_operand 0 "" ""))
1027                       (pc)))]
1028   ""
1029   "
1031   if (hppa_branch_type != CMP_SI)
1032     FAIL;
1033   operands[1] = hppa_compare_op0;
1034   operands[2] = hppa_compare_op1;
1037 (define_expand "bltu"
1038   [(set (pc)
1039         (if_then_else (ltu (match_dup 1) (match_dup 2))
1040                       (label_ref (match_operand 0 "" ""))
1041                       (pc)))]
1042   ""
1043   "
1045   if (hppa_branch_type != CMP_SI)
1046     FAIL;
1047   operands[1] = hppa_compare_op0;
1048   operands[2] = hppa_compare_op1;
1051 (define_expand "bgeu"
1052   [(set (pc)
1053         (if_then_else (geu (match_dup 1) (match_dup 2))
1054                       (label_ref (match_operand 0 "" ""))
1055                       (pc)))]
1056   ""
1057   "
1059   if (hppa_branch_type != CMP_SI)
1060     FAIL;
1061   operands[1] = hppa_compare_op0;
1062   operands[2] = hppa_compare_op1;
1065 (define_expand "bleu"
1066   [(set (pc)
1067         (if_then_else (leu (match_dup 1) (match_dup 2))
1068                       (label_ref (match_operand 0 "" ""))
1069                       (pc)))]
1070   ""
1071   "
1073   if (hppa_branch_type != CMP_SI)
1074     FAIL;
1075   operands[1] = hppa_compare_op0;
1076   operands[2] = hppa_compare_op1;
1079 ;; Match the branch patterns.
1082 ;; Note a long backward conditional branch with an annulled delay slot
1083 ;; has a length of 12.
1084 (define_insn ""
1085   [(set (pc)
1086         (if_then_else
1087          (match_operator 3 "comparison_operator"
1088                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1089                           (match_operand:SI 2 "arith5_operand" "rL")])
1090          (label_ref (match_operand 0 "" ""))
1091          (pc)))]
1092   ""
1093   "*
1095   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1096                          get_attr_length (insn), 0, insn);
1098 [(set_attr "type" "cbranch")
1099  (set (attr "length")
1100     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1101                (const_int 8184))
1102            (const_int 4)
1103            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1104                (const_int 262100))
1105            (const_int 8)
1106            (eq (symbol_ref "flag_pic") (const_int 0))
1107            (const_int 20)]
1108           (const_int 28)))])
1110 ;; Match the negated branch.
1112 (define_insn ""
1113   [(set (pc)
1114         (if_then_else
1115          (match_operator 3 "comparison_operator"
1116                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1117                           (match_operand:SI 2 "arith5_operand" "rL")])
1118          (pc)
1119          (label_ref (match_operand 0 "" ""))))]
1120   ""
1121   "*
1123   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1124                          get_attr_length (insn), 1, insn);
1126 [(set_attr "type" "cbranch")
1127  (set (attr "length")
1128     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1129                (const_int 8184))
1130            (const_int 4)
1131            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1132                (const_int 262100))
1133            (const_int 8)
1134            (eq (symbol_ref "flag_pic") (const_int 0))
1135            (const_int 20)]
1136           (const_int 28)))])
1138 ;; Branch on Bit patterns.
1139 (define_insn ""
1140   [(set (pc)
1141         (if_then_else
1142          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1143                               (const_int 1)
1144                               (match_operand:SI 1 "uint5_operand" ""))
1145              (const_int 0))
1146          (label_ref (match_operand 2 "" ""))
1147          (pc)))]
1148   ""
1149   "*
1151   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1152                          get_attr_length (insn), 0, insn, 0);
1154 [(set_attr "type" "cbranch")
1155  (set (attr "length")
1156     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1157                       (const_int 8184))
1158            (const_int 4)
1159            (const_int 8)))])
1161 (define_insn ""
1162   [(set (pc)
1163         (if_then_else
1164          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1165                               (const_int 1)
1166                               (match_operand:SI 1 "uint5_operand" ""))
1167              (const_int 0))
1168          (pc)
1169          (label_ref (match_operand 2 "" ""))))]
1170   ""
1171   "*
1173   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1174                          get_attr_length (insn), 1, insn, 0);
1176 [(set_attr "type" "cbranch")
1177  (set (attr "length")
1178     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1179                       (const_int 8184))
1180            (const_int 4)
1181            (const_int 8)))])
1183 (define_insn ""
1184   [(set (pc)
1185         (if_then_else
1186          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1187                               (const_int 1)
1188                               (match_operand:SI 1 "uint5_operand" ""))
1189              (const_int 0))
1190          (label_ref (match_operand 2 "" ""))
1191          (pc)))]
1192   ""
1193   "*
1195   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1196                          get_attr_length (insn), 0, insn, 1);
1198 [(set_attr "type" "cbranch")
1199  (set (attr "length")
1200     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1201                       (const_int 8184))
1202            (const_int 4)
1203            (const_int 8)))])
1205 (define_insn ""
1206   [(set (pc)
1207         (if_then_else
1208          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1209                               (const_int 1)
1210                               (match_operand:SI 1 "uint5_operand" ""))
1211              (const_int 0))
1212          (pc)
1213          (label_ref (match_operand 2 "" ""))))]
1214   ""
1215   "*
1217   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1218                          get_attr_length (insn), 1, insn, 1);
1220 [(set_attr "type" "cbranch")
1221  (set (attr "length")
1222     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1223                       (const_int 8184))
1224            (const_int 4)
1225            (const_int 8)))])
1227 ;; Branch on Variable Bit patterns.
1228 (define_insn ""
1229   [(set (pc)
1230         (if_then_else
1231          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1232                               (const_int 1)
1233                               (match_operand:SI 1 "register_operand" "q"))
1234              (const_int 0))
1235          (label_ref (match_operand 2 "" ""))
1236          (pc)))]
1237   ""
1238   "*
1240   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1241                      get_attr_length (insn), 0, insn, 0);
1243 [(set_attr "type" "cbranch")
1244  (set (attr "length")
1245     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1246                       (const_int 8184))
1247            (const_int 4)
1248            (const_int 8)))])
1250 (define_insn ""
1251   [(set (pc)
1252         (if_then_else
1253          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1254                               (const_int 1)
1255                               (match_operand:SI 1 "register_operand" "q"))
1256              (const_int 0))
1257          (pc)
1258          (label_ref (match_operand 2 "" ""))))]
1259   ""
1260   "*
1262   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1263                      get_attr_length (insn), 1, insn, 0);
1265 [(set_attr "type" "cbranch")
1266  (set (attr "length")
1267     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1268                       (const_int 8184))
1269            (const_int 4)
1270            (const_int 8)))])
1272 (define_insn ""
1273   [(set (pc)
1274         (if_then_else
1275          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1276                               (const_int 1)
1277                               (match_operand:SI 1 "register_operand" "q"))
1278              (const_int 0))
1279          (label_ref (match_operand 2 "" ""))
1280          (pc)))]
1281   ""
1282   "*
1284   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1285                      get_attr_length (insn), 0, insn, 1);
1287 [(set_attr "type" "cbranch")
1288  (set (attr "length")
1289     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1290                       (const_int 8184))
1291            (const_int 4)
1292            (const_int 8)))])
1294 (define_insn ""
1295   [(set (pc)
1296         (if_then_else
1297          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1298                               (const_int 1)
1299                               (match_operand:SI 1 "register_operand" "q"))
1300              (const_int 0))
1301          (pc)
1302          (label_ref (match_operand 2 "" ""))))]
1303   ""
1304   "*
1306   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1307                      get_attr_length (insn), 1, insn, 1);
1309 [(set_attr "type" "cbranch")
1310  (set (attr "length")
1311     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1312                       (const_int 8184))
1313            (const_int 4)
1314            (const_int 8)))])
1316 ;; Floating point branches
1317 (define_insn ""
1318   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1319                            (label_ref (match_operand 0 "" ""))
1320                            (pc)))]
1321   "! TARGET_SOFT_FLOAT"
1322   "*
1324   if (INSN_ANNULLED_BRANCH_P (insn))
1325     return \"ftest\;b,n %0\";
1326   else
1327     return \"ftest\;b%* %0\";
1329   [(set_attr "type" "fbranch")
1330    (set_attr "length" "8")])
1332 (define_insn ""
1333   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1334                            (pc)
1335                            (label_ref (match_operand 0 "" ""))))]
1336   "! TARGET_SOFT_FLOAT"
1337   "*
1339   if (INSN_ANNULLED_BRANCH_P (insn))
1340     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b,n %0\";
1341   else
1342     return \"ftest\;add,tr %%r0,%%r0,%%r0\;b%* %0\";
1344   [(set_attr "type" "fbranch")
1345    (set_attr "length" "12")])
1347 ;; Move instructions
1349 (define_expand "movsi"
1350   [(set (match_operand:SI 0 "general_operand" "")
1351         (match_operand:SI 1 "general_operand" ""))]
1352   ""
1353   "
1355   if (emit_move_sequence (operands, SImode, 0))
1356     DONE;
1359 ;; Reloading an SImode or DImode value requires a scratch register if
1360 ;; going in to or out of float point registers.
1362 (define_expand "reload_insi"
1363   [(set (match_operand:SI 0 "register_operand" "=Z")
1364         (match_operand:SI 1 "non_hard_reg_operand" ""))
1365    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1366   ""
1367   "
1369   if (emit_move_sequence (operands, SImode, operands[2]))
1370     DONE;
1372   /* We don't want the clobber emitted, so handle this ourselves.  */
1373   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1374   DONE;
1377 (define_expand "reload_outsi"
1378   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
1379         (match_operand:SI 1  "register_operand" "Z"))
1380    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1381   ""
1382   "
1384   if (emit_move_sequence (operands, SImode, operands[2]))
1385     DONE;
1387   /* We don't want the clobber emitted, so handle this ourselves.  */
1388   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1389   DONE;
1392 ;;; pic symbol references
1394 (define_insn ""
1395   [(set (match_operand:SI 0 "register_operand" "=r")
1396         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1397                          (match_operand:SI 2 "symbolic_operand" ""))))]
1398   "flag_pic && operands[1] == pic_offset_table_rtx"
1399   "ldw T'%2(%1),%0"
1400   [(set_attr "type" "load")
1401    (set_attr "length" "4")])
1403 (define_insn ""
1404   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1405                                 "=r,r,r,r,r,Q,*q,!f,f,*TR")
1406         (match_operand:SI 1 "move_operand"
1407                                 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
1408   "(register_operand (operands[0], SImode)
1409     || reg_or_0_operand (operands[1], SImode))
1410    && ! TARGET_SOFT_FLOAT"
1411   "@
1412    copy %1,%0
1413    ldi %1,%0
1414    ldil L'%1,%0
1415    {zdepi|depwi,z} %Z1,%0
1416    ldw%M1 %1,%0
1417    stw%M0 %r1,%0
1418    mtsar %r1
1419    fcpy,sgl %f1,%0
1420    fldw%F1 %1,%0
1421    fstw%F0 %1,%0"
1422   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
1423    (set_attr "pa_combine_type" "addmove")
1424    (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
1426 (define_insn ""
1427   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1428                                 "=r,r,r,r,r,Q,*q")
1429         (match_operand:SI 1 "move_operand"
1430                                 "r,J,N,K,RQ,rM,rM"))]
1431   "(register_operand (operands[0], SImode)
1432     || reg_or_0_operand (operands[1], SImode))
1433    && TARGET_SOFT_FLOAT"
1434   "@
1435    copy %1,%0
1436    ldi %1,%0
1437    ldil L'%1,%0
1438    {zdepi|depwi,z} %Z1,%0
1439    ldw%M1 %1,%0
1440    stw%M0 %r1,%0
1441    mtsar %r1"
1442   [(set_attr "type" "move,move,move,move,load,store,move")
1443    (set_attr "pa_combine_type" "addmove")
1444    (set_attr "length" "4,4,4,4,4,4,4")])
1446 (define_insn ""
1447   [(set (match_operand:SI 0 "register_operand" "=r")
1448         (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1449                          (match_operand:SI 2 "register_operand" "r"))))]
1450   "! TARGET_DISABLE_INDEXING"
1451   "*
1453   /* Reload can create backwards (relative to cse) unscaled index
1454      address modes when eliminating registers and possibly for
1455      pseudos that don't get hard registers.  Deal with it.  */
1456   if (operands[2] == hard_frame_pointer_rtx
1457       || operands[2] == stack_pointer_rtx)
1458     return \"{ldwx|ldw} %1(%2),%0\";
1459   else
1460     return \"{ldwx|ldw} %2(%1),%0\";
1462   [(set_attr "type" "load")
1463    (set_attr "length" "4")])
1465 (define_insn ""
1466   [(set (match_operand:SI 0 "register_operand" "=r")
1467         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1468                          (match_operand:SI 2 "basereg_operand" "r"))))]
1469   "! TARGET_DISABLE_INDEXING"
1470   "*
1472   /* Reload can create backwards (relative to cse) unscaled index
1473      address modes when eliminating registers and possibly for
1474      pseudos that don't get hard registers.  Deal with it.  */
1475   if (operands[1] == hard_frame_pointer_rtx
1476       || operands[1] == stack_pointer_rtx)
1477     return \"{ldwx|ldw} %2(%1),%0\";
1478   else
1479     return \"{ldwx|ldw} %1(%2),%0\";
1481   [(set_attr "type" "load")
1482    (set_attr "length" "4")])
1484 ;; Load or store with base-register modification.
1486 (define_expand "pre_load"
1487   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1488               (mem (plus (match_operand 1 "register_operand" "")
1489                                (match_operand 2 "pre_cint_operand" ""))))
1490               (set (match_dup 1)
1491                    (plus (match_dup 1) (match_dup 2)))])]
1492   ""
1493   "
1495   emit_insn (gen_pre_ldw (operands[0], operands[1], operands[2]));
1496   DONE;
1499 (define_insn "pre_ldw"
1500   [(set (match_operand:SI 0 "register_operand" "=r")
1501         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1502                          (match_operand:SI 2 "pre_cint_operand" ""))))
1503    (set (match_dup 1)
1504         (plus:SI (match_dup 1) (match_dup 2)))]
1505   ""
1506   "*
1508   if (INTVAL (operands[2]) < 0)
1509     return \"{ldwm|ldw,mb} %2(%1),%0\";
1510   return \"{ldws|ldw},mb %2(%1),%0\";
1512   [(set_attr "type" "load")
1513    (set_attr "length" "4")])
1515 (define_insn ""
1516   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1517                          (match_operand:SI 1 "pre_cint_operand" "")))
1518         (match_operand:SI 2 "reg_or_0_operand" "rM"))
1519    (set (match_dup 0)
1520         (plus:SI (match_dup 0) (match_dup 1)))]
1521   ""
1522   "*
1524   if (INTVAL (operands[1]) < 0)
1525     return \"{stwm|stw,mb} %r2,%1(%0)\";
1526   return \"{stws|stw},mb %r2,%1(%0)\";
1528   [(set_attr "type" "store")
1529    (set_attr "length" "4")])
1531 (define_insn ""
1532   [(set (match_operand:SI 0 "register_operand" "=r")
1533         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
1534    (set (match_dup 1)
1535         (plus:SI (match_dup 1)
1536                  (match_operand:SI 2 "post_cint_operand" "")))]
1537   ""
1538   "*
1540   if (INTVAL (operands[2]) > 0)
1541     return \"{ldwm|ldw,ma} %2(%1),%0\";
1542   return \"{ldws|ldw},ma %2(%1),%0\";
1544   [(set_attr "type" "load")
1545    (set_attr "length" "4")])
1547 (define_expand "post_store"
1548   [(parallel [(set (mem (match_operand 0 "register_operand" ""))
1549                    (match_operand 1 "reg_or_0_operand" ""))
1550               (set (match_dup 0)
1551                    (plus (match_dup 0)
1552                          (match_operand 2 "post_cint_operand" "")))])]
1553   ""
1554   "
1556   emit_insn (gen_post_stw (operands[0], operands[1], operands[2]));
1557   DONE;
1560 (define_insn "post_stw"
1561   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
1562         (match_operand:SI 1 "reg_or_0_operand" "rM"))
1563    (set (match_dup 0)
1564         (plus:SI (match_dup 0)
1565                  (match_operand:SI 2 "post_cint_operand" "")))]
1566   ""
1567   "*
1569   if (INTVAL (operands[2]) > 0)
1570     return \"{stwm|stw,ma} %r1,%2(%0)\";
1571   return \"{stws|stw},ma %r1,%2(%0)\";
1573   [(set_attr "type" "store")
1574    (set_attr "length" "4")])
1576 ;; For loading the address of a label while generating PIC code.
1577 ;; Note since this pattern can be created at reload time (via movsi), all
1578 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
1579 (define_insn ""
1580   [(set (match_operand 0 "pmode_register_operand" "=a")
1581         (match_operand 1 "pic_label_operand" ""))]
1582   ""
1583   "*
1585   rtx label_rtx = gen_label_rtx ();
1586   rtx xoperands[3];
1587   extern FILE *asm_out_file;
1589   xoperands[0] = operands[0];
1590   xoperands[1] = operands[1];
1591   xoperands[2] = label_rtx;
1592   output_asm_insn (\"{bl|b,l} .+8,%0\", xoperands);
1593   output_asm_insn (\"{depi|depwi} 0,31,2,%0\", xoperands);
1594   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1595                              CODE_LABEL_NUMBER (label_rtx));
1597   /* If we're trying to load the address of a label that happens to be
1598      close, then we can use a shorter sequence.  */
1599   if (GET_CODE (operands[1]) == LABEL_REF
1600       && insn_addresses
1601       && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
1602                 - insn_addresses[INSN_UID (insn)]) < 8100)
1603     {
1604       /* Prefixing with R% here is wrong, it extracts just 11 bits and is
1605          always non-negative.  */
1606       output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
1607     }
1608   else
1609     {
1610       output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
1611       output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
1612     }
1613   return \"\";
1615   [(set_attr "type" "multi")
1616    (set_attr "length" "16")])           ; 12 or 16
1618 (define_insn ""
1619   [(set (match_operand:SI 0 "register_operand" "=a")
1620         (plus:SI (match_operand:SI 1 "register_operand" "r")
1621                  (high:SI (match_operand 2 "" ""))))]
1622   "symbolic_operand (operands[2], Pmode)
1623    && ! function_label_operand (operands[2], Pmode)
1624    && flag_pic == 2"
1625   "addil LT'%G2,%1"
1626   [(set_attr "type" "binary")
1627    (set_attr "length" "4")])
1629 ; We need this to make sure CSE doesn't simplify a memory load with a
1630 ; symbolic address, whose content it think it knows.  For PIC, what CSE
1631 ; think is the real value will be the address of that value.
1632 (define_insn ""
1633   [(set (match_operand:SI 0 "register_operand" "=r")
1634         (mem:SI
1635           (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1636                      (unspec:SI
1637                         [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
1638   ""
1639   "*
1641   if (flag_pic != 2)
1642     abort ();
1643   return \"ldw RT'%G2(%1),%0\";
1645   [(set_attr "type" "load")
1646    (set_attr "length" "4")])
1648 ;; Always use addil rather than ldil;add sequences.  This allows the
1649 ;; HP linker to eliminate the dp relocation if the symbolic operand
1650 ;; lives in the TEXT space.
1651 (define_insn ""
1652   [(set (match_operand:SI 0 "register_operand" "=a")
1653         (high:SI (match_operand 1 "" "")))]
1654   "symbolic_operand (operands[1], Pmode)
1655    && ! function_label_operand (operands[1], Pmode)
1656    && ! read_only_operand (operands[1], Pmode)
1657    && ! flag_pic"
1658   "*
1660   if (TARGET_LONG_LOAD_STORE)
1661     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
1662   else
1663     return \"addil LR'%H1,%%r27\";
1665   [(set_attr "type" "binary")
1666    (set (attr "length")
1667       (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
1668                     (const_int 4)
1669                     (const_int 8)))])
1672 ;; This is for use in the prologue/epilogue code.  We need it
1673 ;; to add large constants to a stack pointer or frame pointer.
1674 ;; Because of the additional %r1 pressure, we probably do not
1675 ;; want to use this in general code, so make it available
1676 ;; only after reload.
1677 (define_insn ""
1678   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
1679         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1680                  (high:SI (match_operand 2 "const_int_operand" ""))))]
1681   "reload_completed"
1682   "@
1683    addil L'%G2,%1
1684    ldil L'%G2,%0\;{addl|add,l} %0,%1,%0"
1685   [(set_attr "type" "binary,binary")
1686    (set_attr "length" "4,8")])
1688 (define_insn ""
1689   [(set (match_operand:SI 0 "register_operand" "=r")
1690         (high:SI (match_operand 1 "" "")))]
1691   "(!flag_pic || !symbolic_operand (operands[1], Pmode))
1692     && !is_function_label_plus_const (operands[1])"
1693   "*
1695   if (symbolic_operand (operands[1], Pmode))
1696     return \"ldil LR'%H1,%0\";
1697   else
1698     return \"ldil L'%G1,%0\";
1700   [(set_attr "type" "move")
1701    (set_attr "length" "4")])
1703 (define_insn ""
1704   [(set (match_operand:SI 0 "register_operand" "=r")
1705         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1706                    (match_operand:SI 2 "immediate_operand" "i")))]
1707   "!is_function_label_plus_const (operands[2])"
1708   "*
1710   if (flag_pic && symbolic_operand (operands[2], Pmode))
1711     abort ();
1712   else if (symbolic_operand (operands[2], Pmode))
1713     return \"ldo RR'%G2(%1),%0\";
1714   else
1715     return \"ldo R'%G2(%1),%0\";
1717   [(set_attr "type" "move")
1718    (set_attr "length" "4")])
1720 ;; Now that a symbolic_address plus a constant is broken up early
1721 ;; in the compilation phase (for better CSE) we need a special
1722 ;; combiner pattern to load the symbolic address plus the constant
1723 ;; in only 2 instructions. (For cases where the symbolic address
1724 ;; was not a common subexpression.)
1725 (define_split
1726   [(set (match_operand:SI 0 "register_operand" "")
1727         (match_operand:SI 1 "symbolic_operand" ""))
1728    (clobber (match_operand:SI 2 "register_operand" ""))]
1729   "! (flag_pic && pic_label_operand (operands[1], SImode))"
1730   [(set (match_dup 2) (high:SI (match_dup 1)))
1731    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
1732   "")
1734 ;; hppa_legitimize_address goes to a great deal of trouble to
1735 ;; create addresses which use indexing.  In some cases, this
1736 ;; is a lose because there isn't any store instructions which
1737 ;; allow indexed addresses (with integer register source).
1739 ;; These define_splits try to turn a 3 insn store into
1740 ;; a 2 insn store with some creative RTL rewriting.
1741 (define_split
1742   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1743                                (match_operand:SI 1 "shadd_operand" ""))
1744                    (plus:SI (match_operand:SI 2 "register_operand" "")
1745                             (match_operand:SI 3 "const_int_operand" ""))))
1746         (match_operand:SI 4 "register_operand" ""))
1747    (clobber (match_operand:SI 5 "register_operand" ""))]
1748   ""
1749   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1750                                (match_dup 2)))
1751    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1752   "")
1754 (define_split
1755   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1756                                (match_operand:SI 1 "shadd_operand" ""))
1757                    (plus:SI (match_operand:SI 2 "register_operand" "")
1758                             (match_operand:SI 3 "const_int_operand" ""))))
1759         (match_operand:HI 4 "register_operand" ""))
1760    (clobber (match_operand:SI 5 "register_operand" ""))]
1761   ""
1762   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1763                                (match_dup 2)))
1764    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1765   "")
1767 (define_split
1768   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1769                                (match_operand:SI 1 "shadd_operand" ""))
1770                    (plus:SI (match_operand:SI 2 "register_operand" "")
1771                             (match_operand:SI 3 "const_int_operand" ""))))
1772         (match_operand:QI 4 "register_operand" ""))
1773    (clobber (match_operand:SI 5 "register_operand" ""))]
1774   ""
1775   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1776                                (match_dup 2)))
1777    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1778   "")
1780 (define_expand "movhi"
1781   [(set (match_operand:HI 0 "general_operand" "")
1782         (match_operand:HI 1 "general_operand" ""))]
1783   ""
1784   "
1786   if (emit_move_sequence (operands, HImode, 0))
1787     DONE;
1790 (define_insn ""
1791   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
1792         (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
1793   "register_operand (operands[0], HImode)
1794    || reg_or_0_operand (operands[1], HImode)"
1795   "@
1796    copy %1,%0
1797    ldi %1,%0
1798    ldil L'%1,%0
1799    {zdepi|depwi,z} %Z1,%0
1800    ldh%M1 %1,%0
1801    sth%M0 %r1,%0
1802    mtsar %r1
1803    fcpy,sgl %f1,%0"
1804   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1805    (set_attr "pa_combine_type" "addmove")
1806    (set_attr "length" "4,4,4,4,4,4,4,4")])
1808 (define_insn ""
1809   [(set (match_operand:HI 0 "register_operand" "=r")
1810         (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1811                          (match_operand:SI 2 "register_operand" "r"))))]
1812   "! TARGET_DISABLE_INDEXING"
1813   "*
1815   /* Reload can create backwards (relative to cse) unscaled index
1816      address modes when eliminating registers and possibly for
1817      pseudos that don't get hard registers.  Deal with it.  */
1818   if (operands[2] == hard_frame_pointer_rtx
1819       || operands[2] == stack_pointer_rtx)
1820     return \"{ldhx|ldh} %1(%2),%0\";
1821   else
1822     return \"{ldhx|ldh} %2(%1),%0\";
1824   [(set_attr "type" "load")
1825    (set_attr "length" "4")])
1827 (define_insn ""
1828   [(set (match_operand:HI 0 "register_operand" "=r")
1829         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
1830                          (match_operand:SI 2 "basereg_operand" "r"))))]
1831   "! TARGET_DISABLE_INDEXING"
1832   "*
1834   /* Reload can create backwards (relative to cse) unscaled index
1835      address modes when eliminating registers and possibly for
1836      pseudos that don't get hard registers.  Deal with it.  */
1837   if (operands[1] == hard_frame_pointer_rtx
1838       || operands[1] == stack_pointer_rtx)
1839     return \"{ldhx|ldh} %2(%1),%0\";
1840   else
1841     return \"{ldhx|ldh} %1(%2),%0\";
1843   [(set_attr "type" "load")
1844    (set_attr "length" "4")])
1846 ; Now zero extended variants.
1847 (define_insn ""
1848   [(set (match_operand:SI 0 "register_operand" "=r")
1849         (zero_extend:SI (mem:HI
1850                           (plus:SI
1851                             (match_operand:SI 1 "basereg_operand" "r")
1852                             (match_operand:SI 2 "register_operand" "r")))))]
1853   "! TARGET_DISABLE_INDEXING"
1854   "*
1856   /* Reload can create backwards (relative to cse) unscaled index
1857      address modes when eliminating registers and possibly for
1858      pseudos that don't get hard registers.  Deal with it.  */
1859   if (operands[2] == hard_frame_pointer_rtx
1860       || operands[2] == stack_pointer_rtx)
1861     return \"{ldhx|ldh} %1(%2),%0\";
1862   else
1863     return \"{ldhx|ldh} %2(%1),%0\";
1865   [(set_attr "type" "load")
1866    (set_attr "length" "4")])
1868 (define_insn ""
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870         (zero_extend:SI (mem:HI
1871                           (plus:SI
1872                              (match_operand:SI 1 "register_operand" "r")
1873                              (match_operand:SI 2 "basereg_operand" "r")))))]
1874   "! TARGET_DISABLE_INDEXING"
1875   "*
1877   /* Reload can create backwards (relative to cse) unscaled index
1878      address modes when eliminating registers and possibly for
1879      pseudos that don't get hard registers.  Deal with it.  */
1880   if (operands[1] == hard_frame_pointer_rtx
1881       || operands[1] == stack_pointer_rtx)
1882     return \"{ldhx|ldh} %2(%1),%0\";
1883   else
1884     return \"{ldhx|ldh} %1(%2),%0\";
1886   [(set_attr "type" "load")
1887    (set_attr "length" "4")])
1889 (define_insn ""
1890   [(set (match_operand:HI 0 "register_operand" "=r")
1891         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1892                          (match_operand:SI 2 "int5_operand" "L"))))
1893    (set (match_dup 1)
1894         (plus:SI (match_dup 1) (match_dup 2)))]
1895   ""
1896   "{ldhs|ldh},mb %2(%1),%0"
1897   [(set_attr "type" "load")
1898    (set_attr "length" "4")])
1900 ; And a zero extended variant.
1901 (define_insn ""
1902   [(set (match_operand:SI 0 "register_operand" "=r")
1903         (zero_extend:SI (mem:HI
1904                           (plus:SI
1905                             (match_operand:SI 1 "register_operand" "+r")
1906                             (match_operand:SI 2 "int5_operand" "L")))))
1907    (set (match_dup 1)
1908         (plus:SI (match_dup 1) (match_dup 2)))]
1909   ""
1910   "{ldhs|ldh},mb %2(%1),%0"
1911   [(set_attr "type" "load")
1912    (set_attr "length" "4")])
1914 (define_insn ""
1915   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1916                          (match_operand:SI 1 "int5_operand" "L")))
1917         (match_operand:HI 2 "reg_or_0_operand" "rM"))
1918    (set (match_dup 0)
1919         (plus:SI (match_dup 0) (match_dup 1)))]
1920   ""
1921   "{sths|sth},mb %r2,%1(%0)"
1922   [(set_attr "type" "store")
1923    (set_attr "length" "4")])
1925 (define_insn ""
1926   [(set (match_operand:HI 0 "register_operand" "=r")
1927         (high:HI (match_operand 1 "const_int_operand" "")))]
1928   ""
1929   "ldil L'%G1,%0"
1930   [(set_attr "type" "move")
1931    (set_attr "length" "4")])
1933 (define_insn ""
1934   [(set (match_operand:HI 0 "register_operand" "=r")
1935         (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1936                    (match_operand 2 "const_int_operand" "")))]
1937   ""
1938   "ldo R'%G2(%1),%0"
1939   [(set_attr "type" "move")
1940    (set_attr "length" "4")])
1942 (define_expand "movqi"
1943   [(set (match_operand:QI 0 "general_operand" "")
1944         (match_operand:QI 1 "general_operand" ""))]
1945   ""
1946   "
1948   if (emit_move_sequence (operands, QImode, 0))
1949     DONE;
1952 (define_insn ""
1953   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!*f")
1954         (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!*fM"))]
1955   "register_operand (operands[0], QImode)
1956    || reg_or_0_operand (operands[1], QImode)"
1957   "@
1958    copy %1,%0
1959    ldi %1,%0
1960    ldil L'%1,%0
1961    {zdepi|depwi,z} %Z1,%0
1962    ldb%M1 %1,%0
1963    stb%M0 %r1,%0
1964    mtsar %r1
1965    fcpy,sgl %f1,%0"
1966   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1967    (set_attr "pa_combine_type" "addmove")
1968    (set_attr "length" "4,4,4,4,4,4,4,4")])
1970 (define_insn ""
1971   [(set (match_operand:QI 0 "register_operand" "=r")
1972         (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1973                          (match_operand:SI 2 "register_operand" "r"))))]
1974   "! TARGET_DISABLE_INDEXING"
1975   "*
1977   /* Reload can create backwards (relative to cse) unscaled index
1978      address modes when eliminating registers and possibly for
1979      pseudos that don't get hard registers.  Deal with it.  */
1980   if (operands[2] == hard_frame_pointer_rtx
1981       || operands[2] == stack_pointer_rtx)
1982     return \"{ldbx|ldb} %1(%2),%0\";
1983   else
1984     return \"{ldbx|ldb} %2(%1),%0\";
1986   [(set_attr "type" "load")
1987    (set_attr "length" "4")])
1989 (define_insn ""
1990   [(set (match_operand:QI 0 "register_operand" "=r")
1991         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
1992                          (match_operand:SI 2 "basereg_operand" "r"))))]
1993   "! TARGET_DISABLE_INDEXING"
1994   "*
1996   /* Reload can create backwards (relative to cse) unscaled index
1997      address modes when eliminating registers and possibly for
1998      pseudos that don't get hard registers.  Deal with it.  */
1999   if (operands[1] == hard_frame_pointer_rtx
2000       || operands[1] == stack_pointer_rtx)
2001     return \"{ldbx|ldb} %2(%1),%0\";
2002   else
2003     return \"{ldbx|ldb} %1(%2),%0\";
2005   [(set_attr "type" "load")
2006    (set_attr "length" "4")])
2008 ; Indexed byte load with zero extension to SImode or HImode.
2009 (define_insn ""
2010   [(set (match_operand:SI 0 "register_operand" "=r")
2011         (zero_extend:SI (mem:QI
2012                           (plus:SI
2013                             (match_operand:SI 1 "basereg_operand" "r")
2014                             (match_operand:SI 2 "register_operand" "r")))))]
2015   "! TARGET_DISABLE_INDEXING"
2016   "*
2018   /* Reload can create backwards (relative to cse) unscaled index
2019      address modes when eliminating registers and possibly for
2020      pseudos that don't get hard registers.  Deal with it.  */
2021   if (operands[2] == hard_frame_pointer_rtx
2022       || operands[2] == stack_pointer_rtx)
2023     return \"{ldbx|ldb} %1(%2),%0\";
2024   else
2025     return \"{ldbx|ldb} %2(%1),%0\";
2027   [(set_attr "type" "load")
2028    (set_attr "length" "4")])
2030 (define_insn ""
2031   [(set (match_operand:SI 0 "register_operand" "=r")
2032         (zero_extend:SI (mem:QI
2033                           (plus:SI
2034                             (match_operand:SI 1 "register_operand" "r")
2035                             (match_operand:SI 2 "basereg_operand" "r")))))]
2036   "! TARGET_DISABLE_INDEXING"
2037   "*
2039   /* Reload can create backwards (relative to cse) unscaled index
2040      address modes when eliminating registers and possibly for
2041      pseudos that don't get hard registers.  Deal with it.  */
2042   if (operands[1] == hard_frame_pointer_rtx
2043       || operands[1] == stack_pointer_rtx)
2044     return \"{ldbx|ldb} %2(%1),%0\";
2045   else
2046     return \"{ldbx|ldb} %1(%2),%0\";
2048   [(set_attr "type" "load")
2049    (set_attr "length" "4")])
2051 (define_insn ""
2052   [(set (match_operand:HI 0 "register_operand" "=r")
2053         (zero_extend:HI (mem:QI
2054                           (plus:SI
2055                             (match_operand:SI 1 "basereg_operand" "r")
2056                             (match_operand:SI 2 "register_operand" "r")))))]
2057   "! TARGET_DISABLE_INDEXING"
2058   "*
2060   /* Reload can create backwards (relative to cse) unscaled index
2061      address modes when eliminating registers and possibly for
2062      pseudos that don't get hard registers.  Deal with it.  */
2063   if (operands[2] == hard_frame_pointer_rtx
2064       || operands[2] == stack_pointer_rtx)
2065     return \"{ldbx|ldb} %1(%2),%0\";
2066   else
2067     return \"{ldbx|ldb} %2(%1),%0\";
2069   [(set_attr "type" "load")
2070    (set_attr "length" "4")])
2072 (define_insn ""
2073   [(set (match_operand:HI 0 "register_operand" "=r")
2074         (zero_extend:HI (mem:QI
2075                           (plus:SI
2076                             (match_operand:SI 1 "register_operand" "r")
2077                             (match_operand:SI 2 "basereg_operand" "r")))))]
2078   "! TARGET_DISABLE_INDEXING"
2079   "*
2081   /* Reload can create backwards (relative to cse) unscaled index
2082      address modes when eliminating registers and possibly for
2083      pseudos that don't get hard registers.  Deal with it.  */
2084   if (operands[1] == hard_frame_pointer_rtx
2085       || operands[1] == stack_pointer_rtx)
2086     return \"{ldbx|ldb} %2(%1),%0\";
2087   else
2088     return \"{ldbx|ldb} %1(%2),%0\";
2090   [(set_attr "type" "load")
2091    (set_attr "length" "4")])
2093 (define_insn ""
2094   [(set (match_operand:QI 0 "register_operand" "=r")
2095         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2096                          (match_operand:SI 2 "int5_operand" "L"))))
2097    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2098   ""
2099   "{ldbs|ldb},mb %2(%1),%0"
2100   [(set_attr "type" "load")
2101    (set_attr "length" "4")])
2103 ; Now the same thing with zero extensions.
2104 (define_insn ""
2105   [(set (match_operand:SI 0 "register_operand" "=r")
2106         (zero_extend:SI (mem:QI (plus:SI
2107                                   (match_operand:SI 1 "register_operand" "+r")
2108                                   (match_operand:SI 2 "int5_operand" "L")))))
2109    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2110   ""
2111   "{ldbs|ldb},mb %2(%1),%0"
2112   [(set_attr "type" "load")
2113    (set_attr "length" "4")])
2115 (define_insn ""
2116   [(set (match_operand:HI 0 "register_operand" "=r")
2117         (zero_extend:HI (mem:QI (plus:SI
2118                                   (match_operand:SI 1 "register_operand" "+r")
2119                                   (match_operand:SI 2 "int5_operand" "L")))))
2120    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2121   ""
2122   "{ldbs|ldb},mb %2(%1),%0"
2123   [(set_attr "type" "load")
2124    (set_attr "length" "4")])
2126 (define_insn ""
2127   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2128                          (match_operand:SI 1 "int5_operand" "L")))
2129         (match_operand:QI 2 "reg_or_0_operand" "rM"))
2130    (set (match_dup 0)
2131         (plus:SI (match_dup 0) (match_dup 1)))]
2132   ""
2133   "{stbs|stb},mb %r2,%1(%0)"
2134   [(set_attr "type" "store")
2135    (set_attr "length" "4")])
2137 ;; The definition of this insn does not really explain what it does,
2138 ;; but it should suffice
2139 ;; that anything generated as this insn will be recognized as one
2140 ;; and that it will not successfully combine with anything.
2141 (define_expand "movstrsi"
2142   [(parallel [(set (match_operand:BLK 0 "" "")
2143                    (match_operand:BLK 1 "" ""))
2144               (clobber (match_dup 7))
2145               (clobber (match_dup 8))
2146               (clobber (match_dup 4))
2147               (clobber (match_dup 5))
2148               (clobber (match_dup 6))
2149               (use (match_operand:SI 2 "arith_operand" ""))
2150               (use (match_operand:SI 3 "const_int_operand" ""))])]
2151   ""
2152   "
2154   int size, align;
2156   /* HP provides very fast block move library routine for the PA;
2157      this routine includes:
2159         4x4 byte at a time block moves,
2160         1x4 byte at a time with alignment checked at runtime with
2161             attempts to align the source and destination as needed
2162         1x1 byte loop
2164      With that in mind, here's the heuristics to try and guess when
2165      the inlined block move will be better than the library block
2166      move:
2168         If the size isn't constant, then always use the library routines.
2170         If the size is large in respect to the known alignment, then use
2171         the library routines.
2173         If the size is small in repsect to the known alignment, then open
2174         code the copy (since that will lead to better scheduling).
2176         Else use the block move pattern.   */
2178   /* Undetermined size, use the library routine.  */
2179   if (GET_CODE (operands[2]) != CONST_INT)
2180     FAIL;
2182   size = INTVAL (operands[2]);
2183   align = INTVAL (operands[3]);
2184   align = align > 4 ? 4 : align;
2186   /* If size/alignment > 8 (eg size is large in respect to alignment),
2187      then use the library routines.  */
2188   if (size / align > 16)
2189     FAIL;
2191   /* This does happen, but not often enough to worry much about.  */
2192   if (size / align < MOVE_RATIO)
2193     FAIL;
2194   
2195   /* Fall through means we're going to use our block move pattern.  */
2196   operands[0]
2197     = change_address (operands[0], VOIDmode,
2198                       copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2199   operands[1]
2200     = change_address (operands[1], VOIDmode,
2201                       copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2202   operands[4] = gen_reg_rtx (SImode);
2203   operands[5] = gen_reg_rtx (SImode);
2204   operands[6] = gen_reg_rtx (SImode);
2205   operands[7] = XEXP (operands[0], 0);
2206   operands[8] = XEXP (operands[1], 0);
2209 ;; The operand constraints are written like this to support both compile-time
2210 ;; and run-time determined byte count.  If the count is run-time determined,
2211 ;; the register with the byte count is clobbered by the copying code, and
2212 ;; therefore it is forced to operand 2.  If the count is compile-time
2213 ;; determined, we need two scratch registers for the unrolled code.
2214 (define_insn "movstrsi_internal"
2215   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2216         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2217    (clobber (match_dup 0))
2218    (clobber (match_dup 1))
2219    (clobber (match_operand:SI 2 "register_operand" "=r,r"))     ;loop cnt/tmp
2220    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp
2221    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
2222    (use (match_operand:SI 4 "arith_operand" "J,2"))      ;byte count
2223    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2224   ""
2225   "* return output_block_move (operands, !which_alternative);"
2226   [(set_attr "type" "multi,multi")])
2228 ;; Floating point move insns
2230 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2231 ;; to be reloaded by putting the constant into memory when
2232 ;; reg is a floating point register.
2234 ;; For integer registers we use ldil;ldo to set the appropriate
2235 ;; value.
2237 ;; This must come before the movdf pattern, and it must be present
2238 ;; to handle obscure reloading cases.
2239 (define_insn ""
2240   [(set (match_operand:DF 0 "register_operand" "=?r,f")
2241         (match_operand:DF 1 "" "?F,m"))]
2242   "GET_CODE (operands[1]) == CONST_DOUBLE
2243    && operands[1] != CONST0_RTX (DFmode)
2244    && ! TARGET_SOFT_FLOAT"
2245   "* return (which_alternative == 0 ? output_move_double (operands)
2246                                     : \"fldd%F1 %1,%0\");"
2247   [(set_attr "type" "move,fpload")
2248    (set_attr "length" "16,4")])
2250 (define_expand "movdf"
2251   [(set (match_operand:DF 0 "general_operand" "")
2252         (match_operand:DF 1 "general_operand" ""))]
2253   ""
2254   "
2256   if (emit_move_sequence (operands, DFmode, 0))
2257     DONE;
2260 ;; Reloading an SImode or DImode value requires a scratch register if
2261 ;; going in to or out of float point registers.
2263 (define_expand "reload_indf"
2264   [(set (match_operand:DF 0 "register_operand" "=Z")
2265         (match_operand:DF 1 "non_hard_reg_operand" ""))
2266    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2267   ""
2268   "
2270   if (emit_move_sequence (operands, DFmode, operands[2]))
2271     DONE;
2273   /* We don't want the clobber emitted, so handle this ourselves.  */
2274   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2275   DONE;
2278 (define_expand "reload_outdf" 
2279  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2280         (match_operand:DF 1  "register_operand" "Z"))
2281    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2282   ""
2283   "
2285   if (emit_move_sequence (operands, DFmode, operands[2]))
2286     DONE;
2288   /* We don't want the clobber emitted, so handle this ourselves.  */
2289   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2290   DONE;
2293 (define_insn ""
2294   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2295                           "=f,*r,RQ,?o,?Q,f,*r,*r")
2296         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2297                           "fG,*rG,f,*r,*r,RQ,o,RQ"))]
2298   "(register_operand (operands[0], DFmode)
2299     || reg_or_0_operand (operands[1], DFmode))
2300    && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2301          && GET_CODE (operands[0]) == MEM)
2302    && ! TARGET_SOFT_FLOAT"
2303   "*
2305   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2306       || operands[1] == CONST0_RTX (DFmode))
2307     return output_fp_move_double (operands);
2308   return output_move_double (operands);
2310   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2311    (set_attr "length" "4,8,4,8,16,4,8,16")])
2313 (define_insn ""
2314   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2315                           "=r,?o,?Q,r,r")
2316         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2317                           "rG,r,r,o,Q"))]
2318   "(register_operand (operands[0], DFmode)
2319     || reg_or_0_operand (operands[1], DFmode))
2320    && TARGET_SOFT_FLOAT"
2321   "*
2323   return output_move_double (operands);
2325   [(set_attr "type" "move,store,store,load,load")
2326    (set_attr "length" "8,8,16,8,16")])
2328 (define_insn ""
2329   [(set (match_operand:DF 0 "register_operand" "=fx")
2330         (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2331                          (match_operand:SI 2 "register_operand" "r"))))]
2332   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2333   "*
2335   /* Reload can create backwards (relative to cse) unscaled index
2336      address modes when eliminating registers and possibly for
2337      pseudos that don't get hard registers.  Deal with it.  */
2338   if (operands[2] == hard_frame_pointer_rtx
2339       || operands[2] == stack_pointer_rtx)
2340     return \"{flddx|fldd} %1(%2),%0\";
2341   else
2342     return \"{flddx|fldd} %2(%1),%0\";
2344   [(set_attr "type" "fpload")
2345    (set_attr "length" "4")])
2347 (define_insn ""
2348   [(set (match_operand:DF 0 "register_operand" "=fx")
2349         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2350                          (match_operand:SI 2 "basereg_operand" "r"))))]
2351   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2352   "*
2354   /* Reload can create backwards (relative to cse) unscaled index
2355      address modes when eliminating registers and possibly for
2356      pseudos that don't get hard registers.  Deal with it.  */
2357   if (operands[1] == hard_frame_pointer_rtx
2358       || operands[1] == stack_pointer_rtx)
2359     return \"{flddx|fldd} %2(%1),%0\";
2360   else
2361     return \"{flddx|fldd} %1(%2),%0\";
2363   [(set_attr "type" "fpload")
2364    (set_attr "length" "4")])
2366 (define_insn ""
2367   [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2368                          (match_operand:SI 2 "register_operand" "r")))
2369         (match_operand:DF 0 "register_operand" "fx"))]
2370   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2371   "*
2373   /* Reload can create backwards (relative to cse) unscaled index
2374      address modes when eliminating registers and possibly for
2375      pseudos that don't get hard registers.  Deal with it.  */
2376   if (operands[2] == hard_frame_pointer_rtx
2377       || operands[2] == stack_pointer_rtx)
2378     return \"{fstdx|fstd} %0,%1(%2)\";
2379   else
2380     return \"{fstdx|fstd} %0,%2(%1)\";
2382   [(set_attr "type" "fpstore")
2383    (set_attr "length" "4")])
2385 (define_insn ""
2386   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2387                          (match_operand:SI 2 "basereg_operand" "r")))
2388         (match_operand:DF 0 "register_operand" "fx"))]
2389   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2390   "*
2392   /* Reload can create backwards (relative to cse) unscaled index
2393      address modes when eliminating registers and possibly for
2394      pseudos that don't get hard registers.  Deal with it.  */
2395   if (operands[1] == hard_frame_pointer_rtx
2396       || operands[1] == stack_pointer_rtx)
2397     return \"{fstdx|fstd} %0,%2(%1)\";
2398   else
2399     return \"{fstdx|fstd} %0,%1(%2)\";
2401   [(set_attr "type" "fpstore")
2402    (set_attr "length" "4")])
2404 (define_expand "movdi"
2405   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2406         (match_operand:DI 1 "general_operand" ""))]
2407   ""
2408   "
2410   if (emit_move_sequence (operands, DImode, 0))
2411     DONE;
2414 (define_expand "reload_indi"
2415   [(set (match_operand:DI 0 "register_operand" "=Z")
2416         (match_operand:DI 1 "non_hard_reg_operand" ""))
2417    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2418   ""
2419   "
2421   if (emit_move_sequence (operands, DImode, operands[2]))
2422     DONE;
2424   /* We don't want the clobber emitted, so handle this ourselves.  */
2425   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2426   DONE;
2429 (define_expand "reload_outdi"
2430   [(set (match_operand:DI 0 "general_operand" "")
2431         (match_operand:DI 1 "register_operand" "Z"))
2432    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2433   ""
2434   "
2436   if (emit_move_sequence (operands, DImode, operands[2]))
2437     DONE;
2439   /* We don't want the clobber emitted, so handle this ourselves.  */
2440   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2441   DONE;
2444 (define_insn ""
2445   [(set (match_operand:DI 0 "register_operand" "=r")
2446         (high:DI (match_operand 1 "" "")))]
2447   ""
2448   "*
2450   rtx op0 = operands[0];
2451   rtx op1 = operands[1];
2453   if (GET_CODE (op1) == CONST_INT)
2454     {
2455       operands[0] = operand_subword (op0, 1, 0, DImode);
2456       output_asm_insn (\"ldil L'%1,%0\", operands);
2458       operands[0] = operand_subword (op0, 0, 0, DImode);
2459       if (INTVAL (op1) < 0)
2460         output_asm_insn (\"ldi -1,%0\", operands);
2461       else
2462         output_asm_insn (\"ldi 0,%0\", operands);
2463       return \"\";
2464     }
2465   else if (GET_CODE (op1) == CONST_DOUBLE)
2466     {
2467       operands[0] = operand_subword (op0, 1, 0, DImode);
2468       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
2469       output_asm_insn (\"ldil L'%1,%0\", operands);
2471       operands[0] = operand_subword (op0, 0, 0, DImode);
2472       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
2473       output_asm_insn (singlemove_string (operands), operands);
2474       return \"\";
2475     }
2476   else
2477     abort ();
2479   [(set_attr "type" "move")
2480    (set_attr "length" "8")])
2482 (define_insn ""
2483   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2484                           "=r,o,Q,r,r,r,f,f,*TR")
2485         (match_operand:DI 1 "general_operand"
2486                           "rM,r,r,o*R,Q,i,fM,*TR,f"))]
2487   "(register_operand (operands[0], DImode)
2488     || reg_or_0_operand (operands[1], DImode))
2489    && ! TARGET_SOFT_FLOAT"
2490   "*
2492   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2493       || (operands[1] == CONST0_RTX (DImode)))
2494     return output_fp_move_double (operands);
2495   return output_move_double (operands);
2497   [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
2498    (set_attr "length" "8,8,16,8,16,16,4,4,4")])
2500 (define_insn ""
2501   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2502                           "=r,o,Q,r,r,r")
2503         (match_operand:DI 1 "general_operand"
2504                           "rM,r,r,o,Q,i"))]
2505   "(register_operand (operands[0], DImode)
2506     || reg_or_0_operand (operands[1], DImode))
2507    && TARGET_SOFT_FLOAT"
2508   "*
2510   return output_move_double (operands);
2512   [(set_attr "type" "move,store,store,load,load,multi")
2513    (set_attr "length" "8,8,16,8,16,16")])
2515 (define_insn ""
2516   [(set (match_operand:DI 0 "register_operand" "=r,&r")
2517         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
2518                    (match_operand:DI 2 "immediate_operand" "i,i")))]
2519   ""
2520   "*
2522   /* Don't output a 64 bit constant, since we can't trust the assembler to
2523      handle it correctly.  */
2524   if (GET_CODE (operands[2]) == CONST_DOUBLE)
2525     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2526   if (which_alternative == 1)
2527     output_asm_insn (\"copy %1,%0\", operands);
2528   return \"ldo R'%G2(%R1),%R0\";
2530   [(set_attr "type" "move,move")
2531    (set_attr "length" "4,8")])
2533 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2534 ;; to be reloaded by putting the constant into memory when
2535 ;; reg is a floating point register.
2537 ;; For integer registers we use ldil;ldo to set the appropriate
2538 ;; value.
2540 ;; This must come before the movsf pattern, and it must be present
2541 ;; to handle obscure reloading cases.
2542 (define_insn ""
2543   [(set (match_operand:SF 0 "register_operand" "=?r,f")
2544         (match_operand:SF 1 "" "?F,m"))]
2545   "GET_CODE (operands[1]) == CONST_DOUBLE
2546    && operands[1] != CONST0_RTX (SFmode)
2547    && ! TARGET_SOFT_FLOAT"
2548   "* return (which_alternative == 0 ? singlemove_string (operands)
2549                                     : \" fldw%F1 %1,%0\");"
2550   [(set_attr "type" "move,fpload")
2551    (set_attr "length" "8,4")])
2553 (define_expand "movsf"
2554   [(set (match_operand:SF 0 "general_operand" "")
2555         (match_operand:SF 1 "general_operand" ""))]
2556   ""
2557   "
2559   if (emit_move_sequence (operands, SFmode, 0))
2560     DONE;
2563 ;; Reloading an SImode or DImode value requires a scratch register if
2564 ;; going in to or out of float point registers.
2566 (define_expand "reload_insf"
2567   [(set (match_operand:SF 0 "register_operand" "=Z")
2568         (match_operand:SF 1 "non_hard_reg_operand" ""))
2569    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2570   ""
2571   "
2573   if (emit_move_sequence (operands, SFmode, operands[2]))
2574     DONE;
2576   /* We don't want the clobber emitted, so handle this ourselves.  */
2577   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2578   DONE;
2581 (define_expand "reload_outsf"
2582   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
2583         (match_operand:SF 1  "register_operand" "Z"))
2584    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2585   ""
2586   "
2588   if (emit_move_sequence (operands, SFmode, operands[2]))
2589     DONE;
2591   /* We don't want the clobber emitted, so handle this ourselves.  */
2592   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2593   DONE;
2596 (define_insn ""
2597   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2598                           "=f,r,f,r,RQ,Q")
2599         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2600                           "fG,rG,RQ,RQ,f,rG"))]
2601   "(register_operand (operands[0], SFmode)
2602     || reg_or_0_operand (operands[1], SFmode))
2603    && ! TARGET_SOFT_FLOAT"
2604   "@
2605    fcpy,sgl %f1,%0
2606    copy %r1,%0
2607    fldw%F1 %1,%0
2608    ldw%M1 %1,%0
2609    fstw%F0 %r1,%0
2610    stw%M0 %r1,%0"
2611   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
2612    (set_attr "pa_combine_type" "addmove")
2613    (set_attr "length" "4,4,4,4,4,4")])
2615 (define_insn ""
2616   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2617                           "=r,r,Q")
2618         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2619                           "rG,RQ,rG"))]
2620   "(register_operand (operands[0], SFmode)
2621     || reg_or_0_operand (operands[1], SFmode))
2622    && TARGET_SOFT_FLOAT"
2623   "@
2624    copy %r1,%0
2625    ldw%M1 %1,%0
2626    stw%M0 %r1,%0"
2627   [(set_attr "type" "move,load,store")
2628    (set_attr "pa_combine_type" "addmove")
2629    (set_attr "length" "4,4,4")])
2631 (define_insn ""
2632   [(set (match_operand:SF 0 "register_operand" "=fx")
2633         (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2634                          (match_operand:SI 2 "register_operand" "r"))))]
2635   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2636   "*
2638   /* Reload can create backwards (relative to cse) unscaled index
2639      address modes when eliminating registers and possibly for
2640      pseudos that don't get hard registers.  Deal with it.  */
2641   if (operands[2] == hard_frame_pointer_rtx
2642       || operands[2] == stack_pointer_rtx)
2643     return \"{fldwx|fldw} %1(%2),%0\";
2644   else
2645     return \"{fldwx|fldw} %2(%1),%0\";
2647   [(set_attr "type" "fpload")
2648    (set_attr "length" "4")])
2650 (define_insn ""
2651   [(set (match_operand:SF 0 "register_operand" "=fx")
2652         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2653                          (match_operand:SI 2 "basereg_operand" "r"))))]
2654   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2655   "*
2657   /* Reload can create backwards (relative to cse) unscaled index
2658      address modes when eliminating registers and possibly for
2659      pseudos that don't get hard registers.  Deal with it.  */
2660   if (operands[1] == hard_frame_pointer_rtx
2661       || operands[1] == stack_pointer_rtx)
2662     return \"{fldwx|fldw} %2(%1),%0\";
2663   else
2664     return \"{fldwx|fldw} %1(%2),%0\";
2666   [(set_attr "type" "fpload")
2667    (set_attr "length" "4")])
2669 (define_insn ""
2670   [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2671                          (match_operand:SI 2 "register_operand" "r")))
2672       (match_operand:SF 0 "register_operand" "fx"))]
2673   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2674   "*
2676   /* Reload can create backwards (relative to cse) unscaled index
2677      address modes when eliminating registers and possibly for
2678      pseudos that don't get hard registers.  Deal with it.  */
2679   if (operands[2] == hard_frame_pointer_rtx
2680       || operands[2] == stack_pointer_rtx)
2681     return \"{fstwx|fstw} %0,%1(%2)\";
2682   else
2683     return \"{fstwx|fstw} %0,%2(%1)\";
2685   [(set_attr "type" "fpstore")
2686    (set_attr "length" "4")])
2688 (define_insn ""
2689   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2690                          (match_operand:SI 2 "basereg_operand" "r")))
2691       (match_operand:SF 0 "register_operand" "fx"))]
2692   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2693   "*
2695   /* Reload can create backwards (relative to cse) unscaled index
2696      address modes when eliminating registers and possibly for
2697      pseudos that don't get hard registers.  Deal with it.  */
2698   if (operands[1] == hard_frame_pointer_rtx
2699       || operands[1] == stack_pointer_rtx)
2700     return \"{fstwx|fstw} %0,%2(%1)\";
2701   else
2702     return \"{fstwx|fstw} %0,%1(%2)\";
2704   [(set_attr "type" "fpstore")
2705    (set_attr "length" "4")])
2708 ;;- zero extension instructions
2709 ;; We have define_expand for zero extension patterns to make sure the
2710 ;; operands get loaded into registers.  The define_insns accept
2711 ;; memory operands.  This gives us better overall code than just
2712 ;; having a pattern that does or does not accept memory operands.
2714 (define_expand "zero_extendhisi2"
2715   [(set (match_operand:SI 0 "register_operand" "")
2716         (zero_extend:SI
2717          (match_operand:HI 1 "register_operand" "")))]
2718   ""
2719   "")
2721 (define_insn ""
2722   [(set (match_operand:SI 0 "register_operand" "=r,r")
2723         (zero_extend:SI
2724          (match_operand:HI 1 "move_operand" "r,RQ")))]
2725   "GET_CODE (operands[1]) != CONST_INT"
2726   "@
2727    {extru|extrw,u} %1,31,16,%0
2728    ldh%M1 %1,%0"
2729   [(set_attr "type" "shift,load")
2730    (set_attr "length" "4,4")])
2732 (define_expand "zero_extendqihi2"
2733   [(set (match_operand:HI 0 "register_operand" "")
2734         (zero_extend:HI
2735          (match_operand:QI 1 "register_operand" "")))]
2736   ""
2737   "")
2739 (define_insn ""
2740   [(set (match_operand:HI 0 "register_operand" "=r,r")
2741         (zero_extend:HI
2742          (match_operand:QI 1 "move_operand" "r,RQ")))]
2743   "GET_CODE (operands[1]) != CONST_INT"
2744   "@
2745    {extru|extrw,u} %1,31,8,%0
2746    ldb%M1 %1,%0"
2747   [(set_attr "type" "shift,load")
2748    (set_attr "length" "4,4")])
2750 (define_expand "zero_extendqisi2"
2751   [(set (match_operand:SI 0 "register_operand" "")
2752         (zero_extend:SI
2753          (match_operand:QI 1 "register_operand" "")))]
2754   ""
2755   "")
2757 (define_insn ""
2758   [(set (match_operand:SI 0 "register_operand" "=r,r")
2759         (zero_extend:SI
2760          (match_operand:QI 1 "move_operand" "r,RQ")))]
2761   "GET_CODE (operands[1]) != CONST_INT"
2762   "@
2763    {extru|extrw,u} %1,31,8,%0
2764    ldb%M1 %1,%0"
2765   [(set_attr "type" "shift,load")
2766    (set_attr "length" "4,4")])
2768 ;;- sign extension instructions
2770 (define_insn "extendhisi2"
2771   [(set (match_operand:SI 0 "register_operand" "=r")
2772         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2773   ""
2774   "{extrs|extrw,s} %1,31,16,%0"
2775   [(set_attr "type" "shift")
2776    (set_attr "length" "4")])
2778 (define_insn "extendqihi2"
2779   [(set (match_operand:HI 0 "register_operand" "=r")
2780         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2781   ""
2782   "{extrs|extrw,s} %1,31,8,%0"
2783   [(set_attr "type" "shift") 
2784   (set_attr "length" "4")])
2786 (define_insn "extendqisi2"
2787   [(set (match_operand:SI 0 "register_operand" "=r")
2788         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2789   ""
2790   "{extrs|extrw,s} %1,31,8,%0"
2791   [(set_attr "type" "shift")
2792    (set_attr "length" "4")])
2794 ;; Conversions between float and double.
2796 (define_insn "extendsfdf2"
2797   [(set (match_operand:DF 0 "register_operand" "=f")
2798         (float_extend:DF
2799          (match_operand:SF 1 "register_operand" "f")))]
2800   "! TARGET_SOFT_FLOAT"
2801   "{fcnvff|fcnv},sgl,dbl %1,%0"
2802   [(set_attr "type" "fpalu")
2803    (set_attr "length" "4")])
2805 (define_insn "truncdfsf2"
2806   [(set (match_operand:SF 0 "register_operand" "=f")
2807         (float_truncate:SF
2808          (match_operand:DF 1 "register_operand" "f")))]
2809   "! TARGET_SOFT_FLOAT"
2810   "{fcnvff|fcnv},dbl,sgl %1,%0"
2811   [(set_attr "type" "fpalu")
2812    (set_attr "length" "4")])
2814 ;; Conversion between fixed point and floating point.
2815 ;; Note that among the fix-to-float insns
2816 ;; the ones that start with SImode come first.
2817 ;; That is so that an operand that is a CONST_INT
2818 ;; (and therefore lacks a specific machine mode).
2819 ;; will be recognized as SImode (which is always valid)
2820 ;; rather than as QImode or HImode.
2822 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
2823 ;; to be reloaded by putting the constant into memory.
2824 ;; It must come before the more general floatsisf2 pattern.
2825 (define_insn ""
2826   [(set (match_operand:SF 0 "register_operand" "=f")
2827         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
2828   "! TARGET_SOFT_FLOAT"
2829   "fldw%F1 %1,%0\;{fcnvxf,sgl,sgl|fcnv,w,sgl} %0,%0"
2830   [(set_attr "type" "fpalu")
2831    (set_attr "length" "8")])
2833 (define_insn "floatsisf2"
2834   [(set (match_operand:SF 0 "register_operand" "=f")
2835         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2836   "! TARGET_SOFT_FLOAT"
2837   "{fcnvxf,sgl,sgl|fcnv,w,sgl} %1,%0"
2838   [(set_attr "type" "fpalu")
2839    (set_attr "length" "4")])
2841 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
2842 ;; to be reloaded by putting the constant into memory.
2843 ;; It must come before the more general floatsidf2 pattern.
2844 (define_insn ""
2845   [(set (match_operand:DF 0 "register_operand" "=f")
2846         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
2847   "! TARGET_SOFT_FLOAT"
2848   "fldw%F1 %1,%0\;{fcnvxf,sgl,dbl|fcnv,w,dbl} %0,%0"
2849   [(set_attr "type" "fpalu")
2850    (set_attr "length" "8")])
2852 (define_insn "floatsidf2"
2853   [(set (match_operand:DF 0 "register_operand" "=f")
2854         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2855   "! TARGET_SOFT_FLOAT"
2856   "{fcnvxf,sgl,dbl|fcnv,w,dbl} %1,%0"
2857   [(set_attr "type" "fpalu")
2858    (set_attr "length" "4")])
2860 (define_expand "floatunssisf2"
2861   [(set (subreg:SI (match_dup 2) 1)
2862         (match_operand:SI 1 "register_operand" ""))
2863    (set (subreg:SI (match_dup 2) 0)
2864         (const_int 0))
2865    (set (match_operand:SF 0 "register_operand" "")
2866         (float:SF (match_dup 2)))]
2867   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2868   "
2870   if (TARGET_PA_20)
2871     {
2872       emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
2873       DONE;
2874     }
2875   operands[2] = gen_reg_rtx (DImode);
2878 (define_expand "floatunssidf2"
2879   [(set (subreg:SI (match_dup 2) 1)
2880         (match_operand:SI 1 "register_operand" ""))
2881    (set (subreg:SI (match_dup 2) 0)
2882         (const_int 0))
2883    (set (match_operand:DF 0 "register_operand" "")
2884         (float:DF (match_dup 2)))]
2885   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2886   "
2888   if (TARGET_PA_20)
2889     {
2890       emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
2891       DONE;
2892     }
2893   operands[2] = gen_reg_rtx (DImode);
2896 (define_insn "floatdisf2"
2897   [(set (match_operand:SF 0 "register_operand" "=f")
2898         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2899   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2900   "{fcnvxf,dbl,sgl|fcnv,dw,sgl} %1,%0"
2901   [(set_attr "type" "fpalu")
2902    (set_attr "length" "4")])
2904 (define_insn "floatdidf2"
2905   [(set (match_operand:DF 0 "register_operand" "=f")
2906         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2907   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2908   "{fcnvxf,dbl,dbl|fcnv,dw,dbl} %1,%0"
2909   [(set_attr "type" "fpalu")
2910    (set_attr "length" "4")])
2912 ;; Convert a float to an actual integer.
2913 ;; Truncation is performed as part of the conversion.
2915 (define_insn "fix_truncsfsi2"
2916   [(set (match_operand:SI 0 "register_operand" "=f")
2917         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2918   "! TARGET_SOFT_FLOAT"
2919   "{fcnvfxt,sgl,sgl|fcnv,t,sgl,w} %1,%0"
2920   [(set_attr "type" "fpalu")
2921    (set_attr "length" "4")])
2923 (define_insn "fix_truncdfsi2"
2924   [(set (match_operand:SI 0 "register_operand" "=f")
2925         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2926   "! TARGET_SOFT_FLOAT"
2927   "{fcnvfxt,dbl,sgl|fcnv,t,dbl,w} %1,%0"
2928   [(set_attr "type" "fpalu")
2929    (set_attr "length" "4")])
2931 (define_insn "fix_truncsfdi2"
2932   [(set (match_operand:DI 0 "register_operand" "=f")
2933         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2934   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2935   "{fcnvfxt,sgl,dbl|fcnv,t,sgl,dw} %1,%0"
2936   [(set_attr "type" "fpalu")
2937    (set_attr "length" "4")])
2939 (define_insn "fix_truncdfdi2"
2940   [(set (match_operand:DI 0 "register_operand" "=f")
2941         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2942   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT"
2943   "{fcnvfxt,dbl,dbl|fcnv,t,dbl,dw} %1,%0"
2944   [(set_attr "type" "fpalu")
2945    (set_attr "length" "4")])
2947 (define_insn "floatunssidf2_pa20"
2948   [(set (match_operand:DF 0 "register_operand" "=f")
2949         (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
2950   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2951   "fcnv,uw,dbl %1,%0"
2952   [(set_attr "type" "fpalu")
2953    (set_attr "length" "4")])
2955 (define_insn "floatunssisf2_pa20"
2956   [(set (match_operand:SF 0 "register_operand" "=f")
2957         (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
2958   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2959   "fcnv,uw,sgl %1,%0"
2960   [(set_attr "type" "fpalu")
2961    (set_attr "length" "4")])
2963 (define_insn "floatunsdisf2"
2964   [(set (match_operand:SF 0 "register_operand" "=f")
2965         (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
2966   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2967   "fcnv,udw,sgl %1,%0"
2968   [(set_attr "type" "fpalu")
2969    (set_attr "length" "4")])
2971 (define_insn "floatunsdidf2"
2972   [(set (match_operand:DF 0 "register_operand" "=f")
2973         (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
2974   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2975   "fcnv,udw,dbl %1,%0"
2976   [(set_attr "type" "fpalu")
2977    (set_attr "length" "4")])
2979 (define_insn "fixuns_truncsfsi2"
2980   [(set (match_operand:SI 0 "register_operand" "=f")
2981         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2982   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2983   "fcnv,t,sgl,uw %1,%0"
2984   [(set_attr "type" "fpalu")
2985    (set_attr "length" "4")])
2987 (define_insn "fixuns_truncdfsi2"
2988   [(set (match_operand:SI 0 "register_operand" "=f")
2989         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2990   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2991   "fcnv,t,dbl,uw %1,%0"
2992   [(set_attr "type" "fpalu")
2993    (set_attr "length" "4")])
2995 (define_insn "fixuns_truncsfdi2"
2996   [(set (match_operand:DI 0 "register_operand" "=f")
2997         (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2998   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
2999   "fcnv,t,sgl,udw %1,%0"
3000   [(set_attr "type" "fpalu")
3001    (set_attr "length" "4")])
3003 (define_insn "fixuns_truncdfdi2"
3004   [(set (match_operand:DI 0 "register_operand" "=f")
3005         (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
3006   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3007   "fcnv,t,dbl,udw %1,%0"
3008   [(set_attr "type" "fpalu")
3009    (set_attr "length" "4")])
3011 ;;- arithmetic instructions
3013 (define_expand "adddi3"
3014   [(set (match_operand:DI 0 "register_operand" "")
3015         (plus:DI (match_operand:DI 1 "register_operand" "")
3016                  (match_operand:DI 2 "arith11_operand" "")))]
3017   ""
3018   "")
3020 (define_insn ""
3021   [(set (match_operand:DI 0 "register_operand" "=r")
3022         (plus:DI (match_operand:DI 1 "register_operand" "%r")
3023                  (match_operand:DI 2 "arith11_operand" "rI")))]
3024   ""
3025   "*
3027   if (GET_CODE (operands[2]) == CONST_INT)
3028     {
3029       if (INTVAL (operands[2]) >= 0)
3030         return \"addi %2,%R1,%R0\;{addc|add,c} %1,%%r0,%0\";
3031       else
3032         return \"addi %2,%R1,%R0\;{subb|sub,b} %1,%%r0,%0\";
3033     }
3034   else
3035     return \"add %R2,%R1,%R0\;{addc|add,c} %2,%1,%0\";
3037   [(set_attr "type" "binary")
3038    (set_attr "length" "8")])
3040 (define_insn ""
3041   [(set (match_operand:SI 0 "register_operand" "=r")
3042         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3043                  (match_operand:SI 2 "register_operand" "r")))]
3044   ""
3045   "uaddcm %2,%1,%0"
3046   [(set_attr "type" "binary")
3047    (set_attr "length" "4")])
3049 ;; define_splits to optimize cases of adding a constant integer
3050 ;; to a register when the constant does not fit in 14 bits.  */
3051 (define_split
3052   [(set (match_operand:SI 0 "register_operand" "")
3053         (plus:SI (match_operand:SI 1 "register_operand" "")
3054                  (match_operand:SI 2 "const_int_operand" "")))
3055    (clobber (match_operand:SI 4 "register_operand" ""))]
3056   "! cint_ok_for_move (INTVAL (operands[2]))
3057    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
3058   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
3059    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
3060   "
3062   int val = INTVAL (operands[2]);
3063   int low = (val < 0) ? -0x2000 : 0x1fff;
3064   int rest = val - low;
3066   operands[2] = GEN_INT (rest);
3067   operands[3] = GEN_INT (low);
3070 (define_split
3071   [(set (match_operand:SI 0 "register_operand" "")
3072         (plus:SI (match_operand:SI 1 "register_operand" "")
3073                  (match_operand:SI 2 "const_int_operand" "")))
3074    (clobber (match_operand:SI 4 "register_operand" ""))]
3075   "! cint_ok_for_move (INTVAL (operands[2]))"
3076   [(set (match_dup 4) (match_dup 2))
3077    (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
3078                                (match_dup 1)))]
3079   "
3081   HOST_WIDE_INT intval = INTVAL (operands[2]);
3083   /* Try dividing the constant by 2, then 4, and finally 8 to see
3084      if we can get a constant which can be loaded into a register
3085      in a single instruction (cint_ok_for_move). 
3087      If that fails, try to negate the constant and subtract it
3088      from our input operand.  */
3089   if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
3090     {
3091       operands[2] = GEN_INT (intval / 2);
3092       operands[3] = GEN_INT (2);
3093     }
3094   else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
3095     {
3096       operands[2] = GEN_INT (intval / 4);
3097       operands[3] = GEN_INT (4);
3098     }
3099   else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
3100     {
3101       operands[2] = GEN_INT (intval / 8);
3102       operands[3] = GEN_INT (8);
3103     }
3104   else if (cint_ok_for_move (-intval))
3105     {
3106       emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
3107       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
3108       DONE;
3109     }
3110   else
3111     FAIL;
3114 (define_insn "addsi3"
3115   [(set (match_operand:SI 0 "register_operand" "=r,r")
3116         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3117                  (match_operand:SI 2 "arith_operand" "r,J")))]
3118   ""
3119   "@
3120    {addl|add,l} %1,%2,%0
3121    ldo %2(%1),%0"
3122   [(set_attr "type" "binary,binary")
3123    (set_attr "pa_combine_type" "addmove")
3124    (set_attr "length" "4,4")])
3126 (define_expand "subdi3"
3127   [(set (match_operand:DI 0 "register_operand" "")
3128         (minus:DI (match_operand:DI 1 "register_operand" "")
3129                   (match_operand:DI 2 "register_operand" "")))]
3130   ""
3131   "")
3133 (define_insn ""
3134   [(set (match_operand:DI 0 "register_operand" "=r")
3135         (minus:DI (match_operand:DI 1 "register_operand" "r")
3136                   (match_operand:DI 2 "register_operand" "r")))]
3137   ""
3138   "sub %R1,%R2,%R0\;{subb|sub,b} %1,%2,%0"
3139   [(set_attr "type" "binary")
3140   (set_attr "length" "8")])
3142 (define_expand "subsi3"
3143   [(set (match_operand:SI 0 "register_operand" "")
3144         (minus:SI (match_operand:SI 1 "arith11_operand" "")
3145                   (match_operand:SI 2 "register_operand" "")))]
3146   ""
3147   "")
3149 (define_insn ""
3150   [(set (match_operand:SI 0 "register_operand" "=r,r")
3151         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
3152                   (match_operand:SI 2 "register_operand" "r,r")))]
3153   "!TARGET_PA_20"
3154   "@
3155    sub %1,%2,%0
3156    subi %1,%2,%0"
3157   [(set_attr "type" "binary,binary")
3158    (set_attr "length" "4,4")])
3160 (define_insn ""
3161   [(set (match_operand:SI 0 "register_operand" "=r,r,q")
3162         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
3163                   (match_operand:SI 2 "register_operand" "r,r,r")))]
3164   "TARGET_PA_20"
3165   "@
3166    sub %1,%2,%0
3167    subi %1,%2,%0
3168    mtsarcm %2"
3169   [(set_attr "type" "binary,binary,move")
3170    (set_attr "length" "4,4,4")])
3172 ;; Clobbering a "register_operand" instead of a match_scratch
3173 ;; in operand3 of millicode calls avoids spilling %r1 and
3174 ;; produces better code.
3176 ;; The mulsi3 insns set up registers for the millicode call.
3177 (define_expand "mulsi3"
3178   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3179    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3180    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3181               (clobber (match_dup 3))
3182               (clobber (reg:SI 26))
3183               (clobber (reg:SI 25))
3184               (clobber (reg:SI 31))])
3185    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3186   ""
3187   "
3189   if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3190     {
3191       rtx scratch = gen_reg_rtx (DImode);
3192       operands[1] = force_reg (SImode, operands[1]);
3193       operands[2] = force_reg (SImode, operands[2]);
3194       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3195       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3196                               gen_rtx_SUBREG (SImode, scratch, 1)));
3197       DONE;
3198     }
3199   operands[3] = gen_reg_rtx (SImode);
3202 (define_insn "umulsidi3"
3203   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3204         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3205                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3206   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3207   "xmpyu %1,%2,%0"
3208   [(set_attr "type" "fpmuldbl")
3209    (set_attr "length" "4")])
3211 (define_insn ""
3212   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3213         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3214                  (match_operand:DI 2 "uint32_operand" "f")))]
3215   "TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3216   "xmpyu %1,%R2,%0"
3217   [(set_attr "type" "fpmuldbl")
3218    (set_attr "length" "4")])
3220 (define_insn ""
3221   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3222    (clobber (match_operand:SI 0 "register_operand" "=a"))
3223    (clobber (reg:SI 26))
3224    (clobber (reg:SI 25))
3225    (clobber (reg:SI 31))]
3226   ""
3227   "* return output_mul_insn (0, insn);"
3228   [(set_attr "type" "milli")
3229    (set (attr "length")
3230      (cond [
3231 ;; Target (or stub) within reach
3232             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3233                      (const_int 240000))
3234                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3235                      (const_int 0)))
3236             (const_int 4)
3238 ;; NO_SPACE_REGS
3239             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3240                 (const_int 0))
3241             (const_int 8)
3243 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3244 ;; same as NO_SPACE_REGS code
3245             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3246                      (const_int 0))
3247                  (eq (symbol_ref "flag_pic")
3248                      (const_int 0)))
3249             (const_int 8)]
3251 ;; Out of range and either PIC or PORTABLE_RUNTIME
3252           (const_int 24)))])
3254 ;;; Division and mod.
3255 (define_expand "divsi3"
3256   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3257    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3258    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
3259               (clobber (match_dup 3))
3260               (clobber (match_dup 4))
3261               (clobber (reg:SI 26))
3262               (clobber (reg:SI 25))
3263               (clobber (reg:SI 31))])
3264    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3265   ""
3266   "
3268   operands[3] = gen_reg_rtx (SImode);
3269   operands[4] = gen_reg_rtx (SImode);
3270   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
3271     DONE;
3274 (define_insn ""
3275   [(set (reg:SI 29)
3276         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3277    (clobber (match_operand:SI 1 "register_operand" "=a"))
3278    (clobber (match_operand:SI 2 "register_operand" "=&r"))
3279    (clobber (reg:SI 26))
3280    (clobber (reg:SI 25))
3281    (clobber (reg:SI 31))]
3282   ""
3283   "*
3284    return output_div_insn (operands, 0, insn);"
3285   [(set_attr "type" "milli")
3286    (set (attr "length")
3287      (cond [
3288 ;; Target (or stub) within reach
3289             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3290                      (const_int 240000))
3291                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3292                      (const_int 0)))
3293             (const_int 4)
3295 ;; NO_SPACE_REGS
3296             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3297                 (const_int 0))
3298             (const_int 8)
3300 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3301 ;; same as NO_SPACE_REGS code
3302             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3303                      (const_int 0))
3304                  (eq (symbol_ref "flag_pic")
3305                      (const_int 0)))
3306             (const_int 8)]
3308 ;; Out of range and either PIC or PORTABLE_RUNTIME
3309           (const_int 24)))])
3311 (define_expand "udivsi3"
3312   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3313    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3314    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
3315               (clobber (match_dup 3))
3316               (clobber (match_dup 4))
3317               (clobber (reg:SI 26))
3318               (clobber (reg:SI 25))
3319               (clobber (reg:SI 31))])
3320    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3321   ""
3322   "
3324   operands[3] = gen_reg_rtx (SImode);
3325   operands[4] = gen_reg_rtx (SImode);
3326   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
3327     DONE;
3330 (define_insn ""
3331   [(set (reg:SI 29)
3332         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3333    (clobber (match_operand:SI 1 "register_operand" "=a"))
3334    (clobber (match_operand:SI 2 "register_operand" "=&r"))
3335    (clobber (reg:SI 26))
3336    (clobber (reg:SI 25))
3337    (clobber (reg:SI 31))]
3338   ""
3339   "*
3340    return output_div_insn (operands, 1, insn);"
3341   [(set_attr "type" "milli")
3342    (set (attr "length")
3343      (cond [
3344 ;; Target (or stub) within reach
3345             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3346                      (const_int 240000))
3347                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3348                      (const_int 0)))
3349             (const_int 4)
3351 ;; NO_SPACE_REGS
3352             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3353                 (const_int 0))
3354             (const_int 8)
3356 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3357 ;; same as NO_SPACE_REGS code
3358             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3359                      (const_int 0))
3360                  (eq (symbol_ref "flag_pic")
3361                      (const_int 0)))
3362             (const_int 8)]
3364 ;; Out of range and either PIC or PORTABLE_RUNTIME
3365           (const_int 24)))])
3367 (define_expand "modsi3"
3368   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3369    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3370    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3371               (clobber (match_dup 3))
3372               (clobber (match_dup 4))
3373               (clobber (reg:SI 26))
3374               (clobber (reg:SI 25))
3375               (clobber (reg:SI 31))])
3376    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3377   ""
3378   "
3380   operands[4] = gen_reg_rtx (SImode);
3381   operands[3] = gen_reg_rtx (SImode);
3384 (define_insn ""
3385   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3386    (clobber (match_operand:SI 0 "register_operand" "=a"))
3387    (clobber (match_operand:SI 2 "register_operand" "=&r"))
3388    (clobber (reg:SI 26))
3389    (clobber (reg:SI 25))
3390    (clobber (reg:SI 31))]
3391   ""
3392   "*
3393   return output_mod_insn (0, insn);"
3394   [(set_attr "type" "milli")
3395    (set (attr "length")
3396      (cond [
3397 ;; Target (or stub) within reach
3398             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3399                      (const_int 240000))
3400                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3401                      (const_int 0)))
3402             (const_int 4)
3404 ;; NO_SPACE_REGS
3405             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3406                 (const_int 0))
3407             (const_int 8)
3409 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3410 ;; same as NO_SPACE_REGS code
3411             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3412                      (const_int 0))
3413                  (eq (symbol_ref "flag_pic")
3414                      (const_int 0)))
3415             (const_int 8)]
3417 ;; Out of range and either PIC or PORTABLE_RUNTIME
3418           (const_int 24)))])
3420 (define_expand "umodsi3"
3421   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3422    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3423    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3424               (clobber (match_dup 3))
3425               (clobber (match_dup 4))
3426               (clobber (reg:SI 26))
3427               (clobber (reg:SI 25))
3428               (clobber (reg:SI 31))])
3429    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3430   ""
3431   "
3433   operands[4] = gen_reg_rtx (SImode);
3434   operands[3] = gen_reg_rtx (SImode);
3437 (define_insn ""
3438   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3439    (clobber (match_operand:SI 0 "register_operand" "=a"))
3440    (clobber (match_operand:SI 2 "register_operand" "=&r"))
3441    (clobber (reg:SI 26))
3442    (clobber (reg:SI 25))
3443    (clobber (reg:SI 31))]
3444   ""
3445   "*
3446   return output_mod_insn (1, insn);"
3447   [(set_attr "type" "milli")
3448    (set (attr "length")
3449      (cond [
3450 ;; Target (or stub) within reach
3451             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3452                      (const_int 240000))
3453                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3454                      (const_int 0)))
3455             (const_int 4)
3457 ;; NO_SPACE_REGS
3458             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3459                 (const_int 0))
3460             (const_int 8)
3462 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3463 ;; same as NO_SPACE_REGS code
3464             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3465                      (const_int 0))
3466                  (eq (symbol_ref "flag_pic")
3467                      (const_int 0)))
3468             (const_int 8)]
3470 ;; Out of range and either PIC or PORTABLE_RUNTIME
3471           (const_int 24)))])
3473 ;;- and instructions
3474 ;; We define DImode `and` so with DImode `not` we can get
3475 ;; DImode `andn`.  Other combinations are possible.
3477 (define_expand "anddi3"
3478   [(set (match_operand:DI 0 "register_operand" "")
3479         (and:DI (match_operand:DI 1 "arith_double_operand" "")
3480                 (match_operand:DI 2 "arith_double_operand" "")))]
3481   ""
3482   "
3484   if (! register_operand (operands[1], DImode)
3485       || ! register_operand (operands[2], DImode))
3486     /* Let GCC break this into word-at-a-time operations.  */
3487     FAIL;
3490 (define_insn ""
3491   [(set (match_operand:DI 0 "register_operand" "=r")
3492         (and:DI (match_operand:DI 1 "register_operand" "%r")
3493                 (match_operand:DI 2 "register_operand" "r")))]
3494   ""
3495   "and %1,%2,%0\;and %R1,%R2,%R0"
3496   [(set_attr "type" "binary")
3497    (set_attr "length" "8")])
3499 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
3500 ; constant with ldil;ldo.
3501 (define_insn "andsi3"
3502   [(set (match_operand:SI 0 "register_operand" "=r,r")
3503         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
3504                 (match_operand:SI 2 "and_operand" "rO,P")))]
3505   ""
3506   "* return output_and (operands); "
3507   [(set_attr "type" "binary,shift")
3508    (set_attr "length" "4,4")])
3510 (define_insn ""
3511   [(set (match_operand:DI 0 "register_operand" "=r")
3512         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3513                 (match_operand:DI 2 "register_operand" "r")))]
3514   ""
3515   "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
3516   [(set_attr "type" "binary")
3517    (set_attr "length" "8")])
3519 (define_insn ""
3520   [(set (match_operand:SI 0 "register_operand" "=r")
3521         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3522                 (match_operand:SI 2 "register_operand" "r")))]
3523   ""
3524   "andcm %2,%1,%0"
3525   [(set_attr "type" "binary")
3526   (set_attr "length" "4")])
3528 (define_expand "iordi3"
3529   [(set (match_operand:DI 0 "register_operand" "")
3530         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3531                 (match_operand:DI 2 "arith_double_operand" "")))]
3532   ""
3533   "
3535   if (! register_operand (operands[1], DImode)
3536       || ! register_operand (operands[2], DImode))
3537     /* Let GCC break this into word-at-a-time operations.  */
3538     FAIL;
3541 (define_insn ""
3542   [(set (match_operand:DI 0 "register_operand" "=r")
3543         (ior:DI (match_operand:DI 1 "register_operand" "%r")
3544                 (match_operand:DI 2 "register_operand" "r")))]
3545   ""
3546   "or %1,%2,%0\;or %R1,%R2,%R0"
3547   [(set_attr "type" "binary")
3548    (set_attr "length" "8")])
3550 ;; Need a define_expand because we've run out of CONST_OK... characters.
3551 (define_expand "iorsi3"
3552   [(set (match_operand:SI 0 "register_operand" "")
3553         (ior:SI (match_operand:SI 1 "register_operand" "")
3554                 (match_operand:SI 2 "arith32_operand" "")))]
3555   ""
3556   "
3558   if (! (ior_operand (operands[2], SImode)
3559          || register_operand (operands[2], SImode)))
3560     operands[2] = force_reg (SImode, operands[2]);
3563 (define_insn ""
3564   [(set (match_operand:SI 0 "register_operand" "=r,r")
3565         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
3566                 (match_operand:SI 2 "ior_operand" "M,i")))]
3567   ""
3568   "* return output_ior (operands); "
3569   [(set_attr "type" "binary,shift")
3570    (set_attr "length" "4,4")])
3572 (define_insn ""
3573   [(set (match_operand:SI 0 "register_operand" "=r")
3574         (ior:SI (match_operand:SI 1 "register_operand" "%r")
3575                 (match_operand:SI 2 "register_operand" "r")))]
3576   ""
3577   "or %1,%2,%0"
3578   [(set_attr "type" "binary")
3579    (set_attr "length" "4")])
3581 (define_expand "xordi3"
3582   [(set (match_operand:DI 0 "register_operand" "")
3583         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3584                 (match_operand:DI 2 "arith_double_operand" "")))]
3585   ""
3586   "
3588   if (! register_operand (operands[1], DImode)
3589       || ! register_operand (operands[2], DImode))
3590     /* Let GCC break this into word-at-a-time operations.  */
3591     FAIL;
3594 (define_insn ""
3595   [(set (match_operand:DI 0 "register_operand" "=r")
3596         (xor:DI (match_operand:DI 1 "register_operand" "%r")
3597                 (match_operand:DI 2 "register_operand" "r")))]
3598   ""
3599   "xor %1,%2,%0\;xor %R1,%R2,%R0"
3600   [(set_attr "type" "binary")
3601    (set_attr "length" "8")])
3603 (define_insn "xorsi3"
3604   [(set (match_operand:SI 0 "register_operand" "=r")
3605         (xor:SI (match_operand:SI 1 "register_operand" "%r")
3606                 (match_operand:SI 2 "register_operand" "r")))]
3607   ""
3608   "xor %1,%2,%0"
3609   [(set_attr "type" "binary")
3610    (set_attr "length" "4")])
3612 (define_expand "negdi2"
3613   [(set (match_operand:DI 0 "register_operand" "")
3614         (neg:DI (match_operand:DI 1 "register_operand" "")))]
3615   ""
3616   "")
3618 (define_insn ""
3619   [(set (match_operand:DI 0 "register_operand" "=r")
3620         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
3621   ""
3622   "sub %%r0,%R1,%R0\;{subb|sub,b} %%r0,%1,%0"
3623   [(set_attr "type" "unary")
3624    (set_attr "length" "8")])
3626 (define_insn "negsi2"
3627   [(set (match_operand:SI 0 "register_operand" "=r")
3628         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3629   ""
3630   "sub %%r0,%1,%0"
3631   [(set_attr "type" "unary")
3632    (set_attr "length" "4")])
3634 (define_expand "one_cmpldi2"
3635   [(set (match_operand:DI 0 "register_operand" "")
3636         (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
3637   ""
3638   "
3640   if (! register_operand (operands[1], DImode))
3641     FAIL;
3644 (define_insn ""
3645   [(set (match_operand:DI 0 "register_operand" "=r")
3646         (not:DI (match_operand:DI 1 "register_operand" "r")))]
3647   ""
3648   "uaddcm %%r0,%1,%0\;uaddcm %%r0,%R1,%R0"
3649   [(set_attr "type" "unary")
3650    (set_attr "length" "8")])
3652 (define_insn "one_cmplsi2"
3653   [(set (match_operand:SI 0 "register_operand" "=r")
3654         (not:SI (match_operand:SI 1 "register_operand" "r")))]
3655   ""
3656   "uaddcm %%r0,%1,%0"
3657   [(set_attr "type" "unary")
3658    (set_attr "length" "4")])
3660 ;; Floating point arithmetic instructions.
3662 (define_insn "adddf3"
3663   [(set (match_operand:DF 0 "register_operand" "=f")
3664         (plus:DF (match_operand:DF 1 "register_operand" "f")
3665                  (match_operand:DF 2 "register_operand" "f")))]
3666   "! TARGET_SOFT_FLOAT"
3667   "fadd,dbl %1,%2,%0"
3668   [(set_attr "type" "fpalu")
3669    (set_attr "pa_combine_type" "faddsub")
3670    (set_attr "length" "4")])
3672 (define_insn "addsf3"
3673   [(set (match_operand:SF 0 "register_operand" "=f")
3674         (plus:SF (match_operand:SF 1 "register_operand" "f")
3675                  (match_operand:SF 2 "register_operand" "f")))]
3676   "! TARGET_SOFT_FLOAT"
3677   "fadd,sgl %1,%2,%0"
3678   [(set_attr "type" "fpalu")
3679    (set_attr "pa_combine_type" "faddsub")
3680    (set_attr "length" "4")])
3682 (define_insn "subdf3"
3683   [(set (match_operand:DF 0 "register_operand" "=f")
3684         (minus:DF (match_operand:DF 1 "register_operand" "f")
3685                   (match_operand:DF 2 "register_operand" "f")))]
3686   "! TARGET_SOFT_FLOAT"
3687   "fsub,dbl %1,%2,%0"
3688   [(set_attr "type" "fpalu")
3689    (set_attr "pa_combine_type" "faddsub")
3690    (set_attr "length" "4")])
3692 (define_insn "subsf3"
3693   [(set (match_operand:SF 0 "register_operand" "=f")
3694         (minus:SF (match_operand:SF 1 "register_operand" "f")
3695                   (match_operand:SF 2 "register_operand" "f")))]
3696   "! TARGET_SOFT_FLOAT"
3697   "fsub,sgl %1,%2,%0"
3698   [(set_attr "type" "fpalu")
3699    (set_attr "pa_combine_type" "faddsub")
3700    (set_attr "length" "4")])
3702 (define_insn "muldf3"
3703   [(set (match_operand:DF 0 "register_operand" "=f")
3704         (mult:DF (match_operand:DF 1 "register_operand" "f")
3705                  (match_operand:DF 2 "register_operand" "f")))]
3706   "! TARGET_SOFT_FLOAT"
3707   "fmpy,dbl %1,%2,%0"
3708   [(set_attr "type" "fpmuldbl")
3709    (set_attr "pa_combine_type" "fmpy")
3710    (set_attr "length" "4")])
3712 (define_insn "mulsf3"
3713   [(set (match_operand:SF 0 "register_operand" "=f")
3714         (mult:SF (match_operand:SF 1 "register_operand" "f")
3715                  (match_operand:SF 2 "register_operand" "f")))]
3716   "! TARGET_SOFT_FLOAT"
3717   "fmpy,sgl %1,%2,%0"
3718   [(set_attr "type" "fpmulsgl")
3719    (set_attr "pa_combine_type" "fmpy")
3720    (set_attr "length" "4")])
3722 (define_insn "divdf3"
3723   [(set (match_operand:DF 0 "register_operand" "=f")
3724         (div:DF (match_operand:DF 1 "register_operand" "f")
3725                 (match_operand:DF 2 "register_operand" "f")))]
3726   "! TARGET_SOFT_FLOAT"
3727   "fdiv,dbl %1,%2,%0"
3728   [(set_attr "type" "fpdivdbl")
3729    (set_attr "length" "4")])
3731 (define_insn "divsf3"
3732   [(set (match_operand:SF 0 "register_operand" "=f")
3733         (div:SF (match_operand:SF 1 "register_operand" "f")
3734                 (match_operand:SF 2 "register_operand" "f")))]
3735   "! TARGET_SOFT_FLOAT"
3736   "fdiv,sgl %1,%2,%0"
3737   [(set_attr "type" "fpdivsgl")
3738    (set_attr "length" "4")])
3740 (define_insn "negdf2"
3741   [(set (match_operand:DF 0 "register_operand" "=f")
3742         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3743   "! TARGET_SOFT_FLOAT"
3744   "*
3746   if (TARGET_PA_20)
3747     return \"fneg,dbl %1,%0\";
3748   else
3749     return \"fsub,dbl %%fr0,%1,%0\";
3751   [(set_attr "type" "fpalu")
3752    (set_attr "length" "4")])
3754 (define_insn "negsf2"
3755   [(set (match_operand:SF 0 "register_operand" "=f")
3756         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3757   "! TARGET_SOFT_FLOAT"
3758   "*
3760   if (TARGET_PA_20)
3761     return \"fneg,sgl %1,%0\";
3762   else
3763     return \"fsub,sgl %%fr0,%1,%0\";
3765   [(set_attr "type" "fpalu")
3766    (set_attr "length" "4")])
3768 (define_insn "absdf2"
3769   [(set (match_operand:DF 0 "register_operand" "=f")
3770         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3771   "! TARGET_SOFT_FLOAT"
3772   "fabs,dbl %1,%0"
3773   [(set_attr "type" "fpalu")
3774    (set_attr "length" "4")])
3776 (define_insn "abssf2"
3777   [(set (match_operand:SF 0 "register_operand" "=f")
3778         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3779   "! TARGET_SOFT_FLOAT"
3780   "fabs,sgl %1,%0"
3781   [(set_attr "type" "fpalu")
3782    (set_attr "length" "4")])
3784 (define_insn "sqrtdf2"
3785   [(set (match_operand:DF 0 "register_operand" "=f")
3786         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3787   "! TARGET_SOFT_FLOAT"
3788   "fsqrt,dbl %1,%0"
3789   [(set_attr "type" "fpsqrtdbl")
3790    (set_attr "length" "4")])
3792 (define_insn "sqrtsf2"
3793   [(set (match_operand:SF 0 "register_operand" "=f")
3794         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3795   "! TARGET_SOFT_FLOAT"
3796   "fsqrt,sgl %1,%0"
3797   [(set_attr "type" "fpsqrtsgl")
3798    (set_attr "length" "4")])
3800 ;; PA 2.0 floating point instructions
3802 ; fmpyfadd patterns
3803 (define_insn ""
3804   [(set (match_operand:DF 0 "register_operand" "=f")
3805         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3806                           (match_operand:DF 2 "register_operand" "f"))
3807                  (match_operand:DF 3 "register_operand" "f")))]
3808   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3809   "fmpyfadd,dbl %1,%2,%3,%0"
3810   [(set_attr "type" "fpmuldbl")
3811    (set_attr "length" "4")])
3813 (define_insn ""
3814   [(set (match_operand:DF 0 "register_operand" "=f")
3815         (plus:DF (match_operand:DF 1 "register_operand" "f")
3816                  (mult:DF (match_operand:DF 2 "register_operand" "f")
3817                           (match_operand:DF 3 "register_operand" "f"))))]
3818   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3819   "fmpyfadd,dbl %2,%3,%1,%0"
3820   [(set_attr "type" "fpmuldbl")
3821    (set_attr "length" "4")])
3823 (define_insn ""
3824   [(set (match_operand:SF 0 "register_operand" "=f")
3825         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3826                           (match_operand:SF 2 "register_operand" "f"))
3827                  (match_operand:SF 3 "register_operand" "f")))]
3828   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3829   "fmpyfadd,sgl %1,%2,%3,%0"
3830   [(set_attr "type" "fpmulsgl")
3831    (set_attr "length" "4")])
3833 (define_insn ""
3834   [(set (match_operand:SF 0 "register_operand" "=f")
3835         (plus:SF (match_operand:SF 1 "register_operand" "f")
3836                  (mult:SF (match_operand:SF 2 "register_operand" "f")
3837                           (match_operand:SF 3 "register_operand" "f"))))]
3838   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3839   "fmpyfadd,sgl %2,%3,%1,%0"
3840   [(set_attr "type" "fpmulsgl")
3841    (set_attr "length" "4")])
3843 ; fmpynfadd patterns
3844 (define_insn ""
3845   [(set (match_operand:DF 0 "register_operand" "=f")
3846         (minus:DF (match_operand:DF 1 "register_operand" "f")
3847                   (mult:DF (match_operand:DF 2 "register_operand" "f")
3848                            (match_operand:DF 3 "register_operand" "f"))))]
3849   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3850   "fmpynfadd,dbl %2,%3,%1,%0"
3851   [(set_attr "type" "fpmuldbl")
3852    (set_attr "length" "4")])
3854 (define_insn ""
3855   [(set (match_operand:SF 0 "register_operand" "=f")
3856         (minus:SF (match_operand:SF 1 "register_operand" "f")
3857                   (mult:SF (match_operand:SF 2 "register_operand" "f")
3858                            (match_operand:SF 3 "register_operand" "f"))))]
3859   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3860   "fmpynfadd,sgl %2,%3,%1,%0"
3861   [(set_attr "type" "fpmulsgl")
3862    (set_attr "length" "4")])
3864 ; fnegabs patterns
3865 (define_insn ""
3866   [(set (match_operand:DF 0 "register_operand" "=f")
3867         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
3868   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3869   "fnegabs,dbl %1,%0"
3870   [(set_attr "type" "fpalu")
3871    (set_attr "length" "4")])
3873 (define_insn ""
3874   [(set (match_operand:SF 0 "register_operand" "=f")
3875         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
3876   "TARGET_PA_20 && ! TARGET_SOFT_FLOAT"
3877   "fnegabs,sgl %1,%0"
3878   [(set_attr "type" "fpalu")
3879    (set_attr "length" "4")])
3881 ;; Generating a fused multiply sequence is a win for this case as it will
3882 ;; reduce the latency for the fused case without impacting the plain
3883 ;; multiply case.
3885 ;; Similar possibilities exist for fnegabs, shadd and other insns which
3886 ;; perform two operations with the result of the first feeding the second.
3887 (define_insn ""
3888   [(set (match_operand:DF 0 "register_operand" "=f")
3889         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3890                           (match_operand:DF 2 "register_operand" "f"))
3891                  (match_operand:DF 3 "register_operand" "f")))
3892    (set (match_operand:DF 4 "register_operand" "=&f")
3893         (mult:DF (match_dup 1) (match_dup 2)))]
3894   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3895     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
3896           || reg_overlap_mentioned_p (operands[4], operands[2])))"
3897   "#"
3898   [(set_attr "type" "fpmuldbl")
3899    (set_attr "length" "8")])
3901 ;; We want to split this up during scheduling since we want both insns
3902 ;; to schedule independently.
3903 (define_split
3904   [(set (match_operand:DF 0 "register_operand" "=f")
3905         (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3906                           (match_operand:DF 2 "register_operand" "f"))
3907                  (match_operand:DF 3 "register_operand" "f")))
3908    (set (match_operand:DF 4 "register_operand" "=&f")
3909         (mult:DF (match_dup 1) (match_dup 2)))]
3910   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3911   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
3912    (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
3913                                (match_dup 3)))]
3914   "")
3916 (define_insn ""
3917   [(set (match_operand:SF 0 "register_operand" "=f")
3918         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3919                           (match_operand:SF 2 "register_operand" "f"))
3920                  (match_operand:SF 3 "register_operand" "f")))
3921    (set (match_operand:SF 4 "register_operand" "=&f")
3922         (mult:SF (match_dup 1) (match_dup 2)))]
3923   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3924     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
3925           || reg_overlap_mentioned_p (operands[4], operands[2])))"
3926   "#"
3927   [(set_attr "type" "fpmuldbl")
3928    (set_attr "length" "8")])
3930 ;; We want to split this up during scheduling since we want both insns
3931 ;; to schedule independently.
3932 (define_split
3933   [(set (match_operand:SF 0 "register_operand" "=f")
3934         (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3935                           (match_operand:SF 2 "register_operand" "f"))
3936                  (match_operand:SF 3 "register_operand" "f")))
3937    (set (match_operand:SF 4 "register_operand" "=&f")
3938         (mult:SF (match_dup 1) (match_dup 2)))]
3939   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3940   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
3941    (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
3942                                (match_dup 3)))]
3943   "")
3945 ;; Negating a multiply can be faked by adding zero in a fused multiply-add
3946 ;; instruction.
3947 (define_insn ""
3948   [(set (match_operand:DF 0 "register_operand" "=f")
3949         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3950                          (match_operand:DF 2 "register_operand" "f"))))]
3951   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3952   "fmpynfadd,dbl %1,%2,%%fr0,%0"
3953   [(set_attr "type" "fpmuldbl")
3954    (set_attr "length" "4")])
3956 (define_insn ""
3957   [(set (match_operand:SF 0 "register_operand" "=f")
3958         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3959                          (match_operand:SF 2 "register_operand" "f"))))]
3960   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3961   "fmpynfadd,sgl %1,%2,%%fr0,%0"
3962   [(set_attr "type" "fpmuldbl")
3963    (set_attr "length" "4")])
3965 (define_insn ""
3966   [(set (match_operand:DF 0 "register_operand" "=f")
3967         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3968                          (match_operand:DF 2 "register_operand" "f"))))
3969    (set (match_operand:DF 3 "register_operand" "=&f")
3970         (mult:DF (match_dup 1) (match_dup 2)))]
3971   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3972     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
3973           || reg_overlap_mentioned_p (operands[3], operands[2])))"
3974   "#"
3975   [(set_attr "type" "fpmuldbl")
3976    (set_attr "length" "8")])
3978 (define_split
3979   [(set (match_operand:DF 0 "register_operand" "=f")
3980         (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
3981                          (match_operand:DF 2 "register_operand" "f"))))
3982    (set (match_operand:DF 3 "register_operand" "=&f")
3983         (mult:DF (match_dup 1) (match_dup 2)))]
3984   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
3985   [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
3986    (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
3987   "")
3989 (define_insn ""
3990   [(set (match_operand:SF 0 "register_operand" "=f")
3991         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
3992                          (match_operand:SF 2 "register_operand" "f"))))
3993    (set (match_operand:SF 3 "register_operand" "=&f")
3994         (mult:SF (match_dup 1) (match_dup 2)))]
3995   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
3996     && ! (reg_overlap_mentioned_p (operands[3], operands[1])
3997           || reg_overlap_mentioned_p (operands[3], operands[2])))"
3998   "#"
3999   [(set_attr "type" "fpmuldbl")
4000    (set_attr "length" "8")])
4002 (define_split
4003   [(set (match_operand:SF 0 "register_operand" "=f")
4004         (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4005                          (match_operand:SF 2 "register_operand" "f"))))
4006    (set (match_operand:SF 3 "register_operand" "=&f")
4007         (mult:SF (match_dup 1) (match_dup 2)))]
4008   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4009   [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
4010    (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
4011   "")
4013 ;; Now fused multiplies with the result of the multiply negated.
4014 (define_insn ""
4015   [(set (match_operand:DF 0 "register_operand" "=f")
4016         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4017                                   (match_operand:DF 2 "register_operand" "f")))
4018                  (match_operand:DF 3 "register_operand" "f")))]
4019   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4020   "fmpynfadd,dbl %1,%2,%3,%0"
4021   [(set_attr "type" "fpmuldbl")
4022    (set_attr "length" "4")])
4024 (define_insn ""
4025   [(set (match_operand:SF 0 "register_operand" "=f")
4026         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4027                          (match_operand:SF 2 "register_operand" "f")))
4028                  (match_operand:SF 3 "register_operand" "f")))]
4029   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4030   "fmpynfadd,sgl %1,%2,%3,%0"
4031   [(set_attr "type" "fpmuldbl")
4032    (set_attr "length" "4")])
4034 (define_insn ""
4035   [(set (match_operand:DF 0 "register_operand" "=f")
4036         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4037                                   (match_operand:DF 2 "register_operand" "f")))
4038                  (match_operand:DF 3 "register_operand" "f")))
4039    (set (match_operand:DF 4 "register_operand" "=&f")
4040         (mult:DF (match_dup 1) (match_dup 2)))]
4041   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4042     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4043           || reg_overlap_mentioned_p (operands[4], operands[2])))"
4044   "#"
4045   [(set_attr "type" "fpmuldbl")
4046    (set_attr "length" "8")])
4048 (define_split
4049   [(set (match_operand:DF 0 "register_operand" "=f")
4050         (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
4051                                   (match_operand:DF 2 "register_operand" "f")))
4052                  (match_operand:DF 3 "register_operand" "f")))
4053    (set (match_operand:DF 4 "register_operand" "=&f")
4054         (mult:DF (match_dup 1) (match_dup 2)))]
4055   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4056   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4057    (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
4058                                (match_dup 3)))]
4059   "")
4061 (define_insn ""
4062   [(set (match_operand:SF 0 "register_operand" "=f")
4063         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4064                                   (match_operand:SF 2 "register_operand" "f")))
4065                  (match_operand:SF 3 "register_operand" "f")))
4066    (set (match_operand:SF 4 "register_operand" "=&f")
4067         (mult:SF (match_dup 1) (match_dup 2)))]
4068   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4069     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4070           || reg_overlap_mentioned_p (operands[4], operands[2])))"
4071   "#"
4072   [(set_attr "type" "fpmuldbl")
4073    (set_attr "length" "8")])
4075 (define_split
4076   [(set (match_operand:SF 0 "register_operand" "=f")
4077         (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
4078                                   (match_operand:SF 2 "register_operand" "f")))
4079                  (match_operand:SF 3 "register_operand" "f")))
4080    (set (match_operand:SF 4 "register_operand" "=&f")
4081         (mult:SF (match_dup 1) (match_dup 2)))]
4082   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4083   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4084    (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
4085                                (match_dup 3)))]
4086   "")
4088 (define_insn ""
4089   [(set (match_operand:DF 0 "register_operand" "=f")
4090         (minus:DF (match_operand:DF 3 "register_operand" "f")
4091                   (mult:DF (match_operand:DF 1 "register_operand" "f")
4092                            (match_operand:DF 2 "register_operand" "f"))))
4093    (set (match_operand:DF 4 "register_operand" "=&f")
4094         (mult:DF (match_dup 1) (match_dup 2)))]
4095   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4096     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4097           || reg_overlap_mentioned_p (operands[4], operands[2])))"
4098   "#"
4099   [(set_attr "type" "fpmuldbl")
4100    (set_attr "length" "8")])
4102 (define_split
4103   [(set (match_operand:DF 0 "register_operand" "=f")
4104         (minus:DF (match_operand:DF 3 "register_operand" "f")
4105                   (mult:DF (match_operand:DF 1 "register_operand" "f")
4106                            (match_operand:DF 2 "register_operand" "f"))))
4107    (set (match_operand:DF 4 "register_operand" "=&f")
4108         (mult:DF (match_dup 1) (match_dup 2)))]
4109   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4110   [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
4111    (set (match_dup 0) (minus:DF (match_dup 3)
4112                                 (mult:DF (match_dup 1) (match_dup 2))))]
4113   "")
4115 (define_insn ""
4116   [(set (match_operand:SF 0 "register_operand" "=f")
4117         (minus:SF (match_operand:SF 3 "register_operand" "f")
4118                   (mult:SF (match_operand:SF 1 "register_operand" "f")
4119                            (match_operand:SF 2 "register_operand" "f"))))
4120    (set (match_operand:SF 4 "register_operand" "=&f")
4121         (mult:SF (match_dup 1) (match_dup 2)))]
4122   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4123     && ! (reg_overlap_mentioned_p (operands[4], operands[1])
4124           || reg_overlap_mentioned_p (operands[4], operands[2])))"
4125   "#"
4126   [(set_attr "type" "fpmuldbl")
4127    (set_attr "length" "8")])
4129 (define_split
4130   [(set (match_operand:SF 0 "register_operand" "=f")
4131         (minus:SF (match_operand:SF 3 "register_operand" "f")
4132                   (mult:SF (match_operand:SF 1 "register_operand" "f")
4133                            (match_operand:SF 2 "register_operand" "f"))))
4134    (set (match_operand:SF 4 "register_operand" "=&f")
4135         (mult:SF (match_dup 1) (match_dup 2)))]
4136   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4137   [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
4138    (set (match_dup 0) (minus:SF (match_dup 3)
4139                                 (mult:SF (match_dup 1) (match_dup 2))))]
4140   "")
4142 (define_insn ""
4143   [(set (match_operand:DF 0 "register_operand" "=f")
4144         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
4145    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
4146   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4147     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
4148   "#"
4149   [(set_attr "type" "fpalu")
4150    (set_attr "length" "8")])
4152 (define_split
4153   [(set (match_operand:DF 0 "register_operand" "=f")
4154         (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
4155    (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
4156   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4157   [(set (match_dup 2) (abs:DF (match_dup 1)))
4158    (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
4159   "")
4161 (define_insn ""
4162   [(set (match_operand:SF 0 "register_operand" "=f")
4163         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
4164    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
4165   "(! TARGET_SOFT_FLOAT && TARGET_PA_20
4166     && ! reg_overlap_mentioned_p (operands[2], operands[1]))"
4167   "#"
4168   [(set_attr "type" "fpalu")
4169    (set_attr "length" "8")])
4171 (define_split
4172   [(set (match_operand:SF 0 "register_operand" "=f")
4173         (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
4174    (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
4175   "! TARGET_SOFT_FLOAT && TARGET_PA_20"
4176   [(set (match_dup 2) (abs:SF (match_dup 1)))
4177    (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
4178   "")
4180 ;;- Shift instructions
4182 ;; Optimized special case of shifting.
4184 (define_insn ""
4185   [(set (match_operand:SI 0 "register_operand" "=r")
4186         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4187                      (const_int 24)))]
4188   ""
4189   "ldb%M1 %1,%0"
4190   [(set_attr "type" "load")
4191    (set_attr "length" "4")])
4193 (define_insn ""
4194   [(set (match_operand:SI 0 "register_operand" "=r")
4195         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
4196                      (const_int 16)))]
4197   ""
4198   "ldh%M1 %1,%0"
4199   [(set_attr "type" "load")
4200    (set_attr "length" "4")])
4202 (define_insn ""
4203   [(set (match_operand:SI 0 "register_operand" "=r")
4204         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4205                           (match_operand:SI 3 "shadd_operand" ""))
4206                  (match_operand:SI 1 "register_operand" "r")))]
4207   ""
4208   "{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0} "
4209   [(set_attr "type" "binary")
4210    (set_attr "length" "4")])
4212 ;; This anonymous pattern and splitter wins because it reduces the latency
4213 ;; of the shadd sequence without increasing the latency of the shift.
4215 ;; We want to make sure and split up the operations for the scheduler since
4216 ;; these instructions can (and should) schedule independently.
4218 ;; It would be clearer if combine used the same operator for both expressions,
4219 ;; it's somewhat confusing to have a mult in ine operation and an ashift
4220 ;; in the other.
4222 ;; If this pattern is not split before register allocation, then we must expose
4223 ;; the fact that operand 4 is set before operands 1, 2 and 3 have been read.
4224 (define_insn ""
4225   [(set (match_operand:SI 0 "register_operand" "=r")
4226         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4227                           (match_operand:SI 3 "shadd_operand" ""))
4228                  (match_operand:SI 1 "register_operand" "r")))
4229    (set (match_operand:SI 4 "register_operand" "=&r")
4230         (ashift:SI (match_dup 2)
4231                    (match_operand:SI 5 "const_int_operand" "i")))]
4232   "(INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))
4233     && ! (reg_overlap_mentioned_p (operands[4], operands[2])))"
4234   "#"
4235   [(set_attr "type" "binary")
4236    (set_attr "length" "8")])
4238 (define_split
4239   [(set (match_operand:SI 0 "register_operand" "=r")
4240         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
4241                           (match_operand:SI 3 "shadd_operand" ""))
4242                  (match_operand:SI 1 "register_operand" "r")))
4243    (set (match_operand:SI 4 "register_operand" "=&r")
4244         (ashift:SI (match_dup 2)
4245                    (match_operand:SI 5 "const_int_operand" "i")))]
4246   "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
4247   [(set (match_dup 4) (ashift:SI (match_dup 2) (match_dup 5)))
4248    (set (match_dup 0) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
4249                                (match_dup 1)))]
4250   "")
4252 (define_expand "ashlsi3"
4253   [(set (match_operand:SI 0 "register_operand" "")
4254         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
4255                    (match_operand:SI 2 "arith32_operand" "")))]
4256   ""
4257   "
4259   if (GET_CODE (operands[2]) != CONST_INT)
4260     {
4261       rtx temp = gen_reg_rtx (SImode);
4262       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
4263       if (GET_CODE (operands[1]) == CONST_INT)
4264         emit_insn (gen_zvdep_imm32 (operands[0], operands[1], temp));
4265       else
4266         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
4267       DONE;
4268     }
4269   /* Make sure both inputs are not constants,
4270      there are no patterns for that.  */
4271   operands[1] = force_reg (SImode, operands[1]);
4274 (define_insn ""
4275   [(set (match_operand:SI 0 "register_operand" "=r")
4276         (ashift:SI (match_operand:SI 1 "register_operand" "r")
4277                    (match_operand:SI 2 "const_int_operand" "n")))]
4278   ""
4279   "{zdep|depw,z} %1,%P2,%L2,%0"
4280   [(set_attr "type" "shift")
4281    (set_attr "length" "4")])
4283 ; Match cases of op1 a CONST_INT here that zvdep_imm32 doesn't handle.
4284 ; Doing it like this makes slightly better code since reload can
4285 ; replace a register with a known value in range -16..15 with a
4286 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm32,
4287 ; but since we have no more CONST_OK... characters, that is not
4288 ; possible.
4289 (define_insn "zvdep32"
4290   [(set (match_operand:SI 0 "register_operand" "=r,r")
4291         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
4292                    (minus:SI (const_int 31)
4293                              (match_operand:SI 2 "register_operand" "q,q"))))]
4294   ""
4295   "@
4296    {zvdep %1,32,%0|depw,z %1,%%sar,32,%0}
4297    {zvdepi %1,32,%0|depwi,z %1,%%sar,32,%0}"
4298   [(set_attr "type" "shift,shift")
4299    (set_attr "length" "4,4")])
4301 (define_insn "zvdep_imm32"
4302   [(set (match_operand:SI 0 "register_operand" "=r")
4303         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
4304                    (minus:SI (const_int 31)
4305                              (match_operand:SI 2 "register_operand" "q"))))]
4306   ""
4307   "*
4309   int x = INTVAL (operands[1]);
4310   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
4311   operands[1] = GEN_INT ((x & 0xf) - 0x10);
4312   return \"{zvdepi %1,%2,%0|depwi,z %1,%%sar,%2,%0}\";
4314   [(set_attr "type" "shift")
4315    (set_attr "length" "4")])
4317 (define_insn "vdepi_ior"
4318   [(set (match_operand:SI 0 "register_operand" "=r")
4319         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
4320                            (minus:SI (const_int 31)
4321                                      (match_operand:SI 2 "register_operand" "q")))
4322                 (match_operand:SI 3 "register_operand" "0")))]
4323   ; accept ...0001...1, can this be generalized?
4324   "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
4325   "*
4327   int x = INTVAL (operands[1]);
4328   operands[2] = GEN_INT (exact_log2 (x + 1));
4329   return \"{vdepi -1,%2,%0|depwi -1,%%sar,%2,%0}\";
4331   [(set_attr "type" "shift")
4332    (set_attr "length" "4")])
4334 (define_insn "vdepi_and"
4335   [(set (match_operand:SI 0 "register_operand" "=r")
4336         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
4337                            (minus:SI (const_int 31)
4338                                      (match_operand:SI 2 "register_operand" "q")))
4339                 (match_operand:SI 3 "register_operand" "0")))]
4340   ; this can be generalized...!
4341   "INTVAL (operands[1]) == -2"
4342   "*
4344   int x = INTVAL (operands[1]);
4345   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
4346   return \"{vdepi 0,%2,%0|depwi 0,%%sar,%2,%0}\";
4348   [(set_attr "type" "shift")
4349    (set_attr "length" "4")])
4351 (define_expand "ashrsi3"
4352   [(set (match_operand:SI 0 "register_operand" "")
4353         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
4354                      (match_operand:SI 2 "arith32_operand" "")))]
4355   ""
4356   "
4358   if (GET_CODE (operands[2]) != CONST_INT)
4359     {
4360       rtx temp = gen_reg_rtx (SImode);
4361       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
4362       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
4363       DONE;
4364     }
4367 (define_insn ""
4368   [(set (match_operand:SI 0 "register_operand" "=r")
4369         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4370                      (match_operand:SI 2 "const_int_operand" "n")))]
4371   ""
4372   "{extrs|extrw,s} %1,%P2,%L2,%0"
4373   [(set_attr "type" "shift")
4374    (set_attr "length" "4")])
4376 (define_insn "vextrs32"
4377   [(set (match_operand:SI 0 "register_operand" "=r")
4378         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4379                      (minus:SI (const_int 31)
4380                                (match_operand:SI 2 "register_operand" "q"))))]
4381   ""
4382   "{vextrs %1,32,%0|extrw,s %1,%%sar,32,%0}"
4383   [(set_attr "type" "shift")
4384    (set_attr "length" "4")])
4386 (define_insn "lshrsi3"
4387   [(set (match_operand:SI 0 "register_operand" "=r,r")
4388         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
4389                      (match_operand:SI 2 "arith32_operand" "q,n")))]
4390   ""
4391   "@
4392    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
4393    {extru|extrw,u} %1,%P2,%L2,%0"
4394   [(set_attr "type" "shift")
4395    (set_attr "length" "4")])
4397 (define_insn "rotrsi3"
4398   [(set (match_operand:SI 0 "register_operand" "=r,r")
4399         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
4400                      (match_operand:SI 2 "arith32_operand" "q,n")))]
4401   ""
4402   "*
4404   if (GET_CODE (operands[2]) == CONST_INT)
4405     {
4406       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
4407       return \"{shd|shrpw} %1,%1,%2,%0\";
4408     }
4409   else
4410     return \"{vshd %1,%1,%0|shrpw %1,%1,%%sar,%0}\";
4412   [(set_attr "type" "shift")
4413    (set_attr "length" "4")])
4415 (define_expand "rotlsi3"
4416   [(set (match_operand:SI 0 "register_operand" "")
4417         (rotate:SI (match_operand:SI 1 "register_operand" "")
4418                    (match_operand:SI 2 "arith32_operand" "")))]
4419   ""
4420   "
4422   if (GET_CODE (operands[2]) != CONST_INT)
4423     {
4424       rtx temp = gen_reg_rtx (SImode);
4425       emit_insn (gen_subsi3 (temp, GEN_INT (32), operands[2]));
4426       emit_insn (gen_rotrsi3 (operands[0], operands[1], temp));
4427       DONE;
4428     }
4429   /* Else expand normally.  */
4432 (define_insn ""
4433   [(set (match_operand:SI 0 "register_operand" "=r")
4434         (rotate:SI (match_operand:SI 1 "register_operand" "r")
4435                    (match_operand:SI 2 "const_int_operand" "n")))]
4436   ""
4437   "*
4439   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
4440   return \"{shd|shrpw} %1,%1,%2,%0\";
4442   [(set_attr "type" "shift")
4443    (set_attr "length" "4")])
4445 (define_insn ""
4446   [(set (match_operand:SI 0 "register_operand" "=r")
4447         (match_operator:SI 5 "plus_xor_ior_operator"
4448           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
4449                       (match_operand:SI 3 "const_int_operand" "n"))
4450            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4451                         (match_operand:SI 4 "const_int_operand" "n"))]))]
4452   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
4453   "{shd|shrpw} %1,%2,%4,%0"
4454   [(set_attr "type" "shift")
4455    (set_attr "length" "4")])
4457 (define_insn ""
4458   [(set (match_operand:SI 0 "register_operand" "=r")
4459         (match_operator:SI 5 "plus_xor_ior_operator"
4460           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4461                         (match_operand:SI 4 "const_int_operand" "n"))
4462            (ashift:SI (match_operand:SI 1 "register_operand" "r")
4463                       (match_operand:SI 3 "const_int_operand" "n"))]))]
4464   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
4465   "{shd|shrpw} %1,%2,%4,%0"
4466   [(set_attr "type" "shift")
4467    (set_attr "length" "4")])
4469 (define_insn ""
4470   [(set (match_operand:SI 0 "register_operand" "=r")
4471         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4472                            (match_operand:SI 2 "const_int_operand" ""))
4473                 (match_operand:SI 3 "const_int_operand" "")))]
4474   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
4475   "*
4477   int cnt = INTVAL (operands[2]) & 31;
4478   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
4479   operands[2] = GEN_INT (31 - cnt);
4480   return \"{zdep|depw,z} %1,%2,%3,%0\";
4482   [(set_attr "type" "shift")
4483    (set_attr "length" "4")])
4485 ;; Unconditional and other jump instructions.
4487 (define_insn "return"
4488   [(return)]
4489   "hppa_can_use_return_insn_p ()"
4490   "*
4492   if (TARGET_PA_20)
4493     return \"bve%* (%%r2)\";
4494   return \"bv%* %%r0(%%r2)\";
4496   [(set_attr "type" "branch")
4497    (set_attr "length" "4")])
4499 ;; Use a different pattern for functions which have non-trivial
4500 ;; epilogues so as not to confuse jump and reorg.
4501 (define_insn "return_internal"
4502   [(use (reg:SI 2))
4503    (return)]
4504   ""
4505   "*
4507   if (TARGET_PA_20)
4508     return \"bve%* (%%r2)\";
4509   return \"bv%* %%r0(%%r2)\";
4511   [(set_attr "type" "branch")
4512    (set_attr "length" "4")])
4514 (define_expand "prologue"
4515   [(const_int 0)]
4516   ""
4517   "hppa_expand_prologue ();DONE;")
4519 (define_expand "epilogue"
4520   [(return)]
4521   ""
4522   "
4524   /* Try to use the trivial return first.  Else use the full
4525      epilogue.  */
4526   if (hppa_can_use_return_insn_p ())
4527    emit_jump_insn (gen_return ());
4528   else
4529     {
4530       hppa_expand_epilogue ();
4531       emit_jump_insn (gen_return_internal ());
4532     }
4533   DONE;
4536 ;; Special because we use the value placed in %r2 by the bl instruction
4537 ;; from within its delay slot to set the value for the 2nd parameter to
4538 ;; the call.
4539 (define_insn "call_profiler"
4540   [(unspec_volatile [(const_int 0)] 0)
4541    (use (match_operand:SI 0 "const_int_operand" ""))]
4542   ""
4543   "{bl|b,l} _mcount,%%r2\;ldo %0(%%r2),%%r25"
4544   [(set_attr "type" "multi")
4545    (set_attr "length" "8")])
4547 (define_insn "blockage"
4548   [(unspec_volatile [(const_int 2)] 0)]
4549   ""
4550   ""
4551   [(set_attr "length" "0")])
4553 (define_insn "jump"
4554   [(set (pc) (label_ref (match_operand 0 "" "")))]
4555   ""
4556   "*
4558   extern int optimize;
4560   if (GET_MODE (insn) == SImode)
4561     return \"b %l0%#\";
4563   /* An unconditional branch which can reach its target.  */
4564   if (get_attr_length (insn) != 24
4565       && get_attr_length (insn) != 16)
4566     return \"b%* %l0\";
4568   /* An unconditional branch which can not reach its target.
4570      We need to be able to use %r1 as a scratch register; however,
4571      we can never be sure whether or not it's got a live value in
4572      it.  Therefore, we must restore its original value after the
4573      jump.
4575      To make matters worse, we don't have a stack slot which we
4576      can always clobber.  sp-12/sp-16 shouldn't ever have a live
4577      value during a non-optimizing compilation, so we use those
4578      slots for now.  We don't support very long branches when
4579      optimizing -- they should be quite rare when optimizing.
4581      Really the way to go long term is a register scavenger; goto
4582      the target of the jump and find a register which we can use
4583      as a scratch to hold the value in %r1.  */
4585   /* We don't know how to register scavenge yet.  */
4586   if (optimize)
4587     abort ();
4589   /* First store %r1 into the stack.  */
4590   output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
4592   /* Now load the target address into %r1 and do an indirect jump
4593      to the value specified in %r1.  Be careful to generate PIC
4594      code as needed.  */
4595   if (flag_pic)
4596     {
4597       rtx xoperands[2];
4598       xoperands[0] = operands[0];
4599       xoperands[1] = gen_label_rtx ();
4601       output_asm_insn (\"{bl|b,l} .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\",
4602                        xoperands);
4603       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4604                                  CODE_LABEL_NUMBER (xoperands[1]));
4605       output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv %%r0(%%r1)\",
4606                        xoperands);
4607     }
4608   else
4609     output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
4611   /* And restore the value of %r1 in the delay slot.  We're not optimizing,
4612      so we know nothing else can be in the delay slot.  */
4613   return \"ldw -16(%%r30),%%r1\";
4615   [(set_attr "type" "uncond_branch")
4616    (set_attr "pa_combine_type" "uncond_branch")
4617    (set (attr "length")
4618     (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
4619            (if_then_else (lt (abs (minus (match_dup 0)
4620                                          (plus (pc) (const_int 8))))
4621                              (const_int 8184))
4622                          (const_int 4)
4623                          (const_int 8))
4624            (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
4625                (const_int 262100))
4626            (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
4627                          (const_int 16)
4628                          (const_int 24))]
4629           (const_int 4)))])
4631 ;; Subroutines of "casesi".
4632 ;; operand 0 is index
4633 ;; operand 1 is the minimum bound
4634 ;; operand 2 is the maximum bound - minimum bound + 1
4635 ;; operand 3 is CODE_LABEL for the table;
4636 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4638 (define_expand "casesi"
4639   [(match_operand:SI 0 "general_operand" "")
4640    (match_operand:SI 1 "const_int_operand" "")
4641    (match_operand:SI 2 "const_int_operand" "")
4642    (match_operand 3 "" "")
4643    (match_operand 4 "" "")]
4644   ""
4645   "
4647   if (GET_CODE (operands[0]) != REG)
4648     operands[0] = force_reg (SImode, operands[0]);
4650   if (operands[1] != const0_rtx)
4651     {
4652       rtx reg = gen_reg_rtx (SImode);
4654       operands[1] = GEN_INT (-INTVAL (operands[1]));
4655       if (!INT_14_BITS (operands[1]))
4656         operands[1] = force_reg (SImode, operands[1]);
4657       emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
4659       operands[0] = reg;
4660     }
4662   if (!INT_5_BITS (operands[2]))
4663     operands[2] = force_reg (SImode, operands[2]);
4665   emit_insn (gen_cmpsi (operands[0], operands[2]));
4666   emit_jump_insn (gen_bgtu (operands[4]));
4667   if (TARGET_BIG_SWITCH)
4668     {
4669       rtx temp = gen_reg_rtx (SImode);
4670       emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
4671       operands[0] = temp;
4672     }
4673   emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
4674   DONE;
4677 (define_insn "casesi0"
4678   [(set (pc) (plus:SI
4679                (mem:SI (plus:SI (pc)
4680                                 (match_operand:SI 0 "register_operand" "r")))
4681                (label_ref (match_operand 1 "" ""))))]
4682   ""
4683   "blr %0,%%r0\;nop"
4684   [(set_attr "type" "multi")
4685    (set_attr "length" "8")])
4687 ;; Need nops for the calls because execution is supposed to continue
4688 ;; past; we don't want to nullify an instruction that we need.
4689 ;;- jump to subroutine
4691 (define_expand "call"
4692   [(parallel [(call (match_operand:SI 0 "" "")
4693                     (match_operand 1 "" ""))
4694               (clobber (reg:SI 2))])]
4695   ""
4696   "
4698   rtx op;
4699   rtx call_insn;
4701   if (TARGET_PORTABLE_RUNTIME)
4702     op = force_reg (SImode, XEXP (operands[0], 0));
4703   else
4704     op = XEXP (operands[0], 0);
4706   /* Use two different patterns for calls to explicitly named functions
4707      and calls through function pointers.  This is necessary as these two
4708      types of calls use different calling conventions, and CSE might try
4709      to change the named call into an indirect call in some cases (using
4710      two patterns keeps CSE from performing this optimization).  */
4711   if (GET_CODE (op) == SYMBOL_REF)
4712     call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
4713   else
4714     {
4715       rtx tmpreg = gen_rtx_REG (word_mode, 22);
4716       emit_move_insn (tmpreg, force_reg (word_mode, op));
4717       call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
4718     }
4720   if (flag_pic)
4721     {
4722       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4723       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
4724                gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4726       /* After each call we must restore the PIC register, even if it
4727          doesn't appear to be used.
4729          This will set regs_ever_live for the callee saved register we
4730          stored the PIC register in.  */
4731       emit_move_insn (pic_offset_table_rtx,
4732                       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4733     }
4734   DONE;
4737 (define_insn "call_internal_symref"
4738   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
4739          (match_operand 1 "" "i"))
4740    (clobber (reg:SI 2))
4741    (use (const_int 0))]
4742   "! TARGET_PORTABLE_RUNTIME"
4743   "*
4745   output_arg_descriptor (insn);
4746   return output_call (insn, operands[0]);
4748   [(set_attr "type" "call")
4749    (set (attr "length")
4750 ;;       If we're sure that we can either reach the target or that the
4751 ;;       linker can use a long-branch stub, then the length is 4 bytes.
4753 ;;       For long-calls the length will be either 52 bytes (non-pic)
4754 ;;       or 68 bytes (pic).  */
4755 ;;       Else we have to use a long-call;
4756       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4757                         (const_int 240000))
4758                     (const_int 4)
4759                     (if_then_else (eq (symbol_ref "flag_pic")
4760                                       (const_int 0))
4761                                   (const_int 52)
4762                                   (const_int 68))))])
4764 (define_insn "call_internal_reg"
4765   [(call (mem:SI (reg:SI 22))
4766          (match_operand 0 "" "i"))
4767    (clobber (reg:SI 2))
4768    (use (const_int 1))]
4769   ""
4770   "*
4772   rtx xoperands[2];
4774   /* First the special case for kernels, level 0 systems, etc.  */
4775   if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4776     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4778   /* Now the normal case -- we can reach $$dyncall directly or
4779      we're sure that we can get there via a long-branch stub. 
4781      No need to check target flags as the length uniquely identifies
4782      the remaining cases.  */
4783   if (get_attr_length (insn) == 8)
4784     return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
4786   /* Long millicode call, but we are not generating PIC or portable runtime
4787      code.  */
4788   if (get_attr_length (insn) == 12)
4789     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4791   /* Long millicode call for portable runtime.  */
4792   if (get_attr_length (insn) == 20)
4793     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
4795   /* If we're generating PIC code.  */
4796   xoperands[0] = operands[0];
4797   xoperands[1] = gen_label_rtx ();
4798   output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
4799   output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4800   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4801                              CODE_LABEL_NUMBER (xoperands[1]));
4802   output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4803   output_asm_insn (\"blr %%r0,%%r2\", xoperands);
4804   output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
4805   return \"\";
4807   [(set_attr "type" "dyncall")
4808    (set (attr "length")
4809      (cond [
4810 ;; First NO_SPACE_REGS
4811             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4812                 (const_int 0))
4813             (const_int 8)
4815 ;; Target (or stub) within reach
4816             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4817                      (const_int 240000))
4818                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4819                      (const_int 0)))
4820             (const_int 8)
4822 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4823             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4824                      (const_int 0))
4825                  (eq (symbol_ref "flag_pic")
4826                      (const_int 0)))
4827             (const_int 12)
4829             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4830                 (const_int 0))
4831             (const_int 20)]
4833 ;; Out of range PIC case
4834           (const_int 24)))])
4836 (define_expand "call_value"
4837   [(parallel [(set (match_operand 0 "" "")
4838                    (call (match_operand:SI 1 "" "")
4839                          (match_operand 2 "" "")))
4840               (clobber (reg:SI 2))])]
4841   ""
4842   "
4844   rtx op;
4845   rtx call_insn;
4847   if (TARGET_PORTABLE_RUNTIME)
4848     op = force_reg (word_mode, XEXP (operands[1], 0));
4849   else
4850     op = XEXP (operands[1], 0);
4852   /* Use two different patterns for calls to explicitly named functions
4853      and calls through function pointers.  This is necessary as these two
4854      types of calls use different calling conventions, and CSE might try
4855      to change the named call into an indirect call in some cases (using
4856      two patterns keeps CSE from performing this optimization).  */
4857   if (GET_CODE (op) == SYMBOL_REF)
4858     call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
4859                                                                 op,
4860                                                                 operands[2]));
4861   else
4862     {
4863       rtx tmpreg = gen_rtx_REG (word_mode, 22);
4864       emit_move_insn (tmpreg, force_reg (word_mode, op));
4865       call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
4866                                                                operands[2]));
4867     }
4868   if (flag_pic)
4869     {
4870       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4871       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
4872                gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4874       /* After each call we must restore the PIC register, even if it
4875          doesn't appear to be used.
4877          This will set regs_ever_live for the callee saved register we
4878          stored the PIC register in.  */
4879       emit_move_insn (pic_offset_table_rtx,
4880                       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4881     }
4882   DONE;
4885 (define_insn "call_value_internal_symref"
4886   [(set (match_operand 0 "" "=rf")
4887         (call (mem:SI (match_operand 1 "call_operand_address" ""))
4888               (match_operand 2 "" "i")))
4889    (clobber (reg:SI 2))
4890    (use (const_int 0))]
4891   ;;- Don't use operand 1 for most machines.
4892   "! TARGET_PORTABLE_RUNTIME"
4893   "*
4895   output_arg_descriptor (insn);
4896   return output_call (insn, operands[1]);
4898   [(set_attr "type" "call")
4899    (set (attr "length")
4900 ;;       If we're sure that we can either reach the target or that the
4901 ;;       linker can use a long-branch stub, then the length is 4 bytes.
4903 ;;       For long-calls the length will be either 52 bytes (non-pic)
4904 ;;       or 68 bytes (pic).  */
4905 ;;       Else we have to use a long-call;
4906       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4907                         (const_int 240000))
4908                     (const_int 4)
4909                     (if_then_else (eq (symbol_ref "flag_pic")
4910                                       (const_int 0))
4911                                   (const_int 52)
4912                                   (const_int 68))))])
4914 (define_insn "call_value_internal_reg"
4915   [(set (match_operand 0 "" "=rf")
4916         (call (mem:SI (reg:SI 22))
4917               (match_operand 1 "" "i")))
4918    (clobber (reg:SI 2))
4919    (use (const_int 1))]
4920   ""
4921   "*
4923   rtx xoperands[2];
4925   /* First the special case for kernels, level 0 systems, etc.  */
4926   if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4927     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4929   /* Now the normal case -- we can reach $$dyncall directly or
4930      we're sure that we can get there via a long-branch stub. 
4932      No need to check target flags as the length uniquely identifies
4933      the remaining cases.  */
4934   if (get_attr_length (insn) == 8)
4935     return \".CALL\\tARGW0=GR\;{bl|b,l} $$dyncall,%%r31\;copy %%r31,%%r2\";
4937   /* Long millicode call, but we are not generating PIC or portable runtime
4938      code.  */
4939   if (get_attr_length (insn) == 12)
4940     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4942   /* Long millicode call for portable runtime.  */
4943   if (get_attr_length (insn) == 20)
4944     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr %%r0,%%r2\;bv,n %%r0(%%r31)\;nop\";
4946   /* If we're generating PIC code.  */
4947   xoperands[0] = operands[1];
4948   xoperands[1] = gen_label_rtx ();
4949   output_asm_insn (\"{bl|b,l} .+8,%%r1\", xoperands);
4950   output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4951   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4952                              CODE_LABEL_NUMBER (xoperands[1]));
4953   output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4954   output_asm_insn (\"blr %%r0,%%r2\", xoperands);
4955   output_asm_insn (\"bv,n %%r0(%%r1)\\n\\tnop\", xoperands);
4956   return \"\";
4958   [(set_attr "type" "dyncall")
4959    (set (attr "length")
4960      (cond [
4961 ;; First NO_SPACE_REGS
4962             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4963                 (const_int 0))
4964             (const_int 8)
4966 ;; Target (or stub) within reach
4967             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4968                      (const_int 240000))
4969                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4970                      (const_int 0)))
4971             (const_int 8)
4973 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4974             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4975                      (const_int 0))
4976                  (eq (symbol_ref "flag_pic")
4977                      (const_int 0)))
4978             (const_int 12)
4980             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4981                 (const_int 0))
4982             (const_int 20)]
4984 ;; Out of range PIC case
4985           (const_int 24)))])
4987 ;; Call subroutine returning any type.
4989 (define_expand "untyped_call"
4990   [(parallel [(call (match_operand 0 "" "")
4991                     (const_int 0))
4992               (match_operand 1 "" "")
4993               (match_operand 2 "" "")])]
4994   ""
4995   "
4997   int i;
4999   emit_call_insn (gen_call (operands[0], const0_rtx));
5001   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5002     {
5003       rtx set = XVECEXP (operands[2], 0, i);
5004       emit_move_insn (SET_DEST (set), SET_SRC (set));
5005     }
5007   /* The optimizer does not know that the call sets the function value
5008      registers we stored in the result block.  We avoid problems by
5009      claiming that all hard registers are used and clobbered at this
5010      point.  */
5011   emit_insn (gen_blockage ());
5013   DONE;
5015 (define_insn "nop"
5016   [(const_int 0)]
5017   ""
5018   "nop"
5019   [(set_attr "type" "move")
5020    (set_attr "length" "4")])
5022 ;; These are just placeholders so we know where branch tables
5023 ;; begin and end.
5024 (define_insn "begin_brtab"
5025   [(const_int 1)]
5026   ""
5027   "*
5029   /* Only GAS actually supports this pseudo-op.  */
5030   if (TARGET_GAS)
5031     return \".begin_brtab\";
5032   else
5033     return \"\";
5035   [(set_attr "type" "move")
5036    (set_attr "length" "0")])
5038 (define_insn "end_brtab"
5039   [(const_int 2)]
5040   ""
5041   "*
5043   /* Only GAS actually supports this pseudo-op.  */
5044   if (TARGET_GAS)
5045     return \".end_brtab\";
5046   else
5047     return \"\";
5049   [(set_attr "type" "move")
5050    (set_attr "length" "0")])
5052 ;;; Hope this is only within a function...
5053 (define_insn "indirect_jump"
5054   [(set (pc) (match_operand 0 "register_operand" "r"))]
5055   "GET_MODE (operands[0]) == word_mode"
5056   "bv%* %%r0(%0)"
5057   [(set_attr "type" "branch")
5058    (set_attr "length" "4")])
5060 ;;; EH does longjmp's from and within the data section.  Thus,
5061 ;;; an interspace branch is required for the longjmp implementation.
5062 ;;; Registers r1 and r2 are not saved in the jmpbuf environment.
5063 ;;; Thus, they can be used as scratch registers for the jump.
5064 (define_insn "interspace_jump"
5065   [(set (pc) (match_operand:SI 0 "register_operand" "a"))
5066   (clobber (reg:SI 2))]
5067   ""
5068   "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
5069    [(set_attr "type" "branch")
5070     (set_attr "length" "12")])
5072 (define_expand "builtin_longjmp"
5073   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
5074   ""
5075   "
5077   /* The elements of the buffer are, in order:  */
5078   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5079   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
5080   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5081   rtx pv = gen_rtx_REG (Pmode, 1);
5083   /* This bit is the same as expand_builtin_longjmp.  */
5084   emit_move_insn (hard_frame_pointer_rtx, fp);
5085   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5086   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5087   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5089   /* Load the label we are jumping through into r1 so that we know
5090      where to look for it when we get back to setjmp's function for
5091      restoring the gp.  */
5092   emit_move_insn (pv, lab);
5093   emit_jump_insn (gen_interspace_jump (pv));
5094   emit_barrier ();
5095   DONE;
5098 (define_expand "extzv"
5099   [(set (match_operand:SI 0 "register_operand" "")
5100         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5101                          (match_operand:SI 2 "uint5_operand" "")
5102                          (match_operand:SI 3 "uint5_operand" "")))]
5103   ""
5104   "
5106   if (! uint5_operand (operands[2], SImode)
5107       ||  ! uint5_operand (operands[3], SImode))
5108   FAIL;
5111 (define_insn ""
5112   [(set (match_operand:SI 0 "register_operand" "=r")
5113         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
5114                          (match_operand:SI 2 "uint5_operand" "")
5115                          (match_operand:SI 3 "uint5_operand" "")))]
5116   ""
5117   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
5118   [(set_attr "type" "shift")
5119    (set_attr "length" "4")])
5121 (define_insn ""
5122   [(set (match_operand:SI 0 "register_operand" "=r")
5123         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
5124                          (const_int 1)
5125                          (match_operand:SI 3 "register_operand" "q")))]
5126   ""
5127   "{vextru %1,1,%0|extrw,u %1,%%sar,1,%0}"
5128   [(set_attr "type" "shift")
5129    (set_attr "length" "4")])
5131 (define_expand "extv"
5132   [(set (match_operand:SI 0 "register_operand" "")
5133         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
5134                          (match_operand:SI 2 "uint5_operand" "")
5135                          (match_operand:SI 3 "uint5_operand" "")))]
5136   ""
5137   "
5139   if (! uint5_operand (operands[2], SImode)
5140       ||  ! uint5_operand (operands[3], SImode))
5141   FAIL;
5144 (define_insn ""
5145   [(set (match_operand:SI 0 "register_operand" "=r")
5146         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
5147                          (match_operand:SI 2 "uint5_operand" "")
5148                          (match_operand:SI 3 "uint5_operand" "")))]
5149   ""
5150   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
5151   [(set_attr "type" "shift")
5152    (set_attr "length" "4")])
5154 (define_insn ""
5155   [(set (match_operand:SI 0 "register_operand" "=r")
5156         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
5157                          (const_int 1)
5158                          (match_operand:SI 3 "register_operand" "q")))]
5159   ""
5160   "{vextrs %1,1,%0|extrw,s %1,%%sar,1,%0}"
5161   [(set_attr "type" "shift")
5162    (set_attr "length" "4")])
5164 (define_expand "insv"
5165   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5166                          (match_operand:SI 1 "uint5_operand" "")
5167                          (match_operand:SI 2 "uint5_operand" ""))
5168         (match_operand:SI 3 "arith5_operand" "r,L"))]
5169   ""
5170   "
5172   if (! uint5_operand (operands[1], SImode)
5173       ||  ! uint5_operand (operands[2], SImode))
5174   FAIL;
5177 (define_insn ""
5178   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
5179                          (match_operand:SI 1 "uint5_operand" "")
5180                          (match_operand:SI 2 "uint5_operand" ""))
5181         (match_operand:SI 3 "arith5_operand" "r,L"))]
5182   ""
5183   "@
5184    {dep|depw} %3,%2+%1-1,%1,%0
5185    {depi|depwi} %3,%2+%1-1,%1,%0"
5186   [(set_attr "type" "shift,shift")
5187    (set_attr "length" "4,4")])
5189 ;; Optimize insertion of const_int values of type 1...1xxxx.
5190 (define_insn ""
5191   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
5192                          (match_operand:SI 1 "uint5_operand" "")
5193                          (match_operand:SI 2 "uint5_operand" ""))
5194         (match_operand:SI 3 "const_int_operand" ""))]
5195   "(INTVAL (operands[3]) & 0x10) != 0 &&
5196    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
5197   "*
5199   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
5200   return \"{depi|depwi} %3,%2+%1-1,%1,%0\";
5202   [(set_attr "type" "shift")
5203    (set_attr "length" "4")])
5205 ;; This insn is used for some loop tests, typically loops reversed when
5206 ;; strength reduction is used.  It is actually created when the instruction
5207 ;; combination phase combines the special loop test.  Since this insn
5208 ;; is both a jump insn and has an output, it must deal with its own
5209 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
5210 ;; to not choose the register alternatives in the event a reload is needed.
5211 (define_insn "decrement_and_branch_until_zero"
5212   [(set (pc)
5213         (if_then_else
5214           (match_operator 2 "comparison_operator"
5215            [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
5216                      (match_operand:SI 1 "int5_operand" "L,L,L"))
5217             (const_int 0)])
5218           (label_ref (match_operand 3 "" ""))
5219           (pc)))
5220    (set (match_dup 0)
5221         (plus:SI (match_dup 0) (match_dup 1)))
5222    (clobber (match_scratch:SI 4 "=X,r,r"))]
5223   ""
5224   "* return output_dbra (operands, insn, which_alternative); "
5225 ;; Do not expect to understand this the first time through.
5226 [(set_attr "type" "cbranch,multi,multi")
5227  (set (attr "length")
5228       (if_then_else (eq_attr "alternative" "0")
5229 ;; Loop counter in register case
5230 ;; Short branch has length of 4
5231 ;; Long branch has length of 8
5232         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5233                       (const_int 8184))
5234            (const_int 4)
5235            (const_int 8))
5237 ;; Loop counter in FP reg case.
5238 ;; Extra goo to deal with additional reload insns.
5239         (if_then_else (eq_attr "alternative" "1")
5240           (if_then_else (lt (match_dup 3) (pc))
5241             (if_then_else
5242               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
5243                   (const_int 8184))
5244               (const_int 24)
5245               (const_int 28))
5246             (if_then_else
5247               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5248                   (const_int 8184))
5249               (const_int 24)
5250               (const_int 28)))
5251 ;; Loop counter in memory case.
5252 ;; Extra goo to deal with additional reload insns.
5253         (if_then_else (lt (match_dup 3) (pc))
5254           (if_then_else
5255             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5256                 (const_int 8184))
5257             (const_int 12)
5258             (const_int 16))
5259           (if_then_else
5260             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5261                 (const_int 8184))
5262             (const_int 12)
5263             (const_int 16))))))])
5265 (define_insn ""
5266   [(set (pc)
5267         (if_then_else
5268           (match_operator 2 "movb_comparison_operator"
5269            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
5270           (label_ref (match_operand 3 "" ""))
5271           (pc)))
5272    (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
5273         (match_dup 1))]
5274   ""
5275 "* return output_movb (operands, insn, which_alternative, 0); "
5276 ;; Do not expect to understand this the first time through.
5277 [(set_attr "type" "cbranch,multi,multi,multi")
5278  (set (attr "length")
5279       (if_then_else (eq_attr "alternative" "0")
5280 ;; Loop counter in register case
5281 ;; Short branch has length of 4
5282 ;; Long branch has length of 8
5283         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5284                       (const_int 8184))
5285            (const_int 4)
5286            (const_int 8))
5288 ;; Loop counter in FP reg case.
5289 ;; Extra goo to deal with additional reload insns.
5290         (if_then_else (eq_attr "alternative" "1")
5291           (if_then_else (lt (match_dup 3) (pc))
5292             (if_then_else
5293               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5294                   (const_int 8184))
5295               (const_int 12)
5296               (const_int 16))
5297             (if_then_else
5298               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5299                   (const_int 8184))
5300               (const_int 12)
5301               (const_int 16)))
5302 ;; Loop counter in memory or sar case.
5303 ;; Extra goo to deal with additional reload insns.
5304         (if_then_else
5305           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5306               (const_int 8184))
5307           (const_int 8)
5308           (const_int 12)))))])
5310 ;; Handle negated branch.
5311 (define_insn ""
5312   [(set (pc)
5313         (if_then_else
5314           (match_operator 2 "movb_comparison_operator"
5315            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
5316           (pc)
5317           (label_ref (match_operand 3 "" ""))))
5318    (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
5319         (match_dup 1))]
5320   ""
5321 "* return output_movb (operands, insn, which_alternative, 1); "
5322 ;; Do not expect to understand this the first time through.
5323 [(set_attr "type" "cbranch,multi,multi,multi")
5324  (set (attr "length")
5325       (if_then_else (eq_attr "alternative" "0")
5326 ;; Loop counter in register case
5327 ;; Short branch has length of 4
5328 ;; Long branch has length of 8
5329         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5330                       (const_int 8184))
5331            (const_int 4)
5332            (const_int 8))
5334 ;; Loop counter in FP reg case.
5335 ;; Extra goo to deal with additional reload insns.
5336         (if_then_else (eq_attr "alternative" "1")
5337           (if_then_else (lt (match_dup 3) (pc))
5338             (if_then_else
5339               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
5340                   (const_int 8184))
5341               (const_int 12)
5342               (const_int 16))
5343             (if_then_else
5344               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5345                   (const_int 8184))
5346               (const_int 12)
5347               (const_int 16)))
5348 ;; Loop counter in memory or SAR case.
5349 ;; Extra goo to deal with additional reload insns.
5350         (if_then_else
5351           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5352               (const_int 8184))
5353           (const_int 8)
5354           (const_int 12)))))])
5356 (define_insn ""
5357   [(set (pc) (label_ref (match_operand 3 "" "" )))
5358    (set (match_operand:SI 0 "ireg_operand" "=r")
5359         (plus:SI (match_operand:SI 1 "ireg_operand" "r")
5360                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
5361   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
5362   "*
5364   return output_parallel_addb (operands, get_attr_length (insn));
5366   [(set_attr "type" "parallel_branch")
5367    (set (attr "length")
5368     (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
5369                       (const_int 8184))
5370            (const_int 4)
5371            (const_int 8)))])
5373 (define_insn ""
5374   [(set (pc) (label_ref (match_operand 2 "" "" )))
5375    (set (match_operand:SF 0 "ireg_operand" "=r")
5376         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
5377   "reload_completed"
5378   "*
5380   return output_parallel_movb (operands, get_attr_length (insn));
5382   [(set_attr "type" "parallel_branch")
5383    (set (attr "length")
5384     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5385                       (const_int 8184))
5386            (const_int 4)
5387            (const_int 8)))])
5389 (define_insn ""
5390   [(set (pc) (label_ref (match_operand 2 "" "" )))
5391    (set (match_operand:SI 0 "ireg_operand" "=r")
5392         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
5393   "reload_completed"
5394   "*
5396   return output_parallel_movb (operands, get_attr_length (insn));
5398   [(set_attr "type" "parallel_branch")
5399    (set (attr "length")
5400     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5401                       (const_int 8184))
5402            (const_int 4)
5403            (const_int 8)))])
5405 (define_insn ""
5406   [(set (pc) (label_ref (match_operand 2 "" "" )))
5407    (set (match_operand:HI 0 "ireg_operand" "=r")
5408         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
5409   "reload_completed"
5410   "*
5412   return output_parallel_movb (operands, get_attr_length (insn));
5414   [(set_attr "type" "parallel_branch")
5415    (set (attr "length")
5416     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5417                       (const_int 8184))
5418            (const_int 4)
5419            (const_int 8)))])
5421 (define_insn ""
5422   [(set (pc) (label_ref (match_operand 2 "" "" )))
5423    (set (match_operand:QI 0 "ireg_operand" "=r")
5424         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
5425   "reload_completed"
5426   "*
5428   return output_parallel_movb (operands, get_attr_length (insn));
5430   [(set_attr "type" "parallel_branch")
5431    (set (attr "length")
5432     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
5433                       (const_int 8184))
5434            (const_int 4)
5435            (const_int 8)))])
5437 (define_insn ""
5438   [(set (match_operand 0 "register_operand" "=f")
5439         (mult (match_operand 1 "register_operand" "f")
5440               (match_operand 2 "register_operand" "f")))
5441    (set (match_operand 3 "register_operand" "+f")
5442         (plus (match_operand 4 "register_operand" "f")
5443               (match_operand 5 "register_operand" "f")))]
5444   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5445    && reload_completed && fmpyaddoperands (operands)"
5446   "*
5448   if (GET_MODE (operands[0]) == DFmode)
5449     {
5450       if (rtx_equal_p (operands[3], operands[5]))
5451         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
5452       else
5453         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
5454     }
5455   else
5456     {
5457       if (rtx_equal_p (operands[3], operands[5]))
5458         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
5459       else
5460         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
5461     }
5463   [(set_attr "type" "fpalu")
5464    (set_attr "length" "4")])
5466 (define_insn ""
5467   [(set (match_operand 3 "register_operand" "+f")
5468         (plus (match_operand 4 "register_operand" "f")
5469               (match_operand 5 "register_operand" "f")))
5470    (set (match_operand 0 "register_operand" "=f")
5471         (mult (match_operand 1 "register_operand" "f")
5472               (match_operand 2 "register_operand" "f")))]
5473   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5474    && reload_completed && fmpyaddoperands (operands)"
5475   "*
5477   if (GET_MODE (operands[0]) == DFmode)
5478     {
5479       if (rtx_equal_p (operands[3], operands[5]))
5480         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
5481       else
5482         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
5483     }
5484   else
5485     {
5486       if (rtx_equal_p (operands[3], operands[5]))
5487         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
5488       else
5489         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
5490     }
5492   [(set_attr "type" "fpalu")
5493    (set_attr "length" "4")])
5495 (define_insn ""
5496   [(set (match_operand 0 "register_operand" "=f")
5497         (mult (match_operand 1 "register_operand" "f")
5498               (match_operand 2 "register_operand" "f")))
5499    (set (match_operand 3 "register_operand" "+f")
5500         (minus (match_operand 4 "register_operand" "f")
5501                (match_operand 5 "register_operand" "f")))]
5502   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5503    && reload_completed && fmpysuboperands (operands)"
5504   "*
5506   if (GET_MODE (operands[0]) == DFmode)
5507     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
5508   else
5509     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
5511   [(set_attr "type" "fpalu")
5512    (set_attr "length" "4")])
5514 (define_insn ""
5515   [(set (match_operand 3 "register_operand" "+f")
5516         (minus (match_operand 4 "register_operand" "f")
5517                (match_operand 5 "register_operand" "f")))
5518    (set (match_operand 0 "register_operand" "=f")
5519         (mult (match_operand 1 "register_operand" "f")
5520               (match_operand 2 "register_operand" "f")))]
5521   "TARGET_PA_11 && ! TARGET_SOFT_FLOAT
5522    && reload_completed && fmpysuboperands (operands)"
5523   "*
5525   if (GET_MODE (operands[0]) == DFmode)
5526     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
5527   else
5528     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
5530   [(set_attr "type" "fpalu")
5531    (set_attr "length" "4")])
5533 ;; Clean up turds left by reload.
5534 (define_peephole
5535   [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
5536         (match_operand 1 "register_operand" "fr"))
5537    (set (match_operand 2 "register_operand" "fr")
5538         (match_dup 0))]
5539   "! TARGET_SOFT_FLOAT
5540    && GET_CODE (operands[0]) == MEM
5541    && ! MEM_VOLATILE_P (operands[0])
5542    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5543    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5544    && GET_MODE (operands[0]) == DFmode
5545    && GET_CODE (operands[1]) == REG
5546    && GET_CODE (operands[2]) == REG
5547    && ! side_effects_p (XEXP (operands[0], 0))
5548    && REGNO_REG_CLASS (REGNO (operands[1]))
5549       == REGNO_REG_CLASS (REGNO (operands[2]))"
5550   "*
5552   rtx xoperands[2];
5554   if (FP_REG_P (operands[1]))
5555     output_asm_insn (output_fp_move_double (operands), operands);
5556   else
5557     output_asm_insn (output_move_double (operands), operands);
5559   if (rtx_equal_p (operands[1], operands[2]))
5560     return \"\";
5562   xoperands[0] = operands[2];
5563   xoperands[1] = operands[1];
5564       
5565   if (FP_REG_P (xoperands[1]))
5566     output_asm_insn (output_fp_move_double (xoperands), xoperands);
5567   else
5568     output_asm_insn (output_move_double (xoperands), xoperands);
5570   return \"\";
5573 (define_peephole
5574   [(set (match_operand 0 "register_operand" "fr")
5575         (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
5576    (set (match_operand 2 "register_operand" "fr")
5577         (match_dup 1))]
5578   "! TARGET_SOFT_FLOAT
5579    && GET_CODE (operands[1]) == MEM
5580    && ! MEM_VOLATILE_P (operands[1])
5581    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5582    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5583    && GET_MODE (operands[0]) == DFmode
5584    && GET_CODE (operands[0]) == REG
5585    && GET_CODE (operands[2]) == REG
5586    && ! side_effects_p (XEXP (operands[1], 0))
5587    && REGNO_REG_CLASS (REGNO (operands[0]))
5588       == REGNO_REG_CLASS (REGNO (operands[2]))"
5589   "*
5591   rtx xoperands[2];
5593   if (FP_REG_P (operands[0]))
5594     output_asm_insn (output_fp_move_double (operands), operands);
5595   else
5596     output_asm_insn (output_move_double (operands), operands);
5598   xoperands[0] = operands[2];
5599   xoperands[1] = operands[0];
5600       
5601   if (FP_REG_P (xoperands[1]))
5602     output_asm_insn (output_fp_move_double (xoperands), xoperands);
5603   else
5604     output_asm_insn (output_move_double (xoperands), xoperands);
5606   return \"\";
5609 ;; Flush the I and D cache line found at the address in operand 0.
5610 ;; This is used by the trampoline code for nested functions.
5611 ;; So long as the trampoline itself is less than 32 bytes this
5612 ;; is sufficient.
5614 (define_insn "dcacheflush"
5615   [(unspec_volatile [(const_int 1)] 0)
5616    (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
5617    (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))]
5618   ""
5619   "fdc 0(%0)\;fdc 0(%1)\;sync"
5620   [(set_attr "type" "multi")
5621    (set_attr "length" "12")])
5623 (define_insn "icacheflush"
5624   [(unspec_volatile [(const_int 2)] 0)
5625    (use (mem:SI (match_operand 0 "pmode_register_operand" "r")))
5626    (use (mem:SI (match_operand 1 "pmode_register_operand" "r")))
5627    (use (match_operand 2 "pmode_register_operand" "r"))
5628    (clobber (match_operand 3 "pmode_register_operand" "=&r"))
5629    (clobber (match_operand 4 "pmode_register_operand" "=&r"))]
5630   ""
5631   "mfsp %%sr0,%4\;ldsid (%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
5632   [(set_attr "type" "multi")
5633    (set_attr "length" "52")])
5635 ;; An out-of-line prologue.
5636 (define_insn "outline_prologue_call"
5637   [(unspec_volatile [(const_int 0)] 0)
5638    (clobber (reg:SI 31))
5639    (clobber (reg:SI 22))
5640    (clobber (reg:SI 21))
5641    (clobber (reg:SI 20))
5642    (clobber (reg:SI 19))
5643    (clobber (reg:SI 1))]
5644   ""
5645   "*
5647   extern int frame_pointer_needed;
5649   /* We need two different versions depending on whether or not we
5650      need a frame pointer.   Also note that we return to the instruction
5651      immediately after the branch rather than two instructions after the
5652      break as normally is the case.  */
5653   if (frame_pointer_needed)
5654     {
5655       /* Must import the magic millicode routine(s).  */
5656       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
5658       if (TARGET_PORTABLE_RUNTIME)
5659         {
5660           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
5661           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
5662                            NULL);
5663         }
5664       else
5665         output_asm_insn (\"{bl|b,l},n __outline_prologue_fp,%%r31\", NULL);
5666     }
5667   else
5668     {
5669       /* Must import the magic millicode routine(s).  */
5670       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
5672       if (TARGET_PORTABLE_RUNTIME)
5673         {
5674           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
5675           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
5676         }
5677       else
5678         output_asm_insn (\"{bl|b,l},n __outline_prologue,%%r31\", NULL);
5679     }
5680   return \"\";
5682   [(set_attr "type" "multi")
5683    (set_attr "length" "8")])
5685 ;; An out-of-line epilogue.
5686 (define_insn "outline_epilogue_call"
5687   [(unspec_volatile [(const_int 1)] 0)
5688    (use (reg:SI 29))
5689    (use (reg:SI 28))
5690    (clobber (reg:SI 31))
5691    (clobber (reg:SI 22))
5692    (clobber (reg:SI 21))
5693    (clobber (reg:SI 20))
5694    (clobber (reg:SI 19))
5695    (clobber (reg:SI 2))
5696    (clobber (reg:SI 1))]
5697   ""
5698   "*
5700   extern int frame_pointer_needed;
5702   /* We need two different versions depending on whether or not we
5703      need a frame pointer.   Also note that we return to the instruction
5704      immediately after the branch rather than two instructions after the
5705      break as normally is the case.  */
5706   if (frame_pointer_needed)
5707     {
5708       /* Must import the magic millicode routine.  */
5709       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
5711       /* The out-of-line prologue will make sure we return to the right
5712          instruction.  */
5713       if (TARGET_PORTABLE_RUNTIME)
5714         {
5715           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
5716           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
5717                            NULL);
5718         }
5719       else
5720         output_asm_insn (\"{bl|b,l},n __outline_epilogue_fp,%%r31\", NULL);
5721     }
5722   else
5723     {
5724       /* Must import the magic millicode routine.  */
5725       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
5727       /* The out-of-line prologue will make sure we return to the right
5728          instruction.  */
5729       if (TARGET_PORTABLE_RUNTIME)
5730         {
5731           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
5732           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
5733         }
5734       else
5735         output_asm_insn (\"{bl|b,l},n __outline_epilogue,%%r31\", NULL);
5736     }
5737   return \"\";
5739   [(set_attr "type" "multi")
5740    (set_attr "length" "8")])
5742 ;; Given a function pointer, canonicalize it so it can be 
5743 ;; reliably compared to another function pointer.  */
5744 (define_expand "canonicalize_funcptr_for_compare"
5745   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
5746    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5747               (clobber (match_dup 2))
5748               (clobber (reg:SI 26))
5749               (clobber (reg:SI 22))
5750               (clobber (reg:SI 31))])
5751    (set (match_operand:SI 0 "register_operand" "")
5752         (reg:SI 29))]
5753   "! TARGET_PORTABLE_RUNTIME"
5754   "
5756   operands[2] = gen_reg_rtx (SImode);
5757   if (GET_CODE (operands[1]) != REG)
5758     {
5759       rtx tmp = gen_reg_rtx (Pmode);
5760       emit_move_insn (tmp, operands[1]);
5761       operands[1] = tmp;
5762     }
5765 (define_insn ""
5766   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5767    (clobber (match_operand:SI 0 "register_operand" "=a"))
5768    (clobber (reg:SI 26))
5769    (clobber (reg:SI 22))
5770    (clobber (reg:SI 31))]
5771   ""
5772   "*
5774   /* Must import the magic millicode routine.  */
5775   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
5777   /* This is absolutely amazing.
5779      First, copy our input parameter into %r29 just in case we don't
5780      need to call $$sh_func_adrs.  */
5781   output_asm_insn (\"copy %%r26,%%r29\", NULL);
5783   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
5784      we use %r26 unchanged.  */
5785   if (get_attr_length (insn) == 32)
5786     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+24\", NULL);
5787   else if (get_attr_length (insn) == 40)
5788     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+32\", NULL);
5789   else if (get_attr_length (insn) == 44)
5790     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+36\", NULL);
5791   else
5792     output_asm_insn (\"{extru|extrw,u} %%r26,31,2,%%r31\;{comib|cmpib},<>,n 2,%%r31,.+20\", NULL);
5794   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
5795      4096, then we use %r26 unchanged.  */
5796   if (get_attr_length (insn) == 32)
5797     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+16\",
5798                      NULL);
5799   else if (get_attr_length (insn) == 40)
5800     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+24\",
5801                      NULL);
5802   else if (get_attr_length (insn) == 44)
5803     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+28\",
5804                      NULL);
5805   else
5806     output_asm_insn (\"ldi 4096,%%r31\;{comb|cmpb},<<,n %%r26,%%r31,.+12\",
5807                      NULL);
5809   /* Else call $$sh_func_adrs to extract the function's real add24.  */
5810   return output_millicode_call (insn,
5811                                 gen_rtx_SYMBOL_REF (SImode,
5812                                          \"$$sh_func_adrs\"));
5814   [(set_attr "type" "multi")
5815    (set (attr "length")
5816      (cond [
5817 ;; Target (or stub) within reach
5818             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5819                      (const_int 240000))
5820                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5821                      (const_int 0)))
5822             (const_int 28)
5824 ;; NO_SPACE_REGS
5825             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
5826                 (const_int 0))
5827             (const_int 32)
5829 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
5830 ;; same as NO_SPACE_REGS code
5831             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5832                      (const_int 0))
5833                  (eq (symbol_ref "flag_pic")
5834                      (const_int 0)))
5835             (const_int 32)
5837 ;; PORTABLE_RUNTIME
5838             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5839                 (const_int 0))
5840             (const_int 40)]
5842 ;; Out of range and PIC 
5843           (const_int 44)))])
5845 ;; On the PA, the PIC register is call clobbered, so it must
5846 ;; be saved & restored around calls by the caller.  If the call
5847 ;; doesn't return normally (nonlocal goto, or an exception is
5848 ;; thrown), then the code at the exception handler label must
5849 ;; restore the PIC register.
5850 (define_expand "exception_receiver"
5851   [(const_int 4)]
5852   "!TARGET_PORTABLE_RUNTIME && flag_pic"
5853   "
5855   /* Load the PIC register from the stack slot (in our caller's
5856      frame).  */
5857   emit_move_insn (pic_offset_table_rtx,
5858                   gen_rtx_MEM (SImode,
5859                                plus_constant (stack_pointer_rtx, -32)));
5860   emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
5861   emit_insn (gen_blockage ());
5862   DONE;