OSDN Git Service

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