OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [sparc/] [sparc.md] - Blame information for rev 437

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

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

powered by: WebSVN 2.1.0

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