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