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

Subversion Repositories openrisc

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

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

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

powered by: WebSVN 2.1.0

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