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