OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [config/] [pa/] [pa.md] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.