OSDN Git Service

* pa.md (branch, negated branch): Handle (const_int 0) as first
[pf3gnuchains/gcc-fork.git] / gcc / config / pa / pa.md
1 ;;- Machine description for HP PA-RISC architecture for GNU C compiler
2 ;;   Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc.
3 ;;   Contributed by the Center for Software Science at the University
4 ;;   of Utah.
5
6 ;; This file is part of GNU CC.
7
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.
12
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.
17
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.
22
23 ;; This gcc Version 2 machine description is inspired by sparc.md and
24 ;; mips.md.
25
26 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27
28 ;; Insn type.  Used to default other attribute values.
29
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)
32
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"))
36
37 (define_attr "pa_combine_type"
38   "fmpy,faddsub,uncond_branch,addmove,none"
39   (const_string "none"))
40
41 ;; Processor type (for scheduling, not code generation) -- this attribute
42 ;; must exactly match the processor_type enumeration in pa.h.
43 ;;
44 ;; FIXME: Add 800 scheduling for completeness?
45
46 (define_attr "cpu" "700,7100,7100LC,7200" (const (symbol_ref "pa_cpu_attr")))
47
48 ;; Length (in # of insns).
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))
53
54          (eq_attr "type" "store,fpstore")
55          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
56                        (const_int 8) (const_int 4))
57
58          (eq_attr "type" "binary,shift,nullshift")
59          (if_then_else (match_operand 2 "arith_operand" "")
60                        (const_int 4) (const_int 12))
61
62          (eq_attr "type" "move,unary,shift,nullshift")
63          (if_then_else (match_operand 1 "arith_operand" "")
64                        (const_int 4) (const_int 8))]
65
66         (const_int 4)))
67
68 (define_asm_attributes
69   [(set_attr "length" "4")
70    (set_attr "type" "multi")])
71
72 ;; Attributes for instruction and branch scheduling
73
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")))
80
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")))
88
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")))
101
102
103 ;; Call delay slot description.
104 (define_delay (eq_attr "type" "call")
105   [(eq_attr "in_call_delay" "true") (nil) (nil)])
106
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)])
113
114 ;; Return and other similar instructions.
115 (define_delay (eq_attr "type" "branch,parallel_branch")
116   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
117
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)])
123
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"))])
135
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)])
140
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.
145
146 ;; (define_function_unit {name} {num-units} {n-users} {test}
147 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
148
149 ;; The integer ALU.
150 ;; (Noted only for documentation; units that take one cycle do not need to
151 ;; be specified.)
152
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)
157
158
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.
162
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)
169
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
188
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)
210
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).
214 ;;
215
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)
226
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
245
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)
258
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)
266
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)
271
272
273 ;; Memory subsystem works just like 7100/7150 (except for cache miss times which
274 ;; we don't model here).  
275
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
301
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)
317
318 ;; Define the various functional units for dual-issue.
319
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)
325
326 ;; Shifts and memory ops actually execute in one of the integer
327 ;; ALUs, but we can't really model that.
328 (define_function_unit "pa7100LCshiftmem" 1 1
329   (and
330     (eq_attr "type" "shift,nullshift,load,fpload,store,fpstore")
331     (eq_attr "cpu" "7100LC,7200")) 1 1)
332
333 ;; We have two basic ALUs.
334 (define_function_unit "pa7100LCalu" 2 2
335   (and
336     (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
337    (eq_attr "cpu" "7100LC,7200")) 1 1)
338
339 ;; I don't have complete information on the PA7200; however, most of
340 ;; what I've heard makes it look like a 7100LC without the store-store
341 ;; penalty.  So that's how we'll model it.
342
343 ;; Memory. Disregarding Cache misses, memory loads and stores take
344 ;; two cycles.  Any special cases are handled in pa_adjust_cost.
345 (define_function_unit "pa7200memory" 1 0
346   (and (eq_attr "type" "load,fpload,store,fpstore")
347        (eq_attr "cpu" "7200")) 2 0)
348
349 ;; I don't have detailed information on the PA7200 FP pipeline, so I
350 ;; treat it just like the 7100LC pipeline.
351 ;; Similarly for the multi-issue fake units.
352
353 \f
354 ;; Compare instructions.
355 ;; This controls RTL generation and register allocation.
356
357 ;; We generate RTL for comparisons and branches by having the cmpxx
358 ;; patterns store away the operands.  Then, the scc and bcc patterns
359 ;; emit RTL for both the compare and the branch.
360 ;;
361
362 (define_expand "cmpsi"
363   [(set (reg:CC 0)
364         (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
365                     (match_operand:SI 1 "arith5_operand" "")))]
366   ""
367   "
368 {
369  hppa_compare_op0 = operands[0];
370  hppa_compare_op1 = operands[1];
371  hppa_branch_type = CMP_SI;
372  DONE;
373 }")
374
375 (define_expand "cmpsf"
376   [(set (reg:CCFP 0)
377         (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
378                       (match_operand:SF 1 "reg_or_0_operand" "")))]
379   "! TARGET_SOFT_FLOAT"
380   "
381 {
382   hppa_compare_op0 = operands[0];
383   hppa_compare_op1 = operands[1];
384   hppa_branch_type = CMP_SF;
385   DONE;
386 }")
387
388 (define_expand "cmpdf"
389   [(set (reg:CCFP 0)
390       (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
391                     (match_operand:DF 1 "reg_or_0_operand" "")))]
392   "! TARGET_SOFT_FLOAT"
393   "
394 {
395   hppa_compare_op0 = operands[0];
396   hppa_compare_op1 = operands[1];
397   hppa_branch_type = CMP_DF;
398   DONE;
399 }")
400
401 (define_insn ""
402   [(set (reg:CCFP 0)
403         (match_operator:CCFP 2 "comparison_operator"
404                              [(match_operand:SF 0 "reg_or_0_operand" "fG")
405                               (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
406   "! TARGET_SOFT_FLOAT"
407   "fcmp,sgl,%Y2 %r0,%r1"
408   [(set_attr "length" "4")
409    (set_attr "type" "fpcc")])
410
411 (define_insn ""
412   [(set (reg:CCFP 0)
413         (match_operator:CCFP 2 "comparison_operator"
414                              [(match_operand:DF 0 "reg_or_0_operand" "fG")
415                               (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
416   "! TARGET_SOFT_FLOAT"
417   "fcmp,dbl,%Y2 %r0,%r1"
418   [(set_attr "length" "4")
419    (set_attr "type" "fpcc")])
420
421 ;; scc insns.
422
423 (define_expand "seq"
424   [(set (match_operand:SI 0 "register_operand" "")
425         (eq:SI (match_dup 1)
426                (match_dup 2)))]
427   ""
428   "
429 {
430   /* fp scc patterns rarely match, and are not a win on the PA.  */
431   if (hppa_branch_type != CMP_SI)
432     FAIL;
433   /* set up operands from compare.  */
434   operands[1] = hppa_compare_op0;
435   operands[2] = hppa_compare_op1;
436   /* fall through and generate default code */
437 }")
438
439 (define_expand "sne"
440   [(set (match_operand:SI 0 "register_operand" "")
441         (ne:SI (match_dup 1)
442                (match_dup 2)))]
443   ""
444   "
445 {
446   /* fp scc patterns rarely match, and are not a win on the PA.  */
447   if (hppa_branch_type != CMP_SI)
448     FAIL;
449   operands[1] = hppa_compare_op0;
450   operands[2] = hppa_compare_op1;
451 }")
452
453 (define_expand "slt"
454   [(set (match_operand:SI 0 "register_operand" "")
455         (lt:SI (match_dup 1)
456                (match_dup 2)))]
457   ""
458   "
459 {
460   /* fp scc patterns rarely match, and are not a win on the PA.  */
461   if (hppa_branch_type != CMP_SI)
462     FAIL;
463   operands[1] = hppa_compare_op0;
464   operands[2] = hppa_compare_op1;
465 }")
466
467 (define_expand "sgt"
468   [(set (match_operand:SI 0 "register_operand" "")
469         (gt:SI (match_dup 1)
470                (match_dup 2)))]
471   ""
472   "
473 {
474   /* fp scc patterns rarely match, and are not a win on the PA.  */
475   if (hppa_branch_type != CMP_SI)
476     FAIL;
477   operands[1] = hppa_compare_op0;
478   operands[2] = hppa_compare_op1;
479 }")
480
481 (define_expand "sle"
482   [(set (match_operand:SI 0 "register_operand" "")
483         (le:SI (match_dup 1)
484                (match_dup 2)))]
485   ""
486   "
487 {
488   /* fp scc patterns rarely match, and are not a win on the PA.  */
489   if (hppa_branch_type != CMP_SI)
490     FAIL;
491   operands[1] = hppa_compare_op0;
492   operands[2] = hppa_compare_op1;
493 }")
494
495 (define_expand "sge"
496   [(set (match_operand:SI 0 "register_operand" "")
497         (ge:SI (match_dup 1)
498                (match_dup 2)))]
499   ""
500   "
501 {
502   /* fp scc patterns rarely match, and are not a win on the PA.  */
503   if (hppa_branch_type != CMP_SI)
504     FAIL;
505   operands[1] = hppa_compare_op0;
506   operands[2] = hppa_compare_op1;
507 }")
508
509 (define_expand "sltu"
510   [(set (match_operand:SI 0 "register_operand" "")
511         (ltu:SI (match_dup 1)
512                 (match_dup 2)))]
513   ""
514   "
515 {
516   if (hppa_branch_type != CMP_SI)
517     FAIL;
518   operands[1] = hppa_compare_op0;
519   operands[2] = hppa_compare_op1;
520 }")
521
522 (define_expand "sgtu"
523   [(set (match_operand:SI 0 "register_operand" "")
524         (gtu:SI (match_dup 1)
525                 (match_dup 2)))]
526   ""
527   "
528 {
529   if (hppa_branch_type != CMP_SI)
530     FAIL;
531   operands[1] = hppa_compare_op0;
532   operands[2] = hppa_compare_op1;
533 }")
534
535 (define_expand "sleu"
536   [(set (match_operand:SI 0 "register_operand" "")
537         (leu:SI (match_dup 1)
538                 (match_dup 2)))]
539   ""
540   "
541 {
542   if (hppa_branch_type != CMP_SI)
543     FAIL;
544   operands[1] = hppa_compare_op0;
545   operands[2] = hppa_compare_op1;
546 }")
547
548 (define_expand "sgeu"
549   [(set (match_operand:SI 0 "register_operand" "")
550         (geu:SI (match_dup 1)
551                 (match_dup 2)))]
552   ""
553   "
554 {
555   if (hppa_branch_type != CMP_SI)
556     FAIL;
557   operands[1] = hppa_compare_op0;
558   operands[2] = hppa_compare_op1;
559 }")
560
561 ;; Instruction canonicalization puts immediate operands second, which
562 ;; is the reverse of what we want.
563
564 (define_insn "scc"
565   [(set (match_operand:SI 0 "register_operand" "=r")
566         (match_operator:SI 3 "comparison_operator"
567                            [(match_operand:SI 1 "register_operand" "r")
568                             (match_operand:SI 2 "arith11_operand" "rI")]))]
569   ""
570   "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0"
571   [(set_attr "type" "binary")
572    (set_attr "length" "8")])
573
574 (define_insn "iorscc"
575   [(set (match_operand:SI 0 "register_operand" "=r")
576         (ior:SI (match_operator:SI 3 "comparison_operator"
577                                    [(match_operand:SI 1 "register_operand" "r")
578                                     (match_operand:SI 2 "arith11_operand" "rI")])
579                 (match_operator:SI 6 "comparison_operator"
580                                    [(match_operand:SI 4 "register_operand" "r")
581                                     (match_operand:SI 5 "arith11_operand" "rI")])))]
582   ""
583   "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0"
584   [(set_attr "type" "binary")
585    (set_attr "length" "12")])
586
587 ;; Combiner patterns for common operations performed with the output
588 ;; from an scc insn (negscc and incscc).
589 (define_insn "negscc"
590   [(set (match_operand:SI 0 "register_operand" "=r")
591         (neg:SI (match_operator:SI 3 "comparison_operator"
592                [(match_operand:SI 1 "register_operand" "r")
593                 (match_operand:SI 2 "arith11_operand" "rI")])))]
594   ""
595   "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0"
596   [(set_attr "type" "binary")
597    (set_attr "length" "8")])
598
599 ;; Patterns for adding/subtracting the result of a boolean expression from
600 ;; a register.  First we have special patterns that make use of the carry
601 ;; bit, and output only two instructions.  For the cases we can't in
602 ;; general do in two instructions, the incscc pattern at the end outputs
603 ;; two or three instructions.
604
605 (define_insn ""
606   [(set (match_operand:SI 0 "register_operand" "=r")
607         (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
608                          (match_operand:SI 3 "arith11_operand" "rI"))
609                  (match_operand:SI 1 "register_operand" "r")))]
610   ""
611   "sub%I3 %3,%2,0\;addc 0,%1,%0"
612   [(set_attr "type" "binary")
613    (set_attr "length" "8")])
614
615 ; This need only accept registers for op3, since canonicalization
616 ; replaces geu with gtu when op3 is an integer.
617 (define_insn ""
618   [(set (match_operand:SI 0 "register_operand" "=r")
619         (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
620                          (match_operand:SI 3 "register_operand" "r"))
621                  (match_operand:SI 1 "register_operand" "r")))]
622   ""
623   "sub %2,%3,0\;addc 0,%1,%0"
624   [(set_attr "type" "binary")
625    (set_attr "length" "8")])
626
627 ; Match only integers for op3 here.  This is used as canonical form of the
628 ; geu pattern when op3 is an integer.  Don't match registers since we can't
629 ; make better code than the general incscc pattern.
630 (define_insn ""
631   [(set (match_operand:SI 0 "register_operand" "=r")
632         (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
633                          (match_operand:SI 3 "int11_operand" "I"))
634                  (match_operand:SI 1 "register_operand" "r")))]
635   ""
636   "addi %k3,%2,0\;addc 0,%1,%0"
637   [(set_attr "type" "binary")
638    (set_attr "length" "8")])
639
640 (define_insn "incscc"
641   [(set (match_operand:SI 0 "register_operand" "=r,r")
642         (plus:SI (match_operator:SI 4 "comparison_operator"
643                     [(match_operand:SI 2 "register_operand" "r,r")
644                      (match_operand:SI 3 "arith11_operand" "rI,rI")])
645                  (match_operand:SI 1 "register_operand" "0,?r")))]
646   ""
647   "@
648    com%I3clr,%B4 %3,%2,0\;addi 1,%0,%0
649    com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0"
650   [(set_attr "type" "binary,binary")
651    (set_attr "length" "8,12")])
652
653 (define_insn ""
654   [(set (match_operand:SI 0 "register_operand" "=r")
655         (minus:SI (match_operand:SI 1 "register_operand" "r")
656                   (gtu:SI (match_operand:SI 2 "register_operand" "r")
657                           (match_operand:SI 3 "arith11_operand" "rI"))))]
658   ""
659   "sub%I3 %3,%2,0\;subb %1,0,%0"
660   [(set_attr "type" "binary")
661    (set_attr "length" "8")])
662
663 (define_insn ""
664   [(set (match_operand:SI 0 "register_operand" "=r")
665         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
666                             (gtu:SI (match_operand:SI 2 "register_operand" "r")
667                                     (match_operand:SI 3 "arith11_operand" "rI")))
668                   (match_operand:SI 4 "register_operand" "r")))]
669   ""
670   "sub%I3 %3,%2,0\;subb %1,%4,%0"
671   [(set_attr "type" "binary")
672    (set_attr "length" "8")])
673
674 ; This need only accept registers for op3, since canonicalization
675 ; replaces ltu with leu when op3 is an integer.
676 (define_insn ""
677   [(set (match_operand:SI 0 "register_operand" "=r")
678         (minus:SI (match_operand:SI 1 "register_operand" "r")
679                   (ltu:SI (match_operand:SI 2 "register_operand" "r")
680                           (match_operand:SI 3 "register_operand" "r"))))]
681   ""
682   "sub %2,%3,0\;subb %1,0,%0"
683   [(set_attr "type" "binary")
684    (set_attr "length" "8")])
685
686 (define_insn ""
687   [(set (match_operand:SI 0 "register_operand" "=r")
688         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
689                             (ltu:SI (match_operand:SI 2 "register_operand" "r")
690                                     (match_operand:SI 3 "register_operand" "r")))
691                   (match_operand:SI 4 "register_operand" "r")))]
692   ""
693   "sub %2,%3,0\;subb %1,%4,%0"
694   [(set_attr "type" "binary")
695    (set_attr "length" "8")])
696
697 ; Match only integers for op3 here.  This is used as canonical form of the
698 ; ltu pattern when op3 is an integer.  Don't match registers since we can't
699 ; make better code than the general incscc pattern.
700 (define_insn ""
701   [(set (match_operand:SI 0 "register_operand" "=r")
702         (minus:SI (match_operand:SI 1 "register_operand" "r")
703                   (leu:SI (match_operand:SI 2 "register_operand" "r")
704                           (match_operand:SI 3 "int11_operand" "I"))))]
705   ""
706   "addi %k3,%2,0\;subb %1,0,%0"
707   [(set_attr "type" "binary")
708    (set_attr "length" "8")])
709
710 (define_insn ""
711   [(set (match_operand:SI 0 "register_operand" "=r")
712         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
713                             (leu:SI (match_operand:SI 2 "register_operand" "r")
714                                     (match_operand:SI 3 "int11_operand" "I")))
715                   (match_operand:SI 4 "register_operand" "r")))]
716   ""
717   "addi %k3,%2,0\;subb %1,%4,%0"
718   [(set_attr "type" "binary")
719    (set_attr "length" "8")])
720
721 (define_insn "decscc"
722   [(set (match_operand:SI 0 "register_operand" "=r,r")
723         (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
724                   (match_operator:SI 4 "comparison_operator"
725                      [(match_operand:SI 2 "register_operand" "r,r")
726                       (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
727   ""
728   "@
729    com%I3clr,%B4 %3,%2,0\;addi -1,%0,%0
730    com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0"
731   [(set_attr "type" "binary,binary")
732    (set_attr "length" "8,12")])
733
734 ; Patterns for max and min.  (There is no need for an earlyclobber in the
735 ; last alternative since the middle alternative will match if op0 == op1.)
736
737 (define_insn "sminsi3"
738   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
739         (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
740                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
741   ""
742   "@
743   comclr,> %2,%0,0\;copy %2,%0
744   comiclr,> %2,%0,0\;ldi %2,%0
745   comclr,> %1,%2,%0\;copy %1,%0"
746 [(set_attr "type" "multi,multi,multi")
747  (set_attr "length" "8,8,8")])
748
749 (define_insn "uminsi3"
750   [(set (match_operand:SI 0 "register_operand" "=r,r")
751         (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
752                  (match_operand:SI 2 "arith11_operand" "r,I")))]
753   ""
754   "@
755   comclr,>> %2,%0,0\;copy %2,%0
756   comiclr,>> %2,%0,0\;ldi %2,%0"
757 [(set_attr "type" "multi,multi")
758  (set_attr "length" "8,8")])
759
760 (define_insn "smaxsi3"
761   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
762         (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
763                  (match_operand:SI 2 "arith11_operand" "r,I,M")))]
764   ""
765   "@
766   comclr,< %2,%0,0\;copy %2,%0
767   comiclr,< %2,%0,0\;ldi %2,%0
768   comclr,< %1,%2,%0\;copy %1,%0"
769 [(set_attr "type" "multi,multi,multi")
770  (set_attr "length" "8,8,8")])
771
772 (define_insn "umaxsi3"
773   [(set (match_operand:SI 0 "register_operand" "=r,r")
774         (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
775                  (match_operand:SI 2 "arith11_operand" "r,I")))]
776   ""
777   "@
778   comclr,<< %2,%0,0\;copy %2,%0
779   comiclr,<< %2,%0,0\;ldi %2,%0"
780 [(set_attr "type" "multi,multi")
781  (set_attr "length" "8,8")])
782
783 (define_insn "abssi2"
784   [(set (match_operand:SI 0 "register_operand" "=r")
785         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
786   ""
787   "or,>= %%r0,%1,%0\;subi 0,%0,%0"
788   [(set_attr "type" "multi")
789    (set_attr "length" "8")])
790
791 ;;; Experimental conditional move patterns
792
793 (define_expand "movsicc"
794   [(set (match_operand:SI 0 "register_operand" "")
795         (if_then_else:SI
796          (match_operator 1 "comparison_operator"
797             [(match_dup 4)
798              (match_dup 5)])
799          (match_operand:SI 2 "reg_or_cint_move_operand" "")
800          (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
801   ""
802   "
803 {
804   enum rtx_code code = GET_CODE (operands[1]);
805
806   if (hppa_branch_type != CMP_SI)
807     FAIL;
808
809   /* operands[1] is currently the result of compare_from_rtx.  We want to
810      emit a compare of the original operands.  */
811   operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
812   operands[4] = hppa_compare_op0;
813   operands[5] = hppa_compare_op1;
814 }")
815
816 ; We need the first constraint alternative in order to avoid
817 ; earlyclobbers on all other alternatives.
818 (define_insn ""
819   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
820         (if_then_else:SI
821          (match_operator 5 "comparison_operator"
822             [(match_operand:SI 3 "register_operand" "r,r,r,r,r")
823              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
824          (match_operand:SI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
825          (const_int 0)))]
826   ""
827   "@
828    com%I4clr,%S5 %4,%3,0\;ldi 0,%0
829    com%I4clr,%B5 %4,%3,%0\;copy %1,%0
830    com%I4clr,%B5 %4,%3,%0\;ldi %1,%0
831    com%I4clr,%B5 %4,%3,%0\;ldil L'%1,%0
832    com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0"
833   [(set_attr "type" "multi,multi,multi,multi,nullshift")
834    (set_attr "length" "8,8,8,8,8")])
835
836 (define_insn ""
837   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
838         (if_then_else:SI
839          (match_operator 5 "comparison_operator"
840             [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
841              (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
842          (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
843          (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
844   ""
845   "@
846    com%I4clr,%S5 %4,%3,0\;copy %2,%0
847    com%I4clr,%S5 %4,%3,0\;ldi %2,%0
848    com%I4clr,%S5 %4,%3,0\;ldil L'%2,%0
849    com%I4clr,%S5 %4,%3,0\;zdepi %Z2,%0
850    com%I4clr,%B5 %4,%3,0\;copy %1,%0
851    com%I4clr,%B5 %4,%3,0\;ldi %1,%0
852    com%I4clr,%B5 %4,%3,0\;ldil L'%1,%0
853    com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0"
854   [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
855    (set_attr "length" "8,8,8,8,8,8,8,8")])
856
857 ;; Conditional Branches
858
859 (define_expand "beq"
860   [(set (pc)
861         (if_then_else (eq (match_dup 1) (match_dup 2))
862                       (label_ref (match_operand 0 "" ""))
863                       (pc)))]
864   ""
865   "
866 {
867   if (hppa_branch_type != CMP_SI)
868     {
869       emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
870       emit_bcond_fp (NE, operands[0]);
871       DONE;
872     }
873   /* set up operands from compare.  */
874   operands[1] = hppa_compare_op0;
875   operands[2] = hppa_compare_op1;
876   /* fall through and generate default code */
877 }")
878
879 (define_expand "bne"
880   [(set (pc)
881         (if_then_else (ne (match_dup 1) (match_dup 2))
882                       (label_ref (match_operand 0 "" ""))
883                       (pc)))]
884   ""
885   "
886 {
887   if (hppa_branch_type != CMP_SI)
888     {
889       emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
890       emit_bcond_fp (NE, operands[0]);
891       DONE;
892     }
893   operands[1] = hppa_compare_op0;
894   operands[2] = hppa_compare_op1;
895 }")
896
897 (define_expand "bgt"
898   [(set (pc)
899         (if_then_else (gt (match_dup 1) (match_dup 2))
900                       (label_ref (match_operand 0 "" ""))
901                       (pc)))]
902   ""
903   "
904 {
905   if (hppa_branch_type != CMP_SI)
906     {
907       emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
908       emit_bcond_fp (NE, operands[0]);
909       DONE;
910     }
911   operands[1] = hppa_compare_op0;
912   operands[2] = hppa_compare_op1;
913 }")
914
915 (define_expand "blt"
916   [(set (pc)
917         (if_then_else (lt (match_dup 1) (match_dup 2))
918                       (label_ref (match_operand 0 "" ""))
919                       (pc)))]
920   ""
921   "
922 {
923   if (hppa_branch_type != CMP_SI)
924     {
925       emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
926       emit_bcond_fp (NE, operands[0]);
927       DONE;
928     }
929   operands[1] = hppa_compare_op0;
930   operands[2] = hppa_compare_op1;
931 }")
932
933 (define_expand "bge"
934   [(set (pc)
935         (if_then_else (ge (match_dup 1) (match_dup 2))
936                       (label_ref (match_operand 0 "" ""))
937                       (pc)))]
938   ""
939   "
940 {
941   if (hppa_branch_type != CMP_SI)
942     {
943       emit_insn (gen_cmp_fp (GE, 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;
949 }")
950
951 (define_expand "ble"
952   [(set (pc)
953         (if_then_else (le (match_dup 1) (match_dup 2))
954                       (label_ref (match_operand 0 "" ""))
955                       (pc)))]
956   ""
957   "
958 {
959   if (hppa_branch_type != CMP_SI)
960     {
961       emit_insn (gen_cmp_fp (LE, 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;
967 }")
968
969 (define_expand "bgtu"
970   [(set (pc)
971         (if_then_else (gtu (match_dup 1) (match_dup 2))
972                       (label_ref (match_operand 0 "" ""))
973                       (pc)))]
974   ""
975   "
976 {
977   if (hppa_branch_type != CMP_SI)
978     FAIL;
979   operands[1] = hppa_compare_op0;
980   operands[2] = hppa_compare_op1;
981 }")
982
983 (define_expand "bltu"
984   [(set (pc)
985         (if_then_else (ltu (match_dup 1) (match_dup 2))
986                       (label_ref (match_operand 0 "" ""))
987                       (pc)))]
988   ""
989   "
990 {
991   if (hppa_branch_type != CMP_SI)
992     FAIL;
993   operands[1] = hppa_compare_op0;
994   operands[2] = hppa_compare_op1;
995 }")
996
997 (define_expand "bgeu"
998   [(set (pc)
999         (if_then_else (geu (match_dup 1) (match_dup 2))
1000                       (label_ref (match_operand 0 "" ""))
1001                       (pc)))]
1002   ""
1003   "
1004 {
1005   if (hppa_branch_type != CMP_SI)
1006     FAIL;
1007   operands[1] = hppa_compare_op0;
1008   operands[2] = hppa_compare_op1;
1009 }")
1010
1011 (define_expand "bleu"
1012   [(set (pc)
1013         (if_then_else (leu (match_dup 1) (match_dup 2))
1014                       (label_ref (match_operand 0 "" ""))
1015                       (pc)))]
1016   ""
1017   "
1018 {
1019   if (hppa_branch_type != CMP_SI)
1020     FAIL;
1021   operands[1] = hppa_compare_op0;
1022   operands[2] = hppa_compare_op1;
1023 }")
1024
1025 ;; Match the branch patterns.
1026
1027
1028 ;; Note a long backward conditional branch with an annulled delay slot
1029 ;; has a length of 12.
1030 (define_insn ""
1031   [(set (pc)
1032         (if_then_else
1033          (match_operator 3 "comparison_operator"
1034                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1035                           (match_operand:SI 2 "arith5_operand" "rL")])
1036          (label_ref (match_operand 0 "" ""))
1037          (pc)))]
1038   ""
1039   "*
1040 {
1041   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1042                          get_attr_length (insn), 0, insn);
1043 }"
1044 [(set_attr "type" "cbranch")
1045  (set (attr "length")
1046     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1047                (const_int 8184))
1048            (const_int 4)
1049            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1050                (const_int 262100))
1051            (const_int 8)
1052            (eq (symbol_ref "flag_pic") (const_int 0))
1053            (const_int 20)]
1054           (const_int 28)))])
1055
1056 ;; Match the negated branch.
1057
1058 (define_insn ""
1059   [(set (pc)
1060         (if_then_else
1061          (match_operator 3 "comparison_operator"
1062                          [(match_operand:SI 1 "reg_or_0_operand" "rM")
1063                           (match_operand:SI 2 "arith5_operand" "rL")])
1064          (pc)
1065          (label_ref (match_operand 0 "" ""))))]
1066   ""
1067   "*
1068 {
1069   return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
1070                          get_attr_length (insn), 1, insn);
1071 }"
1072 [(set_attr "type" "cbranch")
1073  (set (attr "length")
1074     (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1075                (const_int 8184))
1076            (const_int 4)
1077            (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
1078                (const_int 262100))
1079            (const_int 8)
1080            (eq (symbol_ref "flag_pic") (const_int 0))
1081            (const_int 20)]
1082           (const_int 28)))])
1083
1084 ;; Branch on Bit patterns.
1085 (define_insn ""
1086   [(set (pc)
1087         (if_then_else
1088          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1089                               (const_int 1)
1090                               (match_operand:SI 1 "uint5_operand" ""))
1091              (const_int 0))
1092          (label_ref (match_operand 2 "" ""))
1093          (pc)))]
1094   ""
1095   "*
1096 {
1097   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1098                          get_attr_length (insn), 0, insn, 0);
1099 }"
1100 [(set_attr "type" "cbranch")
1101  (set (attr "length")
1102     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1103                       (const_int 8184))
1104            (const_int 4)
1105            (const_int 8)))])
1106
1107 (define_insn ""
1108   [(set (pc)
1109         (if_then_else
1110          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1111                               (const_int 1)
1112                               (match_operand:SI 1 "uint5_operand" ""))
1113              (const_int 0))
1114          (pc)
1115          (label_ref (match_operand 2 "" ""))))]
1116   ""
1117   "*
1118 {
1119   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1120                          get_attr_length (insn), 1, insn, 0);
1121 }"
1122 [(set_attr "type" "cbranch")
1123  (set (attr "length")
1124     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1125                       (const_int 8184))
1126            (const_int 4)
1127            (const_int 8)))])
1128
1129 (define_insn ""
1130   [(set (pc)
1131         (if_then_else
1132          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1133                               (const_int 1)
1134                               (match_operand:SI 1 "uint5_operand" ""))
1135              (const_int 0))
1136          (label_ref (match_operand 2 "" ""))
1137          (pc)))]
1138   ""
1139   "*
1140 {
1141   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1142                          get_attr_length (insn), 0, insn, 1);
1143 }"
1144 [(set_attr "type" "cbranch")
1145  (set (attr "length")
1146     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1147                       (const_int 8184))
1148            (const_int 4)
1149            (const_int 8)))])
1150
1151 (define_insn ""
1152   [(set (pc)
1153         (if_then_else
1154          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1155                               (const_int 1)
1156                               (match_operand:SI 1 "uint5_operand" ""))
1157              (const_int 0))
1158          (pc)
1159          (label_ref (match_operand 2 "" ""))))]
1160   ""
1161   "*
1162 {
1163   return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
1164                          get_attr_length (insn), 1, insn, 1);
1165 }"
1166 [(set_attr "type" "cbranch")
1167  (set (attr "length")
1168     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1169                       (const_int 8184))
1170            (const_int 4)
1171            (const_int 8)))])
1172
1173 ;; Branch on Variable Bit patterns.
1174 (define_insn ""
1175   [(set (pc)
1176         (if_then_else
1177          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1178                               (const_int 1)
1179                               (match_operand:SI 1 "register_operand" "q"))
1180              (const_int 0))
1181          (label_ref (match_operand 2 "" ""))
1182          (pc)))]
1183   ""
1184   "*
1185 {
1186   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1187                      get_attr_length (insn), 0, insn, 0);
1188 }"
1189 [(set_attr "type" "cbranch")
1190  (set (attr "length")
1191     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1192                       (const_int 8184))
1193            (const_int 4)
1194            (const_int 8)))])
1195
1196 (define_insn ""
1197   [(set (pc)
1198         (if_then_else
1199          (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1200                               (const_int 1)
1201                               (match_operand:SI 1 "register_operand" "q"))
1202              (const_int 0))
1203          (pc)
1204          (label_ref (match_operand 2 "" ""))))]
1205   ""
1206   "*
1207 {
1208   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1209                      get_attr_length (insn), 1, insn, 0);
1210 }"
1211 [(set_attr "type" "cbranch")
1212  (set (attr "length")
1213     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1214                       (const_int 8184))
1215            (const_int 4)
1216            (const_int 8)))])
1217
1218 (define_insn ""
1219   [(set (pc)
1220         (if_then_else
1221          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1222                               (const_int 1)
1223                               (match_operand:SI 1 "register_operand" "q"))
1224              (const_int 0))
1225          (label_ref (match_operand 2 "" ""))
1226          (pc)))]
1227   ""
1228   "*
1229 {
1230   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1231                      get_attr_length (insn), 0, insn, 1);
1232 }"
1233 [(set_attr "type" "cbranch")
1234  (set (attr "length")
1235     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1236                       (const_int 8184))
1237            (const_int 4)
1238            (const_int 8)))])
1239
1240 (define_insn ""
1241   [(set (pc)
1242         (if_then_else
1243          (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1244                               (const_int 1)
1245                               (match_operand:SI 1 "register_operand" "q"))
1246              (const_int 0))
1247          (pc)
1248          (label_ref (match_operand 2 "" ""))))]
1249   ""
1250   "*
1251 {
1252   return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
1253                      get_attr_length (insn), 1, insn, 1);
1254 }"
1255 [(set_attr "type" "cbranch")
1256  (set (attr "length")
1257     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
1258                       (const_int 8184))
1259            (const_int 4)
1260            (const_int 8)))])
1261
1262 ;; Floating point branches
1263 (define_insn ""
1264   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1265                            (label_ref (match_operand 0 "" ""))
1266                            (pc)))]
1267   "! TARGET_SOFT_FLOAT"
1268   "*
1269 {
1270   if (INSN_ANNULLED_BRANCH_P (insn))
1271     return \"ftest\;bl,n %0,0\";
1272   else
1273     return \"ftest\;bl%* %0,0\";
1274 }"
1275   [(set_attr "type" "fbranch")
1276    (set_attr "length" "8")])
1277
1278 (define_insn ""
1279   [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
1280                            (pc)
1281                            (label_ref (match_operand 0 "" ""))))]
1282   "! TARGET_SOFT_FLOAT"
1283   "*
1284 {
1285   if (INSN_ANNULLED_BRANCH_P (insn))
1286     return \"ftest\;add,tr 0,0,0\;bl,n %0,0\";
1287   else
1288     return \"ftest\;add,tr 0,0,0\;bl%* %0,0\";
1289 }"
1290   [(set_attr "type" "fbranch")
1291    (set_attr "length" "12")])
1292
1293 ;; Move instructions
1294
1295 (define_expand "movsi"
1296   [(set (match_operand:SI 0 "general_operand" "")
1297         (match_operand:SI 1 "general_operand" ""))]
1298   ""
1299   "
1300 {
1301   if (emit_move_sequence (operands, SImode, 0))
1302     DONE;
1303 }")
1304
1305 ;; Reloading an SImode or DImode value requires a scratch register if
1306 ;; going in to or out of float point registers.
1307
1308 (define_expand "reload_insi"
1309   [(set (match_operand:SI 0 "register_operand" "=Z")
1310         (match_operand:SI 1 "non_hard_reg_operand" ""))
1311    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1312   ""
1313   "
1314 {
1315   if (emit_move_sequence (operands, SImode, operands[2]))
1316     DONE;
1317
1318   /* We don't want the clobber emitted, so handle this ourselves.  */
1319   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1320   DONE;
1321 }")
1322
1323 (define_expand "reload_outsi"
1324   [(set (match_operand:SI 0 "non_hard_reg_operand" "")
1325         (match_operand:SI 1  "register_operand" "Z"))
1326    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1327   ""
1328   "
1329 {
1330   if (emit_move_sequence (operands, SImode, operands[2]))
1331     DONE;
1332
1333   /* We don't want the clobber emitted, so handle this ourselves.  */
1334   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1335   DONE;
1336 }")
1337
1338 ;;; pic symbol references
1339
1340 (define_insn ""
1341   [(set (match_operand:SI 0 "register_operand" "=r")
1342         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1343                          (match_operand:SI 2 "symbolic_operand" ""))))]
1344   "flag_pic && operands[1] == pic_offset_table_rtx"
1345   "ldw T'%2(%1),%0"
1346   [(set_attr "type" "load")
1347    (set_attr "length" "4")])
1348
1349 (define_insn ""
1350   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1351                                 "=r,r,r,r,r,Q,*q,!f,f,*TR")
1352         (match_operand:SI 1 "move_operand"
1353                                 "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
1354   "(register_operand (operands[0], SImode)
1355     || reg_or_0_operand (operands[1], SImode))
1356    && ! TARGET_SOFT_FLOAT"
1357   "@
1358    copy %1,%0
1359    ldi %1,%0
1360    ldil L'%1,%0
1361    zdepi %Z1,%0
1362    ldw%M1 %1,%0
1363    stw%M0 %r1,%0
1364    mtsar %r1
1365    fcpy,sgl %r1,%0
1366    fldw%F1 %1,%0
1367    fstw%F0 %1,%0"
1368   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
1369    (set_attr "pa_combine_type" "addmove")
1370    (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
1371
1372 (define_insn ""
1373   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
1374                                 "=r,r,r,r,r,Q,*q")
1375         (match_operand:SI 1 "move_operand"
1376                                 "r,J,N,K,RQ,rM,rM"))]
1377   "(register_operand (operands[0], SImode)
1378     || reg_or_0_operand (operands[1], SImode))
1379    && TARGET_SOFT_FLOAT"
1380   "@
1381    copy %1,%0
1382    ldi %1,%0
1383    ldil L'%1,%0
1384    zdepi %Z1,%0
1385    ldw%M1 %1,%0
1386    stw%M0 %r1,%0
1387    mtsar %r1"
1388   [(set_attr "type" "move,move,move,move,load,store,move")
1389    (set_attr "pa_combine_type" "addmove")
1390    (set_attr "length" "4,4,4,4,4,4,4")])
1391
1392 (define_insn ""
1393   [(set (match_operand:SI 0 "register_operand" "=r")
1394         (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1395                          (match_operand:SI 2 "register_operand" "r"))))]
1396   "! TARGET_DISABLE_INDEXING"
1397   "*
1398 {
1399   /* Reload can create backwards (relative to cse) unscaled index
1400      address modes when eliminating registers and possibly for
1401      pseudos that don't get hard registers.  Deal with it.  */
1402   if (operands[2] == hard_frame_pointer_rtx
1403       || operands[2] == stack_pointer_rtx)
1404     return \"ldwx %1(0,%2),%0\";
1405   else
1406     return \"ldwx %2(0,%1),%0\";
1407 }"
1408   [(set_attr "type" "load")
1409    (set_attr "length" "4")])
1410
1411 (define_insn ""
1412   [(set (match_operand:SI 0 "register_operand" "=r")
1413         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
1414                          (match_operand:SI 2 "basereg_operand" "r"))))]
1415   "! TARGET_DISABLE_INDEXING"
1416   "*
1417 {
1418   /* Reload can create backwards (relative to cse) unscaled index
1419      address modes when eliminating registers and possibly for
1420      pseudos that don't get hard registers.  Deal with it.  */
1421   if (operands[1] == hard_frame_pointer_rtx
1422       || operands[1] == stack_pointer_rtx)
1423     return \"ldwx %2(0,%1),%0\";
1424   else
1425     return \"ldwx %1(0,%2),%0\";
1426 }"
1427   [(set_attr "type" "load")
1428    (set_attr "length" "4")])
1429
1430 ;; Load or store with base-register modification.
1431
1432 (define_insn "pre_ldwm"
1433   [(set (match_operand:SI 0 "register_operand" "=r")
1434         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1435                          (match_operand:SI 2 "pre_cint_operand" ""))))
1436    (set (match_dup 1)
1437         (plus:SI (match_dup 1) (match_dup 2)))]
1438   ""
1439   "*
1440 {
1441   if (INTVAL (operands[2]) < 0)
1442     return \"ldwm %2(0,%1),%0\";
1443   return \"ldws,mb %2(0,%1),%0\";
1444 }"
1445   [(set_attr "type" "load")
1446    (set_attr "length" "4")])
1447
1448 (define_insn "pre_stwm"
1449   [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1450                          (match_operand:SI 1 "pre_cint_operand" "")))
1451         (match_operand:SI 2 "reg_or_0_operand" "rM"))
1452    (set (match_dup 0)
1453         (plus:SI (match_dup 0) (match_dup 1)))]
1454   ""
1455   "*
1456 {
1457   if (INTVAL (operands[1]) < 0)
1458     return \"stwm %r2,%1(0,%0)\";
1459   return \"stws,mb %r2,%1(0,%0)\";
1460 }"
1461   [(set_attr "type" "store")
1462    (set_attr "length" "4")])
1463
1464 (define_insn "post_ldwm"
1465   [(set (match_operand:SI 0 "register_operand" "=r")
1466         (mem:SI (match_operand:SI 1 "register_operand" "+r")))
1467    (set (match_dup 1)
1468         (plus:SI (match_dup 1)
1469                  (match_operand:SI 2 "post_cint_operand" "")))]
1470   ""
1471   "*
1472 {
1473   if (INTVAL (operands[2]) > 0)
1474     return \"ldwm %2(0,%1),%0\";
1475   return \"ldws,ma %2(0,%1),%0\";
1476 }"
1477   [(set_attr "type" "load")
1478    (set_attr "length" "4")])
1479
1480 (define_insn "post_stwm"
1481   [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
1482         (match_operand:SI 1 "reg_or_0_operand" "rM"))
1483    (set (match_dup 0)
1484         (plus:SI (match_dup 0)
1485                  (match_operand:SI 2 "post_cint_operand" "")))]
1486   ""
1487   "*
1488 {
1489   if (INTVAL (operands[2]) > 0)
1490     return \"stwm %r1,%2(0,%0)\";
1491   return \"stws,ma %r1,%2(0,%0)\";
1492 }"
1493   [(set_attr "type" "store")
1494    (set_attr "length" "4")])
1495
1496 ;; For pic
1497 ;; Note since this pattern can be created at reload time (via movsi), all
1498 ;; the same rules for movsi apply here.  (no new pseudos, no temporaries).
1499 (define_insn "pic_load_label"
1500   [(set (match_operand:SI 0 "register_operand" "=a")
1501         (match_operand:SI 1 "pic_label_operand" ""))]
1502   ""
1503   "*
1504 {
1505   rtx label_rtx = gen_label_rtx ();
1506   rtx xoperands[3];
1507   extern FILE *asm_out_file;
1508
1509   xoperands[0] = operands[0];
1510   xoperands[1] = operands[1];
1511   xoperands[2] = label_rtx;
1512   output_asm_insn (\"bl .+8,%0\", xoperands);
1513   output_asm_insn (\"depi 0,31,2,%0\", xoperands);
1514   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1515                              CODE_LABEL_NUMBER (label_rtx));
1516
1517   /* If we're trying to load the address of a label that happens to be
1518      close, then we can use a shorter sequence.  */
1519   if (GET_CODE (operands[1]) == LABEL_REF
1520       && insn_addresses
1521       && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
1522                 - insn_addresses[INSN_UID (insn)]) < 8100)
1523     {
1524       /* Prefixing with R% here is wrong, it extracts just 11 bits and is
1525          always non-negative.  */
1526       output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
1527     }
1528   else
1529     {
1530       output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
1531       output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
1532     }
1533   return \"\";
1534 }"
1535   [(set_attr "type" "multi")
1536    (set_attr "length" "16")])           ; 12 or 16
1537
1538 (define_insn "pic2_highpart"
1539   [(set (match_operand:SI 0 "register_operand" "=a")
1540         (plus:SI (match_operand:SI 1 "register_operand" "r")
1541                  (high:SI (match_operand 2 "" ""))))]
1542   "symbolic_operand (operands[2], Pmode)
1543    && ! function_label_operand (operands[2])
1544    && flag_pic == 2"
1545   "addil LT'%G2,%1"
1546   [(set_attr "type" "binary")
1547    (set_attr "length" "4")])
1548
1549 ; We need this to make sure CSE doesn't simplify a memory load with a
1550 ; symbolic address, whose content it think it knows.  For PIC, what CSE
1551 ; think is the real value will be the address of that value.
1552 (define_insn "pic2_lo_sum"
1553   [(set (match_operand:SI 0 "register_operand" "=r")
1554         (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1555                            (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
1556   ""
1557   "*
1558 {
1559   if (flag_pic != 2)
1560     abort ();
1561   return \"ldw RT'%G2(%1),%0\";
1562 }"
1563   [(set_attr "type" "load")
1564    (set_attr "length" "4")])
1565
1566
1567 ;; Always use addil rather than ldil;add sequences.  This allows the
1568 ;; HP linker to eliminate the dp relocation if the symbolic operand
1569 ;; lives in the TEXT space.
1570 (define_insn ""
1571   [(set (match_operand:SI 0 "register_operand" "=a")
1572         (high:SI (match_operand 1 "" "")))]
1573   "symbolic_operand (operands[1], Pmode)
1574    && ! function_label_operand (operands[1])
1575    && ! read_only_operand (operands[1])
1576    && ! flag_pic"
1577   "*
1578 {
1579   if (TARGET_LONG_LOAD_STORE)
1580     return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
1581   else
1582     return \"addil LR'%H1,%%r27\";
1583 }"
1584   [(set_attr "type" "binary")
1585    (set (attr "length")
1586       (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
1587                     (const_int 4)
1588                     (const_int 8)))])
1589
1590
1591 ;; This is for use in the prologue/epilogue code.  We need it
1592 ;; to add large constants to a stack pointer or frame pointer.
1593 ;; Because of the additional %r1 pressure, we probably do not
1594 ;; want to use this in general code, so make it available
1595 ;; only after reload.
1596 (define_insn "add_high_const"
1597   [(set (match_operand:SI 0 "register_operand" "=!a,*r")
1598         (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1599                  (high:SI (match_operand 2 "const_int_operand" ""))))]
1600   "reload_completed"
1601   "@
1602    addil L'%G2,%1
1603    ldil L'%G2,%0\;addl %0,%1,%0"
1604   [(set_attr "type" "binary,binary")
1605    (set_attr "length" "4,8")])
1606
1607 (define_insn ""
1608   [(set (match_operand:SI 0 "register_operand" "=r")
1609         (high:SI (match_operand 1 "" "")))]
1610   "(!flag_pic || !symbolic_operand (operands[1]), Pmode)
1611     && !is_function_label_plus_const (operands[1])"
1612   "*
1613 {
1614   if (symbolic_operand (operands[1], Pmode))
1615     return \"ldil LR'%H1,%0\";
1616   else
1617     return \"ldil L'%G1,%0\";
1618 }"
1619   [(set_attr "type" "move")
1620    (set_attr "length" "4")])
1621
1622 (define_insn ""
1623   [(set (match_operand:SI 0 "register_operand" "=r")
1624         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1625                    (match_operand:SI 2 "immediate_operand" "i")))]
1626   "!is_function_label_plus_const (operands[2])"
1627   "*
1628 {
1629   if (flag_pic && symbolic_operand (operands[2], Pmode))
1630     abort ();
1631   else if (symbolic_operand (operands[2], Pmode))
1632     return \"ldo RR'%G2(%1),%0\";
1633   else
1634     return \"ldo R'%G2(%1),%0\";
1635 }"
1636   [(set_attr "type" "move")
1637    (set_attr "length" "4")])
1638
1639 ;; Now that a symbolic_address plus a constant is broken up early
1640 ;; in the compilation phase (for better CSE) we need a special
1641 ;; combiner pattern to load the symbolic address plus the constant
1642 ;; in only 2 instructions. (For cases where the symbolic address
1643 ;; was not a common subexpression.)
1644 (define_split
1645   [(set (match_operand:SI 0 "register_operand" "")
1646         (match_operand:SI 1 "symbolic_operand" ""))
1647    (clobber (match_operand:SI 2 "register_operand" ""))]
1648   "! (flag_pic && pic_label_operand (operands[1], SImode))"
1649   [(set (match_dup 2) (high:SI (match_dup 1)))
1650    (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
1651   "")
1652
1653 ;; hppa_legitimize_address goes to a great deal of trouble to
1654 ;; create addresses which use indexing.  In some cases, this
1655 ;; is a lose because there isn't any store instructions which
1656 ;; allow indexed addresses (with integer register source).
1657 ;;
1658 ;; These define_splits try to turn a 3 insn store into
1659 ;; a 2 insn store with some creative RTL rewriting.
1660 (define_split
1661   [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1662                                (match_operand:SI 1 "shadd_operand" ""))
1663                    (plus:SI (match_operand:SI 2 "register_operand" "")
1664                             (match_operand:SI 3 "const_int_operand" ""))))
1665         (match_operand:SI 4 "register_operand" ""))
1666    (clobber (match_operand:SI 5 "register_operand" ""))]
1667   ""
1668   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1669                                (match_dup 2)))
1670    (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1671   "")
1672
1673 (define_split
1674   [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1675                                (match_operand:SI 1 "shadd_operand" ""))
1676                    (plus:SI (match_operand:SI 2 "register_operand" "")
1677                             (match_operand:SI 3 "const_int_operand" ""))))
1678         (match_operand:HI 4 "register_operand" ""))
1679    (clobber (match_operand:SI 5 "register_operand" ""))]
1680   ""
1681   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1682                                (match_dup 2)))
1683    (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1684   "")
1685
1686 (define_split
1687   [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
1688                                (match_operand:SI 1 "shadd_operand" ""))
1689                    (plus:SI (match_operand:SI 2 "register_operand" "")
1690                             (match_operand:SI 3 "const_int_operand" ""))))
1691         (match_operand:QI 4 "register_operand" ""))
1692    (clobber (match_operand:SI 5 "register_operand" ""))]
1693   ""
1694   [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
1695                                (match_dup 2)))
1696    (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
1697   "")
1698
1699 (define_expand "movhi"
1700   [(set (match_operand:HI 0 "general_operand" "")
1701         (match_operand:HI 1 "general_operand" ""))]
1702   ""
1703   "
1704 {
1705   if (emit_move_sequence (operands, HImode, 0))
1706     DONE;
1707 }")
1708
1709 (define_insn ""
1710   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
1711         (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
1712   "register_operand (operands[0], HImode)
1713    || reg_or_0_operand (operands[1], HImode)"
1714   "@
1715    copy %1,%0
1716    ldi %1,%0
1717    ldil L'%1,%0
1718    zdepi %Z1,%0
1719    ldh%M1 %1,%0
1720    sth%M0 %r1,%0
1721    mtsar %r1
1722    fcpy,sgl %r1,%0"
1723   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1724    (set_attr "pa_combine_type" "addmove")
1725    (set_attr "length" "4,4,4,4,4,4,4,4")])
1726
1727 (define_insn ""
1728   [(set (match_operand:HI 0 "register_operand" "=r")
1729         (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1730                          (match_operand:SI 2 "register_operand" "r"))))]
1731   "! TARGET_DISABLE_INDEXING"
1732   "*
1733 {
1734   /* Reload can create backwards (relative to cse) unscaled index
1735      address modes when eliminating registers and possibly for
1736      pseudos that don't get hard registers.  Deal with it.  */
1737   if (operands[2] == hard_frame_pointer_rtx
1738       || operands[2] == stack_pointer_rtx)
1739     return \"ldhx %1(0,%2),%0\";
1740   else
1741     return \"ldhx %2(0,%1),%0\";
1742 }"
1743   [(set_attr "type" "load")
1744    (set_attr "length" "4")])
1745
1746 (define_insn ""
1747   [(set (match_operand:HI 0 "register_operand" "=r")
1748         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
1749                          (match_operand:SI 2 "basereg_operand" "r"))))]
1750   "! TARGET_DISABLE_INDEXING"
1751   "*
1752 {
1753   /* Reload can create backwards (relative to cse) unscaled index
1754      address modes when eliminating registers and possibly for
1755      pseudos that don't get hard registers.  Deal with it.  */
1756   if (operands[1] == hard_frame_pointer_rtx
1757       || operands[1] == stack_pointer_rtx)
1758     return \"ldhx %2(0,%1),%0\";
1759   else
1760     return \"ldhx %1(0,%2),%0\";
1761 }"
1762   [(set_attr "type" "load")
1763    (set_attr "length" "4")])
1764
1765 ; Now zero extended variants.
1766 (define_insn ""
1767   [(set (match_operand:SI 0 "register_operand" "=r")
1768         (zero_extend:SI (mem:HI
1769                           (plus:SI
1770                             (match_operand:SI 1 "basereg_operand" "r")
1771                             (match_operand:SI 2 "register_operand" "r")))))]
1772   "! TARGET_DISABLE_INDEXING"
1773   "*
1774 {
1775   /* Reload can create backwards (relative to cse) unscaled index
1776      address modes when eliminating registers and possibly for
1777      pseudos that don't get hard registers.  Deal with it.  */
1778   if (operands[2] == hard_frame_pointer_rtx
1779       || operands[2] == stack_pointer_rtx)
1780     return \"ldhx %1(0,%2),%0\";
1781   else
1782     return \"ldhx %2(0,%1),%0\";
1783 }"
1784   [(set_attr "type" "load")
1785    (set_attr "length" "4")])
1786
1787 (define_insn ""
1788   [(set (match_operand:SI 0 "register_operand" "=r")
1789         (zero_extend:SI (mem:HI
1790                           (plus:SI
1791                              (match_operand:SI 1 "register_operand" "r")
1792                              (match_operand:SI 2 "basereg_operand" "r")))))]
1793   "! TARGET_DISABLE_INDEXING"
1794   "*
1795 {
1796   /* Reload can create backwards (relative to cse) unscaled index
1797      address modes when eliminating registers and possibly for
1798      pseudos that don't get hard registers.  Deal with it.  */
1799   if (operands[1] == hard_frame_pointer_rtx
1800       || operands[1] == stack_pointer_rtx)
1801     return \"ldhx %2(0,%1),%0\";
1802   else
1803     return \"ldhx %1(0,%2),%0\";
1804 }"
1805   [(set_attr "type" "load")
1806    (set_attr "length" "4")])
1807
1808 (define_insn ""
1809   [(set (match_operand:HI 0 "register_operand" "=r")
1810         (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
1811                          (match_operand:SI 2 "int5_operand" "L"))))
1812    (set (match_dup 1)
1813         (plus:SI (match_dup 1) (match_dup 2)))]
1814   ""
1815   "ldhs,mb %2(0,%1),%0"
1816   [(set_attr "type" "load")
1817    (set_attr "length" "4")])
1818
1819 ; And a zero extended variant.
1820 (define_insn ""
1821   [(set (match_operand:SI 0 "register_operand" "=r")
1822         (zero_extend:SI (mem:HI
1823                           (plus:SI
1824                             (match_operand:SI 1 "register_operand" "+r")
1825                             (match_operand:SI 2 "int5_operand" "L")))))
1826    (set (match_dup 1)
1827         (plus:SI (match_dup 1) (match_dup 2)))]
1828   ""
1829   "ldhs,mb %2(0,%1),%0"
1830   [(set_attr "type" "load")
1831    (set_attr "length" "4")])
1832
1833 (define_insn ""
1834   [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
1835                          (match_operand:SI 1 "int5_operand" "L")))
1836         (match_operand:HI 2 "reg_or_0_operand" "rM"))
1837    (set (match_dup 0)
1838         (plus:SI (match_dup 0) (match_dup 1)))]
1839   ""
1840   "sths,mb %r2,%1(0,%0)"
1841   [(set_attr "type" "store")
1842    (set_attr "length" "4")])
1843
1844 (define_insn ""
1845   [(set (match_operand:HI 0 "register_operand" "=r")
1846         (high:HI (match_operand 1 "const_int_operand" "")))]
1847   ""
1848   "ldil L'%G1,%0"
1849   [(set_attr "type" "move")
1850    (set_attr "length" "4")])
1851
1852 (define_insn ""
1853   [(set (match_operand:HI 0 "register_operand" "=r")
1854         (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1855                    (match_operand 2 "const_int_operand" "")))]
1856   ""
1857   "ldo R'%G2(%1),%0"
1858   [(set_attr "type" "move")
1859    (set_attr "length" "4")])
1860
1861 (define_expand "movqi"
1862   [(set (match_operand:QI 0 "general_operand" "")
1863         (match_operand:QI 1 "general_operand" ""))]
1864   ""
1865   "
1866 {
1867   if (emit_move_sequence (operands, QImode, 0))
1868     DONE;
1869 }")
1870
1871 (define_insn ""
1872   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
1873         (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
1874   "register_operand (operands[0], QImode)
1875    || reg_or_0_operand (operands[1], QImode)"
1876   "@
1877    copy %1,%0
1878    ldi %1,%0
1879    ldil L'%1,%0
1880    zdepi %Z1,%0
1881    ldb%M1 %1,%0
1882    stb%M0 %r1,%0
1883    mtsar %r1
1884    fcpy,sgl %r1,%0"
1885   [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
1886    (set_attr "pa_combine_type" "addmove")
1887    (set_attr "length" "4,4,4,4,4,4,4,4")])
1888
1889 (define_insn ""
1890   [(set (match_operand:QI 0 "register_operand" "=r")
1891         (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
1892                          (match_operand:SI 2 "register_operand" "r"))))]
1893   "! TARGET_DISABLE_INDEXING"
1894   "*
1895 {
1896   /* Reload can create backwards (relative to cse) unscaled index
1897      address modes when eliminating registers and possibly for
1898      pseudos that don't get hard registers.  Deal with it.  */
1899   if (operands[2] == hard_frame_pointer_rtx
1900       || operands[2] == stack_pointer_rtx)
1901     return \"ldbx %1(0,%2),%0\";
1902   else
1903     return \"ldbx %2(0,%1),%0\";
1904 }"
1905   [(set_attr "type" "load")
1906    (set_attr "length" "4")])
1907
1908 (define_insn ""
1909   [(set (match_operand:QI 0 "register_operand" "=r")
1910         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
1911                          (match_operand:SI 2 "basereg_operand" "r"))))]
1912   "! TARGET_DISABLE_INDEXING"
1913   "*
1914 {
1915   /* Reload can create backwards (relative to cse) unscaled index
1916      address modes when eliminating registers and possibly for
1917      pseudos that don't get hard registers.  Deal with it.  */
1918   if (operands[1] == hard_frame_pointer_rtx
1919       || operands[1] == stack_pointer_rtx)
1920     return \"ldbx %2(0,%1),%0\";
1921   else
1922     return \"ldbx %1(0,%2),%0\";
1923 }"
1924   [(set_attr "type" "load")
1925    (set_attr "length" "4")])
1926
1927 ; Indexed byte load with zero extension to SImode or HImode.
1928 (define_insn ""
1929   [(set (match_operand:SI 0 "register_operand" "=r")
1930         (zero_extend:SI (mem:QI
1931                           (plus:SI
1932                             (match_operand:SI 1 "basereg_operand" "r")
1933                             (match_operand:SI 2 "register_operand" "r")))))]
1934   "! TARGET_DISABLE_INDEXING"
1935   "*
1936 {
1937   /* Reload can create backwards (relative to cse) unscaled index
1938      address modes when eliminating registers and possibly for
1939      pseudos that don't get hard registers.  Deal with it.  */
1940   if (operands[2] == hard_frame_pointer_rtx
1941       || operands[2] == stack_pointer_rtx)
1942     return \"ldbx %1(0,%2),%0\";
1943   else
1944     return \"ldbx %2(0,%1),%0\";
1945 }"
1946   [(set_attr "type" "load")
1947    (set_attr "length" "4")])
1948
1949 (define_insn ""
1950   [(set (match_operand:SI 0 "register_operand" "=r")
1951         (zero_extend:SI (mem:QI
1952                           (plus:SI
1953                             (match_operand:SI 1 "register_operand" "r")
1954                             (match_operand:SI 2 "basereg_operand" "r")))))]
1955   "! TARGET_DISABLE_INDEXING"
1956   "*
1957 {
1958   /* Reload can create backwards (relative to cse) unscaled index
1959      address modes when eliminating registers and possibly for
1960      pseudos that don't get hard registers.  Deal with it.  */
1961   if (operands[1] == hard_frame_pointer_rtx
1962       || operands[1] == stack_pointer_rtx)
1963     return \"ldbx %2(0,%1),%0\";
1964   else
1965     return \"ldbx %1(0,%2),%0\";
1966 }"
1967   [(set_attr "type" "load")
1968    (set_attr "length" "4")])
1969
1970 (define_insn ""
1971   [(set (match_operand:HI 0 "register_operand" "=r")
1972         (zero_extend:HI (mem:QI
1973                           (plus:SI
1974                             (match_operand:SI 1 "basereg_operand" "r")
1975                             (match_operand:SI 2 "register_operand" "r")))))]
1976   "! TARGET_DISABLE_INDEXING"
1977   "*
1978 {
1979   /* Reload can create backwards (relative to cse) unscaled index
1980      address modes when eliminating registers and possibly for
1981      pseudos that don't get hard registers.  Deal with it.  */
1982   if (operands[2] == hard_frame_pointer_rtx
1983       || operands[2] == stack_pointer_rtx)
1984     return \"ldbx %1(0,%2),%0\";
1985   else
1986     return \"ldbx %2(0,%1),%0\";
1987 }"
1988   [(set_attr "type" "load")
1989    (set_attr "length" "4")])
1990
1991 (define_insn ""
1992   [(set (match_operand:HI 0 "register_operand" "=r")
1993         (zero_extend:HI (mem:QI
1994                           (plus:SI
1995                             (match_operand:SI 1 "register_operand" "r")
1996                             (match_operand:SI 2 "basereg_operand" "r")))))]
1997   "! TARGET_DISABLE_INDEXING"
1998   "*
1999 {
2000   /* Reload can create backwards (relative to cse) unscaled index
2001      address modes when eliminating registers and possibly for
2002      pseudos that don't get hard registers.  Deal with it.  */
2003   if (operands[1] == hard_frame_pointer_rtx
2004       || operands[1] == stack_pointer_rtx)
2005     return \"ldbx %2(0,%1),%0\";
2006   else
2007     return \"ldbx %1(0,%2),%0\";
2008 }"
2009   [(set_attr "type" "load")
2010    (set_attr "length" "4")])
2011
2012 (define_insn ""
2013   [(set (match_operand:QI 0 "register_operand" "=r")
2014         (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
2015                          (match_operand:SI 2 "int5_operand" "L"))))
2016    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2017   ""
2018   "ldbs,mb %2(0,%1),%0"
2019   [(set_attr "type" "load")
2020    (set_attr "length" "4")])
2021
2022 ; Now the same thing with zero extensions.
2023 (define_insn ""
2024   [(set (match_operand:SI 0 "register_operand" "=r")
2025         (zero_extend:SI (mem:QI (plus:SI
2026                                   (match_operand:SI 1 "register_operand" "+r")
2027                                   (match_operand:SI 2 "int5_operand" "L")))))
2028    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2029   ""
2030   "ldbs,mb %2(0,%1),%0"
2031   [(set_attr "type" "load")
2032    (set_attr "length" "4")])
2033
2034 (define_insn ""
2035   [(set (match_operand:HI 0 "register_operand" "=r")
2036         (zero_extend:HI (mem:QI (plus:SI
2037                                   (match_operand:SI 1 "register_operand" "+r")
2038                                   (match_operand:SI 2 "int5_operand" "L")))))
2039    (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
2040   ""
2041   "ldbs,mb %2(0,%1),%0"
2042   [(set_attr "type" "load")
2043    (set_attr "length" "4")])
2044
2045 (define_insn ""
2046   [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
2047                          (match_operand:SI 1 "int5_operand" "L")))
2048         (match_operand:QI 2 "reg_or_0_operand" "rM"))
2049    (set (match_dup 0)
2050         (plus:SI (match_dup 0) (match_dup 1)))]
2051   ""
2052   "stbs,mb %r2,%1(0,%0)"
2053   [(set_attr "type" "store")
2054    (set_attr "length" "4")])
2055
2056 ;; The definition of this insn does not really explain what it does,
2057 ;; but it should suffice
2058 ;; that anything generated as this insn will be recognized as one
2059 ;; and that it will not successfully combine with anything.
2060 (define_expand "movstrsi"
2061   [(parallel [(set (match_operand:BLK 0 "" "")
2062                    (match_operand:BLK 1 "" ""))
2063               (clobber (match_dup 7))
2064               (clobber (match_dup 8))
2065               (clobber (match_dup 4))
2066               (clobber (match_dup 5))
2067               (clobber (match_dup 6))
2068               (use (match_operand:SI 2 "arith_operand" ""))
2069               (use (match_operand:SI 3 "const_int_operand" ""))])]
2070   ""
2071   "
2072 {
2073   int size, align;
2074
2075   /* HP provides very fast block move library routine for the PA;
2076      this routine includes:
2077
2078         4x4 byte at a time block moves,
2079         1x4 byte at a time with alignment checked at runtime with
2080             attempts to align the source and destination as needed
2081         1x1 byte loop
2082
2083      With that in mind, here's the heuristics to try and guess when
2084      the inlined block move will be better than the library block
2085      move:
2086
2087         If the size isn't constant, then always use the library routines.
2088
2089         If the size is large in respect to the known alignment, then use
2090         the library routines.
2091
2092         If the size is small in repsect to the known alignment, then open
2093         code the copy (since that will lead to better scheduling).
2094
2095         Else use the block move pattern.   */
2096
2097   /* Undetermined size, use the library routine.  */
2098   if (GET_CODE (operands[2]) != CONST_INT)
2099     FAIL;
2100
2101   size = INTVAL (operands[2]);
2102   align = INTVAL (operands[3]);
2103   align = align > 4 ? 4 : align;
2104
2105   /* If size/alignment > 8 (eg size is large in respect to alignment),
2106      then use the library routines.  */
2107   if (size / align > 16)
2108     FAIL;
2109
2110   /* This does happen, but not often enough to worry much about.  */
2111   if (size / align < MOVE_RATIO)
2112     FAIL;
2113   
2114   /* Fall through means we're going to use our block move pattern.  */
2115   operands[0]
2116     = change_address (operands[0], VOIDmode,
2117                       copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
2118   operands[1]
2119     = change_address (operands[1], VOIDmode,
2120                       copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
2121   operands[4] = gen_reg_rtx (SImode);
2122   operands[5] = gen_reg_rtx (SImode);
2123   operands[6] = gen_reg_rtx (SImode);
2124   operands[7] = XEXP (operands[0], 0);
2125   operands[8] = XEXP (operands[1], 0);
2126 }")
2127
2128 ;; The operand constraints are written like this to support both compile-time
2129 ;; and run-time determined byte count.  If the count is run-time determined,
2130 ;; the register with the byte count is clobbered by the copying code, and
2131 ;; therefore it is forced to operand 2.  If the count is compile-time
2132 ;; determined, we need two scratch registers for the unrolled code.
2133 (define_insn "movstrsi_internal"
2134   [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
2135         (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
2136    (clobber (match_dup 0))
2137    (clobber (match_dup 1))
2138    (clobber (match_operand:SI 2 "register_operand" "=r,r"))     ;loop cnt/tmp
2139    (clobber (match_operand:SI 3 "register_operand" "=&r,&r"))   ;item tmp
2140    (clobber (match_operand:SI 6 "register_operand" "=&r,&r"))   ;item tmp2
2141    (use (match_operand:SI 4 "arith_operand" "J,2"))      ;byte count
2142    (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
2143   ""
2144   "* return output_block_move (operands, !which_alternative);"
2145   [(set_attr "type" "multi,multi")])
2146 \f
2147 ;; Floating point move insns
2148
2149 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2150 ;; to be reloaded by putting the constant into memory when
2151 ;; reg is a floating point register.
2152 ;;
2153 ;; For integer registers we use ldil;ldo to set the appropriate
2154 ;; value.
2155 ;;
2156 ;; This must come before the movdf pattern, and it must be present
2157 ;; to handle obscure reloading cases.
2158 (define_insn ""
2159   [(set (match_operand:DF 0 "register_operand" "=?r,f")
2160         (match_operand:DF 1 "" "?F,m"))]
2161   "GET_CODE (operands[1]) == CONST_DOUBLE
2162    && operands[1] != CONST0_RTX (DFmode)
2163    && ! TARGET_SOFT_FLOAT"
2164   "* return (which_alternative == 0 ? output_move_double (operands)
2165                                     : \"fldd%F1 %1,%0\");"
2166   [(set_attr "type" "move,fpload")
2167    (set_attr "length" "16,4")])
2168
2169 (define_expand "movdf"
2170   [(set (match_operand:DF 0 "general_operand" "")
2171         (match_operand:DF 1 "general_operand" ""))]
2172   ""
2173   "
2174 {
2175   if (emit_move_sequence (operands, DFmode, 0))
2176     DONE;
2177 }")
2178
2179 ;; Reloading an SImode or DImode value requires a scratch register if
2180 ;; going in to or out of float point registers.
2181
2182 (define_expand "reload_indf"
2183   [(set (match_operand:DF 0 "register_operand" "=Z")
2184         (match_operand:DF 1 "non_hard_reg_operand" ""))
2185    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2186   ""
2187   "
2188 {
2189   if (emit_move_sequence (operands, DFmode, operands[2]))
2190     DONE;
2191
2192   /* We don't want the clobber emitted, so handle this ourselves.  */
2193   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2194   DONE;
2195 }")
2196
2197 (define_expand "reload_outdf" 
2198  [(set (match_operand:DF 0 "non_hard_reg_operand" "")
2199         (match_operand:DF 1  "register_operand" "Z"))
2200    (clobber (match_operand:DF 2 "register_operand" "=&r"))]
2201   ""
2202   "
2203 {
2204   if (emit_move_sequence (operands, DFmode, operands[2]))
2205     DONE;
2206
2207   /* We don't want the clobber emitted, so handle this ourselves.  */
2208   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2209   DONE;
2210 }")
2211
2212 (define_insn ""
2213   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2214                           "=f,*r,RQ,?o,?Q,f,*r,*r")
2215         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2216                           "fG,*rG,f,*r,*r,RQ,o,RQ"))]
2217   "(register_operand (operands[0], DFmode)
2218     || reg_or_0_operand (operands[1], DFmode))
2219    && ! (GET_CODE (operands[1]) == CONST_DOUBLE
2220          && GET_CODE (operands[0]) == MEM)
2221    && ! TARGET_SOFT_FLOAT"
2222   "*
2223 {
2224   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2225       || operands[1] == CONST0_RTX (DFmode))
2226     return output_fp_move_double (operands);
2227   return output_move_double (operands);
2228 }"
2229   [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
2230    (set_attr "length" "4,8,4,8,16,4,8,16")])
2231
2232 (define_insn ""
2233   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
2234                           "=r,?o,?Q,r,r")
2235         (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
2236                           "rG,r,r,o,Q"))]
2237   "(register_operand (operands[0], DFmode)
2238     || reg_or_0_operand (operands[1], DFmode))
2239    && TARGET_SOFT_FLOAT"
2240   "*
2241 {
2242   return output_move_double (operands);
2243 }"
2244   [(set_attr "type" "move,store,store,load,load")
2245    (set_attr "length" "8,8,16,8,16")])
2246
2247 (define_insn ""
2248   [(set (match_operand:DF 0 "register_operand" "=fx")
2249         (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2250                          (match_operand:SI 2 "register_operand" "r"))))]
2251   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2252   "*
2253 {
2254   /* Reload can create backwards (relative to cse) unscaled index
2255      address modes when eliminating registers and possibly for
2256      pseudos that don't get hard registers.  Deal with it.  */
2257   if (operands[2] == hard_frame_pointer_rtx
2258       || operands[2] == stack_pointer_rtx)
2259     return \"flddx %1(0,%2),%0\";
2260   else
2261     return \"flddx %2(0,%1),%0\";
2262 }"
2263   [(set_attr "type" "fpload")
2264    (set_attr "length" "4")])
2265
2266 (define_insn ""
2267   [(set (match_operand:DF 0 "register_operand" "=fx")
2268         (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2269                          (match_operand:SI 2 "basereg_operand" "r"))))]
2270   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2271   "*
2272 {
2273   /* Reload can create backwards (relative to cse) unscaled index
2274      address modes when eliminating registers and possibly for
2275      pseudos that don't get hard registers.  Deal with it.  */
2276   if (operands[1] == hard_frame_pointer_rtx
2277       || operands[1] == stack_pointer_rtx)
2278     return \"flddx %2(0,%1),%0\";
2279   else
2280     return \"flddx %1(0,%2),%0\";
2281 }"
2282   [(set_attr "type" "fpload")
2283    (set_attr "length" "4")])
2284
2285 (define_insn ""
2286   [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2287                          (match_operand:SI 2 "register_operand" "r")))
2288         (match_operand:DF 0 "register_operand" "fx"))]
2289   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2290   "*
2291 {
2292   /* Reload can create backwards (relative to cse) unscaled index
2293      address modes when eliminating registers and possibly for
2294      pseudos that don't get hard registers.  Deal with it.  */
2295   if (operands[2] == hard_frame_pointer_rtx
2296       || operands[2] == stack_pointer_rtx)
2297     return \"fstdx %0,%1(0,%2)\";
2298   else
2299     return \"fstdx %0,%2(0,%1)\";
2300 }"
2301   [(set_attr "type" "fpstore")
2302    (set_attr "length" "4")])
2303
2304 (define_insn ""
2305   [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
2306                          (match_operand:SI 2 "basereg_operand" "r")))
2307         (match_operand:DF 0 "register_operand" "fx"))]
2308   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2309   "*
2310 {
2311   /* Reload can create backwards (relative to cse) unscaled index
2312      address modes when eliminating registers and possibly for
2313      pseudos that don't get hard registers.  Deal with it.  */
2314   if (operands[1] == hard_frame_pointer_rtx
2315       || operands[1] == stack_pointer_rtx)
2316     return \"fstdx %0,%2(0,%1)\";
2317   else
2318     return \"fstdx %0,%1(0,%2)\";
2319 }"
2320   [(set_attr "type" "fpstore")
2321    (set_attr "length" "4")])
2322
2323 (define_expand "movdi"
2324   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2325         (match_operand:DI 1 "general_operand" ""))]
2326   ""
2327   "
2328 {
2329   if (emit_move_sequence (operands, DImode, 0))
2330     DONE;
2331 }")
2332
2333 (define_expand "reload_indi"
2334   [(set (match_operand:DI 0 "register_operand" "=f")
2335         (match_operand:DI 1 "non_hard_reg_operand" ""))
2336    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2337   ""
2338   "
2339 {
2340   if (emit_move_sequence (operands, DImode, operands[2]))
2341     DONE;
2342
2343   /* We don't want the clobber emitted, so handle this ourselves.  */
2344   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2345   DONE;
2346 }")
2347
2348 (define_expand "reload_outdi"
2349   [(set (match_operand:DI 0 "general_operand" "")
2350         (match_operand:DI 1 "register_operand" "f"))
2351    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
2352   ""
2353   "
2354 {
2355   if (emit_move_sequence (operands, DImode, operands[2]))
2356     DONE;
2357
2358   /* We don't want the clobber emitted, so handle this ourselves.  */
2359   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2360   DONE;
2361 }")
2362
2363 (define_insn ""
2364   [(set (match_operand:DI 0 "register_operand" "=r")
2365         (high:DI (match_operand 1 "" "")))]
2366   ""
2367   "*
2368 {
2369   rtx op0 = operands[0];
2370   rtx op1 = operands[1];
2371
2372   if (GET_CODE (op1) == CONST_INT)
2373     {
2374       operands[0] = operand_subword (op0, 1, 0, DImode);
2375       output_asm_insn (\"ldil L'%1,%0\", operands);
2376
2377       operands[0] = operand_subword (op0, 0, 0, DImode);
2378       if (INTVAL (op1) < 0)
2379         output_asm_insn (\"ldi -1,%0\", operands);
2380       else
2381         output_asm_insn (\"ldi 0,%0\", operands);
2382       return \"\";
2383     }
2384   else if (GET_CODE (op1) == CONST_DOUBLE)
2385     {
2386       operands[0] = operand_subword (op0, 1, 0, DImode);
2387       operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
2388       output_asm_insn (\"ldil L'%1,%0\", operands);
2389
2390       operands[0] = operand_subword (op0, 0, 0, DImode);
2391       operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
2392       output_asm_insn (singlemove_string (operands), operands);
2393       return \"\";
2394     }
2395   else
2396     abort ();
2397 }"
2398   [(set_attr "type" "move")
2399    (set_attr "length" "8")])
2400
2401 ;;; Experimental
2402
2403 (define_insn ""
2404   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2405                           "=r,o,Q,r,r,r,f,f,*TR")
2406         (match_operand:DI 1 "general_operand"
2407                           "rM,r,r,o*R,Q,i,fM,*TR,f"))]
2408   "(register_operand (operands[0], DImode)
2409     || reg_or_0_operand (operands[1], DImode))
2410    && ! TARGET_SOFT_FLOAT"
2411   "*
2412 {
2413   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
2414       || (operands[1] == CONST0_RTX (DImode)))
2415     return output_fp_move_double (operands);
2416   return output_move_double (operands);
2417 }"
2418   [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
2419    (set_attr "length" "8,8,16,8,16,16,4,4,4")])
2420
2421 (define_insn ""
2422   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
2423                           "=r,o,Q,r,r,r")
2424         (match_operand:DI 1 "general_operand"
2425                           "rM,r,r,o,Q,i"))]
2426   "(register_operand (operands[0], DImode)
2427     || reg_or_0_operand (operands[1], DImode))
2428    && TARGET_SOFT_FLOAT"
2429   "*
2430 {
2431   return output_move_double (operands);
2432 }"
2433   [(set_attr "type" "move,store,store,load,load,multi")
2434    (set_attr "length" "8,8,16,8,16,16")])
2435
2436 (define_insn ""
2437   [(set (match_operand:DI 0 "register_operand" "=r,&r")
2438         (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
2439                    (match_operand:DI 2 "immediate_operand" "i,i")))]
2440   ""
2441   "*
2442 {
2443   /* Don't output a 64 bit constant, since we can't trust the assembler to
2444      handle it correctly.  */
2445   if (GET_CODE (operands[2]) == CONST_DOUBLE)
2446     operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
2447   if (which_alternative == 1)
2448     output_asm_insn (\"copy %1,%0\", operands);
2449   return \"ldo R'%G2(%R1),%R0\";
2450 }"
2451   [(set_attr "type" "move,move")
2452    (set_attr "length" "4,8")])
2453
2454 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2455 ;; to be reloaded by putting the constant into memory when
2456 ;; reg is a floating point register.
2457 ;;
2458 ;; For integer registers we use ldil;ldo to set the appropriate
2459 ;; value.
2460 ;;
2461 ;; This must come before the movsf pattern, and it must be present
2462 ;; to handle obscure reloading cases.
2463 (define_insn ""
2464   [(set (match_operand:SF 0 "register_operand" "=?r,f")
2465         (match_operand:SF 1 "" "?F,m"))]
2466   "GET_CODE (operands[1]) == CONST_DOUBLE
2467    && operands[1] != CONST0_RTX (SFmode)
2468    && ! TARGET_SOFT_FLOAT"
2469   "* return (which_alternative == 0 ? singlemove_string (operands)
2470                                     : \" fldw%F1 %1,%0\");"
2471   [(set_attr "type" "move,fpload")
2472    (set_attr "length" "8,4")])
2473
2474 (define_expand "movsf"
2475   [(set (match_operand:SF 0 "general_operand" "")
2476         (match_operand:SF 1 "general_operand" ""))]
2477   ""
2478   "
2479 {
2480   if (emit_move_sequence (operands, SFmode, 0))
2481     DONE;
2482 }")
2483
2484 ;; Reloading an SImode or DImode value requires a scratch register if
2485 ;; going in to or out of float point registers.
2486
2487 (define_expand "reload_insf"
2488   [(set (match_operand:SF 0 "register_operand" "=Z")
2489         (match_operand:SF 1 "non_hard_reg_operand" ""))
2490    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2491   ""
2492   "
2493 {
2494   if (emit_move_sequence (operands, SFmode, operands[2]))
2495     DONE;
2496
2497   /* We don't want the clobber emitted, so handle this ourselves.  */
2498   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2499   DONE;
2500 }")
2501
2502 (define_expand "reload_outsf"
2503   [(set (match_operand:SF 0 "non_hard_reg_operand" "")
2504         (match_operand:SF 1  "register_operand" "Z"))
2505    (clobber (match_operand:SF 2 "register_operand" "=&r"))]
2506   ""
2507   "
2508 {
2509   if (emit_move_sequence (operands, SFmode, operands[2]))
2510     DONE;
2511
2512   /* We don't want the clobber emitted, so handle this ourselves.  */
2513   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2514   DONE;
2515 }")
2516
2517 (define_insn ""
2518   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2519                           "=f,r,f,r,RQ,Q")
2520         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2521                           "fG,rG,RQ,RQ,f,rG"))]
2522   "(register_operand (operands[0], SFmode)
2523     || reg_or_0_operand (operands[1], SFmode))
2524    && ! TARGET_SOFT_FLOAT"
2525   "@
2526    fcpy,sgl %r1,%0
2527    copy %r1,%0
2528    fldw%F1 %1,%0
2529    ldw%M1 %1,%0
2530    fstw%F0 %r1,%0
2531    stw%M0 %r1,%0"
2532   [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
2533    (set_attr "pa_combine_type" "addmove")
2534    (set_attr "length" "4,4,4,4,4,4")])
2535
2536 (define_insn ""
2537   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
2538                           "=r,r,Q")
2539         (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
2540                           "rG,RQ,rG"))]
2541   "(register_operand (operands[0], SFmode)
2542     || reg_or_0_operand (operands[1], SFmode))
2543    && TARGET_SOFT_FLOAT"
2544   "@
2545    copy %r1,%0
2546    ldw%M1 %1,%0
2547    stw%M0 %r1,%0"
2548   [(set_attr "type" "move,load,store")
2549    (set_attr "pa_combine_type" "addmove")
2550    (set_attr "length" "4,4,4")])
2551
2552 (define_insn ""
2553   [(set (match_operand:SF 0 "register_operand" "=fx")
2554         (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2555                          (match_operand:SI 2 "register_operand" "r"))))]
2556   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2557   "*
2558 {
2559   /* Reload can create backwards (relative to cse) unscaled index
2560      address modes when eliminating registers and possibly for
2561      pseudos that don't get hard registers.  Deal with it.  */
2562   if (operands[2] == hard_frame_pointer_rtx
2563       || operands[2] == stack_pointer_rtx)
2564     return \"fldwx %1(0,%2),%0\";
2565   else
2566     return \"fldwx %2(0,%1),%0\";
2567 }"
2568   [(set_attr "type" "fpload")
2569    (set_attr "length" "4")])
2570
2571 (define_insn ""
2572   [(set (match_operand:SF 0 "register_operand" "=fx")
2573         (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2574                          (match_operand:SI 2 "basereg_operand" "r"))))]
2575   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2576   "*
2577 {
2578   /* Reload can create backwards (relative to cse) unscaled index
2579      address modes when eliminating registers and possibly for
2580      pseudos that don't get hard registers.  Deal with it.  */
2581   if (operands[1] == hard_frame_pointer_rtx
2582       || operands[1] == stack_pointer_rtx)
2583     return \"fldwx %2(0,%1),%0\";
2584   else
2585     return \"fldwx %1(0,%2),%0\";
2586 }"
2587   [(set_attr "type" "fpload")
2588    (set_attr "length" "4")])
2589
2590 (define_insn ""
2591   [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
2592                          (match_operand:SI 2 "register_operand" "r")))
2593       (match_operand:SF 0 "register_operand" "fx"))]
2594   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2595   "*
2596 {
2597   /* Reload can create backwards (relative to cse) unscaled index
2598      address modes when eliminating registers and possibly for
2599      pseudos that don't get hard registers.  Deal with it.  */
2600   if (operands[2] == hard_frame_pointer_rtx
2601       || operands[2] == stack_pointer_rtx)
2602     return \"fstwx %0,%1(0,%2)\";
2603   else
2604     return \"fstwx %0,%2(0,%1)\";
2605 }"
2606   [(set_attr "type" "fpstore")
2607    (set_attr "length" "4")])
2608 \f
2609 (define_insn ""
2610   [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
2611                          (match_operand:SI 2 "basereg_operand" "r")))
2612       (match_operand:SF 0 "register_operand" "fx"))]
2613   "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
2614   "*
2615 {
2616   /* Reload can create backwards (relative to cse) unscaled index
2617      address modes when eliminating registers and possibly for
2618      pseudos that don't get hard registers.  Deal with it.  */
2619   if (operands[1] == hard_frame_pointer_rtx
2620       || operands[1] == stack_pointer_rtx)
2621     return \"fstwx %0,%2(0,%1)\";
2622   else
2623     return \"fstwx %0,%1(0,%2)\";
2624 }"
2625   [(set_attr "type" "fpstore")
2626    (set_attr "length" "4")])
2627 \f
2628
2629 ;;- zero extension instructions
2630 ;; We have define_expand for zero extension patterns to make sure the
2631 ;; operands get loaded into registers.  The define_insns accept
2632 ;; memory operands.  This gives us better overall code than just
2633 ;; having a pattern that does or does not accept memory operands.
2634
2635 (define_expand "zero_extendhisi2"
2636   [(set (match_operand:SI 0 "register_operand" "")
2637         (zero_extend:SI
2638          (match_operand:HI 1 "register_operand" "")))]
2639   ""
2640   "")
2641
2642 (define_insn ""
2643   [(set (match_operand:SI 0 "register_operand" "=r,r")
2644         (zero_extend:SI
2645          (match_operand:HI 1 "move_operand" "r,RQ")))]
2646   "GET_CODE (operands[1]) != CONST_INT"
2647   "@
2648    extru %1,31,16,%0
2649    ldh%M1 %1,%0"
2650   [(set_attr "type" "shift,load")
2651    (set_attr "length" "4,4")])
2652
2653 (define_expand "zero_extendqihi2"
2654   [(set (match_operand:HI 0 "register_operand" "")
2655         (zero_extend:HI
2656          (match_operand:QI 1 "register_operand" "")))]
2657   ""
2658   "")
2659
2660 (define_insn ""
2661   [(set (match_operand:HI 0 "register_operand" "=r,r")
2662         (zero_extend:HI
2663          (match_operand:QI 1 "move_operand" "r,RQ")))]
2664   "GET_CODE (operands[1]) != CONST_INT"
2665   "@
2666    extru %1,31,8,%0
2667    ldb%M1 %1,%0"
2668   [(set_attr "type" "shift,load")
2669    (set_attr "length" "4,4")])
2670
2671 (define_expand "zero_extendqisi2"
2672   [(set (match_operand:SI 0 "register_operand" "")
2673         (zero_extend:SI
2674          (match_operand:QI 1 "register_operand" "")))]
2675   ""
2676   "")
2677
2678 (define_insn ""
2679   [(set (match_operand:SI 0 "register_operand" "=r,r")
2680         (zero_extend:SI
2681          (match_operand:QI 1 "move_operand" "r,RQ")))]
2682   "GET_CODE (operands[1]) != CONST_INT"
2683   "@
2684    extru %1,31,8,%0
2685    ldb%M1 %1,%0"
2686   [(set_attr "type" "shift,load")
2687    (set_attr "length" "4,4")])
2688
2689 ;;- sign extension instructions
2690
2691 (define_insn "extendhisi2"
2692   [(set (match_operand:SI 0 "register_operand" "=r")
2693         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2694   ""
2695   "extrs %1,31,16,%0"
2696   [(set_attr "type" "shift")
2697    (set_attr "length" "4")])
2698
2699 (define_insn "extendqihi2"
2700   [(set (match_operand:HI 0 "register_operand" "=r")
2701         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2702   ""
2703   "extrs %1,31,8,%0"
2704   [(set_attr "type" "shift") 
2705   (set_attr "length" "4")])
2706
2707 (define_insn "extendqisi2"
2708   [(set (match_operand:SI 0 "register_operand" "=r")
2709         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2710   ""
2711   "extrs %1,31,8,%0"
2712   [(set_attr "type" "shift")
2713    (set_attr "length" "4")])
2714 \f
2715 ;; Conversions between float and double.
2716
2717 (define_insn "extendsfdf2"
2718   [(set (match_operand:DF 0 "register_operand" "=f")
2719         (float_extend:DF
2720          (match_operand:SF 1 "register_operand" "f")))]
2721   "! TARGET_SOFT_FLOAT"
2722   "fcnvff,sgl,dbl %1,%0"
2723   [(set_attr "type" "fpalu")
2724    (set_attr "length" "4")])
2725
2726 (define_insn "truncdfsf2"
2727   [(set (match_operand:SF 0 "register_operand" "=f")
2728         (float_truncate:SF
2729          (match_operand:DF 1 "register_operand" "f")))]
2730   "! TARGET_SOFT_FLOAT"
2731   "fcnvff,dbl,sgl %1,%0"
2732   [(set_attr "type" "fpalu")
2733    (set_attr "length" "4")])
2734
2735 ;; Conversion between fixed point and floating point.
2736 ;; Note that among the fix-to-float insns
2737 ;; the ones that start with SImode come first.
2738 ;; That is so that an operand that is a CONST_INT
2739 ;; (and therefore lacks a specific machine mode).
2740 ;; will be recognized as SImode (which is always valid)
2741 ;; rather than as QImode or HImode.
2742
2743 ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
2744 ;; to be reloaded by putting the constant into memory.
2745 ;; It must come before the more general floatsisf2 pattern.
2746 (define_insn ""
2747   [(set (match_operand:SF 0 "register_operand" "=f")
2748         (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
2749   "! TARGET_SOFT_FLOAT"
2750   "fldw%F1 %1,%0\;fcnvxf,sgl,sgl %0,%0"
2751   [(set_attr "type" "fpalu")
2752    (set_attr "length" "8")])
2753
2754 (define_insn "floatsisf2"
2755   [(set (match_operand:SF 0 "register_operand" "=f")
2756         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2757   "! TARGET_SOFT_FLOAT"
2758   "fcnvxf,sgl,sgl %1,%0"
2759   [(set_attr "type" "fpalu")
2760    (set_attr "length" "4")])
2761
2762 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
2763 ;; to be reloaded by putting the constant into memory.
2764 ;; It must come before the more general floatsidf2 pattern.
2765 (define_insn ""
2766   [(set (match_operand:DF 0 "register_operand" "=f")
2767         (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
2768   "! TARGET_SOFT_FLOAT"
2769   "fldw%F1 %1,%0\;fcnvxf,sgl,dbl %0,%0"
2770   [(set_attr "type" "fpalu")
2771    (set_attr "length" "8")])
2772
2773 (define_insn "floatsidf2"
2774   [(set (match_operand:DF 0 "register_operand" "=f")
2775         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2776   "! TARGET_SOFT_FLOAT"
2777   "fcnvxf,sgl,dbl %1,%0"
2778   [(set_attr "type" "fpalu")
2779    (set_attr "length" "4")])
2780
2781 (define_expand "floatunssisf2"
2782   [(set (subreg:SI (match_dup 2) 1)
2783         (match_operand:SI 1 "register_operand" ""))
2784    (set (subreg:SI (match_dup 2) 0)
2785         (const_int 0))
2786    (set (match_operand:SF 0 "register_operand" "")
2787         (float:SF (match_dup 2)))]
2788   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2789   "operands[2] = gen_reg_rtx (DImode);")
2790
2791 (define_expand "floatunssidf2"
2792   [(set (subreg:SI (match_dup 2) 1)
2793         (match_operand:SI 1 "register_operand" ""))
2794    (set (subreg:SI (match_dup 2) 0)
2795         (const_int 0))
2796    (set (match_operand:DF 0 "register_operand" "")
2797         (float:DF (match_dup 2)))]
2798   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2799   "operands[2] = gen_reg_rtx (DImode);")
2800
2801 (define_insn "floatdisf2"
2802   [(set (match_operand:SF 0 "register_operand" "=f")
2803         (float:SF (match_operand:DI 1 "register_operand" "f")))]
2804   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2805   "fcnvxf,dbl,sgl %1,%0"
2806   [(set_attr "type" "fpalu")
2807    (set_attr "length" "4")])
2808
2809 (define_insn "floatdidf2"
2810   [(set (match_operand:DF 0 "register_operand" "=f")
2811         (float:DF (match_operand:DI 1 "register_operand" "f")))]
2812   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2813   "fcnvxf,dbl,dbl %1,%0"
2814   [(set_attr "type" "fpalu")
2815    (set_attr "length" "4")])
2816
2817 ;; Convert a float to an actual integer.
2818 ;; Truncation is performed as part of the conversion.
2819
2820 (define_insn "fix_truncsfsi2"
2821   [(set (match_operand:SI 0 "register_operand" "=f")
2822         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2823   "! TARGET_SOFT_FLOAT"
2824   "fcnvfxt,sgl,sgl %1,%0"
2825   [(set_attr "type" "fpalu")
2826    (set_attr "length" "4")])
2827
2828 (define_insn "fix_truncdfsi2"
2829   [(set (match_operand:SI 0 "register_operand" "=f")
2830         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2831   "! TARGET_SOFT_FLOAT"
2832   "fcnvfxt,dbl,sgl %1,%0"
2833   [(set_attr "type" "fpalu")
2834    (set_attr "length" "4")])
2835
2836 (define_insn "fix_truncsfdi2"
2837   [(set (match_operand:DI 0 "register_operand" "=f")
2838         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
2839   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2840   "fcnvfxt,sgl,dbl %1,%0"
2841   [(set_attr "type" "fpalu")
2842    (set_attr "length" "4")])
2843
2844 (define_insn "fix_truncdfdi2"
2845   [(set (match_operand:DI 0 "register_operand" "=f")
2846         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
2847   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
2848   "fcnvfxt,dbl,dbl %1,%0"
2849   [(set_attr "type" "fpalu")
2850    (set_attr "length" "4")])
2851 \f
2852 ;;- arithmetic instructions
2853
2854 (define_insn "adddi3"
2855   [(set (match_operand:DI 0 "register_operand" "=r")
2856         (plus:DI (match_operand:DI 1 "register_operand" "%r")
2857                  (match_operand:DI 2 "arith11_operand" "rI")))]
2858   ""
2859   "*
2860 {
2861   if (GET_CODE (operands[2]) == CONST_INT)
2862     {
2863       if (INTVAL (operands[2]) >= 0)
2864         return \"addi %2,%R1,%R0\;addc %1,0,%0\";
2865       else
2866         return \"addi %2,%R1,%R0\;subb %1,0,%0\";
2867     }
2868   else
2869     return \"add %R2,%R1,%R0\;addc %2,%1,%0\";
2870 }"
2871   [(set_attr "type" "binary")
2872    (set_attr "length" "8")])
2873
2874 (define_insn ""
2875   [(set (match_operand:SI 0 "register_operand" "=r")
2876         (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2877                  (match_operand:SI 2 "register_operand" "r")))]
2878   ""
2879   "uaddcm %2,%1,%0"
2880   [(set_attr "type" "binary")
2881    (set_attr "length" "4")])
2882
2883 ;; define_splits to optimize cases of adding a constant integer
2884 ;; to a register when the constant does not fit in 14 bits.  */
2885 (define_split
2886   [(set (match_operand:SI 0 "register_operand" "")
2887         (plus:SI (match_operand:SI 1 "register_operand" "")
2888                  (match_operand:SI 2 "const_int_operand" "")))
2889    (clobber (match_operand:SI 4 "register_operand" ""))]
2890   "! cint_ok_for_move (INTVAL (operands[2]))
2891    && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
2892   [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
2893    (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
2894   "
2895 {
2896   int val = INTVAL (operands[2]);
2897   int low = (val < 0) ? -0x2000 : 0x1fff;
2898   int rest = val - low;
2899
2900   operands[2] = GEN_INT (rest);
2901   operands[3] = GEN_INT (low);
2902 }")
2903
2904 (define_split
2905   [(set (match_operand:SI 0 "register_operand" "")
2906         (plus:SI (match_operand:SI 1 "register_operand" "")
2907                  (match_operand:SI 2 "const_int_operand" "")))
2908    (clobber (match_operand:SI 4 "register_operand" ""))]
2909   "! cint_ok_for_move (INTVAL (operands[2]))"
2910   [(set (match_dup 4) (match_dup 2))
2911    (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
2912                                (match_dup 1)))]
2913   "
2914 {
2915   HOST_WIDE_INT intval = INTVAL (operands[2]);
2916
2917   /* Try dividing the constant by 2, then 4, and finally 8 to see
2918      if we can get a constant which can be loaded into a register
2919      in a single instruction (cint_ok_for_move). 
2920
2921      If that fails, try to negate the constant and subtract it
2922      from our input operand.  */
2923   if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
2924     {
2925       operands[2] = GEN_INT (intval / 2);
2926       operands[3] = GEN_INT (2);
2927     }
2928   else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
2929     {
2930       operands[2] = GEN_INT (intval / 4);
2931       operands[3] = GEN_INT (4);
2932     }
2933   else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
2934     {
2935       operands[2] = GEN_INT (intval / 8);
2936       operands[3] = GEN_INT (8);
2937     }
2938   else if (cint_ok_for_move (-intval))
2939     {
2940       emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
2941       emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
2942       DONE;
2943     }
2944   else
2945     FAIL;
2946 }")
2947
2948 (define_insn "addsi3"
2949   [(set (match_operand:SI 0 "register_operand" "=r,r")
2950         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
2951                  (match_operand:SI 2 "arith_operand" "r,J")))]
2952   ""
2953   "@
2954    addl %1,%2,%0
2955    ldo %2(%1),%0"
2956   [(set_attr "type" "binary,binary")
2957    (set_attr "pa_combine_type" "addmove")
2958    (set_attr "length" "4,4")])
2959
2960 ;; Disgusting kludge to work around reload bugs with frame pointer
2961 ;; elimination.  Similar to other magic reload patterns in the
2962 ;; indexed memory operations.
2963 (define_insn ""
2964   [(set (match_operand:SI 0 "register_operand" "=&r")
2965         (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
2966                           (match_operand:SI 2 "register_operand" "r"))
2967                  (match_operand:SI 3 "const_int_operand" "rL")))]
2968   "reload_in_progress"
2969   "*
2970 {
2971   if (GET_CODE (operands[3]) == CONST_INT)
2972     return \"ldo %3(%2),%0\;addl %1,%0,%0\";
2973   else
2974     return \"addl %3,%2,%0\;addl %1,%0,%0\";
2975 }"
2976   [(set_attr "type" "binary")
2977    (set_attr "length" "8")])
2978
2979 (define_insn "subdi3"
2980   [(set (match_operand:DI 0 "register_operand" "=r")
2981         (minus:DI (match_operand:DI 1 "register_operand" "r")
2982                   (match_operand:DI 2 "register_operand" "r")))]
2983   ""
2984   "sub %R1,%R2,%R0\;subb %1,%2,%0"
2985   [(set_attr "type" "binary")
2986   (set_attr "length" "8")])
2987
2988 (define_insn "subsi3"
2989   [(set (match_operand:SI 0 "register_operand" "=r,r")
2990         (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
2991                   (match_operand:SI 2 "register_operand" "r,r")))]
2992   ""
2993   "@
2994    sub %1,%2,%0
2995    subi %1,%2,%0"
2996   [(set_attr "type" "binary,binary")
2997    (set_attr "length" "4,4")])
2998
2999 ;; Clobbering a "register_operand" instead of a match_scratch
3000 ;; in operand3 of millicode calls avoids spilling %r1 and
3001 ;; produces better code.
3002
3003 ;; The mulsi3 insns set up registers for the millicode call.
3004 (define_expand "mulsi3"
3005   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3006    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3007    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3008               (clobber (match_dup 3))
3009               (clobber (reg:SI 26))
3010               (clobber (reg:SI 25))
3011               (clobber (reg:SI 31))])
3012    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3013   ""
3014   "
3015 {
3016   if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
3017     {
3018       rtx scratch = gen_reg_rtx (DImode);
3019       operands[1] = force_reg (SImode, operands[1]);
3020       operands[2] = force_reg (SImode, operands[2]);
3021       emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
3022       emit_insn (gen_rtx_SET (VOIDmode,
3023                               operands[0],
3024                               gen_rtx_SUBREG (SImode, scratch, 1)));
3025       DONE;
3026     }
3027   operands[3] = gen_reg_rtx (SImode);
3028 }")
3029
3030 (define_insn "umulsidi3"
3031   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3032         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3033                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
3034   "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3035   "xmpyu %1,%2,%0"
3036   [(set_attr "type" "fpmuldbl")
3037    (set_attr "length" "4")])
3038
3039 (define_insn ""
3040   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
3041         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
3042                  (match_operand:DI 2 "uint32_operand" "f")))]
3043   "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
3044   "xmpyu %1,%R2,%0"
3045   [(set_attr "type" "fpmuldbl")
3046    (set_attr "length" "4")])
3047
3048 (define_insn ""
3049   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
3050    (clobber (match_operand:SI 0 "register_operand" "=a"))
3051    (clobber (reg:SI 26))
3052    (clobber (reg:SI 25))
3053    (clobber (reg:SI 31))]
3054   ""
3055   "* return output_mul_insn (0, insn);"
3056   [(set_attr "type" "milli")
3057    (set (attr "length")
3058      (cond [
3059 ;; Target (or stub) within reach
3060             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3061                      (const_int 240000))
3062                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3063                      (const_int 0)))
3064             (const_int 4)
3065
3066 ;; NO_SPACE_REGS
3067             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3068                 (const_int 0))
3069             (const_int 8)
3070
3071 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3072 ;; same as NO_SPACE_REGS code
3073             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3074                      (const_int 0))
3075                  (eq (symbol_ref "flag_pic")
3076                      (const_int 0)))
3077             (const_int 8)]
3078
3079 ;; Out of range and either PIC or PORTABLE_RUNTIME
3080           (const_int 24)))])
3081
3082 ;;; Division and mod.
3083 (define_expand "divsi3"
3084   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3085    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3086    (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
3087               (clobber (match_dup 3))
3088               (clobber (reg:SI 26))
3089               (clobber (reg:SI 25))
3090               (clobber (reg:SI 31))])
3091    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3092   ""
3093   "
3094 {
3095   operands[3] = gen_reg_rtx (SImode);
3096   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
3097     DONE;
3098 }")
3099
3100 (define_insn ""
3101   [(set (reg:SI 29)
3102         (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3103    (clobber (match_operand:SI 1 "register_operand" "=a"))
3104    (clobber (reg:SI 26))
3105    (clobber (reg:SI 25))
3106    (clobber (reg:SI 31))]
3107   ""
3108   "*
3109    return output_div_insn (operands, 0, insn);"
3110   [(set_attr "type" "milli")
3111    (set (attr "length")
3112      (cond [
3113 ;; Target (or stub) within reach
3114             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3115                      (const_int 240000))
3116                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3117                      (const_int 0)))
3118             (const_int 4)
3119
3120 ;; NO_SPACE_REGS
3121             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3122                 (const_int 0))
3123             (const_int 8)
3124
3125 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3126 ;; same as NO_SPACE_REGS code
3127             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3128                      (const_int 0))
3129                  (eq (symbol_ref "flag_pic")
3130                      (const_int 0)))
3131             (const_int 8)]
3132
3133 ;; Out of range and either PIC or PORTABLE_RUNTIME
3134           (const_int 24)))])
3135
3136 (define_expand "udivsi3"
3137   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3138    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3139    (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
3140               (clobber (match_dup 3))
3141               (clobber (reg:SI 26))
3142               (clobber (reg:SI 25))
3143               (clobber (reg:SI 31))])
3144    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3145   ""
3146   "
3147 {
3148   operands[3] = gen_reg_rtx (SImode);
3149   if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
3150     DONE;
3151 }")
3152
3153 (define_insn ""
3154   [(set (reg:SI 29)
3155         (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
3156    (clobber (match_operand:SI 1 "register_operand" "=a"))
3157    (clobber (reg:SI 26))
3158    (clobber (reg:SI 25))
3159    (clobber (reg:SI 31))]
3160   ""
3161   "*
3162    return output_div_insn (operands, 1, insn);"
3163   [(set_attr "type" "milli")
3164    (set (attr "length")
3165      (cond [
3166 ;; Target (or stub) within reach
3167             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3168                      (const_int 240000))
3169                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3170                      (const_int 0)))
3171             (const_int 4)
3172
3173 ;; NO_SPACE_REGS
3174             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3175                 (const_int 0))
3176             (const_int 8)
3177
3178 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3179 ;; same as NO_SPACE_REGS code
3180             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3181                      (const_int 0))
3182                  (eq (symbol_ref "flag_pic")
3183                      (const_int 0)))
3184             (const_int 8)]
3185
3186 ;; Out of range and either PIC or PORTABLE_RUNTIME
3187           (const_int 24)))])
3188
3189 (define_expand "modsi3"
3190   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3191    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3192    (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3193               (clobber (match_dup 3))
3194               (clobber (reg:SI 26))
3195               (clobber (reg:SI 25))
3196               (clobber (reg:SI 31))])
3197    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3198   ""
3199   "
3200 {
3201   operands[3] = gen_reg_rtx (SImode);
3202 }")
3203
3204 (define_insn ""
3205   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
3206    (clobber (match_operand:SI 0 "register_operand" "=a"))
3207    (clobber (reg:SI 26))
3208    (clobber (reg:SI 25))
3209    (clobber (reg:SI 31))]
3210   ""
3211   "*
3212   return output_mod_insn (0, insn);"
3213   [(set_attr "type" "milli")
3214    (set (attr "length")
3215      (cond [
3216 ;; Target (or stub) within reach
3217             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3218                      (const_int 240000))
3219                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3220                      (const_int 0)))
3221             (const_int 4)
3222
3223 ;; NO_SPACE_REGS
3224             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3225                 (const_int 0))
3226             (const_int 8)
3227
3228 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3229 ;; same as NO_SPACE_REGS code
3230             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3231                      (const_int 0))
3232                  (eq (symbol_ref "flag_pic")
3233                      (const_int 0)))
3234             (const_int 8)]
3235
3236 ;; Out of range and either PIC or PORTABLE_RUNTIME
3237           (const_int 24)))])
3238
3239 (define_expand "umodsi3"
3240   [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
3241    (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
3242    (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3243               (clobber (match_dup 3))
3244               (clobber (reg:SI 26))
3245               (clobber (reg:SI 25))
3246               (clobber (reg:SI 31))])
3247    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
3248   ""
3249   "
3250 {
3251   operands[3] = gen_reg_rtx (SImode);
3252 }")
3253
3254 (define_insn ""
3255   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
3256    (clobber (match_operand:SI 0 "register_operand" "=a"))
3257    (clobber (reg:SI 26))
3258    (clobber (reg:SI 25))
3259    (clobber (reg:SI 31))]
3260   ""
3261   "*
3262   return output_mod_insn (1, insn);"
3263   [(set_attr "type" "milli")
3264    (set (attr "length")
3265      (cond [
3266 ;; Target (or stub) within reach
3267             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
3268                      (const_int 240000))
3269                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3270                      (const_int 0)))
3271             (const_int 4)
3272
3273 ;; NO_SPACE_REGS
3274             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
3275                 (const_int 0))
3276             (const_int 8)
3277
3278 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
3279 ;; same as NO_SPACE_REGS code
3280             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
3281                      (const_int 0))
3282                  (eq (symbol_ref "flag_pic")
3283                      (const_int 0)))
3284             (const_int 8)]
3285
3286 ;; Out of range and either PIC or PORTABLE_RUNTIME
3287           (const_int 24)))])
3288
3289 ;;- and instructions
3290 ;; We define DImode `and` so with DImode `not` we can get
3291 ;; DImode `andn`.  Other combinations are possible.
3292
3293 (define_expand "anddi3"
3294   [(set (match_operand:DI 0 "register_operand" "")
3295         (and:DI (match_operand:DI 1 "arith_double_operand" "")
3296                 (match_operand:DI 2 "arith_double_operand" "")))]
3297   ""
3298   "
3299 {
3300   if (! register_operand (operands[1], DImode)
3301       || ! register_operand (operands[2], DImode))
3302     /* Let GCC break this into word-at-a-time operations.  */
3303     FAIL;
3304 }")
3305
3306 (define_insn ""
3307   [(set (match_operand:DI 0 "register_operand" "=r")
3308         (and:DI (match_operand:DI 1 "register_operand" "%r")
3309                 (match_operand:DI 2 "register_operand" "r")))]
3310   ""
3311   "and %1,%2,%0\;and %R1,%R2,%R0"
3312   [(set_attr "type" "binary")
3313    (set_attr "length" "8")])
3314
3315 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
3316 ; constant with ldil;ldo.
3317 (define_insn "andsi3"
3318   [(set (match_operand:SI 0 "register_operand" "=r,r")
3319         (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
3320                 (match_operand:SI 2 "and_operand" "rO,P")))]
3321   ""
3322   "* return output_and (operands); "
3323   [(set_attr "type" "binary,shift")
3324    (set_attr "length" "4,4")])
3325
3326 (define_insn ""
3327   [(set (match_operand:DI 0 "register_operand" "=r")
3328         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3329                 (match_operand:DI 2 "register_operand" "r")))]
3330   ""
3331   "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
3332   [(set_attr "type" "binary")
3333    (set_attr "length" "8")])
3334
3335 (define_insn ""
3336   [(set (match_operand:SI 0 "register_operand" "=r")
3337         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3338                 (match_operand:SI 2 "register_operand" "r")))]
3339   ""
3340   "andcm %2,%1,%0"
3341   [(set_attr "type" "binary")
3342   (set_attr "length" "4")])
3343
3344 (define_expand "iordi3"
3345   [(set (match_operand:DI 0 "register_operand" "")
3346         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3347                 (match_operand:DI 2 "arith_double_operand" "")))]
3348   ""
3349   "
3350 {
3351   if (! register_operand (operands[1], DImode)
3352       || ! register_operand (operands[2], DImode))
3353     /* Let GCC break this into word-at-a-time operations.  */
3354     FAIL;
3355 }")
3356
3357 (define_insn ""
3358   [(set (match_operand:DI 0 "register_operand" "=r")
3359         (ior:DI (match_operand:DI 1 "register_operand" "%r")
3360                 (match_operand:DI 2 "register_operand" "r")))]
3361   ""
3362   "or %1,%2,%0\;or %R1,%R2,%R0"
3363   [(set_attr "type" "binary")
3364    (set_attr "length" "8")])
3365
3366 ;; Need a define_expand because we've run out of CONST_OK... characters.
3367 (define_expand "iorsi3"
3368   [(set (match_operand:SI 0 "register_operand" "")
3369         (ior:SI (match_operand:SI 1 "register_operand" "")
3370                 (match_operand:SI 2 "arith32_operand" "")))]
3371   ""
3372   "
3373 {
3374   if (! (ior_operand (operands[2], SImode)
3375          || register_operand (operands[2], SImode)))
3376     operands[2] = force_reg (SImode, operands[2]);
3377 }")
3378
3379 (define_insn ""
3380   [(set (match_operand:SI 0 "register_operand" "=r,r")
3381         (ior:SI (match_operand:SI 1 "register_operand" "0,0")
3382                 (match_operand:SI 2 "ior_operand" "M,i")))]
3383   ""
3384   "* return output_ior (operands); "
3385   [(set_attr "type" "binary,shift")
3386    (set_attr "length" "4,4")])
3387
3388 (define_insn ""
3389   [(set (match_operand:SI 0 "register_operand" "=r")
3390         (ior:SI (match_operand:SI 1 "register_operand" "%r")
3391                 (match_operand:SI 2 "register_operand" "r")))]
3392   ""
3393   "or %1,%2,%0"
3394   [(set_attr "type" "binary")
3395    (set_attr "length" "4")])
3396
3397 (define_expand "xordi3"
3398   [(set (match_operand:DI 0 "register_operand" "")
3399         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3400                 (match_operand:DI 2 "arith_double_operand" "")))]
3401   ""
3402   "
3403 {
3404   if (! register_operand (operands[1], DImode)
3405       || ! register_operand (operands[2], DImode))
3406     /* Let GCC break this into word-at-a-time operations.  */
3407     FAIL;
3408 }")
3409
3410 (define_insn ""
3411   [(set (match_operand:DI 0 "register_operand" "=r")
3412         (xor:DI (match_operand:DI 1 "register_operand" "%r")
3413                 (match_operand:DI 2 "register_operand" "r")))]
3414   ""
3415   "xor %1,%2,%0\;xor %R1,%R2,%R0"
3416   [(set_attr "type" "binary")
3417    (set_attr "length" "8")])
3418
3419 (define_insn "xorsi3"
3420   [(set (match_operand:SI 0 "register_operand" "=r")
3421         (xor:SI (match_operand:SI 1 "register_operand" "%r")
3422                 (match_operand:SI 2 "register_operand" "r")))]
3423   ""
3424   "xor %1,%2,%0"
3425   [(set_attr "type" "binary")
3426    (set_attr "length" "4")])
3427
3428 (define_insn "negdi2"
3429   [(set (match_operand:DI 0 "register_operand" "=r")
3430         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
3431   ""
3432   "sub 0,%R1,%R0\;subb 0,%1,%0"
3433   [(set_attr "type" "unary")
3434    (set_attr "length" "8")])
3435
3436 (define_insn "negsi2"
3437   [(set (match_operand:SI 0 "register_operand" "=r")
3438         (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3439   ""
3440   "sub 0,%1,%0"
3441   [(set_attr "type" "unary")
3442    (set_attr "length" "4")])
3443
3444 (define_expand "one_cmpldi2"
3445   [(set (match_operand:DI 0 "register_operand" "")
3446         (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
3447   ""
3448   "
3449 {
3450   if (! register_operand (operands[1], DImode))
3451     FAIL;
3452 }")
3453
3454 (define_insn ""
3455   [(set (match_operand:DI 0 "register_operand" "=r")
3456         (not:DI (match_operand:DI 1 "register_operand" "r")))]
3457   ""
3458   "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0"
3459   [(set_attr "type" "unary")
3460    (set_attr "length" "8")])
3461
3462 (define_insn "one_cmplsi2"
3463   [(set (match_operand:SI 0 "register_operand" "=r")
3464         (not:SI (match_operand:SI 1 "register_operand" "r")))]
3465   ""
3466   "uaddcm 0,%1,%0"
3467   [(set_attr "type" "unary")
3468    (set_attr "length" "4")])
3469 \f
3470 ;; Floating point arithmetic instructions.
3471
3472 (define_insn "adddf3"
3473   [(set (match_operand:DF 0 "register_operand" "=f")
3474         (plus:DF (match_operand:DF 1 "register_operand" "f")
3475                  (match_operand:DF 2 "register_operand" "f")))]
3476   "! TARGET_SOFT_FLOAT"
3477   "fadd,dbl %1,%2,%0"
3478   [(set_attr "type" "fpalu")
3479    (set_attr "pa_combine_type" "faddsub")
3480    (set_attr "length" "4")])
3481
3482 (define_insn "addsf3"
3483   [(set (match_operand:SF 0 "register_operand" "=f")
3484         (plus:SF (match_operand:SF 1 "register_operand" "f")
3485                  (match_operand:SF 2 "register_operand" "f")))]
3486   "! TARGET_SOFT_FLOAT"
3487   "fadd,sgl %1,%2,%0"
3488   [(set_attr "type" "fpalu")
3489    (set_attr "pa_combine_type" "faddsub")
3490    (set_attr "length" "4")])
3491
3492 (define_insn "subdf3"
3493   [(set (match_operand:DF 0 "register_operand" "=f")
3494         (minus:DF (match_operand:DF 1 "register_operand" "f")
3495                   (match_operand:DF 2 "register_operand" "f")))]
3496   "! TARGET_SOFT_FLOAT"
3497   "fsub,dbl %1,%2,%0"
3498   [(set_attr "type" "fpalu")
3499    (set_attr "pa_combine_type" "faddsub")
3500    (set_attr "length" "4")])
3501
3502 (define_insn "subsf3"
3503   [(set (match_operand:SF 0 "register_operand" "=f")
3504         (minus:SF (match_operand:SF 1 "register_operand" "f")
3505                   (match_operand:SF 2 "register_operand" "f")))]
3506   "! TARGET_SOFT_FLOAT"
3507   "fsub,sgl %1,%2,%0"
3508   [(set_attr "type" "fpalu")
3509    (set_attr "pa_combine_type" "faddsub")
3510    (set_attr "length" "4")])
3511
3512 (define_insn "muldf3"
3513   [(set (match_operand:DF 0 "register_operand" "=f")
3514         (mult:DF (match_operand:DF 1 "register_operand" "f")
3515                  (match_operand:DF 2 "register_operand" "f")))]
3516   "! TARGET_SOFT_FLOAT"
3517   "fmpy,dbl %1,%2,%0"
3518   [(set_attr "type" "fpmuldbl")
3519    (set_attr "pa_combine_type" "fmpy")
3520    (set_attr "length" "4")])
3521
3522 (define_insn "mulsf3"
3523   [(set (match_operand:SF 0 "register_operand" "=f")
3524         (mult:SF (match_operand:SF 1 "register_operand" "f")
3525                  (match_operand:SF 2 "register_operand" "f")))]
3526   "! TARGET_SOFT_FLOAT"
3527   "fmpy,sgl %1,%2,%0"
3528   [(set_attr "type" "fpmulsgl")
3529    (set_attr "pa_combine_type" "fmpy")
3530    (set_attr "length" "4")])
3531
3532 (define_insn "divdf3"
3533   [(set (match_operand:DF 0 "register_operand" "=f")
3534         (div:DF (match_operand:DF 1 "register_operand" "f")
3535                 (match_operand:DF 2 "register_operand" "f")))]
3536   "! TARGET_SOFT_FLOAT"
3537   "fdiv,dbl %1,%2,%0"
3538   [(set_attr "type" "fpdivdbl")
3539    (set_attr "length" "4")])
3540
3541 (define_insn "divsf3"
3542   [(set (match_operand:SF 0 "register_operand" "=f")
3543         (div:SF (match_operand:SF 1 "register_operand" "f")
3544                 (match_operand:SF 2 "register_operand" "f")))]
3545   "! TARGET_SOFT_FLOAT"
3546   "fdiv,sgl %1,%2,%0"
3547   [(set_attr "type" "fpdivsgl")
3548    (set_attr "length" "4")])
3549
3550 (define_insn "negdf2"
3551   [(set (match_operand:DF 0 "register_operand" "=f")
3552         (neg:DF (match_operand:DF 1 "register_operand" "f")))]
3553   "! TARGET_SOFT_FLOAT"
3554   "fsub,dbl 0,%1,%0"
3555   [(set_attr "type" "fpalu")
3556    (set_attr "length" "4")])
3557
3558 (define_insn "negsf2"
3559   [(set (match_operand:SF 0 "register_operand" "=f")
3560         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
3561   "! TARGET_SOFT_FLOAT"
3562   "fsub,sgl 0,%1,%0"
3563   [(set_attr "type" "fpalu")
3564    (set_attr "length" "4")])
3565
3566 (define_insn "absdf2"
3567   [(set (match_operand:DF 0 "register_operand" "=f")
3568         (abs:DF (match_operand:DF 1 "register_operand" "f")))]
3569   "! TARGET_SOFT_FLOAT"
3570   "fabs,dbl %1,%0"
3571   [(set_attr "type" "fpalu")
3572    (set_attr "length" "4")])
3573
3574 (define_insn "abssf2"
3575   [(set (match_operand:SF 0 "register_operand" "=f")
3576         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
3577   "! TARGET_SOFT_FLOAT"
3578   "fabs,sgl %1,%0"
3579   [(set_attr "type" "fpalu")
3580    (set_attr "length" "4")])
3581
3582 (define_insn "sqrtdf2"
3583   [(set (match_operand:DF 0 "register_operand" "=f")
3584         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
3585   "! TARGET_SOFT_FLOAT"
3586   "fsqrt,dbl %1,%0"
3587   [(set_attr "type" "fpsqrtdbl")
3588    (set_attr "length" "4")])
3589
3590 (define_insn "sqrtsf2"
3591   [(set (match_operand:SF 0 "register_operand" "=f")
3592         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
3593   "! TARGET_SOFT_FLOAT"
3594   "fsqrt,sgl %1,%0"
3595   [(set_attr "type" "fpsqrtsgl")
3596    (set_attr "length" "4")])
3597 \f
3598 ;;- Shift instructions
3599
3600 ;; Optimized special case of shifting.
3601
3602 (define_insn ""
3603   [(set (match_operand:SI 0 "register_operand" "=r")
3604         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3605                      (const_int 24)))]
3606   ""
3607   "ldb%M1 %1,%0"
3608   [(set_attr "type" "load")
3609    (set_attr "length" "4")])
3610
3611 (define_insn ""
3612   [(set (match_operand:SI 0 "register_operand" "=r")
3613         (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3614                      (const_int 16)))]
3615   ""
3616   "ldh%M1 %1,%0"
3617   [(set_attr "type" "load")
3618    (set_attr "length" "4")])
3619
3620 (define_insn ""
3621   [(set (match_operand:SI 0 "register_operand" "=r")
3622         (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
3623                           (match_operand:SI 3 "shadd_operand" ""))
3624                  (match_operand:SI 1 "register_operand" "r")))]
3625   ""
3626   "sh%O3addl %2,%1,%0"
3627   [(set_attr "type" "binary")
3628    (set_attr "length" "4")])
3629
3630 ;; This variant of the above insn can occur if the first operand
3631 ;; is the frame pointer.  This is a kludge, but there doesn't
3632 ;; seem to be a way around it.  Only recognize it while reloading.
3633 ;; Note how operand 3 uses a predicate of "const_int_operand", but 
3634 ;; has constraints allowing a register.  I don't know how this works,
3635 ;; but it somehow makes sure that out-of-range constants are placed
3636 ;; in a register which somehow magically is a "const_int_operand".
3637 ;; (this was stolen from alpha.md, I'm not going to try and change it.
3638
3639 (define_insn ""
3640   [(set (match_operand:SI 0 "register_operand" "=&r,r")
3641         (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r,r")
3642                                    (match_operand:SI 4 "shadd_operand" ""))
3643                           (match_operand:SI 1 "register_operand" "r,r"))
3644                  (match_operand:SI 3 "const_int_operand" "r,J")))]
3645   "reload_in_progress"
3646   "@
3647    sh%O4addl %2,%1,%0\;addl %3,%0,%0
3648    sh%O4addl %2,%1,%0\;ldo %3(%0),%0"
3649   [(set_attr "type" "multi")
3650    (set_attr "length" "8")])
3651
3652 (define_expand "ashlsi3"
3653   [(set (match_operand:SI 0 "register_operand" "")
3654         (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
3655                    (match_operand:SI 2 "arith32_operand" "")))]
3656   ""
3657   "
3658 {
3659   if (GET_CODE (operands[2]) != CONST_INT)
3660     {
3661       rtx temp = gen_reg_rtx (SImode);
3662       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
3663       if (GET_CODE (operands[1]) == CONST_INT)
3664         emit_insn (gen_zvdep_imm (operands[0], operands[1], temp));
3665       else
3666         emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
3667       DONE;
3668     }
3669   /* Make sure both inputs are not constants,
3670      there are no patterns for that.  */
3671   operands[1] = force_reg (SImode, operands[1]);
3672 }")
3673
3674 (define_insn ""
3675   [(set (match_operand:SI 0 "register_operand" "=r")
3676         (ashift:SI (match_operand:SI 1 "register_operand" "r")
3677                    (match_operand:SI 2 "const_int_operand" "n")))]
3678   ""
3679   "zdep %1,%P2,%L2,%0"
3680   [(set_attr "type" "shift")
3681    (set_attr "length" "4")])
3682
3683 ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle.
3684 ; Doing it like this makes slightly better code since reload can
3685 ; replace a register with a known value in range -16..15 with a
3686 ; constant.  Ideally, we would like to merge zvdep32 and zvdep_imm,
3687 ; but since we have no more CONST_OK... characters, that is not
3688 ; possible.
3689 (define_insn "zvdep32"
3690   [(set (match_operand:SI 0 "register_operand" "=r,r")
3691         (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
3692                    (minus:SI (const_int 31)
3693                              (match_operand:SI 2 "register_operand" "q,q"))))]
3694   ""
3695   "@
3696    zvdep %1,32,%0
3697    zvdepi %1,32,%0"
3698   [(set_attr "type" "shift,shift")
3699    (set_attr "length" "4,4")])
3700
3701 (define_insn "zvdep_imm"
3702   [(set (match_operand:SI 0 "register_operand" "=r")
3703         (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
3704                    (minus:SI (const_int 31)
3705                              (match_operand:SI 2 "register_operand" "q"))))]
3706   ""
3707   "*
3708 {
3709   int x = INTVAL (operands[1]);
3710   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
3711   operands[1] = GEN_INT ((x & 0xf) - 0x10);
3712   return \"zvdepi %1,%2,%0\";
3713 }"
3714   [(set_attr "type" "shift")
3715    (set_attr "length" "4")])
3716
3717 (define_insn "vdepi_ior"
3718   [(set (match_operand:SI 0 "register_operand" "=r")
3719         (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
3720                            (minus:SI (const_int 31)
3721                                      (match_operand:SI 2 "register_operand" "q")))
3722                 (match_operand:SI 3 "register_operand" "0")))]
3723   ; accept ...0001...1, can this be generalized?
3724   "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
3725   "*
3726 {
3727   int x = INTVAL (operands[1]);
3728   operands[2] = GEN_INT (exact_log2 (x + 1));
3729   return \"vdepi -1,%2,%0\";
3730 }"
3731   [(set_attr "type" "shift")
3732    (set_attr "length" "4")])
3733
3734 (define_insn "vdepi_and"
3735   [(set (match_operand:SI 0 "register_operand" "=r")
3736         (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
3737                            (minus:SI (const_int 31)
3738                                      (match_operand:SI 2 "register_operand" "q")))
3739                 (match_operand:SI 3 "register_operand" "0")))]
3740   ; this can be generalized...!
3741   "INTVAL (operands[1]) == -2"
3742   "*
3743 {
3744   int x = INTVAL (operands[1]);
3745   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
3746   return \"vdepi 0,%2,%0\";
3747 }"
3748   [(set_attr "type" "shift")
3749    (set_attr "length" "4")])
3750
3751 (define_expand "ashrsi3"
3752   [(set (match_operand:SI 0 "register_operand" "")
3753         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3754                      (match_operand:SI 2 "arith32_operand" "")))]
3755   ""
3756   "
3757 {
3758   if (GET_CODE (operands[2]) != CONST_INT)
3759     {
3760       rtx temp = gen_reg_rtx (SImode);
3761       emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
3762       emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
3763       DONE;
3764     }
3765 }")
3766
3767 (define_insn ""
3768   [(set (match_operand:SI 0 "register_operand" "=r")
3769         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
3770                      (match_operand:SI 2 "const_int_operand" "n")))]
3771   ""
3772   "extrs %1,%P2,%L2,%0"
3773   [(set_attr "type" "shift")
3774    (set_attr "length" "4")])
3775
3776 (define_insn "vextrs32"
3777   [(set (match_operand:SI 0 "register_operand" "=r")
3778         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
3779                      (minus:SI (const_int 31)
3780                                (match_operand:SI 2 "register_operand" "q"))))]
3781   ""
3782   "vextrs %1,32,%0"
3783   [(set_attr "type" "shift")
3784    (set_attr "length" "4")])
3785
3786 (define_insn "lshrsi3"
3787   [(set (match_operand:SI 0 "register_operand" "=r,r")
3788         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3789                      (match_operand:SI 2 "arith32_operand" "q,n")))]
3790   ""
3791   "@
3792    vshd 0,%1,%0
3793    extru %1,%P2,%L2,%0"
3794   [(set_attr "type" "shift")
3795    (set_attr "length" "4")])
3796
3797 (define_insn "rotrsi3"
3798   [(set (match_operand:SI 0 "register_operand" "=r,r")
3799         (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
3800                      (match_operand:SI 2 "arith32_operand" "q,n")))]
3801   ""
3802   "*
3803 {
3804   if (GET_CODE (operands[2]) == CONST_INT)
3805     {
3806       operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
3807       return \"shd %1,%1,%2,%0\";
3808     }
3809   else
3810     return \"vshd %1,%1,%0\";
3811 }"
3812   [(set_attr "type" "shift")
3813    (set_attr "length" "4")])
3814
3815 (define_insn ""
3816   [(set (match_operand:SI 0 "register_operand" "=r")
3817         (match_operator:SI 5 "plus_xor_ior_operator"
3818           [(ashift:SI (match_operand:SI 1 "register_operand" "r")
3819                       (match_operand:SI 3 "const_int_operand" "n"))
3820            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3821                         (match_operand:SI 4 "const_int_operand" "n"))]))]
3822   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
3823   "shd %1,%2,%4,%0"
3824   [(set_attr "type" "shift")
3825    (set_attr "length" "4")])
3826
3827 (define_insn ""
3828   [(set (match_operand:SI 0 "register_operand" "=r")
3829         (match_operator:SI 5 "plus_xor_ior_operator"
3830           [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3831                         (match_operand:SI 4 "const_int_operand" "n"))
3832            (ashift:SI (match_operand:SI 1 "register_operand" "r")
3833                       (match_operand:SI 3 "const_int_operand" "n"))]))]
3834   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
3835   "shd %1,%2,%4,%0"
3836   [(set_attr "type" "shift")
3837    (set_attr "length" "4")])
3838
3839 (define_insn ""
3840   [(set (match_operand:SI 0 "register_operand" "=r")
3841         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3842                            (match_operand:SI 2 "const_int_operand" ""))
3843                 (match_operand:SI 3 "const_int_operand" "")))]
3844   "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
3845   "*
3846 {
3847   int cnt = INTVAL (operands[2]) & 31;
3848   operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
3849   operands[2] = GEN_INT (31 - cnt);
3850   return \"zdep %1,%2,%3,%0\";
3851 }"
3852   [(set_attr "type" "shift")
3853    (set_attr "length" "4")])
3854 \f
3855 ;; Unconditional and other jump instructions.
3856
3857 (define_insn "return"
3858   [(return)]
3859   "hppa_can_use_return_insn_p ()"
3860   "bv%* 0(%%r2)"
3861   [(set_attr "type" "branch")
3862    (set_attr "length" "4")])
3863
3864 ;; Use a different pattern for functions which have non-trivial
3865 ;; epilogues so as not to confuse jump and reorg.
3866 (define_insn "return_internal"
3867   [(use (reg:SI 2))
3868    (return)]
3869   ""
3870   "bv%* 0(%%r2)"
3871   [(set_attr "type" "branch")
3872    (set_attr "length" "4")])
3873
3874 (define_expand "prologue"
3875   [(const_int 0)]
3876   ""
3877   "hppa_expand_prologue ();DONE;")
3878
3879 (define_expand "epilogue"
3880   [(return)]
3881   ""
3882   "
3883 {
3884   /* Try to use the trivial return first.  Else use the full
3885      epilogue.  */
3886   if (hppa_can_use_return_insn_p ())
3887    emit_jump_insn (gen_return ());
3888   else
3889     {
3890       hppa_expand_epilogue ();
3891       emit_jump_insn (gen_return_internal ());
3892     }
3893   DONE;
3894 }")
3895
3896 ;; Special because we use the value placed in %r2 by the bl instruction
3897 ;; from within its delay slot to set the value for the 2nd parameter to
3898 ;; the call.
3899 (define_insn "call_profiler"
3900   [(unspec_volatile [(const_int 0)] 0)
3901    (use (match_operand:SI 0 "const_int_operand" ""))]
3902   ""
3903   "bl _mcount,%%r2\;ldo %0(%%r2),%%r25"
3904   [(set_attr "type" "multi")
3905    (set_attr "length" "8")])
3906
3907 (define_insn "blockage"
3908   [(unspec_volatile [(const_int 2)] 0)]
3909   ""
3910   ""
3911   [(set_attr "length" "0")])
3912
3913 (define_insn "jump"
3914   [(set (pc) (label_ref (match_operand 0 "" "")))]
3915   ""
3916   "*
3917 {
3918   extern int optimize;
3919
3920   if (GET_MODE (insn) == SImode)
3921     return \"bl %l0,0%#\";
3922
3923   /* An unconditional branch which can reach its target.  */
3924   if (get_attr_length (insn) != 24
3925       && get_attr_length (insn) != 16)
3926     return \"bl%* %l0,0\";
3927
3928   /* An unconditional branch which can not reach its target.
3929
3930      We need to be able to use %r1 as a scratch register; however,
3931      we can never be sure whether or not it's got a live value in
3932      it.  Therefore, we must restore its original value after the
3933      jump.
3934
3935      To make matters worse, we don't have a stack slot which we
3936      can always clobber.  sp-12/sp-16 shouldn't ever have a live
3937      value during a non-optimizing compilation, so we use those
3938      slots for now.  We don't support very long branches when
3939      optimizing -- they should be quite rare when optimizing.
3940
3941      Really the way to go long term is a register scavenger; goto
3942      the target of the jump and find a register which we can use
3943      as a scratch to hold the value in %r1.  */
3944
3945   /* We don't know how to register scavenge yet.  */
3946   if (optimize)
3947     abort ();
3948
3949   /* First store %r1 into the stack.  */
3950   output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
3951
3952   /* Now load the target address into %r1 and do an indirect jump
3953      to the value specified in %r1.  Be careful to generate PIC
3954      code as needed.  */
3955   if (flag_pic)
3956     {
3957       rtx xoperands[2];
3958       xoperands[0] = operands[0];
3959       xoperands[1] = gen_label_rtx ();
3960
3961       output_asm_insn (\"bl .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\", xoperands);
3962       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
3963                                  CODE_LABEL_NUMBER (xoperands[1]));
3964       output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv 0(%%r1)\",
3965                        xoperands);
3966     }
3967   else
3968     output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
3969
3970   /* And restore the value of %r1 in the delay slot.  We're not optimizing,
3971      so we know nothing else can be in the delay slot.  */
3972   return \"ldw -16(%%r30),%%r1\";
3973 }"
3974   [(set_attr "type" "uncond_branch")
3975    (set_attr "pa_combine_type" "uncond_branch")
3976    (set (attr "length")
3977     (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
3978            (if_then_else (lt (abs (minus (match_dup 0)
3979                                          (plus (pc) (const_int 8))))
3980                              (const_int 8184))
3981                          (const_int 4)
3982                          (const_int 8))
3983            (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
3984                (const_int 262100))
3985            (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
3986                          (const_int 16)
3987                          (const_int 24))]
3988           (const_int 4)))])
3989
3990 ;; Subroutines of "casesi".
3991 ;; operand 0 is index
3992 ;; operand 1 is the minimum bound
3993 ;; operand 2 is the maximum bound - minimum bound + 1
3994 ;; operand 3 is CODE_LABEL for the table;
3995 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3996
3997 (define_expand "casesi"
3998   [(match_operand:SI 0 "general_operand" "")
3999    (match_operand:SI 1 "const_int_operand" "")
4000    (match_operand:SI 2 "const_int_operand" "")
4001    (match_operand 3 "" "")
4002    (match_operand 4 "" "")]
4003   ""
4004   "
4005 {
4006   if (GET_CODE (operands[0]) != REG)
4007     operands[0] = force_reg (SImode, operands[0]);
4008
4009   if (operands[1] != const0_rtx)
4010     {
4011       rtx reg = gen_reg_rtx (SImode);
4012
4013       operands[1] = GEN_INT (-INTVAL (operands[1]));
4014       if (!INT_14_BITS (operands[1]))
4015         operands[1] = force_reg (SImode, operands[1]);
4016       emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
4017
4018       operands[0] = reg;
4019     }
4020
4021   if (!INT_5_BITS (operands[2]))
4022     operands[2] = force_reg (SImode, operands[2]);
4023
4024   emit_insn (gen_cmpsi (operands[0], operands[2]));
4025   emit_jump_insn (gen_bgtu (operands[4]));
4026   if (TARGET_BIG_SWITCH)
4027     {
4028       rtx temp = gen_reg_rtx (SImode);
4029       emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
4030       operands[0] = temp;
4031     }
4032   emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
4033   DONE;
4034 }")
4035
4036 (define_insn "casesi0"
4037   [(set (pc) (plus:SI
4038                (mem:SI (plus:SI (pc)
4039                                 (match_operand:SI 0 "register_operand" "r")))
4040                (label_ref (match_operand 1 "" ""))))]
4041   ""
4042   "blr %0,0\;nop"
4043   [(set_attr "type" "multi")
4044    (set_attr "length" "8")])
4045
4046 ;; Need nops for the calls because execution is supposed to continue
4047 ;; past; we don't want to nullify an instruction that we need.
4048 ;;- jump to subroutine
4049
4050 (define_expand "call"
4051   [(parallel [(call (match_operand:SI 0 "" "")
4052                     (match_operand 1 "" ""))
4053               (clobber (reg:SI 2))])]
4054   ""
4055   "
4056 {
4057   rtx op;
4058   rtx call_insn;
4059
4060   if (TARGET_PORTABLE_RUNTIME)
4061     op = force_reg (SImode, XEXP (operands[0], 0));
4062   else
4063     op = XEXP (operands[0], 0);
4064
4065   /* Use two different patterns for calls to explicitly named functions
4066      and calls through function pointers.  This is necessary as these two
4067      types of calls use different calling conventions, and CSE might try
4068      to change the named call into an indirect call in some cases (using
4069      two patterns keeps CSE from performing this optimization).  */
4070   if (GET_CODE (op) == SYMBOL_REF)
4071     call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
4072   else
4073     {
4074       rtx tmpreg = gen_rtx_REG (SImode, 22);
4075       emit_move_insn (tmpreg, force_reg (SImode, op));
4076       call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
4077     }
4078
4079   if (flag_pic)
4080     {
4081       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4082
4083       /* After each call we must restore the PIC register, even if it
4084          doesn't appear to be used.
4085
4086          This will set regs_ever_live for the callee saved register we
4087          stored the PIC register in.  */
4088       emit_move_insn (pic_offset_table_rtx,
4089                       gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4090       emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
4091
4092       /* Gross.  We have to keep the scheduler from moving the restore
4093          of the PIC register away from the call.  SCHED_GROUP_P is
4094          supposed to do this, but for some reason the compiler will
4095          go into an infinite loop when we use that.
4096
4097          This method (blockage insn) may make worse code (then again
4098          it may not since calls are nearly blockages anyway), but at
4099          least it should work.  */
4100       emit_insn (gen_blockage ());
4101     }
4102   DONE;
4103 }")
4104
4105 (define_insn "call_internal_symref"
4106   [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
4107          (match_operand 1 "" "i"))
4108    (clobber (reg:SI 2))
4109    (use (const_int 0))]
4110   "! TARGET_PORTABLE_RUNTIME"
4111   "*
4112 {
4113   output_arg_descriptor (insn);
4114   return output_call (insn, operands[0], gen_rtx_REG (SImode, 2));
4115 }"
4116   [(set_attr "type" "call")
4117    (set (attr "length")
4118 ;;       If we're sure that we can either reach the target or that the
4119 ;;       linker can use a long-branch stub, then the length is 4 bytes.
4120 ;;
4121 ;;       For long-calls the length will be either 52 bytes (non-pic)
4122 ;;       or 68 bytes (pic).  */
4123 ;;       Else we have to use a long-call;
4124       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4125                         (const_int 240000))
4126                     (const_int 4)
4127                     (if_then_else (eq (symbol_ref "flag_pic")
4128                                       (const_int 0))
4129                                   (const_int 52)
4130                                   (const_int 68))))])
4131
4132 (define_insn "call_internal_reg"
4133   [(call (mem:SI (reg:SI 22))
4134          (match_operand 0 "" "i"))
4135    (clobber (reg:SI 2))
4136    (use (const_int 1))]
4137   ""
4138   "*
4139 {
4140   rtx xoperands[2];
4141
4142   /* First the special case for kernels, level 0 systems, etc.  */
4143   if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4144     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4145
4146   /* Now the normal case -- we can reach $$dyncall directly or
4147      we're sure that we can get there via a long-branch stub. 
4148
4149      No need to check target flags as the length uniquely identifies
4150      the remaining cases.  */
4151   if (get_attr_length (insn) == 8)
4152     return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
4153
4154   /* Long millicode call, but we are not generating PIC or portable runtime
4155      code.  */
4156   if (get_attr_length (insn) == 12)
4157     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4158
4159   /* Long millicode call for portable runtime.  */
4160   if (get_attr_length (insn) == 20)
4161     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
4162
4163   /* If we're generating PIC code.  */
4164   xoperands[0] = operands[0];
4165   xoperands[1] = gen_label_rtx ();
4166   output_asm_insn (\"bl .+8,%%r1\", xoperands);
4167   output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4168   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4169                              CODE_LABEL_NUMBER (xoperands[1]));
4170   output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4171   output_asm_insn (\"blr 0,%%r2\", xoperands);
4172   output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
4173   return \"\";
4174 }"
4175   [(set_attr "type" "dyncall")
4176    (set (attr "length")
4177      (cond [
4178 ;; First NO_SPACE_REGS
4179             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4180                 (const_int 0))
4181             (const_int 8)
4182
4183 ;; Target (or stub) within reach
4184             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4185                      (const_int 240000))
4186                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4187                      (const_int 0)))
4188             (const_int 8)
4189
4190 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4191             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4192                      (const_int 0))
4193                  (eq (symbol_ref "flag_pic")
4194                      (const_int 0)))
4195             (const_int 12)
4196
4197             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4198                 (const_int 0))
4199             (const_int 20)]
4200
4201 ;; Out of range PIC case
4202           (const_int 24)))])
4203
4204 (define_expand "call_value"
4205   [(parallel [(set (match_operand 0 "" "")
4206                    (call (match_operand:SI 1 "" "")
4207                          (match_operand 2 "" "")))
4208               (clobber (reg:SI 2))])]
4209   ""
4210   "
4211 {
4212   rtx op;
4213   rtx call_insn;
4214
4215   if (TARGET_PORTABLE_RUNTIME)
4216     op = force_reg (SImode, XEXP (operands[1], 0));
4217   else
4218     op = XEXP (operands[1], 0);
4219
4220   /* Use two different patterns for calls to explicitly named functions
4221      and calls through function pointers.  This is necessary as these two
4222      types of calls use different calling conventions, and CSE might try
4223      to change the named call into an indirect call in some cases (using
4224      two patterns keeps CSE from performing this optimization).  */
4225   if (GET_CODE (op) == SYMBOL_REF)
4226     call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
4227                                                                 op,
4228                                                                 operands[2]));
4229   else
4230     {
4231       rtx tmpreg = gen_rtx_REG (SImode, 22);
4232       emit_move_insn (tmpreg, force_reg (SImode, op));
4233       call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
4234                                                                operands[2]));
4235     }
4236   if (flag_pic)
4237     {
4238       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
4239
4240       /* After each call we must restore the PIC register, even if it
4241          doesn't appear to be used.
4242
4243          This will set regs_ever_live for the callee saved register we
4244          stored the PIC register in.  */
4245       emit_move_insn (pic_offset_table_rtx,
4246                       gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
4247       emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
4248
4249       /* Gross.  We have to keep the scheduler from moving the restore
4250          of the PIC register away from the call.  SCHED_GROUP_P is
4251          supposed to do this, but for some reason the compiler will
4252          go into an infinite loop when we use that.
4253
4254          This method (blockage insn) may make worse code (then again
4255          it may not since calls are nearly blockages anyway), but at
4256          least it should work.  */
4257       emit_insn (gen_blockage ());
4258     }
4259   DONE;
4260 }")
4261
4262 (define_insn "call_value_internal_symref"
4263   [(set (match_operand 0 "" "=rf")
4264         (call (mem:SI (match_operand:SI 1 "call_operand_address" ""))
4265               (match_operand 2 "" "i")))
4266    (clobber (reg:SI 2))
4267    (use (const_int 0))]
4268   ;;- Don't use operand 1 for most machines.
4269   "! TARGET_PORTABLE_RUNTIME"
4270   "*
4271 {
4272   output_arg_descriptor (insn);
4273   return output_call (insn, operands[1], gen_rtx_REG (SImode, 2));
4274 }"
4275   [(set_attr "type" "call")
4276    (set (attr "length")
4277 ;;       If we're sure that we can either reach the target or that the
4278 ;;       linker can use a long-branch stub, then the length is 4 bytes.
4279 ;;
4280 ;;       For long-calls the length will be either 52 bytes (non-pic)
4281 ;;       or 68 bytes (pic).  */
4282 ;;       Else we have to use a long-call;
4283       (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
4284                         (const_int 240000))
4285                     (const_int 4)
4286                     (if_then_else (eq (symbol_ref "flag_pic")
4287                                       (const_int 0))
4288                                   (const_int 52)
4289                                   (const_int 68))))])
4290
4291 (define_insn "call_value_internal_reg"
4292   [(set (match_operand 0 "" "=rf")
4293         (call (mem:SI (reg:SI 22))
4294               (match_operand 1 "" "i")))
4295    (clobber (reg:SI 2))
4296    (use (const_int 1))]
4297   ""
4298   "*
4299 {
4300   rtx xoperands[2];
4301
4302   /* First the special case for kernels, level 0 systems, etc.  */
4303   if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
4304     return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
4305
4306   /* Now the normal case -- we can reach $$dyncall directly or
4307      we're sure that we can get there via a long-branch stub. 
4308
4309      No need to check target flags as the length uniquely identifies
4310      the remaining cases.  */
4311   if (get_attr_length (insn) == 8)
4312     return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
4313
4314   /* Long millicode call, but we are not generating PIC or portable runtime
4315      code.  */
4316   if (get_attr_length (insn) == 12)
4317     return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
4318
4319   /* Long millicode call for portable runtime.  */
4320   if (get_attr_length (insn) == 20)
4321     return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
4322
4323   /* If we're generating PIC code.  */
4324   xoperands[0] = operands[1];
4325   xoperands[1] = gen_label_rtx ();
4326   output_asm_insn (\"bl .+8,%%r1\", xoperands);
4327   output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
4328   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4329                              CODE_LABEL_NUMBER (xoperands[1]));
4330   output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
4331   output_asm_insn (\"blr 0,%%r2\", xoperands);
4332   output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
4333   return \"\";
4334 }"
4335   [(set_attr "type" "dyncall")
4336    (set (attr "length")
4337      (cond [
4338 ;; First NO_SPACE_REGS
4339             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
4340                 (const_int 0))
4341             (const_int 8)
4342
4343 ;; Target (or stub) within reach
4344             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
4345                      (const_int 240000))
4346                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4347                      (const_int 0)))
4348             (const_int 8)
4349
4350 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
4351             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
4352                      (const_int 0))
4353                  (eq (symbol_ref "flag_pic")
4354                      (const_int 0)))
4355             (const_int 12)
4356
4357             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
4358                 (const_int 0))
4359             (const_int 20)]
4360
4361 ;; Out of range PIC case
4362           (const_int 24)))])
4363
4364 ;; Call subroutine returning any type.
4365
4366 (define_expand "untyped_call"
4367   [(parallel [(call (match_operand 0 "" "")
4368                     (const_int 0))
4369               (match_operand 1 "" "")
4370               (match_operand 2 "" "")])]
4371   ""
4372   "
4373 {
4374   int i;
4375
4376   emit_call_insn (gen_call (operands[0], const0_rtx));
4377
4378   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4379     {
4380       rtx set = XVECEXP (operands[2], 0, i);
4381       emit_move_insn (SET_DEST (set), SET_SRC (set));
4382     }
4383
4384   /* The optimizer does not know that the call sets the function value
4385      registers we stored in the result block.  We avoid problems by
4386      claiming that all hard registers are used and clobbered at this
4387      point.  */
4388   emit_insn (gen_blockage ());
4389
4390   DONE;
4391 }")
4392 (define_insn "nop"
4393   [(const_int 0)]
4394   ""
4395   "nop"
4396   [(set_attr "type" "move")
4397    (set_attr "length" "4")])
4398
4399 ;; These are just placeholders so we know where branch tables
4400 ;; begin and end.
4401 (define_insn "begin_brtab"
4402   [(const_int 1)]
4403   ""
4404   "*
4405 {
4406   /* Only GAS actually supports this pseudo-op.  */
4407   if (TARGET_GAS)
4408     return \".begin_brtab\";
4409   else
4410     return \"\";
4411 }"
4412   [(set_attr "type" "move")
4413    (set_attr "length" "0")])
4414
4415 (define_insn "end_brtab"
4416   [(const_int 2)]
4417   ""
4418   "*
4419 {
4420   /* Only GAS actually supports this pseudo-op.  */
4421   if (TARGET_GAS)
4422     return \".end_brtab\";
4423   else
4424     return \"\";
4425 }"
4426   [(set_attr "type" "move")
4427    (set_attr "length" "0")])
4428
4429 ;;; Hope this is only within a function...
4430 (define_insn "indirect_jump"
4431   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
4432   ""
4433   "bv%* 0(%0)"
4434   [(set_attr "type" "branch")
4435    (set_attr "length" "4")])
4436
4437 (define_insn "extzv"
4438   [(set (match_operand:SI 0 "register_operand" "=r")
4439         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4440                          (match_operand:SI 2 "uint5_operand" "")
4441                          (match_operand:SI 3 "uint5_operand" "")))]
4442   ""
4443   "extru %1,%3+%2-1,%2,%0"
4444   [(set_attr "type" "shift")
4445    (set_attr "length" "4")])
4446
4447 (define_insn ""
4448   [(set (match_operand:SI 0 "register_operand" "=r")
4449         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4450                          (const_int 1)
4451                          (match_operand:SI 3 "register_operand" "q")))]
4452   ""
4453   "vextru %1,1,%0"
4454   [(set_attr "type" "shift")
4455    (set_attr "length" "4")])
4456
4457 (define_insn "extv"
4458   [(set (match_operand:SI 0 "register_operand" "=r")
4459         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
4460                          (match_operand:SI 2 "uint5_operand" "")
4461                          (match_operand:SI 3 "uint5_operand" "")))]
4462   ""
4463   "extrs %1,%3+%2-1,%2,%0"
4464   [(set_attr "type" "shift")
4465    (set_attr "length" "4")])
4466
4467 (define_insn ""
4468   [(set (match_operand:SI 0 "register_operand" "=r")
4469         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
4470                          (const_int 1)
4471                          (match_operand:SI 3 "register_operand" "q")))]
4472   ""
4473   "vextrs %1,1,%0"
4474   [(set_attr "type" "shift")
4475    (set_attr "length" "4")])
4476
4477 (define_insn "insv"
4478   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
4479                          (match_operand:SI 1 "uint5_operand" "")
4480                          (match_operand:SI 2 "uint5_operand" ""))
4481         (match_operand:SI 3 "arith5_operand" "r,L"))]
4482   ""
4483   "@
4484    dep %3,%2+%1-1,%1,%0
4485    depi %3,%2+%1-1,%1,%0"
4486   [(set_attr "type" "shift,shift")
4487    (set_attr "length" "4,4")])
4488
4489 ;; Optimize insertion of const_int values of type 1...1xxxx.
4490 (define_insn ""
4491   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
4492                          (match_operand:SI 1 "uint5_operand" "")
4493                          (match_operand:SI 2 "uint5_operand" ""))
4494         (match_operand:SI 3 "const_int_operand" ""))]
4495   "(INTVAL (operands[3]) & 0x10) != 0 &&
4496    (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
4497   "*
4498 {
4499   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
4500   return \"depi %3,%2+%1-1,%1,%0\";
4501 }"
4502   [(set_attr "type" "shift")
4503    (set_attr "length" "4")])
4504
4505 ;; This insn is used for some loop tests, typically loops reversed when
4506 ;; strength reduction is used.  It is actually created when the instruction
4507 ;; combination phase combines the special loop test.  Since this insn
4508 ;; is both a jump insn and has an output, it must deal with its own
4509 ;; reloads, hence the `m' constraints.  The `!' constraints direct reload
4510 ;; to not choose the register alternatives in the event a reload is needed.
4511 (define_insn "decrement_and_branch_until_zero"
4512   [(set (pc)
4513         (if_then_else
4514           (match_operator 2 "comparison_operator"
4515            [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
4516                      (match_operand:SI 1 "int5_operand" "L,L,L"))
4517             (const_int 0)])
4518           (label_ref (match_operand 3 "" ""))
4519           (pc)))
4520    (set (match_dup 0)
4521         (plus:SI (match_dup 0) (match_dup 1)))
4522    (clobber (match_scratch:SI 4 "=X,r,r"))]
4523   ""
4524   "* return output_dbra (operands, insn, which_alternative); "
4525 ;; Do not expect to understand this the first time through.
4526 [(set_attr "type" "cbranch,multi,multi")
4527  (set (attr "length")
4528       (if_then_else (eq_attr "alternative" "0")
4529 ;; Loop counter in register case
4530 ;; Short branch has length of 4
4531 ;; Long branch has length of 8
4532         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4533                       (const_int 8184))
4534            (const_int 4)
4535            (const_int 8))
4536
4537 ;; Loop counter in FP reg case.
4538 ;; Extra goo to deal with additional reload insns.
4539         (if_then_else (eq_attr "alternative" "1")
4540           (if_then_else (lt (match_dup 3) (pc))
4541             (if_then_else
4542               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
4543                   (const_int 8184))
4544               (const_int 24)
4545               (const_int 28))
4546             (if_then_else
4547               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4548                   (const_int 8184))
4549               (const_int 24)
4550               (const_int 28)))
4551 ;; Loop counter in memory case.
4552 ;; Extra goo to deal with additional reload insns.
4553         (if_then_else (lt (match_dup 3) (pc))
4554           (if_then_else
4555             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4556                 (const_int 8184))
4557             (const_int 12)
4558             (const_int 16))
4559           (if_then_else
4560             (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4561                 (const_int 8184))
4562             (const_int 12)
4563             (const_int 16))))))])
4564
4565 (define_insn ""
4566   [(set (pc)
4567         (if_then_else
4568           (match_operator 2 "movb_comparison_operator"
4569            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
4570           (label_ref (match_operand 3 "" ""))
4571           (pc)))
4572    (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
4573         (match_dup 1))]
4574   ""
4575 "* return output_movb (operands, insn, which_alternative, 0); "
4576 ;; Do not expect to understand this the first time through.
4577 [(set_attr "type" "cbranch,multi,multi,multi")
4578  (set (attr "length")
4579       (if_then_else (eq_attr "alternative" "0")
4580 ;; Loop counter in register case
4581 ;; Short branch has length of 4
4582 ;; Long branch has length of 8
4583         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4584                       (const_int 8184))
4585            (const_int 4)
4586            (const_int 8))
4587
4588 ;; Loop counter in FP reg case.
4589 ;; Extra goo to deal with additional reload insns.
4590         (if_then_else (eq_attr "alternative" "1")
4591           (if_then_else (lt (match_dup 3) (pc))
4592             (if_then_else
4593               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4594                   (const_int 8184))
4595               (const_int 12)
4596               (const_int 16))
4597             (if_then_else
4598               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4599                   (const_int 8184))
4600               (const_int 12)
4601               (const_int 16)))
4602 ;; Loop counter in memory or sar case.
4603 ;; Extra goo to deal with additional reload insns.
4604         (if_then_else
4605           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4606               (const_int 8184))
4607           (const_int 8)
4608           (const_int 12)))))])
4609
4610 ;; Handle negated branch.
4611 (define_insn ""
4612   [(set (pc)
4613         (if_then_else
4614           (match_operator 2 "movb_comparison_operator"
4615            [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
4616           (pc)
4617           (label_ref (match_operand 3 "" ""))))
4618    (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
4619         (match_dup 1))]
4620   ""
4621 "* return output_movb (operands, insn, which_alternative, 1); "
4622 ;; Do not expect to understand this the first time through.
4623 [(set_attr "type" "cbranch,multi,multi,multi")
4624  (set (attr "length")
4625       (if_then_else (eq_attr "alternative" "0")
4626 ;; Loop counter in register case
4627 ;; Short branch has length of 4
4628 ;; Long branch has length of 8
4629         (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4630                       (const_int 8184))
4631            (const_int 4)
4632            (const_int 8))
4633
4634 ;; Loop counter in FP reg case.
4635 ;; Extra goo to deal with additional reload insns.
4636         (if_then_else (eq_attr "alternative" "1")
4637           (if_then_else (lt (match_dup 3) (pc))
4638             (if_then_else
4639               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
4640                   (const_int 8184))
4641               (const_int 12)
4642               (const_int 16))
4643             (if_then_else
4644               (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4645                   (const_int 8184))
4646               (const_int 12)
4647               (const_int 16)))
4648 ;; Loop counter in memory or SAR case.
4649 ;; Extra goo to deal with additional reload insns.
4650         (if_then_else
4651           (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4652               (const_int 8184))
4653           (const_int 8)
4654           (const_int 12)))))])
4655
4656 ;; The next several patterns (parallel_addb, parallel_movb, fmpyadd and
4657 ;; fmpysub aren't currently used by the FSF sources, but will be soon.
4658 ;;
4659 ;; They're in the FSF tree for documentation and to make Cygnus<->FSF
4660 ;; merging easier.
4661 (define_insn ""
4662   [(set (pc) (label_ref (match_operand 3 "" "" )))
4663    (set (match_operand:SI 0 "register_operand" "=r")
4664         (plus:SI (match_operand:SI 1 "register_operand" "r")
4665                  (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
4666   "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
4667   "*
4668 {
4669   return output_parallel_addb (operands, get_attr_length (insn));
4670 }"
4671   [(set_attr "type" "parallel_branch")
4672    (set (attr "length")
4673     (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
4674                       (const_int 8184))
4675            (const_int 4)
4676            (const_int 8)))])
4677
4678 (define_insn ""
4679   [(set (pc) (label_ref (match_operand 2 "" "" )))
4680    (set (match_operand:SF 0 "register_operand" "=r")
4681         (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
4682   "reload_completed"
4683   "*
4684 {
4685   return output_parallel_movb (operands, get_attr_length (insn));
4686 }"
4687   [(set_attr "type" "parallel_branch")
4688    (set (attr "length")
4689     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4690                       (const_int 8184))
4691            (const_int 4)
4692            (const_int 8)))])
4693
4694 (define_insn ""
4695   [(set (pc) (label_ref (match_operand 2 "" "" )))
4696    (set (match_operand:SI 0 "register_operand" "=r")
4697         (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
4698   "reload_completed"
4699   "*
4700 {
4701   return output_parallel_movb (operands, get_attr_length (insn));
4702 }"
4703   [(set_attr "type" "parallel_branch")
4704    (set (attr "length")
4705     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4706                       (const_int 8184))
4707            (const_int 4)
4708            (const_int 8)))])
4709
4710 (define_insn ""
4711   [(set (pc) (label_ref (match_operand 2 "" "" )))
4712    (set (match_operand:HI 0 "register_operand" "=r")
4713         (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
4714   "reload_completed"
4715   "*
4716 {
4717   return output_parallel_movb (operands, get_attr_length (insn));
4718 }"
4719   [(set_attr "type" "parallel_branch")
4720    (set (attr "length")
4721     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4722                       (const_int 8184))
4723            (const_int 4)
4724            (const_int 8)))])
4725
4726 (define_insn ""
4727   [(set (pc) (label_ref (match_operand 2 "" "" )))
4728    (set (match_operand:QI 0 "register_operand" "=r")
4729         (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
4730   "reload_completed"
4731   "*
4732 {
4733   return output_parallel_movb (operands, get_attr_length (insn));
4734 }"
4735   [(set_attr "type" "parallel_branch")
4736    (set (attr "length")
4737     (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
4738                       (const_int 8184))
4739            (const_int 4)
4740            (const_int 8)))])
4741
4742 (define_insn ""
4743   [(set (match_operand 0 "register_operand" "=f")
4744         (mult (match_operand 1 "register_operand" "f")
4745               (match_operand 2 "register_operand" "f")))
4746    (set (match_operand 3 "register_operand" "+f")
4747         (plus (match_operand 4 "register_operand" "f")
4748               (match_operand 5 "register_operand" "f")))]
4749   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4750    && reload_completed && fmpyaddoperands (operands)"
4751   "*
4752 {
4753   if (GET_MODE (operands[0]) == DFmode)
4754     {
4755       if (rtx_equal_p (operands[3], operands[5]))
4756         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
4757       else
4758         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
4759     }
4760   else
4761     {
4762       if (rtx_equal_p (operands[3], operands[5]))
4763         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
4764       else
4765         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
4766     }
4767 }"
4768   [(set_attr "type" "fpalu")
4769    (set_attr "length" "4")])
4770
4771 (define_insn ""
4772   [(set (match_operand 3 "register_operand" "+f")
4773         (plus (match_operand 4 "register_operand" "f")
4774               (match_operand 5 "register_operand" "f")))
4775    (set (match_operand 0 "register_operand" "=f")
4776         (mult (match_operand 1 "register_operand" "f")
4777               (match_operand 2 "register_operand" "f")))]
4778   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4779    && reload_completed && fmpyaddoperands (operands)"
4780   "*
4781 {
4782   if (GET_MODE (operands[0]) == DFmode)
4783     {
4784       if (rtx_equal_p (operands[3], operands[5]))
4785         return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
4786       else
4787         return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
4788     }
4789   else
4790     {
4791       if (rtx_equal_p (operands[3], operands[5]))
4792         return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
4793       else
4794         return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
4795     }
4796 }"
4797   [(set_attr "type" "fpalu")
4798    (set_attr "length" "4")])
4799
4800 (define_insn ""
4801   [(set (match_operand 0 "register_operand" "=f")
4802         (mult (match_operand 1 "register_operand" "f")
4803               (match_operand 2 "register_operand" "f")))
4804    (set (match_operand 3 "register_operand" "+f")
4805         (minus (match_operand 4 "register_operand" "f")
4806                (match_operand 5 "register_operand" "f")))]
4807   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4808    && reload_completed && fmpysuboperands (operands)"
4809   "*
4810 {
4811   if (GET_MODE (operands[0]) == DFmode)
4812     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
4813   else
4814     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
4815 }"
4816   [(set_attr "type" "fpalu")
4817    (set_attr "length" "4")])
4818
4819 (define_insn ""
4820   [(set (match_operand 3 "register_operand" "+f")
4821         (minus (match_operand 4 "register_operand" "f")
4822                (match_operand 5 "register_operand" "f")))
4823    (set (match_operand 0 "register_operand" "=f")
4824         (mult (match_operand 1 "register_operand" "f")
4825               (match_operand 2 "register_operand" "f")))]
4826   "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
4827    && reload_completed && fmpysuboperands (operands)"
4828   "*
4829 {
4830   if (GET_MODE (operands[0]) == DFmode)
4831     return \"fmpysub,dbl %1,%2,%0,%5,%3\";
4832   else
4833     return \"fmpysub,sgl %1,%2,%0,%5,%3\";
4834 }"
4835   [(set_attr "type" "fpalu")
4836    (set_attr "length" "4")])
4837
4838 ;; Clean up turds left by reload.
4839 (define_peephole
4840   [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
4841         (match_operand 1 "register_operand" "fr"))
4842    (set (match_operand 2 "register_operand" "fr")
4843         (match_dup 0))]
4844   "! TARGET_SOFT_FLOAT
4845    && GET_CODE (operands[0]) == MEM
4846    && ! MEM_VOLATILE_P (operands[0])
4847    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4848    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4849    && GET_MODE (operands[0]) == DFmode
4850    && GET_CODE (operands[1]) == REG
4851    && GET_CODE (operands[2]) == REG
4852    && ! side_effects_p (XEXP (operands[0], 0))
4853    && REGNO_REG_CLASS (REGNO (operands[1]))
4854       == REGNO_REG_CLASS (REGNO (operands[2]))"
4855   "*
4856 {
4857   rtx xoperands[2];
4858
4859   if (FP_REG_P (operands[1]))
4860     output_asm_insn (output_fp_move_double (operands), operands);
4861   else
4862     output_asm_insn (output_move_double (operands), operands);
4863
4864   if (rtx_equal_p (operands[1], operands[2]))
4865     return \"\";
4866
4867   xoperands[0] = operands[2];
4868   xoperands[1] = operands[1];
4869       
4870   if (FP_REG_P (xoperands[1]))
4871     output_asm_insn (output_fp_move_double (xoperands), xoperands);
4872   else
4873     output_asm_insn (output_move_double (xoperands), xoperands);
4874
4875   return \"\";
4876 }")
4877
4878 (define_peephole
4879   [(set (match_operand 0 "register_operand" "fr")
4880         (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
4881    (set (match_operand 2 "register_operand" "fr")
4882         (match_dup 1))]
4883   "! TARGET_SOFT_FLOAT
4884    && GET_CODE (operands[1]) == MEM
4885    && ! MEM_VOLATILE_P (operands[1])
4886    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4887    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4888    && GET_MODE (operands[0]) == DFmode
4889    && GET_CODE (operands[0]) == REG
4890    && GET_CODE (operands[2]) == REG
4891    && ! side_effects_p (XEXP (operands[1], 0))
4892    && REGNO_REG_CLASS (REGNO (operands[0]))
4893       == REGNO_REG_CLASS (REGNO (operands[2]))"
4894   "*
4895 {
4896   rtx xoperands[2];
4897
4898   if (FP_REG_P (operands[0]))
4899     output_asm_insn (output_fp_move_double (operands), operands);
4900   else
4901     output_asm_insn (output_move_double (operands), operands);
4902
4903   xoperands[0] = operands[2];
4904   xoperands[1] = operands[0];
4905       
4906   if (FP_REG_P (xoperands[1]))
4907     output_asm_insn (output_fp_move_double (xoperands), xoperands);
4908   else
4909     output_asm_insn (output_move_double (xoperands), xoperands);
4910
4911   return \"\";
4912 }")
4913
4914 ;; Flush the I and D cache line found at the address in operand 0.
4915 ;; This is used by the trampoline code for nested functions.
4916 ;; So long as the trampoline itself is less than 32 bytes this
4917 ;; is sufficient.
4918
4919 (define_insn "dcacheflush"
4920   [(unspec_volatile [(const_int 1)] 0)
4921    (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
4922    (use (mem:SI (match_operand:SI 1 "register_operand" "r")))]
4923   ""
4924   "fdc 0(0,%0)\;fdc 0(0,%1)\;sync"
4925   [(set_attr "type" "multi")
4926    (set_attr "length" "12")])
4927
4928 (define_insn "icacheflush"
4929   [(unspec_volatile [(const_int 2)] 0)
4930    (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
4931    (use (mem:SI (match_operand:SI 1 "register_operand" "r")))
4932    (use (match_operand:SI 2 "register_operand" "r"))
4933    (clobber (match_operand:SI 3 "register_operand" "=&r"))
4934    (clobber (match_operand:SI 4 "register_operand" "=&r"))]
4935   ""
4936   "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
4937   [(set_attr "type" "multi")
4938    (set_attr "length" "52")])
4939
4940 ;; An out-of-line prologue.
4941 (define_insn "outline_prologue_call"
4942   [(unspec_volatile [(const_int 0)] 0)
4943    (clobber (reg:SI 31))
4944    (clobber (reg:SI 22))
4945    (clobber (reg:SI 21))
4946    (clobber (reg:SI 20))
4947    (clobber (reg:SI 19))
4948    (clobber (reg:SI 1))]
4949   ""
4950   "*
4951 {
4952   extern int frame_pointer_needed;
4953
4954   /* We need two different versions depending on whether or not we
4955      need a frame pointer.   Also note that we return to the instruction
4956      immediately after the branch rather than two instructions after the
4957      break as normally is the case.  */
4958   if (frame_pointer_needed)
4959     {
4960       /* Must import the magic millicode routine(s).  */
4961       output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
4962
4963       if (TARGET_PORTABLE_RUNTIME)
4964         {
4965           output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
4966           output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
4967                            NULL);
4968         }
4969       else
4970         output_asm_insn (\"bl,n __outline_prologue_fp,%%r31\", NULL);
4971     }
4972   else
4973     {
4974       /* Must import the magic millicode routine(s).  */
4975       output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
4976
4977       if (TARGET_PORTABLE_RUNTIME)
4978         {
4979           output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
4980           output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
4981         }
4982       else
4983         output_asm_insn (\"bl,n __outline_prologue,%%r31\", NULL);
4984     }
4985   return \"\";
4986 }"
4987   [(set_attr "type" "multi")
4988    (set_attr "length" "8")])
4989
4990 ;; An out-of-line epilogue.
4991 (define_insn "outline_epilogue_call"
4992   [(unspec_volatile [(const_int 1)] 0)
4993    (use (reg:SI 29))
4994    (use (reg:SI 28))
4995    (clobber (reg:SI 31))
4996    (clobber (reg:SI 22))
4997    (clobber (reg:SI 21))
4998    (clobber (reg:SI 20))
4999    (clobber (reg:SI 19))
5000    (clobber (reg:SI 2))
5001    (clobber (reg:SI 1))]
5002   ""
5003   "*
5004 {
5005   extern int frame_pointer_needed;
5006
5007   /* We need two different versions depending on whether or not we
5008      need a frame pointer.   Also note that we return to the instruction
5009      immediately after the branch rather than two instructions after the
5010      break as normally is the case.  */
5011   if (frame_pointer_needed)
5012     {
5013       /* Must import the magic millicode routine.  */
5014       output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
5015
5016       /* The out-of-line prologue will make sure we return to the right
5017          instruction.  */
5018       if (TARGET_PORTABLE_RUNTIME)
5019         {
5020           output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
5021           output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
5022                            NULL);
5023         }
5024       else
5025         output_asm_insn (\"bl,n __outline_epilogue_fp,%%r31\", NULL);
5026     }
5027   else
5028     {
5029       /* Must import the magic millicode routine.  */
5030       output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
5031
5032       /* The out-of-line prologue will make sure we return to the right
5033          instruction.  */
5034       if (TARGET_PORTABLE_RUNTIME)
5035         {
5036           output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
5037           output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
5038         }
5039       else
5040         output_asm_insn (\"bl,n __outline_epilogue,%%r31\", NULL);
5041     }
5042   return \"\";
5043 }"
5044   [(set_attr "type" "multi")
5045    (set_attr "length" "8")])
5046
5047 ;; Given a function pointer, canonicalize it so it can be 
5048 ;; reliably compared to another function pointer.  */
5049 (define_expand "canonicalize_funcptr_for_compare"
5050   [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
5051    (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5052               (clobber (match_dup 2))
5053               (clobber (reg:SI 26))
5054               (clobber (reg:SI 22))
5055               (clobber (reg:SI 31))])
5056    (set (match_operand:SI 0 "register_operand" "")
5057         (reg:SI 29))]
5058   "! TARGET_PORTABLE_RUNTIME"
5059   "
5060 {
5061   operands[2] = gen_reg_rtx (SImode);
5062   if (GET_CODE (operands[1]) != REG)
5063     {
5064       rtx tmp = gen_reg_rtx (Pmode);
5065       emit_move_insn (tmp, operands[1]);
5066       operands[1] = tmp;
5067     }
5068 }")
5069
5070 (define_insn ""
5071   [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
5072    (clobber (match_operand:SI 0 "register_operand" "=a"))
5073    (clobber (reg:SI 26))
5074    (clobber (reg:SI 22))
5075    (clobber (reg:SI 31))]
5076   ""
5077   "*
5078 {
5079   /* Must import the magic millicode routine.  */
5080   output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
5081
5082   /* This is absolutely amazing.
5083
5084      First, copy our input parameter into %r29 just in case we don't
5085      need to call $$sh_func_adrs.  */
5086   output_asm_insn (\"copy %%r26,%%r29\", NULL);
5087
5088   /* Next, examine the low two bits in %r26, if they aren't 0x2, then
5089      we use %r26 unchanged.  */
5090   if (get_attr_length (insn) == 32)
5091     output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+24\", NULL);
5092   else if (get_attr_length (insn) == 40)
5093     output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+32\", NULL);
5094   else if (get_attr_length (insn) == 44)
5095     output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+36\", NULL);
5096   else
5097     output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+20\", NULL);
5098
5099   /* Next, compare %r26 with 4096, if %r26 is less than or equal to
5100      4096, then we use %r26 unchanged.  */
5101   if (get_attr_length (insn) == 32)
5102     output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+16\", NULL);
5103   else if (get_attr_length (insn) == 40)
5104     output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+24\", NULL);
5105   else if (get_attr_length (insn) == 44)
5106     output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+28\", NULL);
5107   else
5108     output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+12\", NULL);
5109
5110   /* Else call $$sh_func_adrs to extract the function's real add24.  */
5111   return output_millicode_call (insn,
5112                                 gen_rtx_SYMBOL_REF (SImode, \"$$sh_func_adrs\"));
5113 }"
5114   [(set_attr "type" "multi")
5115    (set (attr "length")
5116      (cond [
5117 ;; Target (or stub) within reach
5118             (and (lt (plus (symbol_ref "total_code_bytes") (pc))
5119                      (const_int 240000))
5120                  (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5121                      (const_int 0)))
5122             (const_int 28)
5123
5124 ;; NO_SPACE_REGS
5125             (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
5126                 (const_int 0))
5127             (const_int 32)
5128
5129 ;; Out of reach, but not PIC or PORTABLE_RUNTIME
5130 ;; same as NO_SPACE_REGS code
5131             (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
5132                      (const_int 0))
5133                  (eq (symbol_ref "flag_pic")
5134                      (const_int 0)))
5135             (const_int 32)
5136
5137 ;; PORTABLE_RUNTIME
5138             (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
5139                 (const_int 0))
5140             (const_int 40)]
5141
5142 ;; Out of range and PIC 
5143           (const_int 44)))])
5144
5145 ;; On the PA, the PIC register is call clobbered, so it must
5146 ;; be saved & restored around calls by the caller.  If the call
5147 ;; doesn't return normally (nonlocal goto, or an exception is
5148 ;; thrown), then the code at the exception handler label must
5149 ;; restore the PIC register.
5150 (define_expand "exception_receiver"
5151   [(const_int 4)]
5152   "!TARGET_PORTABLE_RUNTIME && flag_pic"
5153   "
5154 {
5155   /* Load the PIC register from the stack slot (in our caller's
5156      frame).  */
5157   emit_move_insn (pic_offset_table_rtx,
5158                   gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, -32)));
5159   emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
5160   emit_insn (gen_blockage ());
5161   DONE;
5162 }")
5163
5164