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