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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [sparc/] [sparc.md] - Blame information for rev 820

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

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

powered by: WebSVN 2.1.0

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