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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
;; Machine description for SPARC chip for GCC
2
;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
;;  1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5
;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6
;;  at Cygnus Support.
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 2, 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 COPYING.  If not, write to
22
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23
;; Boston, MA 02110-1301, USA.
24
 
25
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
 
27
(define_constants
28
  [(UNSPEC_MOVE_PIC             0)
29
   (UNSPEC_UPDATE_RETURN        1)
30
   (UNSPEC_LOAD_PCREL_SYM       2)
31
   (UNSPEC_MOVE_PIC_LABEL       5)
32
   (UNSPEC_SETH44               6)
33
   (UNSPEC_SETM44               7)
34
   (UNSPEC_SETHH                9)
35
   (UNSPEC_SETLM                10)
36
   (UNSPEC_EMB_HISUM            11)
37
   (UNSPEC_EMB_TEXTUHI          13)
38
   (UNSPEC_EMB_TEXTHI           14)
39
   (UNSPEC_EMB_TEXTULO          15)
40
   (UNSPEC_EMB_SETHM            18)
41
 
42
   (UNSPEC_TLSGD                30)
43
   (UNSPEC_TLSLDM               31)
44
   (UNSPEC_TLSLDO               32)
45
   (UNSPEC_TLSIE                33)
46
   (UNSPEC_TLSLE                34)
47
   (UNSPEC_TLSLD_BASE           35)
48
 
49
   (UNSPEC_FPACK16              40)
50
   (UNSPEC_FPACK32              41)
51
   (UNSPEC_FPACKFIX             42)
52
   (UNSPEC_FEXPAND              43)
53
   (UNSPEC_FPMERGE              44)
54
   (UNSPEC_MUL16AL              45)
55
   (UNSPEC_MUL8UL               46)
56
   (UNSPEC_MULDUL               47)
57
   (UNSPEC_ALIGNDATA            48)
58
   (UNSPEC_ALIGNADDR            49)
59
   (UNSPEC_PDIST                50)
60
 
61
   (UNSPEC_SP_SET               60)
62
   (UNSPEC_SP_TEST              61)
63
  ])
64
 
65
(define_constants
66
  [(UNSPECV_BLOCKAGE            0)
67
   (UNSPECV_FLUSHW              1)
68
   (UNSPECV_GOTO                2)
69
   (UNSPECV_FLUSH               4)
70
   (UNSPECV_SETJMP              5)
71
   (UNSPECV_SAVEW               6)
72
  ])
73
 
74
;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
75
;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
76
;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
77
;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
78
;; 'f' for all DF/TFmode values, including those that are specific to the v8.
79
 
80
 
81
;; Attribute for cpu type.
82
;; These must match the values for enum processor_type in sparc.h.
83
(define_attr "cpu"
84
  "v7,
85
   cypress,
86
   v8,
87
   supersparc,
88
   sparclite,f930,f934,
89
   hypersparc,sparclite86x,
90
   sparclet,tsc701,
91
   v9,
92
   ultrasparc,
93
   ultrasparc3"
94
  (const (symbol_ref "sparc_cpu_attr")))
95
 
96
;; Attribute for the instruction set.
97
;; At present we only need to distinguish v9/!v9, but for clarity we
98
;; test TARGET_V8 too.
99
(define_attr "isa" "v7,v8,v9,sparclet"
100
 (const
101
  (cond [(symbol_ref "TARGET_V9") (const_string "v9")
102
         (symbol_ref "TARGET_V8") (const_string "v8")
103
         (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
104
        (const_string "v7"))))
105
 
106
;; Insn type.
107
(define_attr "type"
108
  "ialu,compare,shift,
109
   load,sload,store,
110
   uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
111
   imul,idiv,
112
   fpload,fpstore,
113
   fp,fpmove,
114
   fpcmove,fpcrmove,
115
   fpcmp,
116
   fpmul,fpdivs,fpdivd,
117
   fpsqrts,fpsqrtd,
118
   fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
119
   cmove,
120
   ialuX,
121
   multi,savew,flushw,iflush,trap"
122
  (const_string "ialu"))
123
 
124
;; True if branch/call has empty delay slot and will emit a nop in it
125
(define_attr "empty_delay_slot" "false,true"
126
  (symbol_ref "empty_delay_slot (insn)"))
127
 
128
(define_attr "branch_type" "none,icc,fcc,reg"
129
  (const_string "none"))
130
 
131
(define_attr "pic" "false,true"
132
  (symbol_ref "flag_pic != 0"))
133
 
134
(define_attr "calls_alloca" "false,true"
135
  (symbol_ref "current_function_calls_alloca != 0"))
136
 
137
(define_attr "calls_eh_return" "false,true"
138
   (symbol_ref "current_function_calls_eh_return !=0 "))
139
 
140
(define_attr "leaf_function" "false,true"
141
  (symbol_ref "current_function_uses_only_leaf_regs != 0"))
142
 
143
(define_attr "delayed_branch" "false,true"
144
  (symbol_ref "flag_delayed_branch != 0"))
145
 
146
;; Length (in # of insns).
147
;; Beware that setting a length greater or equal to 3 for conditional branches
148
;; has a side-effect (see output_cbranch and output_v9branch).
149
(define_attr "length" ""
150
  (cond [(eq_attr "type" "uncond_branch,call")
151
           (if_then_else (eq_attr "empty_delay_slot" "true")
152
             (const_int 2)
153
             (const_int 1))
154
         (eq_attr "type" "sibcall")
155
           (if_then_else (eq_attr "leaf_function" "true")
156
             (if_then_else (eq_attr "empty_delay_slot" "true")
157
               (const_int 3)
158
               (const_int 2))
159
             (if_then_else (eq_attr "empty_delay_slot" "true")
160
               (const_int 2)
161
               (const_int 1)))
162
         (eq_attr "branch_type" "icc")
163
           (if_then_else (match_operand 0 "noov_compare64_operator" "")
164
             (if_then_else (lt (pc) (match_dup 1))
165
               (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
166
                 (if_then_else (eq_attr "empty_delay_slot" "true")
167
                   (const_int 2)
168
                   (const_int 1))
169
                 (if_then_else (eq_attr "empty_delay_slot" "true")
170
                   (const_int 4)
171
                   (const_int 3)))
172
               (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
173
                 (if_then_else (eq_attr "empty_delay_slot" "true")
174
                   (const_int 2)
175
                   (const_int 1))
176
                 (if_then_else (eq_attr "empty_delay_slot" "true")
177
                   (const_int 4)
178
                   (const_int 3))))
179
             (if_then_else (eq_attr "empty_delay_slot" "true")
180
               (const_int 2)
181
               (const_int 1)))
182
         (eq_attr "branch_type" "fcc")
183
           (if_then_else (match_operand 0 "fcc0_register_operand" "")
184
             (if_then_else (eq_attr "empty_delay_slot" "true")
185
               (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
186
                 (const_int 3)
187
                 (const_int 2))
188
               (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
189
                 (const_int 2)
190
                 (const_int 1)))
191
             (if_then_else (lt (pc) (match_dup 2))
192
               (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
193
                 (if_then_else (eq_attr "empty_delay_slot" "true")
194
                   (const_int 2)
195
                   (const_int 1))
196
                 (if_then_else (eq_attr "empty_delay_slot" "true")
197
                   (const_int 4)
198
                   (const_int 3)))
199
               (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
200
                 (if_then_else (eq_attr "empty_delay_slot" "true")
201
                   (const_int 2)
202
                   (const_int 1))
203
                 (if_then_else (eq_attr "empty_delay_slot" "true")
204
                   (const_int 4)
205
                   (const_int 3)))))
206
         (eq_attr "branch_type" "reg")
207
           (if_then_else (lt (pc) (match_dup 2))
208
             (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
209
               (if_then_else (eq_attr "empty_delay_slot" "true")
210
                 (const_int 2)
211
                 (const_int 1))
212
               (if_then_else (eq_attr "empty_delay_slot" "true")
213
                 (const_int 4)
214
                 (const_int 3)))
215
             (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
216
               (if_then_else (eq_attr "empty_delay_slot" "true")
217
                 (const_int 2)
218
                 (const_int 1))
219
               (if_then_else (eq_attr "empty_delay_slot" "true")
220
                 (const_int 4)
221
                 (const_int 3))))
222
         ] (const_int 1)))
223
 
224
;; FP precision.
225
(define_attr "fptype" "single,double"
226
  (const_string "single"))
227
 
228
;; UltraSPARC-III integer load type.
229
(define_attr "us3load_type" "2cycle,3cycle"
230
  (const_string "2cycle"))
231
 
232
(define_asm_attributes
233
  [(set_attr "length" "2")
234
   (set_attr "type" "multi")])
235
 
236
;; Attributes for instruction and branch scheduling
237
(define_attr "tls_call_delay" "false,true"
238
  (symbol_ref "tls_call_delay (insn)"))
239
 
240
(define_attr "in_call_delay" "false,true"
241
  (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
242
                (const_string "false")
243
         (eq_attr "type" "load,fpload,store,fpstore")
244
                (if_then_else (eq_attr "length" "1")
245
                              (const_string "true")
246
                              (const_string "false"))]
247
        (if_then_else (and (eq_attr "length" "1")
248
                           (eq_attr "tls_call_delay" "true"))
249
                      (const_string "true")
250
                      (const_string "false"))))
251
 
252
(define_attr "eligible_for_sibcall_delay" "false,true"
253
  (symbol_ref "eligible_for_sibcall_delay (insn)"))
254
 
255
(define_attr "eligible_for_return_delay" "false,true"
256
  (symbol_ref "eligible_for_return_delay (insn)"))
257
 
258
;; ??? !v9: Should implement the notion of predelay slots for floating-point
259
;; branches.  This would allow us to remove the nop always inserted before
260
;; a floating point branch.
261
 
262
;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
263
;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
264
;; This is because doing so will add several pipeline stalls to the path
265
;; that the load/store did not come from.  Unfortunately, there is no way
266
;; to prevent fill_eager_delay_slots from using load/store without completely
267
;; disabling them.  For the SPEC benchmark set, this is a serious lose,
268
;; because it prevents us from moving back the final store of inner loops.
269
 
270
(define_attr "in_branch_delay" "false,true"
271
  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
272
                     (eq_attr "length" "1"))
273
                (const_string "true")
274
                (const_string "false")))
275
 
276
(define_attr "in_uncond_branch_delay" "false,true"
277
  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
278
                     (eq_attr "length" "1"))
279
                (const_string "true")
280
                (const_string "false")))
281
 
282
(define_attr "in_annul_branch_delay" "false,true"
283
  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
284
                     (eq_attr "length" "1"))
285
                (const_string "true")
286
                (const_string "false")))
287
 
288
(define_delay (eq_attr "type" "call")
289
  [(eq_attr "in_call_delay" "true") (nil) (nil)])
290
 
291
(define_delay (eq_attr "type" "sibcall")
292
  [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
293
 
294
(define_delay (eq_attr "type" "branch")
295
  [(eq_attr "in_branch_delay" "true")
296
   (nil) (eq_attr "in_annul_branch_delay" "true")])
297
 
298
(define_delay (eq_attr "type" "uncond_branch")
299
  [(eq_attr "in_uncond_branch_delay" "true")
300
   (nil) (nil)])
301
 
302
(define_delay (eq_attr "type" "return")
303
  [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
304
 
305
 
306
;; Include SPARC DFA schedulers
307
 
308
(include "cypress.md")
309
(include "supersparc.md")
310
(include "hypersparc.md")
311
(include "sparclet.md")
312
(include "ultra1_2.md")
313
(include "ultra3.md")
314
 
315
 
316
;; Operand and operator predicates.
317
 
318
(include "predicates.md")
319
 
320
 
321
;; Compare instructions.
322
 
323
;; We generate RTL for comparisons and branches by having the cmpxx
324
;; patterns store away the operands.  Then, the scc and bcc patterns
325
;; emit RTL for both the compare and the branch.
326
;;
327
;; We do this because we want to generate different code for an sne and
328
;; seq insn.  In those cases, if the second operand of the compare is not
329
;; const0_rtx, we want to compute the xor of the two operands and test
330
;; it against zero.
331
;;
332
;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
333
;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
334
;; insns that actually require more than one machine instruction.
335
 
336
(define_expand "cmpsi"
337
  [(set (reg:CC 100)
338
        (compare:CC (match_operand:SI 0 "compare_operand" "")
339
                    (match_operand:SI 1 "arith_operand" "")))]
340
  ""
341
{
342
  if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
343
    operands[0] = force_reg (SImode, operands[0]);
344
 
345
  sparc_compare_op0 = operands[0];
346
  sparc_compare_op1 = operands[1];
347
  DONE;
348
})
349
 
350
(define_expand "cmpdi"
351
  [(set (reg:CCX 100)
352
        (compare:CCX (match_operand:DI 0 "compare_operand" "")
353
                     (match_operand:DI 1 "arith_operand" "")))]
354
  "TARGET_ARCH64"
355
{
356
  if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
357
    operands[0] = force_reg (DImode, operands[0]);
358
 
359
  sparc_compare_op0 = operands[0];
360
  sparc_compare_op1 = operands[1];
361
  DONE;
362
})
363
 
364
(define_expand "cmpsf"
365
  ;; The 96 here isn't ever used by anyone.
366
  [(set (reg:CCFP 96)
367
        (compare:CCFP (match_operand:SF 0 "register_operand" "")
368
                      (match_operand:SF 1 "register_operand" "")))]
369
  "TARGET_FPU"
370
{
371
  sparc_compare_op0 = operands[0];
372
  sparc_compare_op1 = operands[1];
373
  DONE;
374
})
375
 
376
(define_expand "cmpdf"
377
  ;; The 96 here isn't ever used by anyone.
378
  [(set (reg:CCFP 96)
379
        (compare:CCFP (match_operand:DF 0 "register_operand" "")
380
                      (match_operand:DF 1 "register_operand" "")))]
381
  "TARGET_FPU"
382
{
383
  sparc_compare_op0 = operands[0];
384
  sparc_compare_op1 = operands[1];
385
  DONE;
386
})
387
 
388
(define_expand "cmptf"
389
  ;; The 96 here isn't ever used by anyone.
390
  [(set (reg:CCFP 96)
391
        (compare:CCFP (match_operand:TF 0 "register_operand" "")
392
                      (match_operand:TF 1 "register_operand" "")))]
393
  "TARGET_FPU"
394
{
395
  sparc_compare_op0 = operands[0];
396
  sparc_compare_op1 = operands[1];
397
  DONE;
398
})
399
 
400
;; Now the compare DEFINE_INSNs.
401
 
402
(define_insn "*cmpsi_insn"
403
  [(set (reg:CC 100)
404
        (compare:CC (match_operand:SI 0 "register_operand" "r")
405
                    (match_operand:SI 1 "arith_operand" "rI")))]
406
  ""
407
  "cmp\t%0, %1"
408
  [(set_attr "type" "compare")])
409
 
410
(define_insn "*cmpdi_sp64"
411
  [(set (reg:CCX 100)
412
        (compare:CCX (match_operand:DI 0 "register_operand" "r")
413
                     (match_operand:DI 1 "arith_operand" "rI")))]
414
  "TARGET_ARCH64"
415
  "cmp\t%0, %1"
416
  [(set_attr "type" "compare")])
417
 
418
(define_insn "*cmpsf_fpe"
419
  [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
420
        (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
421
                       (match_operand:SF 2 "register_operand" "f")))]
422
  "TARGET_FPU"
423
{
424
  if (TARGET_V9)
425
    return "fcmpes\t%0, %1, %2";
426
  return "fcmpes\t%1, %2";
427
}
428
  [(set_attr "type" "fpcmp")])
429
 
430
(define_insn "*cmpdf_fpe"
431
  [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
432
        (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
433
                       (match_operand:DF 2 "register_operand" "e")))]
434
  "TARGET_FPU"
435
{
436
  if (TARGET_V9)
437
    return "fcmped\t%0, %1, %2";
438
  return "fcmped\t%1, %2";
439
}
440
  [(set_attr "type" "fpcmp")
441
   (set_attr "fptype" "double")])
442
 
443
(define_insn "*cmptf_fpe"
444
  [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
445
        (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
446
                       (match_operand:TF 2 "register_operand" "e")))]
447
  "TARGET_FPU && TARGET_HARD_QUAD"
448
{
449
  if (TARGET_V9)
450
    return "fcmpeq\t%0, %1, %2";
451
  return "fcmpeq\t%1, %2";
452
}
453
  [(set_attr "type" "fpcmp")])
454
 
455
(define_insn "*cmpsf_fp"
456
  [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
457
        (compare:CCFP (match_operand:SF 1 "register_operand" "f")
458
                      (match_operand:SF 2 "register_operand" "f")))]
459
  "TARGET_FPU"
460
{
461
  if (TARGET_V9)
462
    return "fcmps\t%0, %1, %2";
463
  return "fcmps\t%1, %2";
464
}
465
  [(set_attr "type" "fpcmp")])
466
 
467
(define_insn "*cmpdf_fp"
468
  [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
469
        (compare:CCFP (match_operand:DF 1 "register_operand" "e")
470
                      (match_operand:DF 2 "register_operand" "e")))]
471
  "TARGET_FPU"
472
{
473
  if (TARGET_V9)
474
    return "fcmpd\t%0, %1, %2";
475
  return "fcmpd\t%1, %2";
476
}
477
  [(set_attr "type" "fpcmp")
478
   (set_attr "fptype" "double")])
479
 
480
(define_insn "*cmptf_fp"
481
  [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
482
        (compare:CCFP (match_operand:TF 1 "register_operand" "e")
483
                      (match_operand:TF 2 "register_operand" "e")))]
484
  "TARGET_FPU && TARGET_HARD_QUAD"
485
{
486
  if (TARGET_V9)
487
    return "fcmpq\t%0, %1, %2";
488
  return "fcmpq\t%1, %2";
489
}
490
  [(set_attr "type" "fpcmp")])
491
 
492
;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
493
;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
494
;; the same code as v8 (the addx/subx method has more applications).  The
495
;; exception to this is "reg != 0" which can be done in one instruction on v9
496
;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
497
;; branches.
498
 
499
;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
500
;; generate addcc/subcc instructions.
501
 
502
(define_expand "seqsi_special"
503
  [(set (match_dup 3)
504
        (xor:SI (match_operand:SI 1 "register_operand" "")
505
                (match_operand:SI 2 "register_operand" "")))
506
   (parallel [(set (match_operand:SI 0 "register_operand" "")
507
                   (eq:SI (match_dup 3) (const_int 0)))
508
              (clobber (reg:CC 100))])]
509
  ""
510
  { operands[3] = gen_reg_rtx (SImode); })
511
 
512
(define_expand "seqdi_special"
513
  [(set (match_dup 3)
514
        (xor:DI (match_operand:DI 1 "register_operand" "")
515
                (match_operand:DI 2 "register_operand" "")))
516
   (set (match_operand:DI 0 "register_operand" "")
517
        (eq:DI (match_dup 3) (const_int 0)))]
518
  "TARGET_ARCH64"
519
  { operands[3] = gen_reg_rtx (DImode); })
520
 
521
(define_expand "snesi_special"
522
  [(set (match_dup 3)
523
        (xor:SI (match_operand:SI 1 "register_operand" "")
524
                (match_operand:SI 2 "register_operand" "")))
525
   (parallel [(set (match_operand:SI 0 "register_operand" "")
526
                   (ne:SI (match_dup 3) (const_int 0)))
527
              (clobber (reg:CC 100))])]
528
  ""
529
  { operands[3] = gen_reg_rtx (SImode); })
530
 
531
(define_expand "snedi_special"
532
  [(set (match_dup 3)
533
        (xor:DI (match_operand:DI 1 "register_operand" "")
534
                (match_operand:DI 2 "register_operand" "")))
535
   (set (match_operand:DI 0 "register_operand" "")
536
        (ne:DI (match_dup 3) (const_int 0)))]
537
  "TARGET_ARCH64"
538
  { operands[3] = gen_reg_rtx (DImode); })
539
 
540
(define_expand "seqdi_special_trunc"
541
  [(set (match_dup 3)
542
        (xor:DI (match_operand:DI 1 "register_operand" "")
543
                (match_operand:DI 2 "register_operand" "")))
544
   (set (match_operand:SI 0 "register_operand" "")
545
        (eq:SI (match_dup 3) (const_int 0)))]
546
  "TARGET_ARCH64"
547
  { operands[3] = gen_reg_rtx (DImode); })
548
 
549
(define_expand "snedi_special_trunc"
550
  [(set (match_dup 3)
551
        (xor:DI (match_operand:DI 1 "register_operand" "")
552
                (match_operand:DI 2 "register_operand" "")))
553
   (set (match_operand:SI 0 "register_operand" "")
554
        (ne:SI (match_dup 3) (const_int 0)))]
555
  "TARGET_ARCH64"
556
  { operands[3] = gen_reg_rtx (DImode); })
557
 
558
(define_expand "seqsi_special_extend"
559
  [(set (match_dup 3)
560
        (xor:SI (match_operand:SI 1 "register_operand" "")
561
                (match_operand:SI 2 "register_operand" "")))
562
   (parallel [(set (match_operand:DI 0 "register_operand" "")
563
                   (eq:DI (match_dup 3) (const_int 0)))
564
              (clobber (reg:CC 100))])]
565
  "TARGET_ARCH64"
566
  { operands[3] = gen_reg_rtx (SImode); })
567
 
568
(define_expand "snesi_special_extend"
569
  [(set (match_dup 3)
570
        (xor:SI (match_operand:SI 1 "register_operand" "")
571
                (match_operand:SI 2 "register_operand" "")))
572
   (parallel [(set (match_operand:DI 0 "register_operand" "")
573
                   (ne:DI (match_dup 3) (const_int 0)))
574
              (clobber (reg:CC 100))])]
575
  "TARGET_ARCH64"
576
  { operands[3] = gen_reg_rtx (SImode); })
577
 
578
;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
579
;; However, the code handles both SImode and DImode.
580
(define_expand "seq"
581
  [(set (match_operand:SI 0 "int_register_operand" "")
582
        (eq:SI (match_dup 1) (const_int 0)))]
583
  ""
584
{
585
  if (GET_MODE (sparc_compare_op0) == SImode)
586
    {
587
      rtx pat;
588
 
589
      if (GET_MODE (operands[0]) == SImode)
590
        pat = gen_seqsi_special (operands[0], sparc_compare_op0,
591
                                 sparc_compare_op1);
592
      else if (! TARGET_ARCH64)
593
        FAIL;
594
      else
595
        pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
596
                                        sparc_compare_op1);
597
      emit_insn (pat);
598
      DONE;
599
    }
600
  else if (GET_MODE (sparc_compare_op0) == DImode)
601
    {
602
      rtx pat;
603
 
604
      if (! TARGET_ARCH64)
605
        FAIL;
606
      else if (GET_MODE (operands[0]) == SImode)
607
        pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
608
                                       sparc_compare_op1);
609
      else
610
        pat = gen_seqdi_special (operands[0], sparc_compare_op0,
611
                                 sparc_compare_op1);
612
      emit_insn (pat);
613
      DONE;
614
    }
615
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
616
    {
617
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
618
      emit_jump_insn (gen_sne (operands[0]));
619
      DONE;
620
    }
621
  else if (TARGET_V9)
622
    {
623
      if (gen_v9_scc (EQ, operands))
624
        DONE;
625
      /* fall through */
626
    }
627
  FAIL;
628
})
629
 
630
;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
631
;; However, the code handles both SImode and DImode.
632
(define_expand "sne"
633
  [(set (match_operand:SI 0 "int_register_operand" "")
634
        (ne:SI (match_dup 1) (const_int 0)))]
635
  ""
636
{
637
  if (GET_MODE (sparc_compare_op0) == SImode)
638
    {
639
      rtx pat;
640
 
641
      if (GET_MODE (operands[0]) == SImode)
642
        pat = gen_snesi_special (operands[0], sparc_compare_op0,
643
                                 sparc_compare_op1);
644
      else if (! TARGET_ARCH64)
645
        FAIL;
646
      else
647
        pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
648
                                        sparc_compare_op1);
649
      emit_insn (pat);
650
      DONE;
651
    }
652
  else if (GET_MODE (sparc_compare_op0) == DImode)
653
    {
654
      rtx pat;
655
 
656
      if (! TARGET_ARCH64)
657
        FAIL;
658
      else if (GET_MODE (operands[0]) == SImode)
659
        pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
660
                                       sparc_compare_op1);
661
      else
662
        pat = gen_snedi_special (operands[0], sparc_compare_op0,
663
                                 sparc_compare_op1);
664
      emit_insn (pat);
665
      DONE;
666
    }
667
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
668
    {
669
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
670
      emit_jump_insn (gen_sne (operands[0]));
671
      DONE;
672
    }
673
  else if (TARGET_V9)
674
    {
675
      if (gen_v9_scc (NE, operands))
676
        DONE;
677
      /* fall through */
678
    }
679
  FAIL;
680
})
681
 
682
(define_expand "sgt"
683
  [(set (match_operand:SI 0 "int_register_operand" "")
684
        (gt:SI (match_dup 1) (const_int 0)))]
685
  ""
686
{
687
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
688
    {
689
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
690
      emit_jump_insn (gen_sne (operands[0]));
691
      DONE;
692
    }
693
  else if (TARGET_V9)
694
    {
695
      if (gen_v9_scc (GT, operands))
696
        DONE;
697
      /* fall through */
698
    }
699
  FAIL;
700
})
701
 
702
(define_expand "slt"
703
  [(set (match_operand:SI 0 "int_register_operand" "")
704
        (lt:SI (match_dup 1) (const_int 0)))]
705
  ""
706
{
707
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
708
    {
709
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
710
      emit_jump_insn (gen_sne (operands[0]));
711
      DONE;
712
    }
713
  else if (TARGET_V9)
714
    {
715
      if (gen_v9_scc (LT, operands))
716
        DONE;
717
      /* fall through */
718
    }
719
  FAIL;
720
})
721
 
722
(define_expand "sge"
723
  [(set (match_operand:SI 0 "int_register_operand" "")
724
        (ge:SI (match_dup 1) (const_int 0)))]
725
  ""
726
{
727
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
728
    {
729
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
730
      emit_jump_insn (gen_sne (operands[0]));
731
      DONE;
732
    }
733
  else if (TARGET_V9)
734
    {
735
      if (gen_v9_scc (GE, operands))
736
        DONE;
737
      /* fall through */
738
    }
739
  FAIL;
740
})
741
 
742
(define_expand "sle"
743
  [(set (match_operand:SI 0 "int_register_operand" "")
744
        (le:SI (match_dup 1) (const_int 0)))]
745
  ""
746
{
747
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
748
    {
749
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
750
      emit_jump_insn (gen_sne (operands[0]));
751
      DONE;
752
    }
753
  else if (TARGET_V9)
754
    {
755
      if (gen_v9_scc (LE, operands))
756
        DONE;
757
      /* fall through */
758
    }
759
  FAIL;
760
})
761
 
762
(define_expand "sgtu"
763
  [(set (match_operand:SI 0 "int_register_operand" "")
764
        (gtu:SI (match_dup 1) (const_int 0)))]
765
  ""
766
{
767
  if (! TARGET_V9)
768
    {
769
      rtx tem, pat;
770
 
771
      /* We can do ltu easily, so if both operands are registers, swap them and
772
         do a LTU.  */
773
      if ((GET_CODE (sparc_compare_op0) == REG
774
           || GET_CODE (sparc_compare_op0) == SUBREG)
775
          && (GET_CODE (sparc_compare_op1) == REG
776
              || GET_CODE (sparc_compare_op1) == SUBREG))
777
        {
778
          tem = sparc_compare_op0;
779
          sparc_compare_op0 = sparc_compare_op1;
780
          sparc_compare_op1 = tem;
781
          pat = gen_sltu (operands[0]);
782
          if (pat == NULL_RTX)
783
            FAIL;
784
          emit_insn (pat);
785
          DONE;
786
        }
787
    }
788
  else
789
    {
790
      if (gen_v9_scc (GTU, operands))
791
        DONE;
792
    }
793
  FAIL;
794
})
795
 
796
(define_expand "sltu"
797
  [(set (match_operand:SI 0 "int_register_operand" "")
798
        (ltu:SI (match_dup 1) (const_int 0)))]
799
  ""
800
{
801
  if (TARGET_V9)
802
    {
803
      if (gen_v9_scc (LTU, operands))
804
        DONE;
805
    }
806
  operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
807
})
808
 
809
(define_expand "sgeu"
810
  [(set (match_operand:SI 0 "int_register_operand" "")
811
        (geu:SI (match_dup 1) (const_int 0)))]
812
  ""
813
{
814
  if (TARGET_V9)
815
    {
816
      if (gen_v9_scc (GEU, operands))
817
        DONE;
818
    }
819
  operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
820
})
821
 
822
(define_expand "sleu"
823
  [(set (match_operand:SI 0 "int_register_operand" "")
824
        (leu:SI (match_dup 1) (const_int 0)))]
825
  ""
826
{
827
  if (! TARGET_V9)
828
    {
829
      rtx tem, pat;
830
 
831
      /* We can do geu easily, so if both operands are registers, swap them and
832
         do a GEU.  */
833
      if ((GET_CODE (sparc_compare_op0) == REG
834
           || GET_CODE (sparc_compare_op0) == SUBREG)
835
          && (GET_CODE (sparc_compare_op1) == REG
836
              || GET_CODE (sparc_compare_op1) == SUBREG))
837
        {
838
          tem = sparc_compare_op0;
839
          sparc_compare_op0 = sparc_compare_op1;
840
          sparc_compare_op1 = tem;
841
          pat = gen_sgeu (operands[0]);
842
          if (pat == NULL_RTX)
843
            FAIL;
844
          emit_insn (pat);
845
          DONE;
846
        }
847
    }
848
  else
849
    {
850
      if (gen_v9_scc (LEU, operands))
851
        DONE;
852
    }
853
  FAIL;
854
})
855
 
856
;; Now the DEFINE_INSNs for the scc cases.
857
 
858
;; The SEQ and SNE patterns are special because they can be done
859
;; without any branching and do not involve a COMPARE.  We want
860
;; them to always use the splits below so the results can be
861
;; scheduled.
862
 
863
(define_insn_and_split "*snesi_zero"
864
  [(set (match_operand:SI 0 "register_operand" "=r")
865
        (ne:SI (match_operand:SI 1 "register_operand" "r")
866
               (const_int 0)))
867
   (clobber (reg:CC 100))]
868
  ""
869
  "#"
870
  ""
871
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
872
                                           (const_int 0)))
873
   (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
874
  ""
875
  [(set_attr "length" "2")])
876
 
877
(define_insn_and_split "*neg_snesi_zero"
878
  [(set (match_operand:SI 0 "register_operand" "=r")
879
        (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
880
                       (const_int 0))))
881
   (clobber (reg:CC 100))]
882
  ""
883
  "#"
884
  ""
885
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
886
                                           (const_int 0)))
887
   (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
888
  ""
889
  [(set_attr "length" "2")])
890
 
891
(define_insn_and_split "*snesi_zero_extend"
892
  [(set (match_operand:DI 0 "register_operand" "=r")
893
        (ne:DI (match_operand:SI 1 "register_operand" "r")
894
               (const_int 0)))
895
   (clobber (reg:CC 100))]
896
  "TARGET_ARCH64"
897
  "#"
898
  "&& 1"
899
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
900
                                                     (match_dup 1))
901
                                           (const_int 0)))
902
   (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
903
                                                        (const_int 0))
904
                                               (ltu:SI (reg:CC_NOOV 100)
905
                                                       (const_int 0)))))]
906
  ""
907
  [(set_attr "length" "2")])
908
 
909
(define_insn_and_split "*snedi_zero"
910
  [(set (match_operand:DI 0 "register_operand" "=&r")
911
        (ne:DI (match_operand:DI 1 "register_operand" "r")
912
               (const_int 0)))]
913
  "TARGET_ARCH64"
914
  "#"
915
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916
  [(set (match_dup 0) (const_int 0))
917
   (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
918
                                              (const_int 0))
919
                                       (const_int 1)
920
                                       (match_dup 0)))]
921
  ""
922
  [(set_attr "length" "2")])
923
 
924
(define_insn_and_split "*neg_snedi_zero"
925
  [(set (match_operand:DI 0 "register_operand" "=&r")
926
        (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
927
                       (const_int 0))))]
928
  "TARGET_ARCH64"
929
  "#"
930
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931
  [(set (match_dup 0) (const_int 0))
932
   (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
933
                                              (const_int 0))
934
                                       (const_int -1)
935
                                       (match_dup 0)))]
936
  ""
937
  [(set_attr "length" "2")])
938
 
939
(define_insn_and_split "*snedi_zero_trunc"
940
  [(set (match_operand:SI 0 "register_operand" "=&r")
941
        (ne:SI (match_operand:DI 1 "register_operand" "r")
942
               (const_int 0)))]
943
  "TARGET_ARCH64"
944
  "#"
945
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946
  [(set (match_dup 0) (const_int 0))
947
   (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
948
                                              (const_int 0))
949
                                       (const_int 1)
950
                                       (match_dup 0)))]
951
  ""
952
  [(set_attr "length" "2")])
953
 
954
(define_insn_and_split "*seqsi_zero"
955
  [(set (match_operand:SI 0 "register_operand" "=r")
956
        (eq:SI (match_operand:SI 1 "register_operand" "r")
957
               (const_int 0)))
958
   (clobber (reg:CC 100))]
959
  ""
960
  "#"
961
  ""
962
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
963
                                           (const_int 0)))
964
   (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
965
  ""
966
  [(set_attr "length" "2")])
967
 
968
(define_insn_and_split "*neg_seqsi_zero"
969
  [(set (match_operand:SI 0 "register_operand" "=r")
970
        (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
971
                       (const_int 0))))
972
   (clobber (reg:CC 100))]
973
  ""
974
  "#"
975
  ""
976
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
977
                                           (const_int 0)))
978
   (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
979
  ""
980
  [(set_attr "length" "2")])
981
 
982
(define_insn_and_split "*seqsi_zero_extend"
983
  [(set (match_operand:DI 0 "register_operand" "=r")
984
        (eq:DI (match_operand:SI 1 "register_operand" "r")
985
               (const_int 0)))
986
   (clobber (reg:CC 100))]
987
  "TARGET_ARCH64"
988
  "#"
989
  "&& 1"
990
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
991
                                                     (match_dup 1))
992
                                           (const_int 0)))
993
   (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
994
                                                          (const_int -1))
995
                                                (ltu:SI (reg:CC_NOOV 100)
996
                                                        (const_int 0)))))]
997
  ""
998
  [(set_attr "length" "2")])
999
 
1000
(define_insn_and_split "*seqdi_zero"
1001
  [(set (match_operand:DI 0 "register_operand" "=&r")
1002
        (eq:DI (match_operand:DI 1 "register_operand" "r")
1003
               (const_int 0)))]
1004
  "TARGET_ARCH64"
1005
  "#"
1006
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1007
  [(set (match_dup 0) (const_int 0))
1008
   (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1009
                                              (const_int 0))
1010
                                       (const_int 1)
1011
                                       (match_dup 0)))]
1012
  ""
1013
  [(set_attr "length" "2")])
1014
 
1015
(define_insn_and_split "*neg_seqdi_zero"
1016
  [(set (match_operand:DI 0 "register_operand" "=&r")
1017
        (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1018
                       (const_int 0))))]
1019
  "TARGET_ARCH64"
1020
  "#"
1021
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1022
  [(set (match_dup 0) (const_int 0))
1023
   (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1024
                                              (const_int 0))
1025
                                       (const_int -1)
1026
                                       (match_dup 0)))]
1027
  ""
1028
  [(set_attr "length" "2")])
1029
 
1030
(define_insn_and_split "*seqdi_zero_trunc"
1031
  [(set (match_operand:SI 0 "register_operand" "=&r")
1032
        (eq:SI (match_operand:DI 1 "register_operand" "r")
1033
               (const_int 0)))]
1034
  "TARGET_ARCH64"
1035
  "#"
1036
  "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1037
  [(set (match_dup 0) (const_int 0))
1038
   (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1039
                                              (const_int 0))
1040
                                       (const_int 1)
1041
                                       (match_dup 0)))]
1042
  ""
1043
  [(set_attr "length" "2")])
1044
 
1045
;; We can also do (x + (i == 0)) and related, so put them in.
1046
;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1047
;; versions for v9.
1048
 
1049
(define_insn_and_split "*x_plus_i_ne_0"
1050
  [(set (match_operand:SI 0 "register_operand" "=r")
1051
        (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1052
                        (const_int 0))
1053
                 (match_operand:SI 2 "register_operand" "r")))
1054
   (clobber (reg:CC 100))]
1055
  ""
1056
  "#"
1057
  ""
1058
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1059
                                           (const_int 0)))
1060
   (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1061
                               (match_dup 2)))]
1062
  ""
1063
  [(set_attr "length" "2")])
1064
 
1065
(define_insn_and_split "*x_minus_i_ne_0"
1066
  [(set (match_operand:SI 0 "register_operand" "=r")
1067
        (minus:SI (match_operand:SI 2 "register_operand" "r")
1068
                  (ne:SI (match_operand:SI 1 "register_operand" "r")
1069
                         (const_int 0))))
1070
   (clobber (reg:CC 100))]
1071
  ""
1072
  "#"
1073
  ""
1074
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1075
                                           (const_int 0)))
1076
   (set (match_dup 0) (minus:SI (match_dup 2)
1077
                                (ltu:SI (reg:CC 100) (const_int 0))))]
1078
  ""
1079
  [(set_attr "length" "2")])
1080
 
1081
(define_insn_and_split "*x_plus_i_eq_0"
1082
  [(set (match_operand:SI 0 "register_operand" "=r")
1083
        (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1084
                        (const_int 0))
1085
                 (match_operand:SI 2 "register_operand" "r")))
1086
   (clobber (reg:CC 100))]
1087
  ""
1088
  "#"
1089
  ""
1090
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1091
                                           (const_int 0)))
1092
   (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1093
                               (match_dup 2)))]
1094
  ""
1095
  [(set_attr "length" "2")])
1096
 
1097
(define_insn_and_split "*x_minus_i_eq_0"
1098
  [(set (match_operand:SI 0 "register_operand" "=r")
1099
        (minus:SI (match_operand:SI 2 "register_operand" "r")
1100
                  (eq:SI (match_operand:SI 1 "register_operand" "r")
1101
                         (const_int 0))))
1102
   (clobber (reg:CC 100))]
1103
  ""
1104
  "#"
1105
  ""
1106
  [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1107
                                           (const_int 0)))
1108
   (set (match_dup 0) (minus:SI (match_dup 2)
1109
                                (geu:SI (reg:CC 100) (const_int 0))))]
1110
  ""
1111
  [(set_attr "length" "2")])
1112
 
1113
;; We can also do GEU and LTU directly, but these operate after a compare.
1114
;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1115
;; versions for v9.
1116
 
1117
(define_insn "*sltu_insn"
1118
  [(set (match_operand:SI 0 "register_operand" "=r")
1119
        (ltu:SI (reg:CC 100) (const_int 0)))]
1120
  ""
1121
  "addx\t%%g0, 0, %0"
1122
  [(set_attr "type" "ialuX")])
1123
 
1124
(define_insn "*neg_sltu_insn"
1125
  [(set (match_operand:SI 0 "register_operand" "=r")
1126
        (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1127
  ""
1128
  "subx\t%%g0, 0, %0"
1129
  [(set_attr "type" "ialuX")])
1130
 
1131
;; ??? Combine should canonicalize these next two to the same pattern.
1132
(define_insn "*neg_sltu_minus_x"
1133
  [(set (match_operand:SI 0 "register_operand" "=r")
1134
        (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1135
                  (match_operand:SI 1 "arith_operand" "rI")))]
1136
  ""
1137
  "subx\t%%g0, %1, %0"
1138
  [(set_attr "type" "ialuX")])
1139
 
1140
(define_insn "*neg_sltu_plus_x"
1141
  [(set (match_operand:SI 0 "register_operand" "=r")
1142
        (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1143
                         (match_operand:SI 1 "arith_operand" "rI"))))]
1144
  ""
1145
  "subx\t%%g0, %1, %0"
1146
  [(set_attr "type" "ialuX")])
1147
 
1148
(define_insn "*sgeu_insn"
1149
  [(set (match_operand:SI 0 "register_operand" "=r")
1150
        (geu:SI (reg:CC 100) (const_int 0)))]
1151
  ""
1152
  "subx\t%%g0, -1, %0"
1153
  [(set_attr "type" "ialuX")])
1154
 
1155
(define_insn "*neg_sgeu_insn"
1156
  [(set (match_operand:SI 0 "register_operand" "=r")
1157
        (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1158
  ""
1159
  "addx\t%%g0, -1, %0"
1160
  [(set_attr "type" "ialuX")])
1161
 
1162
;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1163
;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1164
;; versions for v9.
1165
 
1166
(define_insn "*sltu_plus_x"
1167
  [(set (match_operand:SI 0 "register_operand" "=r")
1168
        (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1169
                 (match_operand:SI 1 "arith_operand" "rI")))]
1170
  ""
1171
  "addx\t%%g0, %1, %0"
1172
  [(set_attr "type" "ialuX")])
1173
 
1174
(define_insn "*sltu_plus_x_plus_y"
1175
  [(set (match_operand:SI 0 "register_operand" "=r")
1176
        (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1177
                 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1178
                          (match_operand:SI 2 "arith_operand" "rI"))))]
1179
  ""
1180
  "addx\t%1, %2, %0"
1181
  [(set_attr "type" "ialuX")])
1182
 
1183
(define_insn "*x_minus_sltu"
1184
  [(set (match_operand:SI 0 "register_operand" "=r")
1185
        (minus:SI (match_operand:SI 1 "register_operand" "r")
1186
                  (ltu:SI (reg:CC 100) (const_int 0))))]
1187
  ""
1188
  "subx\t%1, 0, %0"
1189
  [(set_attr "type" "ialuX")])
1190
 
1191
;; ??? Combine should canonicalize these next two to the same pattern.
1192
(define_insn "*x_minus_y_minus_sltu"
1193
  [(set (match_operand:SI 0 "register_operand" "=r")
1194
        (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1195
                            (match_operand:SI 2 "arith_operand" "rI"))
1196
                  (ltu:SI (reg:CC 100) (const_int 0))))]
1197
  ""
1198
  "subx\t%r1, %2, %0"
1199
  [(set_attr "type" "ialuX")])
1200
 
1201
(define_insn "*x_minus_sltu_plus_y"
1202
  [(set (match_operand:SI 0 "register_operand" "=r")
1203
        (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1204
                  (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1205
                           (match_operand:SI 2 "arith_operand" "rI"))))]
1206
  ""
1207
  "subx\t%r1, %2, %0"
1208
  [(set_attr "type" "ialuX")])
1209
 
1210
(define_insn "*sgeu_plus_x"
1211
  [(set (match_operand:SI 0 "register_operand" "=r")
1212
        (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1213
                 (match_operand:SI 1 "register_operand" "r")))]
1214
  ""
1215
  "subx\t%1, -1, %0"
1216
  [(set_attr "type" "ialuX")])
1217
 
1218
(define_insn "*x_minus_sgeu"
1219
  [(set (match_operand:SI 0 "register_operand" "=r")
1220
        (minus:SI (match_operand:SI 1 "register_operand" "r")
1221
                  (geu:SI (reg:CC 100) (const_int 0))))]
1222
  ""
1223
  "addx\t%1, -1, %0"
1224
  [(set_attr "type" "ialuX")])
1225
 
1226
(define_split
1227
  [(set (match_operand:SI 0 "register_operand" "")
1228
        (match_operator:SI 2 "noov_compare_operator"
1229
                           [(match_operand 1 "icc_or_fcc_register_operand" "")
1230
                            (const_int 0)]))]
1231
  "TARGET_V9
1232
   && REGNO (operands[1]) == SPARC_ICC_REG
1233
   && (GET_MODE (operands[1]) == CCXmode
1234
       /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1235
       || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1236
  [(set (match_dup 0) (const_int 0))
1237
   (set (match_dup 0)
1238
        (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1239
                         (const_int 1)
1240
                         (match_dup 0)))]
1241
  "")
1242
 
1243
 
1244
;; These control RTL generation for conditional jump insns
1245
 
1246
;; The quad-word fp compare library routines all return nonzero to indicate
1247
;; true, which is different from the equivalent libgcc routines, so we must
1248
;; handle them specially here.
1249
 
1250
(define_expand "beq"
1251
  [(set (pc)
1252
        (if_then_else (eq (match_dup 1) (const_int 0))
1253
                      (label_ref (match_operand 0 "" ""))
1254
                      (pc)))]
1255
  ""
1256
{
1257
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1258
      && GET_CODE (sparc_compare_op0) == REG
1259
      && GET_MODE (sparc_compare_op0) == DImode)
1260
    {
1261
      emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1262
      DONE;
1263
    }
1264
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1265
    {
1266
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1267
      emit_jump_insn (gen_bne (operands[0]));
1268
      DONE;
1269
    }
1270
  operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1271
})
1272
 
1273
(define_expand "bne"
1274
  [(set (pc)
1275
        (if_then_else (ne (match_dup 1) (const_int 0))
1276
                      (label_ref (match_operand 0 "" ""))
1277
                      (pc)))]
1278
  ""
1279
{
1280
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1281
      && GET_CODE (sparc_compare_op0) == REG
1282
      && GET_MODE (sparc_compare_op0) == DImode)
1283
    {
1284
      emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1285
      DONE;
1286
    }
1287
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1288
    {
1289
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1290
      emit_jump_insn (gen_bne (operands[0]));
1291
      DONE;
1292
    }
1293
  operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1294
})
1295
 
1296
(define_expand "bgt"
1297
  [(set (pc)
1298
        (if_then_else (gt (match_dup 1) (const_int 0))
1299
                      (label_ref (match_operand 0 "" ""))
1300
                      (pc)))]
1301
  ""
1302
{
1303
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1304
      && GET_CODE (sparc_compare_op0) == REG
1305
      && GET_MODE (sparc_compare_op0) == DImode)
1306
    {
1307
      emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1308
      DONE;
1309
    }
1310
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1311
    {
1312
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1313
      emit_jump_insn (gen_bne (operands[0]));
1314
      DONE;
1315
    }
1316
  operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1317
})
1318
 
1319
(define_expand "bgtu"
1320
  [(set (pc)
1321
        (if_then_else (gtu (match_dup 1) (const_int 0))
1322
                      (label_ref (match_operand 0 "" ""))
1323
                      (pc)))]
1324
  ""
1325
{
1326
  operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1327
})
1328
 
1329
(define_expand "blt"
1330
  [(set (pc)
1331
        (if_then_else (lt (match_dup 1) (const_int 0))
1332
                      (label_ref (match_operand 0 "" ""))
1333
                      (pc)))]
1334
  ""
1335
{
1336
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337
      && GET_CODE (sparc_compare_op0) == REG
1338
      && GET_MODE (sparc_compare_op0) == DImode)
1339
    {
1340
      emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1341
      DONE;
1342
    }
1343
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1344
    {
1345
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1346
      emit_jump_insn (gen_bne (operands[0]));
1347
      DONE;
1348
    }
1349
  operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1350
})
1351
 
1352
(define_expand "bltu"
1353
  [(set (pc)
1354
        (if_then_else (ltu (match_dup 1) (const_int 0))
1355
                      (label_ref (match_operand 0 "" ""))
1356
                      (pc)))]
1357
  ""
1358
{
1359
  operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1360
})
1361
 
1362
(define_expand "bge"
1363
  [(set (pc)
1364
        (if_then_else (ge (match_dup 1) (const_int 0))
1365
                      (label_ref (match_operand 0 "" ""))
1366
                      (pc)))]
1367
  ""
1368
{
1369
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370
      && GET_CODE (sparc_compare_op0) == REG
1371
      && GET_MODE (sparc_compare_op0) == DImode)
1372
    {
1373
      emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1374
      DONE;
1375
    }
1376
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1377
    {
1378
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1379
      emit_jump_insn (gen_bne (operands[0]));
1380
      DONE;
1381
    }
1382
  operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1383
})
1384
 
1385
(define_expand "bgeu"
1386
  [(set (pc)
1387
        (if_then_else (geu (match_dup 1) (const_int 0))
1388
                      (label_ref (match_operand 0 "" ""))
1389
                      (pc)))]
1390
  ""
1391
{
1392
  operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1393
})
1394
 
1395
(define_expand "ble"
1396
  [(set (pc)
1397
        (if_then_else (le (match_dup 1) (const_int 0))
1398
                      (label_ref (match_operand 0 "" ""))
1399
                      (pc)))]
1400
  ""
1401
{
1402
  if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1403
      && GET_CODE (sparc_compare_op0) == REG
1404
      && GET_MODE (sparc_compare_op0) == DImode)
1405
    {
1406
      emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1407
      DONE;
1408
    }
1409
  else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1410
    {
1411
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1412
      emit_jump_insn (gen_bne (operands[0]));
1413
      DONE;
1414
    }
1415
  operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1416
})
1417
 
1418
(define_expand "bleu"
1419
  [(set (pc)
1420
        (if_then_else (leu (match_dup 1) (const_int 0))
1421
                      (label_ref (match_operand 0 "" ""))
1422
                      (pc)))]
1423
  ""
1424
{
1425
  operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1426
})
1427
 
1428
(define_expand "bunordered"
1429
  [(set (pc)
1430
        (if_then_else (unordered (match_dup 1) (const_int 0))
1431
                      (label_ref (match_operand 0 "" ""))
1432
                      (pc)))]
1433
  ""
1434
{
1435
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1436
    {
1437
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1438
                                UNORDERED);
1439
      emit_jump_insn (gen_beq (operands[0]));
1440
      DONE;
1441
    }
1442
  operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1443
                                 sparc_compare_op1);
1444
})
1445
 
1446
(define_expand "bordered"
1447
  [(set (pc)
1448
        (if_then_else (ordered (match_dup 1) (const_int 0))
1449
                      (label_ref (match_operand 0 "" ""))
1450
                      (pc)))]
1451
  ""
1452
{
1453
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1454
    {
1455
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1456
      emit_jump_insn (gen_bne (operands[0]));
1457
      DONE;
1458
    }
1459
  operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1460
                                 sparc_compare_op1);
1461
})
1462
 
1463
(define_expand "bungt"
1464
  [(set (pc)
1465
        (if_then_else (ungt (match_dup 1) (const_int 0))
1466
                      (label_ref (match_operand 0 "" ""))
1467
                      (pc)))]
1468
  ""
1469
{
1470
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1471
    {
1472
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1473
      emit_jump_insn (gen_bgt (operands[0]));
1474
      DONE;
1475
    }
1476
  operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1477
})
1478
 
1479
(define_expand "bunlt"
1480
  [(set (pc)
1481
        (if_then_else (unlt (match_dup 1) (const_int 0))
1482
                      (label_ref (match_operand 0 "" ""))
1483
                      (pc)))]
1484
  ""
1485
{
1486
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1487
    {
1488
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1489
      emit_jump_insn (gen_bne (operands[0]));
1490
      DONE;
1491
    }
1492
  operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1493
})
1494
 
1495
(define_expand "buneq"
1496
  [(set (pc)
1497
        (if_then_else (uneq (match_dup 1) (const_int 0))
1498
                      (label_ref (match_operand 0 "" ""))
1499
                      (pc)))]
1500
  ""
1501
{
1502
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1503
    {
1504
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1505
      emit_jump_insn (gen_beq (operands[0]));
1506
      DONE;
1507
    }
1508
  operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1509
})
1510
 
1511
(define_expand "bunge"
1512
  [(set (pc)
1513
        (if_then_else (unge (match_dup 1) (const_int 0))
1514
                      (label_ref (match_operand 0 "" ""))
1515
                      (pc)))]
1516
  ""
1517
{
1518
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1519
    {
1520
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1521
      emit_jump_insn (gen_bne (operands[0]));
1522
      DONE;
1523
    }
1524
  operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1525
})
1526
 
1527
(define_expand "bunle"
1528
  [(set (pc)
1529
        (if_then_else (unle (match_dup 1) (const_int 0))
1530
                      (label_ref (match_operand 0 "" ""))
1531
                      (pc)))]
1532
  ""
1533
{
1534
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1535
    {
1536
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1537
      emit_jump_insn (gen_bne (operands[0]));
1538
      DONE;
1539
    }
1540
  operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1541
})
1542
 
1543
(define_expand "bltgt"
1544
  [(set (pc)
1545
        (if_then_else (ltgt (match_dup 1) (const_int 0))
1546
                      (label_ref (match_operand 0 "" ""))
1547
                      (pc)))]
1548
  ""
1549
{
1550
  if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1551
    {
1552
      sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1553
      emit_jump_insn (gen_bne (operands[0]));
1554
      DONE;
1555
    }
1556
  operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1557
})
1558
 
1559
;; Now match both normal and inverted jump.
1560
 
1561
;; XXX fpcmp nop braindamage
1562
(define_insn "*normal_branch"
1563
  [(set (pc)
1564
        (if_then_else (match_operator 0 "noov_compare_operator"
1565
                                      [(reg 100) (const_int 0)])
1566
                      (label_ref (match_operand 1 "" ""))
1567
                      (pc)))]
1568
  ""
1569
{
1570
  return output_cbranch (operands[0], operands[1], 1, 0,
1571
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1572
                         insn);
1573
}
1574
  [(set_attr "type" "branch")
1575
   (set_attr "branch_type" "icc")])
1576
 
1577
;; XXX fpcmp nop braindamage
1578
(define_insn "*inverted_branch"
1579
  [(set (pc)
1580
        (if_then_else (match_operator 0 "noov_compare_operator"
1581
                                      [(reg 100) (const_int 0)])
1582
                      (pc)
1583
                      (label_ref (match_operand 1 "" ""))))]
1584
  ""
1585
{
1586
  return output_cbranch (operands[0], operands[1], 1, 1,
1587
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1588
                         insn);
1589
}
1590
  [(set_attr "type" "branch")
1591
   (set_attr "branch_type" "icc")])
1592
 
1593
;; XXX fpcmp nop braindamage
1594
(define_insn "*normal_fp_branch"
1595
  [(set (pc)
1596
        (if_then_else (match_operator 1 "comparison_operator"
1597
                                      [(match_operand:CCFP 0 "fcc_register_operand" "c")
1598
                                       (const_int 0)])
1599
                      (label_ref (match_operand 2 "" ""))
1600
                      (pc)))]
1601
  ""
1602
{
1603
  return output_cbranch (operands[1], operands[2], 2, 0,
1604
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605
                         insn);
1606
}
1607
  [(set_attr "type" "branch")
1608
   (set_attr "branch_type" "fcc")])
1609
 
1610
;; XXX fpcmp nop braindamage
1611
(define_insn "*inverted_fp_branch"
1612
  [(set (pc)
1613
        (if_then_else (match_operator 1 "comparison_operator"
1614
                                      [(match_operand:CCFP 0 "fcc_register_operand" "c")
1615
                                       (const_int 0)])
1616
                      (pc)
1617
                      (label_ref (match_operand 2 "" ""))))]
1618
  ""
1619
{
1620
  return output_cbranch (operands[1], operands[2], 2, 1,
1621
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622
                         insn);
1623
}
1624
  [(set_attr "type" "branch")
1625
   (set_attr "branch_type" "fcc")])
1626
 
1627
;; XXX fpcmp nop braindamage
1628
(define_insn "*normal_fpe_branch"
1629
  [(set (pc)
1630
        (if_then_else (match_operator 1 "comparison_operator"
1631
                                      [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1632
                                       (const_int 0)])
1633
                      (label_ref (match_operand 2 "" ""))
1634
                      (pc)))]
1635
  ""
1636
{
1637
  return output_cbranch (operands[1], operands[2], 2, 0,
1638
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639
                         insn);
1640
}
1641
  [(set_attr "type" "branch")
1642
   (set_attr "branch_type" "fcc")])
1643
 
1644
;; XXX fpcmp nop braindamage
1645
(define_insn "*inverted_fpe_branch"
1646
  [(set (pc)
1647
        (if_then_else (match_operator 1 "comparison_operator"
1648
                                      [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1649
                                       (const_int 0)])
1650
                      (pc)
1651
                      (label_ref (match_operand 2 "" ""))))]
1652
  ""
1653
{
1654
  return output_cbranch (operands[1], operands[2], 2, 1,
1655
                         final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656
                         insn);
1657
}
1658
  [(set_attr "type" "branch")
1659
   (set_attr "branch_type" "fcc")])
1660
 
1661
;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1662
;; in the architecture.
1663
 
1664
;; There are no 32 bit brreg insns.
1665
 
1666
;; XXX
1667
(define_insn "*normal_int_branch_sp64"
1668
  [(set (pc)
1669
        (if_then_else (match_operator 0 "v9_register_compare_operator"
1670
                                      [(match_operand:DI 1 "register_operand" "r")
1671
                                       (const_int 0)])
1672
                      (label_ref (match_operand 2 "" ""))
1673
                      (pc)))]
1674
  "TARGET_ARCH64"
1675
{
1676
  return output_v9branch (operands[0], operands[2], 1, 2, 0,
1677
                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1678
                          insn);
1679
}
1680
  [(set_attr "type" "branch")
1681
   (set_attr "branch_type" "reg")])
1682
 
1683
;; XXX
1684
(define_insn "*inverted_int_branch_sp64"
1685
  [(set (pc)
1686
        (if_then_else (match_operator 0 "v9_register_compare_operator"
1687
                                      [(match_operand:DI 1 "register_operand" "r")
1688
                                       (const_int 0)])
1689
                      (pc)
1690
                      (label_ref (match_operand 2 "" ""))))]
1691
  "TARGET_ARCH64"
1692
{
1693
  return output_v9branch (operands[0], operands[2], 1, 2, 1,
1694
                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1695
                          insn);
1696
}
1697
  [(set_attr "type" "branch")
1698
   (set_attr "branch_type" "reg")])
1699
 
1700
 
1701
(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1702
 
1703
;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1704
;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1705
;; that adds the PC value at the call point to operand 0.
1706
 
1707
(define_insn "load_pcrel_sym"
1708
  [(set (match_operand:P 0 "register_operand" "=r")
1709
        (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1710
                   (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1711
   (clobber (reg:P 15))]
1712
  ""
1713
{
1714
  if (flag_delayed_branch)
1715
    return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1716
  else
1717
    return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1718
}
1719
  [(set (attr "type") (const_string "multi"))
1720
   (set (attr "length")
1721
        (if_then_else (eq_attr "delayed_branch" "true")
1722
                      (const_int 3)
1723
                      (const_int 4)))])
1724
 
1725
 
1726
;; Integer move instructions
1727
 
1728
(define_expand "movqi"
1729
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1730
        (match_operand:QI 1 "general_operand" ""))]
1731
  ""
1732
{
1733
  if (sparc_expand_move (QImode, operands))
1734
    DONE;
1735
})
1736
 
1737
(define_insn "*movqi_insn"
1738
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1739
        (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1740
  "(register_operand (operands[0], QImode)
1741
    || register_or_zero_operand (operands[1], QImode))"
1742
  "@
1743
   mov\t%1, %0
1744
   ldub\t%1, %0
1745
   stb\t%r1, %0"
1746
  [(set_attr "type" "*,load,store")
1747
   (set_attr "us3load_type" "*,3cycle,*")])
1748
 
1749
(define_expand "movhi"
1750
  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1751
        (match_operand:HI 1 "general_operand" ""))]
1752
  ""
1753
{
1754
  if (sparc_expand_move (HImode, operands))
1755
    DONE;
1756
})
1757
 
1758
(define_insn "*movhi_insn"
1759
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1760
        (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1761
  "(register_operand (operands[0], HImode)
1762
    || register_or_zero_operand (operands[1], HImode))"
1763
  "@
1764
   mov\t%1, %0
1765
   sethi\t%%hi(%a1), %0
1766
   lduh\t%1, %0
1767
   sth\t%r1, %0"
1768
  [(set_attr "type" "*,*,load,store")
1769
   (set_attr "us3load_type" "*,*,3cycle,*")])
1770
 
1771
;; We always work with constants here.
1772
(define_insn "*movhi_lo_sum"
1773
  [(set (match_operand:HI 0 "register_operand" "=r")
1774
        (ior:HI (match_operand:HI 1 "register_operand" "%r")
1775
                (match_operand:HI 2 "small_int_operand" "I")))]
1776
  ""
1777
  "or\t%1, %2, %0")
1778
 
1779
(define_expand "movsi"
1780
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1781
        (match_operand:SI 1 "general_operand" ""))]
1782
  ""
1783
{
1784
  if (sparc_expand_move (SImode, operands))
1785
    DONE;
1786
})
1787
 
1788
(define_insn "*movsi_insn"
1789
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1790
        (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1791
  "(register_operand (operands[0], SImode)
1792
    || register_or_zero_operand (operands[1], SImode))"
1793
  "@
1794
   mov\t%1, %0
1795
   sethi\t%%hi(%a1), %0
1796
   ld\t%1, %0
1797
   st\t%r1, %0
1798
   fmovs\t%1, %0
1799
   ld\t%1, %0
1800
   st\t%1, %0
1801
   fzeros\t%0"
1802
  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1803
 
1804
(define_insn "*movsi_lo_sum"
1805
  [(set (match_operand:SI 0 "register_operand" "=r")
1806
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1807
                   (match_operand:SI 2 "immediate_operand" "in")))]
1808
  ""
1809
  "or\t%1, %%lo(%a2), %0")
1810
 
1811
(define_insn "*movsi_high"
1812
  [(set (match_operand:SI 0 "register_operand" "=r")
1813
        (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1814
  ""
1815
  "sethi\t%%hi(%a1), %0")
1816
 
1817
;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1818
;; so that CSE won't optimize the address computation away.
1819
(define_insn "movsi_lo_sum_pic"
1820
  [(set (match_operand:SI 0 "register_operand" "=r")
1821
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1822
                   (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1823
  "flag_pic"
1824
  "or\t%1, %%lo(%a2), %0")
1825
 
1826
(define_insn "movsi_high_pic"
1827
  [(set (match_operand:SI 0 "register_operand" "=r")
1828
        (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1829
  "flag_pic && check_pic (1)"
1830
  "sethi\t%%hi(%a1), %0")
1831
 
1832
(define_expand "movsi_pic_label_ref"
1833
  [(set (match_dup 3) (high:SI
1834
     (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1835
                 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1836
   (set (match_dup 4) (lo_sum:SI (match_dup 3)
1837
     (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1838
   (set (match_operand:SI 0 "register_operand" "=r")
1839
        (minus:SI (match_dup 5) (match_dup 4)))]
1840
  "flag_pic"
1841
{
1842
  current_function_uses_pic_offset_table = 1;
1843
  operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1844
  if (no_new_pseudos)
1845
    {
1846
      operands[3] = operands[0];
1847
      operands[4] = operands[0];
1848
    }
1849
  else
1850
    {
1851
      operands[3] = gen_reg_rtx (SImode);
1852
      operands[4] = gen_reg_rtx (SImode);
1853
    }
1854
  operands[5] = pic_offset_table_rtx;
1855
})
1856
 
1857
(define_insn "*movsi_high_pic_label_ref"
1858
  [(set (match_operand:SI 0 "register_operand" "=r")
1859
      (high:SI
1860
        (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1861
                    (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1862
  "flag_pic"
1863
  "sethi\t%%hi(%a2-(%a1-.)), %0")
1864
 
1865
(define_insn "*movsi_lo_sum_pic_label_ref"
1866
  [(set (match_operand:SI 0 "register_operand" "=r")
1867
      (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1868
        (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1869
                    (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1870
  "flag_pic"
1871
  "or\t%1, %%lo(%a3-(%a2-.)), %0")
1872
 
1873
(define_expand "movdi"
1874
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1875
        (match_operand:DI 1 "general_operand" ""))]
1876
  ""
1877
{
1878
  if (sparc_expand_move (DImode, operands))
1879
    DONE;
1880
})
1881
 
1882
;; Be careful, fmovd does not exist when !v9.
1883
;; We match MEM moves directly when we have correct even
1884
;; numbered registers, but fall into splits otherwise.
1885
;; The constraint ordering here is really important to
1886
;; avoid insane problems in reload, especially for patterns
1887
;; of the form:
1888
;;
1889
;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1890
;;                       (const_int -5016)))
1891
;;      (reg:DI 2 %g2))
1892
;;
1893
 
1894
(define_insn "*movdi_insn_sp32"
1895
  [(set (match_operand:DI 0 "nonimmediate_operand"
1896
                                "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1897
        (match_operand:DI 1 "input_operand"
1898
                                " J,U,T,r,o,i,r, f, T, o, f, f"))]
1899
  "! TARGET_V9
1900
   && (register_operand (operands[0], DImode)
1901
       || register_or_zero_operand (operands[1], DImode))"
1902
  "@
1903
   #
1904
   std\t%1, %0
1905
   ldd\t%1, %0
1906
   #
1907
   #
1908
   #
1909
   #
1910
   std\t%1, %0
1911
   ldd\t%1, %0
1912
   #
1913
   #
1914
   #"
1915
  [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1916
   (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1917
 
1918
(define_insn "*movdi_insn_sp32_v9"
1919
  [(set (match_operand:DI 0 "nonimmediate_operand"
1920
                                        "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1921
        (match_operand:DI 1 "input_operand"
1922
                                        " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1923
  "! TARGET_ARCH64
1924
   && TARGET_V9
1925
   && (register_operand (operands[0], DImode)
1926
       || register_or_zero_operand (operands[1], DImode))"
1927
  "@
1928
   stx\t%%g0, %0
1929
   #
1930
   std\t%1, %0
1931
   ldd\t%1, %0
1932
   #
1933
   #
1934
   #
1935
   #
1936
   std\t%1, %0
1937
   ldd\t%1, %0
1938
   #
1939
   #
1940
   fmovd\\t%1, %0
1941
   ldd\\t%1, %0
1942
   std\\t%1, %0"
1943
  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1944
   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1945
   (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1946
 
1947
(define_insn "*movdi_insn_sp64"
1948
  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1949
        (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1950
  "TARGET_ARCH64
1951
   && (register_operand (operands[0], DImode)
1952
       || register_or_zero_operand (operands[1], DImode))"
1953
  "@
1954
   mov\t%1, %0
1955
   sethi\t%%hi(%a1), %0
1956
   ldx\t%1, %0
1957
   stx\t%r1, %0
1958
   fmovd\t%1, %0
1959
   ldd\t%1, %0
1960
   std\t%1, %0
1961
   fzero\t%0"
1962
  [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1963
   (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1964
 
1965
(define_expand "movdi_pic_label_ref"
1966
  [(set (match_dup 3) (high:DI
1967
     (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1968
                 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1969
   (set (match_dup 4) (lo_sum:DI (match_dup 3)
1970
     (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1971
   (set (match_operand:DI 0 "register_operand" "=r")
1972
        (minus:DI (match_dup 5) (match_dup 4)))]
1973
  "TARGET_ARCH64 && flag_pic"
1974
{
1975
  current_function_uses_pic_offset_table = 1;
1976
  operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1977
  if (no_new_pseudos)
1978
    {
1979
      operands[3] = operands[0];
1980
      operands[4] = operands[0];
1981
    }
1982
  else
1983
    {
1984
      operands[3] = gen_reg_rtx (DImode);
1985
      operands[4] = gen_reg_rtx (DImode);
1986
    }
1987
  operands[5] = pic_offset_table_rtx;
1988
})
1989
 
1990
(define_insn "*movdi_high_pic_label_ref"
1991
  [(set (match_operand:DI 0 "register_operand" "=r")
1992
        (high:DI
1993
          (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1994
                      (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1995
  "TARGET_ARCH64 && flag_pic"
1996
  "sethi\t%%hi(%a2-(%a1-.)), %0")
1997
 
1998
(define_insn "*movdi_lo_sum_pic_label_ref"
1999
  [(set (match_operand:DI 0 "register_operand" "=r")
2000
      (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2001
        (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2002
                    (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2003
  "TARGET_ARCH64 && flag_pic"
2004
  "or\t%1, %%lo(%a3-(%a2-.)), %0")
2005
 
2006
;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2007
;; in sparc.c to see what is going on here... PIC stuff comes first.
2008
 
2009
(define_insn "movdi_lo_sum_pic"
2010
  [(set (match_operand:DI 0 "register_operand" "=r")
2011
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2012
                   (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2013
  "TARGET_ARCH64 && flag_pic"
2014
  "or\t%1, %%lo(%a2), %0")
2015
 
2016
(define_insn "movdi_high_pic"
2017
  [(set (match_operand:DI 0 "register_operand" "=r")
2018
        (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2019
  "TARGET_ARCH64 && flag_pic && check_pic (1)"
2020
  "sethi\t%%hi(%a1), %0")
2021
 
2022
(define_insn "*sethi_di_medlow_embmedany_pic"
2023
  [(set (match_operand:DI 0 "register_operand" "=r")
2024
        (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2025
  "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2026
  "sethi\t%%hi(%a1), %0")
2027
 
2028
(define_insn "*sethi_di_medlow"
2029
  [(set (match_operand:DI 0 "register_operand" "=r")
2030
        (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2031
  "TARGET_CM_MEDLOW && check_pic (1)"
2032
  "sethi\t%%hi(%a1), %0")
2033
 
2034
(define_insn "*losum_di_medlow"
2035
  [(set (match_operand:DI 0 "register_operand" "=r")
2036
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2037
                   (match_operand:DI 2 "symbolic_operand" "")))]
2038
  "TARGET_CM_MEDLOW"
2039
  "or\t%1, %%lo(%a2), %0")
2040
 
2041
(define_insn "seth44"
2042
  [(set (match_operand:DI 0 "register_operand" "=r")
2043
        (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2044
  "TARGET_CM_MEDMID"
2045
  "sethi\t%%h44(%a1), %0")
2046
 
2047
(define_insn "setm44"
2048
  [(set (match_operand:DI 0 "register_operand" "=r")
2049
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2050
                   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2051
  "TARGET_CM_MEDMID"
2052
  "or\t%1, %%m44(%a2), %0")
2053
 
2054
(define_insn "setl44"
2055
  [(set (match_operand:DI 0 "register_operand" "=r")
2056
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2057
                   (match_operand:DI 2 "symbolic_operand" "")))]
2058
  "TARGET_CM_MEDMID"
2059
  "or\t%1, %%l44(%a2), %0")
2060
 
2061
(define_insn "sethh"
2062
  [(set (match_operand:DI 0 "register_operand" "=r")
2063
        (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2064
  "TARGET_CM_MEDANY"
2065
  "sethi\t%%hh(%a1), %0")
2066
 
2067
(define_insn "setlm"
2068
  [(set (match_operand:DI 0 "register_operand" "=r")
2069
        (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2070
  "TARGET_CM_MEDANY"
2071
  "sethi\t%%lm(%a1), %0")
2072
 
2073
(define_insn "sethm"
2074
  [(set (match_operand:DI 0 "register_operand" "=r")
2075
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2076
                   (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2077
  "TARGET_CM_MEDANY"
2078
  "or\t%1, %%hm(%a2), %0")
2079
 
2080
(define_insn "setlo"
2081
  [(set (match_operand:DI 0 "register_operand" "=r")
2082
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2083
                   (match_operand:DI 2 "symbolic_operand" "")))]
2084
  "TARGET_CM_MEDANY"
2085
  "or\t%1, %%lo(%a2), %0")
2086
 
2087
(define_insn "embmedany_sethi"
2088
  [(set (match_operand:DI 0 "register_operand" "=r")
2089
        (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2090
  "TARGET_CM_EMBMEDANY && check_pic (1)"
2091
  "sethi\t%%hi(%a1), %0")
2092
 
2093
(define_insn "embmedany_losum"
2094
  [(set (match_operand:DI 0 "register_operand" "=r")
2095
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2096
                   (match_operand:DI 2 "data_segment_operand" "")))]
2097
  "TARGET_CM_EMBMEDANY"
2098
  "add\t%1, %%lo(%a2), %0")
2099
 
2100
(define_insn "embmedany_brsum"
2101
  [(set (match_operand:DI 0 "register_operand" "=r")
2102
        (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2103
  "TARGET_CM_EMBMEDANY"
2104
  "add\t%1, %_, %0")
2105
 
2106
(define_insn "embmedany_textuhi"
2107
  [(set (match_operand:DI 0 "register_operand" "=r")
2108
        (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2109
  "TARGET_CM_EMBMEDANY && check_pic (1)"
2110
  "sethi\t%%uhi(%a1), %0")
2111
 
2112
(define_insn "embmedany_texthi"
2113
  [(set (match_operand:DI 0 "register_operand" "=r")
2114
        (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2115
  "TARGET_CM_EMBMEDANY && check_pic (1)"
2116
  "sethi\t%%hi(%a1), %0")
2117
 
2118
(define_insn "embmedany_textulo"
2119
  [(set (match_operand:DI 0 "register_operand" "=r")
2120
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2121
                   (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2122
  "TARGET_CM_EMBMEDANY"
2123
  "or\t%1, %%ulo(%a2), %0")
2124
 
2125
(define_insn "embmedany_textlo"
2126
  [(set (match_operand:DI 0 "register_operand" "=r")
2127
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2128
                   (match_operand:DI 2 "text_segment_operand" "")))]
2129
  "TARGET_CM_EMBMEDANY"
2130
  "or\t%1, %%lo(%a2), %0")
2131
 
2132
;; Now some patterns to help reload out a bit.
2133
(define_expand "reload_indi"
2134
  [(parallel [(match_operand:DI 0 "register_operand" "=r")
2135
              (match_operand:DI 1 "immediate_operand" "")
2136
              (match_operand:TI 2 "register_operand" "=&r")])]
2137
  "(TARGET_CM_MEDANY
2138
    || TARGET_CM_EMBMEDANY)
2139
   && ! flag_pic"
2140
{
2141
  sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2142
  DONE;
2143
})
2144
 
2145
(define_expand "reload_outdi"
2146
  [(parallel [(match_operand:DI 0 "register_operand" "=r")
2147
              (match_operand:DI 1 "immediate_operand" "")
2148
              (match_operand:TI 2 "register_operand" "=&r")])]
2149
  "(TARGET_CM_MEDANY
2150
    || TARGET_CM_EMBMEDANY)
2151
   && ! flag_pic"
2152
{
2153
  sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2154
  DONE;
2155
})
2156
 
2157
;; Split up putting CONSTs and REGs into DI regs when !arch64
2158
(define_split
2159
  [(set (match_operand:DI 0 "register_operand" "")
2160
        (match_operand:DI 1 "const_int_operand" ""))]
2161
  "! TARGET_ARCH64 && reload_completed"
2162
  [(clobber (const_int 0))]
2163
{
2164
#if HOST_BITS_PER_WIDE_INT == 32
2165
  emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2166
                        (INTVAL (operands[1]) < 0) ?
2167
                        constm1_rtx :
2168
                        const0_rtx));
2169
  emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2170
                        operands[1]));
2171
#else
2172
  unsigned int low, high;
2173
 
2174
  low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2175
  high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2176
  emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2177
 
2178
  /* Slick... but this trick loses if this subreg constant part
2179
     can be done in one insn.  */
2180
  if (low == high
2181
      && ! SPARC_SETHI32_P (high)
2182
      && ! SPARC_SIMM13_P (high))
2183
    emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2184
                          gen_highpart (SImode, operands[0])));
2185
  else
2186
    emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2187
#endif
2188
  DONE;
2189
})
2190
 
2191
(define_split
2192
  [(set (match_operand:DI 0 "register_operand" "")
2193
        (match_operand:DI 1 "const_double_operand" ""))]
2194
  "reload_completed
2195
   && (! TARGET_V9
2196
       || (! TARGET_ARCH64
2197
           && ((GET_CODE (operands[0]) == REG
2198
                && REGNO (operands[0]) < 32)
2199
               || (GET_CODE (operands[0]) == SUBREG
2200
                   && GET_CODE (SUBREG_REG (operands[0])) == REG
2201
                   && REGNO (SUBREG_REG (operands[0])) < 32))))"
2202
  [(clobber (const_int 0))]
2203
{
2204
  emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2205
                        GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2206
 
2207
  /* Slick... but this trick loses if this subreg constant part
2208
     can be done in one insn.  */
2209
  if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2210
      && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2211
      && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2212
    {
2213
      emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2214
                            gen_highpart (SImode, operands[0])));
2215
    }
2216
  else
2217
    {
2218
      emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2219
                            GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2220
    }
2221
  DONE;
2222
})
2223
 
2224
(define_split
2225
  [(set (match_operand:DI 0 "register_operand" "")
2226
        (match_operand:DI 1 "register_operand" ""))]
2227
  "reload_completed
2228
   && (! TARGET_V9
2229
       || (! TARGET_ARCH64
2230
           && ((GET_CODE (operands[0]) == REG
2231
                && REGNO (operands[0]) < 32)
2232
               || (GET_CODE (operands[0]) == SUBREG
2233
                   && GET_CODE (SUBREG_REG (operands[0])) == REG
2234
                   && REGNO (SUBREG_REG (operands[0])) < 32))))"
2235
  [(clobber (const_int 0))]
2236
{
2237
  rtx set_dest = operands[0];
2238
  rtx set_src = operands[1];
2239
  rtx dest1, dest2;
2240
  rtx src1, src2;
2241
 
2242
  dest1 = gen_highpart (SImode, set_dest);
2243
  dest2 = gen_lowpart (SImode, set_dest);
2244
  src1 = gen_highpart (SImode, set_src);
2245
  src2 = gen_lowpart (SImode, set_src);
2246
 
2247
  /* Now emit using the real source and destination we found, swapping
2248
     the order if we detect overlap.  */
2249
  if (reg_overlap_mentioned_p (dest1, src2))
2250
    {
2251
      emit_insn (gen_movsi (dest2, src2));
2252
      emit_insn (gen_movsi (dest1, src1));
2253
    }
2254
  else
2255
    {
2256
      emit_insn (gen_movsi (dest1, src1));
2257
      emit_insn (gen_movsi (dest2, src2));
2258
    }
2259
  DONE;
2260
})
2261
 
2262
;; Now handle the cases of memory moves from/to non-even
2263
;; DI mode register pairs.
2264
(define_split
2265
  [(set (match_operand:DI 0 "register_operand" "")
2266
        (match_operand:DI 1 "memory_operand" ""))]
2267
  "(! TARGET_ARCH64
2268
    && reload_completed
2269
    && sparc_splitdi_legitimate (operands[0], operands[1]))"
2270
  [(clobber (const_int 0))]
2271
{
2272
  rtx word0 = adjust_address (operands[1], SImode, 0);
2273
  rtx word1 = adjust_address (operands[1], SImode, 4);
2274
  rtx high_part = gen_highpart (SImode, operands[0]);
2275
  rtx low_part = gen_lowpart (SImode, operands[0]);
2276
 
2277
  if (reg_overlap_mentioned_p (high_part, word1))
2278
    {
2279
      emit_insn (gen_movsi (low_part, word1));
2280
      emit_insn (gen_movsi (high_part, word0));
2281
    }
2282
  else
2283
    {
2284
      emit_insn (gen_movsi (high_part, word0));
2285
      emit_insn (gen_movsi (low_part, word1));
2286
    }
2287
  DONE;
2288
})
2289
 
2290
(define_split
2291
  [(set (match_operand:DI 0 "memory_operand" "")
2292
        (match_operand:DI 1 "register_operand" ""))]
2293
  "(! TARGET_ARCH64
2294
    && reload_completed
2295
    && sparc_splitdi_legitimate (operands[1], operands[0]))"
2296
  [(clobber (const_int 0))]
2297
{
2298
  emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2299
                        gen_highpart (SImode, operands[1])));
2300
  emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2301
                        gen_lowpart (SImode, operands[1])));
2302
  DONE;
2303
})
2304
 
2305
(define_split
2306
  [(set (match_operand:DI 0 "memory_operand" "")
2307
        (match_operand:DI 1 "const_zero_operand" ""))]
2308
  "reload_completed
2309
   && (! TARGET_V9
2310
       || (! TARGET_ARCH64
2311
           && ! mem_min_alignment (operands[0], 8)))
2312
   && offsettable_memref_p (operands[0])"
2313
  [(clobber (const_int 0))]
2314
{
2315
  emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2316
  emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2317
  DONE;
2318
})
2319
 
2320
 
2321
;; Floating point and vector move instructions
2322
 
2323
;; We don't define V1SI because SI should work just fine.
2324
(define_mode_macro V32 [SF V2HI V4QI])
2325
 
2326
;; Yes, you guessed it right, the former movsf expander.
2327
(define_expand "mov"
2328
  [(set (match_operand:V32 0 "nonimmediate_operand" "")
2329
        (match_operand:V32 1 "general_operand" ""))]
2330
  "mode == SFmode || TARGET_VIS"
2331
{
2332
  if (sparc_expand_move (mode, operands))
2333
    DONE;
2334
})
2335
 
2336
(define_insn "*movsf_insn"
2337
  [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2338
        (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2339
  "TARGET_FPU
2340
   && (register_operand (operands[0], mode)
2341
       || register_or_zero_operand (operands[1], mode))"
2342
{
2343
  if (GET_CODE (operands[1]) == CONST_DOUBLE
2344
      && (which_alternative == 2
2345
          || which_alternative == 3
2346
          || which_alternative == 4))
2347
    {
2348
      REAL_VALUE_TYPE r;
2349
      long i;
2350
 
2351
      REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2352
      REAL_VALUE_TO_TARGET_SINGLE (r, i);
2353
      operands[1] = GEN_INT (i);
2354
    }
2355
 
2356
  switch (which_alternative)
2357
    {
2358
    case 0:
2359
      return "fzeros\t%0";
2360
    case 1:
2361
      return "fmovs\t%1, %0";
2362
    case 2:
2363
      return "mov\t%1, %0";
2364
    case 3:
2365
      return "sethi\t%%hi(%a1), %0";
2366
    case 4:
2367
      return "#";
2368
    case 5:
2369
    case 6:
2370
      return "ld\t%1, %0";
2371
    case 7:
2372
    case 8:
2373
      return "st\t%r1, %0";
2374
    default:
2375
      gcc_unreachable ();
2376
    }
2377
}
2378
  [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2379
 
2380
;; Exactly the same as above, except that all `f' cases are deleted.
2381
;; This is necessary to prevent reload from ever trying to use a `f' reg
2382
;; when -mno-fpu.
2383
 
2384
(define_insn "*movsf_insn_no_fpu"
2385
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2386
        (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2387
  "! TARGET_FPU
2388
   && (register_operand (operands[0], SFmode)
2389
       || register_or_zero_operand (operands[1], SFmode))"
2390
{
2391
  if (GET_CODE (operands[1]) == CONST_DOUBLE
2392
      && (which_alternative == 0
2393
          || which_alternative == 1
2394
          || which_alternative == 2))
2395
    {
2396
      REAL_VALUE_TYPE r;
2397
      long i;
2398
 
2399
      REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2400
      REAL_VALUE_TO_TARGET_SINGLE (r, i);
2401
      operands[1] = GEN_INT (i);
2402
    }
2403
 
2404
  switch (which_alternative)
2405
    {
2406
    case 0:
2407
      return "mov\t%1, %0";
2408
    case 1:
2409
      return "sethi\t%%hi(%a1), %0";
2410
    case 2:
2411
      return "#";
2412
    case 3:
2413
      return "ld\t%1, %0";
2414
    case 4:
2415
      return "st\t%r1, %0";
2416
    default:
2417
      gcc_unreachable ();
2418
    }
2419
}
2420
  [(set_attr "type" "*,*,*,load,store")])
2421
 
2422
;; The following 3 patterns build SFmode constants in integer registers.
2423
 
2424
(define_insn "*movsf_lo_sum"
2425
  [(set (match_operand:SF 0 "register_operand" "=r")
2426
        (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2427
                   (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2428
  ""
2429
{
2430
  REAL_VALUE_TYPE r;
2431
  long i;
2432
 
2433
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2434
  REAL_VALUE_TO_TARGET_SINGLE (r, i);
2435
  operands[2] = GEN_INT (i);
2436
  return "or\t%1, %%lo(%a2), %0";
2437
})
2438
 
2439
(define_insn "*movsf_high"
2440
  [(set (match_operand:SF 0 "register_operand" "=r")
2441
        (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2442
  ""
2443
{
2444
  REAL_VALUE_TYPE r;
2445
  long i;
2446
 
2447
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2448
  REAL_VALUE_TO_TARGET_SINGLE (r, i);
2449
  operands[1] = GEN_INT (i);
2450
  return "sethi\t%%hi(%1), %0";
2451
})
2452
 
2453
(define_split
2454
  [(set (match_operand:SF 0 "register_operand" "")
2455
        (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2456
  "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2457
  [(set (match_dup 0) (high:SF (match_dup 1)))
2458
   (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2459
 
2460
(define_mode_macro V64 [DF V2SI V4HI V8QI])
2461
 
2462
;; Yes, you again guessed it right, the former movdf expander.
2463
(define_expand "mov"
2464
  [(set (match_operand:V64 0 "nonimmediate_operand" "")
2465
        (match_operand:V64 1 "general_operand" ""))]
2466
  "mode == DFmode || TARGET_VIS"
2467
{
2468
  if (sparc_expand_move (mode, operands))
2469
    DONE;
2470
})
2471
 
2472
;; Be careful, fmovd does not exist when !v9.
2473
(define_insn "*movdf_insn_sp32"
2474
  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2475
        (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2476
  "TARGET_FPU
2477
   && ! TARGET_V9
2478
   && (register_operand (operands[0], DFmode)
2479
       || register_or_zero_operand (operands[1], DFmode))"
2480
  "@
2481
  ldd\t%1, %0
2482
  std\t%1, %0
2483
  ldd\t%1, %0
2484
  std\t%1, %0
2485
  #
2486
  #
2487
  #
2488
  #
2489
  #
2490
  #"
2491
 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2492
  (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2493
 
2494
(define_insn "*movdf_insn_sp32_no_fpu"
2495
  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2496
        (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2497
  "! TARGET_FPU
2498
   && ! TARGET_V9
2499
   && (register_operand (operands[0], DFmode)
2500
       || register_or_zero_operand (operands[1], DFmode))"
2501
  "@
2502
  ldd\t%1, %0
2503
  std\t%1, %0
2504
  #
2505
  #
2506
  #"
2507
  [(set_attr "type" "load,store,*,*,*")
2508
   (set_attr "length" "*,*,2,2,2")])
2509
 
2510
;; We have available v9 double floats but not 64-bit integer registers.
2511
(define_insn "*movdf_insn_sp32_v9"
2512
  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2513
        (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2514
  "TARGET_FPU
2515
   && TARGET_V9
2516
   && ! TARGET_ARCH64
2517
   && (register_operand (operands[0], mode)
2518
       || register_or_zero_operand (operands[1], mode))"
2519
  "@
2520
  fzero\t%0
2521
  fmovd\t%1, %0
2522
  ldd\t%1, %0
2523
  stx\t%r1, %0
2524
  std\t%1, %0
2525
  ldd\t%1, %0
2526
  std\t%1, %0
2527
  #
2528
  #
2529
  #"
2530
  [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2531
   (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2532
   (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2533
 
2534
(define_insn "*movdf_insn_sp32_v9_no_fpu"
2535
  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2536
        (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2537
  "! TARGET_FPU
2538
   && TARGET_V9
2539
   && ! TARGET_ARCH64
2540
   && (register_operand (operands[0], DFmode)
2541
       || register_or_zero_operand (operands[1], DFmode))"
2542
  "@
2543
  ldd\t%1, %0
2544
  std\t%1, %0
2545
  stx\t%r1, %0
2546
  #
2547
  #"
2548
  [(set_attr "type" "load,store,store,*,*")
2549
   (set_attr "length" "*,*,*,2,2")])
2550
 
2551
;; We have available both v9 double floats and 64-bit integer registers.
2552
(define_insn "*movdf_insn_sp64"
2553
  [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2554
        (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2555
  "TARGET_FPU
2556
   && TARGET_ARCH64
2557
   && (register_operand (operands[0], mode)
2558
       || register_or_zero_operand (operands[1], mode))"
2559
  "@
2560
  fzero\t%0
2561
  fmovd\t%1, %0
2562
  ldd\t%1, %0
2563
  std\t%1, %0
2564
  mov\t%r1, %0
2565
  ldx\t%1, %0
2566
  stx\t%r1, %0
2567
  #"
2568
  [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2569
   (set_attr "length" "*,*,*,*,*,*,*,2")
2570
   (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2571
 
2572
(define_insn "*movdf_insn_sp64_no_fpu"
2573
  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2574
        (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2575
  "! TARGET_FPU
2576
   && TARGET_ARCH64
2577
   && (register_operand (operands[0], DFmode)
2578
       || register_or_zero_operand (operands[1], DFmode))"
2579
  "@
2580
  mov\t%1, %0
2581
  ldx\t%1, %0
2582
  stx\t%r1, %0"
2583
  [(set_attr "type" "*,load,store")])
2584
 
2585
;; This pattern build DFmode constants in integer registers.
2586
(define_split
2587
  [(set (match_operand:DF 0 "register_operand" "")
2588
        (match_operand:DF 1 "const_double_operand" ""))]
2589
  "TARGET_FPU
2590
   && (GET_CODE (operands[0]) == REG
2591
       && REGNO (operands[0]) < 32)
2592
   && ! const_zero_operand(operands[1], DFmode)
2593
   && reload_completed"
2594
  [(clobber (const_int 0))]
2595
{
2596
  REAL_VALUE_TYPE r;
2597
  long l[2];
2598
 
2599
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2600
  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2601
  operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2602
 
2603
  if (TARGET_ARCH64)
2604
    {
2605
#if HOST_BITS_PER_WIDE_INT == 32
2606
      gcc_unreachable ();
2607
#else
2608
      HOST_WIDE_INT val;
2609
 
2610
      val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2611
             ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2612
      emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2613
#endif
2614
    }
2615
  else
2616
    {
2617
      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2618
                            gen_int_mode (l[0], SImode)));
2619
 
2620
      /* Slick... but this trick loses if this subreg constant part
2621
         can be done in one insn.  */
2622
      if (l[1] == l[0]
2623
          && ! SPARC_SETHI32_P (l[0])
2624
          && ! SPARC_SIMM13_P (l[0]))
2625
        {
2626
          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2627
                                gen_highpart (SImode, operands[0])));
2628
        }
2629
      else
2630
        {
2631
          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2632
                                gen_int_mode (l[1], SImode)));
2633
        }
2634
    }
2635
  DONE;
2636
})
2637
 
2638
;; Ok, now the splits to handle all the multi insn and
2639
;; mis-aligned memory address cases.
2640
;; In these splits please take note that we must be
2641
;; careful when V9 but not ARCH64 because the integer
2642
;; register DFmode cases must be handled.
2643
(define_split
2644
  [(set (match_operand:V64 0 "register_operand" "")
2645
        (match_operand:V64 1 "register_operand" ""))]
2646
  "(! TARGET_V9
2647
    || (! TARGET_ARCH64
2648
        && ((GET_CODE (operands[0]) == REG
2649
             && REGNO (operands[0]) < 32)
2650
            || (GET_CODE (operands[0]) == SUBREG
2651
                && GET_CODE (SUBREG_REG (operands[0])) == REG
2652
                && REGNO (SUBREG_REG (operands[0])) < 32))))
2653
   && reload_completed"
2654
  [(clobber (const_int 0))]
2655
{
2656
  rtx set_dest = operands[0];
2657
  rtx set_src = operands[1];
2658
  rtx dest1, dest2;
2659
  rtx src1, src2;
2660
  enum machine_mode half_mode;
2661
 
2662
  /* We can be expanded for DFmode or integral vector modes.  */
2663
  if (mode == DFmode)
2664
    half_mode = SFmode;
2665
  else
2666
    half_mode = SImode;
2667
 
2668
  dest1 = gen_highpart (half_mode, set_dest);
2669
  dest2 = gen_lowpart (half_mode, set_dest);
2670
  src1 = gen_highpart (half_mode, set_src);
2671
  src2 = gen_lowpart (half_mode, set_src);
2672
 
2673
  /* Now emit using the real source and destination we found, swapping
2674
     the order if we detect overlap.  */
2675
  if (reg_overlap_mentioned_p (dest1, src2))
2676
    {
2677
      emit_move_insn_1 (dest2, src2);
2678
      emit_move_insn_1 (dest1, src1);
2679
    }
2680
  else
2681
    {
2682
      emit_move_insn_1 (dest1, src1);
2683
      emit_move_insn_1 (dest2, src2);
2684
    }
2685
  DONE;
2686
})
2687
 
2688
(define_split
2689
  [(set (match_operand:V64 0 "register_operand" "")
2690
        (match_operand:V64 1 "memory_operand" ""))]
2691
  "reload_completed
2692
   && ! TARGET_ARCH64
2693
   && (((REGNO (operands[0]) % 2) != 0)
2694
       || ! mem_min_alignment (operands[1], 8))
2695
   && offsettable_memref_p (operands[1])"
2696
  [(clobber (const_int 0))]
2697
{
2698
  enum machine_mode half_mode;
2699
  rtx word0, word1;
2700
 
2701
  /* We can be expanded for DFmode or integral vector modes.  */
2702
  if (mode == DFmode)
2703
    half_mode = SFmode;
2704
  else
2705
    half_mode = SImode;
2706
 
2707
  word0 = adjust_address (operands[1], half_mode, 0);
2708
  word1 = adjust_address (operands[1], half_mode, 4);
2709
 
2710
  if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2711
    {
2712
      emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2713
      emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2714
    }
2715
  else
2716
    {
2717
      emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2718
      emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2719
    }
2720
  DONE;
2721
})
2722
 
2723
(define_split
2724
  [(set (match_operand:V64 0 "memory_operand" "")
2725
        (match_operand:V64 1 "register_operand" ""))]
2726
  "reload_completed
2727
   && ! TARGET_ARCH64
2728
   && (((REGNO (operands[1]) % 2) != 0)
2729
       || ! mem_min_alignment (operands[0], 8))
2730
   && offsettable_memref_p (operands[0])"
2731
  [(clobber (const_int 0))]
2732
{
2733
  enum machine_mode half_mode;
2734
  rtx word0, word1;
2735
 
2736
  /* We can be expanded for DFmode or integral vector modes.  */
2737
  if (mode == DFmode)
2738
    half_mode = SFmode;
2739
  else
2740
    half_mode = SImode;
2741
 
2742
  word0 = adjust_address (operands[0], half_mode, 0);
2743
  word1 = adjust_address (operands[0], half_mode, 4);
2744
 
2745
  emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2746
  emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2747
  DONE;
2748
})
2749
 
2750
(define_split
2751
  [(set (match_operand:V64 0 "memory_operand" "")
2752
        (match_operand:V64 1 "const_zero_operand" ""))]
2753
  "reload_completed
2754
   && (! TARGET_V9
2755
       || (! TARGET_ARCH64
2756
           && ! mem_min_alignment (operands[0], 8)))
2757
   && offsettable_memref_p (operands[0])"
2758
  [(clobber (const_int 0))]
2759
{
2760
  enum machine_mode half_mode;
2761
  rtx dest1, dest2;
2762
 
2763
  /* We can be expanded for DFmode or integral vector modes.  */
2764
  if (mode == DFmode)
2765
    half_mode = SFmode;
2766
  else
2767
    half_mode = SImode;
2768
 
2769
  dest1 = adjust_address (operands[0], half_mode, 0);
2770
  dest2 = adjust_address (operands[0], half_mode, 4);
2771
 
2772
  emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2773
  emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2774
  DONE;
2775
})
2776
 
2777
(define_split
2778
  [(set (match_operand:V64 0 "register_operand" "")
2779
        (match_operand:V64 1 "const_zero_operand" ""))]
2780
  "reload_completed
2781
   && ! TARGET_ARCH64
2782
   && ((GET_CODE (operands[0]) == REG
2783
        && REGNO (operands[0]) < 32)
2784
       || (GET_CODE (operands[0]) == SUBREG
2785
           && GET_CODE (SUBREG_REG (operands[0])) == REG
2786
           && REGNO (SUBREG_REG (operands[0])) < 32))"
2787
  [(clobber (const_int 0))]
2788
{
2789
  enum machine_mode half_mode;
2790
  rtx set_dest = operands[0];
2791
  rtx dest1, dest2;
2792
 
2793
  /* We can be expanded for DFmode or integral vector modes.  */
2794
  if (mode == DFmode)
2795
    half_mode = SFmode;
2796
  else
2797
    half_mode = SImode;
2798
 
2799
  dest1 = gen_highpart (half_mode, set_dest);
2800
  dest2 = gen_lowpart (half_mode, set_dest);
2801
  emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2802
  emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2803
  DONE;
2804
})
2805
 
2806
(define_expand "movtf"
2807
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2808
        (match_operand:TF 1 "general_operand" ""))]
2809
  ""
2810
{
2811
  if (sparc_expand_move (TFmode, operands))
2812
    DONE;
2813
})
2814
 
2815
(define_insn "*movtf_insn_sp32"
2816
  [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2817
        (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2818
  "TARGET_FPU
2819
   && ! TARGET_ARCH64
2820
   && (register_operand (operands[0], TFmode)
2821
       || register_or_zero_operand (operands[1], TFmode))"
2822
  "#"
2823
  [(set_attr "length" "4")])
2824
 
2825
;; Exactly the same as above, except that all `e' cases are deleted.
2826
;; This is necessary to prevent reload from ever trying to use a `e' reg
2827
;; when -mno-fpu.
2828
 
2829
(define_insn "*movtf_insn_sp32_no_fpu"
2830
  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2831
        (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2832
  "! TARGET_FPU
2833
   && ! TARGET_ARCH64
2834
   && (register_operand (operands[0], TFmode)
2835
       || register_or_zero_operand (operands[1], TFmode))"
2836
  "#"
2837
  [(set_attr "length" "4")])
2838
 
2839
(define_insn "*movtf_insn_sp64"
2840
  [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2841
        (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2842
  "TARGET_FPU
2843
   && TARGET_ARCH64
2844
   && ! TARGET_HARD_QUAD
2845
   && (register_operand (operands[0], TFmode)
2846
       || register_or_zero_operand (operands[1], TFmode))"
2847
  "#"
2848
  [(set_attr "length" "2")])
2849
 
2850
(define_insn "*movtf_insn_sp64_hq"
2851
  [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2852
        (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2853
  "TARGET_FPU
2854
   && TARGET_ARCH64
2855
   && TARGET_HARD_QUAD
2856
   && (register_operand (operands[0], TFmode)
2857
       || register_or_zero_operand (operands[1], TFmode))"
2858
  "@
2859
  #
2860
  fmovq\t%1, %0
2861
  ldq\t%1, %0
2862
  stq\t%1, %0
2863
  #
2864
  #"
2865
  [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2866
   (set_attr "length" "2,*,*,*,2,2")])
2867
 
2868
(define_insn "*movtf_insn_sp64_no_fpu"
2869
  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2870
        (match_operand:TF 1 "input_operand"    "orG,rG"))]
2871
  "! TARGET_FPU
2872
   && TARGET_ARCH64
2873
   && (register_operand (operands[0], TFmode)
2874
       || register_or_zero_operand (operands[1], TFmode))"
2875
  "#"
2876
  [(set_attr "length" "2")])
2877
 
2878
;; Now all the splits to handle multi-insn TF mode moves.
2879
(define_split
2880
  [(set (match_operand:TF 0 "register_operand" "")
2881
        (match_operand:TF 1 "register_operand" ""))]
2882
  "reload_completed
2883
   && (! TARGET_ARCH64
2884
       || (TARGET_FPU
2885
           && ! TARGET_HARD_QUAD)
2886
       || ! fp_register_operand (operands[0], TFmode))"
2887
  [(clobber (const_int 0))]
2888
{
2889
  rtx set_dest = operands[0];
2890
  rtx set_src = operands[1];
2891
  rtx dest1, dest2;
2892
  rtx src1, src2;
2893
 
2894
  dest1 = gen_df_reg (set_dest, 0);
2895
  dest2 = gen_df_reg (set_dest, 1);
2896
  src1 = gen_df_reg (set_src, 0);
2897
  src2 = gen_df_reg (set_src, 1);
2898
 
2899
  /* Now emit using the real source and destination we found, swapping
2900
     the order if we detect overlap.  */
2901
  if (reg_overlap_mentioned_p (dest1, src2))
2902
    {
2903
      emit_insn (gen_movdf (dest2, src2));
2904
      emit_insn (gen_movdf (dest1, src1));
2905
    }
2906
  else
2907
    {
2908
      emit_insn (gen_movdf (dest1, src1));
2909
      emit_insn (gen_movdf (dest2, src2));
2910
    }
2911
  DONE;
2912
})
2913
 
2914
(define_split
2915
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2916
        (match_operand:TF 1 "const_zero_operand" ""))]
2917
  "reload_completed"
2918
  [(clobber (const_int 0))]
2919
{
2920
  rtx set_dest = operands[0];
2921
  rtx dest1, dest2;
2922
 
2923
  switch (GET_CODE (set_dest))
2924
    {
2925
    case REG:
2926
      dest1 = gen_df_reg (set_dest, 0);
2927
      dest2 = gen_df_reg (set_dest, 1);
2928
      break;
2929
    case MEM:
2930
      dest1 = adjust_address (set_dest, DFmode, 0);
2931
      dest2 = adjust_address (set_dest, DFmode, 8);
2932
      break;
2933
    default:
2934
      gcc_unreachable ();
2935
    }
2936
 
2937
  emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2938
  emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2939
  DONE;
2940
})
2941
 
2942
(define_split
2943
  [(set (match_operand:TF 0 "register_operand" "")
2944
        (match_operand:TF 1 "memory_operand" ""))]
2945
  "(reload_completed
2946
    && offsettable_memref_p (operands[1])
2947
    && (! TARGET_ARCH64
2948
        || ! TARGET_HARD_QUAD
2949
        || ! fp_register_operand (operands[0], TFmode)))"
2950
  [(clobber (const_int 0))]
2951
{
2952
  rtx word0 = adjust_address (operands[1], DFmode, 0);
2953
  rtx word1 = adjust_address (operands[1], DFmode, 8);
2954
  rtx set_dest, dest1, dest2;
2955
 
2956
  set_dest = operands[0];
2957
 
2958
  dest1 = gen_df_reg (set_dest, 0);
2959
  dest2 = gen_df_reg (set_dest, 1);
2960
 
2961
  /* Now output, ordering such that we don't clobber any registers
2962
     mentioned in the address.  */
2963
  if (reg_overlap_mentioned_p (dest1, word1))
2964
 
2965
    {
2966
      emit_insn (gen_movdf (dest2, word1));
2967
      emit_insn (gen_movdf (dest1, word0));
2968
    }
2969
  else
2970
   {
2971
      emit_insn (gen_movdf (dest1, word0));
2972
      emit_insn (gen_movdf (dest2, word1));
2973
   }
2974
  DONE;
2975
})
2976
 
2977
(define_split
2978
  [(set (match_operand:TF 0 "memory_operand" "")
2979
        (match_operand:TF 1 "register_operand" ""))]
2980
  "(reload_completed
2981
    && offsettable_memref_p (operands[0])
2982
    && (! TARGET_ARCH64
2983
        || ! TARGET_HARD_QUAD
2984
        || ! fp_register_operand (operands[1], TFmode)))"
2985
  [(clobber (const_int 0))]
2986
{
2987
  rtx set_src = operands[1];
2988
 
2989
  emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2990
                        gen_df_reg (set_src, 0)));
2991
  emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2992
                        gen_df_reg (set_src, 1)));
2993
  DONE;
2994
})
2995
 
2996
 
2997
;; SPARC-V9 conditional move instructions.
2998
 
2999
;; We can handle larger constants here for some flavors, but for now we keep
3000
;; it simple and only allow those constants supported by all flavors.
3001
;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3002
;; 3 contains the constant if one is present, but we handle either for
3003
;; generality (sparc.c puts a constant in operand 2).
3004
 
3005
(define_expand "movqicc"
3006
  [(set (match_operand:QI 0 "register_operand" "")
3007
        (if_then_else:QI (match_operand 1 "comparison_operator" "")
3008
                         (match_operand:QI 2 "arith10_operand" "")
3009
                         (match_operand:QI 3 "arith10_operand" "")))]
3010
  "TARGET_V9"
3011
{
3012
  enum rtx_code code = GET_CODE (operands[1]);
3013
 
3014
  if (GET_MODE (sparc_compare_op0) == DImode
3015
      && ! TARGET_ARCH64)
3016
    FAIL;
3017
 
3018
  if (sparc_compare_op1 == const0_rtx
3019
      && GET_CODE (sparc_compare_op0) == REG
3020
      && GET_MODE (sparc_compare_op0) == DImode
3021
      && v9_regcmp_p (code))
3022
    {
3023
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3024
                             sparc_compare_op0, sparc_compare_op1);
3025
    }
3026
  else
3027
    {
3028
      rtx cc_reg = gen_compare_reg (code,
3029
                                    sparc_compare_op0, sparc_compare_op1);
3030
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3031
    }
3032
})
3033
 
3034
(define_expand "movhicc"
3035
  [(set (match_operand:HI 0 "register_operand" "")
3036
        (if_then_else:HI (match_operand 1 "comparison_operator" "")
3037
                         (match_operand:HI 2 "arith10_operand" "")
3038
                         (match_operand:HI 3 "arith10_operand" "")))]
3039
  "TARGET_V9"
3040
{
3041
  enum rtx_code code = GET_CODE (operands[1]);
3042
 
3043
  if (GET_MODE (sparc_compare_op0) == DImode
3044
      && ! TARGET_ARCH64)
3045
    FAIL;
3046
 
3047
  if (sparc_compare_op1 == const0_rtx
3048
      && GET_CODE (sparc_compare_op0) == REG
3049
      && GET_MODE (sparc_compare_op0) == DImode
3050
      && v9_regcmp_p (code))
3051
    {
3052
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3053
                             sparc_compare_op0, sparc_compare_op1);
3054
    }
3055
  else
3056
    {
3057
      rtx cc_reg = gen_compare_reg (code,
3058
                                    sparc_compare_op0, sparc_compare_op1);
3059
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3060
    }
3061
})
3062
 
3063
(define_expand "movsicc"
3064
  [(set (match_operand:SI 0 "register_operand" "")
3065
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
3066
                         (match_operand:SI 2 "arith10_operand" "")
3067
                         (match_operand:SI 3 "arith10_operand" "")))]
3068
  "TARGET_V9"
3069
{
3070
  enum rtx_code code = GET_CODE (operands[1]);
3071
  enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3072
 
3073
  if (sparc_compare_op1 == const0_rtx
3074
      && GET_CODE (sparc_compare_op0) == REG
3075
      && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3076
    {
3077
      operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3078
                             sparc_compare_op0, sparc_compare_op1);
3079
    }
3080
  else
3081
    {
3082
      rtx cc_reg = gen_compare_reg (code,
3083
                                    sparc_compare_op0, sparc_compare_op1);
3084
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3085
                                    cc_reg, const0_rtx);
3086
    }
3087
})
3088
 
3089
(define_expand "movdicc"
3090
  [(set (match_operand:DI 0 "register_operand" "")
3091
        (if_then_else:DI (match_operand 1 "comparison_operator" "")
3092
                         (match_operand:DI 2 "arith10_operand" "")
3093
                         (match_operand:DI 3 "arith10_operand" "")))]
3094
  "TARGET_ARCH64"
3095
{
3096
  enum rtx_code code = GET_CODE (operands[1]);
3097
 
3098
  if (sparc_compare_op1 == const0_rtx
3099
      && GET_CODE (sparc_compare_op0) == REG
3100
      && GET_MODE (sparc_compare_op0) == DImode
3101
      && v9_regcmp_p (code))
3102
    {
3103
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3104
                             sparc_compare_op0, sparc_compare_op1);
3105
    }
3106
  else
3107
    {
3108
      rtx cc_reg = gen_compare_reg (code,
3109
                                    sparc_compare_op0, sparc_compare_op1);
3110
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3111
                                    cc_reg, const0_rtx);
3112
    }
3113
})
3114
 
3115
(define_expand "movsfcc"
3116
  [(set (match_operand:SF 0 "register_operand" "")
3117
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
3118
                         (match_operand:SF 2 "register_operand" "")
3119
                         (match_operand:SF 3 "register_operand" "")))]
3120
  "TARGET_V9 && TARGET_FPU"
3121
{
3122
  enum rtx_code code = GET_CODE (operands[1]);
3123
 
3124
  if (GET_MODE (sparc_compare_op0) == DImode
3125
      && ! TARGET_ARCH64)
3126
    FAIL;
3127
 
3128
  if (sparc_compare_op1 == const0_rtx
3129
      && GET_CODE (sparc_compare_op0) == REG
3130
      && GET_MODE (sparc_compare_op0) == DImode
3131
      && v9_regcmp_p (code))
3132
    {
3133
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3134
                             sparc_compare_op0, sparc_compare_op1);
3135
    }
3136
  else
3137
    {
3138
      rtx cc_reg = gen_compare_reg (code,
3139
                                    sparc_compare_op0, sparc_compare_op1);
3140
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3141
    }
3142
})
3143
 
3144
(define_expand "movdfcc"
3145
  [(set (match_operand:DF 0 "register_operand" "")
3146
        (if_then_else:DF (match_operand 1 "comparison_operator" "")
3147
                         (match_operand:DF 2 "register_operand" "")
3148
                         (match_operand:DF 3 "register_operand" "")))]
3149
  "TARGET_V9 && TARGET_FPU"
3150
{
3151
  enum rtx_code code = GET_CODE (operands[1]);
3152
 
3153
  if (GET_MODE (sparc_compare_op0) == DImode
3154
      && ! TARGET_ARCH64)
3155
    FAIL;
3156
 
3157
  if (sparc_compare_op1 == const0_rtx
3158
      && GET_CODE (sparc_compare_op0) == REG
3159
      && GET_MODE (sparc_compare_op0) == DImode
3160
      && v9_regcmp_p (code))
3161
    {
3162
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3163
                             sparc_compare_op0, sparc_compare_op1);
3164
    }
3165
  else
3166
    {
3167
      rtx cc_reg = gen_compare_reg (code,
3168
                                    sparc_compare_op0, sparc_compare_op1);
3169
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3170
    }
3171
})
3172
 
3173
(define_expand "movtfcc"
3174
  [(set (match_operand:TF 0 "register_operand" "")
3175
        (if_then_else:TF (match_operand 1 "comparison_operator" "")
3176
                         (match_operand:TF 2 "register_operand" "")
3177
                         (match_operand:TF 3 "register_operand" "")))]
3178
  "TARGET_V9 && TARGET_FPU"
3179
{
3180
  enum rtx_code code = GET_CODE (operands[1]);
3181
 
3182
  if (GET_MODE (sparc_compare_op0) == DImode
3183
      && ! TARGET_ARCH64)
3184
    FAIL;
3185
 
3186
  if (sparc_compare_op1 == const0_rtx
3187
      && GET_CODE (sparc_compare_op0) == REG
3188
      && GET_MODE (sparc_compare_op0) == DImode
3189
      && v9_regcmp_p (code))
3190
    {
3191
      operands[1] = gen_rtx_fmt_ee (code, DImode,
3192
                             sparc_compare_op0, sparc_compare_op1);
3193
    }
3194
  else
3195
    {
3196
      rtx cc_reg = gen_compare_reg (code,
3197
                                    sparc_compare_op0, sparc_compare_op1);
3198
      operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3199
    }
3200
})
3201
 
3202
;; Conditional move define_insns.
3203
 
3204
(define_insn "*movqi_cc_sp64"
3205
  [(set (match_operand:QI 0 "register_operand" "=r,r")
3206
        (if_then_else:QI (match_operator 1 "comparison_operator"
3207
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3208
                                 (const_int 0)])
3209
                         (match_operand:QI 3 "arith11_operand" "rL,0")
3210
                         (match_operand:QI 4 "arith11_operand" "0,rL")))]
3211
  "TARGET_V9"
3212
  "@
3213
   mov%C1\t%x2, %3, %0
3214
   mov%c1\t%x2, %4, %0"
3215
  [(set_attr "type" "cmove")])
3216
 
3217
(define_insn "*movhi_cc_sp64"
3218
  [(set (match_operand:HI 0 "register_operand" "=r,r")
3219
        (if_then_else:HI (match_operator 1 "comparison_operator"
3220
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3221
                                 (const_int 0)])
3222
                         (match_operand:HI 3 "arith11_operand" "rL,0")
3223
                         (match_operand:HI 4 "arith11_operand" "0,rL")))]
3224
  "TARGET_V9"
3225
  "@
3226
   mov%C1\t%x2, %3, %0
3227
   mov%c1\t%x2, %4, %0"
3228
  [(set_attr "type" "cmove")])
3229
 
3230
(define_insn "*movsi_cc_sp64"
3231
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3232
        (if_then_else:SI (match_operator 1 "comparison_operator"
3233
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3234
                                 (const_int 0)])
3235
                         (match_operand:SI 3 "arith11_operand" "rL,0")
3236
                         (match_operand:SI 4 "arith11_operand" "0,rL")))]
3237
  "TARGET_V9"
3238
  "@
3239
   mov%C1\t%x2, %3, %0
3240
   mov%c1\t%x2, %4, %0"
3241
  [(set_attr "type" "cmove")])
3242
 
3243
(define_insn "*movdi_cc_sp64"
3244
  [(set (match_operand:DI 0 "register_operand" "=r,r")
3245
        (if_then_else:DI (match_operator 1 "comparison_operator"
3246
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3247
                                 (const_int 0)])
3248
                         (match_operand:DI 3 "arith11_operand" "rL,0")
3249
                         (match_operand:DI 4 "arith11_operand" "0,rL")))]
3250
  "TARGET_ARCH64"
3251
  "@
3252
   mov%C1\t%x2, %3, %0
3253
   mov%c1\t%x2, %4, %0"
3254
  [(set_attr "type" "cmove")])
3255
 
3256
(define_insn "*movdi_cc_sp64_trunc"
3257
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3258
        (if_then_else:SI (match_operator 1 "comparison_operator"
3259
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3260
                                 (const_int 0)])
3261
                         (match_operand:SI 3 "arith11_operand" "rL,0")
3262
                         (match_operand:SI 4 "arith11_operand" "0,rL")))]
3263
  "TARGET_ARCH64"
3264
  "@
3265
   mov%C1\t%x2, %3, %0
3266
   mov%c1\t%x2, %4, %0"
3267
  [(set_attr "type" "cmove")])
3268
 
3269
(define_insn "*movsf_cc_sp64"
3270
  [(set (match_operand:SF 0 "register_operand" "=f,f")
3271
        (if_then_else:SF (match_operator 1 "comparison_operator"
3272
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3273
                                 (const_int 0)])
3274
                         (match_operand:SF 3 "register_operand" "f,0")
3275
                         (match_operand:SF 4 "register_operand" "0,f")))]
3276
  "TARGET_V9 && TARGET_FPU"
3277
  "@
3278
   fmovs%C1\t%x2, %3, %0
3279
   fmovs%c1\t%x2, %4, %0"
3280
  [(set_attr "type" "fpcmove")])
3281
 
3282
(define_insn "movdf_cc_sp64"
3283
  [(set (match_operand:DF 0 "register_operand" "=e,e")
3284
        (if_then_else:DF (match_operator 1 "comparison_operator"
3285
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3286
                                 (const_int 0)])
3287
                         (match_operand:DF 3 "register_operand" "e,0")
3288
                         (match_operand:DF 4 "register_operand" "0,e")))]
3289
  "TARGET_V9 && TARGET_FPU"
3290
  "@
3291
   fmovd%C1\t%x2, %3, %0
3292
   fmovd%c1\t%x2, %4, %0"
3293
  [(set_attr "type" "fpcmove")
3294
   (set_attr "fptype" "double")])
3295
 
3296
(define_insn "*movtf_cc_hq_sp64"
3297
  [(set (match_operand:TF 0 "register_operand" "=e,e")
3298
        (if_then_else:TF (match_operator 1 "comparison_operator"
3299
                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3300
                                 (const_int 0)])
3301
                         (match_operand:TF 3 "register_operand" "e,0")
3302
                         (match_operand:TF 4 "register_operand" "0,e")))]
3303
  "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3304
  "@
3305
   fmovq%C1\t%x2, %3, %0
3306
   fmovq%c1\t%x2, %4, %0"
3307
  [(set_attr "type" "fpcmove")])
3308
 
3309
(define_insn_and_split "*movtf_cc_sp64"
3310
  [(set (match_operand:TF 0 "register_operand" "=e,e")
3311
        (if_then_else:TF (match_operator 1 "comparison_operator"
3312
                            [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3313
                             (const_int 0)])
3314
                         (match_operand:TF 3 "register_operand" "e,0")
3315
                         (match_operand:TF 4 "register_operand" "0,e")))]
3316
  "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3317
  "#"
3318
  "&& reload_completed"
3319
  [(clobber (const_int 0))]
3320
{
3321
  rtx set_dest = operands[0];
3322
  rtx set_srca = operands[3];
3323
  rtx set_srcb = operands[4];
3324
  int third = rtx_equal_p (set_dest, set_srca);
3325
  rtx dest1, dest2;
3326
  rtx srca1, srca2, srcb1, srcb2;
3327
 
3328
  dest1 = gen_df_reg (set_dest, 0);
3329
  dest2 = gen_df_reg (set_dest, 1);
3330
  srca1 = gen_df_reg (set_srca, 0);
3331
  srca2 = gen_df_reg (set_srca, 1);
3332
  srcb1 = gen_df_reg (set_srcb, 0);
3333
  srcb2 = gen_df_reg (set_srcb, 1);
3334
 
3335
  /* Now emit using the real source and destination we found, swapping
3336
     the order if we detect overlap.  */
3337
  if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3338
      || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3339
    {
3340
      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3341
      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3342
    }
3343
  else
3344
    {
3345
      emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3346
      emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3347
    }
3348
  DONE;
3349
}
3350
  [(set_attr "length" "2")])
3351
 
3352
(define_insn "*movqi_cc_reg_sp64"
3353
  [(set (match_operand:QI 0 "register_operand" "=r,r")
3354
        (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3355
                                [(match_operand:DI 2 "register_operand" "r,r")
3356
                                 (const_int 0)])
3357
                         (match_operand:QI 3 "arith10_operand" "rM,0")
3358
                         (match_operand:QI 4 "arith10_operand" "0,rM")))]
3359
  "TARGET_ARCH64"
3360
  "@
3361
   movr%D1\t%2, %r3, %0
3362
   movr%d1\t%2, %r4, %0"
3363
  [(set_attr "type" "cmove")])
3364
 
3365
(define_insn "*movhi_cc_reg_sp64"
3366
  [(set (match_operand:HI 0 "register_operand" "=r,r")
3367
        (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3368
                                [(match_operand:DI 2 "register_operand" "r,r")
3369
                                 (const_int 0)])
3370
                         (match_operand:HI 3 "arith10_operand" "rM,0")
3371
                         (match_operand:HI 4 "arith10_operand" "0,rM")))]
3372
  "TARGET_ARCH64"
3373
  "@
3374
   movr%D1\t%2, %r3, %0
3375
   movr%d1\t%2, %r4, %0"
3376
  [(set_attr "type" "cmove")])
3377
 
3378
(define_insn "*movsi_cc_reg_sp64"
3379
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3380
        (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3381
                                [(match_operand:DI 2 "register_operand" "r,r")
3382
                                 (const_int 0)])
3383
                         (match_operand:SI 3 "arith10_operand" "rM,0")
3384
                         (match_operand:SI 4 "arith10_operand" "0,rM")))]
3385
  "TARGET_ARCH64"
3386
  "@
3387
   movr%D1\t%2, %r3, %0
3388
   movr%d1\t%2, %r4, %0"
3389
  [(set_attr "type" "cmove")])
3390
 
3391
(define_insn "*movdi_cc_reg_sp64"
3392
  [(set (match_operand:DI 0 "register_operand" "=r,r")
3393
        (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3394
                                [(match_operand:DI 2 "register_operand" "r,r")
3395
                                 (const_int 0)])
3396
                         (match_operand:DI 3 "arith10_operand" "rM,0")
3397
                         (match_operand:DI 4 "arith10_operand" "0,rM")))]
3398
  "TARGET_ARCH64"
3399
  "@
3400
   movr%D1\t%2, %r3, %0
3401
   movr%d1\t%2, %r4, %0"
3402
  [(set_attr "type" "cmove")])
3403
 
3404
(define_insn "*movsf_cc_reg_sp64"
3405
  [(set (match_operand:SF 0 "register_operand" "=f,f")
3406
        (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3407
                                [(match_operand:DI 2 "register_operand" "r,r")
3408
                                 (const_int 0)])
3409
                         (match_operand:SF 3 "register_operand" "f,0")
3410
                         (match_operand:SF 4 "register_operand" "0,f")))]
3411
  "TARGET_ARCH64 && TARGET_FPU"
3412
  "@
3413
   fmovrs%D1\t%2, %3, %0
3414
   fmovrs%d1\t%2, %4, %0"
3415
  [(set_attr "type" "fpcrmove")])
3416
 
3417
(define_insn "movdf_cc_reg_sp64"
3418
  [(set (match_operand:DF 0 "register_operand" "=e,e")
3419
        (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3420
                                [(match_operand:DI 2 "register_operand" "r,r")
3421
                                 (const_int 0)])
3422
                         (match_operand:DF 3 "register_operand" "e,0")
3423
                         (match_operand:DF 4 "register_operand" "0,e")))]
3424
  "TARGET_ARCH64 && TARGET_FPU"
3425
  "@
3426
   fmovrd%D1\t%2, %3, %0
3427
   fmovrd%d1\t%2, %4, %0"
3428
  [(set_attr "type" "fpcrmove")
3429
   (set_attr "fptype" "double")])
3430
 
3431
(define_insn "*movtf_cc_reg_hq_sp64"
3432
  [(set (match_operand:TF 0 "register_operand" "=e,e")
3433
        (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3434
                                [(match_operand:DI 2 "register_operand" "r,r")
3435
                                 (const_int 0)])
3436
                         (match_operand:TF 3 "register_operand" "e,0")
3437
                         (match_operand:TF 4 "register_operand" "0,e")))]
3438
  "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3439
  "@
3440
   fmovrq%D1\t%2, %3, %0
3441
   fmovrq%d1\t%2, %4, %0"
3442
  [(set_attr "type" "fpcrmove")])
3443
 
3444
(define_insn_and_split "*movtf_cc_reg_sp64"
3445
  [(set (match_operand:TF 0 "register_operand" "=e,e")
3446
        (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3447
                                [(match_operand:DI 2 "register_operand" "r,r")
3448
                                 (const_int 0)])
3449
                         (match_operand:TF 3 "register_operand" "e,0")
3450
                         (match_operand:TF 4 "register_operand" "0,e")))]
3451
  "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3452
  "#"
3453
  "&& reload_completed"
3454
  [(clobber (const_int 0))]
3455
{
3456
  rtx set_dest = operands[0];
3457
  rtx set_srca = operands[3];
3458
  rtx set_srcb = operands[4];
3459
  int third = rtx_equal_p (set_dest, set_srca);
3460
  rtx dest1, dest2;
3461
  rtx srca1, srca2, srcb1, srcb2;
3462
 
3463
  dest1 = gen_df_reg (set_dest, 0);
3464
  dest2 = gen_df_reg (set_dest, 1);
3465
  srca1 = gen_df_reg (set_srca, 0);
3466
  srca2 = gen_df_reg (set_srca, 1);
3467
  srcb1 = gen_df_reg (set_srcb, 0);
3468
  srcb2 = gen_df_reg (set_srcb, 1);
3469
 
3470
  /* Now emit using the real source and destination we found, swapping
3471
     the order if we detect overlap.  */
3472
  if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3473
      || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3474
    {
3475
      emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3476
      emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3477
    }
3478
  else
3479
    {
3480
      emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3481
      emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3482
    }
3483
  DONE;
3484
}
3485
  [(set_attr "length" "2")])
3486
 
3487
 
3488
;; Zero-extension instructions
3489
 
3490
;; These patterns originally accepted general_operands, however, slightly
3491
;; better code is generated by only accepting register_operands, and then
3492
;; letting combine generate the ldu[hb] insns.
3493
 
3494
(define_expand "zero_extendhisi2"
3495
  [(set (match_operand:SI 0 "register_operand" "")
3496
        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3497
  ""
3498
{
3499
  rtx temp = gen_reg_rtx (SImode);
3500
  rtx shift_16 = GEN_INT (16);
3501
  int op1_subbyte = 0;
3502
 
3503
  if (GET_CODE (operand1) == SUBREG)
3504
    {
3505
      op1_subbyte = SUBREG_BYTE (operand1);
3506
      op1_subbyte /= GET_MODE_SIZE (SImode);
3507
      op1_subbyte *= GET_MODE_SIZE (SImode);
3508
      operand1 = XEXP (operand1, 0);
3509
    }
3510
 
3511
  emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3512
                          shift_16));
3513
  emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3514
  DONE;
3515
})
3516
 
3517
(define_insn "*zero_extendhisi2_insn"
3518
  [(set (match_operand:SI 0 "register_operand" "=r")
3519
        (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3520
  ""
3521
  "lduh\t%1, %0"
3522
  [(set_attr "type" "load")
3523
   (set_attr "us3load_type" "3cycle")])
3524
 
3525
(define_expand "zero_extendqihi2"
3526
  [(set (match_operand:HI 0 "register_operand" "")
3527
        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3528
  ""
3529
  "")
3530
 
3531
(define_insn "*zero_extendqihi2_insn"
3532
  [(set (match_operand:HI 0 "register_operand" "=r,r")
3533
        (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3534
  "GET_CODE (operands[1]) != CONST_INT"
3535
  "@
3536
   and\t%1, 0xff, %0
3537
   ldub\t%1, %0"
3538
  [(set_attr "type" "*,load")
3539
   (set_attr "us3load_type" "*,3cycle")])
3540
 
3541
(define_expand "zero_extendqisi2"
3542
  [(set (match_operand:SI 0 "register_operand" "")
3543
        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3544
  ""
3545
  "")
3546
 
3547
(define_insn "*zero_extendqisi2_insn"
3548
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3549
        (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3550
  "GET_CODE (operands[1]) != CONST_INT"
3551
  "@
3552
   and\t%1, 0xff, %0
3553
   ldub\t%1, %0"
3554
  [(set_attr "type" "*,load")
3555
   (set_attr "us3load_type" "*,3cycle")])
3556
 
3557
(define_expand "zero_extendqidi2"
3558
  [(set (match_operand:DI 0 "register_operand" "")
3559
        (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3560
  "TARGET_ARCH64"
3561
  "")
3562
 
3563
(define_insn "*zero_extendqidi2_insn"
3564
  [(set (match_operand:DI 0 "register_operand" "=r,r")
3565
        (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3566
  "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3567
  "@
3568
   and\t%1, 0xff, %0
3569
   ldub\t%1, %0"
3570
  [(set_attr "type" "*,load")
3571
   (set_attr "us3load_type" "*,3cycle")])
3572
 
3573
(define_expand "zero_extendhidi2"
3574
  [(set (match_operand:DI 0 "register_operand" "")
3575
        (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3576
  "TARGET_ARCH64"
3577
{
3578
  rtx temp = gen_reg_rtx (DImode);
3579
  rtx shift_48 = GEN_INT (48);
3580
  int op1_subbyte = 0;
3581
 
3582
  if (GET_CODE (operand1) == SUBREG)
3583
    {
3584
      op1_subbyte = SUBREG_BYTE (operand1);
3585
      op1_subbyte /= GET_MODE_SIZE (DImode);
3586
      op1_subbyte *= GET_MODE_SIZE (DImode);
3587
      operand1 = XEXP (operand1, 0);
3588
    }
3589
 
3590
  emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3591
                          shift_48));
3592
  emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3593
  DONE;
3594
})
3595
 
3596
(define_insn "*zero_extendhidi2_insn"
3597
  [(set (match_operand:DI 0 "register_operand" "=r")
3598
        (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3599
  "TARGET_ARCH64"
3600
  "lduh\t%1, %0"
3601
  [(set_attr "type" "load")
3602
   (set_attr "us3load_type" "3cycle")])
3603
 
3604
;; ??? Write truncdisi pattern using sra?
3605
 
3606
(define_expand "zero_extendsidi2"
3607
  [(set (match_operand:DI 0 "register_operand" "")
3608
        (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3609
  ""
3610
  "")
3611
 
3612
(define_insn "*zero_extendsidi2_insn_sp64"
3613
  [(set (match_operand:DI 0 "register_operand" "=r,r")
3614
        (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3615
  "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3616
  "@
3617
   srl\t%1, 0, %0
3618
   lduw\t%1, %0"
3619
  [(set_attr "type" "shift,load")])
3620
 
3621
(define_insn_and_split "*zero_extendsidi2_insn_sp32"
3622
  [(set (match_operand:DI 0 "register_operand" "=r")
3623
        (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3624
  "! TARGET_ARCH64"
3625
  "#"
3626
  "&& reload_completed"
3627
  [(set (match_dup 2) (match_dup 3))
3628
   (set (match_dup 4) (match_dup 5))]
3629
{
3630
  rtx dest1, dest2;
3631
 
3632
  dest1 = gen_highpart (SImode, operands[0]);
3633
  dest2 = gen_lowpart (SImode, operands[0]);
3634
 
3635
  /* Swap the order in case of overlap.  */
3636
  if (REGNO (dest1) == REGNO (operands[1]))
3637
    {
3638
      operands[2] = dest2;
3639
      operands[3] = operands[1];
3640
      operands[4] = dest1;
3641
      operands[5] = const0_rtx;
3642
    }
3643
  else
3644
    {
3645
      operands[2] = dest1;
3646
      operands[3] = const0_rtx;
3647
      operands[4] = dest2;
3648
      operands[5] = operands[1];
3649
    }
3650
}
3651
  [(set_attr "length" "2")])
3652
 
3653
;; Simplify comparisons of extended values.
3654
 
3655
(define_insn "*cmp_zero_extendqisi2"
3656
  [(set (reg:CC 100)
3657
        (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3658
                    (const_int 0)))]
3659
  ""
3660
  "andcc\t%0, 0xff, %%g0"
3661
  [(set_attr "type" "compare")])
3662
 
3663
(define_insn "*cmp_zero_qi"
3664
  [(set (reg:CC 100)
3665
        (compare:CC (match_operand:QI 0 "register_operand" "r")
3666
                    (const_int 0)))]
3667
  ""
3668
  "andcc\t%0, 0xff, %%g0"
3669
  [(set_attr "type" "compare")])
3670
 
3671
(define_insn "*cmp_zero_extendqisi2_set"
3672
  [(set (reg:CC 100)
3673
        (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3674
                    (const_int 0)))
3675
   (set (match_operand:SI 0 "register_operand" "=r")
3676
        (zero_extend:SI (match_dup 1)))]
3677
  ""
3678
  "andcc\t%1, 0xff, %0"
3679
  [(set_attr "type" "compare")])
3680
 
3681
(define_insn "*cmp_zero_extendqisi2_andcc_set"
3682
  [(set (reg:CC 100)
3683
        (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3684
                            (const_int 255))
3685
                    (const_int 0)))
3686
   (set (match_operand:SI 0 "register_operand" "=r")
3687
        (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3688
  ""
3689
  "andcc\t%1, 0xff, %0"
3690
  [(set_attr "type" "compare")])
3691
 
3692
(define_insn "*cmp_zero_extendqidi2"
3693
  [(set (reg:CCX 100)
3694
        (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3695
                     (const_int 0)))]
3696
  "TARGET_ARCH64"
3697
  "andcc\t%0, 0xff, %%g0"
3698
  [(set_attr "type" "compare")])
3699
 
3700
(define_insn "*cmp_zero_qi_sp64"
3701
  [(set (reg:CCX 100)
3702
        (compare:CCX (match_operand:QI 0 "register_operand" "r")
3703
                     (const_int 0)))]
3704
  "TARGET_ARCH64"
3705
  "andcc\t%0, 0xff, %%g0"
3706
  [(set_attr "type" "compare")])
3707
 
3708
(define_insn "*cmp_zero_extendqidi2_set"
3709
  [(set (reg:CCX 100)
3710
        (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3711
                     (const_int 0)))
3712
   (set (match_operand:DI 0 "register_operand" "=r")
3713
        (zero_extend:DI (match_dup 1)))]
3714
  "TARGET_ARCH64"
3715
  "andcc\t%1, 0xff, %0"
3716
  [(set_attr "type" "compare")])
3717
 
3718
(define_insn "*cmp_zero_extendqidi2_andcc_set"
3719
  [(set (reg:CCX 100)
3720
        (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3721
                             (const_int 255))
3722
                     (const_int 0)))
3723
   (set (match_operand:DI 0 "register_operand" "=r")
3724
        (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3725
  "TARGET_ARCH64"
3726
  "andcc\t%1, 0xff, %0"
3727
  [(set_attr "type" "compare")])
3728
 
3729
;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3730
 
3731
(define_insn "*cmp_siqi_trunc"
3732
  [(set (reg:CC 100)
3733
        (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3734
                    (const_int 0)))]
3735
  ""
3736
  "andcc\t%0, 0xff, %%g0"
3737
  [(set_attr "type" "compare")])
3738
 
3739
(define_insn "*cmp_siqi_trunc_set"
3740
  [(set (reg:CC 100)
3741
        (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3742
                    (const_int 0)))
3743
   (set (match_operand:QI 0 "register_operand" "=r")
3744
        (subreg:QI (match_dup 1) 3))]
3745
  ""
3746
  "andcc\t%1, 0xff, %0"
3747
  [(set_attr "type" "compare")])
3748
 
3749
(define_insn "*cmp_diqi_trunc"
3750
  [(set (reg:CC 100)
3751
        (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3752
                    (const_int 0)))]
3753
  "TARGET_ARCH64"
3754
  "andcc\t%0, 0xff, %%g0"
3755
  [(set_attr "type" "compare")])
3756
 
3757
(define_insn "*cmp_diqi_trunc_set"
3758
  [(set (reg:CC 100)
3759
        (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3760
                    (const_int 0)))
3761
   (set (match_operand:QI 0 "register_operand" "=r")
3762
        (subreg:QI (match_dup 1) 7))]
3763
  "TARGET_ARCH64"
3764
  "andcc\t%1, 0xff, %0"
3765
  [(set_attr "type" "compare")])
3766
 
3767
 
3768
;; Sign-extension instructions
3769
 
3770
;; These patterns originally accepted general_operands, however, slightly
3771
;; better code is generated by only accepting register_operands, and then
3772
;; letting combine generate the lds[hb] insns.
3773
 
3774
(define_expand "extendhisi2"
3775
  [(set (match_operand:SI 0 "register_operand" "")
3776
        (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3777
  ""
3778
{
3779
  rtx temp = gen_reg_rtx (SImode);
3780
  rtx shift_16 = GEN_INT (16);
3781
  int op1_subbyte = 0;
3782
 
3783
  if (GET_CODE (operand1) == SUBREG)
3784
    {
3785
      op1_subbyte = SUBREG_BYTE (operand1);
3786
      op1_subbyte /= GET_MODE_SIZE (SImode);
3787
      op1_subbyte *= GET_MODE_SIZE (SImode);
3788
      operand1 = XEXP (operand1, 0);
3789
    }
3790
 
3791
  emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3792
                          shift_16));
3793
  emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3794
  DONE;
3795
})
3796
 
3797
(define_insn "*sign_extendhisi2_insn"
3798
  [(set (match_operand:SI 0 "register_operand" "=r")
3799
        (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3800
  ""
3801
  "ldsh\t%1, %0"
3802
  [(set_attr "type" "sload")
3803
   (set_attr "us3load_type" "3cycle")])
3804
 
3805
(define_expand "extendqihi2"
3806
  [(set (match_operand:HI 0 "register_operand" "")
3807
        (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3808
  ""
3809
{
3810
  rtx temp = gen_reg_rtx (SImode);
3811
  rtx shift_24 = GEN_INT (24);
3812
  int op1_subbyte = 0;
3813
  int op0_subbyte = 0;
3814
 
3815
  if (GET_CODE (operand1) == SUBREG)
3816
    {
3817
      op1_subbyte = SUBREG_BYTE (operand1);
3818
      op1_subbyte /= GET_MODE_SIZE (SImode);
3819
      op1_subbyte *= GET_MODE_SIZE (SImode);
3820
      operand1 = XEXP (operand1, 0);
3821
    }
3822
  if (GET_CODE (operand0) == SUBREG)
3823
    {
3824
      op0_subbyte = SUBREG_BYTE (operand0);
3825
      op0_subbyte /= GET_MODE_SIZE (SImode);
3826
      op0_subbyte *= GET_MODE_SIZE (SImode);
3827
      operand0 = XEXP (operand0, 0);
3828
    }
3829
  emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3830
                          shift_24));
3831
  if (GET_MODE (operand0) != SImode)
3832
    operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3833
  emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3834
  DONE;
3835
})
3836
 
3837
(define_insn "*sign_extendqihi2_insn"
3838
  [(set (match_operand:HI 0 "register_operand" "=r")
3839
        (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3840
  ""
3841
  "ldsb\t%1, %0"
3842
  [(set_attr "type" "sload")
3843
   (set_attr "us3load_type" "3cycle")])
3844
 
3845
(define_expand "extendqisi2"
3846
  [(set (match_operand:SI 0 "register_operand" "")
3847
        (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3848
  ""
3849
{
3850
  rtx temp = gen_reg_rtx (SImode);
3851
  rtx shift_24 = GEN_INT (24);
3852
  int op1_subbyte = 0;
3853
 
3854
  if (GET_CODE (operand1) == SUBREG)
3855
    {
3856
      op1_subbyte = SUBREG_BYTE (operand1);
3857
      op1_subbyte /= GET_MODE_SIZE (SImode);
3858
      op1_subbyte *= GET_MODE_SIZE (SImode);
3859
      operand1 = XEXP (operand1, 0);
3860
    }
3861
 
3862
  emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3863
                          shift_24));
3864
  emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3865
  DONE;
3866
})
3867
 
3868
(define_insn "*sign_extendqisi2_insn"
3869
  [(set (match_operand:SI 0 "register_operand" "=r")
3870
        (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3871
  ""
3872
  "ldsb\t%1, %0"
3873
  [(set_attr "type" "sload")
3874
   (set_attr "us3load_type" "3cycle")])
3875
 
3876
(define_expand "extendqidi2"
3877
  [(set (match_operand:DI 0 "register_operand" "")
3878
        (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3879
  "TARGET_ARCH64"
3880
{
3881
  rtx temp = gen_reg_rtx (DImode);
3882
  rtx shift_56 = GEN_INT (56);
3883
  int op1_subbyte = 0;
3884
 
3885
  if (GET_CODE (operand1) == SUBREG)
3886
    {
3887
      op1_subbyte = SUBREG_BYTE (operand1);
3888
      op1_subbyte /= GET_MODE_SIZE (DImode);
3889
      op1_subbyte *= GET_MODE_SIZE (DImode);
3890
      operand1 = XEXP (operand1, 0);
3891
    }
3892
 
3893
  emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3894
                          shift_56));
3895
  emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3896
  DONE;
3897
})
3898
 
3899
(define_insn "*sign_extendqidi2_insn"
3900
  [(set (match_operand:DI 0 "register_operand" "=r")
3901
        (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3902
  "TARGET_ARCH64"
3903
  "ldsb\t%1, %0"
3904
  [(set_attr "type" "sload")
3905
   (set_attr "us3load_type" "3cycle")])
3906
 
3907
(define_expand "extendhidi2"
3908
  [(set (match_operand:DI 0 "register_operand" "")
3909
        (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3910
  "TARGET_ARCH64"
3911
{
3912
  rtx temp = gen_reg_rtx (DImode);
3913
  rtx shift_48 = GEN_INT (48);
3914
  int op1_subbyte = 0;
3915
 
3916
  if (GET_CODE (operand1) == SUBREG)
3917
    {
3918
      op1_subbyte = SUBREG_BYTE (operand1);
3919
      op1_subbyte /= GET_MODE_SIZE (DImode);
3920
      op1_subbyte *= GET_MODE_SIZE (DImode);
3921
      operand1 = XEXP (operand1, 0);
3922
    }
3923
 
3924
  emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3925
                          shift_48));
3926
  emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3927
  DONE;
3928
})
3929
 
3930
(define_insn "*sign_extendhidi2_insn"
3931
  [(set (match_operand:DI 0 "register_operand" "=r")
3932
        (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3933
  "TARGET_ARCH64"
3934
  "ldsh\t%1, %0"
3935
  [(set_attr "type" "sload")
3936
   (set_attr "us3load_type" "3cycle")])
3937
 
3938
(define_expand "extendsidi2"
3939
  [(set (match_operand:DI 0 "register_operand" "")
3940
        (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3941
  "TARGET_ARCH64"
3942
  "")
3943
 
3944
(define_insn "*sign_extendsidi2_insn"
3945
  [(set (match_operand:DI 0 "register_operand" "=r,r")
3946
        (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3947
  "TARGET_ARCH64"
3948
  "@
3949
  sra\t%1, 0, %0
3950
  ldsw\t%1, %0"
3951
  [(set_attr "type" "shift,sload")
3952
   (set_attr "us3load_type" "*,3cycle")])
3953
 
3954
 
3955
;; Special pattern for optimizing bit-field compares.  This is needed
3956
;; because combine uses this as a canonical form.
3957
 
3958
(define_insn "*cmp_zero_extract"
3959
  [(set (reg:CC 100)
3960
        (compare:CC
3961
         (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3962
                          (match_operand:SI 1 "small_int_operand" "I")
3963
                          (match_operand:SI 2 "small_int_operand" "I"))
3964
         (const_int 0)))]
3965
  "INTVAL (operands[2]) > 19"
3966
{
3967
  int len = INTVAL (operands[1]);
3968
  int pos = 32 - INTVAL (operands[2]) - len;
3969
  HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3970
  operands[1] = GEN_INT (mask);
3971
  return "andcc\t%0, %1, %%g0";
3972
}
3973
  [(set_attr "type" "compare")])
3974
 
3975
(define_insn "*cmp_zero_extract_sp64"
3976
  [(set (reg:CCX 100)
3977
        (compare:CCX
3978
         (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3979
                          (match_operand:SI 1 "small_int_operand" "I")
3980
                          (match_operand:SI 2 "small_int_operand" "I"))
3981
         (const_int 0)))]
3982
  "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3983
{
3984
  int len = INTVAL (operands[1]);
3985
  int pos = 64 - INTVAL (operands[2]) - len;
3986
  HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3987
  operands[1] = GEN_INT (mask);
3988
  return "andcc\t%0, %1, %%g0";
3989
}
3990
  [(set_attr "type" "compare")])
3991
 
3992
 
3993
;; Conversions between float, double and long double.
3994
 
3995
(define_insn "extendsfdf2"
3996
  [(set (match_operand:DF 0 "register_operand" "=e")
3997
        (float_extend:DF
3998
         (match_operand:SF 1 "register_operand" "f")))]
3999
  "TARGET_FPU"
4000
  "fstod\t%1, %0"
4001
  [(set_attr "type" "fp")
4002
   (set_attr "fptype" "double")])
4003
 
4004
(define_expand "extendsftf2"
4005
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4006
        (float_extend:TF
4007
         (match_operand:SF 1 "register_operand" "")))]
4008
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4009
  "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4010
 
4011
(define_insn "*extendsftf2_hq"
4012
  [(set (match_operand:TF 0 "register_operand" "=e")
4013
        (float_extend:TF
4014
         (match_operand:SF 1 "register_operand" "f")))]
4015
  "TARGET_FPU && TARGET_HARD_QUAD"
4016
  "fstoq\t%1, %0"
4017
  [(set_attr "type" "fp")])
4018
 
4019
(define_expand "extenddftf2"
4020
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4021
        (float_extend:TF
4022
         (match_operand:DF 1 "register_operand" "")))]
4023
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4024
  "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4025
 
4026
(define_insn "*extenddftf2_hq"
4027
  [(set (match_operand:TF 0 "register_operand" "=e")
4028
        (float_extend:TF
4029
         (match_operand:DF 1 "register_operand" "e")))]
4030
  "TARGET_FPU && TARGET_HARD_QUAD"
4031
  "fdtoq\t%1, %0"
4032
  [(set_attr "type" "fp")])
4033
 
4034
(define_insn "truncdfsf2"
4035
  [(set (match_operand:SF 0 "register_operand" "=f")
4036
        (float_truncate:SF
4037
         (match_operand:DF 1 "register_operand" "e")))]
4038
  "TARGET_FPU"
4039
  "fdtos\t%1, %0"
4040
  [(set_attr "type" "fp")
4041
   (set_attr "fptype" "double")])
4042
 
4043
(define_expand "trunctfsf2"
4044
  [(set (match_operand:SF 0 "register_operand" "")
4045
        (float_truncate:SF
4046
         (match_operand:TF 1 "general_operand" "")))]
4047
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4048
  "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4049
 
4050
(define_insn "*trunctfsf2_hq"
4051
  [(set (match_operand:SF 0 "register_operand" "=f")
4052
        (float_truncate:SF
4053
         (match_operand:TF 1 "register_operand" "e")))]
4054
  "TARGET_FPU && TARGET_HARD_QUAD"
4055
  "fqtos\t%1, %0"
4056
  [(set_attr "type" "fp")])
4057
 
4058
(define_expand "trunctfdf2"
4059
  [(set (match_operand:DF 0 "register_operand" "")
4060
        (float_truncate:DF
4061
         (match_operand:TF 1 "general_operand" "")))]
4062
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4063
  "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4064
 
4065
(define_insn "*trunctfdf2_hq"
4066
  [(set (match_operand:DF 0 "register_operand" "=e")
4067
        (float_truncate:DF
4068
         (match_operand:TF 1 "register_operand" "e")))]
4069
  "TARGET_FPU && TARGET_HARD_QUAD"
4070
  "fqtod\t%1, %0"
4071
  [(set_attr "type" "fp")])
4072
 
4073
 
4074
;; Conversion between fixed point and floating point.
4075
 
4076
(define_insn "floatsisf2"
4077
  [(set (match_operand:SF 0 "register_operand" "=f")
4078
        (float:SF (match_operand:SI 1 "register_operand" "f")))]
4079
  "TARGET_FPU"
4080
  "fitos\t%1, %0"
4081
  [(set_attr "type" "fp")
4082
   (set_attr "fptype" "double")])
4083
 
4084
(define_insn "floatsidf2"
4085
  [(set (match_operand:DF 0 "register_operand" "=e")
4086
        (float:DF (match_operand:SI 1 "register_operand" "f")))]
4087
  "TARGET_FPU"
4088
  "fitod\t%1, %0"
4089
  [(set_attr "type" "fp")
4090
   (set_attr "fptype" "double")])
4091
 
4092
(define_expand "floatsitf2"
4093
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4094
        (float:TF (match_operand:SI 1 "register_operand" "")))]
4095
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4096
  "emit_tfmode_cvt (FLOAT, operands); DONE;")
4097
 
4098
(define_insn "*floatsitf2_hq"
4099
  [(set (match_operand:TF 0 "register_operand" "=e")
4100
        (float:TF (match_operand:SI 1 "register_operand" "f")))]
4101
  "TARGET_FPU && TARGET_HARD_QUAD"
4102
  "fitoq\t%1, %0"
4103
  [(set_attr "type" "fp")])
4104
 
4105
(define_expand "floatunssitf2"
4106
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4107
        (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4108
  "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4109
  "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4110
 
4111
;; Now the same for 64 bit sources.
4112
 
4113
(define_insn "floatdisf2"
4114
  [(set (match_operand:SF 0 "register_operand" "=f")
4115
        (float:SF (match_operand:DI 1 "register_operand" "e")))]
4116
  "TARGET_V9 && TARGET_FPU"
4117
  "fxtos\t%1, %0"
4118
  [(set_attr "type" "fp")
4119
   (set_attr "fptype" "double")])
4120
 
4121
(define_expand "floatunsdisf2"
4122
  [(use (match_operand:SF 0 "register_operand" ""))
4123
   (use (match_operand:DI 1 "general_operand" ""))]
4124
  "TARGET_ARCH64 && TARGET_FPU"
4125
  "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4126
 
4127
(define_insn "floatdidf2"
4128
  [(set (match_operand:DF 0 "register_operand" "=e")
4129
        (float:DF (match_operand:DI 1 "register_operand" "e")))]
4130
  "TARGET_V9 && TARGET_FPU"
4131
  "fxtod\t%1, %0"
4132
  [(set_attr "type" "fp")
4133
   (set_attr "fptype" "double")])
4134
 
4135
(define_expand "floatunsdidf2"
4136
  [(use (match_operand:DF 0 "register_operand" ""))
4137
   (use (match_operand:DI 1 "general_operand" ""))]
4138
  "TARGET_ARCH64 && TARGET_FPU"
4139
  "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4140
 
4141
(define_expand "floatditf2"
4142
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4143
        (float:TF (match_operand:DI 1 "register_operand" "")))]
4144
  "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4145
  "emit_tfmode_cvt (FLOAT, operands); DONE;")
4146
 
4147
(define_insn "*floatditf2_hq"
4148
  [(set (match_operand:TF 0 "register_operand" "=e")
4149
        (float:TF (match_operand:DI 1 "register_operand" "e")))]
4150
  "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4151
  "fxtoq\t%1, %0"
4152
  [(set_attr "type" "fp")])
4153
 
4154
(define_expand "floatunsditf2"
4155
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
4156
        (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4157
  "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4158
  "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4159
 
4160
;; Convert a float to an actual integer.
4161
;; Truncation is performed as part of the conversion.
4162
 
4163
(define_insn "fix_truncsfsi2"
4164
  [(set (match_operand:SI 0 "register_operand" "=f")
4165
        (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4166
  "TARGET_FPU"
4167
  "fstoi\t%1, %0"
4168
  [(set_attr "type" "fp")
4169
   (set_attr "fptype" "double")])
4170
 
4171
(define_insn "fix_truncdfsi2"
4172
  [(set (match_operand:SI 0 "register_operand" "=f")
4173
        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4174
  "TARGET_FPU"
4175
  "fdtoi\t%1, %0"
4176
  [(set_attr "type" "fp")
4177
   (set_attr "fptype" "double")])
4178
 
4179
(define_expand "fix_trunctfsi2"
4180
  [(set (match_operand:SI 0 "register_operand" "")
4181
        (fix:SI (match_operand:TF 1 "general_operand" "")))]
4182
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4183
  "emit_tfmode_cvt (FIX, operands); DONE;")
4184
 
4185
(define_insn "*fix_trunctfsi2_hq"
4186
  [(set (match_operand:SI 0 "register_operand" "=f")
4187
        (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4188
  "TARGET_FPU && TARGET_HARD_QUAD"
4189
  "fqtoi\t%1, %0"
4190
  [(set_attr "type" "fp")])
4191
 
4192
(define_expand "fixuns_trunctfsi2"
4193
  [(set (match_operand:SI 0 "register_operand" "")
4194
        (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4195
  "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4196
  "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4197
 
4198
;; Now the same, for V9 targets
4199
 
4200
(define_insn "fix_truncsfdi2"
4201
  [(set (match_operand:DI 0 "register_operand" "=e")
4202
        (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4203
  "TARGET_V9 && TARGET_FPU"
4204
  "fstox\t%1, %0"
4205
  [(set_attr "type" "fp")
4206
   (set_attr "fptype" "double")])
4207
 
4208
(define_expand "fixuns_truncsfdi2"
4209
  [(use (match_operand:DI 0 "register_operand" ""))
4210
   (use (match_operand:SF 1 "general_operand" ""))]
4211
  "TARGET_ARCH64 && TARGET_FPU"
4212
  "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4213
 
4214
(define_insn "fix_truncdfdi2"
4215
  [(set (match_operand:DI 0 "register_operand" "=e")
4216
        (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4217
  "TARGET_V9 && TARGET_FPU"
4218
  "fdtox\t%1, %0"
4219
  [(set_attr "type" "fp")
4220
   (set_attr "fptype" "double")])
4221
 
4222
(define_expand "fixuns_truncdfdi2"
4223
  [(use (match_operand:DI 0 "register_operand" ""))
4224
   (use (match_operand:DF 1 "general_operand" ""))]
4225
  "TARGET_ARCH64 && TARGET_FPU"
4226
  "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4227
 
4228
(define_expand "fix_trunctfdi2"
4229
  [(set (match_operand:DI 0 "register_operand" "")
4230
        (fix:DI (match_operand:TF 1 "general_operand" "")))]
4231
  "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4232
  "emit_tfmode_cvt (FIX, operands); DONE;")
4233
 
4234
(define_insn "*fix_trunctfdi2_hq"
4235
  [(set (match_operand:DI 0 "register_operand" "=e")
4236
        (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4237
  "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4238
  "fqtox\t%1, %0"
4239
  [(set_attr "type" "fp")])
4240
 
4241
(define_expand "fixuns_trunctfdi2"
4242
  [(set (match_operand:DI 0 "register_operand" "")
4243
        (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4244
  "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4245
  "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4246
 
4247
 
4248
;; Integer addition/subtraction instructions.
4249
 
4250
(define_expand "adddi3"
4251
  [(set (match_operand:DI 0 "register_operand" "")
4252
        (plus:DI (match_operand:DI 1 "register_operand" "")
4253
                 (match_operand:DI 2 "arith_double_add_operand" "")))]
4254
  ""
4255
{
4256
  if (! TARGET_ARCH64)
4257
    {
4258
      emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4259
                          gen_rtx_SET (VOIDmode, operands[0],
4260
                                   gen_rtx_PLUS (DImode, operands[1],
4261
                                                 operands[2])),
4262
                          gen_rtx_CLOBBER (VOIDmode,
4263
                                   gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4264
      DONE;
4265
    }
4266
})
4267
 
4268
(define_insn_and_split "adddi3_insn_sp32"
4269
  [(set (match_operand:DI 0 "register_operand" "=r")
4270
        (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4271
                 (match_operand:DI 2 "arith_double_operand" "rHI")))
4272
   (clobber (reg:CC 100))]
4273
  "! TARGET_ARCH64"
4274
  "#"
4275
  "&& reload_completed"
4276
  [(parallel [(set (reg:CC_NOOV 100)
4277
                   (compare:CC_NOOV (plus:SI (match_dup 4)
4278
                                             (match_dup 5))
4279
                                    (const_int 0)))
4280
              (set (match_dup 3)
4281
                   (plus:SI (match_dup 4) (match_dup 5)))])
4282
   (set (match_dup 6)
4283
        (plus:SI (plus:SI (match_dup 7)
4284
                          (match_dup 8))
4285
                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4286
{
4287
  operands[3] = gen_lowpart (SImode, operands[0]);
4288
  operands[4] = gen_lowpart (SImode, operands[1]);
4289
  operands[5] = gen_lowpart (SImode, operands[2]);
4290
  operands[6] = gen_highpart (SImode, operands[0]);
4291
  operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4292
#if HOST_BITS_PER_WIDE_INT == 32
4293
  if (GET_CODE (operands[2]) == CONST_INT)
4294
    {
4295
      if (INTVAL (operands[2]) < 0)
4296
        operands[8] = constm1_rtx;
4297
      else
4298
        operands[8] = const0_rtx;
4299
    }
4300
  else
4301
#endif
4302
    operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4303
}
4304
  [(set_attr "length" "2")])
4305
 
4306
;; LTU here means "carry set"
4307
(define_insn "addx"
4308
  [(set (match_operand:SI 0 "register_operand" "=r")
4309
        (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4310
                          (match_operand:SI 2 "arith_operand" "rI"))
4311
                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4312
  ""
4313
  "addx\t%1, %2, %0"
4314
  [(set_attr "type" "ialuX")])
4315
 
4316
(define_insn_and_split "*addx_extend_sp32"
4317
  [(set (match_operand:DI 0 "register_operand" "=r")
4318
        (zero_extend:DI (plus:SI (plus:SI
4319
                                  (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4320
                                  (match_operand:SI 2 "arith_operand" "rI"))
4321
                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4322
  "! TARGET_ARCH64"
4323
  "#"
4324
  "&& reload_completed"
4325
  [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4326
                               (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4327
   (set (match_dup 4) (const_int 0))]
4328
  "operands[3] = gen_lowpart (SImode, operands[0]);
4329
   operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4330
  [(set_attr "length" "2")])
4331
 
4332
(define_insn "*addx_extend_sp64"
4333
  [(set (match_operand:DI 0 "register_operand" "=r")
4334
        (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4335
                                          (match_operand:SI 2 "arith_operand" "rI"))
4336
                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4337
  "TARGET_ARCH64"
4338
  "addx\t%r1, %2, %0"
4339
  [(set_attr "type" "ialuX")])
4340
 
4341
(define_insn_and_split ""
4342
  [(set (match_operand:DI 0 "register_operand" "=r")
4343
        (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4344
                 (match_operand:DI 2 "register_operand" "r")))
4345
   (clobber (reg:CC 100))]
4346
  "! TARGET_ARCH64"
4347
  "#"
4348
  "&& reload_completed"
4349
  [(parallel [(set (reg:CC_NOOV 100)
4350
                   (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4351
                                    (const_int 0)))
4352
              (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4353
   (set (match_dup 6)
4354
        (plus:SI (plus:SI (match_dup 4) (const_int 0))
4355
                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4356
  "operands[3] = gen_lowpart (SImode, operands[2]);
4357
   operands[4] = gen_highpart (SImode, operands[2]);
4358
   operands[5] = gen_lowpart (SImode, operands[0]);
4359
   operands[6] = gen_highpart (SImode, operands[0]);"
4360
  [(set_attr "length" "2")])
4361
 
4362
(define_insn "*adddi3_sp64"
4363
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4364
        (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4365
                 (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4366
  "TARGET_ARCH64"
4367
  "@
4368
   add\t%1, %2, %0
4369
   sub\t%1, -%2, %0")
4370
 
4371
(define_insn "addsi3"
4372
  [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4373
        (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4374
                 (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4375
  ""
4376
  "@
4377
   add\t%1, %2, %0
4378
   sub\t%1, -%2, %0
4379
   fpadd32s\t%1, %2, %0"
4380
  [(set_attr "type" "*,*,fga")
4381
   (set_attr "fptype" "*,*,single")])
4382
 
4383
(define_insn "*cmp_cc_plus"
4384
  [(set (reg:CC_NOOV 100)
4385
        (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4386
                                  (match_operand:SI 1 "arith_operand" "rI"))
4387
                         (const_int 0)))]
4388
  ""
4389
  "addcc\t%0, %1, %%g0"
4390
  [(set_attr "type" "compare")])
4391
 
4392
(define_insn "*cmp_ccx_plus"
4393
  [(set (reg:CCX_NOOV 100)
4394
        (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4395
                                   (match_operand:DI 1 "arith_operand" "rI"))
4396
                          (const_int 0)))]
4397
  "TARGET_ARCH64"
4398
  "addcc\t%0, %1, %%g0"
4399
  [(set_attr "type" "compare")])
4400
 
4401
(define_insn "*cmp_cc_plus_set"
4402
  [(set (reg:CC_NOOV 100)
4403
        (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4404
                                  (match_operand:SI 2 "arith_operand" "rI"))
4405
                         (const_int 0)))
4406
   (set (match_operand:SI 0 "register_operand" "=r")
4407
        (plus:SI (match_dup 1) (match_dup 2)))]
4408
  ""
4409
  "addcc\t%1, %2, %0"
4410
  [(set_attr "type" "compare")])
4411
 
4412
(define_insn "*cmp_ccx_plus_set"
4413
  [(set (reg:CCX_NOOV 100)
4414
        (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4415
                                   (match_operand:DI 2 "arith_operand" "rI"))
4416
                          (const_int 0)))
4417
   (set (match_operand:DI 0 "register_operand" "=r")
4418
        (plus:DI (match_dup 1) (match_dup 2)))]
4419
  "TARGET_ARCH64"
4420
  "addcc\t%1, %2, %0"
4421
  [(set_attr "type" "compare")])
4422
 
4423
(define_expand "subdi3"
4424
  [(set (match_operand:DI 0 "register_operand" "")
4425
        (minus:DI (match_operand:DI 1 "register_operand" "")
4426
                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4427
  ""
4428
{
4429
  if (! TARGET_ARCH64)
4430
    {
4431
      emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4432
                          gen_rtx_SET (VOIDmode, operands[0],
4433
                                   gen_rtx_MINUS (DImode, operands[1],
4434
                                                  operands[2])),
4435
                          gen_rtx_CLOBBER (VOIDmode,
4436
                                   gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4437
      DONE;
4438
    }
4439
})
4440
 
4441
(define_insn_and_split "subdi3_insn_sp32"
4442
  [(set (match_operand:DI 0 "register_operand" "=r")
4443
        (minus:DI (match_operand:DI 1 "register_operand" "r")
4444
                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4445
   (clobber (reg:CC 100))]
4446
  "! TARGET_ARCH64"
4447
  "#"
4448
  "&& reload_completed"
4449
  [(parallel [(set (reg:CC_NOOV 100)
4450
                   (compare:CC_NOOV (minus:SI (match_dup 4)
4451
                                              (match_dup 5))
4452
                                    (const_int 0)))
4453
              (set (match_dup 3)
4454
                   (minus:SI (match_dup 4) (match_dup 5)))])
4455
   (set (match_dup 6)
4456
        (minus:SI (minus:SI (match_dup 7)
4457
                            (match_dup 8))
4458
                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4459
{
4460
  operands[3] = gen_lowpart (SImode, operands[0]);
4461
  operands[4] = gen_lowpart (SImode, operands[1]);
4462
  operands[5] = gen_lowpart (SImode, operands[2]);
4463
  operands[6] = gen_highpart (SImode, operands[0]);
4464
  operands[7] = gen_highpart (SImode, operands[1]);
4465
#if HOST_BITS_PER_WIDE_INT == 32
4466
  if (GET_CODE (operands[2]) == CONST_INT)
4467
    {
4468
      if (INTVAL (operands[2]) < 0)
4469
        operands[8] = constm1_rtx;
4470
      else
4471
        operands[8] = const0_rtx;
4472
    }
4473
  else
4474
#endif
4475
    operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4476
}
4477
  [(set_attr "length" "2")])
4478
 
4479
;; LTU here means "carry set"
4480
(define_insn "subx"
4481
  [(set (match_operand:SI 0 "register_operand" "=r")
4482
        (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4483
                            (match_operand:SI 2 "arith_operand" "rI"))
4484
                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4485
  ""
4486
  "subx\t%r1, %2, %0"
4487
  [(set_attr "type" "ialuX")])
4488
 
4489
(define_insn "*subx_extend_sp64"
4490
  [(set (match_operand:DI 0 "register_operand" "=r")
4491
        (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4492
                                            (match_operand:SI 2 "arith_operand" "rI"))
4493
                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4494
  "TARGET_ARCH64"
4495
  "subx\t%r1, %2, %0"
4496
  [(set_attr "type" "ialuX")])
4497
 
4498
(define_insn_and_split "*subx_extend"
4499
  [(set (match_operand:DI 0 "register_operand" "=r")
4500
        (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4501
                                            (match_operand:SI 2 "arith_operand" "rI"))
4502
                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4503
  "! TARGET_ARCH64"
4504
  "#"
4505
  "&& reload_completed"
4506
  [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4507
                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4508
   (set (match_dup 4) (const_int 0))]
4509
  "operands[3] = gen_lowpart (SImode, operands[0]);
4510
   operands[4] = gen_highpart (SImode, operands[0]);"
4511
  [(set_attr "length" "2")])
4512
 
4513
(define_insn_and_split ""
4514
  [(set (match_operand:DI 0 "register_operand" "=r")
4515
      (minus:DI (match_operand:DI 1 "register_operand" "r")
4516
                (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4517
   (clobber (reg:CC 100))]
4518
  "! TARGET_ARCH64"
4519
  "#"
4520
  "&& reload_completed"
4521
  [(parallel [(set (reg:CC_NOOV 100)
4522
                   (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4523
                                    (const_int 0)))
4524
              (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4525
   (set (match_dup 6)
4526
        (minus:SI (minus:SI (match_dup 4) (const_int 0))
4527
                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4528
  "operands[3] = gen_lowpart (SImode, operands[1]);
4529
   operands[4] = gen_highpart (SImode, operands[1]);
4530
   operands[5] = gen_lowpart (SImode, operands[0]);
4531
   operands[6] = gen_highpart (SImode, operands[0]);"
4532
  [(set_attr "length" "2")])
4533
 
4534
(define_insn "*subdi3_sp64"
4535
  [(set (match_operand:DI 0 "register_operand" "=r,r")
4536
        (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4537
                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4538
  "TARGET_ARCH64"
4539
  "@
4540
   sub\t%1, %2, %0
4541
   add\t%1, -%2, %0")
4542
 
4543
(define_insn "subsi3"
4544
  [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4545
        (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4546
                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4547
  ""
4548
  "@
4549
   sub\t%1, %2, %0
4550
   add\t%1, -%2, %0
4551
   fpsub32s\t%1, %2, %0"
4552
  [(set_attr "type" "*,*,fga")
4553
   (set_attr "fptype" "*,*,single")])
4554
 
4555
(define_insn "*cmp_minus_cc"
4556
  [(set (reg:CC_NOOV 100)
4557
        (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4558
                                   (match_operand:SI 1 "arith_operand" "rI"))
4559
                         (const_int 0)))]
4560
  ""
4561
  "subcc\t%r0, %1, %%g0"
4562
  [(set_attr "type" "compare")])
4563
 
4564
(define_insn "*cmp_minus_ccx"
4565
  [(set (reg:CCX_NOOV 100)
4566
        (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4567
                                    (match_operand:DI 1 "arith_operand" "rI"))
4568
                          (const_int 0)))]
4569
  "TARGET_ARCH64"
4570
  "subcc\t%0, %1, %%g0"
4571
  [(set_attr "type" "compare")])
4572
 
4573
(define_insn "cmp_minus_cc_set"
4574
  [(set (reg:CC_NOOV 100)
4575
        (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4576
                                   (match_operand:SI 2 "arith_operand" "rI"))
4577
                         (const_int 0)))
4578
   (set (match_operand:SI 0 "register_operand" "=r")
4579
        (minus:SI (match_dup 1) (match_dup 2)))]
4580
  ""
4581
  "subcc\t%r1, %2, %0"
4582
  [(set_attr "type" "compare")])
4583
 
4584
(define_insn "*cmp_minus_ccx_set"
4585
  [(set (reg:CCX_NOOV 100)
4586
        (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4587
                                    (match_operand:DI 2 "arith_operand" "rI"))
4588
                          (const_int 0)))
4589
   (set (match_operand:DI 0 "register_operand" "=r")
4590
        (minus:DI (match_dup 1) (match_dup 2)))]
4591
  "TARGET_ARCH64"
4592
  "subcc\t%1, %2, %0"
4593
  [(set_attr "type" "compare")])
4594
 
4595
 
4596
;; Integer multiply/divide instructions.
4597
 
4598
;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4599
;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4600
 
4601
(define_insn "mulsi3"
4602
  [(set (match_operand:SI 0 "register_operand" "=r")
4603
        (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4604
                 (match_operand:SI 2 "arith_operand" "rI")))]
4605
  "TARGET_HARD_MUL"
4606
  "smul\t%1, %2, %0"
4607
  [(set_attr "type" "imul")])
4608
 
4609
(define_expand "muldi3"
4610
  [(set (match_operand:DI 0 "register_operand" "")
4611
        (mult:DI (match_operand:DI 1 "arith_operand" "")
4612
                 (match_operand:DI 2 "arith_operand" "")))]
4613
  "TARGET_ARCH64 || TARGET_V8PLUS"
4614
{
4615
  if (TARGET_V8PLUS)
4616
    {
4617
      emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4618
      DONE;
4619
    }
4620
})
4621
 
4622
(define_insn "*muldi3_sp64"
4623
  [(set (match_operand:DI 0 "register_operand" "=r")
4624
        (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4625
                 (match_operand:DI 2 "arith_operand" "rI")))]
4626
  "TARGET_ARCH64"
4627
  "mulx\t%1, %2, %0"
4628
  [(set_attr "type" "imul")])
4629
 
4630
;; V8plus wide multiply.
4631
;; XXX
4632
(define_insn "muldi3_v8plus"
4633
  [(set (match_operand:DI 0 "register_operand" "=r,h")
4634
        (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4635
                 (match_operand:DI 2 "arith_operand" "rI,rI")))
4636
   (clobber (match_scratch:SI 3 "=&h,X"))
4637
   (clobber (match_scratch:SI 4 "=&h,X"))]
4638
  "TARGET_V8PLUS"
4639
{
4640
  if (sparc_check_64 (operands[1], insn) <= 0)
4641
    output_asm_insn ("srl\t%L1, 0, %L1", operands);
4642
  if (which_alternative == 1)
4643
    output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4644
  if (GET_CODE (operands[2]) == CONST_INT)
4645
    {
4646
      if (which_alternative == 1)
4647
        return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4648
      else
4649
        return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4650
    }
4651
  else if (rtx_equal_p (operands[1], operands[2]))
4652
    {
4653
      if (which_alternative == 1)
4654
        return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4655
      else
4656
        return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4657
    }
4658
  if (sparc_check_64 (operands[2], insn) <= 0)
4659
    output_asm_insn ("srl\t%L2, 0, %L2", operands);
4660
  if (which_alternative == 1)
4661
    return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
4662
  else
4663
    return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4664
}
4665
  [(set_attr "type" "multi")
4666
   (set_attr "length" "9,8")])
4667
 
4668
(define_insn "*cmp_mul_set"
4669
  [(set (reg:CC 100)
4670
        (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4671
                    (match_operand:SI 2 "arith_operand" "rI"))
4672
                    (const_int 0)))
4673
   (set (match_operand:SI 0 "register_operand" "=r")
4674
        (mult:SI (match_dup 1) (match_dup 2)))]
4675
  "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4676
  "smulcc\t%1, %2, %0"
4677
  [(set_attr "type" "imul")])
4678
 
4679
(define_expand "mulsidi3"
4680
  [(set (match_operand:DI 0 "register_operand" "")
4681
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4682
                 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4683
  "TARGET_HARD_MUL"
4684
{
4685
  if (CONSTANT_P (operands[2]))
4686
    {
4687
      if (TARGET_V8PLUS)
4688
        emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4689
                                              operands[2]));
4690
      else if (TARGET_ARCH32)
4691
        emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4692
                                            operands[2]));
4693
      else
4694
        emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4695
                                            operands[2]));
4696
      DONE;
4697
    }
4698
  if (TARGET_V8PLUS)
4699
    {
4700
      emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4701
      DONE;
4702
    }
4703
})
4704
 
4705
;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
4706
;; registers can hold 64 bit values in the V8plus environment.
4707
;; XXX
4708
(define_insn "mulsidi3_v8plus"
4709
  [(set (match_operand:DI 0 "register_operand" "=h,r")
4710
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4711
                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4712
   (clobber (match_scratch:SI 3 "=X,&h"))]
4713
  "TARGET_V8PLUS"
4714
  "@
4715
   smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4716
   smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4717
  [(set_attr "type" "multi")
4718
   (set_attr "length" "2,3")])
4719
 
4720
;; XXX
4721
(define_insn "const_mulsidi3_v8plus"
4722
  [(set (match_operand:DI 0 "register_operand" "=h,r")
4723
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4724
                 (match_operand:DI 2 "small_int_operand" "I,I")))
4725
   (clobber (match_scratch:SI 3 "=X,&h"))]
4726
  "TARGET_V8PLUS"
4727
  "@
4728
   smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4729
   smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4730
  [(set_attr "type" "multi")
4731
   (set_attr "length" "2,3")])
4732
 
4733
;; XXX
4734
(define_insn "*mulsidi3_sp32"
4735
  [(set (match_operand:DI 0 "register_operand" "=r")
4736
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4737
                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4738
  "TARGET_HARD_MUL32"
4739
{
4740
  return TARGET_SPARCLET
4741
         ? "smuld\t%1, %2, %L0"
4742
         : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4743
}
4744
  [(set (attr "type")
4745
        (if_then_else (eq_attr "isa" "sparclet")
4746
                      (const_string "imul") (const_string "multi")))
4747
   (set (attr "length")
4748
        (if_then_else (eq_attr "isa" "sparclet")
4749
                      (const_int 1) (const_int 2)))])
4750
 
4751
(define_insn "*mulsidi3_sp64"
4752
  [(set (match_operand:DI 0 "register_operand" "=r")
4753
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4754
                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4755
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4756
  "smul\t%1, %2, %0"
4757
  [(set_attr "type" "imul")])
4758
 
4759
;; Extra pattern, because sign_extend of a constant isn't valid.
4760
 
4761
;; XXX
4762
(define_insn "const_mulsidi3_sp32"
4763
  [(set (match_operand:DI 0 "register_operand" "=r")
4764
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4765
                 (match_operand:DI 2 "small_int_operand" "I")))]
4766
  "TARGET_HARD_MUL32"
4767
{
4768
  return TARGET_SPARCLET
4769
         ? "smuld\t%1, %2, %L0"
4770
         : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4771
}
4772
  [(set (attr "type")
4773
        (if_then_else (eq_attr "isa" "sparclet")
4774
                      (const_string "imul") (const_string "multi")))
4775
   (set (attr "length")
4776
        (if_then_else (eq_attr "isa" "sparclet")
4777
                      (const_int 1) (const_int 2)))])
4778
 
4779
(define_insn "const_mulsidi3_sp64"
4780
  [(set (match_operand:DI 0 "register_operand" "=r")
4781
        (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4782
                 (match_operand:DI 2 "small_int_operand" "I")))]
4783
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4784
  "smul\t%1, %2, %0"
4785
  [(set_attr "type" "imul")])
4786
 
4787
(define_expand "smulsi3_highpart"
4788
  [(set (match_operand:SI 0 "register_operand" "")
4789
        (truncate:SI
4790
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4791
                               (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4792
                      (const_int 32))))]
4793
  "TARGET_HARD_MUL && TARGET_ARCH32"
4794
{
4795
  if (CONSTANT_P (operands[2]))
4796
    {
4797
      if (TARGET_V8PLUS)
4798
        {
4799
          emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4800
                                                        operands[1],
4801
                                                        operands[2],
4802
                                                        GEN_INT (32)));
4803
          DONE;
4804
        }
4805
      emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4806
      DONE;
4807
    }
4808
  if (TARGET_V8PLUS)
4809
    {
4810
      emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4811
                                              operands[2], GEN_INT (32)));
4812
      DONE;
4813
    }
4814
})
4815
 
4816
;; XXX
4817
(define_insn "smulsi3_highpart_v8plus"
4818
  [(set (match_operand:SI 0 "register_operand" "=h,r")
4819
        (truncate:SI
4820
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4821
                               (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4822
                      (match_operand:SI 3 "small_int_operand" "I,I"))))
4823
   (clobber (match_scratch:SI 4 "=X,&h"))]
4824
  "TARGET_V8PLUS"
4825
  "@
4826
   smul\t%1, %2, %0\;srlx\t%0, %3, %0
4827
   smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4828
  [(set_attr "type" "multi")
4829
   (set_attr "length" "2")])
4830
 
4831
;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4832
;; XXX
4833
(define_insn ""
4834
  [(set (match_operand:SI 0 "register_operand" "=h,r")
4835
        (subreg:SI
4836
         (lshiftrt:DI
4837
          (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4838
                   (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4839
          (match_operand:SI 3 "small_int_operand" "I,I"))
4840
         4))
4841
   (clobber (match_scratch:SI 4 "=X,&h"))]
4842
  "TARGET_V8PLUS"
4843
  "@
4844
   smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4845
   smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4846
  [(set_attr "type" "multi")
4847
   (set_attr "length" "2")])
4848
 
4849
;; XXX
4850
(define_insn "const_smulsi3_highpart_v8plus"
4851
  [(set (match_operand:SI 0 "register_operand" "=h,r")
4852
        (truncate:SI
4853
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4854
                               (match_operand:DI 2 "small_int_operand" "I,I"))
4855
                      (match_operand:SI 3 "small_int_operand" "I,I"))))
4856
   (clobber (match_scratch:SI 4 "=X,&h"))]
4857
  "TARGET_V8PLUS"
4858
  "@
4859
   smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4860
   smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4861
  [(set_attr "type" "multi")
4862
   (set_attr "length" "2")])
4863
 
4864
;; XXX
4865
(define_insn "*smulsi3_highpart_sp32"
4866
  [(set (match_operand:SI 0 "register_operand" "=r")
4867
        (truncate:SI
4868
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4869
                               (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4870
                      (const_int 32))))]
4871
  "TARGET_HARD_MUL32"
4872
  "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4873
  [(set_attr "type" "multi")
4874
   (set_attr "length" "2")])
4875
 
4876
;; XXX
4877
(define_insn "const_smulsi3_highpart"
4878
  [(set (match_operand:SI 0 "register_operand" "=r")
4879
        (truncate:SI
4880
         (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881
                               (match_operand:DI 2 "small_int_operand" "i"))
4882
                      (const_int 32))))]
4883
  "TARGET_HARD_MUL32"
4884
  "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885
  [(set_attr "type" "multi")
4886
   (set_attr "length" "2")])
4887
 
4888
(define_expand "umulsidi3"
4889
  [(set (match_operand:DI 0 "register_operand" "")
4890
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4891
                 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4892
  "TARGET_HARD_MUL"
4893
{
4894
  if (CONSTANT_P (operands[2]))
4895
    {
4896
      if (TARGET_V8PLUS)
4897
        emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4898
                                               operands[2]));
4899
      else if (TARGET_ARCH32)
4900
        emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4901
                                             operands[2]));
4902
      else
4903
        emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4904
                                             operands[2]));
4905
      DONE;
4906
    }
4907
  if (TARGET_V8PLUS)
4908
    {
4909
      emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4910
      DONE;
4911
    }
4912
})
4913
 
4914
;; XXX
4915
(define_insn "umulsidi3_v8plus"
4916
  [(set (match_operand:DI 0 "register_operand" "=h,r")
4917
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4918
                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4919
   (clobber (match_scratch:SI 3 "=X,&h"))]
4920
  "TARGET_V8PLUS"
4921
  "@
4922
   umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4923
   umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4924
  [(set_attr "type" "multi")
4925
   (set_attr "length" "2,3")])
4926
 
4927
;; XXX
4928
(define_insn "*umulsidi3_sp32"
4929
  [(set (match_operand:DI 0 "register_operand" "=r")
4930
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4931
                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4932
  "TARGET_HARD_MUL32"
4933
{
4934
  return TARGET_SPARCLET
4935
         ? "umuld\t%1, %2, %L0"
4936
         : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4937
}
4938
  [(set (attr "type")
4939
        (if_then_else (eq_attr "isa" "sparclet")
4940
                      (const_string "imul") (const_string "multi")))
4941
   (set (attr "length")
4942
        (if_then_else (eq_attr "isa" "sparclet")
4943
                      (const_int 1) (const_int 2)))])
4944
 
4945
(define_insn "*umulsidi3_sp64"
4946
  [(set (match_operand:DI 0 "register_operand" "=r")
4947
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4948
                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4949
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4950
  "umul\t%1, %2, %0"
4951
  [(set_attr "type" "imul")])
4952
 
4953
;; Extra pattern, because sign_extend of a constant isn't valid.
4954
 
4955
;; XXX
4956
(define_insn "const_umulsidi3_sp32"
4957
  [(set (match_operand:DI 0 "register_operand" "=r")
4958
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4959
                 (match_operand:DI 2 "uns_small_int_operand" "")))]
4960
  "TARGET_HARD_MUL32"
4961
{
4962
  return TARGET_SPARCLET
4963
         ? "umuld\t%1, %s2, %L0"
4964
         : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4965
}
4966
  [(set (attr "type")
4967
        (if_then_else (eq_attr "isa" "sparclet")
4968
                      (const_string "imul") (const_string "multi")))
4969
   (set (attr "length")
4970
        (if_then_else (eq_attr "isa" "sparclet")
4971
                      (const_int 1) (const_int 2)))])
4972
 
4973
(define_insn "const_umulsidi3_sp64"
4974
  [(set (match_operand:DI 0 "register_operand" "=r")
4975
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4976
                 (match_operand:DI 2 "uns_small_int_operand" "")))]
4977
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4978
  "umul\t%1, %s2, %0"
4979
  [(set_attr "type" "imul")])
4980
 
4981
;; XXX
4982
(define_insn "const_umulsidi3_v8plus"
4983
  [(set (match_operand:DI 0 "register_operand" "=h,r")
4984
        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4985
                 (match_operand:DI 2 "uns_small_int_operand" "")))
4986
   (clobber (match_scratch:SI 3 "=X,h"))]
4987
  "TARGET_V8PLUS"
4988
  "@
4989
   umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4990
   umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4991
  [(set_attr "type" "multi")
4992
   (set_attr "length" "2,3")])
4993
 
4994
(define_expand "umulsi3_highpart"
4995
  [(set (match_operand:SI 0 "register_operand" "")
4996
        (truncate:SI
4997
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4998
                               (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4999
                      (const_int 32))))]
5000
  "TARGET_HARD_MUL && TARGET_ARCH32"
5001
{
5002
  if (CONSTANT_P (operands[2]))
5003
    {
5004
      if (TARGET_V8PLUS)
5005
        {
5006
          emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5007
                                                        operands[1],
5008
                                                        operands[2],
5009
                                                        GEN_INT (32)));
5010
          DONE;
5011
        }
5012
      emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5013
      DONE;
5014
    }
5015
  if (TARGET_V8PLUS)
5016
    {
5017
      emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5018
                                              operands[2], GEN_INT (32)));
5019
      DONE;
5020
    }
5021
})
5022
 
5023
;; XXX
5024
(define_insn "umulsi3_highpart_v8plus"
5025
  [(set (match_operand:SI 0 "register_operand" "=h,r")
5026
        (truncate:SI
5027
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5028
                               (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5029
                      (match_operand:SI 3 "small_int_operand" "I,I"))))
5030
   (clobber (match_scratch:SI 4 "=X,h"))]
5031
  "TARGET_V8PLUS"
5032
  "@
5033
   umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5034
   umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5035
  [(set_attr "type" "multi")
5036
   (set_attr "length" "2")])
5037
 
5038
;; XXX
5039
(define_insn "const_umulsi3_highpart_v8plus"
5040
  [(set (match_operand:SI 0 "register_operand" "=h,r")
5041
        (truncate:SI
5042
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5043
                               (match_operand:DI 2 "uns_small_int_operand" ""))
5044
                      (match_operand:SI 3 "small_int_operand" "I,I"))))
5045
   (clobber (match_scratch:SI 4 "=X,h"))]
5046
  "TARGET_V8PLUS"
5047
  "@
5048
   umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5049
   umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5050
  [(set_attr "type" "multi")
5051
   (set_attr "length" "2")])
5052
 
5053
;; XXX
5054
(define_insn "*umulsi3_highpart_sp32"
5055
  [(set (match_operand:SI 0 "register_operand" "=r")
5056
        (truncate:SI
5057
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5058
                               (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5059
                      (const_int 32))))]
5060
  "TARGET_HARD_MUL32"
5061
  "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5062
  [(set_attr "type" "multi")
5063
   (set_attr "length" "2")])
5064
 
5065
;; XXX
5066
(define_insn "const_umulsi3_highpart"
5067
  [(set (match_operand:SI 0 "register_operand" "=r")
5068
        (truncate:SI
5069
         (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5070
                               (match_operand:DI 2 "uns_small_int_operand" ""))
5071
                      (const_int 32))))]
5072
  "TARGET_HARD_MUL32"
5073
  "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5074
  [(set_attr "type" "multi")
5075
   (set_attr "length" "2")])
5076
 
5077
;; The V8 architecture specifies that there must be 3 instructions between
5078
;; a Y register write and a use of it for correct results.
5079
 
5080
(define_expand "divsi3"
5081
  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5082
                   (div:SI (match_operand:SI 1 "register_operand" "r,r")
5083
                           (match_operand:SI 2 "input_operand" "rI,m")))
5084
              (clobber (match_scratch:SI 3 "=&r,&r"))])]
5085
  "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5086
{
5087
  if (TARGET_ARCH64)
5088
    {
5089
      operands[3] = gen_reg_rtx(SImode);
5090
      emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5091
      emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5092
                                  operands[3]));
5093
      DONE;
5094
    }
5095
})
5096
 
5097
(define_insn "divsi3_sp32"
5098
  [(set (match_operand:SI 0 "register_operand" "=r,r")
5099
        (div:SI (match_operand:SI 1 "register_operand" "r,r")
5100
                (match_operand:SI 2 "input_operand" "rI,m")))
5101
   (clobber (match_scratch:SI 3 "=&r,&r"))]
5102
  "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5103
   && TARGET_ARCH32"
5104
{
5105
  if (which_alternative == 0)
5106
    if (TARGET_V9)
5107
      return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5108
    else
5109
      return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5110
  else
5111
    if (TARGET_V9)
5112
      return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5113
    else
5114
      return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5115
}
5116
  [(set_attr "type" "multi")
5117
   (set (attr "length")
5118
        (if_then_else (eq_attr "isa" "v9")
5119
                      (const_int 4) (const_int 6)))])
5120
 
5121
(define_insn "divsi3_sp64"
5122
  [(set (match_operand:SI 0 "register_operand" "=r")
5123
        (div:SI (match_operand:SI 1 "register_operand" "r")
5124
                (match_operand:SI 2 "input_operand" "rI")))
5125
   (use (match_operand:SI 3 "register_operand" "r"))]
5126
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5127
  "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5128
  [(set_attr "type" "multi")
5129
   (set_attr "length" "2")])
5130
 
5131
(define_insn "divdi3"
5132
  [(set (match_operand:DI 0 "register_operand" "=r")
5133
        (div:DI (match_operand:DI 1 "register_operand" "r")
5134
                (match_operand:DI 2 "arith_operand" "rI")))]
5135
  "TARGET_ARCH64"
5136
  "sdivx\t%1, %2, %0"
5137
  [(set_attr "type" "idiv")])
5138
 
5139
(define_insn "*cmp_sdiv_cc_set"
5140
  [(set (reg:CC 100)
5141
        (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5142
                            (match_operand:SI 2 "arith_operand" "rI"))
5143
                    (const_int 0)))
5144
   (set (match_operand:SI 0 "register_operand" "=r")
5145
        (div:SI (match_dup 1) (match_dup 2)))
5146
   (clobber (match_scratch:SI 3 "=&r"))]
5147
  "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5148
{
5149
  if (TARGET_V9)
5150
    return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5151
  else
5152
    return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5153
}
5154
  [(set_attr "type" "multi")
5155
   (set (attr "length")
5156
        (if_then_else (eq_attr "isa" "v9")
5157
                      (const_int 3) (const_int 6)))])
5158
 
5159
;; XXX
5160
(define_expand "udivsi3"
5161
  [(set (match_operand:SI 0 "register_operand" "")
5162
        (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5163
                 (match_operand:SI 2 "input_operand" "")))]
5164
  "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5165
  "")
5166
 
5167
;; The V8 architecture specifies that there must be 3 instructions between
5168
;; a Y register write and a use of it for correct results.
5169
 
5170
(define_insn "udivsi3_sp32"
5171
  [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5172
        (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5173
                 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5174
  "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5175
   && TARGET_ARCH32"
5176
{
5177
  output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5178
  switch (which_alternative)
5179
    {
5180
    default:
5181
      return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5182
    case 1:
5183
      return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5184
    case 2:
5185
      return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5186
    }
5187
}
5188
  [(set_attr "type" "multi")
5189
   (set_attr "length" "5")])
5190
 
5191
(define_insn "udivsi3_sp64"
5192
  [(set (match_operand:SI 0 "register_operand" "=r")
5193
        (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5194
                 (match_operand:SI 2 "input_operand" "rI")))]
5195
  "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5196
  "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5197
  [(set_attr "type" "multi")
5198
   (set_attr "length" "2")])
5199
 
5200
(define_insn "udivdi3"
5201
  [(set (match_operand:DI 0 "register_operand" "=r")
5202
        (udiv:DI (match_operand:DI 1 "register_operand" "r")
5203
                 (match_operand:DI 2 "arith_operand" "rI")))]
5204
  "TARGET_ARCH64"
5205
  "udivx\t%1, %2, %0"
5206
  [(set_attr "type" "idiv")])
5207
 
5208
(define_insn "*cmp_udiv_cc_set"
5209
  [(set (reg:CC 100)
5210
        (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5211
                             (match_operand:SI 2 "arith_operand" "rI"))
5212
                    (const_int 0)))
5213
   (set (match_operand:SI 0 "register_operand" "=r")
5214
        (udiv:SI (match_dup 1) (match_dup 2)))]
5215
  "TARGET_V8
5216
   || TARGET_DEPRECATED_V8_INSNS"
5217
{
5218
  if (TARGET_V9)
5219
    return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5220
  else
5221
    return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5222
}
5223
  [(set_attr "type" "multi")
5224
   (set (attr "length")
5225
        (if_then_else (eq_attr "isa" "v9")
5226
                      (const_int 2) (const_int 5)))])
5227
 
5228
; sparclet multiply/accumulate insns
5229
 
5230
(define_insn "*smacsi"
5231
  [(set (match_operand:SI 0 "register_operand" "=r")
5232
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5233
                          (match_operand:SI 2 "arith_operand" "rI"))
5234
                 (match_operand:SI 3 "register_operand" "0")))]
5235
  "TARGET_SPARCLET"
5236
  "smac\t%1, %2, %0"
5237
  [(set_attr "type" "imul")])
5238
 
5239
(define_insn "*smacdi"
5240
  [(set (match_operand:DI 0 "register_operand" "=r")
5241
        (plus:DI (mult:DI (sign_extend:DI
5242
                           (match_operand:SI 1 "register_operand" "%r"))
5243
                          (sign_extend:DI
5244
                           (match_operand:SI 2 "register_operand" "r")))
5245
                 (match_operand:DI 3 "register_operand" "0")))]
5246
  "TARGET_SPARCLET"
5247
  "smacd\t%1, %2, %L0"
5248
  [(set_attr "type" "imul")])
5249
 
5250
(define_insn "*umacdi"
5251
  [(set (match_operand:DI 0 "register_operand" "=r")
5252
        (plus:DI (mult:DI (zero_extend:DI
5253
                           (match_operand:SI 1 "register_operand" "%r"))
5254
                          (zero_extend:DI
5255
                           (match_operand:SI 2 "register_operand" "r")))
5256
                 (match_operand:DI 3 "register_operand" "0")))]
5257
  "TARGET_SPARCLET"
5258
  "umacd\t%1, %2, %L0"
5259
  [(set_attr "type" "imul")])
5260
 
5261
 
5262
;; Boolean instructions.
5263
 
5264
;; We define DImode `and' so with DImode `not' we can get
5265
;; DImode `andn'.  Other combinations are possible.
5266
 
5267
(define_mode_macro V64I [DI V2SI V4HI V8QI])
5268
(define_mode_macro V32I [SI V2HI V4QI])
5269
 
5270
(define_expand "and3"
5271
  [(set (match_operand:V64I 0 "register_operand" "")
5272
        (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5273
                  (match_operand:V64I 2 "arith_double_operand" "")))]
5274
  ""
5275
  "")
5276
 
5277
(define_insn "*and3_sp32"
5278
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5279
        (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5280
                  (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5281
  "! TARGET_ARCH64"
5282
  "@
5283
  #
5284
  fand\t%1, %2, %0"
5285
  [(set_attr "type" "*,fga")
5286
   (set_attr "length" "2,*")
5287
   (set_attr "fptype" "*,double")])
5288
 
5289
(define_insn "*and3_sp64"
5290
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5291
        (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5292
                  (match_operand:V64I 2 "arith_operand" "rI,b")))]
5293
  "TARGET_ARCH64"
5294
  "@
5295
   and\t%1, %2, %0
5296
   fand\t%1, %2, %0"
5297
  [(set_attr "type" "*,fga")
5298
   (set_attr "fptype" "*,double")])
5299
 
5300
(define_insn "and3"
5301
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5302
        (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5303
                  (match_operand:V32I 2 "arith_operand" "rI,d")))]
5304
  ""
5305
  "@
5306
   and\t%1, %2, %0
5307
   fands\t%1, %2, %0"
5308
  [(set_attr "type" "*,fga")
5309
   (set_attr "fptype" "*,single")])
5310
 
5311
(define_split
5312
  [(set (match_operand:SI 0 "register_operand" "")
5313
        (and:SI (match_operand:SI 1 "register_operand" "")
5314
                (match_operand:SI 2 "const_compl_high_operand" "")))
5315
   (clobber (match_operand:SI 3 "register_operand" ""))]
5316
  ""
5317
  [(set (match_dup 3) (match_dup 4))
5318
   (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5319
{
5320
  operands[4] = GEN_INT (~INTVAL (operands[2]));
5321
})
5322
 
5323
(define_insn_and_split "*and_not__sp32"
5324
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5325
        (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5326
                  (match_operand:V64I 2 "register_operand" "r,b")))]
5327
  "! TARGET_ARCH64"
5328
  "@
5329
   #
5330
   fandnot1\t%1, %2, %0"
5331
  "&& reload_completed
5332
   && ((GET_CODE (operands[0]) == REG
5333
        && REGNO (operands[0]) < 32)
5334
       || (GET_CODE (operands[0]) == SUBREG
5335
           && GET_CODE (SUBREG_REG (operands[0])) == REG
5336
           && REGNO (SUBREG_REG (operands[0])) < 32))"
5337
  [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5338
   (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5339
  "operands[3] = gen_highpart (SImode, operands[0]);
5340
   operands[4] = gen_highpart (SImode, operands[1]);
5341
   operands[5] = gen_highpart (SImode, operands[2]);
5342
   operands[6] = gen_lowpart (SImode, operands[0]);
5343
   operands[7] = gen_lowpart (SImode, operands[1]);
5344
   operands[8] = gen_lowpart (SImode, operands[2]);"
5345
  [(set_attr "type" "*,fga")
5346
   (set_attr "length" "2,*")
5347
   (set_attr "fptype" "*,double")])
5348
 
5349
(define_insn "*and_not__sp64"
5350
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5351
        (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5352
                  (match_operand:V64I 2 "register_operand" "r,b")))]
5353
  "TARGET_ARCH64"
5354
  "@
5355
   andn\t%2, %1, %0
5356
   fandnot1\t%1, %2, %0"
5357
  [(set_attr "type" "*,fga")
5358
   (set_attr "fptype" "*,double")])
5359
 
5360
(define_insn "*and_not_"
5361
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5362
        (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5363
                  (match_operand:V32I 2 "register_operand" "r,d")))]
5364
  ""
5365
  "@
5366
   andn\t%2, %1, %0
5367
   fandnot1s\t%1, %2, %0"
5368
  [(set_attr "type" "*,fga")
5369
   (set_attr "fptype" "*,single")])
5370
 
5371
(define_expand "ior3"
5372
  [(set (match_operand:V64I 0 "register_operand" "")
5373
        (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5374
                  (match_operand:V64I 2 "arith_double_operand" "")))]
5375
  ""
5376
  "")
5377
 
5378
(define_insn "*ior3_sp32"
5379
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5380
        (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5381
                  (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5382
  "! TARGET_ARCH64"
5383
  "@
5384
  #
5385
  for\t%1, %2, %0"
5386
  [(set_attr "type" "*,fga")
5387
   (set_attr "length" "2,*")
5388
   (set_attr "fptype" "*,double")])
5389
 
5390
(define_insn "*ior3_sp64"
5391
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5392
        (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5393
                  (match_operand:V64I 2 "arith_operand" "rI,b")))]
5394
  "TARGET_ARCH64"
5395
  "@
5396
  or\t%1, %2, %0
5397
  for\t%1, %2, %0"
5398
  [(set_attr "type" "*,fga")
5399
   (set_attr "fptype" "*,double")])
5400
 
5401
(define_insn "ior3"
5402
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5403
        (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5404
                  (match_operand:V32I 2 "arith_operand" "rI,d")))]
5405
  ""
5406
  "@
5407
   or\t%1, %2, %0
5408
   fors\t%1, %2, %0"
5409
  [(set_attr "type" "*,fga")
5410
   (set_attr "fptype" "*,single")])
5411
 
5412
(define_split
5413
  [(set (match_operand:SI 0 "register_operand" "")
5414
        (ior:SI (match_operand:SI 1 "register_operand" "")
5415
                (match_operand:SI 2 "const_compl_high_operand" "")))
5416
   (clobber (match_operand:SI 3 "register_operand" ""))]
5417
  ""
5418
  [(set (match_dup 3) (match_dup 4))
5419
   (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5420
{
5421
  operands[4] = GEN_INT (~INTVAL (operands[2]));
5422
})
5423
 
5424
(define_insn_and_split "*or_not__sp32"
5425
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5426
        (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5427
                  (match_operand:V64I 2 "register_operand" "r,b")))]
5428
  "! TARGET_ARCH64"
5429
  "@
5430
   #
5431
   fornot1\t%1, %2, %0"
5432
  "&& reload_completed
5433
   && ((GET_CODE (operands[0]) == REG
5434
        && REGNO (operands[0]) < 32)
5435
       || (GET_CODE (operands[0]) == SUBREG
5436
           && GET_CODE (SUBREG_REG (operands[0])) == REG
5437
           && REGNO (SUBREG_REG (operands[0])) < 32))"
5438
  [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5439
   (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5440
  "operands[3] = gen_highpart (SImode, operands[0]);
5441
   operands[4] = gen_highpart (SImode, operands[1]);
5442
   operands[5] = gen_highpart (SImode, operands[2]);
5443
   operands[6] = gen_lowpart (SImode, operands[0]);
5444
   operands[7] = gen_lowpart (SImode, operands[1]);
5445
   operands[8] = gen_lowpart (SImode, operands[2]);"
5446
  [(set_attr "type" "*,fga")
5447
   (set_attr "length" "2,*")
5448
   (set_attr "fptype" "*,double")])
5449
 
5450
(define_insn "*or_not__sp64"
5451
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5452
        (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5453
                  (match_operand:V64I 2 "register_operand" "r,b")))]
5454
  "TARGET_ARCH64"
5455
  "@
5456
  orn\t%2, %1, %0
5457
  fornot1\t%1, %2, %0"
5458
  [(set_attr "type" "*,fga")
5459
   (set_attr "fptype" "*,double")])
5460
 
5461
(define_insn "*or_not_"
5462
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5463
        (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5464
                  (match_operand:V32I 2 "register_operand" "r,d")))]
5465
  ""
5466
  "@
5467
   orn\t%2, %1, %0
5468
   fornot1s\t%1, %2, %0"
5469
  [(set_attr "type" "*,fga")
5470
   (set_attr "fptype" "*,single")])
5471
 
5472
(define_expand "xor3"
5473
  [(set (match_operand:V64I 0 "register_operand" "")
5474
        (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5475
                  (match_operand:V64I 2 "arith_double_operand" "")))]
5476
  ""
5477
  "")
5478
 
5479
(define_insn "*xor3_sp32"
5480
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5481
        (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5482
                  (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5483
  "! TARGET_ARCH64"
5484
  "@
5485
  #
5486
  fxor\t%1, %2, %0"
5487
  [(set_attr "type" "*,fga")
5488
   (set_attr "length" "2,*")
5489
   (set_attr "fptype" "*,double")])
5490
 
5491
(define_insn "*xor3_sp64"
5492
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5493
        (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5494
                  (match_operand:V64I 2 "arith_operand" "rI,b")))]
5495
  "TARGET_ARCH64"
5496
  "@
5497
  xor\t%r1, %2, %0
5498
  fxor\t%1, %2, %0"
5499
  [(set_attr "type" "*,fga")
5500
   (set_attr "fptype" "*,double")])
5501
 
5502
(define_insn "xor3"
5503
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5504
        (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5505
                  (match_operand:V32I 2 "arith_operand" "rI,d")))]
5506
  ""
5507
  "@
5508
   xor\t%r1, %2, %0
5509
   fxors\t%1, %2, %0"
5510
  [(set_attr "type" "*,fga")
5511
   (set_attr "fptype" "*,single")])
5512
 
5513
(define_split
5514
  [(set (match_operand:SI 0 "register_operand" "")
5515
        (xor:SI (match_operand:SI 1 "register_operand" "")
5516
                (match_operand:SI 2 "const_compl_high_operand" "")))
5517
   (clobber (match_operand:SI 3 "register_operand" ""))]
5518
   ""
5519
  [(set (match_dup 3) (match_dup 4))
5520
   (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5521
{
5522
  operands[4] = GEN_INT (~INTVAL (operands[2]));
5523
})
5524
 
5525
(define_split
5526
  [(set (match_operand:SI 0 "register_operand" "")
5527
        (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5528
                        (match_operand:SI 2 "const_compl_high_operand" ""))))
5529
   (clobber (match_operand:SI 3 "register_operand" ""))]
5530
  ""
5531
  [(set (match_dup 3) (match_dup 4))
5532
   (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5533
{
5534
  operands[4] = GEN_INT (~INTVAL (operands[2]));
5535
})
5536
 
5537
;; Split DImode logical operations requiring two instructions.
5538
(define_split
5539
  [(set (match_operand:V64I 0 "register_operand" "")
5540
        (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5541
                           [(match_operand:V64I 2 "register_operand" "")
5542
                            (match_operand:V64I 3 "arith_double_operand" "")]))]
5543
  "! TARGET_ARCH64
5544
   && reload_completed
5545
   && ((GET_CODE (operands[0]) == REG
5546
        && REGNO (operands[0]) < 32)
5547
       || (GET_CODE (operands[0]) == SUBREG
5548
           && GET_CODE (SUBREG_REG (operands[0])) == REG
5549
           && REGNO (SUBREG_REG (operands[0])) < 32))"
5550
  [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5551
   (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5552
{
5553
  operands[4] = gen_highpart (SImode, operands[0]);
5554
  operands[5] = gen_lowpart (SImode, operands[0]);
5555
  operands[6] = gen_highpart (SImode, operands[2]);
5556
  operands[7] = gen_lowpart (SImode, operands[2]);
5557
#if HOST_BITS_PER_WIDE_INT == 32
5558
  if (GET_CODE (operands[3]) == CONST_INT && mode == DImode)
5559
    {
5560
      if (INTVAL (operands[3]) < 0)
5561
        operands[8] = constm1_rtx;
5562
      else
5563
        operands[8] = const0_rtx;
5564
    }
5565
  else
5566
#endif
5567
    operands[8] = gen_highpart_mode (SImode, mode, operands[3]);
5568
  operands[9] = gen_lowpart (SImode, operands[3]);
5569
})
5570
 
5571
;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5572
;; Combine now canonicalizes to the rightmost expression.
5573
(define_insn_and_split "*xor_not__sp32"
5574
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5575
        (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5576
                            (match_operand:V64I 2 "register_operand" "r,b"))))]
5577
  "! TARGET_ARCH64"
5578
  "@
5579
   #
5580
   fxnor\t%1, %2, %0"
5581
  "&& reload_completed
5582
   && ((GET_CODE (operands[0]) == REG
5583
        && REGNO (operands[0]) < 32)
5584
       || (GET_CODE (operands[0]) == SUBREG
5585
           && GET_CODE (SUBREG_REG (operands[0])) == REG
5586
           && REGNO (SUBREG_REG (operands[0])) < 32))"
5587
  [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5588
   (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5589
  "operands[3] = gen_highpart (SImode, operands[0]);
5590
   operands[4] = gen_highpart (SImode, operands[1]);
5591
   operands[5] = gen_highpart (SImode, operands[2]);
5592
   operands[6] = gen_lowpart (SImode, operands[0]);
5593
   operands[7] = gen_lowpart (SImode, operands[1]);
5594
   operands[8] = gen_lowpart (SImode, operands[2]);"
5595
  [(set_attr "type" "*,fga")
5596
   (set_attr "length" "2,*")
5597
   (set_attr "fptype" "*,double")])
5598
 
5599
(define_insn "*xor_not__sp64"
5600
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5601
        (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5602
                            (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5603
  "TARGET_ARCH64"
5604
  "@
5605
  xnor\t%r1, %2, %0
5606
  fxnor\t%1, %2, %0"
5607
  [(set_attr "type" "*,fga")
5608
   (set_attr "fptype" "*,double")])
5609
 
5610
(define_insn "*xor_not_"
5611
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5612
        (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5613
                            (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5614
  ""
5615
  "@
5616
   xnor\t%r1, %2, %0
5617
   fxnors\t%1, %2, %0"
5618
  [(set_attr "type" "*,fga")
5619
   (set_attr "fptype" "*,single")])
5620
 
5621
;; These correspond to the above in the case where we also (or only)
5622
;; want to set the condition code.
5623
 
5624
(define_insn "*cmp_cc_arith_op"
5625
  [(set (reg:CC 100)
5626
        (compare:CC
5627
         (match_operator:SI 2 "cc_arith_operator"
5628
                            [(match_operand:SI 0 "arith_operand" "%r")
5629
                             (match_operand:SI 1 "arith_operand" "rI")])
5630
         (const_int 0)))]
5631
  ""
5632
  "%A2cc\t%0, %1, %%g0"
5633
  [(set_attr "type" "compare")])
5634
 
5635
(define_insn "*cmp_ccx_arith_op"
5636
  [(set (reg:CCX 100)
5637
        (compare:CCX
5638
         (match_operator:DI 2 "cc_arith_operator"
5639
                            [(match_operand:DI 0 "arith_operand" "%r")
5640
                             (match_operand:DI 1 "arith_operand" "rI")])
5641
         (const_int 0)))]
5642
  "TARGET_ARCH64"
5643
  "%A2cc\t%0, %1, %%g0"
5644
  [(set_attr "type" "compare")])
5645
 
5646
(define_insn "*cmp_cc_arith_op_set"
5647
  [(set (reg:CC 100)
5648
        (compare:CC
5649
         (match_operator:SI 3 "cc_arith_operator"
5650
                            [(match_operand:SI 1 "arith_operand" "%r")
5651
                             (match_operand:SI 2 "arith_operand" "rI")])
5652
         (const_int 0)))
5653
   (set (match_operand:SI 0 "register_operand" "=r")
5654
        (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5655
  "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5656
  "%A3cc\t%1, %2, %0"
5657
  [(set_attr "type" "compare")])
5658
 
5659
(define_insn "*cmp_ccx_arith_op_set"
5660
  [(set (reg:CCX 100)
5661
        (compare:CCX
5662
         (match_operator:DI 3 "cc_arith_operator"
5663
                            [(match_operand:DI 1 "arith_operand" "%r")
5664
                             (match_operand:DI 2 "arith_operand" "rI")])
5665
         (const_int 0)))
5666
   (set (match_operand:DI 0 "register_operand" "=r")
5667
        (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5668
  "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5669
  "%A3cc\t%1, %2, %0"
5670
  [(set_attr "type" "compare")])
5671
 
5672
(define_insn "*cmp_cc_xor_not"
5673
  [(set (reg:CC 100)
5674
        (compare:CC
5675
         (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5676
                         (match_operand:SI 1 "arith_operand" "rI")))
5677
         (const_int 0)))]
5678
  ""
5679
  "xnorcc\t%r0, %1, %%g0"
5680
  [(set_attr "type" "compare")])
5681
 
5682
(define_insn "*cmp_ccx_xor_not"
5683
  [(set (reg:CCX 100)
5684
        (compare:CCX
5685
         (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5686
                         (match_operand:DI 1 "arith_operand" "rI")))
5687
         (const_int 0)))]
5688
  "TARGET_ARCH64"
5689
  "xnorcc\t%r0, %1, %%g0"
5690
  [(set_attr "type" "compare")])
5691
 
5692
(define_insn "*cmp_cc_xor_not_set"
5693
  [(set (reg:CC 100)
5694
        (compare:CC
5695
         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5696
                         (match_operand:SI 2 "arith_operand" "rI")))
5697
         (const_int 0)))
5698
   (set (match_operand:SI 0 "register_operand" "=r")
5699
        (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5700
  ""
5701
  "xnorcc\t%r1, %2, %0"
5702
  [(set_attr "type" "compare")])
5703
 
5704
(define_insn "*cmp_ccx_xor_not_set"
5705
  [(set (reg:CCX 100)
5706
        (compare:CCX
5707
         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5708
                         (match_operand:DI 2 "arith_operand" "rI")))
5709
         (const_int 0)))
5710
   (set (match_operand:DI 0 "register_operand" "=r")
5711
        (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5712
  "TARGET_ARCH64"
5713
  "xnorcc\t%r1, %2, %0"
5714
  [(set_attr "type" "compare")])
5715
 
5716
(define_insn "*cmp_cc_arith_op_not"
5717
  [(set (reg:CC 100)
5718
        (compare:CC
5719
         (match_operator:SI 2 "cc_arith_not_operator"
5720
                            [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5721
                             (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5722
         (const_int 0)))]
5723
  ""
5724
  "%B2cc\t%r1, %0, %%g0"
5725
  [(set_attr "type" "compare")])
5726
 
5727
(define_insn "*cmp_ccx_arith_op_not"
5728
  [(set (reg:CCX 100)
5729
        (compare:CCX
5730
         (match_operator:DI 2 "cc_arith_not_operator"
5731
                            [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5732
                             (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5733
         (const_int 0)))]
5734
  "TARGET_ARCH64"
5735
  "%B2cc\t%r1, %0, %%g0"
5736
  [(set_attr "type" "compare")])
5737
 
5738
(define_insn "*cmp_cc_arith_op_not_set"
5739
  [(set (reg:CC 100)
5740
        (compare:CC
5741
         (match_operator:SI 3 "cc_arith_not_operator"
5742
                            [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5743
                             (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5744
         (const_int 0)))
5745
   (set (match_operand:SI 0 "register_operand" "=r")
5746
        (match_operator:SI 4 "cc_arith_not_operator"
5747
                            [(not:SI (match_dup 1)) (match_dup 2)]))]
5748
  "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5749
  "%B3cc\t%r2, %1, %0"
5750
  [(set_attr "type" "compare")])
5751
 
5752
(define_insn "*cmp_ccx_arith_op_not_set"
5753
  [(set (reg:CCX 100)
5754
        (compare:CCX
5755
         (match_operator:DI 3 "cc_arith_not_operator"
5756
                            [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5757
                             (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5758
         (const_int 0)))
5759
   (set (match_operand:DI 0 "register_operand" "=r")
5760
        (match_operator:DI 4 "cc_arith_not_operator"
5761
                            [(not:DI (match_dup 1)) (match_dup 2)]))]
5762
  "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5763
  "%B3cc\t%r2, %1, %0"
5764
  [(set_attr "type" "compare")])
5765
 
5766
;; We cannot use the "neg" pseudo insn because the Sun assembler
5767
;; does not know how to make it work for constants.
5768
 
5769
(define_expand "negdi2"
5770
  [(set (match_operand:DI 0 "register_operand" "=r")
5771
        (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5772
  ""
5773
{
5774
  if (! TARGET_ARCH64)
5775
    {
5776
      emit_insn (gen_rtx_PARALLEL
5777
                 (VOIDmode,
5778
                  gen_rtvec (2,
5779
                             gen_rtx_SET (VOIDmode, operand0,
5780
                                          gen_rtx_NEG (DImode, operand1)),
5781
                             gen_rtx_CLOBBER (VOIDmode,
5782
                                              gen_rtx_REG (CCmode,
5783
                                                           SPARC_ICC_REG)))));
5784
      DONE;
5785
    }
5786
})
5787
 
5788
(define_insn_and_split "*negdi2_sp32"
5789
  [(set (match_operand:DI 0 "register_operand" "=r")
5790
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
5791
   (clobber (reg:CC 100))]
5792
  "TARGET_ARCH32"
5793
  "#"
5794
  "&& reload_completed"
5795
  [(parallel [(set (reg:CC_NOOV 100)
5796
                   (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5797
                                    (const_int 0)))
5798
              (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5799
   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5800
                                (ltu:SI (reg:CC 100) (const_int 0))))]
5801
  "operands[2] = gen_highpart (SImode, operands[0]);
5802
   operands[3] = gen_highpart (SImode, operands[1]);
5803
   operands[4] = gen_lowpart (SImode, operands[0]);
5804
   operands[5] = gen_lowpart (SImode, operands[1]);"
5805
  [(set_attr "length" "2")])
5806
 
5807
(define_insn "*negdi2_sp64"
5808
  [(set (match_operand:DI 0 "register_operand" "=r")
5809
        (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5810
  "TARGET_ARCH64"
5811
  "sub\t%%g0, %1, %0")
5812
 
5813
(define_insn "negsi2"
5814
  [(set (match_operand:SI 0 "register_operand" "=r")
5815
        (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5816
  ""
5817
  "sub\t%%g0, %1, %0")
5818
 
5819
(define_insn "*cmp_cc_neg"
5820
  [(set (reg:CC_NOOV 100)
5821
        (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5822
                         (const_int 0)))]
5823
  ""
5824
  "subcc\t%%g0, %0, %%g0"
5825
  [(set_attr "type" "compare")])
5826
 
5827
(define_insn "*cmp_ccx_neg"
5828
  [(set (reg:CCX_NOOV 100)
5829
        (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5830
                          (const_int 0)))]
5831
  "TARGET_ARCH64"
5832
  "subcc\t%%g0, %0, %%g0"
5833
  [(set_attr "type" "compare")])
5834
 
5835
(define_insn "*cmp_cc_set_neg"
5836
  [(set (reg:CC_NOOV 100)
5837
        (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5838
                         (const_int 0)))
5839
   (set (match_operand:SI 0 "register_operand" "=r")
5840
        (neg:SI (match_dup 1)))]
5841
  ""
5842
  "subcc\t%%g0, %1, %0"
5843
  [(set_attr "type" "compare")])
5844
 
5845
(define_insn "*cmp_ccx_set_neg"
5846
  [(set (reg:CCX_NOOV 100)
5847
        (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5848
                          (const_int 0)))
5849
   (set (match_operand:DI 0 "register_operand" "=r")
5850
        (neg:DI (match_dup 1)))]
5851
  "TARGET_ARCH64"
5852
  "subcc\t%%g0, %1, %0"
5853
  [(set_attr "type" "compare")])
5854
 
5855
;; We cannot use the "not" pseudo insn because the Sun assembler
5856
;; does not know how to make it work for constants.
5857
(define_expand "one_cmpl2"
5858
  [(set (match_operand:V64I 0 "register_operand" "")
5859
        (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5860
  ""
5861
  "")
5862
 
5863
(define_insn_and_split "*one_cmpl2_sp32"
5864
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5865
        (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5866
  "! TARGET_ARCH64"
5867
  "@
5868
   #
5869
   fnot1\t%1, %0"
5870
  "&& reload_completed
5871
   && ((GET_CODE (operands[0]) == REG
5872
        && REGNO (operands[0]) < 32)
5873
       || (GET_CODE (operands[0]) == SUBREG
5874
           && GET_CODE (SUBREG_REG (operands[0])) == REG
5875
           && REGNO (SUBREG_REG (operands[0])) < 32))"
5876
  [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5877
   (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5878
  "operands[2] = gen_highpart (SImode, operands[0]);
5879
   operands[3] = gen_highpart (SImode, operands[1]);
5880
   operands[4] = gen_lowpart (SImode, operands[0]);
5881
   operands[5] = gen_lowpart (SImode, operands[1]);"
5882
  [(set_attr "type" "*,fga")
5883
   (set_attr "length" "2,*")
5884
   (set_attr "fptype" "*,double")])
5885
 
5886
(define_insn "*one_cmpl2_sp64"
5887
  [(set (match_operand:V64I 0 "register_operand" "=r,b")
5888
        (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5889
  "TARGET_ARCH64"
5890
  "@
5891
   xnor\t%%g0, %1, %0
5892
   fnot1\t%1, %0"
5893
  [(set_attr "type" "*,fga")
5894
   (set_attr "fptype" "*,double")])
5895
 
5896
(define_insn "one_cmpl2"
5897
  [(set (match_operand:V32I 0 "register_operand" "=r,d")
5898
        (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5899
  ""
5900
  "@
5901
  xnor\t%%g0, %1, %0
5902
  fnot1s\t%1, %0"
5903
  [(set_attr "type" "*,fga")
5904
   (set_attr "fptype" "*,single")])
5905
 
5906
(define_insn "*cmp_cc_not"
5907
  [(set (reg:CC 100)
5908
        (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5909
                    (const_int 0)))]
5910
  ""
5911
  "xnorcc\t%%g0, %0, %%g0"
5912
  [(set_attr "type" "compare")])
5913
 
5914
(define_insn "*cmp_ccx_not"
5915
  [(set (reg:CCX 100)
5916
        (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5917
                     (const_int 0)))]
5918
  "TARGET_ARCH64"
5919
  "xnorcc\t%%g0, %0, %%g0"
5920
  [(set_attr "type" "compare")])
5921
 
5922
(define_insn "*cmp_cc_set_not"
5923
  [(set (reg:CC 100)
5924
        (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5925
                    (const_int 0)))
5926
   (set (match_operand:SI 0 "register_operand" "=r")
5927
        (not:SI (match_dup 1)))]
5928
  ""
5929
  "xnorcc\t%%g0, %1, %0"
5930
  [(set_attr "type" "compare")])
5931
 
5932
(define_insn "*cmp_ccx_set_not"
5933
  [(set (reg:CCX 100)
5934
        (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5935
                    (const_int 0)))
5936
   (set (match_operand:DI 0 "register_operand" "=r")
5937
        (not:DI (match_dup 1)))]
5938
  "TARGET_ARCH64"
5939
  "xnorcc\t%%g0, %1, %0"
5940
  [(set_attr "type" "compare")])
5941
 
5942
(define_insn "*cmp_cc_set"
5943
  [(set (match_operand:SI 0 "register_operand" "=r")
5944
        (match_operand:SI 1 "register_operand" "r"))
5945
   (set (reg:CC 100)
5946
        (compare:CC (match_dup 1)
5947
                    (const_int 0)))]
5948
  ""
5949
  "orcc\t%1, 0, %0"
5950
  [(set_attr "type" "compare")])
5951
 
5952
(define_insn "*cmp_ccx_set64"
5953
  [(set (match_operand:DI 0 "register_operand" "=r")
5954
        (match_operand:DI 1 "register_operand" "r"))
5955
   (set (reg:CCX 100)
5956
        (compare:CCX (match_dup 1)
5957
                     (const_int 0)))]
5958
  "TARGET_ARCH64"
5959
  "orcc\t%1, 0, %0"
5960
   [(set_attr "type" "compare")])
5961
 
5962
 
5963
;; Floating point arithmetic instructions.
5964
 
5965
(define_expand "addtf3"
5966
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
5967
        (plus:TF (match_operand:TF 1 "general_operand" "")
5968
                 (match_operand:TF 2 "general_operand" "")))]
5969
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5970
  "emit_tfmode_binop (PLUS, operands); DONE;")
5971
 
5972
(define_insn "*addtf3_hq"
5973
  [(set (match_operand:TF 0 "register_operand" "=e")
5974
        (plus:TF (match_operand:TF 1 "register_operand" "e")
5975
                 (match_operand:TF 2 "register_operand" "e")))]
5976
  "TARGET_FPU && TARGET_HARD_QUAD"
5977
  "faddq\t%1, %2, %0"
5978
  [(set_attr "type" "fp")])
5979
 
5980
(define_insn "adddf3"
5981
  [(set (match_operand:DF 0 "register_operand" "=e")
5982
        (plus:DF (match_operand:DF 1 "register_operand" "e")
5983
                 (match_operand:DF 2 "register_operand" "e")))]
5984
  "TARGET_FPU"
5985
  "faddd\t%1, %2, %0"
5986
  [(set_attr "type" "fp")
5987
   (set_attr "fptype" "double")])
5988
 
5989
(define_insn "addsf3"
5990
  [(set (match_operand:SF 0 "register_operand" "=f")
5991
        (plus:SF (match_operand:SF 1 "register_operand" "f")
5992
                 (match_operand:SF 2 "register_operand" "f")))]
5993
  "TARGET_FPU"
5994
  "fadds\t%1, %2, %0"
5995
  [(set_attr "type" "fp")])
5996
 
5997
(define_expand "subtf3"
5998
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
5999
        (minus:TF (match_operand:TF 1 "general_operand" "")
6000
                  (match_operand:TF 2 "general_operand" "")))]
6001
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6002
  "emit_tfmode_binop (MINUS, operands); DONE;")
6003
 
6004
(define_insn "*subtf3_hq"
6005
  [(set (match_operand:TF 0 "register_operand" "=e")
6006
        (minus:TF (match_operand:TF 1 "register_operand" "e")
6007
                  (match_operand:TF 2 "register_operand" "e")))]
6008
  "TARGET_FPU && TARGET_HARD_QUAD"
6009
  "fsubq\t%1, %2, %0"
6010
  [(set_attr "type" "fp")])
6011
 
6012
(define_insn "subdf3"
6013
  [(set (match_operand:DF 0 "register_operand" "=e")
6014
        (minus:DF (match_operand:DF 1 "register_operand" "e")
6015
                  (match_operand:DF 2 "register_operand" "e")))]
6016
  "TARGET_FPU"
6017
  "fsubd\t%1, %2, %0"
6018
  [(set_attr "type" "fp")
6019
   (set_attr "fptype" "double")])
6020
 
6021
(define_insn "subsf3"
6022
  [(set (match_operand:SF 0 "register_operand" "=f")
6023
        (minus:SF (match_operand:SF 1 "register_operand" "f")
6024
                  (match_operand:SF 2 "register_operand" "f")))]
6025
  "TARGET_FPU"
6026
  "fsubs\t%1, %2, %0"
6027
  [(set_attr "type" "fp")])
6028
 
6029
(define_expand "multf3"
6030
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
6031
        (mult:TF (match_operand:TF 1 "general_operand" "")
6032
                 (match_operand:TF 2 "general_operand" "")))]
6033
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6034
  "emit_tfmode_binop (MULT, operands); DONE;")
6035
 
6036
(define_insn "*multf3_hq"
6037
  [(set (match_operand:TF 0 "register_operand" "=e")
6038
        (mult:TF (match_operand:TF 1 "register_operand" "e")
6039
                 (match_operand:TF 2 "register_operand" "e")))]
6040
  "TARGET_FPU && TARGET_HARD_QUAD"
6041
  "fmulq\t%1, %2, %0"
6042
  [(set_attr "type" "fpmul")])
6043
 
6044
(define_insn "muldf3"
6045
  [(set (match_operand:DF 0 "register_operand" "=e")
6046
        (mult:DF (match_operand:DF 1 "register_operand" "e")
6047
                 (match_operand:DF 2 "register_operand" "e")))]
6048
  "TARGET_FPU"
6049
  "fmuld\t%1, %2, %0"
6050
  [(set_attr "type" "fpmul")
6051
   (set_attr "fptype" "double")])
6052
 
6053
(define_insn "mulsf3"
6054
  [(set (match_operand:SF 0 "register_operand" "=f")
6055
        (mult:SF (match_operand:SF 1 "register_operand" "f")
6056
                 (match_operand:SF 2 "register_operand" "f")))]
6057
  "TARGET_FPU"
6058
  "fmuls\t%1, %2, %0"
6059
  [(set_attr "type" "fpmul")])
6060
 
6061
(define_insn "*muldf3_extend"
6062
  [(set (match_operand:DF 0 "register_operand" "=e")
6063
        (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6064
                 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6065
  "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6066
  "fsmuld\t%1, %2, %0"
6067
  [(set_attr "type" "fpmul")
6068
   (set_attr "fptype" "double")])
6069
 
6070
(define_insn "*multf3_extend"
6071
  [(set (match_operand:TF 0 "register_operand" "=e")
6072
        (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6073
                 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6074
  "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6075
  "fdmulq\t%1, %2, %0"
6076
  [(set_attr "type" "fpmul")])
6077
 
6078
(define_expand "divtf3"
6079
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
6080
        (div:TF (match_operand:TF 1 "general_operand" "")
6081
                (match_operand:TF 2 "general_operand" "")))]
6082
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6083
  "emit_tfmode_binop (DIV, operands); DONE;")
6084
 
6085
;; don't have timing for quad-prec. divide.
6086
(define_insn "*divtf3_hq"
6087
  [(set (match_operand:TF 0 "register_operand" "=e")
6088
        (div:TF (match_operand:TF 1 "register_operand" "e")
6089
                (match_operand:TF 2 "register_operand" "e")))]
6090
  "TARGET_FPU && TARGET_HARD_QUAD"
6091
  "fdivq\t%1, %2, %0"
6092
  [(set_attr "type" "fpdivd")])
6093
 
6094
(define_insn "divdf3"
6095
  [(set (match_operand:DF 0 "register_operand" "=e")
6096
        (div:DF (match_operand:DF 1 "register_operand" "e")
6097
                (match_operand:DF 2 "register_operand" "e")))]
6098
  "TARGET_FPU"
6099
  "fdivd\t%1, %2, %0"
6100
  [(set_attr "type" "fpdivd")
6101
   (set_attr "fptype" "double")])
6102
 
6103
(define_insn "divsf3"
6104
  [(set (match_operand:SF 0 "register_operand" "=f")
6105
        (div:SF (match_operand:SF 1 "register_operand" "f")
6106
                (match_operand:SF 2 "register_operand" "f")))]
6107
  "TARGET_FPU"
6108
  "fdivs\t%1, %2, %0"
6109
  [(set_attr "type" "fpdivs")])
6110
 
6111
(define_expand "negtf2"
6112
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6113
        (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6114
  "TARGET_FPU"
6115
  "")
6116
 
6117
(define_insn_and_split "*negtf2_notv9"
6118
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6119
        (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6120
  ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6121
  "TARGET_FPU
6122
   && ! TARGET_V9"
6123
  "@
6124
  fnegs\t%0, %0
6125
  #"
6126
  "&& reload_completed
6127
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6128
  [(set (match_dup 2) (neg:SF (match_dup 3)))
6129
   (set (match_dup 4) (match_dup 5))
6130
   (set (match_dup 6) (match_dup 7))]
6131
  "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6132
   operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6133
   operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6134
   operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6135
   operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6136
   operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6137
  [(set_attr "type" "fpmove,*")
6138
   (set_attr "length" "*,2")])
6139
 
6140
(define_insn_and_split "*negtf2_v9"
6141
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6142
        (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6143
  ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6144
  "TARGET_FPU && TARGET_V9"
6145
  "@
6146
  fnegd\t%0, %0
6147
  #"
6148
  "&& reload_completed
6149
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6150
  [(set (match_dup 2) (neg:DF (match_dup 3)))
6151
   (set (match_dup 4) (match_dup 5))]
6152
  "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6153
   operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6154
   operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6155
   operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6156
  [(set_attr "type" "fpmove,*")
6157
   (set_attr "length" "*,2")
6158
   (set_attr "fptype" "double")])
6159
 
6160
(define_expand "negdf2"
6161
  [(set (match_operand:DF 0 "register_operand" "")
6162
        (neg:DF (match_operand:DF 1 "register_operand" "")))]
6163
  "TARGET_FPU"
6164
  "")
6165
 
6166
(define_insn_and_split "*negdf2_notv9"
6167
  [(set (match_operand:DF 0 "register_operand" "=e,e")
6168
        (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6169
  "TARGET_FPU && ! TARGET_V9"
6170
  "@
6171
  fnegs\t%0, %0
6172
  #"
6173
  "&& reload_completed
6174
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6175
  [(set (match_dup 2) (neg:SF (match_dup 3)))
6176
   (set (match_dup 4) (match_dup 5))]
6177
  "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6178
   operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6179
   operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6180
   operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6181
  [(set_attr "type" "fpmove,*")
6182
   (set_attr "length" "*,2")])
6183
 
6184
(define_insn "*negdf2_v9"
6185
  [(set (match_operand:DF 0 "register_operand" "=e")
6186
        (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6187
  "TARGET_FPU && TARGET_V9"
6188
  "fnegd\t%1, %0"
6189
  [(set_attr "type" "fpmove")
6190
   (set_attr "fptype" "double")])
6191
 
6192
(define_insn "negsf2"
6193
  [(set (match_operand:SF 0 "register_operand" "=f")
6194
        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6195
  "TARGET_FPU"
6196
  "fnegs\t%1, %0"
6197
  [(set_attr "type" "fpmove")])
6198
 
6199
(define_expand "abstf2"
6200
  [(set (match_operand:TF 0 "register_operand" "")
6201
        (abs:TF (match_operand:TF 1 "register_operand" "")))]
6202
  "TARGET_FPU"
6203
  "")
6204
 
6205
(define_insn_and_split "*abstf2_notv9"
6206
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6207
        (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6208
  ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6209
  "TARGET_FPU && ! TARGET_V9"
6210
  "@
6211
  fabss\t%0, %0
6212
  #"
6213
  "&& reload_completed
6214
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6215
  [(set (match_dup 2) (abs:SF (match_dup 3)))
6216
   (set (match_dup 4) (match_dup 5))
6217
   (set (match_dup 6) (match_dup 7))]
6218
  "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6219
   operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6220
   operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6221
   operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6222
   operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6223
   operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6224
  [(set_attr "type" "fpmove,*")
6225
   (set_attr "length" "*,2")])
6226
 
6227
(define_insn "*abstf2_hq_v9"
6228
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6229
        (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6230
  "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6231
  "@
6232
  fabsd\t%0, %0
6233
  fabsq\t%1, %0"
6234
  [(set_attr "type" "fpmove")
6235
   (set_attr "fptype" "double,*")])
6236
 
6237
(define_insn_and_split "*abstf2_v9"
6238
  [(set (match_operand:TF 0 "register_operand" "=e,e")
6239
        (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6240
  "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6241
  "@
6242
  fabsd\t%0, %0
6243
  #"
6244
  "&& reload_completed
6245
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6246
  [(set (match_dup 2) (abs:DF (match_dup 3)))
6247
   (set (match_dup 4) (match_dup 5))]
6248
  "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6249
   operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6250
   operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6251
   operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6252
  [(set_attr "type" "fpmove,*")
6253
   (set_attr "length" "*,2")
6254
   (set_attr "fptype" "double,*")])
6255
 
6256
(define_expand "absdf2"
6257
  [(set (match_operand:DF 0 "register_operand" "")
6258
        (abs:DF (match_operand:DF 1 "register_operand" "")))]
6259
  "TARGET_FPU"
6260
  "")
6261
 
6262
(define_insn_and_split "*absdf2_notv9"
6263
  [(set (match_operand:DF 0 "register_operand" "=e,e")
6264
        (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6265
  "TARGET_FPU && ! TARGET_V9"
6266
  "@
6267
  fabss\t%0, %0
6268
  #"
6269
  "&& reload_completed
6270
   && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6271
  [(set (match_dup 2) (abs:SF (match_dup 3)))
6272
   (set (match_dup 4) (match_dup 5))]
6273
  "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6274
   operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6275
   operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6276
   operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6277
  [(set_attr "type" "fpmove,*")
6278
   (set_attr "length" "*,2")])
6279
 
6280
(define_insn "*absdf2_v9"
6281
  [(set (match_operand:DF 0 "register_operand" "=e")
6282
        (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6283
  "TARGET_FPU && TARGET_V9"
6284
  "fabsd\t%1, %0"
6285
  [(set_attr "type" "fpmove")
6286
   (set_attr "fptype" "double")])
6287
 
6288
(define_insn "abssf2"
6289
  [(set (match_operand:SF 0 "register_operand" "=f")
6290
        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6291
  "TARGET_FPU"
6292
  "fabss\t%1, %0"
6293
  [(set_attr "type" "fpmove")])
6294
 
6295
(define_expand "sqrttf2"
6296
  [(set (match_operand:TF 0 "nonimmediate_operand" "")
6297
        (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6298
  "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6299
  "emit_tfmode_unop (SQRT, operands); DONE;")
6300
 
6301
(define_insn "*sqrttf2_hq"
6302
  [(set (match_operand:TF 0 "register_operand" "=e")
6303
        (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6304
  "TARGET_FPU && TARGET_HARD_QUAD"
6305
  "fsqrtq\t%1, %0"
6306
  [(set_attr "type" "fpsqrtd")])
6307
 
6308
(define_insn "sqrtdf2"
6309
  [(set (match_operand:DF 0 "register_operand" "=e")
6310
        (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6311
  "TARGET_FPU"
6312
  "fsqrtd\t%1, %0"
6313
  [(set_attr "type" "fpsqrtd")
6314
   (set_attr "fptype" "double")])
6315
 
6316
(define_insn "sqrtsf2"
6317
  [(set (match_operand:SF 0 "register_operand" "=f")
6318
        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6319
  "TARGET_FPU"
6320
  "fsqrts\t%1, %0"
6321
  [(set_attr "type" "fpsqrts")])
6322
 
6323
 
6324
;; Arithmetic shift instructions.
6325
 
6326
(define_insn "ashlsi3"
6327
  [(set (match_operand:SI 0 "register_operand" "=r")
6328
        (ashift:SI (match_operand:SI 1 "register_operand" "r")
6329
                   (match_operand:SI 2 "arith_operand" "rI")))]
6330
  ""
6331
{
6332
  if (GET_CODE (operands[2]) == CONST_INT)
6333
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6334
  return "sll\t%1, %2, %0";
6335
}
6336
  [(set (attr "type")
6337
        (if_then_else (match_operand 2 "const_one_operand" "")
6338
                      (const_string "ialu") (const_string "shift")))])
6339
 
6340
(define_expand "ashldi3"
6341
  [(set (match_operand:DI 0 "register_operand" "=r")
6342
        (ashift:DI (match_operand:DI 1 "register_operand" "r")
6343
                   (match_operand:SI 2 "arith_operand" "rI")))]
6344
  "TARGET_ARCH64 || TARGET_V8PLUS"
6345
{
6346
  if (! TARGET_ARCH64)
6347
    {
6348
      if (GET_CODE (operands[2]) == CONST_INT)
6349
        FAIL;
6350
      emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6351
      DONE;
6352
    }
6353
})
6354
 
6355
(define_insn "*ashldi3_sp64"
6356
  [(set (match_operand:DI 0 "register_operand" "=r")
6357
        (ashift:DI (match_operand:DI 1 "register_operand" "r")
6358
                   (match_operand:SI 2 "arith_operand" "rI")))]
6359
  "TARGET_ARCH64"
6360
{
6361
  if (GET_CODE (operands[2]) == CONST_INT)
6362
    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6363
  return "sllx\t%1, %2, %0";
6364
}
6365
  [(set (attr "type")
6366
        (if_then_else (match_operand 2 "const_one_operand" "")
6367
                      (const_string "ialu") (const_string "shift")))])
6368
 
6369
;; XXX UGH!
6370
(define_insn "ashldi3_v8plus"
6371
  [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6372
        (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6373
                   (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6374
   (clobber (match_scratch:SI 3 "=X,X,&h"))]
6375
  "TARGET_V8PLUS"
6376
  "* return output_v8plus_shift (operands, insn, \"sllx\");"
6377
  [(set_attr "type" "multi")
6378
   (set_attr "length" "5,5,6")])
6379
 
6380
;; Optimize (1LL<
6381
;; XXX this also needs to be fixed to handle equal subregs
6382
;; XXX first before we could re-enable it.
6383
;(define_insn ""
6384
;  [(set (match_operand:DI 0 "register_operand" "=h")
6385
;       (plus:DI (ashift:DI (const_int 1)
6386
;                           (match_operand:SI 1 "arith_operand" "rI"))
6387
;                (const_int -1)))]
6388
;  "0 && TARGET_V8PLUS"
6389
;{
6390
;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6391
;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6392
;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6393
;}
6394
;  [(set_attr "type" "multi")
6395
;   (set_attr "length" "4")])
6396
 
6397
(define_insn "*cmp_cc_ashift_1"
6398
  [(set (reg:CC_NOOV 100)
6399
        (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6400
                                    (const_int 1))
6401
                         (const_int 0)))]
6402
  ""
6403
  "addcc\t%0, %0, %%g0"
6404
  [(set_attr "type" "compare")])
6405
 
6406
(define_insn "*cmp_cc_set_ashift_1"
6407
  [(set (reg:CC_NOOV 100)
6408
        (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6409
                                    (const_int 1))
6410
                         (const_int 0)))
6411
   (set (match_operand:SI 0 "register_operand" "=r")
6412
        (ashift:SI (match_dup 1) (const_int 1)))]
6413
  ""
6414
  "addcc\t%1, %1, %0"
6415
  [(set_attr "type" "compare")])
6416
 
6417
(define_insn "ashrsi3"
6418
  [(set (match_operand:SI 0 "register_operand" "=r")
6419
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6420
                     (match_operand:SI 2 "arith_operand" "rI")))]
6421
  ""
6422
  {
6423
     if (GET_CODE (operands[2]) == CONST_INT)
6424
       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6425
     return "sra\t%1, %2, %0";
6426
  }
6427
  [(set_attr "type" "shift")])
6428
 
6429
(define_insn "*ashrsi3_extend"
6430
  [(set (match_operand:DI 0 "register_operand" "=r")
6431
        (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6432
                                     (match_operand:SI 2 "arith_operand" "r"))))]
6433
  "TARGET_ARCH64"
6434
  "sra\t%1, %2, %0"
6435
  [(set_attr "type" "shift")])
6436
 
6437
;; This handles the case as above, but with constant shift instead of
6438
;; register. Combiner "simplifies" it for us a little bit though.
6439
(define_insn "*ashrsi3_extend2"
6440
  [(set (match_operand:DI 0 "register_operand" "=r")
6441
        (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6442
                                (const_int 32))
6443
                     (match_operand:SI 2 "small_int_operand" "I")))]
6444
  "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6445
{
6446
  operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6447
  return "sra\t%1, %2, %0";
6448
}
6449
  [(set_attr "type" "shift")])
6450
 
6451
(define_expand "ashrdi3"
6452
  [(set (match_operand:DI 0 "register_operand" "=r")
6453
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6454
                     (match_operand:SI 2 "arith_operand" "rI")))]
6455
  "TARGET_ARCH64 || TARGET_V8PLUS"
6456
{
6457
  if (! TARGET_ARCH64)
6458
    {
6459
      if (GET_CODE (operands[2]) == CONST_INT)
6460
        FAIL;   /* prefer generic code in this case */
6461
      emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6462
      DONE;
6463
    }
6464
})
6465
 
6466
(define_insn "*ashrdi3_sp64"
6467
  [(set (match_operand:DI 0 "register_operand" "=r")
6468
        (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6469
                     (match_operand:SI 2 "arith_operand" "rI")))]
6470
  "TARGET_ARCH64"
6471
 
6472
  {
6473
    if (GET_CODE (operands[2]) == CONST_INT)
6474
      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6475
    return "srax\t%1, %2, %0";
6476
  }
6477
  [(set_attr "type" "shift")])
6478
 
6479
;; XXX
6480
(define_insn "ashrdi3_v8plus"
6481
  [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6482
        (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6483
                     (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6484
   (clobber (match_scratch:SI 3 "=X,X,&h"))]
6485
  "TARGET_V8PLUS"
6486
  "* return output_v8plus_shift (operands, insn, \"srax\");"
6487
  [(set_attr "type" "multi")
6488
   (set_attr "length" "5,5,6")])
6489
 
6490
(define_insn "lshrsi3"
6491
  [(set (match_operand:SI 0 "register_operand" "=r")
6492
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6493
                     (match_operand:SI 2 "arith_operand" "rI")))]
6494
  ""
6495
  {
6496
    if (GET_CODE (operands[2]) == CONST_INT)
6497
      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6498
    return "srl\t%1, %2, %0";
6499
  }
6500
  [(set_attr "type" "shift")])
6501
 
6502
;; This handles the case where
6503
;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6504
;; but combiner "simplifies" it for us.
6505
(define_insn "*lshrsi3_extend"
6506
  [(set (match_operand:DI 0 "register_operand" "=r")
6507
        (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6508
                           (match_operand:SI 2 "arith_operand" "r")) 0)
6509
                (match_operand 3 "const_int_operand" "")))]
6510
  "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6511
  "srl\t%1, %2, %0"
6512
  [(set_attr "type" "shift")])
6513
 
6514
;; This handles the case where
6515
;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6516
;; but combiner "simplifies" it for us.
6517
(define_insn "*lshrsi3_extend2"
6518
  [(set (match_operand:DI 0 "register_operand" "=r")
6519
        (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6520
                         (match_operand 2 "small_int_operand" "I")
6521
                         (const_int 32)))]
6522
  "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6523
{
6524
  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6525
  return "srl\t%1, %2, %0";
6526
}
6527
  [(set_attr "type" "shift")])
6528
 
6529
(define_expand "lshrdi3"
6530
  [(set (match_operand:DI 0 "register_operand" "=r")
6531
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6532
                     (match_operand:SI 2 "arith_operand" "rI")))]
6533
  "TARGET_ARCH64 || TARGET_V8PLUS"
6534
{
6535
  if (! TARGET_ARCH64)
6536
    {
6537
      if (GET_CODE (operands[2]) == CONST_INT)
6538
        FAIL;
6539
      emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6540
      DONE;
6541
    }
6542
})
6543
 
6544
(define_insn "*lshrdi3_sp64"
6545
  [(set (match_operand:DI 0 "register_operand" "=r")
6546
        (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6547
                     (match_operand:SI 2 "arith_operand" "rI")))]
6548
  "TARGET_ARCH64"
6549
  {
6550
    if (GET_CODE (operands[2]) == CONST_INT)
6551
      operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6552
    return "srlx\t%1, %2, %0";
6553
  }
6554
  [(set_attr "type" "shift")])
6555
 
6556
;; XXX
6557
(define_insn "lshrdi3_v8plus"
6558
  [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6559
        (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6560
                     (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6561
   (clobber (match_scratch:SI 3 "=X,X,&h"))]
6562
  "TARGET_V8PLUS"
6563
  "* return output_v8plus_shift (operands, insn, \"srlx\");"
6564
  [(set_attr "type" "multi")
6565
   (set_attr "length" "5,5,6")])
6566
 
6567
(define_insn ""
6568
  [(set (match_operand:SI 0 "register_operand" "=r")
6569
        (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6570
                                             (const_int 32)) 4)
6571
                     (match_operand:SI 2 "small_int_operand" "I")))]
6572
  "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6573
{
6574
  operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6575
  return "srax\t%1, %2, %0";
6576
}
6577
  [(set_attr "type" "shift")])
6578
 
6579
(define_insn ""
6580
  [(set (match_operand:SI 0 "register_operand" "=r")
6581
        (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6582
                                             (const_int 32)) 4)
6583
                     (match_operand:SI 2 "small_int_operand" "I")))]
6584
  "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6585
{
6586
  operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6587
  return "srlx\t%1, %2, %0";
6588
}
6589
  [(set_attr "type" "shift")])
6590
 
6591
(define_insn ""
6592
  [(set (match_operand:SI 0 "register_operand" "=r")
6593
        (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6594
                                             (match_operand:SI 2 "small_int_operand" "I")) 4)
6595
                     (match_operand:SI 3 "small_int_operand" "I")))]
6596
  "TARGET_ARCH64
6597
   && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6598
   && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6599
   && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6600
{
6601
  operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6602
 
6603
  return "srax\t%1, %2, %0";
6604
}
6605
  [(set_attr "type" "shift")])
6606
 
6607
(define_insn ""
6608
  [(set (match_operand:SI 0 "register_operand" "=r")
6609
        (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6610
                                             (match_operand:SI 2 "small_int_operand" "I")) 4)
6611
                     (match_operand:SI 3 "small_int_operand" "I")))]
6612
  "TARGET_ARCH64
6613
   && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6614
   && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6615
   && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6616
{
6617
  operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6618
 
6619
  return "srlx\t%1, %2, %0";
6620
}
6621
  [(set_attr "type" "shift")])
6622
 
6623
 
6624
;; Unconditional and other jump instructions.
6625
 
6626
(define_insn "jump"
6627
  [(set (pc) (label_ref (match_operand 0 "" "")))]
6628
  ""
6629
  "* return output_ubranch (operands[0], 0, insn);"
6630
  [(set_attr "type" "uncond_branch")])
6631
 
6632
(define_expand "tablejump"
6633
  [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6634
              (use (label_ref (match_operand 1 "" "")))])]
6635
  ""
6636
{
6637
  gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6638
 
6639
  /* In pic mode, our address differences are against the base of the
6640
     table.  Add that base value back in; CSE ought to be able to combine
6641
     the two address loads.  */
6642
  if (flag_pic)
6643
    {
6644
      rtx tmp, tmp2;
6645
      tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6646
      tmp2 = operands[0];
6647
      if (CASE_VECTOR_MODE != Pmode)
6648
        tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6649
      tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6650
      operands[0] = memory_address (Pmode, tmp);
6651
    }
6652
})
6653
 
6654
(define_insn "*tablejump_sp32"
6655
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6656
   (use (label_ref (match_operand 1 "" "")))]
6657
  "! TARGET_ARCH64"
6658
  "jmp\t%a0%#"
6659
  [(set_attr "type" "uncond_branch")])
6660
 
6661
(define_insn "*tablejump_sp64"
6662
  [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6663
   (use (label_ref (match_operand 1 "" "")))]
6664
  "TARGET_ARCH64"
6665
  "jmp\t%a0%#"
6666
  [(set_attr "type" "uncond_branch")])
6667
 
6668
 
6669
;; Jump to subroutine instructions.
6670
 
6671
(define_expand "call"
6672
  ;; Note that this expression is not used for generating RTL.
6673
  ;; All the RTL is generated explicitly below.
6674
  [(call (match_operand 0 "call_operand" "")
6675
         (match_operand 3 "" "i"))]
6676
  ;; operands[2] is next_arg_register
6677
  ;; operands[3] is struct_value_size_rtx.
6678
  ""
6679
{
6680
  rtx fn_rtx;
6681
 
6682
  gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6683
 
6684
  gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6685
 
6686
  if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6687
    {
6688
      /* This is really a PIC sequence.  We want to represent
6689
         it as a funny jump so its delay slots can be filled.
6690
 
6691
         ??? But if this really *is* a CALL, will not it clobber the
6692
         call-clobbered registers?  We lose this if it is a JUMP_INSN.
6693
         Why cannot we have delay slots filled if it were a CALL?  */
6694
 
6695
      /* We accept negative sizes for untyped calls.  */
6696
      if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6697
        emit_jump_insn
6698
          (gen_rtx_PARALLEL
6699
           (VOIDmode,
6700
            gen_rtvec (3,
6701
                       gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6702
                       operands[3],
6703
                       gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6704
      else
6705
        emit_jump_insn
6706
          (gen_rtx_PARALLEL
6707
           (VOIDmode,
6708
            gen_rtvec (2,
6709
                       gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6710
                       gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6711
      goto finish_call;
6712
    }
6713
 
6714
  fn_rtx = operands[0];
6715
 
6716
  /* We accept negative sizes for untyped calls.  */
6717
  if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6718
    emit_call_insn
6719
      (gen_rtx_PARALLEL
6720
       (VOIDmode,
6721
        gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6722
                   operands[3],
6723
                   gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6724
  else
6725
    emit_call_insn
6726
      (gen_rtx_PARALLEL
6727
       (VOIDmode,
6728
        gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6729
                   gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6730
 
6731
 finish_call:
6732
 
6733
  DONE;
6734
})
6735
 
6736
;; We can't use the same pattern for these two insns, because then registers
6737
;; in the address may not be properly reloaded.
6738
 
6739
(define_insn "*call_address_sp32"
6740
  [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6741
         (match_operand 1 "" ""))
6742
   (clobber (reg:SI 15))]
6743
  ;;- Do not use operand 1 for most machines.
6744
  "! TARGET_ARCH64"
6745
  "call\t%a0, %1%#"
6746
  [(set_attr "type" "call")])
6747
 
6748
(define_insn "*call_symbolic_sp32"
6749
  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6750
         (match_operand 1 "" ""))
6751
   (clobber (reg:SI 15))]
6752
  ;;- Do not use operand 1 for most machines.
6753
  "! TARGET_ARCH64"
6754
  "call\t%a0, %1%#"
6755
  [(set_attr "type" "call")])
6756
 
6757
(define_insn "*call_address_sp64"
6758
  [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6759
         (match_operand 1 "" ""))
6760
   (clobber (reg:DI 15))]
6761
  ;;- Do not use operand 1 for most machines.
6762
  "TARGET_ARCH64"
6763
  "call\t%a0, %1%#"
6764
  [(set_attr "type" "call")])
6765
 
6766
(define_insn "*call_symbolic_sp64"
6767
  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6768
         (match_operand 1 "" ""))
6769
   (clobber (reg:DI 15))]
6770
  ;;- Do not use operand 1 for most machines.
6771
  "TARGET_ARCH64"
6772
  "call\t%a0, %1%#"
6773
  [(set_attr "type" "call")])
6774
 
6775
;; This is a call that wants a structure value.
6776
;; There is no such critter for v9 (??? we may need one anyway).
6777
(define_insn "*call_address_struct_value_sp32"
6778
  [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6779
         (match_operand 1 "" ""))
6780
   (match_operand 2 "immediate_operand" "")
6781
   (clobber (reg:SI 15))]
6782
  ;;- Do not use operand 1 for most machines.
6783
  "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6784
{
6785
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6786
  return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6787
}
6788
  [(set_attr "type" "call_no_delay_slot")
6789
   (set_attr "length" "3")])
6790
 
6791
;; This is a call that wants a structure value.
6792
;; There is no such critter for v9 (??? we may need one anyway).
6793
(define_insn "*call_symbolic_struct_value_sp32"
6794
  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6795
         (match_operand 1 "" ""))
6796
   (match_operand 2 "immediate_operand" "")
6797
   (clobber (reg:SI 15))]
6798
  ;;- Do not use operand 1 for most machines.
6799
  "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6800
{
6801
  operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6802
  return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6803
}
6804
  [(set_attr "type" "call_no_delay_slot")
6805
   (set_attr "length" "3")])
6806
 
6807
;; This is a call that may want a structure value.  This is used for
6808
;; untyped_calls.
6809
(define_insn "*call_address_untyped_struct_value_sp32"
6810
  [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6811
         (match_operand 1 "" ""))
6812
   (match_operand 2 "immediate_operand" "")
6813
   (clobber (reg:SI 15))]
6814
  ;;- Do not use operand 1 for most machines.
6815
  "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6816
  "call\t%a0, %1\n\t nop\n\tnop"
6817
  [(set_attr "type" "call_no_delay_slot")
6818
   (set_attr "length" "3")])
6819
 
6820
;; This is a call that may want a structure value.  This is used for
6821
;; untyped_calls.
6822
(define_insn "*call_symbolic_untyped_struct_value_sp32"
6823
  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6824
         (match_operand 1 "" ""))
6825
   (match_operand 2 "immediate_operand" "")
6826
   (clobber (reg:SI 15))]
6827
  ;;- Do not use operand 1 for most machines.
6828
  "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6829
  "call\t%a0, %1\n\t nop\n\tnop"
6830
  [(set_attr "type" "call_no_delay_slot")
6831
   (set_attr "length" "3")])
6832
 
6833
(define_expand "call_value"
6834
  ;; Note that this expression is not used for generating RTL.
6835
  ;; All the RTL is generated explicitly below.
6836
  [(set (match_operand 0 "register_operand" "=rf")
6837
        (call (match_operand 1 "" "")
6838
              (match_operand 4 "" "")))]
6839
  ;; operand 2 is stack_size_rtx
6840
  ;; operand 3 is next_arg_register
6841
  ""
6842
{
6843
  rtx fn_rtx;
6844
  rtvec vec;
6845
 
6846
  gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6847
 
6848
  fn_rtx = operands[1];
6849
 
6850
  vec = gen_rtvec (2,
6851
                   gen_rtx_SET (VOIDmode, operands[0],
6852
                                gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6853
                   gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6854
 
6855
  emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6856
 
6857
  DONE;
6858
})
6859
 
6860
(define_insn "*call_value_address_sp32"
6861
  [(set (match_operand 0 "" "=rf")
6862
        (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6863
              (match_operand 2 "" "")))
6864
   (clobber (reg:SI 15))]
6865
  ;;- Do not use operand 2 for most machines.
6866
  "! TARGET_ARCH64"
6867
  "call\t%a1, %2%#"
6868
  [(set_attr "type" "call")])
6869
 
6870
(define_insn "*call_value_symbolic_sp32"
6871
  [(set (match_operand 0 "" "=rf")
6872
        (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6873
              (match_operand 2 "" "")))
6874
   (clobber (reg:SI 15))]
6875
  ;;- Do not use operand 2 for most machines.
6876
  "! TARGET_ARCH64"
6877
  "call\t%a1, %2%#"
6878
  [(set_attr "type" "call")])
6879
 
6880
(define_insn "*call_value_address_sp64"
6881
  [(set (match_operand 0 "" "")
6882
        (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6883
              (match_operand 2 "" "")))
6884
   (clobber (reg:DI 15))]
6885
  ;;- Do not use operand 2 for most machines.
6886
  "TARGET_ARCH64"
6887
  "call\t%a1, %2%#"
6888
  [(set_attr "type" "call")])
6889
 
6890
(define_insn "*call_value_symbolic_sp64"
6891
  [(set (match_operand 0 "" "")
6892
        (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6893
              (match_operand 2 "" "")))
6894
   (clobber (reg:DI 15))]
6895
  ;;- Do not use operand 2 for most machines.
6896
  "TARGET_ARCH64"
6897
  "call\t%a1, %2%#"
6898
  [(set_attr "type" "call")])
6899
 
6900
(define_expand "untyped_call"
6901
  [(parallel [(call (match_operand 0 "" "")
6902
                    (const_int 0))
6903
              (match_operand:BLK 1 "memory_operand" "")
6904
              (match_operand 2 "" "")])]
6905
  ""
6906
{
6907
  rtx valreg1 = gen_rtx_REG (DImode, 8);
6908
  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6909
  rtx result = operands[1];
6910
 
6911
  /* Pass constm1 to indicate that it may expect a structure value, but
6912
     we don't know what size it is.  */
6913
  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6914
 
6915
  /* Save the function value registers.  */
6916
  emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6917
  emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6918
                                  valreg2);
6919
 
6920
  /* The optimizer does not know that the call sets the function value
6921
     registers we stored in the result block.  We avoid problems by
6922
     claiming that all hard registers are used and clobbered at this
6923
     point.  */
6924
  emit_insn (gen_blockage ());
6925
 
6926
  DONE;
6927
})
6928
 
6929
;;  Tail call instructions.
6930
 
6931
(define_expand "sibcall"
6932
  [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6933
              (return)])]
6934
  ""
6935
  "")
6936
 
6937
(define_insn "*sibcall_symbolic_sp32"
6938
  [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6939
         (match_operand 1 "" ""))
6940
   (return)]
6941
  "! TARGET_ARCH64"
6942
  "* return output_sibcall(insn, operands[0]);"
6943
  [(set_attr "type" "sibcall")])
6944
 
6945
(define_insn "*sibcall_symbolic_sp64"
6946
  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6947
         (match_operand 1 "" ""))
6948
   (return)]
6949
  "TARGET_ARCH64"
6950
  "* return output_sibcall(insn, operands[0]);"
6951
  [(set_attr "type" "sibcall")])
6952
 
6953
(define_expand "sibcall_value"
6954
  [(parallel [(set (match_operand 0 "register_operand" "=rf")
6955
                (call (match_operand 1 "" "") (const_int 0)))
6956
              (return)])]
6957
  ""
6958
  "")
6959
 
6960
(define_insn "*sibcall_value_symbolic_sp32"
6961
  [(set (match_operand 0 "" "=rf")
6962
        (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6963
              (match_operand 2 "" "")))
6964
   (return)]
6965
  "! TARGET_ARCH64"
6966
  "* return output_sibcall(insn, operands[1]);"
6967
  [(set_attr "type" "sibcall")])
6968
 
6969
(define_insn "*sibcall_value_symbolic_sp64"
6970
  [(set (match_operand 0 "" "")
6971
        (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6972
              (match_operand 2 "" "")))
6973
   (return)]
6974
  "TARGET_ARCH64"
6975
  "* return output_sibcall(insn, operands[1]);"
6976
  [(set_attr "type" "sibcall")])
6977
 
6978
 
6979
;; Special instructions.
6980
 
6981
(define_expand "prologue"
6982
  [(const_int 0)]
6983
  ""
6984
{
6985
  sparc_expand_prologue ();
6986
  DONE;
6987
})
6988
 
6989
;; The "save register window" insn is modelled as follows so that the DWARF-2
6990
;; backend automatically emits the required call frame debugging information
6991
;; while it is parsing it.  Therefore, the pattern should not be modified
6992
;; without first studying the impact of the changes on the debug info.
6993
;; [(set (%fp) (%sp))
6994
;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6995
;;  (set (%i7) (%o7))]
6996
 
6997
(define_insn "save_register_window"
6998
  [(set (reg:P 30) (reg:P 14))
6999
   (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7000
                                       (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7001
   (set (reg:P 31) (reg:P 15))]
7002
  ""
7003
  "save\t%%sp, %0, %%sp"
7004
  [(set_attr "type" "savew")])
7005
 
7006
(define_expand "epilogue"
7007
  [(return)]
7008
  ""
7009
{
7010
  sparc_expand_epilogue ();
7011
})
7012
 
7013
(define_expand "sibcall_epilogue"
7014
  [(return)]
7015
  ""
7016
{
7017
  sparc_expand_epilogue ();
7018
  DONE;
7019
})
7020
 
7021
(define_expand "return"
7022
  [(return)]
7023
  "sparc_can_use_return_insn_p ()"
7024
  "")
7025
 
7026
(define_insn "*return_internal"
7027
  [(return)]
7028
  ""
7029
  "* return output_return (insn);"
7030
  [(set_attr "type" "return")
7031
   (set (attr "length")
7032
        (cond [(eq_attr "leaf_function" "true")
7033
                 (if_then_else (eq_attr "empty_delay_slot" "true")
7034
                               (const_int 2)
7035
                               (const_int 1))
7036
               (eq_attr "calls_eh_return" "true")
7037
                 (if_then_else (eq_attr "delayed_branch" "true")
7038
                               (if_then_else (eq_attr "isa" "v9")
7039
                                             (const_int 2)
7040
                                             (const_int 3))
7041
                               (if_then_else (eq_attr "isa" "v9")
7042
                                             (const_int 3)
7043
                                             (const_int 4)))
7044
               (eq_attr "empty_delay_slot" "true")
7045
                 (if_then_else (eq_attr "delayed_branch" "true")
7046
                               (const_int 2)
7047
                               (const_int 3))
7048
              ] (const_int 1)))])
7049
 
7050
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7051
;; all of memory.  This blocks insns from being moved across this point.
7052
 
7053
(define_insn "blockage"
7054
  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7055
  ""
7056
  ""
7057
  [(set_attr "length" "0")])
7058
 
7059
;; Prepare to return any type including a structure value.
7060
 
7061
(define_expand "untyped_return"
7062
  [(match_operand:BLK 0 "memory_operand" "")
7063
   (match_operand 1 "" "")]
7064
  ""
7065
{
7066
  rtx valreg1 = gen_rtx_REG (DImode, 24);
7067
  rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7068
  rtx result = operands[0];
7069
 
7070
  if (! TARGET_ARCH64)
7071
    {
7072
      rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7073
                                         ? 15 : 31));
7074
      rtx value = gen_reg_rtx (SImode);
7075
 
7076
      /* Fetch the instruction where we will return to and see if it's an unimp
7077
         instruction (the most significant 10 bits will be zero).  If so,
7078
         update the return address to skip the unimp instruction.  */
7079
      emit_move_insn (value,
7080
                      gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7081
      emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7082
      emit_insn (gen_update_return (rtnreg, value));
7083
    }
7084
 
7085
  /* Reload the function value registers.  */
7086
  emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7087
  emit_move_insn (valreg2,
7088
                  adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7089
 
7090
  /* Put USE insns before the return.  */
7091
  emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7092
  emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7093
 
7094
  /* Construct the return.  */
7095
  expand_naked_return ();
7096
 
7097
  DONE;
7098
})
7099
 
7100
;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7101
;; and parts of the compiler don't want to believe that the add is needed.
7102
 
7103
(define_insn "update_return"
7104
  [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7105
               (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7106
  "! TARGET_ARCH64"
7107
{
7108
  if (flag_delayed_branch)
7109
    return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7110
  else
7111
    return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7112
}
7113
  [(set (attr "type") (const_string "multi"))
7114
   (set (attr "length")
7115
        (if_then_else (eq_attr "delayed_branch" "true")
7116
                      (const_int 3)
7117
                      (const_int 4)))])
7118
 
7119
(define_insn "nop"
7120
  [(const_int 0)]
7121
  ""
7122
  "nop")
7123
 
7124
(define_expand "indirect_jump"
7125
  [(set (pc) (match_operand 0 "address_operand" "p"))]
7126
  ""
7127
  "")
7128
 
7129
(define_insn "*branch_sp32"
7130
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7131
  "! TARGET_ARCH64"
7132
 "jmp\t%a0%#"
7133
 [(set_attr "type" "uncond_branch")])
7134
 
7135
(define_insn "*branch_sp64"
7136
  [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7137
  "TARGET_ARCH64"
7138
  "jmp\t%a0%#"
7139
  [(set_attr "type" "uncond_branch")])
7140
 
7141
(define_expand "nonlocal_goto"
7142
  [(match_operand:SI 0 "general_operand" "")
7143
   (match_operand:SI 1 "general_operand" "")
7144
   (match_operand:SI 2 "general_operand" "")
7145
   (match_operand:SI 3 "" "")]
7146
  ""
7147
{
7148
  rtx lab = operands[1];
7149
  rtx stack = operands[2];
7150
  rtx fp = operands[3];
7151
  rtx labreg;
7152
 
7153
  /* Trap instruction to flush all the register windows.  */
7154
  emit_insn (gen_flush_register_windows ());
7155
 
7156
  /* Load the fp value for the containing fn into %fp.  This is needed
7157
     because STACK refers to %fp.  Note that virtual register instantiation
7158
     fails if the virtual %fp isn't set from a register.  */
7159
  if (GET_CODE (fp) != REG)
7160
    fp = force_reg (Pmode, fp);
7161
  emit_move_insn (virtual_stack_vars_rtx, fp);
7162
 
7163
  /* Find the containing function's current nonlocal goto handler,
7164
     which will do any cleanups and then jump to the label.  */
7165
  labreg = gen_rtx_REG (Pmode, 8);
7166
  emit_move_insn (labreg, lab);
7167
 
7168
  /* Restore %fp from stack pointer value for containing function.
7169
     The restore insn that follows will move this to %sp,
7170
     and reload the appropriate value into %fp.  */
7171
  emit_move_insn (hard_frame_pointer_rtx, stack);
7172
 
7173
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7174
  emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7175
 
7176
  /* ??? The V9-specific version was disabled in rev 1.65.  */
7177
  emit_jump_insn (gen_goto_handler_and_restore (labreg));
7178
  emit_barrier ();
7179
  DONE;
7180
})
7181
 
7182
;; Special trap insn to flush register windows.
7183
(define_insn "flush_register_windows"
7184
  [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7185
  ""
7186
  { return TARGET_V9 ? "flushw" : "ta\t3"; }
7187
  [(set_attr "type" "flushw")])
7188
 
7189
(define_insn "goto_handler_and_restore"
7190
  [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7191
  "GET_MODE (operands[0]) == Pmode"
7192
{
7193
  if (flag_delayed_branch)
7194
    return "jmp\t%0\n\t restore";
7195
  else
7196
    return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7197
}
7198
  [(set (attr "type") (const_string "multi"))
7199
   (set (attr "length")
7200
        (if_then_else (eq_attr "delayed_branch" "true")
7201
                      (const_int 2)
7202
                      (const_int 4)))])
7203
 
7204
;; For __builtin_setjmp we need to flush register windows iff the function
7205
;; calls alloca as well, because otherwise the register window might be
7206
;; saved after %sp adjustment and thus setjmp would crash
7207
(define_expand "builtin_setjmp_setup"
7208
  [(match_operand 0 "register_operand" "r")]
7209
  ""
7210
{
7211
  emit_insn (gen_do_builtin_setjmp_setup ());
7212
  DONE;
7213
})
7214
 
7215
(define_insn "do_builtin_setjmp_setup"
7216
  [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7217
  ""
7218
{
7219
  if (! current_function_calls_alloca)
7220
    return "";
7221
  if (! TARGET_V9)
7222
    return "\tta\t3\n";
7223
  fputs ("\tflushw\n", asm_out_file);
7224
  if (flag_pic)
7225
    fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7226
             TARGET_ARCH64 ? 'x' : 'w',
7227
             SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7228
  fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7229
           TARGET_ARCH64 ? 'x' : 'w',
7230
           SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7231
  fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7232
           TARGET_ARCH64 ? 'x' : 'w',
7233
           SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7234
  return "";
7235
}
7236
  [(set_attr "type" "multi")
7237
   (set (attr "length")
7238
        (cond [(eq_attr "calls_alloca" "false")
7239
                 (const_int 0)
7240
               (eq_attr "isa" "!v9")
7241
                 (const_int 1)
7242
               (eq_attr "pic" "true")
7243
                 (const_int 4)] (const_int 3)))])
7244
 
7245
;; Pattern for use after a setjmp to store FP and the return register
7246
;; into the stack area.
7247
 
7248
(define_expand "setjmp"
7249
  [(const_int 0)]
7250
  ""
7251
{
7252
  if (TARGET_ARCH64)
7253
    emit_insn (gen_setjmp_64 ());
7254
  else
7255
    emit_insn (gen_setjmp_32 ());
7256
  DONE;
7257
})
7258
 
7259
(define_expand "setjmp_32"
7260
  [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7261
   (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7262
  ""
7263
  { operands[0] = frame_pointer_rtx; })
7264
 
7265
(define_expand "setjmp_64"
7266
  [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7267
   (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7268
  ""
7269
  { operands[0] = frame_pointer_rtx; })
7270
 
7271
;; Special pattern for the FLUSH instruction.
7272
 
7273
; We do SImode and DImode versions of this to quiet down genrecog's complaints
7274
; of the define_insn otherwise missing a mode.  We make "flush", aka
7275
; gen_flush, the default one since sparc_initialize_trampoline uses
7276
; it on SImode mem values.
7277
 
7278
(define_insn "flush"
7279
  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7280
  ""
7281
  { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7282
  [(set_attr "type" "iflush")])
7283
 
7284
(define_insn "flushdi"
7285
  [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7286
  ""
7287
  { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7288
  [(set_attr "type" "iflush")])
7289
 
7290
 
7291
;; Find first set instructions.
7292
 
7293
;; The scan instruction searches from the most significant bit while ffs
7294
;; searches from the least significant bit.  The bit index and treatment of
7295
;; zero also differ.  It takes at least 7 instructions to get the proper
7296
;; result.  Here is an obvious 8 instruction sequence.
7297
 
7298
;; XXX
7299
(define_insn "ffssi2"
7300
  [(set (match_operand:SI 0 "register_operand" "=&r")
7301
        (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7302
   (clobber (match_scratch:SI 2 "=&r"))]
7303
  "TARGET_SPARCLITE || TARGET_SPARCLET"
7304
{
7305
  return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
7306
}
7307
  [(set_attr "type" "multi")
7308
   (set_attr "length" "8")])
7309
 
7310
;; ??? This should be a define expand, so that the extra instruction have
7311
;; a chance of being optimized away.
7312
 
7313
;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7314
;; does, but no one uses that and we don't have a switch for it.
7315
;
7316
;(define_insn "ffsdi2"
7317
;  [(set (match_operand:DI 0 "register_operand" "=&r")
7318
;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7319
;   (clobber (match_scratch:DI 2 "=&r"))]
7320
;  "TARGET_ARCH64"
7321
;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7322
;  [(set_attr "type" "multi")
7323
;   (set_attr "length" "4")])
7324
 
7325
 
7326
 
7327
;; Peepholes go at the end.
7328
 
7329
;; Optimize consecutive loads or stores into ldd and std when possible.
7330
;; The conditions in which we do this are very restricted and are
7331
;; explained in the code for {registers,memory}_ok_for_ldd functions.
7332
 
7333
(define_peephole2
7334
  [(set (match_operand:SI 0 "memory_operand" "")
7335
      (const_int 0))
7336
   (set (match_operand:SI 1 "memory_operand" "")
7337
      (const_int 0))]
7338
  "TARGET_V9
7339
   && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7340
  [(set (match_dup 0)
7341
       (const_int 0))]
7342
  "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7343
 
7344
(define_peephole2
7345
  [(set (match_operand:SI 0 "memory_operand" "")
7346
      (const_int 0))
7347
   (set (match_operand:SI 1 "memory_operand" "")
7348
      (const_int 0))]
7349
  "TARGET_V9
7350
   && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7351
  [(set (match_dup 1)
7352
       (const_int 0))]
7353
  "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7354
 
7355
(define_peephole2
7356
  [(set (match_operand:SI 0 "register_operand" "")
7357
        (match_operand:SI 1 "memory_operand" ""))
7358
   (set (match_operand:SI 2 "register_operand" "")
7359
        (match_operand:SI 3 "memory_operand" ""))]
7360
  "registers_ok_for_ldd_peep (operands[0], operands[2])
7361
   && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7362
  [(set (match_dup 0)
7363
        (match_dup 1))]
7364
  "operands[1] = widen_memory_access (operands[1], DImode, 0);
7365
   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7366
 
7367
(define_peephole2
7368
  [(set (match_operand:SI 0 "memory_operand" "")
7369
        (match_operand:SI 1 "register_operand" ""))
7370
   (set (match_operand:SI 2 "memory_operand" "")
7371
        (match_operand:SI 3 "register_operand" ""))]
7372
  "registers_ok_for_ldd_peep (operands[1], operands[3])
7373
   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7374
  [(set (match_dup 0)
7375
        (match_dup 1))]
7376
  "operands[0] = widen_memory_access (operands[0], DImode, 0);
7377
   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7378
 
7379
(define_peephole2
7380
  [(set (match_operand:SF 0 "register_operand" "")
7381
        (match_operand:SF 1 "memory_operand" ""))
7382
   (set (match_operand:SF 2 "register_operand" "")
7383
        (match_operand:SF 3 "memory_operand" ""))]
7384
  "registers_ok_for_ldd_peep (operands[0], operands[2])
7385
   && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7386
  [(set (match_dup 0)
7387
        (match_dup 1))]
7388
  "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7389
   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7390
 
7391
(define_peephole2
7392
  [(set (match_operand:SF 0 "memory_operand" "")
7393
        (match_operand:SF 1 "register_operand" ""))
7394
   (set (match_operand:SF 2 "memory_operand" "")
7395
        (match_operand:SF 3 "register_operand" ""))]
7396
  "registers_ok_for_ldd_peep (operands[1], operands[3])
7397
  && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7398
  [(set (match_dup 0)
7399
        (match_dup 1))]
7400
  "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7401
   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7402
 
7403
(define_peephole2
7404
  [(set (match_operand:SI 0 "register_operand" "")
7405
        (match_operand:SI 1 "memory_operand" ""))
7406
   (set (match_operand:SI 2 "register_operand" "")
7407
        (match_operand:SI 3 "memory_operand" ""))]
7408
  "registers_ok_for_ldd_peep (operands[2], operands[0])
7409
  && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7410
  [(set (match_dup 2)
7411
        (match_dup 3))]
7412
   "operands[3] = widen_memory_access (operands[3], DImode, 0);
7413
    operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7414
 
7415
(define_peephole2
7416
  [(set (match_operand:SI 0 "memory_operand" "")
7417
        (match_operand:SI 1 "register_operand" ""))
7418
   (set (match_operand:SI 2 "memory_operand" "")
7419
        (match_operand:SI 3 "register_operand" ""))]
7420
  "registers_ok_for_ldd_peep (operands[3], operands[1])
7421
  && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7422
  [(set (match_dup 2)
7423
        (match_dup 3))]
7424
  "operands[2] = widen_memory_access (operands[2], DImode, 0);
7425
   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7426
   ")
7427
 
7428
(define_peephole2
7429
  [(set (match_operand:SF 0 "register_operand" "")
7430
        (match_operand:SF 1 "memory_operand" ""))
7431
   (set (match_operand:SF 2 "register_operand" "")
7432
        (match_operand:SF 3 "memory_operand" ""))]
7433
  "registers_ok_for_ldd_peep (operands[2], operands[0])
7434
  && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7435
  [(set (match_dup 2)
7436
        (match_dup 3))]
7437
  "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7438
   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7439
 
7440
(define_peephole2
7441
  [(set (match_operand:SF 0 "memory_operand" "")
7442
        (match_operand:SF 1 "register_operand" ""))
7443
   (set (match_operand:SF 2 "memory_operand" "")
7444
        (match_operand:SF 3 "register_operand" ""))]
7445
  "registers_ok_for_ldd_peep (operands[3], operands[1])
7446
  && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7447
  [(set (match_dup 2)
7448
        (match_dup 3))]
7449
  "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7450
   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7451
 
7452
;; Optimize the case of following a reg-reg move with a test
7453
;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7454
;; This can result from a float to fix conversion.
7455
 
7456
(define_peephole2
7457
  [(set (match_operand:SI 0 "register_operand" "")
7458
        (match_operand:SI 1 "register_operand" ""))
7459
   (set (reg:CC 100)
7460
        (compare:CC (match_operand:SI 2 "register_operand" "")
7461
                    (const_int 0)))]
7462
  "(rtx_equal_p (operands[2], operands[0])
7463
    || rtx_equal_p (operands[2], operands[1]))
7464
    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7465
    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7466
  [(parallel [(set (match_dup 0) (match_dup 1))
7467
              (set (reg:CC 100)
7468
                   (compare:CC (match_dup 1) (const_int 0)))])]
7469
  "")
7470
 
7471
(define_peephole2
7472
  [(set (match_operand:DI 0 "register_operand" "")
7473
        (match_operand:DI 1 "register_operand" ""))
7474
   (set (reg:CCX 100)
7475
        (compare:CCX (match_operand:DI 2 "register_operand" "")
7476
                    (const_int 0)))]
7477
  "TARGET_ARCH64
7478
   && (rtx_equal_p (operands[2], operands[0])
7479
       || rtx_equal_p (operands[2], operands[1]))
7480
   && ! SPARC_FP_REG_P (REGNO (operands[0]))
7481
   && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7482
  [(parallel [(set (match_dup 0) (match_dup 1))
7483
              (set (reg:CCX 100)
7484
                   (compare:CCX (match_dup 1) (const_int 0)))])]
7485
  "")
7486
 
7487
 
7488
;; Prefetch instructions.
7489
 
7490
;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7491
;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7492
;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7493
;; ??? state.
7494
(define_expand "prefetch"
7495
  [(match_operand 0 "address_operand" "")
7496
   (match_operand 1 "const_int_operand" "")
7497
   (match_operand 2 "const_int_operand" "")]
7498
  "TARGET_V9"
7499
{
7500
  if (TARGET_ARCH64)
7501
    emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7502
  else
7503
    emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7504
  DONE;
7505
})
7506
 
7507
(define_insn "prefetch_64"
7508
  [(prefetch (match_operand:DI 0 "address_operand" "p")
7509
             (match_operand:DI 1 "const_int_operand" "n")
7510
             (match_operand:DI 2 "const_int_operand" "n"))]
7511
  ""
7512
{
7513
  static const char * const prefetch_instr[2][2] = {
7514
    {
7515
      "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7516
      "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7517
    },
7518
    {
7519
      "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7520
      "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7521
    }
7522
  };
7523
  int read_or_write = INTVAL (operands[1]);
7524
  int locality = INTVAL (operands[2]);
7525
 
7526
  gcc_assert (read_or_write == 0 || read_or_write == 1);
7527
  gcc_assert (locality >= 0 && locality < 4);
7528
  return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7529
}
7530
  [(set_attr "type" "load")])
7531
 
7532
(define_insn "prefetch_32"
7533
  [(prefetch (match_operand:SI 0 "address_operand" "p")
7534
             (match_operand:SI 1 "const_int_operand" "n")
7535
             (match_operand:SI 2 "const_int_operand" "n"))]
7536
  ""
7537
{
7538
  static const char * const prefetch_instr[2][2] = {
7539
    {
7540
      "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7541
      "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7542
    },
7543
    {
7544
      "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7545
      "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7546
    }
7547
  };
7548
  int read_or_write = INTVAL (operands[1]);
7549
  int locality = INTVAL (operands[2]);
7550
 
7551
  gcc_assert (read_or_write == 0 || read_or_write == 1);
7552
  gcc_assert (locality >= 0 && locality < 4);
7553
  return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7554
}
7555
  [(set_attr "type" "load")])
7556
 
7557
 
7558
;; Trap instructions.
7559
 
7560
(define_insn "trap"
7561
  [(trap_if (const_int 1) (const_int 5))]
7562
  ""
7563
  "ta\t5"
7564
  [(set_attr "type" "trap")])
7565
 
7566
(define_expand "conditional_trap"
7567
  [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7568
            (match_operand:SI 1 "arith_operand" ""))]
7569
  ""
7570
  "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
7571
                                  sparc_compare_op0, sparc_compare_op1);
7572
   if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7573
     FAIL;
7574
   operands[3] = const0_rtx;")
7575
 
7576
(define_insn ""
7577
  [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7578
            (match_operand:SI 1 "arith_operand" "rM"))]
7579
  ""
7580
{
7581
  if (TARGET_V9)
7582
    return "t%C0\t%%icc, %1";
7583
  else
7584
    return "t%C0\t%1";
7585
}
7586
  [(set_attr "type" "trap")])
7587
 
7588
(define_insn ""
7589
  [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7590
            (match_operand:SI 1 "arith_operand" "rM"))]
7591
  "TARGET_V9"
7592
  "t%C0\t%%xcc, %1"
7593
  [(set_attr "type" "trap")])
7594
 
7595
 
7596
;; TLS support instructions.
7597
 
7598
(define_insn "tgd_hi22"
7599
  [(set (match_operand:SI 0 "register_operand" "=r")
7600
        (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7601
                            UNSPEC_TLSGD)))]
7602
  "TARGET_TLS"
7603
  "sethi\\t%%tgd_hi22(%a1), %0")
7604
 
7605
(define_insn "tgd_lo10"
7606
  [(set (match_operand:SI 0 "register_operand" "=r")
7607
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7608
                   (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7609
                              UNSPEC_TLSGD)))]
7610
  "TARGET_TLS"
7611
  "add\\t%1, %%tgd_lo10(%a2), %0")
7612
 
7613
(define_insn "tgd_add32"
7614
  [(set (match_operand:SI 0 "register_operand" "=r")
7615
        (plus:SI (match_operand:SI 1 "register_operand" "r")
7616
                 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7617
                             (match_operand 3 "tgd_symbolic_operand" "")]
7618
                            UNSPEC_TLSGD)))]
7619
  "TARGET_TLS && TARGET_ARCH32"
7620
  "add\\t%1, %2, %0, %%tgd_add(%a3)")
7621
 
7622
(define_insn "tgd_add64"
7623
  [(set (match_operand:DI 0 "register_operand" "=r")
7624
        (plus:DI (match_operand:DI 1 "register_operand" "r")
7625
                 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7626
                             (match_operand 3 "tgd_symbolic_operand" "")]
7627
                            UNSPEC_TLSGD)))]
7628
  "TARGET_TLS && TARGET_ARCH64"
7629
  "add\\t%1, %2, %0, %%tgd_add(%a3)")
7630
 
7631
(define_insn "tgd_call32"
7632
  [(set (match_operand 0 "register_operand" "=r")
7633
        (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7634
                                  (match_operand 2 "tgd_symbolic_operand" "")]
7635
                                 UNSPEC_TLSGD))
7636
              (match_operand 3 "" "")))
7637
   (clobber (reg:SI 15))]
7638
  "TARGET_TLS && TARGET_ARCH32"
7639
  "call\t%a1, %%tgd_call(%a2)%#"
7640
  [(set_attr "type" "call")])
7641
 
7642
(define_insn "tgd_call64"
7643
  [(set (match_operand 0 "register_operand" "=r")
7644
        (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7645
                                  (match_operand 2 "tgd_symbolic_operand" "")]
7646
                                 UNSPEC_TLSGD))
7647
              (match_operand 3 "" "")))
7648
   (clobber (reg:DI 15))]
7649
  "TARGET_TLS && TARGET_ARCH64"
7650
  "call\t%a1, %%tgd_call(%a2)%#"
7651
  [(set_attr "type" "call")])
7652
 
7653
(define_insn "tldm_hi22"
7654
  [(set (match_operand:SI 0 "register_operand" "=r")
7655
        (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7656
  "TARGET_TLS"
7657
  "sethi\\t%%tldm_hi22(%&), %0")
7658
 
7659
(define_insn "tldm_lo10"
7660
  [(set (match_operand:SI 0 "register_operand" "=r")
7661
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7662
                    (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7663
  "TARGET_TLS"
7664
  "add\\t%1, %%tldm_lo10(%&), %0")
7665
 
7666
(define_insn "tldm_add32"
7667
  [(set (match_operand:SI 0 "register_operand" "=r")
7668
        (plus:SI (match_operand:SI 1 "register_operand" "r")
7669
                 (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7670
                            UNSPEC_TLSLDM)))]
7671
  "TARGET_TLS && TARGET_ARCH32"
7672
  "add\\t%1, %2, %0, %%tldm_add(%&)")
7673
 
7674
(define_insn "tldm_add64"
7675
  [(set (match_operand:DI 0 "register_operand" "=r")
7676
        (plus:DI (match_operand:DI 1 "register_operand" "r")
7677
                 (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7678
                            UNSPEC_TLSLDM)))]
7679
  "TARGET_TLS && TARGET_ARCH64"
7680
  "add\\t%1, %2, %0, %%tldm_add(%&)")
7681
 
7682
(define_insn "tldm_call32"
7683
  [(set (match_operand 0 "register_operand" "=r")
7684
        (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7685
                                 UNSPEC_TLSLDM))
7686
              (match_operand 2 "" "")))
7687
   (clobber (reg:SI 15))]
7688
  "TARGET_TLS && TARGET_ARCH32"
7689
  "call\t%a1, %%tldm_call(%&)%#"
7690
  [(set_attr "type" "call")])
7691
 
7692
(define_insn "tldm_call64"
7693
  [(set (match_operand 0 "register_operand" "=r")
7694
        (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7695
                                 UNSPEC_TLSLDM))
7696
              (match_operand 2 "" "")))
7697
   (clobber (reg:DI 15))]
7698
  "TARGET_TLS && TARGET_ARCH64"
7699
  "call\t%a1, %%tldm_call(%&)%#"
7700
  [(set_attr "type" "call")])
7701
 
7702
(define_insn "tldo_hix22"
7703
  [(set (match_operand:SI 0 "register_operand" "=r")
7704
        (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7705
                            UNSPEC_TLSLDO)))]
7706
  "TARGET_TLS"
7707
  "sethi\\t%%tldo_hix22(%a1), %0")
7708
 
7709
(define_insn "tldo_lox10"
7710
  [(set (match_operand:SI 0 "register_operand" "=r")
7711
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7712
                   (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7713
                              UNSPEC_TLSLDO)))]
7714
  "TARGET_TLS"
7715
  "xor\\t%1, %%tldo_lox10(%a2), %0")
7716
 
7717
(define_insn "tldo_add32"
7718
  [(set (match_operand:SI 0 "register_operand" "=r")
7719
        (plus:SI (match_operand:SI 1 "register_operand" "r")
7720
                 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7721
                             (match_operand 3 "tld_symbolic_operand" "")]
7722
                            UNSPEC_TLSLDO)))]
7723
  "TARGET_TLS && TARGET_ARCH32"
7724
  "add\\t%1, %2, %0, %%tldo_add(%a3)")
7725
 
7726
(define_insn "tldo_add64"
7727
  [(set (match_operand:DI 0 "register_operand" "=r")
7728
        (plus:DI (match_operand:DI 1 "register_operand" "r")
7729
                 (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7730
                             (match_operand 3 "tld_symbolic_operand" "")]
7731
                            UNSPEC_TLSLDO)))]
7732
  "TARGET_TLS && TARGET_ARCH64"
7733
  "add\\t%1, %2, %0, %%tldo_add(%a3)")
7734
 
7735
(define_insn "tie_hi22"
7736
  [(set (match_operand:SI 0 "register_operand" "=r")
7737
        (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7738
                            UNSPEC_TLSIE)))]
7739
  "TARGET_TLS"
7740
  "sethi\\t%%tie_hi22(%a1), %0")
7741
 
7742
(define_insn "tie_lo10"
7743
  [(set (match_operand:SI 0 "register_operand" "=r")
7744
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7745
                   (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7746
                              UNSPEC_TLSIE)))]
7747
  "TARGET_TLS"
7748
  "add\\t%1, %%tie_lo10(%a2), %0")
7749
 
7750
(define_insn "tie_ld32"
7751
  [(set (match_operand:SI 0 "register_operand" "=r")
7752
        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7753
                    (match_operand:SI 2 "register_operand" "r")
7754
                    (match_operand 3 "tie_symbolic_operand" "")]
7755
                   UNSPEC_TLSIE))]
7756
  "TARGET_TLS && TARGET_ARCH32"
7757
  "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7758
  [(set_attr "type" "load")])
7759
 
7760
(define_insn "tie_ld64"
7761
  [(set (match_operand:DI 0 "register_operand" "=r")
7762
        (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7763
                    (match_operand:SI 2 "register_operand" "r")
7764
                    (match_operand 3 "tie_symbolic_operand" "")]
7765
                   UNSPEC_TLSIE))]
7766
  "TARGET_TLS && TARGET_ARCH64"
7767
  "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7768
  [(set_attr "type" "load")])
7769
 
7770
(define_insn "tie_add32"
7771
  [(set (match_operand:SI 0 "register_operand" "=r")
7772
        (plus:SI (match_operand:SI 1 "register_operand" "r")
7773
                 (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7774
                             (match_operand 3 "tie_symbolic_operand" "")]
7775
                            UNSPEC_TLSIE)))]
7776
  "TARGET_SUN_TLS && TARGET_ARCH32"
7777
  "add\\t%1, %2, %0, %%tie_add(%a3)")
7778
 
7779
(define_insn "tie_add64"
7780
  [(set (match_operand:DI 0 "register_operand" "=r")
7781
        (plus:DI (match_operand:DI 1 "register_operand" "r")
7782
                 (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7783
                             (match_operand 3 "tie_symbolic_operand" "")]
7784
                            UNSPEC_TLSIE)))]
7785
  "TARGET_SUN_TLS && TARGET_ARCH64"
7786
  "add\\t%1, %2, %0, %%tie_add(%a3)")
7787
 
7788
(define_insn "tle_hix22_sp32"
7789
  [(set (match_operand:SI 0 "register_operand" "=r")
7790
        (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7791
                            UNSPEC_TLSLE)))]
7792
  "TARGET_TLS && TARGET_ARCH32"
7793
  "sethi\\t%%tle_hix22(%a1), %0")
7794
 
7795
(define_insn "tle_lox10_sp32"
7796
  [(set (match_operand:SI 0 "register_operand" "=r")
7797
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7798
                   (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7799
                              UNSPEC_TLSLE)))]
7800
  "TARGET_TLS && TARGET_ARCH32"
7801
  "xor\\t%1, %%tle_lox10(%a2), %0")
7802
 
7803
(define_insn "tle_hix22_sp64"
7804
  [(set (match_operand:DI 0 "register_operand" "=r")
7805
        (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7806
                            UNSPEC_TLSLE)))]
7807
  "TARGET_TLS && TARGET_ARCH64"
7808
  "sethi\\t%%tle_hix22(%a1), %0")
7809
 
7810
(define_insn "tle_lox10_sp64"
7811
  [(set (match_operand:DI 0 "register_operand" "=r")
7812
        (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7813
                   (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7814
                              UNSPEC_TLSLE)))]
7815
  "TARGET_TLS && TARGET_ARCH64"
7816
  "xor\\t%1, %%tle_lox10(%a2), %0")
7817
 
7818
;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7819
(define_insn "*tldo_ldub_sp32"
7820
  [(set (match_operand:QI 0 "register_operand" "=r")
7821
        (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7822
                                     (match_operand 3 "tld_symbolic_operand" "")]
7823
                                    UNSPEC_TLSLDO)
7824
                         (match_operand:SI 1 "register_operand" "r"))))]
7825
  "TARGET_TLS && TARGET_ARCH32"
7826
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7827
  [(set_attr "type" "load")
7828
   (set_attr "us3load_type" "3cycle")])
7829
 
7830
(define_insn "*tldo_ldub1_sp32"
7831
  [(set (match_operand:HI 0 "register_operand" "=r")
7832
        (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7833
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7834
                                                    UNSPEC_TLSLDO)
7835
                                         (match_operand:SI 1 "register_operand" "r")))))]
7836
  "TARGET_TLS && TARGET_ARCH32"
7837
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7838
  [(set_attr "type" "load")
7839
   (set_attr "us3load_type" "3cycle")])
7840
 
7841
(define_insn "*tldo_ldub2_sp32"
7842
  [(set (match_operand:SI 0 "register_operand" "=r")
7843
        (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7844
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7845
                                                    UNSPEC_TLSLDO)
7846
                                         (match_operand:SI 1 "register_operand" "r")))))]
7847
  "TARGET_TLS && TARGET_ARCH32"
7848
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7849
  [(set_attr "type" "load")
7850
   (set_attr "us3load_type" "3cycle")])
7851
 
7852
(define_insn "*tldo_ldsb1_sp32"
7853
  [(set (match_operand:HI 0 "register_operand" "=r")
7854
        (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7855
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7856
                                                    UNSPEC_TLSLDO)
7857
                                         (match_operand:SI 1 "register_operand" "r")))))]
7858
  "TARGET_TLS && TARGET_ARCH32"
7859
  "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7860
  [(set_attr "type" "sload")
7861
   (set_attr "us3load_type" "3cycle")])
7862
 
7863
(define_insn "*tldo_ldsb2_sp32"
7864
  [(set (match_operand:SI 0 "register_operand" "=r")
7865
        (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7866
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7867
                                                    UNSPEC_TLSLDO)
7868
                                         (match_operand:SI 1 "register_operand" "r")))))]
7869
  "TARGET_TLS && TARGET_ARCH32"
7870
  "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7871
  [(set_attr "type" "sload")
7872
   (set_attr "us3load_type" "3cycle")])
7873
 
7874
(define_insn "*tldo_ldub_sp64"
7875
  [(set (match_operand:QI 0 "register_operand" "=r")
7876
        (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7877
                                     (match_operand 3 "tld_symbolic_operand" "")]
7878
                                    UNSPEC_TLSLDO)
7879
                         (match_operand:DI 1 "register_operand" "r"))))]
7880
  "TARGET_TLS && TARGET_ARCH64"
7881
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7882
  [(set_attr "type" "load")
7883
   (set_attr "us3load_type" "3cycle")])
7884
 
7885
(define_insn "*tldo_ldub1_sp64"
7886
  [(set (match_operand:HI 0 "register_operand" "=r")
7887
        (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7888
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7889
                                                    UNSPEC_TLSLDO)
7890
                                         (match_operand:DI 1 "register_operand" "r")))))]
7891
  "TARGET_TLS && TARGET_ARCH64"
7892
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7893
  [(set_attr "type" "load")
7894
   (set_attr "us3load_type" "3cycle")])
7895
 
7896
(define_insn "*tldo_ldub2_sp64"
7897
  [(set (match_operand:SI 0 "register_operand" "=r")
7898
        (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7899
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7900
                                                    UNSPEC_TLSLDO)
7901
                                         (match_operand:DI 1 "register_operand" "r")))))]
7902
  "TARGET_TLS && TARGET_ARCH64"
7903
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7904
  [(set_attr "type" "load")
7905
   (set_attr "us3load_type" "3cycle")])
7906
 
7907
(define_insn "*tldo_ldub3_sp64"
7908
  [(set (match_operand:DI 0 "register_operand" "=r")
7909
        (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7910
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7911
                                                    UNSPEC_TLSLDO)
7912
                                         (match_operand:DI 1 "register_operand" "r")))))]
7913
  "TARGET_TLS && TARGET_ARCH64"
7914
  "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7915
  [(set_attr "type" "load")
7916
   (set_attr "us3load_type" "3cycle")])
7917
 
7918
(define_insn "*tldo_ldsb1_sp64"
7919
  [(set (match_operand:HI 0 "register_operand" "=r")
7920
        (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7921
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7922
                                                    UNSPEC_TLSLDO)
7923
                                         (match_operand:DI 1 "register_operand" "r")))))]
7924
  "TARGET_TLS && TARGET_ARCH64"
7925
  "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7926
  [(set_attr "type" "sload")
7927
   (set_attr "us3load_type" "3cycle")])
7928
 
7929
(define_insn "*tldo_ldsb2_sp64"
7930
  [(set (match_operand:SI 0 "register_operand" "=r")
7931
        (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7932
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7933
                                                    UNSPEC_TLSLDO)
7934
                                         (match_operand:DI 1 "register_operand" "r")))))]
7935
  "TARGET_TLS && TARGET_ARCH64"
7936
  "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7937
  [(set_attr "type" "sload")
7938
   (set_attr "us3load_type" "3cycle")])
7939
 
7940
(define_insn "*tldo_ldsb3_sp64"
7941
  [(set (match_operand:DI 0 "register_operand" "=r")
7942
        (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7943
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7944
                                                    UNSPEC_TLSLDO)
7945
                                         (match_operand:DI 1 "register_operand" "r")))))]
7946
  "TARGET_TLS && TARGET_ARCH64"
7947
  "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7948
  [(set_attr "type" "sload")
7949
   (set_attr "us3load_type" "3cycle")])
7950
 
7951
(define_insn "*tldo_lduh_sp32"
7952
  [(set (match_operand:HI 0 "register_operand" "=r")
7953
        (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7954
                                     (match_operand 3 "tld_symbolic_operand" "")]
7955
                                    UNSPEC_TLSLDO)
7956
                         (match_operand:SI 1 "register_operand" "r"))))]
7957
  "TARGET_TLS && TARGET_ARCH32"
7958
  "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7959
  [(set_attr "type" "load")
7960
   (set_attr "us3load_type" "3cycle")])
7961
 
7962
(define_insn "*tldo_lduh1_sp32"
7963
  [(set (match_operand:SI 0 "register_operand" "=r")
7964
        (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7965
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7966
                                                    UNSPEC_TLSLDO)
7967
                                         (match_operand:SI 1 "register_operand" "r")))))]
7968
  "TARGET_TLS && TARGET_ARCH32"
7969
  "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7970
  [(set_attr "type" "load")
7971
   (set_attr "us3load_type" "3cycle")])
7972
 
7973
(define_insn "*tldo_ldsh1_sp32"
7974
  [(set (match_operand:SI 0 "register_operand" "=r")
7975
        (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7976
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7977
                                                    UNSPEC_TLSLDO)
7978
                                         (match_operand:SI 1 "register_operand" "r")))))]
7979
  "TARGET_TLS && TARGET_ARCH32"
7980
  "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7981
  [(set_attr "type" "sload")
7982
   (set_attr "us3load_type" "3cycle")])
7983
 
7984
(define_insn "*tldo_lduh_sp64"
7985
  [(set (match_operand:HI 0 "register_operand" "=r")
7986
        (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7987
                                     (match_operand 3 "tld_symbolic_operand" "")]
7988
                                    UNSPEC_TLSLDO)
7989
                         (match_operand:DI 1 "register_operand" "r"))))]
7990
  "TARGET_TLS && TARGET_ARCH64"
7991
  "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7992
  [(set_attr "type" "load")
7993
   (set_attr "us3load_type" "3cycle")])
7994
 
7995
(define_insn "*tldo_lduh1_sp64"
7996
  [(set (match_operand:SI 0 "register_operand" "=r")
7997
        (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7998
                                                     (match_operand 3 "tld_symbolic_operand" "")]
7999
                                                    UNSPEC_TLSLDO)
8000
                                         (match_operand:DI 1 "register_operand" "r")))))]
8001
  "TARGET_TLS && TARGET_ARCH64"
8002
  "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8003
  [(set_attr "type" "load")
8004
   (set_attr "us3load_type" "3cycle")])
8005
 
8006
(define_insn "*tldo_lduh2_sp64"
8007
  [(set (match_operand:DI 0 "register_operand" "=r")
8008
        (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8009
                                                     (match_operand 3 "tld_symbolic_operand" "")]
8010
                                                    UNSPEC_TLSLDO)
8011
                                         (match_operand:DI 1 "register_operand" "r")))))]
8012
  "TARGET_TLS && TARGET_ARCH64"
8013
  "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8014
  [(set_attr "type" "load")
8015
   (set_attr "us3load_type" "3cycle")])
8016
 
8017
(define_insn "*tldo_ldsh1_sp64"
8018
  [(set (match_operand:SI 0 "register_operand" "=r")
8019
        (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8020
                                                     (match_operand 3 "tld_symbolic_operand" "")]
8021
                                                    UNSPEC_TLSLDO)
8022
                                         (match_operand:DI 1 "register_operand" "r")))))]
8023
  "TARGET_TLS && TARGET_ARCH64"
8024
  "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8025
  [(set_attr "type" "sload")
8026
   (set_attr "us3load_type" "3cycle")])
8027
 
8028
(define_insn "*tldo_ldsh2_sp64"
8029
  [(set (match_operand:DI 0 "register_operand" "=r")
8030
        (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8031
                                                     (match_operand 3 "tld_symbolic_operand" "")]
8032
                                                    UNSPEC_TLSLDO)
8033
                                         (match_operand:DI 1 "register_operand" "r")))))]
8034
  "TARGET_TLS && TARGET_ARCH64"
8035
  "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8036
  [(set_attr "type" "sload")
8037
   (set_attr "us3load_type" "3cycle")])
8038
 
8039
(define_insn "*tldo_lduw_sp32"
8040
  [(set (match_operand:SI 0 "register_operand" "=r")
8041
        (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8042
                                     (match_operand 3 "tld_symbolic_operand" "")]
8043
                                    UNSPEC_TLSLDO)
8044
                         (match_operand:SI 1 "register_operand" "r"))))]
8045
  "TARGET_TLS && TARGET_ARCH32"
8046
  "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8047
  [(set_attr "type" "load")])
8048
 
8049
(define_insn "*tldo_lduw_sp64"
8050
  [(set (match_operand:SI 0 "register_operand" "=r")
8051
        (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8052
                                     (match_operand 3 "tld_symbolic_operand" "")]
8053
                                    UNSPEC_TLSLDO)
8054
                         (match_operand:DI 1 "register_operand" "r"))))]
8055
  "TARGET_TLS && TARGET_ARCH64"
8056
  "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8057
  [(set_attr "type" "load")])
8058
 
8059
(define_insn "*tldo_lduw1_sp64"
8060
  [(set (match_operand:DI 0 "register_operand" "=r")
8061
        (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8062
                                                     (match_operand 3 "tld_symbolic_operand" "")]
8063
                                                    UNSPEC_TLSLDO)
8064
                                         (match_operand:DI 1 "register_operand" "r")))))]
8065
  "TARGET_TLS && TARGET_ARCH64"
8066
  "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8067
  [(set_attr "type" "load")])
8068
 
8069
(define_insn "*tldo_ldsw1_sp64"
8070
  [(set (match_operand:DI 0 "register_operand" "=r")
8071
        (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8072
                                                     (match_operand 3 "tld_symbolic_operand" "")]
8073
                                                    UNSPEC_TLSLDO)
8074
                                         (match_operand:DI 1 "register_operand" "r")))))]
8075
  "TARGET_TLS && TARGET_ARCH64"
8076
  "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8077
  [(set_attr "type" "sload")
8078
   (set_attr "us3load_type" "3cycle")])
8079
 
8080
(define_insn "*tldo_ldx_sp64"
8081
  [(set (match_operand:DI 0 "register_operand" "=r")
8082
        (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8083
                                     (match_operand 3 "tld_symbolic_operand" "")]
8084
                                    UNSPEC_TLSLDO)
8085
                         (match_operand:DI 1 "register_operand" "r"))))]
8086
  "TARGET_TLS && TARGET_ARCH64"
8087
  "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8088
  [(set_attr "type" "load")])
8089
 
8090
(define_insn "*tldo_stb_sp32"
8091
  [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8092
                                     (match_operand 3 "tld_symbolic_operand" "")]
8093
                                    UNSPEC_TLSLDO)
8094
                         (match_operand:SI 1 "register_operand" "r")))
8095
        (match_operand:QI 0 "register_operand" "=r"))]
8096
  "TARGET_TLS && TARGET_ARCH32"
8097
  "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8098
  [(set_attr "type" "store")])
8099
 
8100
(define_insn "*tldo_stb_sp64"
8101
  [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8102
                                     (match_operand 3 "tld_symbolic_operand" "")]
8103
                                    UNSPEC_TLSLDO)
8104
                         (match_operand:DI 1 "register_operand" "r")))
8105
        (match_operand:QI 0 "register_operand" "=r"))]
8106
  "TARGET_TLS && TARGET_ARCH64"
8107
  "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8108
  [(set_attr "type" "store")])
8109
 
8110
(define_insn "*tldo_sth_sp32"
8111
  [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8112
                                     (match_operand 3 "tld_symbolic_operand" "")]
8113
                                    UNSPEC_TLSLDO)
8114
                         (match_operand:SI 1 "register_operand" "r")))
8115
        (match_operand:HI 0 "register_operand" "=r"))]
8116
  "TARGET_TLS && TARGET_ARCH32"
8117
  "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8118
  [(set_attr "type" "store")])
8119
 
8120
(define_insn "*tldo_sth_sp64"
8121
  [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8122
                                     (match_operand 3 "tld_symbolic_operand" "")]
8123
                                    UNSPEC_TLSLDO)
8124
                         (match_operand:DI 1 "register_operand" "r")))
8125
        (match_operand:HI 0 "register_operand" "=r"))]
8126
  "TARGET_TLS && TARGET_ARCH64"
8127
  "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8128
  [(set_attr "type" "store")])
8129
 
8130
(define_insn "*tldo_stw_sp32"
8131
  [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8132
                                     (match_operand 3 "tld_symbolic_operand" "")]
8133
                                    UNSPEC_TLSLDO)
8134
                         (match_operand:SI 1 "register_operand" "r")))
8135
        (match_operand:SI 0 "register_operand" "=r"))]
8136
  "TARGET_TLS && TARGET_ARCH32"
8137
  "st\t%0, [%1 + %2], %%tldo_add(%3)"
8138
  [(set_attr "type" "store")])
8139
 
8140
(define_insn "*tldo_stw_sp64"
8141
  [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8142
                                     (match_operand 3 "tld_symbolic_operand" "")]
8143
                                    UNSPEC_TLSLDO)
8144
                         (match_operand:DI 1 "register_operand" "r")))
8145
        (match_operand:SI 0 "register_operand" "=r"))]
8146
  "TARGET_TLS && TARGET_ARCH64"
8147
  "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8148
  [(set_attr "type" "store")])
8149
 
8150
(define_insn "*tldo_stx_sp64"
8151
  [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8152
                                     (match_operand 3 "tld_symbolic_operand" "")]
8153
                                    UNSPEC_TLSLDO)
8154
                         (match_operand:DI 1 "register_operand" "r")))
8155
        (match_operand:DI 0 "register_operand" "=r"))]
8156
  "TARGET_TLS && TARGET_ARCH64"
8157
  "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8158
  [(set_attr "type" "store")])
8159
 
8160
 
8161
;; Stack protector instructions.
8162
 
8163
(define_expand "stack_protect_set"
8164
  [(match_operand 0 "memory_operand" "")
8165
   (match_operand 1 "memory_operand" "")]
8166
  ""
8167
{
8168
#ifdef TARGET_THREAD_SSP_OFFSET
8169
  rtx tlsreg = gen_rtx_REG (Pmode, 7);
8170
  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8171
  operands[1] = gen_rtx_MEM (Pmode, addr);
8172
#endif
8173
  if (TARGET_ARCH64)
8174
    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8175
  else
8176
    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8177
  DONE;
8178
})
8179
 
8180
(define_insn "stack_protect_setsi"
8181
  [(set (match_operand:SI 0 "memory_operand" "=m")
8182
        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8183
   (set (match_scratch:SI 2 "=&r") (const_int 0))]
8184
  "TARGET_ARCH32"
8185
  "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8186
  [(set_attr "type" "multi")
8187
   (set_attr "length" "3")])
8188
 
8189
(define_insn "stack_protect_setdi"
8190
  [(set (match_operand:DI 0 "memory_operand" "=m")
8191
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8192
   (set (match_scratch:DI 2 "=&r") (const_int 0))]
8193
  "TARGET_ARCH64"
8194
  "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8195
  [(set_attr "type" "multi")
8196
   (set_attr "length" "3")])
8197
 
8198
(define_expand "stack_protect_test"
8199
  [(match_operand 0 "memory_operand" "")
8200
   (match_operand 1 "memory_operand" "")
8201
   (match_operand 2 "" "")]
8202
  ""
8203
{
8204
#ifdef TARGET_THREAD_SSP_OFFSET
8205
  rtx tlsreg = gen_rtx_REG (Pmode, 7);
8206
  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8207
  operands[1] = gen_rtx_MEM (Pmode, addr);
8208
#endif
8209
  if (TARGET_ARCH64)
8210
    {
8211
      rtx temp = gen_reg_rtx (Pmode);
8212
      emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8213
      sparc_compare_op0 = temp;
8214
      sparc_compare_op1 = const0_rtx;
8215
    }
8216
  else
8217
    {
8218
      emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8219
      sparc_compare_op0 = operands[0];
8220
      sparc_compare_op1 = operands[1];
8221
      sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8222
    }
8223
  emit_jump_insn (gen_beq (operands[2]));
8224
  DONE;
8225
})
8226
 
8227
(define_insn "stack_protect_testsi"
8228
  [(set (reg:CC 100)
8229
        (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8230
                    (match_operand:SI 1 "memory_operand" "m")]
8231
                   UNSPEC_SP_TEST))
8232
   (set (match_scratch:SI 3 "=r") (const_int 0))
8233
   (clobber (match_scratch:SI 2 "=&r"))]
8234
  "TARGET_ARCH32"
8235
  "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8236
  [(set_attr "type" "multi")
8237
   (set_attr "length" "4")])
8238
 
8239
(define_insn "stack_protect_testdi"
8240
  [(set (match_operand:DI 0 "register_operand" "=&r")
8241
        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8242
                    (match_operand:DI 2 "memory_operand" "m")]
8243
                   UNSPEC_SP_TEST))
8244
   (set (match_scratch:DI 3 "=r") (const_int 0))]
8245
  "TARGET_ARCH64"
8246
  "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8247
  [(set_attr "type" "multi")
8248
   (set_attr "length" "4")])
8249
 
8250
 
8251
;; Vector instructions.
8252
 
8253
(define_insn "addv2si3"
8254
  [(set (match_operand:V2SI 0 "register_operand" "=e")
8255
        (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8256
                   (match_operand:V2SI 2 "register_operand" "e")))]
8257
  "TARGET_VIS"
8258
  "fpadd32\t%1, %2, %0"
8259
  [(set_attr "type" "fga")
8260
   (set_attr "fptype" "double")])
8261
 
8262
(define_insn "addv4hi3"
8263
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8264
         (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8265
                    (match_operand:V4HI 2 "register_operand" "e")))]
8266
  "TARGET_VIS"
8267
  "fpadd16\t%1, %2, %0"
8268
  [(set_attr "type" "fga")
8269
   (set_attr "fptype" "double")])
8270
 
8271
;; fpadd32s is emitted by the addsi3 pattern.
8272
 
8273
(define_insn "addv2hi3"
8274
  [(set (match_operand:V2HI 0 "register_operand" "=f")
8275
        (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8276
                   (match_operand:V2HI 2 "register_operand" "f")))]
8277
  "TARGET_VIS"
8278
  "fpadd16s\t%1, %2, %0"
8279
  [(set_attr "type" "fga")
8280
   (set_attr "fptype" "single")])
8281
 
8282
(define_insn "subv2si3"
8283
  [(set (match_operand:V2SI 0 "register_operand" "=e")
8284
        (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8285
                    (match_operand:V2SI 2 "register_operand" "e")))]
8286
  "TARGET_VIS"
8287
  "fpsub32\t%1, %2, %0"
8288
  [(set_attr "type" "fga")
8289
   (set_attr "fptype" "double")])
8290
 
8291
(define_insn "subv4hi3"
8292
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8293
        (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8294
                    (match_operand:V4HI 2 "register_operand" "e")))]
8295
  "TARGET_VIS"
8296
  "fpsub16\t%1, %2, %0"
8297
  [(set_attr "type" "fga")
8298
   (set_attr "fptype" "double")])
8299
 
8300
;; fpsub32s is emitted by the subsi3 pattern.
8301
 
8302
(define_insn "subv2hi3"
8303
  [(set (match_operand:V2HI 0 "register_operand" "=f")
8304
        (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8305
                    (match_operand:V2HI 2 "register_operand" "f")))]
8306
  "TARGET_VIS"
8307
  "fpsub16s\t%1, %2, %0"
8308
  [(set_attr "type" "fga")
8309
   (set_attr "fptype" "single")])
8310
 
8311
;; All other logical instructions have integer equivalents so they
8312
;; are defined together.
8313
 
8314
;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8315
 
8316
(define_insn "*nand_vis"
8317
  [(set (match_operand:V64 0 "register_operand" "=e")
8318
        (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8319
                 (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8320
  "TARGET_VIS"
8321
  "fnand\t%1, %2, %0"
8322
  [(set_attr "type" "fga")
8323
   (set_attr "fptype" "double")])
8324
 
8325
(define_insn "*nand_vis"
8326
  [(set (match_operand:V32 0 "register_operand" "=f")
8327
         (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8328
                  (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8329
  "TARGET_VIS"
8330
  "fnands\t%1, %2, %0"
8331
  [(set_attr "type" "fga")
8332
   (set_attr "fptype" "single")])
8333
 
8334
;; Hard to generate VIS instructions.  We have builtins for these.
8335
 
8336
(define_insn "fpack16_vis"
8337
  [(set (match_operand:V4QI 0 "register_operand" "=f")
8338
        (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8339
                      UNSPEC_FPACK16))]
8340
  "TARGET_VIS"
8341
  "fpack16\t%1, %0"
8342
  [(set_attr "type" "fga")
8343
   (set_attr "fptype" "double")])
8344
 
8345
(define_insn "fpackfix_vis"
8346
  [(set (match_operand:V2HI 0 "register_operand" "=f")
8347
        (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8348
                      UNSPEC_FPACKFIX))]
8349
  "TARGET_VIS"
8350
  "fpackfix\t%1, %0"
8351
  [(set_attr "type" "fga")
8352
   (set_attr "fptype" "double")])
8353
 
8354
(define_insn "fpack32_vis"
8355
  [(set (match_operand:V8QI 0 "register_operand" "=e")
8356
        (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8357
                      (match_operand:V8QI 2 "register_operand" "e")]
8358
                     UNSPEC_FPACK32))]
8359
  "TARGET_VIS"
8360
  "fpack32\t%1, %2, %0"
8361
  [(set_attr "type" "fga")
8362
   (set_attr "fptype" "double")])
8363
 
8364
(define_insn "fexpand_vis"
8365
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8366
        (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8367
         UNSPEC_FEXPAND))]
8368
 "TARGET_VIS"
8369
 "fexpand\t%1, %0"
8370
 [(set_attr "type" "fga")
8371
  (set_attr "fptype" "double")])
8372
 
8373
;; It may be possible to describe this operation as (1 indexed):
8374
;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8375
;;  1,5,10,14,19,23,28,32)
8376
;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8377
;; because vec_merge expects all the operands to be of the same type.
8378
(define_insn "fpmerge_vis"
8379
  [(set (match_operand:V8QI 0 "register_operand" "=e")
8380
        (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8381
                      (match_operand:V4QI 2 "register_operand" "f")]
8382
         UNSPEC_FPMERGE))]
8383
 "TARGET_VIS"
8384
 "fpmerge\t%1, %2, %0"
8385
 [(set_attr "type" "fga")
8386
  (set_attr "fptype" "double")])
8387
 
8388
;; Partitioned multiply instructions
8389
(define_insn "fmul8x16_vis"
8390
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8391
        (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8392
                   (match_operand:V4HI 2 "register_operand" "e")))]
8393
  "TARGET_VIS"
8394
  "fmul8x16\t%1, %2, %0"
8395
  [(set_attr "type" "fpmul")
8396
   (set_attr "fptype" "double")])
8397
 
8398
;; Only one of the following two insns can be a multiply.
8399
(define_insn "fmul8x16au_vis"
8400
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8401
        (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8402
                   (match_operand:V2HI 2 "register_operand" "f")))]
8403
  "TARGET_VIS"
8404
  "fmul8x16au\t%1, %2, %0"
8405
  [(set_attr "type" "fpmul")
8406
   (set_attr "fptype" "double")])
8407
 
8408
(define_insn "fmul8x16al_vis"
8409
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8410
        (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8411
                      (match_operand:V2HI 2 "register_operand" "f")]
8412
         UNSPEC_MUL16AL))]
8413
  "TARGET_VIS"
8414
  "fmul8x16al\t%1, %2, %0"
8415
  [(set_attr "type" "fpmul")
8416
   (set_attr "fptype" "double")])
8417
 
8418
;; Only one of the following two insns can be a multiply.
8419
(define_insn "fmul8sux16_vis"
8420
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8421
        (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8422
                   (match_operand:V4HI 2 "register_operand" "e")))]
8423
  "TARGET_VIS"
8424
  "fmul8sux16\t%1, %2, %0"
8425
  [(set_attr "type" "fpmul")
8426
   (set_attr "fptype" "double")])
8427
 
8428
(define_insn "fmul8ulx16_vis"
8429
  [(set (match_operand:V4HI 0 "register_operand" "=e")
8430
        (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8431
                      (match_operand:V4HI 2 "register_operand" "e")]
8432
         UNSPEC_MUL8UL))]
8433
  "TARGET_VIS"
8434
  "fmul8ulx16\t%1, %2, %0"
8435
  [(set_attr "type" "fpmul")
8436
   (set_attr "fptype" "double")])
8437
 
8438
;; Only one of the following two insns can be a multiply.
8439
(define_insn "fmuld8sux16_vis"
8440
  [(set (match_operand:V2SI 0 "register_operand" "=e")
8441
        (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8442
                   (match_operand:V2HI 2 "register_operand" "f")))]
8443
  "TARGET_VIS"
8444
  "fmuld8sux16\t%1, %2, %0"
8445
  [(set_attr "type" "fpmul")
8446
   (set_attr "fptype" "double")])
8447
 
8448
(define_insn "fmuld8ulx16_vis"
8449
  [(set (match_operand:V2SI 0 "register_operand" "=e")
8450
        (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8451
                      (match_operand:V2HI 2 "register_operand" "f")]
8452
         UNSPEC_MULDUL))]
8453
  "TARGET_VIS"
8454
  "fmuld8ulx16\t%1, %2, %0"
8455
  [(set_attr "type" "fpmul")
8456
   (set_attr "fptype" "double")])
8457
 
8458
;; Using faligndata only makes sense after an alignaddr since the choice of
8459
;; bytes to take out of each operand is dependent on the results of the last
8460
;; alignaddr.
8461
(define_insn "faligndata_vis"
8462
  [(set (match_operand:V64I 0 "register_operand" "=e")
8463
        (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8464
                      (match_operand:V64I 2 "register_operand" "e")]
8465
         UNSPEC_ALIGNDATA))]
8466
  "TARGET_VIS"
8467
  "faligndata\t%1, %2, %0"
8468
  [(set_attr "type" "fga")
8469
   (set_attr "fptype" "double")])
8470
 
8471
(define_insn "alignaddr_vis"
8472
  [(set (match_operand:P 0 "register_operand" "=r")
8473
        (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8474
                   (match_operand:P 2 "register_or_zero_operand" "rJ")]
8475
         UNSPEC_ALIGNADDR))]
8476
  "TARGET_VIS"
8477
  "alignaddr\t%r1, %r2, %0")
8478
 
8479
(define_insn "pdist_vis"
8480
  [(set (match_operand:DI 0 "register_operand" "=e")
8481
        (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8482
                    (match_operand:V8QI 2 "register_operand" "e")
8483
                    (match_operand:DI 3 "register_operand" "0")]
8484
         UNSPEC_PDIST))]
8485
  "TARGET_VIS"
8486
  "pdist\t%1, %2, %0"
8487
  [(set_attr "type" "fga")
8488
   (set_attr "fptype" "double")])

powered by: WebSVN 2.1.0

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