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