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