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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [pa/] [pa.md] - Blame information for rev 747

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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