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