]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/i386.md
invoke.texi (i386 Options): Document x86-64 options.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
CommitLineData
d2836273 1;; GCC machine description for IA-32 and x86-64.
0e4970d7 2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
4592bdcb 3;; Free Software Foundation, Inc.
886c62d1 4;; Mostly by William Schelter.
d2836273 5;; x86_64 support added by Jan Hubicka
e075ae69 6;;
886c62d1 7;; This file is part of GNU CC.
e075ae69 8;;
886c62d1
JVA
9;; GNU CC is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 2, or (at your option)
12;; any later version.
e075ae69 13;;
886c62d1
JVA
14;; GNU CC is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
e075ae69 18;;
886c62d1
JVA
19;; You should have received a copy of the GNU General Public License
20;; along with GNU CC; see the file COPYING. If not, write to
3f63df56 21;; the Free Software Foundation, 59 Temple Place - Suite 330,
2ae0f82c 22;; Boston, MA 02111-1307, USA. */
e075ae69 23;;
4af3895e
JVA
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
e075ae69 26;;
4af3895e 27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
e075ae69 28;;
4af3895e
JVA
29;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30;; updates for most instructions.
e075ae69 31;;
4af3895e
JVA
32;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33;; constraint letters.
e075ae69
RH
34;;
35;; The special asm out single letter directives following a '%' are:
4af3895e
JVA
36;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
37;; operands[1].
38;; 'L' Print the opcode suffix for a 32-bit integer opcode.
39;; 'W' Print the opcode suffix for a 16-bit integer opcode.
40;; 'B' Print the opcode suffix for an 8-bit integer opcode.
4af3895e 41;; 'Q' Print the opcode suffix for a 64-bit float opcode.
56710e42 42;; 'S' Print the opcode suffix for a 32-bit float opcode.
b08de47e
MM
43;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44;; 'J' Print the appropriate jump operand.
e075ae69 45;;
4af3895e
JVA
46;; 'b' Print the QImode name of the register for the indicated operand.
47;; %b0 would print %al if operands[0] is reg 0.
48;; 'w' Likewise, print the HImode name of the register.
49;; 'k' Likewise, print the SImode name of the register.
50;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; 'y' Print "st(0)" instead of "st" as a register.
e075ae69 52;;
4af3895e
JVA
53;; UNSPEC usage:
54;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
55;; operand 0 is the memory address to scan.
56;; operand 1 is a register containing the value to scan for. The mode
57;; of the scas opcode will be the same as the mode of this operand.
58;; operand 2 is the known alignment of operand 0.
a199fdd6
JVA
59;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
60;; operand 0 is the argument for `sin'.
61;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
62;; operand 0 is the argument for `cos'.
578b58f5
RK
63;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
64;; always SImode. operand 0 is the size of the stack allocation.
47d36400
BS
65;; 4 This is the source of a fake SET of the frame pointer which is used to
66;; prevent insns referencing it being scheduled across the initial
67;; decrement of the stack pointer.
ce193852 68;; 5 This is a `bsf' operation.
91bb873f
RH
69;; 6 This is the @GOT offset of a PIC address.
70;; 7 This is the @GOTOFF offset of a PIC address.
71;; 8 This is a reference to a symbol's @PLT address.
e075ae69
RH
72;; 9 This is an `fnstsw' operation.
73;; 10 This is a `sahf' operation.
74;; 11 This is a `fstcw' operation
7e08e190 75;; 12 This is behaviour of add when setting carry flag.
1020a5ab 76;; 13 This is a `eh_return' placeholder.
915119a5
BS
77
78;; For SSE/MMX support:
79;; 30 This is `fix', guaranteed to be truncating.
80;; 31 This is a `emms' operation.
81;; 32 This is a `maskmov' operation.
82;; 33 This is a `movmsk' operation.
83;; 34 This is a `non-temporal' move.
84;; 35 This is a `prefetch' operation.
85;; 36 This is used to distinguish COMISS from UCOMISS.
86;; 37 This is a `ldmxcsr' operation.
87;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
88;; 39 This is a forced `movups' instruction (rather than whatever movti does)
89;; 40 This is a `stmxcsr' operation.
90;; 41 This is a `shuffle' operation.
91;; 42 This is a `rcp' operation.
92;; 43 This is a `rsqsrt' operation.
93;; 44 This is a `sfence' operation.
94;; 45 This is a noop to prevent excessive combiner cleverness.
47f339cf
BS
95;; 46 This is a `femms' operation.
96;; 47 This is a `prefetch' (3DNow) operation.
97;; 48 This is a `prefetchw' operation.
98;; 49 This is a 'pavgusb' operation.
99;; 50 This is a `pfrcp' operation.
100;; 51 This is a `pfrcpit1' operation.
101;; 52 This is a `pfrcpit2' operation.
102;; 53 This is a `pfrsqrt' operation.
103;; 54 This is a `pfrsqrit1' operation.
915119a5 104
6343a50e
ZW
105;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
106;; from i386.c.
107
1b0c37d7
ZW
108;; In C guard expressions, put expressions which may be compile-time
109;; constants first. This allows for better optimization. For
110;; example, write "TARGET_64BIT && reload_completed", not
111;; "reload_completed && TARGET_64BIT".
112
2ae0f82c 113\f
e075ae69
RH
114;; Processor type. This attribute must exactly match the processor_type
115;; enumeration in i386.h.
b4e89e2d 116(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
e075ae69 117 (const (symbol_ref "ix86_cpu")))
2ae0f82c 118
e075ae69
RH
119;; A basic instruction type. Refinements due to arguments to be
120;; provided in other attributes.
a269a03c 121(define_attr "type"
22fb740d 122 "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
e075ae69
RH
123 (const_string "other"))
124
6ef67412 125;; Main data type used by the insn
2b04e52b 126(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
6ef67412
JH
127 (const_string "unknown"))
128
129;; Set for i387 operations.
130(define_attr "i387" ""
22fb740d 131 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
6ef67412
JH
132 (const_int 1)
133 (const_int 0)))
134
135;; The (bounding maximum) length of an instruction immediate.
136(define_attr "length_immediate" ""
bd793c65 137 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
6ef67412
JH
138 (const_int 0)
139 (eq_attr "i387" "1")
140 (const_int 0)
141 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
142 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
143 (eq_attr "type" "imov,test")
144 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
145 (eq_attr "type" "call")
146 (if_then_else (match_operand 0 "constant_call_address_operand" "")
147 (const_int 4)
148 (const_int 0))
149 (eq_attr "type" "callv")
150 (if_then_else (match_operand 1 "constant_call_address_operand" "")
151 (const_int 4)
152 (const_int 0))
153 (eq_attr "type" "ibr")
154 (if_then_else (and (ge (minus (match_dup 0) (pc))
155 (const_int -128))
156 (lt (minus (match_dup 0) (pc))
157 (const_int 124)))
158 (const_int 1)
159 (const_int 4))
160 ]
161 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
e075ae69 162
6ef67412
JH
163;; The (bounding maximum) length of an instruction address.
164(define_attr "length_address" ""
165 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
166 (const_int 0)
167 (and (eq_attr "type" "call")
168 (match_operand 1 "constant_call_address_operand" ""))
169 (const_int 0)
170 (and (eq_attr "type" "callv")
171 (match_operand 1 "constant_call_address_operand" ""))
172 (const_int 0)
173 ]
174 (symbol_ref "ix86_attr_length_address_default (insn)")))
175
176;; Set when length prefix is used.
177(define_attr "prefix_data16" ""
178 (if_then_else (eq_attr "mode" "HI")
179 (const_int 1)
180 (const_int 0)))
181
182;; Set when string REP prefix is used.
183(define_attr "prefix_rep" "" (const_int 0))
184
185;; Set when 0f opcode prefix is used.
186(define_attr "prefix_0f" ""
bd793c65 187 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
6ef67412
JH
188 (const_int 1)
189 (const_int 0)))
190
191;; Set when modrm byte is used.
192(define_attr "modrm" ""
193 (cond [(eq_attr "type" "str,cld")
194 (const_int 0)
195 (eq_attr "i387" "1")
196 (const_int 0)
e075ae69
RH
197 (and (eq_attr "type" "incdec")
198 (ior (match_operand:SI 1 "register_operand" "")
199 (match_operand:HI 1 "register_operand" "")))
6ef67412 200 (const_int 0)
e075ae69
RH
201 (and (eq_attr "type" "push")
202 (not (match_operand 1 "memory_operand" "")))
6ef67412 203 (const_int 0)
e075ae69
RH
204 (and (eq_attr "type" "pop")
205 (not (match_operand 0 "memory_operand" "")))
6ef67412 206 (const_int 0)
e075ae69
RH
207 (and (eq_attr "type" "imov")
208 (and (match_operand 0 "register_operand" "")
209 (match_operand 1 "immediate_operand" "")))
6ef67412 210 (const_int 0)
e075ae69 211 ]
6ef67412
JH
212 (const_int 1)))
213
214;; The (bounding maximum) length of an instruction in bytes.
22fb740d
JH
215;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
216;; to split it and compute proper length as for other insns.
6ef67412 217(define_attr "length" ""
22fb740d 218 (cond [(eq_attr "type" "other,multi,fistp")
6ef67412
JH
219 (const_int 16)
220 ]
221 (plus (plus (attr "modrm")
222 (plus (attr "prefix_0f")
223 (plus (attr "i387")
224 (const_int 1))))
225 (plus (attr "prefix_rep")
226 (plus (attr "prefix_data16")
227 (plus (attr "length_immediate")
228 (attr "length_address")))))))
e075ae69
RH
229
230;; The `memory' attribute is `none' if no memory is referenced, `load' or
231;; `store' if there is a simple memory reference therein, or `unknown'
232;; if the instruction is complex.
233
234(define_attr "memory" "none,load,store,both,unknown"
7c7ef435 235 (cond [(eq_attr "type" "other,multi,str")
e075ae69 236 (const_string "unknown")
7c7ef435 237 (eq_attr "type" "lea,fcmov,fpspc,cld")
e075ae69 238 (const_string "none")
22fb740d
JH
239 (eq_attr "type" "fistp")
240 (const_string "both")
e075ae69
RH
241 (eq_attr "type" "push")
242 (if_then_else (match_operand 1 "memory_operand" "")
243 (const_string "both")
244 (const_string "store"))
245 (eq_attr "type" "pop,setcc")
246 (if_then_else (match_operand 0 "memory_operand" "")
247 (const_string "both")
248 (const_string "load"))
6ef67412 249 (eq_attr "type" "icmp,test")
e075ae69
RH
250 (if_then_else (ior (match_operand 0 "memory_operand" "")
251 (match_operand 1 "memory_operand" ""))
252 (const_string "load")
253 (const_string "none"))
254 (eq_attr "type" "ibr")
255 (if_then_else (match_operand 0 "memory_operand" "")
256 (const_string "load")
257 (const_string "none"))
258 (eq_attr "type" "call")
259 (if_then_else (match_operand 0 "constant_call_address_operand" "")
260 (const_string "none")
261 (const_string "load"))
262 (eq_attr "type" "callv")
263 (if_then_else (match_operand 1 "constant_call_address_operand" "")
264 (const_string "none")
265 (const_string "load"))
266 (and (eq_attr "type" "alu1,negnot")
a269a03c 267 (match_operand 1 "memory_operand" ""))
e075ae69
RH
268 (const_string "both")
269 (and (match_operand 0 "memory_operand" "")
270 (match_operand 1 "memory_operand" ""))
271 (const_string "both")
272 (match_operand 0 "memory_operand" "")
273 (const_string "store")
274 (match_operand 1 "memory_operand" "")
275 (const_string "load")
915119a5 276 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
e075ae69
RH
277 (match_operand 2 "memory_operand" ""))
278 (const_string "load")
279 (and (eq_attr "type" "icmov")
280 (match_operand 3 "memory_operand" ""))
281 (const_string "load")
282 ]
a269a03c
JC
283 (const_string "none")))
284
e075ae69
RH
285;; Indicates if an instruction has both an immediate and a displacement.
286
287(define_attr "imm_disp" "false,true,unknown"
288 (cond [(eq_attr "type" "other,multi")
289 (const_string "unknown")
6ef67412 290 (and (eq_attr "type" "icmp,test,imov")
e075ae69
RH
291 (and (match_operand 0 "memory_displacement_operand" "")
292 (match_operand 1 "immediate_operand" "")))
293 (const_string "true")
294 (and (eq_attr "type" "alu,ishift,imul,idiv")
295 (and (match_operand 0 "memory_displacement_operand" "")
296 (match_operand 2 "immediate_operand" "")))
297 (const_string "true")
298 ]
299 (const_string "false")))
300
301;; Indicates if an FP operation has an integer source.
302
303(define_attr "fp_int_src" "false,true"
304 (const_string "false"))
305
306;; Describe a user's asm statement.
307(define_asm_attributes
308 [(set_attr "length" "128")
309 (set_attr "type" "multi")])
310\f
311;; Pentium Scheduling
312;;
313;; The Pentium is an in-order core with two integer pipelines.
314
6ef67412
JH
315;; True for insns that behave like prefixed insns on the Pentium.
316(define_attr "pent_prefix" "false,true"
317 (if_then_else (ior (eq_attr "prefix_0f" "1")
318 (ior (eq_attr "prefix_data16" "1")
319 (eq_attr "prefix_rep" "1")))
320 (const_string "true")
321 (const_string "false")))
322
e075ae69
RH
323;; Categorize how an instruction slots.
324
325;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
326;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
327;; rules, because it results in noticeably better code on non-MMX Pentium
328;; and doesn't hurt much on MMX. (Prefixed instructions are not very
329;; common, so the scheduler usualy has a non-prefixed insn to pair).
330
331(define_attr "pent_pair" "uv,pu,pv,np"
332 (cond [(eq_attr "imm_disp" "true")
333 (const_string "np")
6ef67412
JH
334 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
335 (and (eq_attr "type" "pop,push")
336 (eq_attr "memory" "!both")))
337 (if_then_else (eq_attr "pent_prefix" "true")
e075ae69
RH
338 (const_string "pu")
339 (const_string "uv"))
340 (eq_attr "type" "ibr")
341 (const_string "pv")
342 (and (eq_attr "type" "ishift")
343 (match_operand 2 "const_int_operand" ""))
344 (const_string "pu")
e075ae69
RH
345 (and (eq_attr "type" "call")
346 (match_operand 0 "constant_call_address_operand" ""))
347 (const_string "pv")
348 (and (eq_attr "type" "callv")
349 (match_operand 1 "constant_call_address_operand" ""))
350 (const_string "pv")
351 ]
352 (const_string "np")))
353
354;; Rough readiness numbers. Fine tuning happens in i386.c.
355;;
356;; u describes pipe U
357;; v describes pipe V
358;; uv describes either pipe U or V for those that can issue to either
359;; np describes not paring
360;; fpu describes fpu
361;; fpm describes fp insns of different types are not pipelined.
362;;
363;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
2ae0f82c 364
e075ae69
RH
365(define_function_unit "pent_np" 1 0
366 (and (eq_attr "cpu" "pentium")
367 (eq_attr "type" "imul"))
368 11 11)
36cf4bcf 369
e075ae69
RH
370(define_function_unit "pent_mul" 1 1
371 (and (eq_attr "cpu" "pentium")
372 (eq_attr "type" "imul"))
373 11 11)
36cf4bcf 374
7c7ef435
JH
375;; Rep movs takes minimally 12 cycles.
376(define_function_unit "pent_np" 1 0
377 (and (eq_attr "cpu" "pentium")
378 (eq_attr "type" "str"))
379 12 12)
380
e075ae69
RH
381; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
382(define_function_unit "pent_np" 1 0
383 (and (eq_attr "cpu" "pentium")
384 (eq_attr "type" "idiv"))
385 46 46)
386
387; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
388; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
389; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
390; The integer <-> fp conversion is not modeled correctly. Fild behaves
391; like normal fp operation and fist takes 6 cycles.
392
393(define_function_unit "fpu" 1 0
394 (and (eq_attr "cpu" "pentium")
395 (and (eq_attr "type" "fmov")
2b589241
JH
396 (and (eq_attr "memory" "load,store")
397 (eq_attr "mode" "XF"))))
e075ae69
RH
398 3 3)
399
400(define_function_unit "pent_np" 1 0
401 (and (eq_attr "cpu" "pentium")
402 (and (eq_attr "type" "fmov")
2b589241
JH
403 (and (eq_attr "memory" "load,store")
404 (eq_attr "mode" "XF"))))
e075ae69
RH
405 3 3)
406
407(define_function_unit "fpu" 1 0
408 (and (eq_attr "cpu" "pentium")
409 (and (eq_attr "type" "fmov")
410 (ior (match_operand 1 "immediate_operand" "")
411 (eq_attr "memory" "store"))))
412 2 2)
36cf4bcf 413
e075ae69
RH
414(define_function_unit "pent_np" 1 0
415 (and (eq_attr "cpu" "pentium")
416 (and (eq_attr "type" "fmov")
417 (ior (match_operand 1 "immediate_operand" "")
418 (eq_attr "memory" "store"))))
419 2 2)
2ae0f82c 420
7c7ef435
JH
421(define_function_unit "pent_np" 1 0
422 (and (eq_attr "cpu" "pentium")
423 (eq_attr "type" "cld"))
424 2 2)
425
e075ae69
RH
426(define_function_unit "fpu" 1 0
427 (and (eq_attr "cpu" "pentium")
428 (and (eq_attr "type" "fmov")
429 (eq_attr "memory" "none,load")))
430 1 1)
431
432; Read/Modify/Write instructions usually take 3 cycles.
433(define_function_unit "pent_u" 1 0
434 (and (eq_attr "cpu" "pentium")
435 (and (eq_attr "type" "alu,alu1,ishift")
436 (and (eq_attr "pent_pair" "pu")
437 (eq_attr "memory" "both"))))
438 3 3)
439
440(define_function_unit "pent_uv" 2 0
441 (and (eq_attr "cpu" "pentium")
442 (and (eq_attr "type" "alu,alu1,ishift")
443 (and (eq_attr "pent_pair" "!np")
444 (eq_attr "memory" "both"))))
445 3 3)
446
447(define_function_unit "pent_np" 1 0
448 (and (eq_attr "cpu" "pentium")
449 (and (eq_attr "type" "alu,alu1,negnot,ishift")
450 (and (eq_attr "pent_pair" "np")
451 (eq_attr "memory" "both"))))
452 3 3)
453
454; Read/Modify or Modify/Write instructions usually take 2 cycles.
455(define_function_unit "pent_u" 1 0
456 (and (eq_attr "cpu" "pentium")
457 (and (eq_attr "type" "alu,ishift")
458 (and (eq_attr "pent_pair" "pu")
459 (eq_attr "memory" "load,store"))))
460 2 2)
2ae0f82c 461
e075ae69
RH
462(define_function_unit "pent_uv" 2 0
463 (and (eq_attr "cpu" "pentium")
464 (and (eq_attr "type" "alu,ishift")
465 (and (eq_attr "pent_pair" "!np")
466 (eq_attr "memory" "load,store"))))
467 2 2)
2ae0f82c 468
e075ae69
RH
469(define_function_unit "pent_np" 1 0
470 (and (eq_attr "cpu" "pentium")
471 (and (eq_attr "type" "alu,ishift")
472 (and (eq_attr "pent_pair" "np")
473 (eq_attr "memory" "load,store"))))
474 2 2)
36cf4bcf 475
e075ae69
RH
476; Insns w/o memory operands and move instructions usually take one cycle.
477(define_function_unit "pent_u" 1 0
478 (and (eq_attr "cpu" "pentium")
479 (eq_attr "pent_pair" "pu"))
480 1 1)
481
482(define_function_unit "pent_v" 1 0
483 (and (eq_attr "cpu" "pentium")
484 (eq_attr "pent_pair" "pv"))
485 1 1)
486
487(define_function_unit "pent_uv" 2 0
488 (and (eq_attr "cpu" "pentium")
489 (eq_attr "pent_pair" "!np"))
490 1 1)
491
492(define_function_unit "pent_np" 1 0
493 (and (eq_attr "cpu" "pentium")
494 (eq_attr "pent_pair" "np"))
495 1 1)
496
497; Pairable insns only conflict with other non-pairable insns.
498(define_function_unit "pent_np" 1 0
499 (and (eq_attr "cpu" "pentium")
500 (and (eq_attr "type" "alu,alu1,ishift")
501 (and (eq_attr "pent_pair" "!np")
502 (eq_attr "memory" "both"))))
503 3 3
504 [(eq_attr "pent_pair" "np")])
505
506(define_function_unit "pent_np" 1 0
507 (and (eq_attr "cpu" "pentium")
508 (and (eq_attr "type" "alu,alu1,ishift")
509 (and (eq_attr "pent_pair" "!np")
510 (eq_attr "memory" "load,store"))))
511 2 2
512 [(eq_attr "pent_pair" "np")])
513
514(define_function_unit "pent_np" 1 0
515 (and (eq_attr "cpu" "pentium")
516 (eq_attr "pent_pair" "!np"))
517 1 1
518 [(eq_attr "pent_pair" "np")])
519
520; Floating point instructions usually blocks cycle longer when combined with
521; integer instructions, because of the inpaired fxch instruction.
522(define_function_unit "pent_np" 1 0
523 (and (eq_attr "cpu" "pentium")
22fb740d 524 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
e075ae69 525 2 2
22fb740d 526 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
e075ae69
RH
527
528(define_function_unit "fpu" 1 0
529 (and (eq_attr "cpu" "pentium")
530 (eq_attr "type" "fcmp,fxch,fsgn"))
531 1 1)
532
533; Addition takes 3 cycles; assume other random cruft does as well.
534; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
535(define_function_unit "fpu" 1 0
536 (and (eq_attr "cpu" "pentium")
22fb740d 537 (eq_attr "type" "fop,fop1,fistp"))
e075ae69
RH
538 3 1)
539
540; Multiplication takes 3 cycles and is only half pipelined.
541(define_function_unit "fpu" 1 0
542 (and (eq_attr "cpu" "pentium")
543 (eq_attr "type" "fmul"))
544 3 1)
545
546(define_function_unit "pent_mul" 1 1
547 (and (eq_attr "cpu" "pentium")
548 (eq_attr "type" "fmul"))
549 2 2)
36cf4bcf 550
e075ae69
RH
551; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
552; They can overlap with integer insns. Only the last two cycles can overlap
553; with other fp insns. Only fsin/fcos can overlap with multiplies.
554; Only last two cycles of fsin/fcos can overlap with other instructions.
555(define_function_unit "fpu" 1 0
556 (and (eq_attr "cpu" "pentium")
557 (eq_attr "type" "fdiv"))
558 39 37)
559
560(define_function_unit "pent_mul" 1 1
561 (and (eq_attr "cpu" "pentium")
562 (eq_attr "type" "fdiv"))
563 39 39)
564
565(define_function_unit "fpu" 1 0
566 (and (eq_attr "cpu" "pentium")
567 (eq_attr "type" "fpspc"))
568 70 68)
569
570(define_function_unit "pent_mul" 1 1
571 (and (eq_attr "cpu" "pentium")
572 (eq_attr "type" "fpspc"))
573 70 70)
574\f
575;; Pentium Pro/PII Scheduling
576;;
577;; The PPro has an out-of-order core, but the instruction decoders are
578;; naturally in-order and asymmetric. We get best performance by scheduling
579;; for the decoders, for in doing so we give the oo execution unit the
580;; most choices.
581
582;; Categorize how many uops an ia32 instruction evaluates to:
583;; one -- an instruction with 1 uop can be decoded by any of the
584;; three decoders.
585;; few -- an instruction with 1 to 4 uops can be decoded only by
586;; decoder 0.
587;; many -- a complex instruction may take an unspecified number of
588;; cycles to decode in decoder 0.
589
590(define_attr "ppro_uops" "one,few,many"
7c7ef435 591 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
e075ae69 592 (const_string "many")
7c7ef435 593 (eq_attr "type" "icmov,fcmov,str,cld")
e075ae69
RH
594 (const_string "few")
595 (eq_attr "type" "imov")
596 (if_then_else (eq_attr "memory" "store,both")
597 (const_string "few")
598 (const_string "one"))
599 (eq_attr "memory" "!none")
600 (const_string "few")
601 ]
602 (const_string "one")))
603
604;; Rough readiness numbers. Fine tuning happens in i386.c.
605;;
606;; p0 describes port 0.
607;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
608;; p2 describes port 2 for loads.
609;; p34 describes ports 3 and 4 for stores.
610;; fpu describes the fpu accessed via port 0.
611;; ??? It is less than clear if there are separate fadd and fmul units
612;; that could operate in parallel.
613;;
614;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
615
616(define_function_unit "ppro_p0" 1 0
617 (and (eq_attr "cpu" "pentiumpro")
7c7ef435 618 (eq_attr "type" "ishift,lea,ibr,cld"))
e075ae69
RH
619 1 1)
620
621(define_function_unit "ppro_p0" 1 0
622 (and (eq_attr "cpu" "pentiumpro")
623 (eq_attr "type" "imul"))
624 4 1)
625
626;; ??? Does the divider lock out the pipe while it works,
627;; or is there a disconnected unit?
628(define_function_unit "ppro_p0" 1 0
629 (and (eq_attr "cpu" "pentiumpro")
630 (eq_attr "type" "idiv"))
631 17 17)
36cf4bcf 632
e075ae69
RH
633(define_function_unit "ppro_p0" 1 0
634 (and (eq_attr "cpu" "pentiumpro")
22fb740d 635 (eq_attr "type" "fop,fop1,fsgn,fistp"))
e075ae69
RH
636 3 1)
637
638(define_function_unit "ppro_p0" 1 0
639 (and (eq_attr "cpu" "pentiumpro")
640 (eq_attr "type" "fcmov"))
641 2 1)
642
643(define_function_unit "ppro_p0" 1 0
644 (and (eq_attr "cpu" "pentiumpro")
645 (eq_attr "type" "fcmp"))
646 1 1)
647
648(define_function_unit "ppro_p0" 1 0
649 (and (eq_attr "cpu" "pentiumpro")
650 (eq_attr "type" "fmov"))
651 1 1)
652
653(define_function_unit "ppro_p0" 1 0
654 (and (eq_attr "cpu" "pentiumpro")
655 (eq_attr "type" "fmul"))
656 5 1)
657
658(define_function_unit "ppro_p0" 1 0
659 (and (eq_attr "cpu" "pentiumpro")
660 (eq_attr "type" "fdiv,fpspc"))
661 56 1)
662
663(define_function_unit "ppro_p01" 2 0
664 (and (eq_attr "cpu" "pentiumpro")
665 (eq_attr "type" "!imov,fmov"))
666 1 1)
667
668(define_function_unit "ppro_p01" 2 0
669 (and (and (eq_attr "cpu" "pentiumpro")
670 (eq_attr "type" "imov,fmov"))
671 (eq_attr "memory" "none"))
672 1 1)
673
674(define_function_unit "ppro_p2" 1 0
675 (and (eq_attr "cpu" "pentiumpro")
676 (ior (eq_attr "type" "pop")
677 (eq_attr "memory" "load,both")))
678 3 1)
679
680(define_function_unit "ppro_p34" 1 0
681 (and (eq_attr "cpu" "pentiumpro")
682 (ior (eq_attr "type" "push")
683 (eq_attr "memory" "store,both")))
684 1 1)
685
686(define_function_unit "fpu" 1 0
687 (and (eq_attr "cpu" "pentiumpro")
22fb740d 688 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
e075ae69
RH
689 1 1)
690
691(define_function_unit "fpu" 1 0
692 (and (eq_attr "cpu" "pentiumpro")
693 (eq_attr "type" "fmul"))
694 5 2)
695
696(define_function_unit "fpu" 1 0
697 (and (eq_attr "cpu" "pentiumpro")
698 (eq_attr "type" "fdiv,fpspc"))
699 56 56)
700
701;; imul uses the fpu. ??? does it have the same throughput as fmul?
702(define_function_unit "fpu" 1 0
703 (and (eq_attr "cpu" "pentiumpro")
704 (eq_attr "type" "imul"))
705 4 1)
706\f
707;; AMD K6/K6-2 Scheduling
708;;
709;; The K6 has similar architecture to PPro. Important difference is, that
710;; there are only two decoders and they seems to be much slower than execution
711;; units. So we have to pay much more attention to proper decoding for
712;; schedulers. We share most of scheduler code for PPro in i386.c
713;;
714;; The fp unit is not pipelined and do one operation per two cycles including
715;; the FXCH.
716;;
717;; alu describes both ALU units (ALU-X and ALU-Y).
718;; alux describes X alu unit
719;; fpu describes FPU unit
720;; load describes load unit.
721;; branch describes branch unit.
722;; store decsribes store unit. This unit is not modelled completely and only
723;; used to model lea operation. Otherwise it lie outside of the critical
724;; path.
725;;
726;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
36cf4bcf 727
e075ae69 728;; The decoder specification is in the PPro section above!
2ae0f82c 729
e075ae69
RH
730;; Shift instructions and certain arithmetic are issued only to X pipe.
731(define_function_unit "k6_alux" 1 0
732 (and (eq_attr "cpu" "k6")
7c7ef435 733 (eq_attr "type" "ishift,alu1,negnot,cld"))
e075ae69 734 1 1)
2ae0f82c 735
e075ae69
RH
736;; The QI mode arithmetic is issued to X pipe only.
737(define_function_unit "k6_alux" 1 0
738 (and (eq_attr "cpu" "k6")
6ef67412 739 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
e075ae69
RH
740 (match_operand:QI 0 "general_operand" "")))
741 1 1)
a269a03c 742
e075ae69
RH
743(define_function_unit "k6_alu" 2 0
744 (and (eq_attr "cpu" "k6")
6ef67412 745 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
e075ae69 746 1 1)
a269a03c 747
e075ae69
RH
748(define_function_unit "k6_alu" 2 0
749 (and (eq_attr "cpu" "k6")
750 (and (eq_attr "type" "imov")
751 (eq_attr "memory" "none")))
752 1 1)
a269a03c 753
e075ae69 754(define_function_unit "k6_branch" 1 0
a269a03c 755 (and (eq_attr "cpu" "k6")
e075ae69
RH
756 (eq_attr "type" "call,callv,ibr"))
757 1 1)
a269a03c 758
e075ae69
RH
759;; Load unit have two cycle latency, but we take care for it in adjust_cost
760(define_function_unit "k6_load" 1 0
a269a03c 761 (and (eq_attr "cpu" "k6")
e075ae69
RH
762 (ior (eq_attr "type" "pop")
763 (eq_attr "memory" "load,both")))
764 1 1)
a269a03c 765
7c7ef435
JH
766(define_function_unit "k6_load" 1 0
767 (and (eq_attr "cpu" "k6")
768 (and (eq_attr "type" "str")
769 (eq_attr "memory" "load,both")))
770 10 10)
771
e075ae69
RH
772;; Lea have two instructions, so latency is probably 2
773(define_function_unit "k6_store" 1 0
774 (and (eq_attr "cpu" "k6")
775 (eq_attr "type" "lea"))
776 2 1)
a269a03c 777
7c7ef435
JH
778(define_function_unit "k6_store" 1 0
779 (and (eq_attr "cpu" "k6")
780 (eq_attr "type" "str"))
781 10 10)
782
e075ae69
RH
783(define_function_unit "k6_store" 1 0
784 (and (eq_attr "cpu" "k6")
785 (ior (eq_attr "type" "push")
786 (eq_attr "memory" "store,both")))
787 1 1)
a269a03c 788
e075ae69
RH
789(define_function_unit "k6_fpu" 1 1
790 (and (eq_attr "cpu" "k6")
22fb740d 791 (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
e075ae69 792 2 2)
a269a03c 793
e075ae69
RH
794(define_function_unit "k6_fpu" 1 1
795 (and (eq_attr "cpu" "k6")
796 (eq_attr "type" "fmul"))
797 2 2)
a269a03c 798
e075ae69
RH
799;; ??? Guess
800(define_function_unit "k6_fpu" 1 1
801 (and (eq_attr "cpu" "k6")
802 (eq_attr "type" "fdiv,fpspc"))
803 56 56)
a269a03c 804
e075ae69
RH
805(define_function_unit "k6_alu" 2 0
806 (and (eq_attr "cpu" "k6")
807 (eq_attr "type" "imul"))
808 2 2)
a269a03c 809
e075ae69
RH
810(define_function_unit "k6_alux" 1 0
811 (and (eq_attr "cpu" "k6")
812 (eq_attr "type" "imul"))
813 2 2)
a269a03c 814
e075ae69
RH
815;; ??? Guess
816(define_function_unit "k6_alu" 2 0
817 (and (eq_attr "cpu" "k6")
818 (eq_attr "type" "idiv"))
819 17 17)
2ae0f82c 820
e075ae69
RH
821(define_function_unit "k6_alux" 1 0
822 (and (eq_attr "cpu" "k6")
823 (eq_attr "type" "idiv"))
824 17 17)
886c62d1 825\f
309ada50
JH
826;; AMD Athlon Scheduling
827;;
828;; The Athlon does contain three pipelined FP units, three integer units and
829;; three address generation units.
830;;
831;; The predecode logic is determining boundaries of instructions in the 64
832;; byte cache line. So the cache line straddling problem of K6 might be issue
833;; here as well, but it is not noted in the documentation.
834;;
835;; Three DirectPath instructions decoders and only one VectorPath decoder
836;; is available. They can decode three DirectPath instructions or one VectorPath
837;; instruction per cycle.
838;; Decoded macro instructions are then passed to 72 entry instruction control
839;; unit, that passes
840;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
841;;
842;; The load/store queue unit is not attached to the schedulers but
843;; communicates with all the execution units seperately instead.
844
845(define_attr "athlon_decode" "direct,vector"
0b5107cf 846 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
309ada50
JH
847 (const_string "vector")
848 (and (eq_attr "type" "push")
849 (match_operand 1 "memory_operand" ""))
850 (const_string "vector")
851 (and (eq_attr "type" "fmov")
2b589241
JH
852 (and (eq_attr "memory" "load,store")
853 (eq_attr "mode" "XF")))
309ada50
JH
854 (const_string "vector")]
855 (const_string "direct")))
856
857(define_function_unit "athlon_vectordec" 1 0
858 (and (eq_attr "cpu" "athlon")
859 (eq_attr "athlon_decode" "vector"))
860 1 1)
861
862(define_function_unit "athlon_directdec" 3 0
863 (and (eq_attr "cpu" "athlon")
864 (eq_attr "athlon_decode" "direct"))
865 1 1)
866
867(define_function_unit "athlon_vectordec" 1 0
868 (and (eq_attr "cpu" "athlon")
869 (eq_attr "athlon_decode" "direct"))
870 1 1 [(eq_attr "athlon_decode" "vector")])
871
872(define_function_unit "athlon_ieu" 3 0
873 (and (eq_attr "cpu" "athlon")
6ef67412 874 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
309ada50
JH
875 1 1)
876
7c7ef435
JH
877(define_function_unit "athlon_ieu" 3 0
878 (and (eq_attr "cpu" "athlon")
879 (eq_attr "type" "str"))
880 15 15)
881
309ada50
JH
882(define_function_unit "athlon_ieu" 3 0
883 (and (eq_attr "cpu" "athlon")
884 (eq_attr "type" "imul"))
0b5107cf 885 5 0)
309ada50
JH
886
887(define_function_unit "athlon_ieu" 3 0
888 (and (eq_attr "cpu" "athlon")
889 (eq_attr "type" "idiv"))
0b5107cf 890 42 0)
309ada50
JH
891
892(define_function_unit "athlon_muldiv" 1 0
893 (and (eq_attr "cpu" "athlon")
894 (eq_attr "type" "imul"))
895 5 0)
896
897(define_function_unit "athlon_muldiv" 1 0
898 (and (eq_attr "cpu" "athlon")
899 (eq_attr "type" "idiv"))
0b5107cf 900 42 42)
309ada50 901
0b5107cf 902(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
22fb740d 903 (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
309ada50 904 (const_string "add")
0b5107cf 905 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
309ada50 906 (const_string "mul")
0b5107cf 907 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
309ada50 908 (const_string "store")
0b5107cf
JH
909 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
910 (const_string "any")
309ada50
JH
911 (and (eq_attr "type" "fmov")
912 (ior (match_operand:SI 1 "register_operand" "")
913 (match_operand 1 "immediate_operand" "")))
914 (const_string "store")
915 (eq_attr "type" "fmov")
0b5107cf 916 (const_string "muladd")]
309ada50
JH
917 (const_string "none")))
918
0b5107cf
JH
919;; We use latencies 1 for definitions. This is OK to model colisions
920;; in execution units. The real latencies are modeled in the "fp" pipeline.
921
922;; fsin, fcos: 96-192
923;; fsincos: 107-211
924;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
925(define_function_unit "athlon_fp" 3 0
309ada50 926 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
927 (eq_attr "type" "fpspc"))
928 100 1)
309ada50 929
0b5107cf
JH
930;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
931(define_function_unit "athlon_fp" 3 0
309ada50 932 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
933 (eq_attr "type" "fdiv"))
934 24 1)
935
936(define_function_unit "athlon_fp" 3 0
937 (and (eq_attr "cpu" "athlon")
22fb740d 938 (eq_attr "type" "fop,fop1,fmul,fistp"))
309ada50
JH
939 4 1)
940
0b5107cf
JH
941;; XFmode loads are slow.
942;; XFmode store is slow too (8 cycles), but we don't need to model it, because
943;; there are no dependent instructions.
944
945(define_function_unit "athlon_fp" 3 0
309ada50
JH
946 (and (eq_attr "cpu" "athlon")
947 (and (eq_attr "type" "fmov")
2b589241
JH
948 (and (eq_attr "memory" "load")
949 (eq_attr "mode" "XF"))))
0b5107cf
JH
950 10 1)
951
952(define_function_unit "athlon_fp" 3 0
953 (and (eq_attr "cpu" "athlon")
954 (eq_attr "type" "fmov,fsgn"))
309ada50
JH
955 2 1)
956
0b5107cf
JH
957;; fcmp and ftst instructions
958(define_function_unit "athlon_fp" 3 0
959 (and (eq_attr "cpu" "athlon")
960 (and (eq_attr "type" "fcmp")
961 (eq_attr "athlon_decode" "direct")))
962 3 1)
963
964;; fcmpi instructions.
965(define_function_unit "athlon_fp" 3 0
966 (and (eq_attr "cpu" "athlon")
967 (and (eq_attr "type" "fcmp")
968 (eq_attr "athlon_decode" "vector")))
969 3 1)
970
971(define_function_unit "athlon_fp" 3 0
972 (and (eq_attr "cpu" "athlon")
973 (eq_attr "type" "fcmov"))
974 7 1)
975
976(define_function_unit "athlon_fp_mul" 1 0
977 (and (eq_attr "cpu" "athlon")
978 (eq_attr "athlon_fpunits" "mul"))
979 1 1)
980
981(define_function_unit "athlon_fp_add" 1 0
982 (and (eq_attr "cpu" "athlon")
983 (eq_attr "athlon_fpunits" "add"))
984 1 1)
985
309ada50
JH
986(define_function_unit "athlon_fp_muladd" 2 0
987 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
988 (eq_attr "athlon_fpunits" "muladd,mul,add"))
989 1 1)
309ada50
JH
990
991(define_function_unit "athlon_fp_store" 1 0
992 (and (eq_attr "cpu" "athlon")
0b5107cf 993 (eq_attr "athlon_fpunits" "store"))
309ada50
JH
994 1 1)
995
0b5107cf
JH
996;; We don't need to model the Adress Generation Unit, since we don't model
997;; the re-order buffer yet and thus we never schedule more than three operations
998;; at time. Later we may want to experiment with MD_SCHED macros modeling the
999;; decoders independently on the functional units.
1000
1001;(define_function_unit "athlon_agu" 3 0
1002; (and (eq_attr "cpu" "athlon")
1003; (and (eq_attr "memory" "!none")
1004; (eq_attr "athlon_fpunits" "none")))
1005; 1 1)
1006
1007;; Model load unit to avoid too long sequences of loads. We don't need to
1008;; model store queue, since it is hardly going to be bottleneck.
1009
1010(define_function_unit "athlon_load" 2 0
309ada50 1011 (and (eq_attr "cpu" "athlon")
0b5107cf 1012 (eq_attr "memory" "load,both"))
309ada50
JH
1013 1 1)
1014
1015\f
e075ae69 1016;; Compare instructions.
886c62d1 1017
e075ae69 1018;; All compare insns have expanders that save the operands away without
c572e5ba 1019;; actually generating RTL. The bCOND or sCOND (emitted immediately
e075ae69 1020;; after the cmp) will actually emit the cmpM.
886c62d1 1021
e075ae69
RH
1022(define_expand "cmpdi"
1023 [(set (reg:CC 17)
b9b2c339 1024 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
9b70259d 1025 (match_operand:DI 1 "x86_64_general_operand" "")))]
c572e5ba 1026 ""
c572e5ba 1027{
b9b2c339 1028 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
1029 operands[0] = force_reg (DImode, operands[0]);
1030 ix86_compare_op0 = operands[0];
1031 ix86_compare_op1 = operands[1];
c572e5ba 1032 DONE;
0f40f9f7 1033})
c572e5ba 1034
e075ae69
RH
1035(define_expand "cmpsi"
1036 [(set (reg:CC 17)
1037 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1038 (match_operand:SI 1 "general_operand" "")))]
c572e5ba 1039 ""
c572e5ba 1040{
b9b2c339 1041 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
1042 operands[0] = force_reg (SImode, operands[0]);
1043 ix86_compare_op0 = operands[0];
1044 ix86_compare_op1 = operands[1];
c572e5ba 1045 DONE;
0f40f9f7 1046})
c572e5ba 1047
e075ae69
RH
1048(define_expand "cmphi"
1049 [(set (reg:CC 17)
b9b2c339 1050 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69 1051 (match_operand:HI 1 "general_operand" "")))]
c572e5ba 1052 ""
c572e5ba 1053{
b9b2c339 1054 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
1055 operands[0] = force_reg (HImode, operands[0]);
1056 ix86_compare_op0 = operands[0];
1057 ix86_compare_op1 = operands[1];
c572e5ba 1058 DONE;
0f40f9f7 1059})
c572e5ba 1060
e075ae69
RH
1061(define_expand "cmpqi"
1062 [(set (reg:CC 17)
b9b2c339 1063 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
e075ae69 1064 (match_operand:QI 1 "general_operand" "")))]
d9f32422 1065 "TARGET_QIMODE_MATH"
c572e5ba 1066{
b9b2c339 1067 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
e075ae69
RH
1068 operands[0] = force_reg (QImode, operands[0]);
1069 ix86_compare_op0 = operands[0];
1070 ix86_compare_op1 = operands[1];
c572e5ba 1071 DONE;
0f40f9f7 1072})
886c62d1 1073
9b70259d
JH
1074(define_insn "cmpdi_ccno_1_rex64"
1075 [(set (reg 17)
1076 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1077 (match_operand:DI 1 "const0_operand" "n,n")))]
1078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1079 "@
0f40f9f7
ZW
1080 test{q}\t{%0, %0|%0, %0}
1081 cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
1082 [(set_attr "type" "test,icmp")
1083 (set_attr "length_immediate" "0,1")
1084 (set_attr "mode" "DI")])
1085
1086(define_insn "*cmpdi_minus_1_rex64"
1087 [(set (reg 17)
1088 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1089 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1090 (const_int 0)))]
1b0c37d7 1091 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1092 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "DI")])
1095
1096(define_expand "cmpdi_1_rex64"
1097 [(set (reg:CC 17)
1098 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1099 (match_operand:DI 1 "general_operand" "")))]
1b0c37d7 1100 "TARGET_64BIT"
9b70259d
JH
1101 "")
1102
1103(define_insn "cmpdi_1_insn_rex64"
1104 [(set (reg 17)
1105 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1106 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1107 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1108 "cmp{q}\t{%1, %0|%0, %1}"
9b70259d
JH
1109 [(set_attr "type" "icmp")
1110 (set_attr "mode" "DI")])
1111
1112
9076b9c1
JH
1113(define_insn "*cmpsi_ccno_1"
1114 [(set (reg 17)
1115 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1116 (match_operand:SI 1 "const0_operand" "n,n")))]
1117 "ix86_match_ccmode (insn, CCNOmode)"
16189740 1118 "@
0f40f9f7
ZW
1119 test{l}\t{%0, %0|%0, %0}
1120 cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
1121 [(set_attr "type" "test,icmp")
1122 (set_attr "length_immediate" "0,1")
1123 (set_attr "mode" "SI")])
16189740 1124
9076b9c1
JH
1125(define_insn "*cmpsi_minus_1"
1126 [(set (reg 17)
1127 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1128 (match_operand:SI 1 "general_operand" "ri,mr"))
1129 (const_int 0)))]
1130 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1131 "cmp{l}\t{%1, %0|%0, %1}"
9076b9c1 1132 [(set_attr "type" "icmp")
6ef67412 1133 (set_attr "mode" "SI")])
886c62d1 1134
9076b9c1 1135(define_expand "cmpsi_1"
e075ae69
RH
1136 [(set (reg:CC 17)
1137 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1138 (match_operand:SI 1 "general_operand" "ri,mr")))]
9076b9c1
JH
1139 ""
1140 "")
1141
1142(define_insn "*cmpsi_1_insn"
1143 [(set (reg 17)
1144 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1145 (match_operand:SI 1 "general_operand" "ri,mr")))]
1146 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1147 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1148 "cmp{l}\t{%1, %0|%0, %1}"
6ef67412
JH
1149 [(set_attr "type" "icmp")
1150 (set_attr "mode" "SI")])
886c62d1 1151
9076b9c1 1152(define_insn "*cmphi_ccno_1"
16189740
RH
1153 [(set (reg 17)
1154 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1155 (match_operand:HI 1 "const0_operand" "n,n")))]
1156 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 1157 "@
0f40f9f7
ZW
1158 test{w}\t{%0, %0|%0, %0}
1159 cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1160 [(set_attr "type" "test,icmp")
1161 (set_attr "length_immediate" "0,1")
1162 (set_attr "mode" "HI")])
886c62d1 1163
9076b9c1
JH
1164(define_insn "*cmphi_minus_1"
1165 [(set (reg 17)
1166 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1167 (match_operand:HI 1 "general_operand" "ri,mr"))
1168 (const_int 0)))]
1169 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1170 "cmp{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1171 [(set_attr "type" "icmp")
1172 (set_attr "mode" "HI")])
e075ae69 1173
9076b9c1
JH
1174(define_insn "*cmphi_1"
1175 [(set (reg 17)
1176 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1177 (match_operand:HI 1 "general_operand" "ri,mr")))]
1178 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1179 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1180 "cmp{w}\t{%1, %0|%0, %1}"
9076b9c1
JH
1181 [(set_attr "type" "icmp")
1182 (set_attr "mode" "HI")])
16189740
RH
1183
1184(define_insn "*cmpqi_ccno_1"
9076b9c1
JH
1185 [(set (reg 17)
1186 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1187 (match_operand:QI 1 "const0_operand" "n,n")))]
1188 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 1189 "@
0f40f9f7
ZW
1190 test{b}\t{%0, %0|%0, %0}
1191 cmp{b}\t{$0, %0|%0, 0}"
6ef67412
JH
1192 [(set_attr "type" "test,icmp")
1193 (set_attr "length_immediate" "0,1")
1194 (set_attr "mode" "QI")])
886c62d1 1195
16189740 1196(define_insn "*cmpqi_1"
9076b9c1
JH
1197 [(set (reg 17)
1198 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1199 (match_operand:QI 1 "general_operand" "qi,mq")))]
1200 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1201 && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1202 "cmp{b}\t{%1, %0|%0, %1}"
6ef67412
JH
1203 [(set_attr "type" "icmp")
1204 (set_attr "mode" "QI")])
e075ae69 1205
9076b9c1
JH
1206(define_insn "*cmpqi_minus_1"
1207 [(set (reg 17)
d70401eb
JJ
1208 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1209 (match_operand:QI 1 "general_operand" "qi,mq"))
9076b9c1
JH
1210 (const_int 0)))]
1211 "ix86_match_ccmode (insn, CCGOCmode)"
0f40f9f7 1212 "cmp{b}\t{%1, %0|%0, %1}"
9076b9c1
JH
1213 [(set_attr "type" "icmp")
1214 (set_attr "mode" "QI")])
1215
e075ae69 1216(define_insn "*cmpqi_ext_1"
9076b9c1
JH
1217 [(set (reg 17)
1218 (compare
d2836273 1219 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
1220 (subreg:QI
1221 (zero_extract:SI
d2836273 1222 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1223 (const_int 8)
1224 (const_int 8)) 0)))]
d2836273 1225 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1226 "cmp{b}\t{%h1, %0|%0, %h1}"
d2836273
JH
1227 [(set_attr "type" "icmp")
1228 (set_attr "mode" "QI")])
1229
1230(define_insn "*cmpqi_ext_1_rex64"
1231 [(set (reg 17)
1232 (compare
3522082b 1233 (match_operand:QI 0 "register_operand" "Q")
d2836273
JH
1234 (subreg:QI
1235 (zero_extract:SI
1236 (match_operand 1 "ext_register_operand" "Q")
1237 (const_int 8)
1238 (const_int 8)) 0)))]
1239 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1240 "cmp{b}\t{%h1, %0|%0, %h1}"
6ef67412
JH
1241 [(set_attr "type" "icmp")
1242 (set_attr "mode" "QI")])
e075ae69
RH
1243
1244(define_insn "*cmpqi_ext_2"
16189740
RH
1245 [(set (reg 17)
1246 (compare
e075ae69
RH
1247 (subreg:QI
1248 (zero_extract:SI
d2836273 1249 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1250 (const_int 8)
1251 (const_int 8)) 0)
1252 (match_operand:QI 1 "const0_operand" "n")))]
16189740 1253 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 1254 "test{b}\t%h0, %h0"
6ef67412
JH
1255 [(set_attr "type" "test")
1256 (set_attr "length_immediate" "0")
1257 (set_attr "mode" "QI")])
e075ae69 1258
9076b9c1 1259(define_expand "cmpqi_ext_3"
e075ae69
RH
1260 [(set (reg:CC 17)
1261 (compare:CC
1262 (subreg:QI
1263 (zero_extract:SI
d2836273 1264 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
1265 (const_int 8)
1266 (const_int 8)) 0)
d2836273 1267 (match_operand:QI 1 "general_operand" "")))]
e075ae69 1268 ""
9076b9c1
JH
1269 "")
1270
1271(define_insn "cmpqi_ext_3_insn"
1272 [(set (reg 17)
1273 (compare
1274 (subreg:QI
1275 (zero_extract:SI
d2836273 1276 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
1277 (const_int 8)
1278 (const_int 8)) 0)
d2836273
JH
1279 (match_operand:QI 1 "general_operand" "Qmn")))]
1280 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1281 "cmp{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
1282 [(set_attr "type" "icmp")
1283 (set_attr "mode" "QI")])
1284
1285(define_insn "cmpqi_ext_3_insn_rex64"
1286 [(set (reg 17)
1287 (compare
1288 (subreg:QI
1289 (zero_extract:SI
1290 (match_operand 0 "ext_register_operand" "Q")
1291 (const_int 8)
1292 (const_int 8)) 0)
1293 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1294 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1295 "cmp{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
1296 [(set_attr "type" "icmp")
1297 (set_attr "mode" "QI")])
e075ae69
RH
1298
1299(define_insn "*cmpqi_ext_4"
9076b9c1
JH
1300 [(set (reg 17)
1301 (compare
e075ae69
RH
1302 (subreg:QI
1303 (zero_extract:SI
d2836273 1304 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1305 (const_int 8)
1306 (const_int 8)) 0)
1307 (subreg:QI
1308 (zero_extract:SI
d2836273 1309 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1310 (const_int 8)
1311 (const_int 8)) 0)))]
9076b9c1 1312 "ix86_match_ccmode (insn, CCmode)"
0f40f9f7 1313 "cmp{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1314 [(set_attr "type" "icmp")
1315 (set_attr "mode" "QI")])
e075ae69
RH
1316
1317;; These implement float point compares.
1318;; %%% See if we can get away with VOIDmode operands on the actual insns,
1319;; which would allow mix and match FP modes on the compares. Which is what
1320;; the old patterns did, but with many more of them.
c572e5ba 1321
e075ae69
RH
1322(define_expand "cmpxf"
1323 [(set (reg:CC 17)
1324 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1325 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1b0c37d7 1326 "!TARGET_64BIT && TARGET_80387"
c572e5ba 1327{
e075ae69
RH
1328 ix86_compare_op0 = operands[0];
1329 ix86_compare_op1 = operands[1];
c572e5ba 1330 DONE;
0f40f9f7 1331})
4fb21e90 1332
2b589241
JH
1333(define_expand "cmptf"
1334 [(set (reg:CC 17)
1335 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1336 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1337 "TARGET_80387"
2b589241
JH
1338{
1339 ix86_compare_op0 = operands[0];
1340 ix86_compare_op1 = operands[1];
1341 DONE;
0f40f9f7 1342})
2b589241 1343
e075ae69
RH
1344(define_expand "cmpdf"
1345 [(set (reg:CC 17)
1346 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1347 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
0644b628 1348 "TARGET_80387 || TARGET_SSE2"
4fb21e90 1349{
e075ae69
RH
1350 ix86_compare_op0 = operands[0];
1351 ix86_compare_op1 = operands[1];
4fb21e90 1352 DONE;
0f40f9f7 1353})
886c62d1 1354
e075ae69
RH
1355(define_expand "cmpsf"
1356 [(set (reg:CC 17)
1357 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1358 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
0644b628 1359 "TARGET_80387 || TARGET_SSE"
c572e5ba 1360{
e075ae69
RH
1361 ix86_compare_op0 = operands[0];
1362 ix86_compare_op1 = operands[1];
c572e5ba 1363 DONE;
0f40f9f7 1364})
c572e5ba 1365
e075ae69
RH
1366;; FP compares, step 1:
1367;; Set the FP condition codes.
1368;;
1369;; CCFPmode compare with exceptions
1370;; CCFPUmode compare with no exceptions
fe4435d9 1371
e075ae69
RH
1372;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1373;; and that fp moves clobber the condition codes, and that there is
1374;; currently no way to describe this fact to reg-stack. So there are
1375;; no splitters yet for this.
c572e5ba 1376
e075ae69
RH
1377;; %%% YIKES! This scheme does not retain a strong connection between
1378;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1379;; work! Only allow tos/mem with tos in op 0.
1380;;
1381;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1382;; things aren't as bad as they sound...
886c62d1 1383
e075ae69
RH
1384(define_insn "*cmpfp_0"
1385 [(set (match_operand:HI 0 "register_operand" "=a")
1386 (unspec:HI
1387 [(compare:CCFP (match_operand 1 "register_operand" "f")
1388 (match_operand 2 "const0_operand" "X"))] 9))]
1389 "TARGET_80387
1390 && FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
c572e5ba 1392{
e075ae69 1393 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 1394 return "ftst\;fnstsw\t%0\;fstp\t%y0";
e075ae69 1395 else
0f40f9f7
ZW
1396 return "ftst\;fnstsw\t%0";
1397}
6ef67412
JH
1398 [(set_attr "type" "multi")
1399 (set_attr "mode" "unknownfp")])
c572e5ba 1400
e075ae69
RH
1401;; We may not use "#" to split and emit these, since the REG_DEAD notes
1402;; used to manage the reg stack popping would not be preserved.
886c62d1 1403
e075ae69
RH
1404(define_insn "*cmpfp_2_sf"
1405 [(set (reg:CCFP 18)
1406 (compare:CCFP
1407 (match_operand:SF 0 "register_operand" "f")
1408 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
cac58785 1409 "TARGET_80387"
e075ae69 1410 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1411 [(set_attr "type" "fcmp")
1412 (set_attr "mode" "SF")])
4fb21e90 1413
6343a50e 1414(define_insn "*cmpfp_2_sf_1"
e075ae69
RH
1415 [(set (match_operand:HI 0 "register_operand" "=a")
1416 (unspec:HI
1417 [(compare:CCFP
1418 (match_operand:SF 1 "register_operand" "f")
1419 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
4fb21e90 1420 "TARGET_80387"
e075ae69 1421 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1422 [(set_attr "type" "fcmp")
1423 (set_attr "mode" "SF")])
e075ae69
RH
1424
1425(define_insn "*cmpfp_2_df"
1426 [(set (reg:CCFP 18)
1427 (compare:CCFP
1428 (match_operand:DF 0 "register_operand" "f")
1429 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
926b3fae 1430 "TARGET_80387"
e075ae69 1431 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1432 [(set_attr "type" "fcmp")
1433 (set_attr "mode" "DF")])
926b3fae 1434
6343a50e 1435(define_insn "*cmpfp_2_df_1"
e075ae69
RH
1436 [(set (match_operand:HI 0 "register_operand" "=a")
1437 (unspec:HI
1438 [(compare:CCFP
1439 (match_operand:DF 1 "register_operand" "f")
1440 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
4fb21e90 1441 "TARGET_80387"
e075ae69 1442 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1443 [(set_attr "type" "multi")
1444 (set_attr "mode" "DF")])
e075ae69
RH
1445
1446(define_insn "*cmpfp_2_xf"
1447 [(set (reg:CCFP 18)
1448 (compare:CCFP
1449 (match_operand:XF 0 "register_operand" "f")
1450 (match_operand:XF 1 "register_operand" "f")))]
1b0c37d7 1451 "!TARGET_64BIT && TARGET_80387"
e075ae69 1452 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1453 [(set_attr "type" "fcmp")
1454 (set_attr "mode" "XF")])
9ec36da5 1455
2b589241
JH
1456(define_insn "*cmpfp_2_tf"
1457 [(set (reg:CCFP 18)
1458 (compare:CCFP
1459 (match_operand:TF 0 "register_operand" "f")
1460 (match_operand:TF 1 "register_operand" "f")))]
1461 "TARGET_80387"
1462 "* return output_fp_compare (insn, operands, 0, 0);"
1463 [(set_attr "type" "fcmp")
1464 (set_attr "mode" "XF")])
1465
6343a50e 1466(define_insn "*cmpfp_2_xf_1"
e075ae69
RH
1467 [(set (match_operand:HI 0 "register_operand" "=a")
1468 (unspec:HI
1469 [(compare:CCFP
1470 (match_operand:XF 1 "register_operand" "f")
1471 (match_operand:XF 2 "register_operand" "f"))] 9))]
1b0c37d7 1472 "!TARGET_64BIT && TARGET_80387"
e075ae69 1473 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1474 [(set_attr "type" "multi")
1475 (set_attr "mode" "XF")])
e075ae69 1476
2b589241
JH
1477(define_insn "*cmpfp_2_tf_1"
1478 [(set (match_operand:HI 0 "register_operand" "=a")
1479 (unspec:HI
1480 [(compare:CCFP
1481 (match_operand:TF 1 "register_operand" "f")
1482 (match_operand:TF 2 "register_operand" "f"))] 9))]
1483 "TARGET_80387"
1484 "* return output_fp_compare (insn, operands, 2, 0);"
1485 [(set_attr "type" "multi")
1486 (set_attr "mode" "XF")])
1487
e075ae69
RH
1488(define_insn "*cmpfp_2u"
1489 [(set (reg:CCFPU 18)
1490 (compare:CCFPU
1491 (match_operand 0 "register_operand" "f")
1492 (match_operand 1 "register_operand" "f")))]
1493 "TARGET_80387
1494 && FLOAT_MODE_P (GET_MODE (operands[0]))
1495 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1496 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412
JH
1497 [(set_attr "type" "fcmp")
1498 (set_attr "mode" "unknownfp")])
4fb21e90 1499
6343a50e 1500(define_insn "*cmpfp_2u_1"
e075ae69
RH
1501 [(set (match_operand:HI 0 "register_operand" "=a")
1502 (unspec:HI
1503 [(compare:CCFPU
1504 (match_operand 1 "register_operand" "f")
1505 (match_operand 2 "register_operand" "f"))] 9))]
08a7baac 1506 "TARGET_80387
e075ae69
RH
1507 && FLOAT_MODE_P (GET_MODE (operands[1]))
1508 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1509 "* return output_fp_compare (insn, operands, 2, 1);"
6ef67412
JH
1510 [(set_attr "type" "multi")
1511 (set_attr "mode" "unknownfp")])
08a7baac 1512
e075ae69
RH
1513;; Patterns to match the SImode-in-memory ficom instructions.
1514;;
1515;; %%% Play games with accepting gp registers, as otherwise we have to
1516;; force them to memory during rtl generation, which is no good. We
1517;; can get rid of this once we teach reload to do memory input reloads
1518;; via pushes.
1519
6343a50e 1520(define_insn "*ficom_1"
e075ae69
RH
1521 [(set (reg:CCFP 18)
1522 (compare:CCFP
1523 (match_operand 0 "register_operand" "f,f")
1524 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1525 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1527 "#")
08a7baac 1528
e075ae69
RH
1529;; Split the not-really-implemented gp register case into a
1530;; push-op-pop sequence.
1531;;
1532;; %%% This is most efficient, but am I gonna get in trouble
1533;; for separating cc0_setter and cc0_user?
2bb7a0f5 1534
e075ae69
RH
1535(define_split
1536 [(set (reg:CCFP 18)
1537 (compare:CCFP
1538 (match_operand:SF 0 "register_operand" "")
1539 (float (match_operand:SI 1 "register_operand" ""))))]
1540 "0 && TARGET_80387 && reload_completed"
1541 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1542 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1543 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1544 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1545 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1546 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1547
1548;; FP compares, step 2
1549;; Move the fpsw to ax.
1550
1551(define_insn "x86_fnstsw_1"
1552 [(set (match_operand:HI 0 "register_operand" "=a")
1553 (unspec:HI [(reg 18)] 9))]
2ae0f82c 1554 "TARGET_80387"
0f40f9f7 1555 "fnstsw\t%0"
e075ae69 1556 [(set_attr "length" "2")
6ef67412
JH
1557 (set_attr "mode" "SI")
1558 (set_attr "i387" "1")
e075ae69
RH
1559 (set_attr "ppro_uops" "few")])
1560
1561;; FP compares, step 3
1562;; Get ax into flags, general case.
1563
1564(define_insn "x86_sahf_1"
1565 [(set (reg:CC 17)
1566 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1e07edd3 1567 "!TARGET_64BIT"
e075ae69
RH
1568 "sahf"
1569 [(set_attr "length" "1")
0b5107cf 1570 (set_attr "athlon_decode" "vector")
6ef67412 1571 (set_attr "mode" "SI")
e075ae69
RH
1572 (set_attr "ppro_uops" "one")])
1573
1574;; Pentium Pro can do steps 1 through 3 in one go.
1575
1576(define_insn "*cmpfp_i"
1577 [(set (reg:CCFP 17)
1578 (compare:CCFP (match_operand 0 "register_operand" "f")
1579 (match_operand 1 "register_operand" "f")))]
1580 "TARGET_80387 && TARGET_CMOVE
0644b628 1581 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69
RH
1582 && FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1584 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 1585 [(set_attr "type" "fcmp")
6ef67412 1586 (set_attr "mode" "unknownfp")
309ada50 1587 (set_attr "athlon_decode" "vector")])
e075ae69 1588
0644b628
JH
1589(define_insn "*cmpfp_i_sse"
1590 [(set (reg:CCFP 17)
1591 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1592 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1593 "TARGET_80387
1594 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1596 "* return output_fp_compare (insn, operands, 1, 0);"
1597 [(set_attr "type" "fcmp,sse")
1598 (set_attr "mode" "unknownfp")
1599 (set_attr "athlon_decode" "vector")])
1600
1601(define_insn "*cmpfp_i_sse_only"
1602 [(set (reg:CCFP 17)
1603 (compare:CCFP (match_operand 0 "register_operand" "x")
1604 (match_operand 1 "nonimmediate_operand" "xm")))]
1605 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1606 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1607 "* return output_fp_compare (insn, operands, 1, 0);"
1608 [(set_attr "type" "sse")
1609 (set_attr "mode" "unknownfp")
1610 (set_attr "athlon_decode" "vector")])
1611
e075ae69
RH
1612(define_insn "*cmpfp_iu"
1613 [(set (reg:CCFPU 17)
1614 (compare:CCFPU (match_operand 0 "register_operand" "f")
1615 (match_operand 1 "register_operand" "f")))]
1616 "TARGET_80387 && TARGET_CMOVE
0644b628 1617 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69
RH
1618 && FLOAT_MODE_P (GET_MODE (operands[0]))
1619 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1620 "* return output_fp_compare (insn, operands, 1, 1);"
309ada50 1621 [(set_attr "type" "fcmp")
6ef67412 1622 (set_attr "mode" "unknownfp")
309ada50 1623 (set_attr "athlon_decode" "vector")])
0644b628
JH
1624
1625(define_insn "*cmpfp_iu_sse"
1626 [(set (reg:CCFPU 17)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1628 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1629 "TARGET_80387
1630 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1632 "* return output_fp_compare (insn, operands, 1, 1);"
1633 [(set_attr "type" "fcmp,sse")
1634 (set_attr "mode" "unknownfp")
1635 (set_attr "athlon_decode" "vector")])
1636
1637(define_insn "*cmpfp_iu_sse_only"
1638 [(set (reg:CCFPU 17)
1639 (compare:CCFPU (match_operand 0 "register_operand" "x")
1640 (match_operand 1 "nonimmediate_operand" "xm")))]
1641 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1642 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1643 "* return output_fp_compare (insn, operands, 1, 1);"
1644 [(set_attr "type" "sse")
1645 (set_attr "mode" "unknownfp")
1646 (set_attr "athlon_decode" "vector")])
e075ae69
RH
1647\f
1648;; Move instructions.
2ae0f82c 1649
e075ae69 1650;; General case of fullword move.
886c62d1 1651
e075ae69
RH
1652(define_expand "movsi"
1653 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1654 (match_operand:SI 1 "general_operand" ""))]
1655 ""
1656 "ix86_expand_move (SImode, operands); DONE;")
08a7baac 1657
e075ae69
RH
1658;; Push/pop instructions. They are separate since autoinc/dec is not a
1659;; general_operand.
1660;;
1661;; %%% We don't use a post-inc memory reference because x86 is not a
1662;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1663;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1664;; targets without our curiosities, and it is just as easy to represent
1665;; this differently.
886c62d1 1666
a4414093 1667(define_insn "*pushsi2"
e075ae69 1668 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1669 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
0ec259ed 1670 "!TARGET_64BIT"
0f40f9f7 1671 "push{l}\t%1"
6ef67412
JH
1672 [(set_attr "type" "push")
1673 (set_attr "mode" "SI")])
4fb21e90 1674
0ec259ed
JH
1675;; For 64BIT abi we always round up to 8 bytes.
1676(define_insn "*pushsi2_rex64"
1677 [(set (match_operand:SI 0 "push_operand" "=X")
1678 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1679 "TARGET_64BIT"
0f40f9f7 1680 "push{q}\t%q1"
0ec259ed
JH
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1683
bdeb029c
JH
1684(define_insn "*pushsi2_prologue"
1685 [(set (match_operand:SI 0 "push_operand" "=<")
1686 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
f2042df3 1687 (clobber (mem:BLK (scratch)))]
0ec259ed 1688 "!TARGET_64BIT"
0f40f9f7 1689 "push{l}\t%1"
6ef67412
JH
1690 [(set_attr "type" "push")
1691 (set_attr "mode" "SI")])
bdeb029c
JH
1692
1693(define_insn "*popsi1_epilogue"
1694 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1695 (mem:SI (reg:SI 7)))
1696 (set (reg:SI 7)
1697 (plus:SI (reg:SI 7) (const_int 4)))
f2042df3 1698 (clobber (mem:BLK (scratch)))]
1e07edd3 1699 "!TARGET_64BIT"
0f40f9f7 1700 "pop{l}\t%0"
6ef67412
JH
1701 [(set_attr "type" "pop")
1702 (set_attr "mode" "SI")])
bdeb029c 1703
e075ae69
RH
1704(define_insn "popsi1"
1705 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1706 (mem:SI (reg:SI 7)))
1707 (set (reg:SI 7)
1708 (plus:SI (reg:SI 7) (const_int 4)))]
1e07edd3 1709 "!TARGET_64BIT"
0f40f9f7 1710 "pop{l}\t%0"
6ef67412
JH
1711 [(set_attr "type" "pop")
1712 (set_attr "mode" "SI")])
c572e5ba 1713
591702de
JH
1714(define_insn "*movsi_xor"
1715 [(set (match_operand:SI 0 "register_operand" "=r")
1716 (match_operand:SI 1 "const0_operand" "i"))
e075ae69 1717 (clobber (reg:CC 17))]
591702de 1718 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 1719 "xor{l}\t{%0, %0|%0, %0}"
591702de 1720 [(set_attr "type" "alu1")
6ef67412
JH
1721 (set_attr "mode" "SI")
1722 (set_attr "length_immediate" "0")])
591702de
JH
1723
1724(define_insn "*movsi_or"
1725 [(set (match_operand:SI 0 "register_operand" "=r")
1726 (match_operand:SI 1 "immediate_operand" "i"))
1727 (clobber (reg:CC 17))]
1728 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1729 && INTVAL (operands[1]) == -1
1730 && (TARGET_PENTIUM || optimize_size)"
c572e5ba 1731{
591702de 1732 operands[1] = constm1_rtx;
0f40f9f7
ZW
1733 return "or{l}\t{%1, %0|%0, %1}";
1734}
591702de 1735 [(set_attr "type" "alu1")
6ef67412
JH
1736 (set_attr "mode" "SI")
1737 (set_attr "length_immediate" "1")])
e075ae69 1738
591702de 1739(define_insn "*movsi_1"
141e454b
JH
1740 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
1741 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
e075ae69 1742 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1743{
e075ae69 1744 switch (get_attr_type (insn))
886c62d1 1745 {
141e454b
JH
1746 case TYPE_SSE:
1747 if (get_attr_mode (insn) == TImode)
0f40f9f7
ZW
1748 return "movdqa\t{%1, %0|%0, %1}";
1749 return "movd\t{%1, %0|%0, %1}";
141e454b 1750
915119a5 1751 case TYPE_MMX:
0f40f9f7 1752 return "movd\t{%1, %0|%0, %1}";
915119a5 1753
e075ae69 1754 case TYPE_LEA:
0f40f9f7 1755 return "lea{l}\t{%1, %0|%0, %1}";
915119a5 1756
e075ae69
RH
1757 default:
1758 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1759 abort();
0f40f9f7 1760 return "mov{l}\t{%1, %0|%0, %1}";
886c62d1 1761 }
0f40f9f7 1762}
e075ae69 1763 [(set (attr "type")
141e454b 1764 (cond [(eq_attr "alternative" "4,5")
915119a5 1765 (const_string "mmx")
141e454b
JH
1766 (eq_attr "alternative" "6,7,8")
1767 (const_string "sse")
915119a5 1768 (and (ne (symbol_ref "flag_pic") (const_int 0))
e075ae69
RH
1769 (match_operand:SI 1 "symbolic_operand" ""))
1770 (const_string "lea")
1771 ]
6ef67412 1772 (const_string "imov")))
141e454b
JH
1773 (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
1774 (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
e075ae69 1775
0ec259ed
JH
1776;; Stores and loads of ax to arbitary constant address.
1777;; We fake an second form of instruction to force reload to load address
1778;; into register when rax is not available
1779(define_insn "*movabssi_1_rex64"
1780 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1781 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1782 "TARGET_64BIT"
1783 "@
0f40f9f7
ZW
1784 movabs{l}\t{%1, %P0|%P0, %1}
1785 mov{l}\t{%1, %a0|%a0, %1}
1786 movabs{l}\t{%1, %a0|%a0, %1}"
0ec259ed
JH
1787 [(set_attr "type" "imov")
1788 (set_attr "modrm" "0,*,*")
1789 (set_attr "length_address" "8,0,0")
1790 (set_attr "length_immediate" "0,*,*")
1791 (set_attr "memory" "store")
1792 (set_attr "mode" "SI")])
1793
1794(define_insn "*movabssi_2_rex64"
1795 [(set (match_operand:SI 0 "register_operand" "=a,r")
1796 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1797 "TARGET_64BIT"
1798 "@
0f40f9f7
ZW
1799 movabs{l}\t{%P1, %0|%0, %P1}
1800 mov{l}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1801 [(set_attr "type" "imov")
1802 (set_attr "modrm" "0,*")
1803 (set_attr "length_address" "8,0")
1804 (set_attr "length_immediate" "0")
1805 (set_attr "memory" "load")
1806 (set_attr "mode" "SI")])
1807
e075ae69
RH
1808(define_insn "*swapsi"
1809 [(set (match_operand:SI 0 "register_operand" "+r")
1810 (match_operand:SI 1 "register_operand" "+r"))
1811 (set (match_dup 1)
1812 (match_dup 0))]
2bb7a0f5 1813 ""
0f40f9f7 1814 "xchg{l}\t%1, %0"
e075ae69
RH
1815 [(set_attr "type" "imov")
1816 (set_attr "pent_pair" "np")
0b5107cf 1817 (set_attr "athlon_decode" "vector")
6ef67412
JH
1818 (set_attr "mode" "SI")
1819 (set_attr "modrm" "0")
e075ae69 1820 (set_attr "ppro_uops" "few")])
886c62d1 1821
e075ae69
RH
1822(define_expand "movhi"
1823 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1824 (match_operand:HI 1 "general_operand" ""))]
ca097615 1825 ""
e075ae69 1826 "ix86_expand_move (HImode, operands); DONE;")
2f2a49e8 1827
a4414093 1828(define_insn "*pushhi2"
e075ae69 1829 [(set (match_operand:HI 0 "push_operand" "=<,<")
2c5a510c 1830 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1e07edd3 1831 "!TARGET_64BIT"
e075ae69 1832 "@
0f40f9f7
ZW
1833 push{w}\t{|WORD PTR }%1
1834 push{w}\t%1"
6ef67412
JH
1835 [(set_attr "type" "push")
1836 (set_attr "mode" "HI")])
e075ae69 1837
b3298882
JH
1838;; For 64BIT abi we always round up to 8 bytes.
1839(define_insn "*pushhi2_rex64"
1840 [(set (match_operand:HI 0 "push_operand" "=X")
1841 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1842 "TARGET_64BIT"
0f40f9f7 1843 "push{q}\t%q1"
b3298882
JH
1844 [(set_attr "type" "push")
1845 (set_attr "mode" "QI")])
1846
e075ae69 1847(define_insn "*movhi_1"
6ef67412
JH
1848 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1849 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
e075ae69 1850 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 1851{
e075ae69 1852 switch (get_attr_type (insn))
886c62d1 1853 {
e075ae69
RH
1854 case TYPE_IMOVX:
1855 /* movzwl is faster than movw on p2 due to partial word stalls,
1856 though not as fast as an aligned movl. */
0f40f9f7 1857 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
e075ae69 1858 default:
6ef67412 1859 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 1860 return "mov{l}\t{%k1, %k0|%k0, %k1}";
e075ae69 1861 else
0f40f9f7 1862 return "mov{w}\t{%1, %0|%0, %1}";
886c62d1 1863 }
0f40f9f7 1864}
e075ae69 1865 [(set (attr "type")
6ef67412 1866 (cond [(and (eq_attr "alternative" "0,1")
0b5107cf
JH
1867 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1868 (const_int 0))
1869 (eq (symbol_ref "TARGET_HIMODE_MATH")
1870 (const_int 0))))
369e59b1 1871 (const_string "imov")
6ef67412 1872 (and (eq_attr "alternative" "2,3,4")
2247f6ed 1873 (match_operand:HI 1 "aligned_operand" ""))
e075ae69
RH
1874 (const_string "imov")
1875 (and (ne (symbol_ref "TARGET_MOVX")
1876 (const_int 0))
6ef67412 1877 (eq_attr "alternative" "0,1,3,4"))
e075ae69
RH
1878 (const_string "imovx")
1879 ]
1880 (const_string "imov")))
6ef67412 1881 (set (attr "mode")
e075ae69 1882 (cond [(eq_attr "type" "imovx")
6ef67412
JH
1883 (const_string "SI")
1884 (and (eq_attr "alternative" "2,3,4")
369e59b1 1885 (match_operand:HI 1 "aligned_operand" ""))
6ef67412
JH
1886 (const_string "SI")
1887 (and (eq_attr "alternative" "0,1")
0b5107cf
JH
1888 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1889 (const_int 0))
1890 (eq (symbol_ref "TARGET_HIMODE_MATH")
1891 (const_int 0))))
6ef67412 1892 (const_string "SI")
e075ae69 1893 ]
6ef67412
JH
1894 (const_string "HI")))
1895 (set_attr "modrm" "0,*,*,0,*,*")])
e075ae69 1896
0ec259ed
JH
1897;; Stores and loads of ax to arbitary constant address.
1898;; We fake an second form of instruction to force reload to load address
1899;; into register when rax is not available
1900(define_insn "*movabshi_1_rex64"
1901 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1902 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1903 "TARGET_64BIT"
1904 "@
0f40f9f7
ZW
1905 movabs{w}\t{%1, %P0|%P0, %1}
1906 mov{w}\t{%1, %a0|%a0, %1}
1907 movabs{w}\t{%1, %a0|%a0, %1}"
0ec259ed
JH
1908 [(set_attr "type" "imov")
1909 (set_attr "modrm" "0,*,*")
1910 (set_attr "length_address" "8,0,0")
1911 (set_attr "length_immediate" "0,*,*")
1912 (set_attr "memory" "store")
1913 (set_attr "mode" "HI")])
1914
1915(define_insn "*movabshi_2_rex64"
1916 [(set (match_operand:HI 0 "register_operand" "=a,r")
1917 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1918 "TARGET_64BIT"
1919 "@
0f40f9f7
ZW
1920 movabs{w}\t{%P1, %0|%0, %P1}
1921 mov{w}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
1922 [(set_attr "type" "imov")
1923 (set_attr "modrm" "0,*")
1924 (set_attr "length_address" "8,0")
1925 (set_attr "length_immediate" "0")
1926 (set_attr "memory" "load")
1927 (set_attr "mode" "HI")])
1928
e075ae69
RH
1929(define_insn "*swaphi_1"
1930 [(set (match_operand:HI 0 "register_operand" "+r")
1931 (match_operand:HI 1 "register_operand" "+r"))
1932 (set (match_dup 1)
1933 (match_dup 0))]
1934 "TARGET_PARTIAL_REG_STALL"
0f40f9f7 1935 "xchg{w}\t%1, %0"
e075ae69
RH
1936 [(set_attr "type" "imov")
1937 (set_attr "pent_pair" "np")
6ef67412
JH
1938 (set_attr "mode" "HI")
1939 (set_attr "modrm" "0")
e075ae69
RH
1940 (set_attr "ppro_uops" "few")])
1941
1942(define_insn "*swaphi_2"
1943 [(set (match_operand:HI 0 "register_operand" "+r")
1944 (match_operand:HI 1 "register_operand" "+r"))
1945 (set (match_dup 1)
1946 (match_dup 0))]
1947 "! TARGET_PARTIAL_REG_STALL"
0f40f9f7 1948 "xchg{l}\t%k1, %k0"
e075ae69 1949 [(set_attr "type" "imov")
e075ae69 1950 (set_attr "pent_pair" "np")
6ef67412
JH
1951 (set_attr "mode" "SI")
1952 (set_attr "modrm" "0")
e075ae69 1953 (set_attr "ppro_uops" "few")])
886c62d1 1954
2f2a49e8 1955(define_expand "movstricthi"
e075ae69 1956 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2f2a49e8 1957 (match_operand:HI 1 "general_operand" ""))]
b9b2c339 1958 "! TARGET_PARTIAL_REG_STALL || optimize_size"
2f2a49e8
MM
1959{
1960 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
1961 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1962 operands[1] = force_reg (HImode, operands[1]);
0f40f9f7 1963})
2f2a49e8 1964
e075ae69 1965(define_insn "*movstricthi_1"
fc524c1c 1966 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
e075ae69 1967 (match_operand:HI 1 "general_operand" "rn,m"))]
b9b2c339 1968 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
e075ae69 1969 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 1970 "mov{w}\t{%1, %0|%0, %1}"
6ef67412
JH
1971 [(set_attr "type" "imov")
1972 (set_attr "mode" "HI")])
1973
1974(define_insn "*movstricthi_xor"
208b0ab1 1975 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
6ef67412
JH
1976 (match_operand:HI 1 "const0_operand" "i"))
1977 (clobber (reg:CC 17))]
b9b2c339
JH
1978 "reload_completed
1979 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
0f40f9f7 1980 "xor{w}\t{%0, %0|%0, %0}"
6ef67412
JH
1981 [(set_attr "type" "alu1")
1982 (set_attr "mode" "HI")
1983 (set_attr "length_immediate" "0")])
886c62d1 1984
2f2a49e8 1985(define_expand "movqi"
4cbfbb1b 1986 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2f2a49e8
MM
1987 (match_operand:QI 1 "general_operand" ""))]
1988 ""
e075ae69
RH
1989 "ix86_expand_move (QImode, operands); DONE;")
1990
7dd4b4a3
JH
1991;; emit_push_insn when it calls move_by_pieces requires an insn to
1992;; "push a byte". But actually we use pushw, which has the effect
1993;; of rounding the amount pushed up to a halfword.
1994
1995(define_insn "*pushqi2"
1996 [(set (match_operand:QI 0 "push_operand" "=X,X")
1997 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1998 "!TARGET_64BIT"
1999 "@
0f40f9f7
ZW
2000 push{w}\t{|word ptr }%1
2001 push{w}\t%w1"
7dd4b4a3
JH
2002 [(set_attr "type" "push")
2003 (set_attr "mode" "HI")])
2004
b3298882
JH
2005;; For 64BIT abi we always round up to 8 bytes.
2006(define_insn "*pushqi2_rex64"
2007 [(set (match_operand:QI 0 "push_operand" "=X")
2008 (match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
2009 "TARGET_64BIT"
0f40f9f7 2010 "push{q}\t%q1"
b3298882
JH
2011 [(set_attr "type" "push")
2012 (set_attr "mode" "QI")])
2013
0b5107cf
JH
2014;; Situation is quite tricky about when to choose full sized (SImode) move
2015;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2016;; partial register dependency machines (such as AMD Athlon), where QImode
2017;; moves issue extra dependency and for partial register stalls machines
2018;; that don't use QImode patterns (and QImode move cause stall on the next
2019;; instruction).
2020;;
2021;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2022;; register stall machines with, where we use QImode instructions, since
2023;; partial register stall can be caused there. Then we use movzx.
e075ae69 2024(define_insn "*movqi_1"
0b5107cf
JH
2025 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2026 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
e075ae69 2027 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1 2028{
e075ae69 2029 switch (get_attr_type (insn))
b76c90cf 2030 {
e075ae69 2031 case TYPE_IMOVX:
1a06f5fe 2032 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
e075ae69 2033 abort ();
0f40f9f7 2034 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
e075ae69 2035 default:
6ef67412 2036 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 2037 return "mov{l}\t{%k1, %k0|%k0, %k1}";
b76c90cf 2038 else
0f40f9f7 2039 return "mov{b}\t{%1, %0|%0, %1}";
b76c90cf 2040 }
0f40f9f7 2041}
e075ae69 2042 [(set (attr "type")
0b5107cf
JH
2043 (cond [(and (eq_attr "alternative" "3")
2044 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2045 (const_int 0))
2046 (eq (symbol_ref "TARGET_QIMODE_MATH")
2047 (const_int 0))))
2048 (const_string "imov")
2049 (eq_attr "alternative" "3,5")
e075ae69
RH
2050 (const_string "imovx")
2051 (and (ne (symbol_ref "TARGET_MOVX")
2052 (const_int 0))
0b5107cf 2053 (eq_attr "alternative" "2"))
e075ae69
RH
2054 (const_string "imovx")
2055 ]
2056 (const_string "imov")))
6ef67412
JH
2057 (set (attr "mode")
2058 (cond [(eq_attr "alternative" "3,4,5")
2059 (const_string "SI")
2060 (eq_attr "alternative" "6")
2061 (const_string "QI")
2062 (eq_attr "type" "imovx")
2063 (const_string "SI")
0b5107cf 2064 (and (eq_attr "type" "imov")
6ef67412 2065 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
2066 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2067 (const_int 0))))
6ef67412 2068 (const_string "SI")
0b5107cf
JH
2069 ;; Avoid partial register stalls when not using QImode arithmetic
2070 (and (eq_attr "type" "imov")
6ef67412 2071 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
2072 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2073 (const_int 0))
2074 (eq (symbol_ref "TARGET_QIMODE_MATH")
2075 (const_int 0)))))
6ef67412
JH
2076 (const_string "SI")
2077 ]
2078 (const_string "QI")))])
e075ae69
RH
2079
2080(define_expand "reload_outqi"
2081 [(parallel [(match_operand:QI 0 "" "=m")
2082 (match_operand:QI 1 "register_operand" "r")
2083 (match_operand:QI 2 "register_operand" "=&q")])]
2084 ""
e075ae69
RH
2085{
2086 rtx op0, op1, op2;
2087 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
886c62d1 2088
e075ae69
RH
2089 if (reg_overlap_mentioned_p (op2, op0))
2090 abort ();
2091 if (! q_regs_operand (op1, QImode))
2092 {
2093 emit_insn (gen_movqi (op2, op1));
2094 op1 = op2;
2095 }
2096 emit_insn (gen_movqi (op0, op1));
2097 DONE;
0f40f9f7 2098})
886c62d1 2099
e075ae69
RH
2100(define_insn "*swapqi"
2101 [(set (match_operand:QI 0 "register_operand" "+r")
2102 (match_operand:QI 1 "register_operand" "+r"))
2103 (set (match_dup 1)
2104 (match_dup 0))]
2105 ""
0f40f9f7 2106 "xchg{b}\t%1, %0"
e075ae69
RH
2107 [(set_attr "type" "imov")
2108 (set_attr "pent_pair" "np")
6ef67412
JH
2109 (set_attr "mode" "QI")
2110 (set_attr "modrm" "0")
e075ae69 2111 (set_attr "ppro_uops" "few")])
886c62d1 2112
2f2a49e8 2113(define_expand "movstrictqi"
4cbfbb1b 2114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2f2a49e8 2115 (match_operand:QI 1 "general_operand" ""))]
e075ae69 2116 "! TARGET_PARTIAL_REG_STALL"
2f2a49e8
MM
2117{
2118 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
2119 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2120 operands[1] = force_reg (QImode, operands[1]);
0f40f9f7 2121})
2f2a49e8 2122
e075ae69 2123(define_insn "*movstrictqi_1"
2ae0f82c 2124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 2125 (match_operand:QI 1 "general_operand" "*qn,m"))]
e075ae69
RH
2126 "! TARGET_PARTIAL_REG_STALL
2127 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 2128 "mov{b}\t{%1, %0|%0, %1}"
6ef67412
JH
2129 [(set_attr "type" "imov")
2130 (set_attr "mode" "QI")])
2131
2132(define_insn "*movstrictqi_xor"
5e6d6bf0 2133 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
6ef67412
JH
2134 (match_operand:QI 1 "const0_operand" "i"))
2135 (clobber (reg:CC 17))]
2136 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
0f40f9f7 2137 "xor{b}\t{%0, %0|%0, %0}"
6ef67412
JH
2138 [(set_attr "type" "alu1")
2139 (set_attr "mode" "QI")
2140 (set_attr "length_immediate" "0")])
e075ae69
RH
2141
2142(define_insn "*movsi_extv_1"
d2836273 2143 [(set (match_operand:SI 0 "register_operand" "=R")
3522082b 2144 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2145 (const_int 8)
2146 (const_int 8)))]
2147 ""
0f40f9f7 2148 "movs{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
2149 [(set_attr "type" "imovx")
2150 (set_attr "mode" "SI")])
e075ae69
RH
2151
2152(define_insn "*movhi_extv_1"
d2836273 2153 [(set (match_operand:HI 0 "register_operand" "=R")
3522082b 2154 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2155 (const_int 8)
2156 (const_int 8)))]
2157 ""
0f40f9f7 2158 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
6ef67412
JH
2159 [(set_attr "type" "imovx")
2160 (set_attr "mode" "SI")])
e075ae69
RH
2161
2162(define_insn "*movqi_extv_1"
0ec259ed 2163 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
3522082b 2164 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
2165 (const_int 8)
2166 (const_int 8)))]
0ec259ed 2167 "!TARGET_64BIT"
886c62d1 2168{
e075ae69 2169 switch (get_attr_type (insn))
886c62d1 2170 {
e075ae69 2171 case TYPE_IMOVX:
0f40f9f7 2172 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 2173 default:
0f40f9f7 2174 return "mov{b}\t{%h1, %0|%0, %h1}";
886c62d1 2175 }
0f40f9f7 2176}
e075ae69
RH
2177 [(set (attr "type")
2178 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2179 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2180 (ne (symbol_ref "TARGET_MOVX")
2181 (const_int 0))))
2182 (const_string "imovx")
6ef67412
JH
2183 (const_string "imov")))
2184 (set (attr "mode")
2185 (if_then_else (eq_attr "type" "imovx")
2186 (const_string "SI")
2187 (const_string "QI")))])
e075ae69 2188
0ec259ed
JH
2189(define_insn "*movqi_extv_1_rex64"
2190 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
3522082b 2191 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
0ec259ed
JH
2192 (const_int 8)
2193 (const_int 8)))]
2194 "TARGET_64BIT"
0ec259ed
JH
2195{
2196 switch (get_attr_type (insn))
2197 {
2198 case TYPE_IMOVX:
0f40f9f7 2199 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
0ec259ed 2200 default:
0f40f9f7 2201 return "mov{b}\t{%h1, %0|%0, %h1}";
0ec259ed 2202 }
0f40f9f7 2203}
0ec259ed
JH
2204 [(set (attr "type")
2205 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2206 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2207 (ne (symbol_ref "TARGET_MOVX")
2208 (const_int 0))))
2209 (const_string "imovx")
2210 (const_string "imov")))
2211 (set (attr "mode")
2212 (if_then_else (eq_attr "type" "imovx")
2213 (const_string "SI")
2214 (const_string "QI")))])
2215
2216;; Stores and loads of ax to arbitary constant address.
2217;; We fake an second form of instruction to force reload to load address
2218;; into register when rax is not available
2219(define_insn "*movabsqi_1_rex64"
2220 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2221 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2222 "TARGET_64BIT"
2223 "@
0f40f9f7
ZW
2224 movabs{q}\t{%1, %P0|%P0, %1}
2225 mov{q}\t{%1, %a0|%a0, %1}
2226 movabs{q}\t{%1, %a0|%a0, %1}"
0ec259ed
JH
2227 [(set_attr "type" "imov")
2228 (set_attr "modrm" "0,*,*")
2229 (set_attr "length_address" "8,0,0")
2230 (set_attr "length_immediate" "0,*,*")
2231 (set_attr "memory" "store")
2232 (set_attr "mode" "QI")])
2233
2234(define_insn "*movabsqi_2_rex64"
2235 [(set (match_operand:QI 0 "register_operand" "=a,r")
2236 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2237 "TARGET_64BIT"
2238 "@
0f40f9f7
ZW
2239 movabs{q}\t{%P1, %0|%0, %P1}
2240 mov{q}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2241 [(set_attr "type" "imov")
2242 (set_attr "modrm" "0,*")
2243 (set_attr "length_address" "8,0")
2244 (set_attr "length_immediate" "0")
2245 (set_attr "memory" "load")
2246 (set_attr "mode" "QI")])
2247
e075ae69 2248(define_insn "*movsi_extzv_1"
d2836273
JH
2249 [(set (match_operand:SI 0 "register_operand" "=R")
2250 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2251 (const_int 8)
2252 (const_int 8)))]
2253 ""
0f40f9f7 2254 "movz{bl|x}\t{%h1, %0|%0, %h1}"
6ef67412
JH
2255 [(set_attr "type" "imovx")
2256 (set_attr "mode" "SI")])
886c62d1 2257
d2836273
JH
2258(define_insn "*movqi_extzv_2"
2259 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2260 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
2261 (const_int 8)
2262 (const_int 8)) 0))]
d2836273 2263 "!TARGET_64BIT"
f31fce3f 2264{
e075ae69 2265 switch (get_attr_type (insn))
f31fce3f 2266 {
e075ae69 2267 case TYPE_IMOVX:
0f40f9f7 2268 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
e075ae69 2269 default:
0f40f9f7 2270 return "mov{b}\t{%h1, %0|%0, %h1}";
e075ae69 2271 }
0f40f9f7 2272}
e075ae69
RH
2273 [(set (attr "type")
2274 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2275 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2276 (ne (symbol_ref "TARGET_MOVX")
2277 (const_int 0))))
2278 (const_string "imovx")
6ef67412
JH
2279 (const_string "imov")))
2280 (set (attr "mode")
2281 (if_then_else (eq_attr "type" "imovx")
2282 (const_string "SI")
2283 (const_string "QI")))])
e075ae69 2284
d2836273
JH
2285(define_insn "*movqi_extzv_2_rex64"
2286 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2287 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2288 (const_int 8)
2289 (const_int 8)) 0))]
2290 "TARGET_64BIT"
d2836273
JH
2291{
2292 switch (get_attr_type (insn))
2293 {
2294 case TYPE_IMOVX:
0f40f9f7 2295 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
d2836273 2296 default:
0f40f9f7 2297 return "mov{b}\t{%h1, %0|%0, %h1}";
d2836273 2298 }
0f40f9f7 2299}
d2836273
JH
2300 [(set (attr "type")
2301 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2302 (ne (symbol_ref "TARGET_MOVX")
2303 (const_int 0)))
2304 (const_string "imovx")
2305 (const_string "imov")))
2306 (set (attr "mode")
2307 (if_then_else (eq_attr "type" "imovx")
2308 (const_string "SI")
2309 (const_string "QI")))])
2310
7a2e09f4 2311(define_insn "movsi_insv_1"
d2836273 2312 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2313 (const_int 8)
2314 (const_int 8))
f47c8646 2315 (match_operand:SI 1 "general_operand" "Qmn"))]
d2836273 2316 "!TARGET_64BIT"
0f40f9f7 2317 "mov{b}\t{%b1, %h0|%h0, %b1}"
d2836273
JH
2318 [(set_attr "type" "imov")
2319 (set_attr "mode" "QI")])
2320
2321(define_insn "*movsi_insv_1_rex64"
2322 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2323 (const_int 8)
2324 (const_int 8))
f47c8646 2325 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
d2836273 2326 "TARGET_64BIT"
0f40f9f7 2327 "mov{b}\t{%b1, %h0|%h0, %b1}"
6ef67412
JH
2328 [(set_attr "type" "imov")
2329 (set_attr "mode" "QI")])
e075ae69
RH
2330
2331(define_insn "*movqi_insv_2"
d2836273 2332 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2333 (const_int 8)
2334 (const_int 8))
3522082b 2335 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
e075ae69
RH
2336 (const_int 8))
2337 (const_int 255)))]
2338 ""
0f40f9f7 2339 "mov{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
2340 [(set_attr "type" "imov")
2341 (set_attr "mode" "QI")])
f31fce3f 2342
e075ae69 2343(define_expand "movdi"
4cbfbb1b 2344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
2345 (match_operand:DI 1 "general_operand" ""))]
2346 ""
2347 "ix86_expand_move (DImode, operands); DONE;")
f31fce3f 2348
e075ae69
RH
2349(define_insn "*pushdi"
2350 [(set (match_operand:DI 0 "push_operand" "=<")
2c5a510c 2351 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1e07edd3 2352 "!TARGET_64BIT"
e075ae69 2353 "#")
f31fce3f 2354
0ec259ed
JH
2355(define_insn "pushdi2_rex64"
2356 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2357 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2358 "TARGET_64BIT"
2359 "@
0f40f9f7 2360 push{q}\t%1
0ec259ed
JH
2361 #"
2362 [(set_attr "type" "push,multi")
2363 (set_attr "mode" "DI")])
2364
2365;; Convert impossible pushes of immediate to existing instructions.
2366;; First try to get scratch register and go trought it. In case this
2367;; fails, push sign extended lower part first and then overwrite
2368;; upper part by 32bit move.
2369(define_peephole2
2370 [(match_scratch:DI 2 "r")
2371 (set (match_operand:DI 0 "push_operand" "")
2372 (match_operand:DI 1 "immediate_operand" ""))]
2373 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2374 && !x86_64_immediate_operand (operands[1], DImode)"
2375 [(set (match_dup 2) (match_dup 1))
2376 (set (match_dup 0) (match_dup 2))]
2377 "")
2378
2379;; We need to define this as both peepholer and splitter for case
2380;; peephole2 pass is not run.
2381(define_peephole2
2382 [(set (match_operand:DI 0 "push_operand" "")
2383 (match_operand:DI 1 "immediate_operand" ""))]
2384 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2385 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2386 [(set (match_dup 0) (match_dup 1))
2387 (set (match_dup 2) (match_dup 3))]
2388 "split_di (operands + 1, 1, operands + 2, operands + 3);
2389 operands[1] = gen_lowpart (DImode, operands[2]);
2390 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2391 GEN_INT (4)));
2392 ")
2393
2394(define_split
2395 [(set (match_operand:DI 0 "push_operand" "")
2396 (match_operand:DI 1 "immediate_operand" ""))]
2397 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2398 && !symbolic_operand (operands[1], DImode)
2399 && !x86_64_immediate_operand (operands[1], DImode)"
2400 [(set (match_dup 0) (match_dup 1))
2401 (set (match_dup 2) (match_dup 3))]
2402 "split_di (operands + 1, 1, operands + 2, operands + 3);
2403 operands[1] = gen_lowpart (DImode, operands[2]);
2404 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2405 GEN_INT (4)));
2406 ")
2407
2408(define_insn "*pushdi2_prologue_rex64"
2409 [(set (match_operand:DI 0 "push_operand" "=<")
2410 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
f2042df3 2411 (clobber (mem:BLK (scratch)))]
0ec259ed 2412 "TARGET_64BIT"
0f40f9f7 2413 "push{q}\t%1"
0ec259ed
JH
2414 [(set_attr "type" "push")
2415 (set_attr "mode" "DI")])
2416
2417(define_insn "*popdi1_epilogue_rex64"
2418 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2419 (mem:DI (reg:DI 7)))
2420 (set (reg:DI 7)
2421 (plus:DI (reg:DI 7) (const_int 8)))
f2042df3 2422 (clobber (mem:BLK (scratch)))]
0ec259ed 2423 "TARGET_64BIT"
0f40f9f7 2424 "pop{q}\t%0"
0ec259ed
JH
2425 [(set_attr "type" "pop")
2426 (set_attr "mode" "DI")])
2427
2428(define_insn "popdi1"
2429 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2430 (mem:DI (reg:DI 7)))
2431 (set (reg:DI 7)
2432 (plus:DI (reg:DI 7) (const_int 8)))]
2433 "TARGET_64BIT"
0f40f9f7 2434 "pop{q}\t%0"
0ec259ed
JH
2435 [(set_attr "type" "pop")
2436 (set_attr "mode" "DI")])
2437
2438(define_insn "*movdi_xor_rex64"
2439 [(set (match_operand:DI 0 "register_operand" "=r")
2440 (match_operand:DI 1 "const0_operand" "i"))
2441 (clobber (reg:CC 17))]
1b0c37d7
ZW
2442 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2443 && reload_completed"
0f40f9f7 2444 "xor{l}\t{%k0, %k0|%k0, %k0}"
0ec259ed
JH
2445 [(set_attr "type" "alu1")
2446 (set_attr "mode" "SI")
2447 (set_attr "length_immediate" "0")])
2448
2449(define_insn "*movdi_or_rex64"
2450 [(set (match_operand:DI 0 "register_operand" "=r")
2451 (match_operand:DI 1 "const_int_operand" "i"))
2452 (clobber (reg:CC 17))]
1b0c37d7
ZW
2453 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2454 && reload_completed
2455 && GET_CODE (operands[1]) == CONST_INT
2456 && INTVAL (operands[1]) == -1"
0ec259ed
JH
2457{
2458 operands[1] = constm1_rtx;
0f40f9f7
ZW
2459 return "or{q}\t{%1, %0|%0, %1}";
2460}
0ec259ed
JH
2461 [(set_attr "type" "alu1")
2462 (set_attr "mode" "DI")
2463 (set_attr "length_immediate" "1")])
2464
e075ae69 2465(define_insn "*movdi_2"
141e454b
JH
2466 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
2467 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1e07edd3
JH
2468 "!TARGET_64BIT
2469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
915119a5
BS
2470 "@
2471 #
2472 #
0f40f9f7
ZW
2473 movq\t{%1, %0|%0, %1}
2474 movq\t{%1, %0|%0, %1}
2475 movq\t{%1, %0|%0, %1}
2476 movdqa\t{%1, %0|%0, %1}
2477 movq\t{%1, %0|%0, %1}"
141e454b
JH
2478 [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2479 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
dc0f0eb8 2480
e075ae69
RH
2481(define_split
2482 [(set (match_operand:DI 0 "push_operand" "")
2483 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
2484 "!TARGET_64BIT && reload_completed
2485 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2450a057 2486 [(const_int 0)]
26e5b205 2487 "ix86_split_long_move (operands); DONE;")
f31fce3f 2488
e075ae69 2489;; %%% This multiword shite has got to go.
e075ae69 2490(define_split
c76aab11 2491 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 2492 (match_operand:DI 1 "general_operand" ""))]
6c12e488
JH
2493 "!TARGET_64BIT && reload_completed
2494 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2495 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
26e5b205
JH
2496 [(const_int 0)]
2497 "ix86_split_long_move (operands); DONE;")
0ec259ed
JH
2498
2499(define_insn "*movdi_1_rex64"
141e454b
JH
2500 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2501 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
1b0c37d7
ZW
2502 "TARGET_64BIT
2503 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0ec259ed
JH
2504{
2505 switch (get_attr_type (insn))
2506 {
2507 case TYPE_SSE:
141e454b
JH
2508 if (register_operand (operands[0], DImode)
2509 && register_operand (operands[1], DImode))
0f40f9f7 2510 return "movdqa\t{%1, %0|%0, %1}";
141e454b 2511 /* FALLTHRU */
0ec259ed 2512 case TYPE_MMX:
0f40f9f7 2513 return "movq\t{%1, %0|%0, %1}";
0ec259ed 2514 case TYPE_MULTI:
0f40f9f7 2515 return "#";
0ec259ed 2516 case TYPE_LEA:
0f40f9f7 2517 return "lea{q}\t{%a1, %0|%0, %a1}";
0ec259ed
JH
2518 default:
2519 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2520 abort ();
2521 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 2522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
0ec259ed 2523 else if (which_alternative == 2)
0f40f9f7 2524 return "movabs{q}\t{%1, %0|%0, %1}";
0ec259ed 2525 else
0f40f9f7 2526 return "mov{q}\t{%1, %0|%0, %1}";
0ec259ed 2527 }
0f40f9f7 2528}
0ec259ed
JH
2529 [(set (attr "type")
2530 (cond [(eq_attr "alternative" "5,6")
2531 (const_string "mmx")
2532 (eq_attr "alternative" "7,8")
2533 (const_string "sse")
2534 (eq_attr "alternative" "4")
2535 (const_string "multi")
2536 (and (ne (symbol_ref "flag_pic") (const_int 0))
2537 (match_operand:DI 1 "symbolic_operand" ""))
2538 (const_string "lea")
2539 ]
2540 (const_string "imov")))
141e454b
JH
2541 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2542 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2543 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
0ec259ed
JH
2544
2545;; Stores and loads of ax to arbitary constant address.
2546;; We fake an second form of instruction to force reload to load address
2547;; into register when rax is not available
2548(define_insn "*movabsdi_1_rex64"
2549 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2550 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2551 "TARGET_64BIT"
2552 "@
0f40f9f7
ZW
2553 movabs{q}\t{%1, %P0|%P0, %1}
2554 mov{q}\t{%1, %a0|%a0, %1}
2555 movabs{q}\t{%1, %a0|%a0, %1}"
0ec259ed
JH
2556 [(set_attr "type" "imov")
2557 (set_attr "modrm" "0,*,*")
2558 (set_attr "length_address" "8,0,0")
2559 (set_attr "length_immediate" "0,*,*")
2560 (set_attr "memory" "store")
2561 (set_attr "mode" "DI")])
2562
2563(define_insn "*movabsdi_2_rex64"
2564 [(set (match_operand:DI 0 "register_operand" "=a,r")
2565 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2566 "TARGET_64BIT"
2567 "@
0f40f9f7
ZW
2568 movabs{q}\t{%P1, %0|%0, %P1}
2569 mov{q}\t{%a1, %0|%0, %a1}"
0ec259ed
JH
2570 [(set_attr "type" "imov")
2571 (set_attr "modrm" "0,*")
2572 (set_attr "length_address" "8,0")
2573 (set_attr "length_immediate" "0")
2574 (set_attr "memory" "load")
2575 (set_attr "mode" "DI")])
2576
2577;; Convert impossible stores of immediate to existing instructions.
2578;; First try to get scratch register and go trought it. In case this
2579;; fails, move by 32bit parts.
2580(define_peephole2
2581 [(match_scratch:DI 2 "r")
2582 (set (match_operand:DI 0 "memory_operand" "")
2583 (match_operand:DI 1 "immediate_operand" ""))]
2584 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2585 && !x86_64_immediate_operand (operands[1], DImode)"
2586 [(set (match_dup 2) (match_dup 1))
2587 (set (match_dup 0) (match_dup 2))]
2588 "")
2589
2590;; We need to define this as both peepholer and splitter for case
2591;; peephole2 pass is not run.
2592(define_peephole2
2593 [(set (match_operand:DI 0 "memory_operand" "")
2594 (match_operand:DI 1 "immediate_operand" ""))]
2595 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2596 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2597 [(set (match_dup 2) (match_dup 3))
2598 (set (match_dup 4) (match_dup 5))]
2599 "split_di (operands, 2, operands + 2, operands + 4);")
2600
2601(define_split
2602 [(set (match_operand:DI 0 "memory_operand" "")
2603 (match_operand:DI 1 "immediate_operand" ""))]
2604 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2605 && !symbolic_operand (operands[1], DImode)
2606 && !x86_64_immediate_operand (operands[1], DImode)"
2607 [(set (match_dup 2) (match_dup 3))
2608 (set (match_dup 4) (match_dup 5))]
2609 "split_di (operands, 2, operands + 2, operands + 4);")
2610
2611(define_insn "*swapdi_rex64"
2612 [(set (match_operand:DI 0 "register_operand" "+r")
2613 (match_operand:DI 1 "register_operand" "+r"))
2614 (set (match_dup 1)
2615 (match_dup 0))]
2616 "TARGET_64BIT"
0f40f9f7 2617 "xchg{q}\t%1, %0"
0ec259ed
JH
2618 [(set_attr "type" "imov")
2619 (set_attr "pent_pair" "np")
2620 (set_attr "athlon_decode" "vector")
2621 (set_attr "mode" "DI")
2622 (set_attr "modrm" "0")
2623 (set_attr "ppro_uops" "few")])
2624
e075ae69 2625
0be5d99f 2626(define_expand "movsf"
4cbfbb1b 2627 [(set (match_operand:SF 0 "nonimmediate_operand" "")
0be5d99f
MM
2628 (match_operand:SF 1 "general_operand" ""))]
2629 ""
e075ae69
RH
2630 "ix86_expand_move (SFmode, operands); DONE;")
2631
2632(define_insn "*pushsf"
446988df 2633 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
c6e95f34 2634 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
0ec259ed 2635 "!TARGET_64BIT"
0be5d99f 2636{
e075ae69 2637 switch (which_alternative)
0be5d99f 2638 {
e075ae69
RH
2639 case 0:
2640 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2641 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2642 operands[2] = stack_pointer_rtx;
2643 operands[3] = GEN_INT (4);
2644 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2645 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
e075ae69 2646 else
0f40f9f7 2647 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
0bb6c81b 2648
e075ae69 2649 case 1:
0f40f9f7 2650 return "push{l}\t%1";
446988df 2651 case 2:
0f40f9f7 2652 return "#";
e075ae69
RH
2653
2654 default:
2655 abort ();
0bb6c81b 2656 }
0f40f9f7 2657}
446988df
JH
2658 [(set_attr "type" "multi,push,multi")
2659 (set_attr "mode" "SF,SI,SF")])
0be5d99f 2660
0ec259ed
JH
2661(define_insn "*pushsf_rex64"
2662 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2663 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2664 "TARGET_64BIT"
0ec259ed
JH
2665{
2666 switch (which_alternative)
2667 {
2668 case 0:
2669 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2670 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2671 operands[2] = stack_pointer_rtx;
2672 operands[3] = GEN_INT (8);
2673 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2674 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0ec259ed 2675 else
0f40f9f7 2676 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
0ec259ed
JH
2677
2678 case 1:
0f40f9f7 2679 return "push{q}\t%q1";
0ec259ed
JH
2680
2681 case 2:
0f40f9f7 2682 return "#";
0ec259ed
JH
2683
2684 default:
2685 abort ();
2686 }
0f40f9f7 2687}
0ec259ed
JH
2688 [(set_attr "type" "multi,push,multi")
2689 (set_attr "mode" "SF,DI,SF")])
2690
d7a29404
JH
2691(define_split
2692 [(set (match_operand:SF 0 "push_operand" "")
2693 (match_operand:SF 1 "memory_operand" ""))]
2694 "reload_completed
2695 && GET_CODE (operands[1]) == MEM
2696 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2697 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2698 [(set (match_dup 0)
2699 (match_dup 1))]
2700 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2701
2702
e075ae69
RH
2703;; %%% Kill this when call knows how to work this out.
2704(define_split
2705 [(set (match_operand:SF 0 "push_operand" "")
2706 (match_operand:SF 1 "register_operand" ""))]
0ec259ed 2707 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
2708 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2709 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2710
0ec259ed
JH
2711(define_split
2712 [(set (match_operand:SF 0 "push_operand" "")
2713 (match_operand:SF 1 "register_operand" ""))]
2714 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2715 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2716 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2717
e075ae69 2718(define_insn "*movsf_1"
2b04e52b
JH
2719 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2720 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
d7a29404
JH
2721 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2722 && (reload_in_progress || reload_completed
2723 || GET_CODE (operands[1]) != CONST_DOUBLE
2724 || memory_operand (operands[0], SFmode))"
886c62d1 2725{
e075ae69 2726 switch (which_alternative)
886c62d1 2727 {
e075ae69 2728 case 0:
0c174a68
AB
2729 if (REG_P (operands[1])
2730 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2731 return "fstp\t%y0";
e075ae69 2732 else if (STACK_TOP_P (operands[0]))
0f40f9f7 2733 return "fld%z1\t%y1";
886c62d1 2734 else
0f40f9f7 2735 return "fst\t%y0";
886c62d1 2736
e075ae69
RH
2737 case 1:
2738 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2739 return "fstp%z0\t%y0";
886c62d1 2740 else
0f40f9f7 2741 return "fst%z0\t%y0";
886c62d1 2742
e075ae69
RH
2743 case 2:
2744 switch (standard_80387_constant_p (operands[1]))
2745 {
2746 case 1:
0f40f9f7 2747 return "fldz";
e075ae69 2748 case 2:
0f40f9f7 2749 return "fld1";
e075ae69
RH
2750 }
2751 abort();
886c62d1 2752
e075ae69
RH
2753 case 3:
2754 case 4:
0f40f9f7 2755 return "mov{l}\t{%1, %0|%0, %1}";
446988df 2756 case 5:
0f40f9f7 2757 return "pxor\t%0, %0";
446988df 2758 case 6:
2b04e52b 2759 if (TARGET_PARTIAL_REG_DEPENDENCY)
0f40f9f7 2760 return "movaps\t{%1, %0|%0, %1}";
2b04e52b 2761 else
0f40f9f7 2762 return "movss\t{%1, %0|%0, %1}";
2b04e52b
JH
2763 case 7:
2764 case 8:
0f40f9f7 2765 return "movss\t{%1, %0|%0, %1}";
886c62d1 2766
e075ae69
RH
2767 default:
2768 abort();
2769 }
0f40f9f7 2770}
2b04e52b
JH
2771 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2772 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
d7a29404 2773
a4414093 2774(define_insn "*swapsf"
e075ae69
RH
2775 [(set (match_operand:SF 0 "register_operand" "+f")
2776 (match_operand:SF 1 "register_operand" "+f"))
0be5d99f
MM
2777 (set (match_dup 1)
2778 (match_dup 0))]
446988df 2779 "reload_completed || !TARGET_SSE2"
0be5d99f
MM
2780{
2781 if (STACK_TOP_P (operands[0]))
0f40f9f7 2782 return "fxch\t%1";
0be5d99f 2783 else
0f40f9f7
ZW
2784 return "fxch\t%0";
2785}
6ef67412
JH
2786 [(set_attr "type" "fxch")
2787 (set_attr "mode" "SF")])
0be5d99f 2788
e075ae69 2789(define_expand "movdf"
4cbfbb1b 2790 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e075ae69
RH
2791 (match_operand:DF 1 "general_operand" ""))]
2792 ""
2793 "ix86_expand_move (DFmode, operands); DONE;")
55953cea 2794
8fcaaa80
JH
2795;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2796;; Size of pushdf using integer insturctions is 2+2*memory operand size
2797;; On the average, pushdf using integers can be still shorter. Allow this
2798;; pattern for optimize_size too.
2799
0b5107cf 2800(define_insn "*pushdf_nointeger"
446988df 2801 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
c6e95f34 2802 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
0ec259ed 2803 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
0b5107cf
JH
2804{
2805 switch (which_alternative)
2806 {
2807 case 0:
2808 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2809 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2810 operands[2] = stack_pointer_rtx;
2811 operands[3] = GEN_INT (8);
2812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2813 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0b5107cf 2814 else
0f40f9f7 2815 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
0b5107cf
JH
2816
2817 case 1:
2818 case 2:
446988df 2819 case 3:
0f40f9f7 2820 return "#";
0b5107cf
JH
2821
2822 default:
2823 abort ();
2824 }
0f40f9f7 2825}
6ef67412 2826 [(set_attr "type" "multi")
446988df 2827 (set_attr "mode" "DF,SI,SI,DF")])
0b5107cf
JH
2828
2829(define_insn "*pushdf_integer"
446988df
JH
2830 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2831 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
0ec259ed 2832 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
f31fce3f 2833{
e075ae69 2834 switch (which_alternative)
f31fce3f 2835 {
e075ae69
RH
2836 case 0:
2837 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2838 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2839 operands[2] = stack_pointer_rtx;
2840 operands[3] = GEN_INT (8);
0ec259ed
JH
2841 if (TARGET_64BIT)
2842 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2843 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0ec259ed 2844 else
0f40f9f7 2845 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
f31fce3f 2846 else
0ec259ed 2847 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2848 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0ec259ed 2849 else
0f40f9f7 2850 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
0ec259ed 2851
dc0f0eb8 2852
e075ae69 2853 case 1:
446988df 2854 case 2:
0f40f9f7 2855 return "#";
dc0f0eb8 2856
e075ae69
RH
2857 default:
2858 abort ();
2859 }
0f40f9f7 2860}
6ef67412 2861 [(set_attr "type" "multi")
446988df 2862 (set_attr "mode" "DF,SI,DF")])
f31fce3f 2863
e075ae69 2864;; %%% Kill this when call knows how to work this out.
f72b27a5
JH
2865(define_split
2866 [(set (match_operand:DF 0 "push_operand" "")
e075ae69 2867 (match_operand:DF 1 "register_operand" ""))]
0ec259ed 2868 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
2869 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2870 (set (mem:DF (reg:SI 7)) (match_dup 1))]
f72b27a5 2871 "")
f31fce3f 2872
0ec259ed
JH
2873(define_split
2874 [(set (match_operand:DF 0 "push_operand" "")
2875 (match_operand:DF 1 "register_operand" ""))]
2876 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2877 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2878 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2879 "")
2880
e075ae69
RH
2881(define_split
2882 [(set (match_operand:DF 0 "push_operand" "")
0be5d99f 2883 (match_operand:DF 1 "general_operand" ""))]
e075ae69 2884 "reload_completed"
2450a057 2885 [(const_int 0)]
26e5b205 2886 "ix86_split_long_move (operands); DONE;")
0be5d99f 2887
8fcaaa80
JH
2888;; Moving is usually shorter when only FP registers are used. This separate
2889;; movdf pattern avoids the use of integer registers for FP operations
2890;; when optimizing for size.
2891
2892(define_insn "*movdf_nointeger"
2b04e52b
JH
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2894 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
8fcaaa80 2895 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
0b5107cf 2896 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
d7a29404
JH
2897 && (reload_in_progress || reload_completed
2898 || GET_CODE (operands[1]) != CONST_DOUBLE
2899 || memory_operand (operands[0], DFmode))"
8fcaaa80
JH
2900{
2901 switch (which_alternative)
2902 {
2903 case 0:
2904 if (REG_P (operands[1])
2905 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2906 return "fstp\t%y0";
8fcaaa80 2907 else if (STACK_TOP_P (operands[0]))
0f40f9f7 2908 return "fld%z1\t%y1";
8fcaaa80 2909 else
0f40f9f7 2910 return "fst\t%y0";
8fcaaa80
JH
2911
2912 case 1:
2913 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2914 return "fstp%z0\t%y0";
8fcaaa80 2915 else
0f40f9f7 2916 return "fst%z0\t%y0";
8fcaaa80
JH
2917
2918 case 2:
2919 switch (standard_80387_constant_p (operands[1]))
2920 {
2921 case 1:
0f40f9f7 2922 return "fldz";
8fcaaa80 2923 case 2:
0f40f9f7 2924 return "fld1";
8fcaaa80
JH
2925 }
2926 abort();
2927
2928 case 3:
2929 case 4:
0f40f9f7 2930 return "#";
446988df 2931 case 5:
0f40f9f7 2932 return "pxor\t%0, %0";
446988df 2933 case 6:
2b04e52b 2934 if (TARGET_PARTIAL_REG_DEPENDENCY)
0f40f9f7 2935 return "movapd\t{%1, %0|%0, %1}";
2b04e52b 2936 else
0f40f9f7 2937 return "movsd\t{%1, %0|%0, %1}";
2b04e52b
JH
2938 case 7:
2939 case 8:
0f40f9f7 2940 return "movsd\t{%1, %0|%0, %1}";
8fcaaa80
JH
2941
2942 default:
2943 abort();
2944 }
0f40f9f7 2945}
2b04e52b
JH
2946 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2947 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
8fcaaa80
JH
2948
2949(define_insn "*movdf_integer"
2b04e52b
JH
2950 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2951 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
8fcaaa80 2952 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
0b5107cf 2953 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
d7a29404
JH
2954 && (reload_in_progress || reload_completed
2955 || GET_CODE (operands[1]) != CONST_DOUBLE
2956 || memory_operand (operands[0], DFmode))"
886c62d1 2957{
e075ae69 2958 switch (which_alternative)
886c62d1 2959 {
e075ae69 2960 case 0:
0c174a68
AB
2961 if (REG_P (operands[1])
2962 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2963 return "fstp\t%y0";
e075ae69 2964 else if (STACK_TOP_P (operands[0]))
0f40f9f7 2965 return "fld%z1\t%y1";
886c62d1 2966 else
0f40f9f7 2967 return "fst\t%y0";
886c62d1 2968
e075ae69
RH
2969 case 1:
2970 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 2971 return "fstp%z0\t%y0";
886c62d1 2972 else
0f40f9f7 2973 return "fst%z0\t%y0";
886c62d1 2974
e075ae69
RH
2975 case 2:
2976 switch (standard_80387_constant_p (operands[1]))
2977 {
2978 case 1:
0f40f9f7 2979 return "fldz";
e075ae69 2980 case 2:
0f40f9f7 2981 return "fld1";
e075ae69
RH
2982 }
2983 abort();
886c62d1 2984
e075ae69
RH
2985 case 3:
2986 case 4:
0f40f9f7 2987 return "#";
886c62d1 2988
446988df 2989 case 5:
0f40f9f7 2990 return "pxor\t%0, %0";
446988df 2991 case 6:
2b04e52b 2992 if (TARGET_PARTIAL_REG_DEPENDENCY)
0f40f9f7 2993 return "movapd\t{%1, %0|%0, %1}";
2b04e52b 2994 else
0f40f9f7 2995 return "movsd\t{%1, %0|%0, %1}";
2b04e52b
JH
2996 case 7:
2997 case 8:
0f40f9f7 2998 return "movsd\t{%1, %0|%0, %1}";
446988df 2999
e075ae69
RH
3000 default:
3001 abort();
3002 }
0f40f9f7 3003}
2b04e52b
JH
3004 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3005 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2ae0f82c 3006
e075ae69
RH
3007(define_split
3008 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3009 (match_operand:DF 1 "general_operand" ""))]
3010 "reload_completed
3011 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
446988df 3012 && ! (ANY_FP_REG_P (operands[0]) ||
e075ae69 3013 (GET_CODE (operands[0]) == SUBREG
446988df
JH
3014 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3015 && ! (ANY_FP_REG_P (operands[1]) ||
e075ae69 3016 (GET_CODE (operands[1]) == SUBREG
446988df 3017 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
3018 [(const_int 0)]
3019 "ix86_split_long_move (operands); DONE;")
886c62d1 3020
a4414093 3021(define_insn "*swapdf"
e075ae69
RH
3022 [(set (match_operand:DF 0 "register_operand" "+f")
3023 (match_operand:DF 1 "register_operand" "+f"))
0be5d99f
MM
3024 (set (match_dup 1)
3025 (match_dup 0))]
446988df 3026 "reload_completed || !TARGET_SSE2"
0be5d99f
MM
3027{
3028 if (STACK_TOP_P (operands[0]))
0f40f9f7 3029 return "fxch\t%1";
0be5d99f 3030 else
0f40f9f7
ZW
3031 return "fxch\t%0";
3032}
6ef67412
JH
3033 [(set_attr "type" "fxch")
3034 (set_attr "mode" "DF")])
e075ae69
RH
3035
3036(define_expand "movxf"
4cbfbb1b 3037 [(set (match_operand:XF 0 "nonimmediate_operand" "")
e075ae69 3038 (match_operand:XF 1 "general_operand" ""))]
1e07edd3 3039 "!TARGET_64BIT"
e075ae69 3040 "ix86_expand_move (XFmode, operands); DONE;")
0be5d99f 3041
2b589241
JH
3042(define_expand "movtf"
3043 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3044 (match_operand:TF 1 "general_operand" ""))]
3045 ""
3046 "ix86_expand_move (TFmode, operands); DONE;")
3047
8fcaaa80
JH
3048;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3049;; Size of pushdf using integer insturctions is 3+3*memory operand size
3050;; Pushing using integer instructions is longer except for constants
3051;; and direct memory references.
3052;; (assuming that any given constant is pushed only once, but this ought to be
3053;; handled elsewhere).
3054
3055(define_insn "*pushxf_nointeger"
1e07edd3 3056 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2c5a510c 3057 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
1b0c37d7 3058 "!TARGET_64BIT && optimize_size"
8fcaaa80
JH
3059{
3060 switch (which_alternative)
3061 {
3062 case 0:
3063 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3064 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3065 operands[2] = stack_pointer_rtx;
3066 operands[3] = GEN_INT (12);
3067 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3068 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
8fcaaa80 3069 else
0f40f9f7 3070 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
8fcaaa80
JH
3071
3072 case 1:
3073 case 2:
0f40f9f7 3074 return "#";
8fcaaa80
JH
3075
3076 default:
3077 abort ();
3078 }
0f40f9f7 3079}
6ef67412
JH
3080 [(set_attr "type" "multi")
3081 (set_attr "mode" "XF,SI,SI")])
8fcaaa80 3082
2b589241
JH
3083(define_insn "*pushtf_nointeger"
3084 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3085 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3086 "optimize_size"
2b589241
JH
3087{
3088 switch (which_alternative)
3089 {
3090 case 0:
3091 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3092 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3093 operands[2] = stack_pointer_rtx;
3094 operands[3] = GEN_INT (16);
3095 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3096 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2b589241 3097 else
0f40f9f7 3098 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2b589241
JH
3099
3100 case 1:
3101 case 2:
0f40f9f7 3102 return "#";
2b589241
JH
3103
3104 default:
3105 abort ();
3106 }
0f40f9f7 3107}
2b589241
JH
3108 [(set_attr "type" "multi")
3109 (set_attr "mode" "XF,SI,SI")])
3110
8fcaaa80 3111(define_insn "*pushxf_integer"
2450a057 3112 [(set (match_operand:XF 0 "push_operand" "=<,<")
1e07edd3 3113 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
1b0c37d7 3114 "!TARGET_64BIT && !optimize_size"
f31fce3f 3115{
8fcaaa80
JH
3116 switch (which_alternative)
3117 {
3118 case 0:
3119 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3120 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3121 operands[2] = stack_pointer_rtx;
3122 operands[3] = GEN_INT (12);
3123 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3124 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
8fcaaa80 3125 else
0f40f9f7 3126 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
8fcaaa80
JH
3127
3128 case 1:
0f40f9f7 3129 return "#";
8fcaaa80
JH
3130
3131 default:
3132 abort ();
3133 }
0f40f9f7 3134}
6ef67412
JH
3135 [(set_attr "type" "multi")
3136 (set_attr "mode" "XF,SI")])
f31fce3f 3137
2b589241
JH
3138(define_insn "*pushtf_integer"
3139 [(set (match_operand:TF 0 "push_operand" "=<,<")
3140 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3141 "!optimize_size"
2b589241
JH
3142{
3143 switch (which_alternative)
3144 {
3145 case 0:
3146 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3147 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3148 operands[2] = stack_pointer_rtx;
3149 operands[3] = GEN_INT (16);
0ec259ed
JH
3150 if (TARGET_64BIT)
3151 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3152 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0ec259ed 3153 else
0f40f9f7 3154 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2b589241 3155 else
0ec259ed 3156 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3157 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
0ec259ed 3158 else
0f40f9f7 3159 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2b589241
JH
3160
3161 case 1:
0f40f9f7 3162 return "#";
2b589241
JH
3163
3164 default:
3165 abort ();
3166 }
0f40f9f7 3167}
2b589241
JH
3168 [(set_attr "type" "multi")
3169 (set_attr "mode" "XF,SI")])
3170
2450a057 3171(define_split
2b589241
JH
3172 [(set (match_operand 0 "push_operand" "")
3173 (match_operand 1 "general_operand" ""))]
2450a057 3174 "reload_completed
2b589241
JH
3175 && (GET_MODE (operands[0]) == XFmode
3176 || GET_MODE (operands[0]) == TFmode
3177 || GET_MODE (operands[0]) == DFmode)
446988df 3178 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
2450a057 3179 [(const_int 0)]
26e5b205 3180 "ix86_split_long_move (operands); DONE;")
2450a057 3181
f72b27a5
JH
3182(define_split
3183 [(set (match_operand:XF 0 "push_operand" "")
e075ae69 3184 (match_operand:XF 1 "register_operand" ""))]
0ec259ed 3185 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
3186 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3187 (set (mem:XF (reg:SI 7)) (match_dup 1))])
f31fce3f 3188
2b589241
JH
3189(define_split
3190 [(set (match_operand:TF 0 "push_operand" "")
3191 (match_operand:TF 1 "register_operand" ""))]
0ec259ed 3192 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2b589241
JH
3193 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3194 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3195
0ec259ed
JH
3196(define_split
3197 [(set (match_operand:TF 0 "push_operand" "")
3198 (match_operand:TF 1 "register_operand" ""))]
3199 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3200 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3201 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3202
8fcaaa80
JH
3203;; Do not use integer registers when optimizing for size
3204(define_insn "*movxf_nointeger"
3205 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
1b0c37d7 3207 "!TARGET_64BIT
d7a29404 3208 && optimize_size
1b0c37d7 3209 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
3210 && (reload_in_progress || reload_completed
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || memory_operand (operands[0], XFmode))"
0be5d99f 3213{
8fcaaa80
JH
3214 switch (which_alternative)
3215 {
3216 case 0:
3217 if (REG_P (operands[1])
3218 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3219 return "fstp\t%y0";
8fcaaa80 3220 else if (STACK_TOP_P (operands[0]))
0f40f9f7 3221 return "fld%z1\t%y1";
8fcaaa80 3222 else
0f40f9f7 3223 return "fst\t%y0";
0be5d99f 3224
8fcaaa80
JH
3225 case 1:
3226 /* There is no non-popping store to memory for XFmode. So if
3227 we need one, follow the store with a load. */
3228 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3229 return "fstp%z0\t%y0\;fld%z0\t%y0";
8fcaaa80 3230 else
0f40f9f7 3231 return "fstp%z0\t%y0";
8fcaaa80
JH
3232
3233 case 2:
3234 switch (standard_80387_constant_p (operands[1]))
3235 {
3236 case 1:
0f40f9f7 3237 return "fldz";
8fcaaa80 3238 case 2:
0f40f9f7 3239 return "fld1";
8fcaaa80
JH
3240 }
3241 break;
3242
3243 case 3: case 4:
0f40f9f7 3244 return "#";
8fcaaa80
JH
3245 }
3246 abort();
0f40f9f7 3247}
6ef67412
JH
3248 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3249 (set_attr "mode" "XF,XF,XF,SI,SI")])
8fcaaa80 3250
2b589241
JH
3251(define_insn "*movtf_nointeger"
3252 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3253 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3254 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3255 && optimize_size
3256 && (reload_in_progress || reload_completed
3257 || GET_CODE (operands[1]) != CONST_DOUBLE
3258 || memory_operand (operands[0], TFmode))"
2b589241
JH
3259{
3260 switch (which_alternative)
3261 {
3262 case 0:
3263 if (REG_P (operands[1])
3264 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3265 return "fstp\t%y0";
2b589241 3266 else if (STACK_TOP_P (operands[0]))
0f40f9f7 3267 return "fld%z1\t%y1";
2b589241 3268 else
0f40f9f7 3269 return "fst\t%y0";
2b589241
JH
3270
3271 case 1:
3272 /* There is no non-popping store to memory for XFmode. So if
3273 we need one, follow the store with a load. */
3274 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3275 return "fstp%z0\t%y0\;fld%z0\t%y0";
2b589241 3276 else
0f40f9f7 3277 return "fstp%z0\t%y0";
2b589241
JH
3278
3279 case 2:
3280 switch (standard_80387_constant_p (operands[1]))
3281 {
3282 case 1:
0f40f9f7 3283 return "fldz";
2b589241 3284 case 2:
0f40f9f7 3285 return "fld1";
2b589241
JH
3286 }
3287 break;
3288
3289 case 3: case 4:
0f40f9f7 3290 return "#";
2b589241
JH
3291 }
3292 abort();
0f40f9f7 3293}
2b589241
JH
3294 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3295 (set_attr "mode" "XF,XF,XF,SI,SI")])
3296
8fcaaa80
JH
3297(define_insn "*movxf_integer"
3298 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3299 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
1b0c37d7 3300 "!TARGET_64BIT
d7a29404 3301 && !optimize_size
1b0c37d7 3302 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
d7a29404
JH
3303 && (reload_in_progress || reload_completed
3304 || GET_CODE (operands[1]) != CONST_DOUBLE
3305 || memory_operand (operands[0], XFmode))"
4fb21e90 3306{
e075ae69 3307 switch (which_alternative)
4fb21e90 3308 {
e075ae69 3309 case 0:
0c174a68
AB
3310 if (REG_P (operands[1])
3311 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3312 return "fstp\t%y0";
e075ae69 3313 else if (STACK_TOP_P (operands[0]))
0f40f9f7 3314 return "fld%z1\t%y1";
4fb21e90 3315 else
0f40f9f7 3316 return "fst\t%y0";
4fb21e90 3317
e075ae69
RH
3318 case 1:
3319 /* There is no non-popping store to memory for XFmode. So if
3320 we need one, follow the store with a load. */
3321 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3322 return "fstp%z0\t%y0\;fld%z0\t%y0";
e075ae69 3323 else
0f40f9f7 3324 return "fstp%z0\t%y0";
2f17722a 3325
e075ae69
RH
3326 case 2:
3327 switch (standard_80387_constant_p (operands[1]))
3328 {
3329 case 1:
0f40f9f7 3330 return "fldz";
e075ae69 3331 case 2:
0f40f9f7 3332 return "fld1";
e075ae69
RH
3333 }
3334 break;
467403ca
RH
3335
3336 case 3: case 4:
0f40f9f7 3337 return "#";
4fb21e90 3338 }
e075ae69 3339 abort();
0f40f9f7 3340}
6ef67412
JH
3341 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3342 (set_attr "mode" "XF,XF,XF,SI,SI")])
4fb21e90 3343
2b589241
JH
3344(define_insn "*movtf_integer"
3345 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3346 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3347 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3348 && !optimize_size
3349 && (reload_in_progress || reload_completed
3350 || GET_CODE (operands[1]) != CONST_DOUBLE
3351 || memory_operand (operands[0], TFmode))"
2b589241
JH
3352{
3353 switch (which_alternative)
3354 {
3355 case 0:
3356 if (REG_P (operands[1])
3357 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3358 return "fstp\t%y0";
2b589241 3359 else if (STACK_TOP_P (operands[0]))
0f40f9f7 3360 return "fld%z1\t%y1";
2b589241 3361 else
0f40f9f7 3362 return "fst\t%y0";
2b589241
JH
3363
3364 case 1:
3365 /* There is no non-popping store to memory for XFmode. So if
3366 we need one, follow the store with a load. */
3367 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 3368 return "fstp%z0\t%y0\;fld%z0\t%y0";
2b589241 3369 else
0f40f9f7 3370 return "fstp%z0\t%y0";
2b589241
JH
3371
3372 case 2:
3373 switch (standard_80387_constant_p (operands[1]))
3374 {
3375 case 1:
0f40f9f7 3376 return "fldz";
2b589241 3377 case 2:
0f40f9f7 3378 return "fld1";
2b589241
JH
3379 }
3380 break;
3381
3382 case 3: case 4:
0f40f9f7 3383 return "#";
2b589241
JH
3384 }
3385 abort();
0f40f9f7 3386}
2b589241
JH
3387 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3388 (set_attr "mode" "XF,XF,XF,SI,SI")])
3389
467403ca 3390(define_split
2b589241
JH
3391 [(set (match_operand 0 "nonimmediate_operand" "")
3392 (match_operand 1 "general_operand" ""))]
2450a057 3393 "reload_completed
8fcaaa80 3394 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2b589241 3395 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
446988df 3396 && ! (ANY_FP_REG_P (operands[0]) ||
8fcaaa80 3397 (GET_CODE (operands[0]) == SUBREG
446988df
JH
3398 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3399 && ! (ANY_FP_REG_P (operands[1]) ||
8fcaaa80 3400 (GET_CODE (operands[1]) == SUBREG
446988df 3401 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
26e5b205
JH
3402 [(const_int 0)]
3403 "ix86_split_long_move (operands); DONE;")
467403ca 3404
d7a29404 3405(define_split
2b589241
JH
3406 [(set (match_operand 0 "register_operand" "")
3407 (match_operand 1 "memory_operand" ""))]
d7a29404
JH
3408 "reload_completed
3409 && GET_CODE (operands[1]) == MEM
2b04e52b
JH
3410 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3411 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
d7a29404
JH
3412 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3413 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2b04e52b
JH
3414 && (!(SSE_REG_P (operands[0]) ||
3415 (GET_CODE (operands[0]) == SUBREG
3416 && SSE_REG_P (SUBREG_REG (operands[0]))))
3417 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3418 && (!(FP_REG_P (operands[0]) ||
3419 (GET_CODE (operands[0]) == SUBREG
3420 && FP_REG_P (SUBREG_REG (operands[0]))))
3421 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
d7a29404
JH
3422 [(set (match_dup 0)
3423 (match_dup 1))]
3424 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3425
e075ae69
RH
3426(define_insn "swapxf"
3427 [(set (match_operand:XF 0 "register_operand" "+f")
3428 (match_operand:XF 1 "register_operand" "+f"))
0be5d99f
MM
3429 (set (match_dup 1)
3430 (match_dup 0))]
3431 ""
0be5d99f
MM
3432{
3433 if (STACK_TOP_P (operands[0]))
0f40f9f7 3434 return "fxch\t%1";
0be5d99f 3435 else
0f40f9f7
ZW
3436 return "fxch\t%0";
3437}
0b5107cf 3438 [(set_attr "type" "fxch")
6ef67412 3439 (set_attr "mode" "XF")])
2b589241
JH
3440
3441(define_insn "swaptf"
3442 [(set (match_operand:TF 0 "register_operand" "+f")
3443 (match_operand:TF 1 "register_operand" "+f"))
3444 (set (match_dup 1)
3445 (match_dup 0))]
3446 ""
2b589241
JH
3447{
3448 if (STACK_TOP_P (operands[0]))
0f40f9f7 3449 return "fxch\t%1";
2b589241 3450 else
0f40f9f7
ZW
3451 return "fxch\t%0";
3452}
2b589241
JH
3453 [(set_attr "type" "fxch")
3454 (set_attr "mode" "XF")])
886c62d1 3455\f
e075ae69 3456;; Zero extension instructions
886c62d1 3457
8f7661f2
JH
3458(define_expand "zero_extendhisi2"
3459 [(set (match_operand:SI 0 "register_operand" "")
3460 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 3461 ""
e075ae69 3462{
8f7661f2 3463 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2ae0f82c 3464 {
8f7661f2
JH
3465 operands[1] = force_reg (HImode, operands[1]);
3466 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3467 DONE;
2ae0f82c 3468 }
0f40f9f7 3469})
886c62d1 3470
8f7661f2
JH
3471(define_insn "zero_extendhisi2_and"
3472 [(set (match_operand:SI 0 "register_operand" "=r")
3473 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
e075ae69 3474 (clobber (reg:CC 17))]
8f7661f2
JH
3475 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3476 "#"
6ef67412
JH
3477 [(set_attr "type" "alu1")
3478 (set_attr "mode" "SI")])
2ae0f82c
SC
3479
3480(define_split
3481 [(set (match_operand:SI 0 "register_operand" "")
8f7661f2 3482 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
e075ae69 3483 (clobber (reg:CC 17))]
8f7661f2
JH
3484 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3485 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
e075ae69 3486 (clobber (reg:CC 17))])]
d626200a
JL
3487 "")
3488
8f7661f2
JH
3489(define_insn "*zero_extendhisi2_movzwl"
3490 [(set (match_operand:SI 0 "register_operand" "=r")
3491 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3492 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
0f40f9f7 3493 "movz{wl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3494 [(set_attr "type" "imovx")
3495 (set_attr "mode" "SI")])
8f7661f2
JH
3496
3497(define_expand "zero_extendqihi2"
3498 [(parallel
3499 [(set (match_operand:HI 0 "register_operand" "")
3500 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3501 (clobber (reg:CC 17))])]
e075ae69 3502 ""
8f7661f2
JH
3503 "")
3504
3505(define_insn "*zero_extendqihi2_and"
3506 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3507 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3508 (clobber (reg:CC 17))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3510 "#"
6ef67412
JH
3511 [(set_attr "type" "alu1")
3512 (set_attr "mode" "HI")])
8f7661f2
JH
3513
3514(define_insn "*zero_extendqihi2_movzbw_and"
3515 [(set (match_operand:HI 0 "register_operand" "=r,r")
3516 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3517 (clobber (reg:CC 17))]
3518 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3519 "#"
6ef67412
JH
3520 [(set_attr "type" "imovx,alu1")
3521 (set_attr "mode" "HI")])
886c62d1 3522
8f7661f2
JH
3523(define_insn "*zero_extendqihi2_movzbw"
3524 [(set (match_operand:HI 0 "register_operand" "=r")
3525 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1c27d4b2 3526 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 3527 "movz{bw|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "HI")])
8f7661f2
JH
3530
3531;; For the movzbw case strip only the clobber
2ae0f82c
SC
3532(define_split
3533 [(set (match_operand:HI 0 "register_operand" "")
e075ae69
RH
3534 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC 17))]
8f7661f2
JH
3536 "reload_completed
3537 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3538 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2ae0f82c 3541
8f7661f2
JH
3542;; When source and destination does not overlap, clear destination
3543;; first and then do the movb
2ae0f82c
SC
3544(define_split
3545 [(set (match_operand:HI 0 "register_operand" "")
8f7661f2 3546 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
e075ae69
RH
3547 (clobber (reg:CC 17))]
3548 "reload_completed
1a06f5fe 3549 && ANY_QI_REG_P (operands[0])
8f7661f2
JH
3550 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3551 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3552 [(set (match_dup 0) (const_int 0))
3553 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3554 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3555
8f7661f2 3556;; Rest is handled by single and.
2ae0f82c
SC
3557(define_split
3558 [(set (match_operand:HI 0 "register_operand" "")
e075ae69
RH
3559 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3560 (clobber (reg:CC 17))]
3561 "reload_completed
8f7661f2
JH
3562 && true_regnum (operands[0]) == true_regnum (operands[1])"
3563 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
e075ae69 3564 (clobber (reg:CC 17))])]
d626200a
JL
3565 "")
3566
8f7661f2
JH
3567(define_expand "zero_extendqisi2"
3568 [(parallel
3569 [(set (match_operand:SI 0 "register_operand" "")
3570 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3571 (clobber (reg:CC 17))])]
e075ae69 3572 ""
8f7661f2
JH
3573 "")
3574
3575(define_insn "*zero_extendqisi2_and"
3576 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3577 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3578 (clobber (reg:CC 17))]
3579 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3580 "#"
6ef67412
JH
3581 [(set_attr "type" "alu1")
3582 (set_attr "mode" "SI")])
8f7661f2
JH
3583
3584(define_insn "*zero_extendqisi2_movzbw_and"
3585 [(set (match_operand:SI 0 "register_operand" "=r,r")
3586 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3587 (clobber (reg:CC 17))]
3588 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3589 "#"
6ef67412
JH
3590 [(set_attr "type" "imovx,alu1")
3591 (set_attr "mode" "SI")])
2ae0f82c 3592
8f7661f2
JH
3593(define_insn "*zero_extendqisi2_movzbw"
3594 [(set (match_operand:SI 0 "register_operand" "=r")
3595 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3596 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
0f40f9f7 3597 "movz{bl|x}\t{%1, %0|%0, %1}"
6ef67412
JH
3598 [(set_attr "type" "imovx")
3599 (set_attr "mode" "SI")])
8f7661f2
JH
3600
3601;; For the movzbl case strip only the clobber
3602(define_split
3603 [(set (match_operand:SI 0 "register_operand" "")
3604 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605 (clobber (reg:CC 17))]
3606 "reload_completed
3607 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3608 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3609 [(set (match_dup 0)
3610 (zero_extend:SI (match_dup 1)))])
3611
3612;; When source and destination does not overlap, clear destination
3613;; first and then do the movb
2ae0f82c
SC
3614(define_split
3615 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
3616 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3617 (clobber (reg:CC 17))]
3618 "reload_completed
1a06f5fe
JH
3619 && ANY_QI_REG_P (operands[0])
3620 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
8f7661f2 3621 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
e075ae69 3622 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8f7661f2
JH
3623 [(set (match_dup 0) (const_int 0))
3624 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3625 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3626
8f7661f2 3627;; Rest is handled by single and.
2ae0f82c
SC
3628(define_split
3629 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
3630 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3631 (clobber (reg:CC 17))]
3632 "reload_completed
8f7661f2
JH
3633 && true_regnum (operands[0]) == true_regnum (operands[1])"
3634 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
e075ae69
RH
3635 (clobber (reg:CC 17))])]
3636 "")
2ae0f82c 3637
e075ae69 3638;; %%% Kill me once multi-word ops are sane.
123bf9e3
JH
3639(define_expand "zero_extendsidi2"
3640 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3642 ""
3643 "if (!TARGET_64BIT)
3644 {
3645 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3646 DONE;
3647 }
3648 ")
3649
3650(define_insn "zero_extendsidi2_32"
bb62e19a 3651 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
123bf9e3 3652 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
e075ae69 3653 (clobber (reg:CC 17))]
123bf9e3 3654 "!TARGET_64BIT"
6ef67412
JH
3655 "#"
3656 [(set_attr "mode" "SI")])
2ae0f82c 3657
123bf9e3
JH
3658(define_insn "zero_extendsidi2_rex64"
3659 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3660 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3661 "TARGET_64BIT"
3662 "@
0f40f9f7 3663 mov\t{%k1, %k0|%k0, %k1}
123bf9e3
JH
3664 #"
3665 [(set_attr "type" "imovx,imov")
3666 (set_attr "mode" "SI,DI")])
3667
3668(define_split
3669 [(set (match_operand:DI 0 "memory_operand" "")
3670 (zero_extend:DI (match_dup 0)))]
1b0c37d7 3671 "TARGET_64BIT"
123bf9e3
JH
3672 [(set (match_dup 4) (const_int 0))]
3673 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3674
bb62e19a
JH
3675(define_split
3676 [(set (match_operand:DI 0 "register_operand" "")
e075ae69
RH
3677 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3678 (clobber (reg:CC 17))]
1b0c37d7
ZW
3679 "!TARGET_64BIT && reload_completed
3680 && true_regnum (operands[0]) == true_regnum (operands[1])"
591702de 3681 [(set (match_dup 4) (const_int 0))]
bb62e19a
JH
3682 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3683
3684(define_split
3685 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
3686 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3687 (clobber (reg:CC 17))]
1b0c37d7 3688 "!TARGET_64BIT && reload_completed"
bb62e19a 3689 [(set (match_dup 3) (match_dup 1))
591702de 3690 (set (match_dup 4) (const_int 0))]
bb62e19a 3691 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
123bf9e3
JH
3692
3693(define_insn "zero_extendhidi2"
3694 [(set (match_operand:DI 0 "register_operand" "=r,r")
3695 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3696 "TARGET_64BIT"
3697 "@
0f40f9f7
ZW
3698 movz{wl|x}\t{%1, %k0|%k0, %1}
3699 movz{wq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3700 [(set_attr "type" "imovx")
3701 (set_attr "mode" "SI,DI")])
3702
3703(define_insn "zero_extendqidi2"
3704 [(set (match_operand:DI 0 "register_operand" "=r,r")
3705 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3706 "TARGET_64BIT"
3707 "@
0f40f9f7
ZW
3708 movz{bl|x}\t{%1, %k0|%k0, %1}
3709 movz{bq|x}\t{%1, %0|%0, %1}"
123bf9e3
JH
3710 [(set_attr "type" "imovx")
3711 (set_attr "mode" "SI,DI")])
886c62d1 3712\f
e075ae69 3713;; Sign extension instructions
886c62d1 3714
123bf9e3
JH
3715(define_expand "extendsidi2"
3716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC 17))
3719 (clobber (match_scratch:SI 2 ""))])]
3720 ""
123bf9e3
JH
3721{
3722 if (TARGET_64BIT)
3723 {
3724 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3725 DONE;
3726 }
0f40f9f7 3727})
123bf9e3
JH
3728
3729(define_insn "*extendsidi2_1"
e075ae69
RH
3730 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
6b29b0e2
JW
3732 (clobber (reg:CC 17))
3733 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
123bf9e3 3734 "!TARGET_64BIT"
724d568a
JH
3735 "#")
3736
123bf9e3
JH
3737(define_insn "extendsidi2_rex64"
3738 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3740 "TARGET_64BIT"
3741 "@
3742 {cltq|cdqe}
0f40f9f7 3743 movs{lq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "DI")
3746 (set_attr "prefix_0f" "0")
3747 (set_attr "modrm" "0,1")])
3748
3749(define_insn "extendhidi2"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3752 "TARGET_64BIT"
0f40f9f7 3753 "movs{wq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3756
3757(define_insn "extendqidi2"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3759 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760 "TARGET_64BIT"
0f40f9f7 3761 "movs{bq|x}\t{%1,%0|%0, %1}"
123bf9e3
JH
3762 [(set_attr "type" "imovx")
3763 (set_attr "mode" "DI")])
3764
724d568a
JH
3765;; Extend to memory case when source register does die.
3766(define_split
3767 [(set (match_operand:DI 0 "memory_operand" "")
3768 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3769 (clobber (reg:CC 17))
3770 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3771 "(reload_completed
724d568a
JH
3772 && dead_or_set_p (insn, operands[1])
3773 && !reg_mentioned_p (operands[1], operands[0]))"
3774 [(set (match_dup 3) (match_dup 1))
e075ae69
RH
3775 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776 (clobber (reg:CC 17))])
724d568a
JH
3777 (set (match_dup 4) (match_dup 1))]
3778 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3779
3780;; Extend to memory case when source register does not die.
3781(define_split
3782 [(set (match_operand:DI 0 "memory_operand" "")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3784 (clobber (reg:CC 17))
3785 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3786 "reload_completed"
724d568a 3787 [(const_int 0)]
9c530261 3788{
724d568a
JH
3789 split_di (&operands[0], 1, &operands[3], &operands[4]);
3790
3791 emit_move_insn (operands[3], operands[1]);
3792
3793 /* Generate a cltd if possible and doing so it profitable. */
3794 if (true_regnum (operands[1]) == 0
3795 && true_regnum (operands[2]) == 1
e075ae69 3796 && (optimize_size || TARGET_USE_CLTD))
71a247f0 3797 {
e075ae69 3798 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
3799 }
3800 else
3801 {
3802 emit_move_insn (operands[2], operands[1]);
e075ae69 3803 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
71a247f0 3804 }
724d568a
JH
3805 emit_move_insn (operands[4], operands[2]);
3806 DONE;
0f40f9f7 3807})
9c530261 3808
724d568a
JH
3809;; Extend to register case. Optimize case where source and destination
3810;; registers match and cases where we can use cltd.
3811(define_split
3812 [(set (match_operand:DI 0 "register_operand" "")
3813 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3814 (clobber (reg:CC 17))
3815 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
3816 "reload_completed"
3817 [(const_int 0)]
724d568a
JH
3818{
3819 split_di (&operands[0], 1, &operands[3], &operands[4]);
3820
3821 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822 emit_move_insn (operands[3], operands[1]);
9c530261 3823
724d568a
JH
3824 /* Generate a cltd if possible and doing so it profitable. */
3825 if (true_regnum (operands[3]) == 0
e075ae69 3826 && (optimize_size || TARGET_USE_CLTD))
724d568a 3827 {
e075ae69 3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
3829 DONE;
3830 }
3831
3832 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833 emit_move_insn (operands[4], operands[1]);
3834
e075ae69 3835 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
724d568a 3836 DONE;
0f40f9f7 3837})
886c62d1 3838
886c62d1 3839(define_insn "extendhisi2"
e075ae69
RH
3840 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1 3842 ""
886c62d1 3843{
6ef67412 3844 switch (get_attr_prefix_0f (insn))
e075ae69 3845 {
6ef67412 3846 case 0:
0f40f9f7 3847 return "{cwtl|cwde}";
e075ae69 3848 default:
0f40f9f7 3849 return "movs{wl|x}\t{%1,%0|%0, %1}";
e075ae69 3850 }
0f40f9f7 3851}
e075ae69 3852 [(set_attr "type" "imovx")
6ef67412
JH
3853 (set_attr "mode" "SI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3858 (const_string "0")
3859 (const_string "1")))
3860 (set (attr "modrm")
3861 (if_then_else (eq_attr "prefix_0f" "0")
3862 (const_string "0")
3863 (const_string "1")))])
886c62d1 3864
123bf9e3
JH
3865(define_insn "*extendhisi2_zext"
3866 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3867 (zero_extend:DI
3868 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3869 "TARGET_64BIT"
123bf9e3
JH
3870{
3871 switch (get_attr_prefix_0f (insn))
3872 {
3873 case 0:
0f40f9f7 3874 return "{cwtl|cwde}";
123bf9e3 3875 default:
0f40f9f7 3876 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
123bf9e3 3877 }
0f40f9f7 3878}
123bf9e3
JH
3879 [(set_attr "type" "imovx")
3880 (set_attr "mode" "SI")
3881 (set (attr "prefix_0f")
3882 ;; movsx is short decodable while cwtl is vector decoded.
3883 (if_then_else (and (eq_attr "cpu" "!k6")
3884 (eq_attr "alternative" "0"))
3885 (const_string "0")
3886 (const_string "1")))
3887 (set (attr "modrm")
3888 (if_then_else (eq_attr "prefix_0f" "0")
3889 (const_string "0")
3890 (const_string "1")))])
3891
886c62d1 3892(define_insn "extendqihi2"
e075ae69
RH
3893 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1 3895 ""
886c62d1 3896{
6ef67412 3897 switch (get_attr_prefix_0f (insn))
e075ae69 3898 {
6ef67412 3899 case 0:
0f40f9f7 3900 return "{cbtw|cbw}";
e075ae69 3901 default:
0f40f9f7 3902 return "movs{bw|x}\t{%1,%0|%0, %1}";
e075ae69 3903 }
0f40f9f7 3904}
e075ae69 3905 [(set_attr "type" "imovx")
6ef67412
JH
3906 (set_attr "mode" "HI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3911 (const_string "0")
3912 (const_string "1")))
3913 (set (attr "modrm")
3914 (if_then_else (eq_attr "prefix_0f" "0")
3915 (const_string "0")
3916 (const_string "1")))])
886c62d1
JVA
3917
3918(define_insn "extendqisi2"
2ae0f82c
SC
3919 [(set (match_operand:SI 0 "register_operand" "=r")
3920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1 3921 ""
0f40f9f7 3922 "movs{bl|x}\t{%1,%0|%0, %1}"
6ef67412
JH
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "SI")])
123bf9e3
JH
3925
3926(define_insn "*extendqisi2_zext"
3927 [(set (match_operand:DI 0 "register_operand" "=r")
3928 (zero_extend:DI
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3930 "TARGET_64BIT"
0f40f9f7 3931 "movs{bl|x}\t{%1,%k0|%k0, %1}"
123bf9e3
JH
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
886c62d1
JVA
3934\f
3935;; Conversions between float and double.
3936
e075ae69
RH
3937;; These are all no-ops in the model used for the 80387. So just
3938;; emit moves.
6a4a5d95 3939
e075ae69 3940;; %%% Kill these when call knows how to work out a DFmode push earlier.
6343a50e 3941(define_insn "*dummy_extendsfdf2"
e075ae69 3942 [(set (match_operand:DF 0 "push_operand" "=<")
42a0aa6f 3943 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
e075ae69
RH
3944 "0"
3945 "#")
6a4a5d95
JW
3946
3947(define_split
e075ae69
RH
3948 [(set (match_operand:DF 0 "push_operand" "")
3949 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
1b0c37d7 3950 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
3951 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3952 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
0fcad513 3953
123bf9e3
JH
3954(define_split
3955 [(set (match_operand:DF 0 "push_operand" "")
3956 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
1b0c37d7 3957 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
123bf9e3
JH
3958 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3959 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3960
6343a50e 3961(define_insn "*dummy_extendsfxf2"
e075ae69
RH
3962 [(set (match_operand:XF 0 "push_operand" "=<")
3963 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3964 "0"
3965 "#")
e4ad1003
JW
3966
3967(define_split
e075ae69
RH
3968 [(set (match_operand:XF 0 "push_operand" "")
3969 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
1b0c37d7 3970 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
e075ae69 3971 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2b589241
JH
3972 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3973
3974(define_insn "*dummy_extendsftf2"
3975 [(set (match_operand:TF 0 "push_operand" "=<")
3976 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3977 "0"
3978 "#")
3979
3980(define_split
3981 [(set (match_operand:TF 0 "push_operand" "")
3982 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
1b0c37d7 3983 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
2b589241 3984 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
123bf9e3
JH
3985 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3986
3987(define_split
3988 [(set (match_operand:TF 0 "push_operand" "")
3989 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
1b0c37d7 3990 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
123bf9e3
JH
3991 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3992 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4fb21e90 3993
6343a50e 3994(define_insn "*dummy_extenddfxf2"
e075ae69
RH
3995 [(set (match_operand:XF 0 "push_operand" "=<")
3996 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3997 "0"
3998 "#")
e4ad1003
JW
3999
4000(define_split
e075ae69
RH
4001 [(set (match_operand:XF 0 "push_operand" "")
4002 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
1b0c37d7 4003 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
e075ae69 4004 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
123bf9e3 4005 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
2b589241
JH
4006
4007(define_insn "*dummy_extenddftf2"
4008 [(set (match_operand:TF 0 "push_operand" "=<")
4009 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4010 "0"
4011 "#")
4012
4013(define_split
4014 [(set (match_operand:TF 0 "push_operand" "")
4015 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
1b0c37d7 4016 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
2b589241
JH
4017 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4018 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4fb21e90 4019
123bf9e3
JH
4020(define_split
4021 [(set (match_operand:TF 0 "push_operand" "")
4022 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
1b0c37d7 4023 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
123bf9e3 4024 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
a2bafd20 4025 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
123bf9e3 4026
f97d9ec3
JH
4027(define_expand "extendsfdf2"
4028 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4029 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
42a0aa6f 4030 "TARGET_80387 || TARGET_SSE2"
f97d9ec3
JH
4031{
4032 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 4033 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 4034})
f97d9ec3
JH
4035
4036(define_insn "*extendsfdf2_1"
a811cc63
JH
4037 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4038 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
42a0aa6f 4039 "(TARGET_80387 || TARGET_SSE2)
f97d9ec3 4040 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4fb21e90 4041{
e075ae69 4042 switch (which_alternative)
4fb21e90 4043 {
e075ae69 4044 case 0:
0c174a68
AB
4045 if (REG_P (operands[1])
4046 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4047 return "fstp\t%y0";
e075ae69 4048 else if (STACK_TOP_P (operands[0]))
0f40f9f7 4049 return "fld%z1\t%y1";
e075ae69 4050 else
0f40f9f7 4051 return "fst\t%y0";
886c62d1 4052
e075ae69
RH
4053 case 1:
4054 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4055 return "fstp%z0\t%y0";
10195bd8 4056
e075ae69 4057 else
0f40f9f7 4058 return "fst%z0\t%y0";
42a0aa6f 4059 case 2:
0f40f9f7 4060 return "cvtss2sd\t{%1, %0|%0, %1}";
4fb21e90 4061
e075ae69
RH
4062 default:
4063 abort ();
4064 }
0f40f9f7 4065}
a811cc63
JH
4066 [(set_attr "type" "fmov,fmov,sse")
4067 (set_attr "mode" "SF,XF,DF")])
42a0aa6f
JH
4068
4069(define_insn "*extendsfdf2_1_sse_only"
4070 [(set (match_operand:DF 0 "register_operand" "=Y")
4071 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4072 "!TARGET_80387 && TARGET_SSE2
4073 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
0f40f9f7 4074 "cvtss2sd\t{%1, %0|%0, %1}"
42a0aa6f
JH
4075 [(set_attr "type" "sse")
4076 (set_attr "mode" "DF")])
e075ae69 4077
f97d9ec3
JH
4078(define_expand "extendsfxf2"
4079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4080 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
1b0c37d7 4081 "!TARGET_64BIT && TARGET_80387"
f97d9ec3
JH
4082{
4083 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 4084 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 4085})
f97d9ec3
JH
4086
4087(define_insn "*extendsfxf2_1"
e075ae69
RH
4088 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4089 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
1b0c37d7 4090 "!TARGET_64BIT && TARGET_80387
f97d9ec3 4091 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
10195bd8 4092{
e075ae69
RH
4093 switch (which_alternative)
4094 {
4095 case 0:
0c174a68
AB
4096 if (REG_P (operands[1])
4097 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4098 return "fstp\t%y0";
e075ae69 4099 else if (STACK_TOP_P (operands[0]))
0f40f9f7 4100 return "fld%z1\t%y1";
e075ae69 4101 else
0f40f9f7 4102 return "fst\t%y0";
886c62d1 4103
e075ae69
RH
4104 case 1:
4105 /* There is no non-popping store to memory for XFmode. So if
4106 we need one, follow the store with a load. */
4107 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4108 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
e075ae69 4109 else
0f40f9f7 4110 return "fstp%z0\t%y0";
886c62d1 4111
e075ae69
RH
4112 default:
4113 abort ();
4114 }
0f40f9f7 4115}
6ef67412
JH
4116 [(set_attr "type" "fmov")
4117 (set_attr "mode" "SF,XF")])
886c62d1 4118
2b589241
JH
4119(define_expand "extendsftf2"
4120 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4121 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4122 "TARGET_80387"
2b589241
JH
4123{
4124 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4125 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 4126})
2b589241
JH
4127
4128(define_insn "*extendsftf2_1"
4129 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4130 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4131 "TARGET_80387
4132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
4133{
4134 switch (which_alternative)
4135 {
4136 case 0:
4137 if (REG_P (operands[1])
4138 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4139 return "fstp\t%y0";
2b589241 4140 else if (STACK_TOP_P (operands[0]))
0f40f9f7 4141 return "fld%z1\t%y1";
2b589241 4142 else
0f40f9f7 4143 return "fst\t%y0";
2b589241
JH
4144
4145 case 1:
4146 /* There is no non-popping store to memory for XFmode. So if
4147 we need one, follow the store with a load. */
4148 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4149 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241 4150 else
0f40f9f7 4151 return "fstp%z0\t%y0";
2b589241
JH
4152
4153 default:
4154 abort ();
4155 }
0f40f9f7 4156}
2b589241
JH
4157 [(set_attr "type" "fmov")
4158 (set_attr "mode" "SF,XF")])
4159
f97d9ec3
JH
4160(define_expand "extenddfxf2"
4161 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4162 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
1b0c37d7 4163 "!TARGET_64BIT && TARGET_80387"
f97d9ec3
JH
4164{
4165 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 4166 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 4167})
f97d9ec3
JH
4168
4169(define_insn "*extenddfxf2_1"
e075ae69
RH
4170 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4171 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
1b0c37d7 4172 "!TARGET_64BIT && TARGET_80387
f97d9ec3 4173 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
e075ae69
RH
4174{
4175 switch (which_alternative)
4176 {
4177 case 0:
0c174a68
AB
4178 if (REG_P (operands[1])
4179 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4180 return "fstp\t%y0";
e075ae69 4181 else if (STACK_TOP_P (operands[0]))
0f40f9f7 4182 return "fld%z1\t%y1";
e075ae69 4183 else
0f40f9f7 4184 return "fst\t%y0";
bc725565 4185
e075ae69
RH
4186 case 1:
4187 /* There is no non-popping store to memory for XFmode. So if
4188 we need one, follow the store with a load. */
4189 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4190 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
e075ae69 4191 else
0f40f9f7 4192 return "fstp%z0\t%y0";
bc725565 4193
e075ae69
RH
4194 default:
4195 abort ();
4196 }
0f40f9f7 4197}
6ef67412
JH
4198 [(set_attr "type" "fmov")
4199 (set_attr "mode" "DF,XF")])
bc725565 4200
2b589241
JH
4201(define_expand "extenddftf2"
4202 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4203 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4204 "TARGET_80387"
2b589241
JH
4205{
4206 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4207 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 4208})
2b589241
JH
4209
4210(define_insn "*extenddftf2_1"
4211 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4212 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4213 "TARGET_80387
4214 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2b589241
JH
4215{
4216 switch (which_alternative)
4217 {
4218 case 0:
4219 if (REG_P (operands[1])
4220 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4221 return "fstp\t%y0";
2b589241 4222 else if (STACK_TOP_P (operands[0]))
0f40f9f7 4223 return "fld%z1\t%y1";
2b589241 4224 else
0f40f9f7 4225 return "fst\t%y0";
2b589241
JH
4226
4227 case 1:
4228 /* There is no non-popping store to memory for XFmode. So if
4229 we need one, follow the store with a load. */
4230 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4231 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
2b589241 4232 else
0f40f9f7 4233 return "fstp%z0\t%y0";
2b589241
JH
4234
4235 default:
4236 abort ();
4237 }
0f40f9f7 4238}
2b589241
JH
4239 [(set_attr "type" "fmov")
4240 (set_attr "mode" "DF,XF")])
4241
e075ae69
RH
4242;; %%% This seems bad bad news.
4243;; This cannot output into an f-reg because there is no way to be sure
4244;; of truncating in that case. Otherwise this is just like a simple move
4245;; insn. So we pretend we can output to a reg in order to get better
4246;; register preferencing, but we really use a stack slot.
886c62d1 4247
e075ae69
RH
4248(define_expand "truncdfsf2"
4249 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4250 (float_truncate:SF
4251 (match_operand:DF 1 "register_operand" "")))
4252 (clobber (match_dup 2))])]
42a0aa6f
JH
4253 "TARGET_80387 || TARGET_SSE2"
4254 "
4255 if (TARGET_80387)
4256 operands[2] = assign_386_stack_local (SFmode, 0);
4257 else
4258 {
4259 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4260 DONE;
4261 }
4262")
bc725565 4263
e075ae69 4264(define_insn "*truncdfsf2_1"
46ed7963 4265 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
e075ae69 4266 (float_truncate:SF
46ed7963
JH
4267 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4268 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
42a0aa6f 4269 "TARGET_80387 && !TARGET_SSE2"
e075ae69
RH
4270{
4271 switch (which_alternative)
4272 {
4273 case 0:
4274 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4275 return "fstp%z0\t%y0";
e075ae69 4276 else
0f40f9f7 4277 return "fst%z0\t%y0";
46ed7963
JH
4278 default:
4279 abort ();
e075ae69 4280 }
0f40f9f7 4281}
46ed7963
JH
4282 [(set_attr "type" "fmov,multi,multi,multi")
4283 (set_attr "mode" "SF,SF,SF,SF")])
42a0aa6f
JH
4284
4285(define_insn "*truncdfsf2_1_sse"
46ed7963 4286 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
42a0aa6f 4287 (float_truncate:SF
46ed7963
JH
4288 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4289 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
42a0aa6f 4290 "TARGET_80387 && TARGET_SSE2"
42a0aa6f
JH
4291{
4292 switch (which_alternative)
4293 {
4294 case 0:
4295 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4296 return "fstp%z0\t%y0";
42a0aa6f 4297 else
0f40f9f7 4298 return "fst%z0\t%y0";
46ed7963 4299 case 4:
0f40f9f7 4300 return "cvtsd2ss\t{%1, %0|%0, %1}";
46ed7963
JH
4301 default:
4302 abort ();
42a0aa6f 4303 }
0f40f9f7 4304}
46ed7963
JH
4305 [(set_attr "type" "fmov,multi,multi,multi,sse")
4306 (set_attr "mode" "SF,SF,SF,SF,DF")])
53b5ce19 4307
e075ae69 4308(define_insn "*truncdfsf2_2"
79005df5 4309 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
42a0aa6f 4310 (float_truncate:SF
79005df5
JH
4311 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4312 "TARGET_80387 && TARGET_SSE2
4313 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
42a0aa6f
JH
4314{
4315 switch (which_alternative)
4316 {
4317 case 0:
0f40f9f7 4318 return "cvtsd2ss\t{%1, %0|%0, %1}";
79005df5 4319 case 1:
42a0aa6f 4320 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4321 return "fstp%z0\t%y0";
42a0aa6f 4322 else
0f40f9f7
ZW
4323 return "fst%z0\t%y0";
4324 default:
4325 abort ();
42a0aa6f 4326 }
0f40f9f7 4327}
79005df5
JH
4328 [(set_attr "type" "sse,fmov")
4329 (set_attr "mode" "DF,SF")])
42a0aa6f
JH
4330
4331(define_insn "truncdfsf2_3"
cc2e591b 4332 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
4333 (float_truncate:SF
4334 (match_operand:DF 1 "register_operand" "f")))]
53b5ce19 4335 "TARGET_80387"
e075ae69
RH
4336{
4337 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4338 return "fstp%z0\t%y0";
e075ae69 4339 else
0f40f9f7
ZW
4340 return "fst%z0\t%y0";
4341}
6ef67412
JH
4342 [(set_attr "type" "fmov")
4343 (set_attr "mode" "SF")])
53b5ce19 4344
42a0aa6f
JH
4345(define_insn "truncdfsf2_sse_only"
4346 [(set (match_operand:SF 0 "register_operand" "=Y")
4347 (float_truncate:SF
4348 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4349 "!TARGET_80387 && TARGET_SSE2"
0f40f9f7 4350 "cvtsd2ss\t{%1, %0|%0, %1}"
42a0aa6f
JH
4351 [(set_attr "type" "sse")
4352 (set_attr "mode" "DF")])
4353
53b5ce19 4354(define_split
e075ae69
RH
4355 [(set (match_operand:SF 0 "memory_operand" "")
4356 (float_truncate:SF
4357 (match_operand:DF 1 "register_operand" "")))
4358 (clobber (match_operand:SF 2 "memory_operand" ""))]
4359 "TARGET_80387"
4360 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
53b5ce19
JW
4361 "")
4362
42a0aa6f
JH
4363(define_split
4364 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4365 (float_truncate:SF
4366 (match_operand:DF 1 "nonimmediate_operand" "")))
4367 (clobber (match_operand 2 "" ""))]
05b432db
JH
4368 "TARGET_80387 && reload_completed
4369 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
42a0aa6f
JH
4370 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4371 "")
4372
53b5ce19
JW
4373(define_split
4374 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
4375 (float_truncate:SF
4376 (match_operand:DF 1 "register_operand" "")))
4377 (clobber (match_operand:SF 2 "memory_operand" ""))]
42a0aa6f 4378 "TARGET_80387 && reload_completed
46ed7963 4379 && FP_REG_P (operands[1])"
e075ae69
RH
4380 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4381 (set (match_dup 0) (match_dup 2))]
53b5ce19
JW
4382 "")
4383
e075ae69
RH
4384(define_expand "truncxfsf2"
4385 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4386 (float_truncate:SF
4387 (match_operand:XF 1 "register_operand" "")))
4388 (clobber (match_dup 2))])]
1b0c37d7 4389 "!TARGET_64BIT && TARGET_80387"
e075ae69 4390 "operands[2] = assign_386_stack_local (SFmode, 0);")
53b5ce19 4391
e075ae69 4392(define_insn "*truncxfsf2_1"
46ed7963 4393 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
e075ae69 4394 (float_truncate:SF
46ed7963
JH
4395 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4396 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
1b0c37d7 4397 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
4398{
4399 switch (which_alternative)
4400 {
4401 case 0:
4402 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4403 return "fstp%z0\t%y0";
e075ae69 4404 else
0f40f9f7 4405 return "fst%z0\t%y0";
46ed7963
JH
4406 default:
4407 abort();
e075ae69 4408 }
0f40f9f7 4409}
46ed7963 4410 [(set_attr "type" "fmov,multi,multi,multi")
6ef67412 4411 (set_attr "mode" "SF")])
886c62d1 4412
e075ae69 4413(define_insn "*truncxfsf2_2"
dd80b906 4414 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
4415 (float_truncate:SF
4416 (match_operand:XF 1 "register_operand" "f")))]
1b0c37d7 4417 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
4418{
4419 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4420 return "fstp%z0\t%y0";
e075ae69 4421 else
0f40f9f7
ZW
4422 return "fst%z0\t%y0";
4423}
6ef67412
JH
4424 [(set_attr "type" "fmov")
4425 (set_attr "mode" "SF")])
bc725565
JW
4426
4427(define_split
e075ae69
RH
4428 [(set (match_operand:SF 0 "memory_operand" "")
4429 (float_truncate:SF
4430 (match_operand:XF 1 "register_operand" "")))
4431 (clobber (match_operand:SF 2 "memory_operand" ""))]
4432 "TARGET_80387"
4433 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
886c62d1
JVA
4434 "")
4435
bc725565 4436(define_split
6a4a5d95 4437 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
4438 (float_truncate:SF
4439 (match_operand:XF 1 "register_operand" "")))
4440 (clobber (match_operand:SF 2 "memory_operand" ""))]
bc725565 4441 "TARGET_80387 && reload_completed"
e075ae69
RH
4442 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4443 (set (match_dup 0) (match_dup 2))]
886c62d1
JVA
4444 "")
4445
2b589241
JH
4446(define_expand "trunctfsf2"
4447 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4448 (float_truncate:SF
4449 (match_operand:TF 1 "register_operand" "")))
4450 (clobber (match_dup 2))])]
4451 "TARGET_80387"
4452 "operands[2] = assign_386_stack_local (SFmode, 0);")
4453
4454(define_insn "*trunctfsf2_1"
46ed7963 4455 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
2b589241 4456 (float_truncate:SF
46ed7963
JH
4457 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4458 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
2b589241 4459 "TARGET_80387"
2b589241
JH
4460{
4461 switch (which_alternative)
4462 {
4463 case 0:
4464 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4465 return "fstp%z0\t%y0";
2b589241 4466 else
0f40f9f7 4467 return "fst%z0\t%y0";
46ed7963
JH
4468 default:
4469 abort();
2b589241 4470 }
0f40f9f7 4471}
46ed7963 4472 [(set_attr "type" "fmov,multi,multi,multi")
2b589241
JH
4473 (set_attr "mode" "SF")])
4474
1e07edd3 4475(define_insn "*trunctfsf2_2"
cc2e591b 4476 [(set (match_operand:SF 0 "memory_operand" "=m")
2b589241
JH
4477 (float_truncate:SF
4478 (match_operand:TF 1 "register_operand" "f")))]
4479 "TARGET_80387"
2b589241
JH
4480{
4481 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4482 return "fstp%z0\t%y0";
2b589241 4483 else
0f40f9f7
ZW
4484 return "fst%z0\t%y0";
4485}
2b589241
JH
4486 [(set_attr "type" "fmov")
4487 (set_attr "mode" "SF")])
4488
4489(define_split
4490 [(set (match_operand:SF 0 "memory_operand" "")
4491 (float_truncate:SF
4492 (match_operand:TF 1 "register_operand" "")))
4493 (clobber (match_operand:SF 2 "memory_operand" ""))]
4494 "TARGET_80387"
4495 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4496 "")
4497
4498(define_split
4499 [(set (match_operand:SF 0 "register_operand" "")
4500 (float_truncate:SF
4501 (match_operand:TF 1 "register_operand" "")))
4502 (clobber (match_operand:SF 2 "memory_operand" ""))]
4503 "TARGET_80387 && reload_completed"
4504 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4505 (set (match_dup 0) (match_dup 2))]
4506 "")
4507
4508
e075ae69
RH
4509(define_expand "truncxfdf2"
4510 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4511 (float_truncate:DF
4512 (match_operand:XF 1 "register_operand" "")))
4513 (clobber (match_dup 2))])]
1b0c37d7 4514 "!TARGET_64BIT && TARGET_80387"
e075ae69 4515 "operands[2] = assign_386_stack_local (DFmode, 0);")
bc725565 4516
e075ae69 4517(define_insn "*truncxfdf2_1"
46ed7963 4518 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
e075ae69 4519 (float_truncate:DF
46ed7963
JH
4520 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4521 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
1b0c37d7 4522 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
4523{
4524 switch (which_alternative)
4525 {
4526 case 0:
4527 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4528 return "fstp%z0\t%y0";
e075ae69 4529 else
0f40f9f7 4530 return "fst%z0\t%y0";
46ed7963
JH
4531 default:
4532 abort();
e075ae69
RH
4533 }
4534 abort ();
0f40f9f7 4535}
46ed7963 4536 [(set_attr "type" "fmov,multi,multi,multi")
6ef67412 4537 (set_attr "mode" "DF")])
bc725565 4538
e075ae69
RH
4539(define_insn "*truncxfdf2_2"
4540 [(set (match_operand:DF 0 "memory_operand" "=m")
4541 (float_truncate:DF
4542 (match_operand:XF 1 "register_operand" "f")))]
1b0c37d7 4543 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
4544{
4545 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4546 return "fstp%z0\t%y0";
e075ae69 4547 else
0f40f9f7
ZW
4548 return "fst%z0\t%y0";
4549}
6ef67412
JH
4550 [(set_attr "type" "fmov")
4551 (set_attr "mode" "DF")])
bc725565
JW
4552
4553(define_split
e075ae69
RH
4554 [(set (match_operand:DF 0 "memory_operand" "")
4555 (float_truncate:DF
4556 (match_operand:XF 1 "register_operand" "")))
4557 (clobber (match_operand:DF 2 "memory_operand" ""))]
ca285e07
JH
4558 "TARGET_80387"
4559 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4fb21e90
JVA
4560 "")
4561
bc725565 4562(define_split
6a4a5d95 4563 [(set (match_operand:DF 0 "register_operand" "")
e075ae69
RH
4564 (float_truncate:DF
4565 (match_operand:XF 1 "register_operand" "")))
4566 (clobber (match_operand:DF 2 "memory_operand" ""))]
bc725565 4567 "TARGET_80387 && reload_completed"
ca285e07 4568 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
e075ae69 4569 (set (match_dup 0) (match_dup 2))]
4fb21e90 4570 "")
ca285e07 4571
2b589241
JH
4572(define_expand "trunctfdf2"
4573 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4574 (float_truncate:DF
4575 (match_operand:TF 1 "register_operand" "")))
4576 (clobber (match_dup 2))])]
4577 "TARGET_80387"
4578 "operands[2] = assign_386_stack_local (DFmode, 0);")
4579
4580(define_insn "*trunctfdf2_1"
46ed7963 4581 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
2b589241 4582 (float_truncate:DF
46ed7963
JH
4583 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4584 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
2b589241 4585 "TARGET_80387"
2b589241
JH
4586{
4587 switch (which_alternative)
4588 {
4589 case 0:
4590 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4591 return "fstp%z0\t%y0";
2b589241 4592 else
0f40f9f7 4593 return "fst%z0\t%y0";
46ed7963
JH
4594 default:
4595 abort();
2b589241
JH
4596 }
4597 abort ();
0f40f9f7 4598}
46ed7963 4599 [(set_attr "type" "fmov,multi,multi,multi")
2b589241
JH
4600 (set_attr "mode" "DF")])
4601
46ed7963 4602 (define_insn "*trunctfdf2_2"
2b589241
JH
4603 [(set (match_operand:DF 0 "memory_operand" "=m")
4604 (float_truncate:DF
4605 (match_operand:TF 1 "register_operand" "f")))]
4606 "TARGET_80387"
2b589241
JH
4607{
4608 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
0f40f9f7 4609 return "fstp%z0\t%y0";
2b589241 4610 else
0f40f9f7
ZW
4611 return "fst%z0\t%y0";
4612}
2b589241
JH
4613 [(set_attr "type" "fmov")
4614 (set_attr "mode" "DF")])
4615
4616(define_split
4617 [(set (match_operand:DF 0 "memory_operand" "")
4618 (float_truncate:DF
4619 (match_operand:TF 1 "register_operand" "")))
4620 (clobber (match_operand:DF 2 "memory_operand" ""))]
4621 "TARGET_80387"
4622 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4623 "")
4624
4625(define_split
4626 [(set (match_operand:DF 0 "register_operand" "")
4627 (float_truncate:DF
4628 (match_operand:TF 1 "register_operand" "")))
4629 (clobber (match_operand:DF 2 "memory_operand" ""))]
4630 "TARGET_80387 && reload_completed"
4631 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4632 (set (match_dup 0) (match_dup 2))]
4633 "")
4634
e075ae69
RH
4635\f
4636;; %%% Break up all these bad boys.
4fb21e90 4637
e075ae69
RH
4638;; Signed conversion to DImode.
4639
2b589241 4640(define_expand "fix_truncxfdi2"
22fb740d
JH
4641 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4642 (fix:DI (match_operand:XF 1 "register_operand" "")))]
1b0c37d7 4643 "!TARGET_64BIT && TARGET_80387"
22fb740d 4644 "")
2b589241
JH
4645
4646(define_expand "fix_trunctfdi2"
22fb740d
JH
4647 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4648 (fix:DI (match_operand:TF 1 "register_operand" "")))]
bc725565 4649 "TARGET_80387"
22fb740d 4650 "")
bc725565 4651
e075ae69 4652(define_expand "fix_truncdfdi2"
22fb740d
JH
4653 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4654 (fix:DI (match_operand:DF 1 "register_operand" "")))]
46ed7963 4655 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
46ed7963 4656{
1b0c37d7 4657 if (TARGET_64BIT && TARGET_SSE2)
46ed7963
JH
4658 {
4659 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4660 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4661 if (out != operands[0])
4662 emit_move_insn (operands[0], out);
4663 DONE;
4664 }
0f40f9f7 4665})
53b5ce19 4666
e075ae69 4667(define_expand "fix_truncsfdi2"
22fb740d
JH
4668 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4669 (fix:DI (match_operand:SF 1 "register_operand" "")))]
46ed7963 4670 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
46ed7963 4671{
22fb740d 4672 if (TARGET_SSE && TARGET_64BIT)
46ed7963
JH
4673 {
4674 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4675 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4676 if (out != operands[0])
4677 emit_move_insn (operands[0], out);
4678 DONE;
4679 }
0f40f9f7 4680})
e075ae69 4681
22fb740d
JH
4682;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4683;; of the machinery.
4684(define_insn_and_split "*fix_truncdi_1"
4685 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4686 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4687 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4688 && !reload_completed && !reload_in_progress
4689 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4690 "#"
14f73b5a 4691 "&& 1"
22fb740d
JH
4692 [(const_int 0)]
4693{
4694 operands[2] = assign_386_stack_local (HImode, 1);
4695 operands[3] = assign_386_stack_local (HImode, 2);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4698 operands[2], operands[3]));
4699 else
4700 {
4701 operands[4] = assign_386_stack_local (DImode, 0);
4702 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4703 operands[2], operands[3],
4704 operands[4]));
4705 }
4706 DONE;
4707}
4708 [(set_attr "type" "fistp")])
4709
4710(define_insn "fix_truncdi_nomemory"
c76aab11 4711 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4712 (fix:DI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4713 (use (match_operand:HI 2 "memory_operand" "m,m"))
4714 (use (match_operand:HI 3 "memory_operand" "m,m"))
4715 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
22fb740d 4716 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
46ed7963 4717 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4718 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4719 "#"
4720 [(set_attr "type" "fistp")])
4721
4722(define_insn "fix_truncdi_memory"
4723 [(set (match_operand:DI 0 "memory_operand" "=m")
4724 (fix:DI (match_operand 1 "register_operand" "f")))
4725 (use (match_operand:HI 2 "memory_operand" "m"))
4726 (use (match_operand:HI 3 "memory_operand" "m"))
4727 (clobber (match_scratch:DF 4 "=&1f"))]
4728 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4729 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4730 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4731 [(set_attr "type" "fistp")])
53b5ce19 4732
e075ae69
RH
4733(define_split
4734 [(set (match_operand:DI 0 "register_operand" "")
4735 (fix:DI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4736 (use (match_operand:HI 2 "memory_operand" ""))
4737 (use (match_operand:HI 3 "memory_operand" ""))
4738 (clobber (match_operand:DI 4 "memory_operand" ""))
a05924f9 4739 (clobber (match_scratch 5 ""))]
7a2e09f4
JH
4740 "reload_completed"
4741 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4742 (use (match_dup 2))
4743 (use (match_dup 3))
e075ae69 4744 (clobber (match_dup 5))])
7a2e09f4 4745 (set (match_dup 0) (match_dup 4))]
53b5ce19
JW
4746 "")
4747
22fb740d
JH
4748(define_split
4749 [(set (match_operand:DI 0 "memory_operand" "")
4750 (fix:DI (match_operand 1 "register_operand" "")))
4751 (use (match_operand:HI 2 "memory_operand" ""))
4752 (use (match_operand:HI 3 "memory_operand" ""))
4753 (clobber (match_operand:DI 4 "memory_operand" ""))
4754 (clobber (match_scratch 5 ""))]
4755 "reload_completed"
4756 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4757 (use (match_dup 2))
4758 (use (match_dup 3))
4759 (clobber (match_dup 5))])]
4760 "")
4761
46ed7963
JH
4762;; When SSE available, it is always faster to use it!
4763(define_insn "fix_truncsfdi_sse"
4764 [(set (match_operand:DI 0 "register_operand" "=r")
4765 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1b0c37d7 4766 "TARGET_64BIT && TARGET_SSE"
0f40f9f7 4767 "cvttss2si{q}\t{%1, %0|%0, %1}"
46ed7963
JH
4768 [(set_attr "type" "sse")])
4769
4770(define_insn "fix_truncdfdi_sse"
4771 [(set (match_operand:DI 0 "register_operand" "=r")
4772 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1b0c37d7 4773 "TARGET_64BIT && TARGET_SSE2"
0f40f9f7 4774 "cvttsd2si{q}\t{%1, %0|%0, %1}"
46ed7963
JH
4775 [(set_attr "type" "sse")])
4776
e075ae69 4777;; Signed conversion to SImode.
53b5ce19 4778
e075ae69 4779(define_expand "fix_truncxfsi2"
22fb740d
JH
4780 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4781 (fix:SI (match_operand:XF 1 "register_operand" "")))]
1b0c37d7 4782 "!TARGET_64BIT && TARGET_80387"
22fb740d 4783 "")
53b5ce19 4784
2b589241 4785(define_expand "fix_trunctfsi2"
22fb740d
JH
4786 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4787 (fix:SI (match_operand:TF 1 "register_operand" "")))]
2b589241 4788 "TARGET_80387"
22fb740d 4789 "")
2b589241 4790
e075ae69 4791(define_expand "fix_truncdfsi2"
22fb740d
JH
4792 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4793 (fix:SI (match_operand:DF 1 "register_operand" "")))]
42a0aa6f 4794 "TARGET_80387 || TARGET_SSE2"
42a0aa6f
JH
4795{
4796 if (TARGET_SSE2)
4797 {
ca9a9b12 4798 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
b1675dbd
JH
4799 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4800 if (out != operands[0])
4801 emit_move_insn (operands[0], out);
42a0aa6f
JH
4802 DONE;
4803 }
0f40f9f7 4804})
886c62d1 4805
e075ae69 4806(define_expand "fix_truncsfsi2"
22fb740d
JH
4807 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4808 (fix:SI (match_operand:SF 1 "register_operand" "")))]
42a0aa6f 4809 "TARGET_80387 || TARGET_SSE"
42a0aa6f 4810{
22fb740d 4811 if (TARGET_SSE)
42a0aa6f 4812 {
ca9a9b12 4813 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
46ed7963 4814 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
b1675dbd
JH
4815 if (out != operands[0])
4816 emit_move_insn (operands[0], out);
42a0aa6f
JH
4817 DONE;
4818 }
0f40f9f7 4819})
e075ae69 4820
22fb740d
JH
4821;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4822;; of the machinery.
4823(define_insn_and_split "*fix_truncsi_1"
4824 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4825 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4826 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4827 && !reload_completed && !reload_in_progress
4828 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4829 "#"
ab75d1f1 4830 "&& 1"
22fb740d
JH
4831 [(const_int 0)]
4832{
4833 operands[2] = assign_386_stack_local (HImode, 1);
4834 operands[3] = assign_386_stack_local (HImode, 2);
4835 if (memory_operand (operands[0], VOIDmode))
4836 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4837 operands[2], operands[3]));
4838 else
4839 {
4840 operands[4] = assign_386_stack_local (SImode, 0);
4841 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4842 operands[2], operands[3],
4843 operands[4]));
4844 }
4845 DONE;
4846}
4847 [(set_attr "type" "fistp")])
4848
4849(define_insn "fix_truncsi_nomemory"
c76aab11 4850 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4851 (fix:SI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4852 (use (match_operand:HI 2 "memory_operand" "m,m"))
4853 (use (match_operand:HI 3 "memory_operand" "m,m"))
4854 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
42a0aa6f 4855 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4856 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4857 "#"
4858 [(set_attr "type" "fistp")])
4859
4860(define_insn "fix_truncsi_memory"
4861 [(set (match_operand:SI 0 "memory_operand" "=m")
4862 (fix:SI (match_operand 1 "register_operand" "f")))
4863 (use (match_operand:HI 2 "memory_operand" "m"))
4864 (use (match_operand:HI 3 "memory_operand" "m"))]
4865 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4866 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
e075ae69 4867 "* return output_fix_trunc (insn, operands);"
22fb740d 4868 [(set_attr "type" "fistp")])
bc725565 4869
42a0aa6f
JH
4870;; When SSE available, it is always faster to use it!
4871(define_insn "fix_truncsfsi_sse"
4872 [(set (match_operand:SI 0 "register_operand" "=r")
4873 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4874 "TARGET_SSE"
0f40f9f7 4875 "cvttss2si\t{%1, %0|%0, %1}"
42a0aa6f
JH
4876 [(set_attr "type" "sse")])
4877
4878(define_insn "fix_truncdfsi_sse"
4879 [(set (match_operand:SI 0 "register_operand" "=r")
4880 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4881 "TARGET_SSE2"
0f40f9f7 4882 "cvttsd2si\t{%1, %0|%0, %1}"
42a0aa6f
JH
4883 [(set_attr "type" "sse")])
4884
e075ae69
RH
4885(define_split
4886 [(set (match_operand:SI 0 "register_operand" "")
4887 (fix:SI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
4888 (use (match_operand:HI 2 "memory_operand" ""))
4889 (use (match_operand:HI 3 "memory_operand" ""))
4890 (clobber (match_operand:SI 4 "memory_operand" ""))]
e075ae69 4891 "reload_completed"
7a2e09f4
JH
4892 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4893 (use (match_dup 2))
22fb740d 4894 (use (match_dup 3))])
7a2e09f4 4895 (set (match_dup 0) (match_dup 4))]
bc725565 4896 "")
4fb21e90 4897
22fb740d
JH
4898(define_split
4899 [(set (match_operand:SI 0 "memory_operand" "")
4900 (fix:SI (match_operand 1 "register_operand" "")))
4901 (use (match_operand:HI 2 "memory_operand" ""))
4902 (use (match_operand:HI 3 "memory_operand" ""))
4903 (clobber (match_operand:SI 4 "memory_operand" ""))]
4904 "reload_completed"
4905 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4906 (use (match_dup 2))
4907 (use (match_dup 3))])]
4908 "")
4909
46d21d2c
JW
4910;; Signed conversion to HImode.
4911
4912(define_expand "fix_truncxfhi2"
22fb740d
JH
4913 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4914 (fix:HI (match_operand:XF 1 "register_operand" "")))]
1b0c37d7 4915 "!TARGET_64BIT && TARGET_80387"
22fb740d 4916 "")
46d21d2c 4917
2b589241 4918(define_expand "fix_trunctfhi2"
22fb740d
JH
4919 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4920 (fix:HI (match_operand:TF 1 "register_operand" "")))]
2b589241 4921 "TARGET_80387"
22fb740d 4922 "")
2b589241 4923
46d21d2c 4924(define_expand "fix_truncdfhi2"
22fb740d
JH
4925 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4926 (fix:HI (match_operand:DF 1 "register_operand" "")))]
42a0aa6f 4927 "TARGET_80387 && !TARGET_SSE2"
22fb740d 4928 "")
46d21d2c
JW
4929
4930(define_expand "fix_truncsfhi2"
22fb740d
JH
4931 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4932 (fix:HI (match_operand:SF 1 "register_operand" "")))]
42a0aa6f 4933 "TARGET_80387 && !TARGET_SSE"
22fb740d
JH
4934 "")
4935
4936;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4937;; of the machinery.
4938(define_insn_and_split "*fix_trunchi_1"
4939 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4940 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4941 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4942 && !reload_completed && !reload_in_progress
4943 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4944 "#"
4945 ""
4946 [(const_int 0)]
4947{
4948 operands[2] = assign_386_stack_local (HImode, 1);
4949 operands[3] = assign_386_stack_local (HImode, 2);
4950 if (memory_operand (operands[0], VOIDmode))
4951 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4952 operands[2], operands[3]));
4953 else
4954 {
4955 operands[4] = assign_386_stack_local (HImode, 0);
4956 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4957 operands[2], operands[3],
4958 operands[4]));
4959 }
4960 DONE;
4961}
4962 [(set_attr "type" "fistp")])
46d21d2c 4963
22fb740d 4964(define_insn "fix_trunchi_nomemory"
46d21d2c
JW
4965 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4966 (fix:HI (match_operand 1 "register_operand" "f,f")))
7a2e09f4
JH
4967 (use (match_operand:HI 2 "memory_operand" "m,m"))
4968 (use (match_operand:HI 3 "memory_operand" "m,m"))
4969 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
42a0aa6f 4970 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
22fb740d
JH
4971 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4972 "#"
4973 [(set_attr "type" "fistp")])
4974
4975(define_insn "fix_trunchi_memory"
4976 [(set (match_operand:HI 0 "memory_operand" "=m")
4977 (fix:HI (match_operand 1 "register_operand" "f")))
4978 (use (match_operand:HI 2 "memory_operand" "m"))
4979 (use (match_operand:HI 3 "memory_operand" "m"))]
4980 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4981 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
46d21d2c 4982 "* return output_fix_trunc (insn, operands);"
22fb740d
JH
4983 [(set_attr "type" "fistp")])
4984
4985(define_split
4986 [(set (match_operand:HI 0 "memory_operand" "")
4987 (fix:HI (match_operand 1 "register_operand" "")))
4988 (use (match_operand:HI 2 "memory_operand" ""))
4989 (use (match_operand:HI 3 "memory_operand" ""))
4990 (clobber (match_operand:HI 4 "memory_operand" ""))]
4991 "reload_completed"
4992 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4993 (use (match_dup 2))
4994 (use (match_dup 3))])]
4995 "")
46d21d2c
JW
4996
4997(define_split
4998 [(set (match_operand:HI 0 "register_operand" "")
4999 (fix:HI (match_operand 1 "register_operand" "")))
7a2e09f4
JH
5000 (use (match_operand:HI 2 "memory_operand" ""))
5001 (use (match_operand:HI 3 "memory_operand" ""))
5002 (clobber (match_operand:HI 4 "memory_operand" ""))]
46d21d2c 5003 "reload_completed"
7a2e09f4
JH
5004 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5005 (use (match_dup 2))
5006 (use (match_dup 3))
46d21d2c 5007 (clobber (match_dup 4))])
7a2e09f4 5008 (set (match_dup 0) (match_dup 4))]
46d21d2c
JW
5009 "")
5010
e075ae69
RH
5011;; %% Not used yet.
5012(define_insn "x86_fnstcw_1"
c76aab11
RH
5013 [(set (match_operand:HI 0 "memory_operand" "=m")
5014 (unspec:HI [(reg:HI 18)] 11))]
e1f998ad 5015 "TARGET_80387"
0f40f9f7 5016 "fnstcw\t%0"
6ef67412
JH
5017 [(set_attr "length" "2")
5018 (set_attr "mode" "HI")
5019 (set_attr "i387" "1")
e075ae69 5020 (set_attr "ppro_uops" "few")])
bc725565 5021
e075ae69
RH
5022(define_insn "x86_fldcw_1"
5023 [(set (reg:HI 18)
c76aab11 5024 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
bc725565 5025 "TARGET_80387"
0f40f9f7 5026 "fldcw\t%0"
6ef67412
JH
5027 [(set_attr "length" "2")
5028 (set_attr "mode" "HI")
5029 (set_attr "i387" "1")
0b5107cf 5030 (set_attr "athlon_decode" "vector")
e075ae69
RH
5031 (set_attr "ppro_uops" "few")])
5032\f
5033;; Conversion between fixed point and floating point.
886c62d1 5034
e075ae69
RH
5035;; Even though we only accept memory inputs, the backend _really_
5036;; wants to be able to do this between registers.
5037
155d8a47
JW
5038(define_insn "floathisf2"
5039 [(set (match_operand:SF 0 "register_operand" "=f,f")
5040 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
42a0aa6f 5041 "TARGET_80387 && !TARGET_SSE"
155d8a47 5042 "@
0f40f9f7 5043 fild%z1\t%1
155d8a47
JW
5044 #"
5045 [(set_attr "type" "fmov,multi")
6ef67412 5046 (set_attr "mode" "SF")
155d8a47
JW
5047 (set_attr "fp_int_src" "true")])
5048
42a0aa6f
JH
5049(define_expand "floatsisf2"
5050 [(set (match_operand:SF 0 "register_operand" "")
5051 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5052 "TARGET_SSE || TARGET_80387"
5053 "")
5054
5055(define_insn "*floatsisf2_i387"
5056 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5057 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5058 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
e075ae69 5059 "@
0f40f9f7 5060 fild%z1\t%1
42a0aa6f 5061 #
0f40f9f7 5062 cvtsi2ss\t{%1, %0|%0, %1}"
42a0aa6f
JH
5063 [(set_attr "type" "fmov,multi,sse")
5064 (set_attr "mode" "SF")
5065 (set_attr "fp_int_src" "true")])
5066
5067(define_insn "*floatsisf2_sse"
5068 [(set (match_operand:SF 0 "register_operand" "=x")
5069 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
46ed7963 5070 "TARGET_SSE"
0f40f9f7 5071 "cvtsi2ss\t{%1, %0|%0, %1}"
42a0aa6f 5072 [(set_attr "type" "sse")
6ef67412 5073 (set_attr "mode" "SF")
e075ae69 5074 (set_attr "fp_int_src" "true")])
bc725565 5075
46ed7963
JH
5076(define_expand "floatdisf2"
5077 [(set (match_operand:SF 0 "register_operand" "")
5078 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
1b0c37d7 5079 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
46ed7963
JH
5080 "")
5081
ef6257cd
JH
5082(define_insn "*floatdisf2_i387_only"
5083 [(set (match_operand:SF 0 "register_operand" "=f,?f")
5084 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5085 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5086 "@
0f40f9f7 5087 fild%z1\t%1
ef6257cd
JH
5088 #"
5089 [(set_attr "type" "fmov,multi")
5090 (set_attr "mode" "SF")
5091 (set_attr "fp_int_src" "true")])
5092
46ed7963
JH
5093(define_insn "*floatdisf2_i387"
5094 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5095 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
1b0c37d7 5096 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
e075ae69 5097 "@
0f40f9f7 5098 fild%z1\t%1
46ed7963 5099 #
0f40f9f7 5100 cvtsi2ss{q}\t{%1, %0|%0, %1}"
46ed7963
JH
5101 [(set_attr "type" "fmov,multi,sse")
5102 (set_attr "mode" "SF")
5103 (set_attr "fp_int_src" "true")])
5104
5105(define_insn "*floatdisf2_sse"
5106 [(set (match_operand:SF 0 "register_operand" "=x")
5107 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
1b0c37d7 5108 "TARGET_64BIT && TARGET_SSE"
0f40f9f7 5109 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
46ed7963 5110 [(set_attr "type" "sse")
6ef67412 5111 (set_attr "mode" "SF")
e075ae69 5112 (set_attr "fp_int_src" "true")])
bc725565 5113
155d8a47
JW
5114(define_insn "floathidf2"
5115 [(set (match_operand:DF 0 "register_operand" "=f,f")
5116 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
42a0aa6f 5117 "TARGET_80387 && !TARGET_SSE2"
155d8a47 5118 "@
0f40f9f7 5119 fild%z1\t%1
155d8a47
JW
5120 #"
5121 [(set_attr "type" "fmov,multi")
6ef67412 5122 (set_attr "mode" "DF")
155d8a47
JW
5123 (set_attr "fp_int_src" "true")])
5124
42a0aa6f
JH
5125(define_expand "floatsidf2"
5126 [(set (match_operand:DF 0 "register_operand" "")
5127 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5128 ""
5129 "")
5130
5131(define_insn "*floatsidf2_i387"
5132 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5133 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5134 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
e075ae69 5135 "@
0f40f9f7 5136 fild%z1\t%1
42a0aa6f 5137 #
0f40f9f7 5138 cvtsi2sd\t{%1, %0|%0, %1}"
42a0aa6f
JH
5139 [(set_attr "type" "fmov,multi,sse")
5140 (set_attr "mode" "DF")
5141 (set_attr "fp_int_src" "true")])
5142
5143(define_insn "*floatsidf2_sse"
5144 [(set (match_operand:DF 0 "register_operand" "=Y")
5145 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5146 "TARGET_SSE2"
0f40f9f7 5147 "cvtsi2sd\t{%1, %0|%0, %1}"
42a0aa6f 5148 [(set_attr "type" "sse")
6ef67412 5149 (set_attr "mode" "DF")
e075ae69 5150 (set_attr "fp_int_src" "true")])
e1f998ad 5151
46ed7963
JH
5152(define_expand "floatdidf2"
5153 [(set (match_operand:DF 0 "register_operand" "")
5154 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
1b0c37d7 5155 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
46ed7963
JH
5156 "")
5157
ef6257cd
JH
5158(define_insn "*floatdidf2_i387_only"
5159 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5160 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5161 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5162 "@
0f40f9f7 5163 fild%z1\t%1
ef6257cd
JH
5164 #"
5165 [(set_attr "type" "fmov,multi")
5166 (set_attr "mode" "DF")
5167 (set_attr "fp_int_src" "true")])
5168
46ed7963
JH
5169(define_insn "*floatdidf2_i387"
5170 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5171 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
1b0c37d7 5172 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
e075ae69 5173 "@
0f40f9f7 5174 fild%z1\t%1
46ed7963 5175 #
0f40f9f7 5176 cvtsi2sd{q}\t{%1, %0|%0, %1}"
46ed7963
JH
5177 [(set_attr "type" "fmov,multi,sse")
5178 (set_attr "mode" "DF")
5179 (set_attr "fp_int_src" "true")])
5180
5181(define_insn "*floatdidf2_sse"
5182 [(set (match_operand:DF 0 "register_operand" "=Y")
5183 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5184 "TARGET_SSE2"
0f40f9f7 5185 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
46ed7963 5186 [(set_attr "type" "sse")
6ef67412 5187 (set_attr "mode" "DF")
e075ae69 5188 (set_attr "fp_int_src" "true")])
bc725565 5189
155d8a47
JW
5190(define_insn "floathixf2"
5191 [(set (match_operand:XF 0 "register_operand" "=f,f")
5192 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
1b0c37d7 5193 "!TARGET_64BIT && TARGET_80387"
155d8a47 5194 "@
0f40f9f7 5195 fild%z1\t%1
155d8a47
JW
5196 #"
5197 [(set_attr "type" "fmov,multi")
6ef67412 5198 (set_attr "mode" "XF")
155d8a47
JW
5199 (set_attr "fp_int_src" "true")])
5200
2b589241
JH
5201(define_insn "floathitf2"
5202 [(set (match_operand:TF 0 "register_operand" "=f,f")
5203 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5204 "TARGET_80387"
5205 "@
0f40f9f7 5206 fild%z1\t%1
2b589241
JH
5207 #"
5208 [(set_attr "type" "fmov,multi")
5209 (set_attr "mode" "XF")
5210 (set_attr "fp_int_src" "true")])
5211
e075ae69
RH
5212(define_insn "floatsixf2"
5213 [(set (match_operand:XF 0 "register_operand" "=f,f")
5214 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
1b0c37d7 5215 "!TARGET_64BIT && TARGET_80387"
e075ae69 5216 "@
0f40f9f7 5217 fild%z1\t%1
e075ae69
RH
5218 #"
5219 [(set_attr "type" "fmov,multi")
6ef67412 5220 (set_attr "mode" "XF")
e075ae69 5221 (set_attr "fp_int_src" "true")])
53b5ce19 5222
2b589241
JH
5223(define_insn "floatsitf2"
5224 [(set (match_operand:TF 0 "register_operand" "=f,f")
5225 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5226 "TARGET_80387"
5227 "@
0f40f9f7 5228 fild%z1\t%1
2b589241
JH
5229 #"
5230 [(set_attr "type" "fmov,multi")
5231 (set_attr "mode" "XF")
5232 (set_attr "fp_int_src" "true")])
5233
e075ae69 5234(define_insn "floatdixf2"
53b5ce19 5235 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69 5236 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
1b0c37d7 5237 "!TARGET_64BIT && TARGET_80387"
e075ae69 5238 "@
0f40f9f7 5239 fild%z1\t%1
e075ae69
RH
5240 #"
5241 [(set_attr "type" "fmov,multi")
6ef67412 5242 (set_attr "mode" "XF")
e075ae69 5243 (set_attr "fp_int_src" "true")])
53b5ce19 5244
2b589241
JH
5245(define_insn "floatditf2"
5246 [(set (match_operand:TF 0 "register_operand" "=f,f")
5247 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5248 "TARGET_80387"
5249 "@
0f40f9f7 5250 fild%z1\t%1
2b589241
JH
5251 #"
5252 [(set_attr "type" "fmov,multi")
5253 (set_attr "mode" "XF")
5254 (set_attr "fp_int_src" "true")])
5255
e075ae69 5256;; %%% Kill these when reload knows how to do it.
155d8a47
JW
5257(define_split
5258 [(set (match_operand 0 "register_operand" "")
4211a8fb 5259 (float (match_operand 1 "register_operand" "")))]
bf71a4f8
JH
5260 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5261 && FP_REG_P (operands[0])"
4211a8fb 5262 [(const_int 0)]
4211a8fb
JH
5263{
5264 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5265 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5267 ix86_free_from_memory (GET_MODE (operands[1]));
5268 DONE;
0f40f9f7 5269})
e075ae69
RH
5270\f
5271;; Add instructions
53b5ce19 5272
e075ae69
RH
5273;; %%% splits for addsidi3
5274; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5275; (plus:DI (match_operand:DI 1 "general_operand" "")
5276; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
e1f998ad 5277
9b70259d
JH
5278(define_expand "adddi3"
5279 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5280 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5281 (match_operand:DI 2 "x86_64_general_operand" "")))
5282 (clobber (reg:CC 17))]
5283 ""
5284 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5285
5286(define_insn "*adddi3_1"
e075ae69
RH
5287 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5288 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5289 (match_operand:DI 2 "general_operand" "roiF,riF")))
5290 (clobber (reg:CC 17))]
9b70259d 5291 "!TARGET_64BIT"
bc725565
JW
5292 "#")
5293
5294(define_split
e075ae69 5295 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 5296 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69
RH
5297 (match_operand:DI 2 "general_operand" "")))
5298 (clobber (reg:CC 17))]
1b0c37d7 5299 "!TARGET_64BIT && reload_completed"
7e08e190 5300 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
e075ae69
RH
5301 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5302 (parallel [(set (match_dup 3)
7e08e190 5303 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9dcbdc7e
JH
5304 (match_dup 4))
5305 (match_dup 5)))
e075ae69
RH
5306 (clobber (reg:CC 17))])]
5307 "split_di (operands+0, 1, operands+0, operands+3);
5308 split_di (operands+1, 1, operands+1, operands+4);
5309 split_di (operands+2, 1, operands+2, operands+5);")
5310
9b70259d
JH
5311(define_insn "*adddi3_carry_rex64"
5312 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5313 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5314 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5315 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5316 (clobber (reg:CC 17))]
1b0c37d7 5317 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 5318 "adc{q}\t{%2, %0|%0, %2}"
9b70259d
JH
5319 [(set_attr "type" "alu")
5320 (set_attr "pent_pair" "pu")
5321 (set_attr "mode" "DI")
5322 (set_attr "ppro_uops" "few")])
5323
5324(define_insn "*adddi3_cc_rex64"
5325 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5326 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5327 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5328 (plus:DI (match_dup 1) (match_dup 2)))]
5329 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
0f40f9f7 5330 "add{q}\t{%2, %0|%0, %2}"
9b70259d
JH
5331 [(set_attr "type" "alu")
5332 (set_attr "mode" "DI")])
5333
7abd4e00 5334(define_insn "*addsi3_carry"
e075ae69 5335 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9dcbdc7e
JH
5336 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5337 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5338 (match_operand:SI 2 "general_operand" "ri,rm")))
e075ae69 5339 (clobber (reg:CC 17))]
d525dfdf 5340 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5341 "adc{l}\t{%2, %0|%0, %2}"
e075ae69
RH
5342 [(set_attr "type" "alu")
5343 (set_attr "pent_pair" "pu")
6ef67412 5344 (set_attr "mode" "SI")
e075ae69 5345 (set_attr "ppro_uops" "few")])
4fb21e90 5346
9b70259d
JH
5347(define_insn "*addsi3_carry_zext"
5348 [(set (match_operand:DI 0 "register_operand" "=r")
5349 (zero_extend:DI
5350 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5351 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5352 (match_operand:SI 2 "general_operand" "rim"))))
5353 (clobber (reg:CC 17))]
5354 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5355 "adc{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
5356 [(set_attr "type" "alu")
5357 (set_attr "pent_pair" "pu")
5358 (set_attr "mode" "SI")
5359 (set_attr "ppro_uops" "few")])
5360
7e08e190
JH
5361(define_insn "*addsi3_cc"
5362 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5363 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5364 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5365 (plus:SI (match_dup 1) (match_dup 2)))]
265dab10 5366 "ix86_binary_operator_ok (PLUS, SImode, operands)"
0f40f9f7 5367 "add{l}\t{%2, %0|%0, %2}"
265dab10 5368 [(set_attr "type" "alu")
7e08e190
JH
5369 (set_attr "mode" "SI")])
5370
5371(define_insn "addqi3_cc"
5372 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5373 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5374 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5375 (plus:QI (match_dup 1) (match_dup 2)))]
5376 "ix86_binary_operator_ok (PLUS, QImode, operands)"
0f40f9f7 5377 "add{b}\t{%2, %0|%0, %2}"
7e08e190
JH
5378 [(set_attr "type" "alu")
5379 (set_attr "mode" "QI")])
265dab10 5380
e075ae69
RH
5381(define_expand "addsi3"
5382 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5383 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5384 (match_operand:SI 2 "general_operand" "")))
5385 (clobber (reg:CC 17))])]
5386 ""
5387 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
886c62d1 5388
ac62a60e 5389(define_insn "*lea_1"
e075ae69 5390 [(set (match_operand:SI 0 "register_operand" "=r")
ad678cb0 5391 (match_operand:SI 1 "address_operand" "p"))]
ac62a60e 5392 "!TARGET_64BIT"
0f40f9f7 5393 "lea{l}\t{%a1, %0|%0, %a1}"
6ef67412
JH
5394 [(set_attr "type" "lea")
5395 (set_attr "mode" "SI")])
2ae0f82c 5396
ac62a60e
JH
5397(define_insn "*lea_1_rex64"
5398 [(set (match_operand:SI 0 "register_operand" "=r")
5399 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5400 "TARGET_64BIT"
0f40f9f7 5401 "lea{l}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5402 [(set_attr "type" "lea")
5403 (set_attr "mode" "SI")])
5404
5405(define_insn "*lea_1_zext"
5406 [(set (match_operand:DI 0 "register_operand" "=r")
5407 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
d4f33f6c 5408 "TARGET_64BIT"
0f40f9f7 5409 "lea{l}\t{%a1, %k0|%k0, %a1}"
ac62a60e
JH
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "SI")])
5412
5413(define_insn "*lea_2_rex64"
5414 [(set (match_operand:DI 0 "register_operand" "=r")
5415 (match_operand:DI 1 "address_operand" "p"))]
5416 "TARGET_64BIT"
0f40f9f7 5417 "lea{q}\t{%a1, %0|%0, %a1}"
ac62a60e
JH
5418 [(set_attr "type" "lea")
5419 (set_attr "mode" "DI")])
5420
58787064
JH
5421;; The lea patterns for non-Pmodes needs to be matched by several
5422;; insns converted to real lea by splitters.
5423
5424(define_insn_and_split "*lea_general_1"
5425 [(set (match_operand 0 "register_operand" "=r")
5426 (plus (plus (match_operand 1 "register_operand" "r")
5427 (match_operand 2 "register_operand" "r"))
5428 (match_operand 3 "immediate_operand" "i")))]
ac62a60e
JH
5429 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5430 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5431 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5432 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5433 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5434 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5435 || GET_MODE (operands[3]) == VOIDmode)"
5436 "#"
cb694d2c 5437 "&& reload_completed"
58787064 5438 [(const_int 0)]
58787064
JH
5439{
5440 rtx pat;
5441 operands[0] = gen_lowpart (SImode, operands[0]);
5442 operands[1] = gen_lowpart (Pmode, operands[1]);
5443 operands[2] = gen_lowpart (Pmode, operands[2]);
5444 operands[3] = gen_lowpart (Pmode, operands[3]);
5445 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5446 operands[3]);
5447 if (Pmode != SImode)
5448 pat = gen_rtx_SUBREG (SImode, pat, 0);
5449 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5450 DONE;
0f40f9f7 5451}
58787064
JH
5452 [(set_attr "type" "lea")
5453 (set_attr "mode" "SI")])
5454
ac62a60e
JH
5455(define_insn_and_split "*lea_general_1_zext"
5456 [(set (match_operand:DI 0 "register_operand" "=r")
5457 (zero_extend:DI
5458 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5459 (match_operand:SI 2 "register_operand" "r"))
5460 (match_operand:SI 3 "immediate_operand" "i"))))]
5461 "TARGET_64BIT"
5462 "#"
5463 "&& reload_completed"
5464 [(set (match_dup 0)
5465 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5466 (match_dup 2))
5467 (match_dup 3)) 0)))]
ac62a60e
JH
5468{
5469 operands[1] = gen_lowpart (Pmode, operands[1]);
5470 operands[2] = gen_lowpart (Pmode, operands[2]);
5471 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5472}
ac62a60e
JH
5473 [(set_attr "type" "lea")
5474 (set_attr "mode" "SI")])
5475
58787064
JH
5476(define_insn_and_split "*lea_general_2"
5477 [(set (match_operand 0 "register_operand" "=r")
5478 (plus (mult (match_operand 1 "register_operand" "r")
5479 (match_operand 2 "const248_operand" "i"))
5480 (match_operand 3 "nonmemory_operand" "ri")))]
ac62a60e
JH
5481 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5482 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5483 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5484 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5485 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5486 || GET_MODE (operands[3]) == VOIDmode)"
5487 "#"
cb694d2c 5488 "&& reload_completed"
58787064 5489 [(const_int 0)]
58787064
JH
5490{
5491 rtx pat;
5492 operands[0] = gen_lowpart (SImode, operands[0]);
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[3] = gen_lowpart (Pmode, operands[3]);
5495 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5496 operands[3]);
5497 if (Pmode != SImode)
5498 pat = gen_rtx_SUBREG (SImode, pat, 0);
5499 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5500 DONE;
0f40f9f7 5501}
58787064
JH
5502 [(set_attr "type" "lea")
5503 (set_attr "mode" "SI")])
5504
ac62a60e
JH
5505(define_insn_and_split "*lea_general_2_zext"
5506 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (zero_extend:DI
5508 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5509 (match_operand:SI 2 "const248_operand" "n"))
5510 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5511 "TARGET_64BIT"
5512 "#"
5513 "&& reload_completed"
5514 [(set (match_dup 0)
5515 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5516 (match_dup 2))
5517 (match_dup 3)) 0)))]
ac62a60e
JH
5518{
5519 operands[1] = gen_lowpart (Pmode, operands[1]);
5520 operands[3] = gen_lowpart (Pmode, operands[3]);
0f40f9f7 5521}
ac62a60e
JH
5522 [(set_attr "type" "lea")
5523 (set_attr "mode" "SI")])
5524
58787064
JH
5525(define_insn_and_split "*lea_general_3"
5526 [(set (match_operand 0 "register_operand" "=r")
5527 (plus (plus (mult (match_operand 1 "register_operand" "r")
5528 (match_operand 2 "const248_operand" "i"))
5529 (match_operand 3 "register_operand" "r"))
5530 (match_operand 4 "immediate_operand" "i")))]
ac62a60e
JH
5531 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5532 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
58787064
JH
5533 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5534 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5535 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5536 "#"
cb694d2c 5537 "&& reload_completed"
58787064 5538 [(const_int 0)]
58787064
JH
5539{
5540 rtx pat;
5541 operands[0] = gen_lowpart (SImode, operands[0]);
5542 operands[1] = gen_lowpart (Pmode, operands[1]);
5543 operands[3] = gen_lowpart (Pmode, operands[3]);
5544 operands[4] = gen_lowpart (Pmode, operands[4]);
5545 pat = gen_rtx_PLUS (Pmode,
5546 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5547 operands[2]),
5548 operands[3]),
5549 operands[4]);
5550 if (Pmode != SImode)
5551 pat = gen_rtx_SUBREG (SImode, pat, 0);
5552 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5553 DONE;
0f40f9f7 5554}
58787064
JH
5555 [(set_attr "type" "lea")
5556 (set_attr "mode" "SI")])
5557
ac62a60e
JH
5558(define_insn_and_split "*lea_general_3_zext"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5560 (zero_extend:DI
5561 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5562 (match_operand:SI 2 "const248_operand" "n"))
5563 (match_operand:SI 3 "register_operand" "r"))
5564 (match_operand:SI 4 "immediate_operand" "i"))))]
5565 "TARGET_64BIT"
5566 "#"
5567 "&& reload_completed"
5568 [(set (match_dup 0)
5569 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5570 (match_dup 2))
5571 (match_dup 3))
5572 (match_dup 4)) 0)))]
ac62a60e
JH
5573{
5574 operands[1] = gen_lowpart (Pmode, operands[1]);
5575 operands[3] = gen_lowpart (Pmode, operands[3]);
5576 operands[4] = gen_lowpart (Pmode, operands[4]);
0f40f9f7 5577}
ac62a60e
JH
5578 [(set_attr "type" "lea")
5579 (set_attr "mode" "SI")])
5580
9b70259d
JH
5581(define_insn "*adddi_1_rex64"
5582 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5583 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5584 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
e075ae69 5585 (clobber (reg:CC 17))]
9b70259d 5586 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
2ae0f82c 5587{
e075ae69 5588 switch (get_attr_type (insn))
2ae0f82c 5589 {
e075ae69
RH
5590 case TYPE_LEA:
5591 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5592 return "lea{q}\t{%a2, %0|%0, %a2}";
2ae0f82c 5593
e075ae69
RH
5594 case TYPE_INCDEC:
5595 if (! rtx_equal_p (operands[0], operands[1]))
5596 abort ();
5597 if (operands[2] == const1_rtx)
0f40f9f7 5598 return "inc{q}\t%0";
e075ae69 5599 else if (operands[2] == constm1_rtx)
0f40f9f7 5600 return "dec{q}\t%0";
2ae0f82c 5601 else
9b70259d 5602 abort ();
2ae0f82c 5603
e075ae69
RH
5604 default:
5605 if (! rtx_equal_p (operands[0], operands[1]))
5606 abort ();
2ae0f82c 5607
e075ae69
RH
5608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5610 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5611 /* Avoid overflows. */
0f40f9f7 5612 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5616 {
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5618 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5619 }
0f40f9f7 5620 return "add{q}\t{%2, %0|%0, %2}";
e075ae69 5621 }
0f40f9f7 5622}
e075ae69
RH
5623 [(set (attr "type")
5624 (cond [(eq_attr "alternative" "2")
5625 (const_string "lea")
5626 ; Current assemblers are broken and do not allow @GOTOFF in
5627 ; ought but a memory context.
9b70259d 5628 (match_operand:DI 2 "pic_symbolic_operand" "")
e075ae69 5629 (const_string "lea")
9b70259d 5630 (match_operand:DI 2 "incdec_operand" "")
e075ae69
RH
5631 (const_string "incdec")
5632 ]
6ef67412 5633 (const_string "alu")))
9b70259d 5634 (set_attr "mode" "DI")])
e075ae69 5635
1c27d4b2
JH
5636;; Convert lea to the lea pattern to avoid flags dependency.
5637(define_split
9b70259d
JH
5638 [(set (match_operand:DI 0 "register_operand" "")
5639 (plus:DI (match_operand:DI 1 "register_operand" "")
5640 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
1c27d4b2 5641 (clobber (reg:CC 17))]
1b0c37d7 5642 "TARGET_64BIT && reload_completed
abe24fb3 5643 && true_regnum (operands[0]) != true_regnum (operands[1])"
9b70259d
JH
5644 [(set (match_dup 0)
5645 (plus:DI (match_dup 1)
5646 (match_dup 2)))]
5647 "")
1c27d4b2 5648
9b70259d 5649(define_insn "*adddi_2_rex64"
16189740
RH
5650 [(set (reg 17)
5651 (compare
9b70259d
JH
5652 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5653 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
e075ae69 5654 (const_int 0)))
9b70259d
JH
5655 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5656 (plus:DI (match_dup 1) (match_dup 2)))]
5657 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5658 && ix86_binary_operator_ok (PLUS, DImode, operands)
e075ae69
RH
5659 /* Current assemblers are broken and do not allow @GOTOFF in
5660 ought but a memory context. */
5661 && ! pic_symbolic_operand (operands[2], VOIDmode)"
886c62d1 5662{
e075ae69 5663 switch (get_attr_type (insn))
96f218bb 5664 {
e075ae69
RH
5665 case TYPE_INCDEC:
5666 if (! rtx_equal_p (operands[0], operands[1]))
5667 abort ();
5668 if (operands[2] == const1_rtx)
0f40f9f7 5669 return "inc{q}\t%0";
e075ae69 5670 else if (operands[2] == constm1_rtx)
0f40f9f7 5671 return "dec{q}\t%0";
96f218bb 5672 else
9b70259d 5673 abort ();
96f218bb 5674
e075ae69
RH
5675 default:
5676 if (! rtx_equal_p (operands[0], operands[1]))
5677 abort ();
9b70259d
JH
5678 /* ???? We ought to handle there the 32bit case too
5679 - do we need new constrant? */
e075ae69
RH
5680 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5681 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5682 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5683 /* Avoid overflows. */
0f40f9f7 5684 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
e075ae69
RH
5685 && (INTVAL (operands[2]) == 128
5686 || (INTVAL (operands[2]) < 0
5687 && INTVAL (operands[2]) != -128)))
5688 {
5689 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5690 return "sub{q}\t{%2, %0|%0, %2}";
e075ae69 5691 }
0f40f9f7 5692 return "add{q}\t{%2, %0|%0, %2}";
9c530261 5693 }
0f40f9f7 5694}
e075ae69 5695 [(set (attr "type")
9b70259d 5696 (if_then_else (match_operand:DI 2 "incdec_operand" "")
e075ae69 5697 (const_string "incdec")
6ef67412 5698 (const_string "alu")))
9b70259d 5699 (set_attr "mode" "DI")])
e075ae69 5700
e74061a9 5701(define_insn "*adddi_3_rex64"
d90ffc8d 5702 [(set (reg 17)
9b70259d
JH
5703 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5704 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5705 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5706 "TARGET_64BIT
5707 && ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
5708 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5709 /* Current assemblers are broken and do not allow @GOTOFF in
5710 ought but a memory context. */
5711 && ! pic_symbolic_operand (operands[2], VOIDmode)"
d90ffc8d
JH
5712{
5713 switch (get_attr_type (insn))
5714 {
5715 case TYPE_INCDEC:
5716 if (! rtx_equal_p (operands[0], operands[1]))
5717 abort ();
5718 if (operands[2] == const1_rtx)
0f40f9f7 5719 return "inc{q}\t%0";
d90ffc8d 5720 else if (operands[2] == constm1_rtx)
0f40f9f7 5721 return "dec{q}\t%0";
d90ffc8d 5722 else
9b70259d 5723 abort ();
d90ffc8d
JH
5724
5725 default:
5726 if (! rtx_equal_p (operands[0], operands[1]))
5727 abort ();
9b70259d
JH
5728 /* ???? We ought to handle there the 32bit case too
5729 - do we need new constrant? */
d90ffc8d
JH
5730 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5731 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5732 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5733 /* Avoid overflows. */
0f40f9f7 5734 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
d90ffc8d
JH
5735 && (INTVAL (operands[2]) == 128
5736 || (INTVAL (operands[2]) < 0
5737 && INTVAL (operands[2]) != -128)))
5738 {
5739 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5740 return "sub{q}\t{%2, %0|%0, %2}";
d90ffc8d 5741 }
0f40f9f7 5742 return "add{q}\t{%2, %0|%0, %2}";
d90ffc8d 5743 }
0f40f9f7 5744}
d90ffc8d 5745 [(set (attr "type")
9b70259d 5746 (if_then_else (match_operand:DI 2 "incdec_operand" "")
d90ffc8d
JH
5747 (const_string "incdec")
5748 (const_string "alu")))
9b70259d 5749 (set_attr "mode" "DI")])
d90ffc8d 5750
9b70259d 5751; For comparisons against 1, -1 and 128, we may generate better code
7e08e190
JH
5752; by converting cmp to add, inc or dec as done by peephole2. This pattern
5753; is matched then. We can't accept general immediate, because for
5754; case of overflows, the result is messed up.
9b70259d 5755; This pattern also don't hold of 0x8000000000000000, since the value overflows
7e08e190
JH
5756; when negated.
5757; Also carry flag is reversed compared to cmp, so this converison is valid
5758; only for comparisons not depending on it.
e74061a9 5759(define_insn "*adddi_4_rex64"
9076b9c1 5760 [(set (reg 17)
9b70259d
JH
5761 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5762 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5763 (clobber (match_scratch:DI 0 "=rm"))]
e74061a9
JH
5764 "TARGET_64BIT
5765 && ix86_match_ccmode (insn, CCGCmode)"
7e08e190
JH
5766{
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_INCDEC:
5770 if (operands[2] == constm1_rtx)
0f40f9f7 5771 return "inc{q}\t%0";
7e08e190 5772 else if (operands[2] == const1_rtx)
0f40f9f7 5773 return "dec{q}\t%0";
7e08e190
JH
5774 else
5775 abort();
e075ae69 5776
7e08e190
JH
5777 default:
5778 if (! rtx_equal_p (operands[0], operands[1]))
5779 abort ();
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if ((INTVAL (operands[2]) == -128
5783 || (INTVAL (operands[2]) > 0
ef6257cd
JH
5784 && INTVAL (operands[2]) != 128))
5785 /* Avoid overflows. */
0f40f9f7
ZW
5786 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5787 return "sub{q}\t{%2, %0|%0, %2}";
7e08e190 5788 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5789 return "add{q}\t{%2, %0|%0, %2}";
7e08e190 5790 }
0f40f9f7 5791}
7e08e190 5792 [(set (attr "type")
9b70259d 5793 (if_then_else (match_operand:DI 2 "incdec_operand" "")
7e08e190
JH
5794 (const_string "incdec")
5795 (const_string "alu")))
9b70259d 5796 (set_attr "mode" "DI")])
d90ffc8d 5797
e74061a9 5798(define_insn "*adddi_5_rex64"
9076b9c1
JH
5799 [(set (reg 17)
5800 (compare
9b70259d
JH
5801 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5802 (match_operand:DI 2 "x86_64_general_operand" "rme"))
9076b9c1 5803 (const_int 0)))
9b70259d 5804 (clobber (match_scratch:DI 0 "=r"))]
e74061a9
JH
5805 "TARGET_64BIT
5806 && ix86_match_ccmode (insn, CCGOCmode)
9076b9c1
JH
5807 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5808 /* Current assemblers are broken and do not allow @GOTOFF in
5809 ought but a memory context. */
5810 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9076b9c1
JH
5811{
5812 switch (get_attr_type (insn))
5813 {
5814 case TYPE_INCDEC:
5815 if (! rtx_equal_p (operands[0], operands[1]))
5816 abort ();
5817 if (operands[2] == const1_rtx)
0f40f9f7 5818 return "inc{q}\t%0";
9076b9c1 5819 else if (operands[2] == constm1_rtx)
0f40f9f7 5820 return "dec{q}\t%0";
9076b9c1
JH
5821 else
5822 abort();
5823
5824 default:
5825 if (! rtx_equal_p (operands[0], operands[1]))
5826 abort ();
5827 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5828 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5829 if (GET_CODE (operands[2]) == CONST_INT
ef6257cd 5830 /* Avoid overflows. */
0f40f9f7 5831 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
9076b9c1
JH
5832 && (INTVAL (operands[2]) == 128
5833 || (INTVAL (operands[2]) < 0
5834 && INTVAL (operands[2]) != -128)))
5835 {
5836 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5837 return "sub{q}\t{%2, %0|%0, %2}";
9076b9c1 5838 }
0f40f9f7 5839 return "add{q}\t{%2, %0|%0, %2}";
9076b9c1 5840 }
0f40f9f7 5841}
9076b9c1 5842 [(set (attr "type")
9b70259d 5843 (if_then_else (match_operand:DI 2 "incdec_operand" "")
9076b9c1
JH
5844 (const_string "incdec")
5845 (const_string "alu")))
9b70259d 5846 (set_attr "mode" "DI")])
2ae0f82c 5847
e075ae69 5848
9b70259d
JH
5849(define_insn "*addsi_1"
5850 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5851 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5852 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
58787064 5853 (clobber (reg:CC 17))]
9b70259d 5854 "ix86_binary_operator_ok (PLUS, SImode, operands)"
58787064
JH
5855{
5856 switch (get_attr_type (insn))
5857 {
5858 case TYPE_LEA:
9b70259d 5859 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5860 return "lea{l}\t{%a2, %0|%0, %a2}";
9b70259d 5861
58787064 5862 case TYPE_INCDEC:
9b70259d
JH
5863 if (! rtx_equal_p (operands[0], operands[1]))
5864 abort ();
58787064 5865 if (operands[2] == const1_rtx)
0f40f9f7 5866 return "inc{l}\t%0";
9b70259d 5867 else if (operands[2] == constm1_rtx)
0f40f9f7 5868 return "dec{l}\t%0";
9b70259d
JH
5869 else
5870 abort();
58787064
JH
5871
5872 default:
9b70259d
JH
5873 if (! rtx_equal_p (operands[0], operands[1]))
5874 abort ();
5875
58787064
JH
5876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5878 if (GET_CODE (operands[2]) == CONST_INT
5879 && (INTVAL (operands[2]) == 128
5880 || (INTVAL (operands[2]) < 0
5881 && INTVAL (operands[2]) != -128)))
9b70259d
JH
5882 {
5883 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5884 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 5885 }
0f40f9f7 5886 return "add{l}\t{%2, %0|%0, %2}";
58787064 5887 }
0f40f9f7 5888}
58787064 5889 [(set (attr "type")
9b70259d
JH
5890 (cond [(eq_attr "alternative" "2")
5891 (const_string "lea")
5892 ; Current assemblers are broken and do not allow @GOTOFF in
5893 ; ought but a memory context.
5894 (match_operand:SI 2 "pic_symbolic_operand" "")
5895 (const_string "lea")
5896 (match_operand:SI 2 "incdec_operand" "")
5897 (const_string "incdec")
5898 ]
5899 (const_string "alu")))
5900 (set_attr "mode" "SI")])
58787064 5901
9b70259d
JH
5902;; Convert lea to the lea pattern to avoid flags dependency.
5903(define_split
5904 [(set (match_operand 0 "register_operand" "")
5905 (plus (match_operand 1 "register_operand" "")
5906 (match_operand 2 "nonmemory_operand" "")))
e075ae69 5907 (clobber (reg:CC 17))]
9b70259d
JH
5908 "reload_completed
5909 && true_regnum (operands[0]) != true_regnum (operands[1])"
5910 [(const_int 0)]
9b70259d
JH
5911{
5912 rtx pat;
5913 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5914 may confuse gen_lowpart. */
5915 if (GET_MODE (operands[0]) != Pmode)
5916 {
5917 operands[1] = gen_lowpart (Pmode, operands[1]);
5918 operands[2] = gen_lowpart (Pmode, operands[2]);
5919 }
5920 operands[0] = gen_lowpart (SImode, operands[0]);
5921 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5922 if (Pmode != SImode)
5923 pat = gen_rtx_SUBREG (SImode, pat, 0);
5924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5925 DONE;
0f40f9f7 5926})
9b70259d
JH
5927
5928;; It may seem that nonimmediate operand is proper one for operand 1.
5929;; The addsi_1 pattern allows nonimmediate operand at that place and
5930;; we take care in ix86_binary_operator_ok to not allow two memory
5931;; operands so proper swapping will be done in reload. This allow
5932;; patterns constructed from addsi_1 to match.
5933(define_insn "addsi_1_zext"
5934 [(set (match_operand:DI 0 "register_operand" "=r,r")
5935 (zero_extend:DI
5936 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5937 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5938 (clobber (reg:CC 17))]
5939 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
886c62d1 5940{
e075ae69 5941 switch (get_attr_type (insn))
7c802a40 5942 {
9b70259d
JH
5943 case TYPE_LEA:
5944 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 5945 return "lea{l}\t{%a2, %k0|%k0, %a2}";
9b70259d 5946
e075ae69
RH
5947 case TYPE_INCDEC:
5948 if (operands[2] == const1_rtx)
0f40f9f7 5949 return "inc{l}\t%k0";
9b70259d 5950 else if (operands[2] == constm1_rtx)
0f40f9f7 5951 return "dec{l}\t%k0";
9b70259d
JH
5952 else
5953 abort();
5954
5955 default:
5956 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5957 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5958 if (GET_CODE (operands[2]) == CONST_INT
5959 && (INTVAL (operands[2]) == 128
5960 || (INTVAL (operands[2]) < 0
5961 && INTVAL (operands[2]) != -128)))
5962 {
5963 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 5964 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 5965 }
0f40f9f7 5966 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 5967 }
0f40f9f7 5968}
9b70259d
JH
5969 [(set (attr "type")
5970 (cond [(eq_attr "alternative" "1")
5971 (const_string "lea")
5972 ; Current assemblers are broken and do not allow @GOTOFF in
5973 ; ought but a memory context.
5974 (match_operand:SI 2 "pic_symbolic_operand" "")
5975 (const_string "lea")
5976 (match_operand:SI 2 "incdec_operand" "")
5977 (const_string "incdec")
5978 ]
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5981
5982;; Convert lea to the lea pattern to avoid flags dependency.
5983(define_split
5984 [(set (match_operand:DI 0 "register_operand" "")
5985 (zero_extend:DI
5986 (plus:SI (match_operand:SI 1 "register_operand" "")
5987 (match_operand:SI 2 "nonmemory_operand" ""))))
5988 (clobber (reg:CC 17))]
5989 "reload_completed
5990 && true_regnum (operands[0]) != true_regnum (operands[1])"
5991 [(set (match_dup 0)
5992 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
9b70259d
JH
5993{
5994 operands[1] = gen_lowpart (Pmode, operands[1]);
5995 operands[2] = gen_lowpart (Pmode, operands[2]);
0f40f9f7 5996})
9b70259d
JH
5997
5998(define_insn "*addsi_2"
5999 [(set (reg 17)
6000 (compare
6001 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6002 (match_operand:SI 2 "general_operand" "rmni,rni"))
6003 (const_int 0)))
6004 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6005 (plus:SI (match_dup 1) (match_dup 2)))]
6006 "ix86_match_ccmode (insn, CCGOCmode)
6007 && ix86_binary_operator_ok (PLUS, SImode, operands)
6008 /* Current assemblers are broken and do not allow @GOTOFF in
6009 ought but a memory context. */
6010 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6011{
6012 switch (get_attr_type (insn))
6013 {
6014 case TYPE_INCDEC:
6015 if (! rtx_equal_p (operands[0], operands[1]))
6016 abort ();
6017 if (operands[2] == const1_rtx)
0f40f9f7 6018 return "inc{l}\t%0";
9b70259d 6019 else if (operands[2] == constm1_rtx)
0f40f9f7 6020 return "dec{l}\t%0";
9b70259d
JH
6021 else
6022 abort();
6023
6024 default:
6025 if (! rtx_equal_p (operands[0], operands[1]))
6026 abort ();
6027 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6028 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6029 if (GET_CODE (operands[2]) == CONST_INT
6030 && (INTVAL (operands[2]) == 128
6031 || (INTVAL (operands[2]) < 0
6032 && INTVAL (operands[2]) != -128)))
6033 {
6034 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6035 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6036 }
0f40f9f7 6037 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 6038 }
0f40f9f7 6039}
9b70259d
JH
6040 [(set (attr "type")
6041 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set_attr "mode" "SI")])
6045
6046;; See comment for addsi_1_zext why we do use nonimmediate_operand
6047(define_insn "*addsi_2_zext"
6048 [(set (reg 17)
6049 (compare
6050 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6051 (match_operand:SI 2 "general_operand" "rmni"))
6052 (const_int 0)))
6053 (set (match_operand:DI 0 "register_operand" "=r")
6054 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6055 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6056 && ix86_binary_operator_ok (PLUS, SImode, operands)
6057 /* Current assemblers are broken and do not allow @GOTOFF in
6058 ought but a memory context. */
6059 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6060{
6061 switch (get_attr_type (insn))
6062 {
6063 case TYPE_INCDEC:
6064 if (operands[2] == const1_rtx)
0f40f9f7 6065 return "inc{l}\t%k0";
9b70259d 6066 else if (operands[2] == constm1_rtx)
0f40f9f7 6067 return "dec{l}\t%k0";
9b70259d
JH
6068 else
6069 abort();
6070
6071 default:
6072 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6074 if (GET_CODE (operands[2]) == CONST_INT
6075 && (INTVAL (operands[2]) == 128
6076 || (INTVAL (operands[2]) < 0
6077 && INTVAL (operands[2]) != -128)))
6078 {
6079 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6080 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 6081 }
0f40f9f7 6082 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 6083 }
0f40f9f7 6084}
9b70259d
JH
6085 [(set (attr "type")
6086 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set_attr "mode" "SI")])
6090
6091(define_insn "*addsi_3"
6092 [(set (reg 17)
6093 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6094 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6095 (clobber (match_scratch:SI 0 "=r"))]
6096 "ix86_match_ccmode (insn, CCZmode)
6097 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6098 /* Current assemblers are broken and do not allow @GOTOFF in
6099 ought but a memory context. */
6100 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6101{
6102 switch (get_attr_type (insn))
6103 {
6104 case TYPE_INCDEC:
6105 if (! rtx_equal_p (operands[0], operands[1]))
6106 abort ();
6107 if (operands[2] == const1_rtx)
0f40f9f7 6108 return "inc{l}\t%0";
9b70259d 6109 else if (operands[2] == constm1_rtx)
0f40f9f7 6110 return "dec{l}\t%0";
9b70259d
JH
6111 else
6112 abort();
6113
6114 default:
6115 if (! rtx_equal_p (operands[0], operands[1]))
6116 abort ();
6117 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6118 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6119 if (GET_CODE (operands[2]) == CONST_INT
6120 && (INTVAL (operands[2]) == 128
6121 || (INTVAL (operands[2]) < 0
6122 && INTVAL (operands[2]) != -128)))
6123 {
6124 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6125 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6126 }
0f40f9f7 6127 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 6128 }
0f40f9f7 6129}
9b70259d
JH
6130 [(set (attr "type")
6131 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6132 (const_string "incdec")
6133 (const_string "alu")))
6134 (set_attr "mode" "SI")])
6135
6136;; See comment for addsi_1_zext why we do use nonimmediate_operand
6137(define_insn "*addsi_3_zext"
6138 [(set (reg 17)
6139 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6140 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6141 (set (match_operand:DI 0 "register_operand" "=r")
6142 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6143 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6144 && ix86_binary_operator_ok (PLUS, SImode, operands)
6145 /* Current assemblers are broken and do not allow @GOTOFF in
6146 ought but a memory context. */
6147 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6148{
6149 switch (get_attr_type (insn))
6150 {
6151 case TYPE_INCDEC:
6152 if (operands[2] == const1_rtx)
0f40f9f7 6153 return "inc{l}\t%k0";
9b70259d 6154 else if (operands[2] == constm1_rtx)
0f40f9f7 6155 return "dec{l}\t%k0";
9b70259d
JH
6156 else
6157 abort();
6158
6159 default:
6160 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6162 if (GET_CODE (operands[2]) == CONST_INT
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6166 {
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6168 return "sub{l}\t{%2, %k0|%k0, %2}";
9b70259d 6169 }
0f40f9f7 6170 return "add{l}\t{%2, %k0|%k0, %2}";
9b70259d 6171 }
0f40f9f7 6172}
9b70259d
JH
6173 [(set (attr "type")
6174 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "mode" "SI")])
6178
6179; For comparisons agains 1, -1 and 128, we may generate better code
6180; by converting cmp to add, inc or dec as done by peephole2. This pattern
6181; is matched then. We can't accept general immediate, because for
6182; case of overflows, the result is messed up.
6183; This pattern also don't hold of 0x80000000, since the value overflows
6184; when negated.
6185; Also carry flag is reversed compared to cmp, so this converison is valid
6186; only for comparisons not depending on it.
6187(define_insn "*addsi_4"
6188 [(set (reg 17)
6189 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6190 (match_operand:SI 2 "const_int_operand" "n")))
6191 (clobber (match_scratch:SI 0 "=rm"))]
6192 "ix86_match_ccmode (insn, CCGCmode)
6193 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
9b70259d
JH
6194{
6195 switch (get_attr_type (insn))
6196 {
6197 case TYPE_INCDEC:
6198 if (operands[2] == constm1_rtx)
0f40f9f7 6199 return "inc{l}\t%0";
9b70259d 6200 else if (operands[2] == const1_rtx)
0f40f9f7 6201 return "dec{l}\t%0";
9b70259d
JH
6202 else
6203 abort();
6204
6205 default:
6206 if (! rtx_equal_p (operands[0], operands[1]))
6207 abort ();
6208 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6209 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6210 if ((INTVAL (operands[2]) == -128
6211 || (INTVAL (operands[2]) > 0
6212 && INTVAL (operands[2]) != 128)))
0f40f9f7 6213 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6214 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6215 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 6216 }
0f40f9f7 6217}
9b70259d
JH
6218 [(set (attr "type")
6219 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu")))
6222 (set_attr "mode" "SI")])
6223
6224(define_insn "*addsi_5"
6225 [(set (reg 17)
6226 (compare
6227 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6228 (match_operand:SI 2 "general_operand" "rmni"))
6229 (const_int 0)))
6230 (clobber (match_scratch:SI 0 "=r"))]
6231 "ix86_match_ccmode (insn, CCGOCmode)
6232 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6233 /* Current assemblers are broken and do not allow @GOTOFF in
6234 ought but a memory context. */
6235 && ! pic_symbolic_operand (operands[2], VOIDmode)"
9b70259d
JH
6236{
6237 switch (get_attr_type (insn))
6238 {
6239 case TYPE_INCDEC:
6240 if (! rtx_equal_p (operands[0], operands[1]))
6241 abort ();
6242 if (operands[2] == const1_rtx)
0f40f9f7 6243 return "inc{l}\t%0";
9b70259d 6244 else if (operands[2] == constm1_rtx)
0f40f9f7 6245 return "dec{l}\t%0";
9b70259d
JH
6246 else
6247 abort();
6248
6249 default:
6250 if (! rtx_equal_p (operands[0], operands[1]))
6251 abort ();
6252 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6253 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6254 if (GET_CODE (operands[2]) == CONST_INT
6255 && (INTVAL (operands[2]) == 128
6256 || (INTVAL (operands[2]) < 0
6257 && INTVAL (operands[2]) != -128)))
6258 {
6259 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6260 return "sub{l}\t{%2, %0|%0, %2}";
9b70259d 6261 }
0f40f9f7 6262 return "add{l}\t{%2, %0|%0, %2}";
9b70259d 6263 }
0f40f9f7 6264}
9b70259d
JH
6265 [(set (attr "type")
6266 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6267 (const_string "incdec")
6268 (const_string "alu")))
6269 (set_attr "mode" "SI")])
6270
6271(define_expand "addhi3"
6272 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6273 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6274 (match_operand:HI 2 "general_operand" "")))
6275 (clobber (reg:CC 17))])]
6276 "TARGET_HIMODE_MATH"
6277 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6278
6279;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6280;; type optimizations enabled by define-splits. This is not important
6281;; for PII, and in fact harmful because of partial register stalls.
6282
6283(define_insn "*addhi_1_lea"
6284 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6285 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6286 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6287 (clobber (reg:CC 17))]
6288 "!TARGET_PARTIAL_REG_STALL
6289 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
6290{
6291 switch (get_attr_type (insn))
6292 {
6293 case TYPE_LEA:
0f40f9f7 6294 return "#";
9b70259d
JH
6295 case TYPE_INCDEC:
6296 if (operands[2] == const1_rtx)
0f40f9f7 6297 return "inc{w}\t%0";
9b70259d
JH
6298 else if (operands[2] == constm1_rtx
6299 || (GET_CODE (operands[2]) == CONST_INT
6300 && INTVAL (operands[2]) == 65535))
0f40f9f7 6301 return "dec{w}\t%0";
9b70259d
JH
6302 abort();
6303
6304 default:
6305 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6306 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6307 if (GET_CODE (operands[2]) == CONST_INT
6308 && (INTVAL (operands[2]) == 128
6309 || (INTVAL (operands[2]) < 0
6310 && INTVAL (operands[2]) != -128)))
6311 {
6312 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6313 return "sub{w}\t{%2, %0|%0, %2}";
9b70259d 6314 }
0f40f9f7 6315 return "add{w}\t{%2, %0|%0, %2}";
9b70259d 6316 }
0f40f9f7 6317}
9b70259d
JH
6318 [(set (attr "type")
6319 (if_then_else (eq_attr "alternative" "2")
6320 (const_string "lea")
6321 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6322 (const_string "incdec")
6323 (const_string "alu"))))
6324 (set_attr "mode" "HI,HI,SI")])
6325
6326(define_insn "*addhi_1"
6327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6328 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6329 (match_operand:HI 2 "general_operand" "ri,rm")))
6330 (clobber (reg:CC 17))]
6331 "TARGET_PARTIAL_REG_STALL
6332 && ix86_binary_operator_ok (PLUS, HImode, operands)"
9b70259d
JH
6333{
6334 switch (get_attr_type (insn))
6335 {
6336 case TYPE_INCDEC:
6337 if (operands[2] == const1_rtx)
0f40f9f7 6338 return "inc{w}\t%0";
9b70259d
JH
6339 else if (operands[2] == constm1_rtx
6340 || (GET_CODE (operands[2]) == CONST_INT
6341 && INTVAL (operands[2]) == 65535))
0f40f9f7 6342 return "dec{w}\t%0";
e075ae69 6343 abort();
7c802a40 6344
e075ae69
RH
6345 default:
6346 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6347 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6348 if (GET_CODE (operands[2]) == CONST_INT
6349 && (INTVAL (operands[2]) == 128
6350 || (INTVAL (operands[2]) < 0
6351 && INTVAL (operands[2]) != -128)))
6352 {
6353 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6354 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6355 }
0f40f9f7 6356 return "add{w}\t{%2, %0|%0, %2}";
7c802a40 6357 }
0f40f9f7 6358}
e075ae69
RH
6359 [(set (attr "type")
6360 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6361 (const_string "incdec")
6ef67412
JH
6362 (const_string "alu")))
6363 (set_attr "mode" "HI")])
7c802a40 6364
e075ae69 6365(define_insn "*addhi_2"
16189740
RH
6366 [(set (reg 17)
6367 (compare
e075ae69
RH
6368 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6369 (match_operand:HI 2 "general_operand" "rmni,rni"))
6370 (const_int 0)))
6371 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6372 (plus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 6373 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6374 && ix86_binary_operator_ok (PLUS, HImode, operands)"
e075ae69
RH
6375{
6376 switch (get_attr_type (insn))
b980bec0 6377 {
e075ae69
RH
6378 case TYPE_INCDEC:
6379 if (operands[2] == const1_rtx)
0f40f9f7 6380 return "inc{w}\t%0";
e075ae69
RH
6381 else if (operands[2] == constm1_rtx
6382 || (GET_CODE (operands[2]) == CONST_INT
6383 && INTVAL (operands[2]) == 65535))
0f40f9f7 6384 return "dec{w}\t%0";
e075ae69 6385 abort();
b980bec0 6386
e075ae69
RH
6387 default:
6388 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6389 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6390 if (GET_CODE (operands[2]) == CONST_INT
6391 && (INTVAL (operands[2]) == 128
6392 || (INTVAL (operands[2]) < 0
6393 && INTVAL (operands[2]) != -128)))
6394 {
6395 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6396 return "sub{w}\t{%2, %0|%0, %2}";
e075ae69 6397 }
0f40f9f7 6398 return "add{w}\t{%2, %0|%0, %2}";
b980bec0 6399 }
0f40f9f7 6400}
e075ae69
RH
6401 [(set (attr "type")
6402 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6403 (const_string "incdec")
6ef67412
JH
6404 (const_string "alu")))
6405 (set_attr "mode" "HI")])
e075ae69
RH
6406
6407(define_insn "*addhi_3"
d90ffc8d 6408 [(set (reg 17)
7e08e190
JH
6409 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6410 (match_operand:HI 1 "nonimmediate_operand" "%0")))
d90ffc8d 6411 (clobber (match_scratch:HI 0 "=r"))]
7e08e190 6412 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6414{
6415 switch (get_attr_type (insn))
6416 {
6417 case TYPE_INCDEC:
6418 if (operands[2] == const1_rtx)
0f40f9f7 6419 return "inc{w}\t%0";
d90ffc8d
JH
6420 else if (operands[2] == constm1_rtx
6421 || (GET_CODE (operands[2]) == CONST_INT
6422 && INTVAL (operands[2]) == 65535))
0f40f9f7 6423 return "dec{w}\t%0";
d90ffc8d
JH
6424 abort();
6425
6426 default:
6427 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6428 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6429 if (GET_CODE (operands[2]) == CONST_INT
6430 && (INTVAL (operands[2]) == 128
6431 || (INTVAL (operands[2]) < 0
6432 && INTVAL (operands[2]) != -128)))
6433 {
6434 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6435 return "sub{w}\t{%2, %0|%0, %2}";
d90ffc8d 6436 }
0f40f9f7 6437 return "add{w}\t{%2, %0|%0, %2}";
d90ffc8d 6438 }
0f40f9f7 6439}
d90ffc8d
JH
6440 [(set (attr "type")
6441 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6442 (const_string "incdec")
6443 (const_string "alu")))
6444 (set_attr "mode" "HI")])
6445
7e08e190 6446; See comments above addsi_3_imm for details.
d90ffc8d 6447(define_insn "*addhi_4"
9076b9c1 6448 [(set (reg 17)
7e08e190
JH
6449 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6450 (match_operand:HI 2 "const_int_operand" "n")))
6451 (clobber (match_scratch:HI 0 "=rm"))]
6452 "ix86_match_ccmode (insn, CCGCmode)
6453 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7e08e190
JH
6454{
6455 switch (get_attr_type (insn))
6456 {
6457 case TYPE_INCDEC:
6458 if (operands[2] == constm1_rtx
6459 || (GET_CODE (operands[2]) == CONST_INT
6460 && INTVAL (operands[2]) == 65535))
0f40f9f7 6461 return "inc{w}\t%0";
7e08e190 6462 else if (operands[2] == const1_rtx)
0f40f9f7 6463 return "dec{w}\t%0";
7e08e190
JH
6464 else
6465 abort();
6466
6467 default:
6468 if (! rtx_equal_p (operands[0], operands[1]))
6469 abort ();
6470 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6471 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6472 if ((INTVAL (operands[2]) == -128
6473 || (INTVAL (operands[2]) > 0
6474 && INTVAL (operands[2]) != 128)))
0f40f9f7 6475 return "sub{w}\t{%2, %0|%0, %2}";
7e08e190 6476 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6477 return "add{w}\t{%2, %0|%0, %2}";
7e08e190 6478 }
0f40f9f7 6479}
7e08e190
JH
6480 [(set (attr "type")
6481 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6482 (const_string "incdec")
6483 (const_string "alu")))
6484 (set_attr "mode" "SI")])
b980bec0 6485
d90ffc8d 6486
7e08e190 6487(define_insn "*addhi_5"
9076b9c1
JH
6488 [(set (reg 17)
6489 (compare
6490 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6491 (match_operand:HI 2 "general_operand" "rmni"))
6492 (const_int 0)))
6493 (clobber (match_scratch:HI 0 "=r"))]
6494 "ix86_match_ccmode (insn, CCGOCmode)
6495 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6496{
6497 switch (get_attr_type (insn))
6498 {
6499 case TYPE_INCDEC:
6500 if (operands[2] == const1_rtx)
0f40f9f7 6501 return "inc{w}\t%0";
9076b9c1
JH
6502 else if (operands[2] == constm1_rtx
6503 || (GET_CODE (operands[2]) == CONST_INT
6504 && INTVAL (operands[2]) == 65535))
0f40f9f7 6505 return "dec{w}\t%0";
9076b9c1
JH
6506 abort();
6507
6508 default:
6509 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6510 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6511 if (GET_CODE (operands[2]) == CONST_INT
6512 && (INTVAL (operands[2]) == 128
6513 || (INTVAL (operands[2]) < 0
6514 && INTVAL (operands[2]) != -128)))
6515 {
6516 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6517 return "sub{w}\t{%2, %0|%0, %2}";
9076b9c1 6518 }
0f40f9f7 6519 return "add{w}\t{%2, %0|%0, %2}";
9076b9c1 6520 }
0f40f9f7 6521}
9076b9c1
JH
6522 [(set (attr "type")
6523 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6524 (const_string "incdec")
6525 (const_string "alu")))
6526 (set_attr "mode" "HI")])
6527
e075ae69 6528(define_expand "addqi3"
4cbfbb1b
JH
6529 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6530 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69
RH
6531 (match_operand:QI 2 "general_operand" "")))
6532 (clobber (reg:CC 17))])]
d9f32422 6533 "TARGET_QIMODE_MATH"
e075ae69
RH
6534 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6535
6536;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
6537(define_insn "*addqi_1_lea"
6538 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6539 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6540 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6541 (clobber (reg:CC 17))]
6542 "!TARGET_PARTIAL_REG_STALL
6543 && ix86_binary_operator_ok (PLUS, QImode, operands)"
58787064
JH
6544{
6545 int widen = (which_alternative == 2);
6546 switch (get_attr_type (insn))
6547 {
6548 case TYPE_LEA:
0f40f9f7 6549 return "#";
58787064
JH
6550 case TYPE_INCDEC:
6551 if (operands[2] == const1_rtx)
0f40f9f7 6552 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
58787064
JH
6553 else if (operands[2] == constm1_rtx
6554 || (GET_CODE (operands[2]) == CONST_INT
6555 && INTVAL (operands[2]) == 255))
0f40f9f7 6556 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
58787064
JH
6557 abort();
6558
6559 default:
6560 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6561 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6562 if (GET_CODE (operands[2]) == CONST_INT
6563 && (INTVAL (operands[2]) == 128
6564 || (INTVAL (operands[2]) < 0
6565 && INTVAL (operands[2]) != -128)))
6566 {
6567 operands[2] = GEN_INT (-INTVAL (operands[2]));
6568 if (widen)
0f40f9f7 6569 return "sub{l}\t{%2, %k0|%k0, %2}";
58787064 6570 else
0f40f9f7 6571 return "sub{b}\t{%2, %0|%0, %2}";
58787064
JH
6572 }
6573 if (widen)
0f40f9f7 6574 return "add{l}\t{%k2, %k0|%k0, %k2}";
58787064 6575 else
0f40f9f7 6576 return "add{b}\t{%2, %0|%0, %2}";
58787064 6577 }
0f40f9f7 6578}
58787064
JH
6579 [(set (attr "type")
6580 (if_then_else (eq_attr "alternative" "3")
6581 (const_string "lea")
adc88131 6582 (if_then_else (match_operand:QI 2 "incdec_operand" "")
58787064
JH
6583 (const_string "incdec")
6584 (const_string "alu"))))
adc88131 6585 (set_attr "mode" "QI,QI,SI,SI")])
58787064 6586
e075ae69 6587(define_insn "*addqi_1"
7c6b971d 6588 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 6589 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 6590 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
e075ae69 6591 (clobber (reg:CC 17))]
58787064
JH
6592 "TARGET_PARTIAL_REG_STALL
6593 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6594{
6595 int widen = (which_alternative == 2);
6596 switch (get_attr_type (insn))
5bc7cd8e 6597 {
e075ae69
RH
6598 case TYPE_INCDEC:
6599 if (operands[2] == const1_rtx)
0f40f9f7 6600 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
e075ae69
RH
6601 else if (operands[2] == constm1_rtx
6602 || (GET_CODE (operands[2]) == CONST_INT
6603 && INTVAL (operands[2]) == 255))
0f40f9f7 6604 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
e075ae69 6605 abort();
5bc7cd8e 6606
e075ae69
RH
6607 default:
6608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6610 if (GET_CODE (operands[2]) == CONST_INT
6611 && (INTVAL (operands[2]) == 128
6612 || (INTVAL (operands[2]) < 0
6613 && INTVAL (operands[2]) != -128)))
5bc7cd8e 6614 {
e075ae69
RH
6615 operands[2] = GEN_INT (-INTVAL (operands[2]));
6616 if (widen)
0f40f9f7 6617 return "sub{l}\t{%2, %k0|%k0, %2}";
e075ae69 6618 else
0f40f9f7 6619 return "sub{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6620 }
e075ae69 6621 if (widen)
0f40f9f7 6622 return "add{l}\t{%k2, %k0|%k0, %k2}";
e075ae69 6623 else
0f40f9f7 6624 return "add{b}\t{%2, %0|%0, %2}";
5bc7cd8e 6625 }
0f40f9f7 6626}
e075ae69
RH
6627 [(set (attr "type")
6628 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6629 (const_string "incdec")
6ef67412
JH
6630 (const_string "alu")))
6631 (set_attr "mode" "QI,QI,SI")])
e075ae69
RH
6632
6633(define_insn "*addqi_2"
16189740
RH
6634 [(set (reg 17)
6635 (compare
e075ae69
RH
6636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6637 (match_operand:QI 2 "general_operand" "qmni,qni"))
6638 (const_int 0)))
6639 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6640 (plus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 6641 "ix86_match_ccmode (insn, CCGOCmode)
16189740 6642 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
6643{
6644 switch (get_attr_type (insn))
6645 {
6646 case TYPE_INCDEC:
6647 if (operands[2] == const1_rtx)
0f40f9f7 6648 return "inc{b}\t%0";
e075ae69
RH
6649 else if (operands[2] == constm1_rtx
6650 || (GET_CODE (operands[2]) == CONST_INT
6651 && INTVAL (operands[2]) == 255))
0f40f9f7 6652 return "dec{b}\t%0";
e075ae69 6653 abort();
5bc7cd8e 6654
e075ae69
RH
6655 default:
6656 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6657 if (GET_CODE (operands[2]) == CONST_INT
6658 && INTVAL (operands[2]) < 0)
6659 {
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6661 return "sub{b}\t{%2, %0|%0, %2}";
e075ae69 6662 }
0f40f9f7 6663 return "add{b}\t{%2, %0|%0, %2}";
e075ae69 6664 }
0f40f9f7 6665}
e075ae69
RH
6666 [(set (attr "type")
6667 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6668 (const_string "incdec")
6ef67412
JH
6669 (const_string "alu")))
6670 (set_attr "mode" "QI")])
e075ae69
RH
6671
6672(define_insn "*addqi_3"
d90ffc8d 6673 [(set (reg 17)
7e08e190
JH
6674 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6675 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6676 (clobber (match_scratch:QI 0 "=q"))]
6677 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d 6678 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
d90ffc8d
JH
6679{
6680 switch (get_attr_type (insn))
6681 {
6682 case TYPE_INCDEC:
6683 if (operands[2] == const1_rtx)
0f40f9f7 6684 return "inc{b}\t%0";
d90ffc8d
JH
6685 else if (operands[2] == constm1_rtx
6686 || (GET_CODE (operands[2]) == CONST_INT
6687 && INTVAL (operands[2]) == 255))
0f40f9f7 6688 return "dec{b}\t%0";
d90ffc8d
JH
6689 abort();
6690
6691 default:
6692 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6693 if (GET_CODE (operands[2]) == CONST_INT
6694 && INTVAL (operands[2]) < 0)
6695 {
6696 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6697 return "sub{b}\t{%2, %0|%0, %2}";
d90ffc8d 6698 }
0f40f9f7 6699 return "add{b}\t{%2, %0|%0, %2}";
d90ffc8d 6700 }
0f40f9f7 6701}
d90ffc8d
JH
6702 [(set (attr "type")
6703 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6704 (const_string "incdec")
6705 (const_string "alu")))
6706 (set_attr "mode" "QI")])
6707
7e08e190 6708; See comments above addsi_3_imm for details.
d90ffc8d 6709(define_insn "*addqi_4"
9076b9c1 6710 [(set (reg 17)
7e08e190
JH
6711 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6712 (match_operand:QI 2 "const_int_operand" "n")))
6713 (clobber (match_scratch:QI 0 "=qm"))]
6714 "ix86_match_ccmode (insn, CCGCmode)
6715 && (INTVAL (operands[2]) & 0xff) != 0x80"
7e08e190
JH
6716{
6717 switch (get_attr_type (insn))
6718 {
6719 case TYPE_INCDEC:
6720 if (operands[2] == constm1_rtx
6721 || (GET_CODE (operands[2]) == CONST_INT
6722 && INTVAL (operands[2]) == 255))
0f40f9f7 6723 return "inc{b}\t%0";
7e08e190 6724 else if (operands[2] == const1_rtx)
0f40f9f7 6725 return "dec{b}\t%0";
7e08e190
JH
6726 else
6727 abort();
6728
6729 default:
6730 if (! rtx_equal_p (operands[0], operands[1]))
6731 abort ();
6732 if (INTVAL (operands[2]) < 0)
6733 {
6734 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6735 return "add{b}\t{%2, %0|%0, %2}";
7e08e190 6736 }
0f40f9f7 6737 return "sub{b}\t{%2, %0|%0, %2}";
7e08e190 6738 }
0f40f9f7 6739}
7e08e190
JH
6740 [(set (attr "type")
6741 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6742 (const_string "incdec")
6743 (const_string "alu")))
6ef67412 6744 (set_attr "mode" "QI")])
886c62d1 6745
9dcbdc7e 6746
d90ffc8d 6747(define_insn "*addqi_5"
9076b9c1
JH
6748 [(set (reg 17)
6749 (compare
6750 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6751 (match_operand:QI 2 "general_operand" "qmni"))
6752 (const_int 0)))
7e08e190 6753 (clobber (match_scratch:QI 0 "=q"))]
9076b9c1
JH
6754 "ix86_match_ccmode (insn, CCGOCmode)
6755 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076b9c1
JH
6756{
6757 switch (get_attr_type (insn))
6758 {
6759 case TYPE_INCDEC:
6760 if (operands[2] == const1_rtx)
0f40f9f7 6761 return "inc{b}\t%0";
9076b9c1
JH
6762 else if (operands[2] == constm1_rtx
6763 || (GET_CODE (operands[2]) == CONST_INT
6764 && INTVAL (operands[2]) == 255))
0f40f9f7 6765 return "dec{b}\t%0";
9076b9c1
JH
6766 abort();
6767
6768 default:
6769 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6770 if (GET_CODE (operands[2]) == CONST_INT
6771 && INTVAL (operands[2]) < 0)
6772 {
6773 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 6774 return "sub{b}\t{%2, %0|%0, %2}";
9076b9c1 6775 }
0f40f9f7 6776 return "add{b}\t{%2, %0|%0, %2}";
9076b9c1 6777 }
0f40f9f7 6778}
9076b9c1
JH
6779 [(set (attr "type")
6780 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6781 (const_string "incdec")
6782 (const_string "alu")))
6783 (set_attr "mode" "QI")])
6784
e075ae69
RH
6785
6786(define_insn "addqi_ext_1"
3522082b 6787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6788 (const_int 8)
6789 (const_int 8))
6790 (plus:SI
6791 (zero_extract:SI
6792 (match_operand 1 "ext_register_operand" "0")
6793 (const_int 8)
6794 (const_int 8))
3522082b 6795 (match_operand:QI 2 "general_operand" "Qmn")))
e075ae69 6796 (clobber (reg:CC 17))]
d2836273 6797 "!TARGET_64BIT"
d2836273
JH
6798{
6799 switch (get_attr_type (insn))
6800 {
6801 case TYPE_INCDEC:
6802 if (operands[2] == const1_rtx)
0f40f9f7 6803 return "inc{b}\t%h0";
d2836273
JH
6804 else if (operands[2] == constm1_rtx
6805 || (GET_CODE (operands[2]) == CONST_INT
6806 && INTVAL (operands[2]) == 255))
0f40f9f7 6807 return "dec{b}\t%h0";
d2836273
JH
6808 abort();
6809
6810 default:
0f40f9f7 6811 return "add{b}\t{%2, %h0|%h0, %2}";
d2836273 6812 }
0f40f9f7 6813}
d2836273
JH
6814 [(set (attr "type")
6815 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6816 (const_string "incdec")
6817 (const_string "alu")))
6818 (set_attr "mode" "QI")])
6819
6820(define_insn "*addqi_ext_1_rex64"
6821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6822 (const_int 8)
6823 (const_int 8))
6824 (plus:SI
6825 (zero_extract:SI
6826 (match_operand 1 "ext_register_operand" "0")
6827 (const_int 8)
6828 (const_int 8))
6829 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6830 (clobber (reg:CC 17))]
6831 "TARGET_64BIT"
e075ae69
RH
6832{
6833 switch (get_attr_type (insn))
6834 {
6835 case TYPE_INCDEC:
6836 if (operands[2] == const1_rtx)
0f40f9f7 6837 return "inc{b}\t%h0";
e075ae69
RH
6838 else if (operands[2] == constm1_rtx
6839 || (GET_CODE (operands[2]) == CONST_INT
6840 && INTVAL (operands[2]) == 255))
0f40f9f7 6841 return "dec{b}\t%h0";
e075ae69 6842 abort();
886c62d1 6843
e075ae69 6844 default:
0f40f9f7 6845 return "add{b}\t{%2, %h0|%h0, %2}";
e075ae69 6846 }
0f40f9f7 6847}
e075ae69
RH
6848 [(set (attr "type")
6849 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6850 (const_string "incdec")
6ef67412
JH
6851 (const_string "alu")))
6852 (set_attr "mode" "QI")])
e075ae69
RH
6853
6854(define_insn "*addqi_ext_2"
d2836273 6855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6856 (const_int 8)
6857 (const_int 8))
6858 (plus:SI
6859 (zero_extract:SI
6860 (match_operand 1 "ext_register_operand" "%0")
6861 (const_int 8)
6862 (const_int 8))
6863 (zero_extract:SI
d2836273 6864 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
6865 (const_int 8)
6866 (const_int 8))))
6867 (clobber (reg:CC 17))]
6868 ""
0f40f9f7 6869 "add{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
6870 [(set_attr "type" "alu")
6871 (set_attr "mode" "QI")])
886c62d1 6872
886c62d1
JVA
6873;; The patterns that match these are at the end of this file.
6874
4fb21e90
JVA
6875(define_expand "addxf3"
6876 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6877 (plus:XF (match_operand:XF 1 "register_operand" "")
6878 (match_operand:XF 2 "register_operand" "")))]
1b0c37d7 6879 "!TARGET_64BIT && TARGET_80387"
4fb21e90
JVA
6880 "")
6881
2b589241
JH
6882(define_expand "addtf3"
6883 [(set (match_operand:TF 0 "register_operand" "")
6884 (plus:TF (match_operand:TF 1 "register_operand" "")
6885 (match_operand:TF 2 "register_operand" "")))]
6886 "TARGET_80387"
6887 "")
6888
886c62d1
JVA
6889(define_expand "adddf3"
6890 [(set (match_operand:DF 0 "register_operand" "")
06a964de 6891 (plus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6892 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 6893 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
6894 "")
6895
6896(define_expand "addsf3"
6897 [(set (match_operand:SF 0 "register_operand" "")
06a964de 6898 (plus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6899 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 6900 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
6901 "")
6902\f
e075ae69 6903;; Subtract instructions
a269a03c 6904
e075ae69 6905;; %%% splits for subsidi3
2ae0f82c 6906
9b70259d
JH
6907(define_expand "subdi3"
6908 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6909 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6910 (match_operand:DI 2 "x86_64_general_operand" "")))
6911 (clobber (reg:CC 17))])]
6912 ""
6913 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6914
6915(define_insn "*subdi3_1"
e075ae69 6916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4cbfbb1b 6917 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
6918 (match_operand:DI 2 "general_operand" "roiF,riF")))
6919 (clobber (reg:CC 17))]
9b70259d 6920 "!TARGET_64BIT"
e075ae69 6921 "#")
9c530261 6922
e075ae69
RH
6923(define_split
6924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 6925 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69
RH
6926 (match_operand:DI 2 "general_operand" "")))
6927 (clobber (reg:CC 17))]
1b0c37d7 6928 "!TARGET_64BIT && reload_completed"
9dcbdc7e 6929 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
e075ae69
RH
6930 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6931 (parallel [(set (match_dup 3)
6932 (minus:SI (match_dup 4)
9dcbdc7e
JH
6933 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6934 (match_dup 5))))
e075ae69
RH
6935 (clobber (reg:CC 17))])]
6936 "split_di (operands+0, 1, operands+0, operands+3);
6937 split_di (operands+1, 1, operands+1, operands+4);
6938 split_di (operands+2, 1, operands+2, operands+5);")
6939
9b70259d
JH
6940(define_insn "subdi3_carry_rex64"
6941 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6942 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6943 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6944 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6945 (clobber (reg:CC 17))]
1b0c37d7 6946 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6947 "sbb{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6948 [(set_attr "type" "alu")
6949 (set_attr "pent_pair" "pu")
6950 (set_attr "ppro_uops" "few")
6951 (set_attr "mode" "DI")])
6952
6953(define_insn "*subdi_1_rex64"
6954 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6955 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6956 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6957 (clobber (reg:CC 17))]
6958 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6959 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6960 [(set_attr "type" "alu")
6961 (set_attr "mode" "DI")])
6962
6963(define_insn "*subdi_2_rex64"
6964 [(set (reg 17)
6965 (compare
6966 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6967 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6968 (const_int 0)))
6969 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6970 (minus:DI (match_dup 1) (match_dup 2)))]
6971 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6972 && ix86_binary_operator_ok (MINUS, DImode, operands)"
0f40f9f7 6973 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6974 [(set_attr "type" "alu")
6975 (set_attr "mode" "DI")])
6976
6977(define_insn "*subdi_3_rex63"
6978 [(set (reg 17)
6979 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6980 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6981 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6982 (minus:DI (match_dup 1) (match_dup 2)))]
6983 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6984 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6985 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
6986 [(set_attr "type" "alu")
6987 (set_attr "mode" "DI")])
6988
6989
7e08e190 6990(define_insn "subsi3_carry"
e075ae69
RH
6991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6992 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9dcbdc7e
JH
6993 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6994 (match_operand:SI 2 "general_operand" "ri,rm"))))
e075ae69 6995 (clobber (reg:CC 17))]
d525dfdf 6996 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 6997 "sbb{l}\t{%2, %0|%0, %2}"
e075ae69
RH
6998 [(set_attr "type" "alu")
6999 (set_attr "pent_pair" "pu")
6ef67412
JH
7000 (set_attr "ppro_uops" "few")
7001 (set_attr "mode" "SI")])
886c62d1 7002
9b70259d
JH
7003(define_insn "subsi3_carry_zext"
7004 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7005 (zero_extend:DI
7006 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7007 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7008 (match_operand:SI 2 "general_operand" "ri,rm")))))
7009 (clobber (reg:CC 17))]
7010 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7011 "sbb{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7012 [(set_attr "type" "alu")
7013 (set_attr "pent_pair" "pu")
7014 (set_attr "ppro_uops" "few")
7015 (set_attr "mode" "SI")])
7016
2ae0f82c 7017(define_expand "subsi3"
e075ae69
RH
7018 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7019 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7020 (match_operand:SI 2 "general_operand" "")))
7021 (clobber (reg:CC 17))])]
886c62d1 7022 ""
e075ae69 7023 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
2ae0f82c 7024
e075ae69 7025(define_insn "*subsi_1"
2ae0f82c
SC
7026 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7027 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
7028 (match_operand:SI 2 "general_operand" "ri,rm")))
7029 (clobber (reg:CC 17))]
7030 "ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7031 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
7032 [(set_attr "type" "alu")
7033 (set_attr "mode" "SI")])
e075ae69 7034
9b70259d
JH
7035(define_insn "*subsi_1_zext"
7036 [(set (match_operand:DI 0 "register_operand" "=r")
7037 (zero_extend:DI
7038 (minus:SI (match_operand:SI 1 "register_operand" "0")
7039 (match_operand:SI 2 "general_operand" "rim"))))
7040 (clobber (reg:CC 17))]
7041 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7042 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7043 [(set_attr "type" "alu")
7044 (set_attr "mode" "SI")])
7045
e075ae69 7046(define_insn "*subsi_2"
16189740
RH
7047 [(set (reg 17)
7048 (compare
e075ae69
RH
7049 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7050 (match_operand:SI 2 "general_operand" "ri,rm"))
7051 (const_int 0)))
7052 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7053 (minus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 7054 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 7055 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7056 "sub{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
7057 [(set_attr "type" "alu")
7058 (set_attr "mode" "SI")])
7059
9b70259d
JH
7060(define_insn "*subsi_2_zext"
7061 [(set (reg 17)
7062 (compare
7063 (minus:SI (match_operand:SI 1 "register_operand" "0")
7064 (match_operand:SI 2 "general_operand" "rim"))
7065 (const_int 0)))
7066 (set (match_operand:DI 0 "register_operand" "=r")
7067 (zero_extend:DI
7068 (minus:SI (match_dup 1)
7069 (match_dup 2))))]
7070 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7071 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7072 "sub{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7073 [(set_attr "type" "alu")
7074 (set_attr "mode" "SI")])
7075
d90ffc8d
JH
7076(define_insn "*subsi_3"
7077 [(set (reg 17)
7078 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7079 (match_operand:SI 2 "general_operand" "ri,rm")))
7080 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7081 (minus:SI (match_dup 1) (match_dup 2)))]
16189740
RH
7082 "ix86_match_ccmode (insn, CCmode)
7083 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7084 "sub{l}\t{%2, %0|%0, %2}"
6ef67412
JH
7085 [(set_attr "type" "alu")
7086 (set_attr "mode" "SI")])
886c62d1 7087
9b70259d
JH
7088(define_insn "*subsi_3_zext"
7089 [(set (reg 17)
7090 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7091 (match_operand:SI 2 "general_operand" "rim")))
7092 (set (match_operand:DI 0 "register_operand" "=r")
7093 (zero_extend:DI
7094 (minus:SI (match_dup 1)
7095 (match_dup 2))))]
8362f420 7096 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
9b70259d 7097 && ix86_binary_operator_ok (MINUS, SImode, operands)"
0f40f9f7 7098 "sub{q}\t{%2, %0|%0, %2}"
9b70259d
JH
7099 [(set_attr "type" "alu")
7100 (set_attr "mode" "DI")])
7101
2ae0f82c 7102(define_expand "subhi3"
4cbfbb1b 7103 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69
RH
7104 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7105 (match_operand:HI 2 "general_operand" "")))
7106 (clobber (reg:CC 17))])]
d9f32422 7107 "TARGET_HIMODE_MATH"
e075ae69 7108 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
2ae0f82c 7109
e075ae69 7110(define_insn "*subhi_1"
2ae0f82c 7111 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 7112 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
7113 (match_operand:HI 2 "general_operand" "ri,rm")))
7114 (clobber (reg:CC 17))]
2ae0f82c 7115 "ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 7116 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
7117 [(set_attr "type" "alu")
7118 (set_attr "mode" "HI")])
e075ae69
RH
7119
7120(define_insn "*subhi_2"
16189740
RH
7121 [(set (reg 17)
7122 (compare
e075ae69
RH
7123 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7124 (match_operand:HI 2 "general_operand" "ri,rm"))
7125 (const_int 0)))
7126 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7127 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 7128 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 7129 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 7130 "sub{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
7131 [(set_attr "type" "alu")
7132 (set_attr "mode" "HI")])
7133
7134(define_insn "*subhi_3"
7135 [(set (reg 17)
7136 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:HI 2 "general_operand" "ri,rm")))
7138 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7139 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
7140 "ix86_match_ccmode (insn, CCmode)
7141 && ix86_binary_operator_ok (MINUS, HImode, operands)"
0f40f9f7 7142 "sub{w}\t{%2, %0|%0, %2}"
6ef67412
JH
7143 [(set_attr "type" "alu")
7144 (set_attr "mode" "HI")])
886c62d1 7145
2ae0f82c 7146(define_expand "subqi3"
4cbfbb1b
JH
7147 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7148 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69
RH
7149 (match_operand:QI 2 "general_operand" "")))
7150 (clobber (reg:CC 17))])]
d9f32422 7151 "TARGET_QIMODE_MATH"
e075ae69 7152 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
2ae0f82c 7153
e075ae69 7154(define_insn "*subqi_1"
2ae0f82c
SC
7155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7156 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
7157 (match_operand:QI 2 "general_operand" "qn,qmn")))
7158 (clobber (reg:CC 17))]
7159 "ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 7160 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
7161 [(set_attr "type" "alu")
7162 (set_attr "mode" "QI")])
e075ae69
RH
7163
7164(define_insn "*subqi_2"
16189740
RH
7165 [(set (reg 17)
7166 (compare
e075ae69
RH
7167 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7168 (match_operand:QI 2 "general_operand" "qi,qm"))
7169 (const_int 0)))
7170 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7171 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 7172 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d 7173 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 7174 "sub{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
7175 [(set_attr "type" "alu")
7176 (set_attr "mode" "QI")])
7177
7178(define_insn "*subqi_3"
7179 [(set (reg 17)
7180 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7181 (match_operand:QI 2 "general_operand" "qi,qm")))
7182 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7183 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
7184 "ix86_match_ccmode (insn, CCmode)
7185 && ix86_binary_operator_ok (MINUS, QImode, operands)"
0f40f9f7 7186 "sub{b}\t{%2, %0|%0, %2}"
6ef67412
JH
7187 [(set_attr "type" "alu")
7188 (set_attr "mode" "QI")])
2ae0f82c 7189
886c62d1
JVA
7190;; The patterns that match these are at the end of this file.
7191
4fb21e90
JVA
7192(define_expand "subxf3"
7193 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7194 (minus:XF (match_operand:XF 1 "register_operand" "")
7195 (match_operand:XF 2 "register_operand" "")))]
1b0c37d7 7196 "!TARGET_64BIT && TARGET_80387"
4fb21e90
JVA
7197 "")
7198
2b589241
JH
7199(define_expand "subtf3"
7200 [(set (match_operand:TF 0 "register_operand" "")
7201 (minus:TF (match_operand:TF 1 "register_operand" "")
7202 (match_operand:TF 2 "register_operand" "")))]
7203 "TARGET_80387"
7204 "")
7205
886c62d1
JVA
7206(define_expand "subdf3"
7207 [(set (match_operand:DF 0 "register_operand" "")
06a964de 7208 (minus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 7209 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 7210 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
7211 "")
7212
7213(define_expand "subsf3"
7214 [(set (match_operand:SF 0 "register_operand" "")
06a964de 7215 (minus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7216 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 7217 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
7218 "")
7219\f
e075ae69 7220;; Multiply instructions
886c62d1 7221
9b70259d
JH
7222(define_expand "muldi3"
7223 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7224 (mult:DI (match_operand:DI 1 "register_operand" "")
7225 (match_operand:DI 2 "x86_64_general_operand" "")))
7226 (clobber (reg:CC 17))])]
7227 "TARGET_64BIT"
7228 "")
7229
7230(define_insn "*muldi3_1_rex64"
7231 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7232 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7233 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7234 (clobber (reg:CC 17))]
1b0c37d7
ZW
7235 "TARGET_64BIT
7236 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9b70259d 7237 "@
0f40f9f7
ZW
7238 imul{q}\t{%2, %1, %0|%0, %1, %2}
7239 imul{q}\t{%2, %1, %0|%0, %1, %2}
7240 imul{q}\t{%2, %0|%0, %2}"
9b70259d
JH
7241 [(set_attr "type" "imul")
7242 (set_attr "prefix_0f" "0,0,1")
7243 (set_attr "mode" "DI")])
7244
d525dfdf
JH
7245(define_expand "mulsi3"
7246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:SI (match_operand:SI 1 "register_operand" "")
7248 (match_operand:SI 2 "general_operand" "")))
7249 (clobber (reg:CC 17))])]
7250 ""
7251 "")
7252
7253(define_insn "*mulsi3_1"
e075ae69
RH
7254 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7256 (match_operand:SI 2 "general_operand" "K,i,mr")))
7257 (clobber (reg:CC 17))]
d525dfdf 7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
20819a09
MM
7259 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7260 ; there are two ways of writing the exact same machine instruction
7261 ; in assembly language. One, for example, is:
7262 ;
7263 ; imul $12, %eax
7264 ;
7265 ; while the other is:
7266 ;
7267 ; imul $12, %eax, %eax
7268 ;
7269 ; The first is simply short-hand for the latter. But, some assemblers,
7270 ; like the SCO OSR5 COFF assembler, don't handle the first form.
e075ae69 7271 "@
0f40f9f7
ZW
7272 imul{l}\t{%2, %1, %0|%0, %1, %2}
7273 imul{l}\t{%2, %1, %0|%0, %1, %2}
7274 imul{l}\t{%2, %0|%0, %2}"
e075ae69 7275 [(set_attr "type" "imul")
6ef67412
JH
7276 (set_attr "prefix_0f" "0,0,1")
7277 (set_attr "mode" "SI")])
886c62d1 7278
9b70259d
JH
7279(define_insn "*mulsi3_1_zext"
7280 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7281 (zero_extend:DI
7282 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7283 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7284 (clobber (reg:CC 17))]
7285 "TARGET_64BIT
7286 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7288 ; there are two ways of writing the exact same machine instruction
7289 ; in assembly language. One, for example, is:
7290 ;
7291 ; imul $12, %eax
7292 ;
7293 ; while the other is:
7294 ;
7295 ; imul $12, %eax, %eax
7296 ;
7297 ; The first is simply short-hand for the latter. But, some assemblers,
7298 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7299 "@
0f40f9f7
ZW
7300 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7301 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7302 imul{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
7303 [(set_attr "type" "imul")
7304 (set_attr "prefix_0f" "0,0,1")
7305 (set_attr "mode" "SI")])
7306
d525dfdf
JH
7307(define_expand "mulhi3"
7308 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7309 (mult:HI (match_operand:HI 1 "register_operand" "")
7310 (match_operand:HI 2 "general_operand" "")))
7311 (clobber (reg:CC 17))])]
d9f32422 7312 "TARGET_HIMODE_MATH"
d525dfdf
JH
7313 "")
7314
7315(define_insn "*mulhi3_1"
6ef67412
JH
7316 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7317 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7318 (match_operand:HI 2 "general_operand" "K,i,mr")))
e075ae69 7319 (clobber (reg:CC 17))]
d525dfdf 7320 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69
RH
7321 ; %%% There was a note about "Assembler has weird restrictions",
7322 ; concerning alternative 1 when op1 == op0. True?
7323 "@
0f40f9f7
ZW
7324 imul{w}\t{%2, %1, %0|%0, %1, %2}
7325 imul{w}\t{%2, %1, %0|%0, %1, %2}
7326 imul{w}\t{%2, %0|%0, %2}"
6ef67412
JH
7327 [(set_attr "type" "imul")
7328 (set_attr "prefix_0f" "0,0,1")
7329 (set_attr "mode" "HI")])
886c62d1 7330
765a46f9
JH
7331(define_insn "mulqi3"
7332 [(set (match_operand:QI 0 "register_operand" "=a")
7333 (mult:QI (match_operand:QI 1 "register_operand" "%0")
7334 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7335 (clobber (reg:CC 17))]
d9f32422 7336 "TARGET_QIMODE_MATH"
0f40f9f7 7337 "mul{b}\t%2"
6ef67412
JH
7338 [(set_attr "type" "imul")
7339 (set_attr "length_immediate" "0")
7340 (set_attr "mode" "QI")])
765a46f9 7341
4b71cd6e 7342(define_insn "umulqihi3"
2ae0f82c
SC
7343 [(set (match_operand:HI 0 "register_operand" "=a")
7344 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
e075ae69
RH
7345 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7346 (clobber (reg:CC 17))]
d9f32422 7347 "TARGET_QIMODE_MATH"
0f40f9f7 7348 "mul{b}\t%2"
6ef67412
JH
7349 [(set_attr "type" "imul")
7350 (set_attr "length_immediate" "0")
7351 (set_attr "mode" "QI")])
886c62d1 7352
4b71cd6e 7353(define_insn "mulqihi3"
2ae0f82c
SC
7354 [(set (match_operand:HI 0 "register_operand" "=a")
7355 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
e075ae69
RH
7356 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7357 (clobber (reg:CC 17))]
d9f32422 7358 "TARGET_QIMODE_MATH"
0f40f9f7 7359 "imul{b}\t%2"
6ef67412
JH
7360 [(set_attr "type" "imul")
7361 (set_attr "length_immediate" "0")
7362 (set_attr "mode" "QI")])
4b71cd6e 7363
9b70259d
JH
7364(define_insn "umulditi3"
7365 [(set (match_operand:TI 0 "register_operand" "=A")
7366 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7367 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
1e07edd3 7368 (clobber (reg:CC 17))]
9b70259d 7369 "TARGET_64BIT"
0f40f9f7 7370 "mul{q}\t%2"
1e07edd3
JH
7371 [(set_attr "type" "imul")
7372 (set_attr "ppro_uops" "few")
7373 (set_attr "length_immediate" "0")
9b70259d 7374 (set_attr "mode" "DI")])
1e07edd3
JH
7375
7376;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
4b71cd6e
MM
7377(define_insn "umulsidi3"
7378 [(set (match_operand:DI 0 "register_operand" "=A")
7379 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
e075ae69
RH
7380 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7381 (clobber (reg:CC 17))]
1e07edd3 7382 "!TARGET_64BIT"
0f40f9f7 7383 "mul{l}\t%2"
e075ae69 7384 [(set_attr "type" "imul")
6ef67412
JH
7385 (set_attr "ppro_uops" "few")
7386 (set_attr "length_immediate" "0")
7387 (set_attr "mode" "SI")])
4b71cd6e 7388
9b70259d
JH
7389(define_insn "mulditi3"
7390 [(set (match_operand:TI 0 "register_operand" "=A")
7391 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7392 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7393 (clobber (reg:CC 17))]
7394 "TARGET_64BIT"
0f40f9f7 7395 "imul{q}\t%2"
9b70259d
JH
7396 [(set_attr "type" "imul")
7397 (set_attr "length_immediate" "0")
7398 (set_attr "mode" "DI")])
7399
4b71cd6e
MM
7400(define_insn "mulsidi3"
7401 [(set (match_operand:DI 0 "register_operand" "=A")
7402 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
e075ae69
RH
7403 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7404 (clobber (reg:CC 17))]
1e07edd3 7405 "!TARGET_64BIT"
0f40f9f7 7406 "imul{l}\t%2"
6ef67412
JH
7407 [(set_attr "type" "imul")
7408 (set_attr "length_immediate" "0")
7409 (set_attr "mode" "SI")])
2f2a49e8 7410
9b70259d
JH
7411(define_insn "*umuldi3_highpart_rex64"
7412 [(set (match_operand:DI 0 "register_operand" "=d")
7413 (truncate:DI
7414 (lshiftrt:TI
7415 (mult:TI (zero_extend:TI
7416 (match_operand:DI 1 "register_operand" "%a"))
7417 (zero_extend:TI
7418 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7419 (const_int 64))))
7420 (clobber (match_scratch:DI 3 "=a"))
7421 (clobber (reg:CC 17))]
7422 "TARGET_64BIT"
0f40f9f7 7423 "mul{q}\t%2"
9b70259d
JH
7424 [(set_attr "type" "imul")
7425 (set_attr "ppro_uops" "few")
7426 (set_attr "length_immediate" "0")
7427 (set_attr "mode" "DI")])
7428
34c659e2 7429(define_insn "umulsi3_highpart"
2f2a49e8 7430 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7431 (truncate:SI
7432 (lshiftrt:DI
7433 (mult:DI (zero_extend:DI
7434 (match_operand:SI 1 "register_operand" "%a"))
7435 (zero_extend:DI
7436 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7437 (const_int 32))))
7438 (clobber (match_scratch:SI 3 "=a"))
7439 (clobber (reg:CC 17))]
32ee7d1d 7440 ""
0f40f9f7 7441 "mul{l}\t%2"
32ee7d1d
JH
7442 [(set_attr "type" "imul")
7443 (set_attr "ppro_uops" "few")
7444 (set_attr "length_immediate" "0")
7445 (set_attr "mode" "SI")])
7446
7447(define_insn "*umulsi3_highpart_zext"
7448 [(set (match_operand:DI 0 "register_operand" "=d")
7449 (zero_extend:DI (truncate:SI
7450 (lshiftrt:DI
7451 (mult:DI (zero_extend:DI
7452 (match_operand:SI 1 "register_operand" "%a"))
7453 (zero_extend:DI
7454 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7455 (const_int 32)))))
7456 (clobber (match_scratch:SI 3 "=a"))
7457 (clobber (reg:CC 17))]
7458 "TARGET_64BIT"
0f40f9f7 7459 "mul{l}\t%2"
e075ae69 7460 [(set_attr "type" "imul")
6ef67412
JH
7461 (set_attr "ppro_uops" "few")
7462 (set_attr "length_immediate" "0")
7463 (set_attr "mode" "SI")])
2f2a49e8 7464
9b70259d
JH
7465(define_insn "*smuldi3_highpart_rex64"
7466 [(set (match_operand:DI 0 "register_operand" "=d")
7467 (truncate:DI
7468 (lshiftrt:TI
7469 (mult:TI (sign_extend:TI
7470 (match_operand:DI 1 "register_operand" "%a"))
7471 (sign_extend:TI
7472 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473 (const_int 64))))
7474 (clobber (match_scratch:DI 3 "=a"))
7475 (clobber (reg:CC 17))]
7476 "TARGET_64BIT"
0f40f9f7 7477 "imul{q}\t%2"
9b70259d
JH
7478 [(set_attr "type" "imul")
7479 (set_attr "ppro_uops" "few")
7480 (set_attr "mode" "DI")])
7481
34c659e2 7482(define_insn "smulsi3_highpart"
2f2a49e8 7483 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
7484 (truncate:SI
7485 (lshiftrt:DI
7486 (mult:DI (sign_extend:DI
7487 (match_operand:SI 1 "register_operand" "%a"))
7488 (sign_extend:DI
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (const_int 32))))
7491 (clobber (match_scratch:SI 3 "=a"))
7492 (clobber (reg:CC 17))]
7493 ""
0f40f9f7 7494 "imul{l}\t%2"
e075ae69 7495 [(set_attr "type" "imul")
6ef67412
JH
7496 (set_attr "ppro_uops" "few")
7497 (set_attr "mode" "SI")])
4b71cd6e 7498
9b70259d
JH
7499(define_insn "*smulsi3_highpart_zext"
7500 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (zero_extend:DI (truncate:SI
7502 (lshiftrt:DI
7503 (mult:DI (sign_extend:DI
7504 (match_operand:SI 1 "register_operand" "%a"))
7505 (sign_extend:DI
7506 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7507 (const_int 32)))))
7508 (clobber (match_scratch:SI 3 "=a"))
7509 (clobber (reg:CC 17))]
7510 "TARGET_64BIT"
0f40f9f7 7511 "imul{l}\t%2"
9b70259d
JH
7512 [(set_attr "type" "imul")
7513 (set_attr "ppro_uops" "few")
7514 (set_attr "mode" "SI")])
7515
886c62d1
JVA
7516;; The patterns that match these are at the end of this file.
7517
4fb21e90
JVA
7518(define_expand "mulxf3"
7519 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7520 (mult:XF (match_operand:XF 1 "register_operand" "")
7521 (match_operand:XF 2 "register_operand" "")))]
1b0c37d7 7522 "!TARGET_64BIT && TARGET_80387"
4fb21e90
JVA
7523 "")
7524
2b589241
JH
7525(define_expand "multf3"
7526 [(set (match_operand:TF 0 "register_operand" "")
7527 (mult:TF (match_operand:TF 1 "register_operand" "")
7528 (match_operand:TF 2 "register_operand" "")))]
7529 "TARGET_80387"
7530 "")
7531
886c62d1
JVA
7532(define_expand "muldf3"
7533 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 7534 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1 7535 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 7536 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
7537 "")
7538
7539(define_expand "mulsf3"
7540 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7541 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7542 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 7543 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
7544 "")
7545\f
e075ae69 7546;; Divide instructions
886c62d1
JVA
7547
7548(define_insn "divqi3"
2ae0f82c
SC
7549 [(set (match_operand:QI 0 "register_operand" "=a")
7550 (div:QI (match_operand:HI 1 "register_operand" "0")
e075ae69
RH
7551 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7552 (clobber (reg:CC 17))]
d9f32422 7553 "TARGET_QIMODE_MATH"
0f40f9f7 7554 "idiv{b}\t%2"
e075ae69 7555 [(set_attr "type" "idiv")
6ef67412 7556 (set_attr "mode" "QI")
e075ae69 7557 (set_attr "ppro_uops" "few")])
886c62d1
JVA
7558
7559(define_insn "udivqi3"
2ae0f82c
SC
7560 [(set (match_operand:QI 0 "register_operand" "=a")
7561 (udiv:QI (match_operand:HI 1 "register_operand" "0")
e075ae69
RH
7562 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7563 (clobber (reg:CC 17))]
d9f32422 7564 "TARGET_QIMODE_MATH"
0f40f9f7 7565 "div{b}\t%2"
e075ae69 7566 [(set_attr "type" "idiv")
6ef67412 7567 (set_attr "mode" "QI")
e075ae69 7568 (set_attr "ppro_uops" "few")])
886c62d1
JVA
7569
7570;; The patterns that match these are at the end of this file.
7571
4fb21e90
JVA
7572(define_expand "divxf3"
7573 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
7574 (div:XF (match_operand:XF 1 "register_operand" "")
7575 (match_operand:XF 2 "register_operand" "")))]
1b0c37d7 7576 "!TARGET_64BIT && TARGET_80387"
886c62d1
JVA
7577 "")
7578
2b589241
JH
7579(define_expand "divtf3"
7580 [(set (match_operand:TF 0 "register_operand" "")
7581 (div:TF (match_operand:TF 1 "register_operand" "")
7582 (match_operand:TF 2 "register_operand" "")))]
7583 "TARGET_80387"
7584 "")
7585
a78cb986
SC
7586(define_expand "divdf3"
7587 [(set (match_operand:DF 0 "register_operand" "")
7588 (div:DF (match_operand:DF 1 "register_operand" "")
7589 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 7590 "TARGET_80387 || TARGET_SSE2"
a78cb986
SC
7591 "")
7592
886c62d1
JVA
7593(define_expand "divsf3"
7594 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 7595 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 7596 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 7597 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
7598 "")
7599\f
7600;; Remainder instructions.
9b70259d
JH
7601
7602(define_expand "divmoddi4"
7603 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7604 (div:DI (match_operand:DI 1 "register_operand" "")
7605 (match_operand:DI 2 "nonimmediate_operand" "")))
7606 (set (match_operand:DI 3 "register_operand" "")
7607 (mod:DI (match_dup 1) (match_dup 2)))
7608 (clobber (reg:CC 17))])]
7609 "TARGET_64BIT"
7610 "")
7611
7612;; Allow to come the parameter in eax or edx to avoid extra moves.
7613;; Penalize eax case sligthly because it results in worse scheduling
7614;; of code.
7615(define_insn "*divmoddi4_nocltd_rex64"
7616 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7617 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7618 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7619 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7620 (mod:DI (match_dup 2) (match_dup 3)))
7621 (clobber (reg:CC 17))]
7622 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7623 "#"
7624 [(set_attr "type" "multi")])
7625
7626(define_insn "*divmoddi4_cltd_rex64"
7627 [(set (match_operand:DI 0 "register_operand" "=a")
7628 (div:DI (match_operand:DI 2 "register_operand" "a")
7629 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7630 (set (match_operand:DI 1 "register_operand" "=&d")
7631 (mod:DI (match_dup 2) (match_dup 3)))
7632 (clobber (reg:CC 17))]
7633 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7634 "#"
7635 [(set_attr "type" "multi")])
7636
7637(define_insn "*divmoddi_noext_rex64"
7638 [(set (match_operand:DI 0 "register_operand" "=a")
7639 (div:DI (match_operand:DI 1 "register_operand" "0")
7640 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7641 (set (match_operand:DI 3 "register_operand" "=d")
7642 (mod:DI (match_dup 1) (match_dup 2)))
7643 (use (match_operand:DI 4 "register_operand" "3"))
7644 (clobber (reg:CC 17))]
7645 "TARGET_64BIT"
0f40f9f7 7646 "idiv{q}\t%2"
9b70259d
JH
7647 [(set_attr "type" "idiv")
7648 (set_attr "mode" "DI")
7649 (set_attr "ppro_uops" "few")])
7650
7651(define_split
7652 [(set (match_operand:DI 0 "register_operand" "")
7653 (div:DI (match_operand:DI 1 "register_operand" "")
7654 (match_operand:DI 2 "nonimmediate_operand" "")))
7655 (set (match_operand:DI 3 "register_operand" "")
7656 (mod:DI (match_dup 1) (match_dup 2)))
7657 (clobber (reg:CC 17))]
7658 "TARGET_64BIT && reload_completed"
7659 [(parallel [(set (match_dup 3)
7660 (ashiftrt:DI (match_dup 4) (const_int 63)))
7661 (clobber (reg:CC 17))])
7662 (parallel [(set (match_dup 0)
7663 (div:DI (reg:DI 0) (match_dup 2)))
7664 (set (match_dup 3)
7665 (mod:DI (reg:DI 0) (match_dup 2)))
7666 (use (match_dup 3))
7667 (clobber (reg:CC 17))])]
9b70259d
JH
7668{
7669 /* Avoid use of cltd in favour of a mov+shift. */
7670 if (!TARGET_USE_CLTD && !optimize_size)
7671 {
7672 if (true_regnum (operands[1]))
7673 emit_move_insn (operands[0], operands[1]);
7674 else
7675 emit_move_insn (operands[3], operands[1]);
7676 operands[4] = operands[3];
7677 }
7678 else
7679 {
7680 if (true_regnum (operands[1]))
7681 abort();
7682 operands[4] = operands[1];
7683 }
0f40f9f7 7684})
9b70259d
JH
7685
7686
40745eec
JH
7687(define_expand "divmodsi4"
7688 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7689 (div:SI (match_operand:SI 1 "register_operand" "")
7690 (match_operand:SI 2 "nonimmediate_operand" "")))
7691 (set (match_operand:SI 3 "register_operand" "")
7692 (mod:SI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC 17))])]
7694 ""
7695 "")
7696
7697;; Allow to come the parameter in eax or edx to avoid extra moves.
7698;; Penalize eax case sligthly because it results in worse scheduling
7699;; of code.
7700(define_insn "*divmodsi4_nocltd"
7701 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7702 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7703 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7704 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7705 (mod:SI (match_dup 2) (match_dup 3)))
7706 (clobber (reg:CC 17))]
7707 "!optimize_size && !TARGET_USE_CLTD"
7708 "#"
7709 [(set_attr "type" "multi")])
886c62d1 7710
40745eec 7711(define_insn "*divmodsi4_cltd"
2bb7a0f5 7712 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec
JH
7713 (div:SI (match_operand:SI 2 "register_operand" "a")
7714 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7715 (set (match_operand:SI 1 "register_operand" "=&d")
7716 (mod:SI (match_dup 2) (match_dup 3)))
e075ae69 7717 (clobber (reg:CC 17))]
40745eec
JH
7718 "optimize_size || TARGET_USE_CLTD"
7719 "#"
e075ae69
RH
7720 [(set_attr "type" "multi")])
7721
6343a50e 7722(define_insn "*divmodsi_noext"
e075ae69 7723 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec 7724 (div:SI (match_operand:SI 1 "register_operand" "0")
e075ae69
RH
7725 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7726 (set (match_operand:SI 3 "register_operand" "=d")
7727 (mod:SI (match_dup 1) (match_dup 2)))
40745eec 7728 (use (match_operand:SI 4 "register_operand" "3"))
e075ae69
RH
7729 (clobber (reg:CC 17))]
7730 ""
0f40f9f7 7731 "idiv{l}\t%2"
e075ae69 7732 [(set_attr "type" "idiv")
6ef67412 7733 (set_attr "mode" "SI")
e075ae69
RH
7734 (set_attr "ppro_uops" "few")])
7735
7736(define_split
7737 [(set (match_operand:SI 0 "register_operand" "")
7738 (div:SI (match_operand:SI 1 "register_operand" "")
7739 (match_operand:SI 2 "nonimmediate_operand" "")))
7740 (set (match_operand:SI 3 "register_operand" "")
7741 (mod:SI (match_dup 1) (match_dup 2)))
7742 (clobber (reg:CC 17))]
7743 "reload_completed"
7744 [(parallel [(set (match_dup 3)
7745 (ashiftrt:SI (match_dup 4) (const_int 31)))
7746 (clobber (reg:CC 17))])
7747 (parallel [(set (match_dup 0)
40745eec 7748 (div:SI (reg:SI 0) (match_dup 2)))
e075ae69 7749 (set (match_dup 3)
40745eec 7750 (mod:SI (reg:SI 0) (match_dup 2)))
e075ae69
RH
7751 (use (match_dup 3))
7752 (clobber (reg:CC 17))])]
886c62d1 7753{
e075ae69 7754 /* Avoid use of cltd in favour of a mov+shift. */
40745eec 7755 if (!TARGET_USE_CLTD && !optimize_size)
e075ae69 7756 {
40745eec
JH
7757 if (true_regnum (operands[1]))
7758 emit_move_insn (operands[0], operands[1]);
7759 else
7760 emit_move_insn (operands[3], operands[1]);
e075ae69
RH
7761 operands[4] = operands[3];
7762 }
7763 else
40745eec
JH
7764 {
7765 if (true_regnum (operands[1]))
7766 abort();
7767 operands[4] = operands[1];
7768 }
0f40f9f7 7769})
e075ae69 7770;; %%% Split me.
886c62d1 7771(define_insn "divmodhi4"
2bb7a0f5
RS
7772 [(set (match_operand:HI 0 "register_operand" "=a")
7773 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 7774 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7775 (set (match_operand:HI 3 "register_operand" "=&d")
e075ae69
RH
7776 (mod:HI (match_dup 1) (match_dup 2)))
7777 (clobber (reg:CC 17))]
d9f32422 7778 "TARGET_HIMODE_MATH"
0f40f9f7 7779 "cwtd\;idiv{w}\t%2"
6ef67412
JH
7780 [(set_attr "type" "multi")
7781 (set_attr "length_immediate" "0")
7782 (set_attr "mode" "SI")])
886c62d1 7783
9b70259d
JH
7784(define_insn "udivmoddi4"
7785 [(set (match_operand:DI 0 "register_operand" "=a")
7786 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7787 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7788 (set (match_operand:DI 3 "register_operand" "=&d")
7789 (umod:DI (match_dup 1) (match_dup 2)))
7790 (clobber (reg:CC 17))]
7791 "TARGET_64BIT"
0f40f9f7 7792 "xor{q}\t%3, %3\;div{q}\t%2"
9b70259d
JH
7793 [(set_attr "type" "multi")
7794 (set_attr "length_immediate" "0")
7795 (set_attr "mode" "DI")])
7796
7797(define_insn "*udivmoddi4_noext"
7798 [(set (match_operand:DI 0 "register_operand" "=a")
7799 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7800 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7801 (set (match_operand:DI 3 "register_operand" "=d")
7802 (umod:DI (match_dup 1) (match_dup 2)))
7803 (use (match_dup 3))
7804 (clobber (reg:CC 17))]
7805 "TARGET_64BIT"
0f40f9f7 7806 "div{q}\t%2"
9b70259d
JH
7807 [(set_attr "type" "idiv")
7808 (set_attr "ppro_uops" "few")
7809 (set_attr "mode" "DI")])
7810
7811(define_split
7812 [(set (match_operand:DI 0 "register_operand" "")
7813 (udiv:DI (match_operand:DI 1 "register_operand" "")
7814 (match_operand:DI 2 "nonimmediate_operand" "")))
7815 (set (match_operand:DI 3 "register_operand" "")
7816 (umod:DI (match_dup 1) (match_dup 2)))
7817 (clobber (reg:CC 17))]
1b0c37d7 7818 "TARGET_64BIT && reload_completed"
9b70259d
JH
7819 [(set (match_dup 3) (const_int 0))
7820 (parallel [(set (match_dup 0)
7821 (udiv:DI (match_dup 1) (match_dup 2)))
7822 (set (match_dup 3)
7823 (umod:DI (match_dup 1) (match_dup 2)))
7824 (use (match_dup 3))
7825 (clobber (reg:CC 17))])]
7826 "")
7827
886c62d1 7828(define_insn "udivmodsi4"
2bb7a0f5
RS
7829 [(set (match_operand:SI 0 "register_operand" "=a")
7830 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7831 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7832 (set (match_operand:SI 3 "register_operand" "=&d")
e075ae69
RH
7833 (umod:SI (match_dup 1) (match_dup 2)))
7834 (clobber (reg:CC 17))]
886c62d1 7835 ""
0f40f9f7 7836 "xor{l}\t%3, %3\;div{l}\t%2"
6ef67412
JH
7837 [(set_attr "type" "multi")
7838 (set_attr "length_immediate" "0")
7839 (set_attr "mode" "SI")])
886c62d1 7840
6343a50e 7841(define_insn "*udivmodsi4_noext"
2bb7a0f5 7842 [(set (match_operand:SI 0 "register_operand" "=a")
e075ae69 7843 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 7844 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 7845 (set (match_operand:SI 3 "register_operand" "=d")
e075ae69
RH
7846 (umod:SI (match_dup 1) (match_dup 2)))
7847 (use (match_dup 3))
7848 (clobber (reg:CC 17))]
886c62d1 7849 ""
0f40f9f7 7850 "div{l}\t%2"
e075ae69 7851 [(set_attr "type" "idiv")
6ef67412
JH
7852 (set_attr "ppro_uops" "few")
7853 (set_attr "mode" "SI")])
886c62d1 7854
e075ae69
RH
7855(define_split
7856 [(set (match_operand:SI 0 "register_operand" "")
7857 (udiv:SI (match_operand:SI 1 "register_operand" "")
7858 (match_operand:SI 2 "nonimmediate_operand" "")))
7859 (set (match_operand:SI 3 "register_operand" "")
7860 (umod:SI (match_dup 1) (match_dup 2)))
7861 (clobber (reg:CC 17))]
7862 "reload_completed"
591702de 7863 [(set (match_dup 3) (const_int 0))
e075ae69
RH
7864 (parallel [(set (match_dup 0)
7865 (udiv:SI (match_dup 1) (match_dup 2)))
7866 (set (match_dup 3)
7867 (umod:SI (match_dup 1) (match_dup 2)))
7868 (use (match_dup 3))
7869 (clobber (reg:CC 17))])]
7870 "")
886c62d1 7871
e075ae69 7872(define_expand "udivmodhi4"
591702de 7873 [(set (match_dup 4) (const_int 0))
40745eec
JH
7874 (parallel [(set (match_operand:HI 0 "register_operand" "")
7875 (udiv:HI (match_operand:HI 1 "register_operand" "")
7876 (match_operand:HI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:HI 3 "register_operand" "")
e075ae69
RH
7878 (umod:HI (match_dup 1) (match_dup 2)))
7879 (use (match_dup 4))
7880 (clobber (reg:CC 17))])]
d9f32422 7881 "TARGET_HIMODE_MATH"
e075ae69 7882 "operands[4] = gen_reg_rtx (HImode);")
886c62d1 7883
6343a50e 7884(define_insn "*udivmodhi_noext"
e075ae69
RH
7885 [(set (match_operand:HI 0 "register_operand" "=a")
7886 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7887 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7888 (set (match_operand:HI 3 "register_operand" "=d")
7889 (umod:HI (match_dup 1) (match_dup 2)))
7890 (use (match_operand:HI 4 "register_operand" "3"))
7891 (clobber (reg:CC 17))]
7892 ""
0f40f9f7 7893 "div{w}\t%2"
e075ae69 7894 [(set_attr "type" "idiv")
6ef67412 7895 (set_attr "mode" "HI")
e075ae69
RH
7896 (set_attr "ppro_uops" "few")])
7897
7898;; We can not use div/idiv for double division, because it causes
7899;; "division by zero" on the overflow and that's not what we expect
7900;; from truncate. Because true (non truncating) double division is
7901;; never generated, we can't create this insn anyway.
7902;
7903;(define_insn ""
7904; [(set (match_operand:SI 0 "register_operand" "=a")
7905; (truncate:SI
7906; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7907; (zero_extend:DI
7908; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7909; (set (match_operand:SI 3 "register_operand" "=d")
7910; (truncate:SI
7911; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7912; (clobber (reg:CC 17))]
7913; ""
0f40f9f7 7914; "div{l}\t{%2, %0|%0, %2}"
e075ae69
RH
7915; [(set_attr "type" "idiv")
7916; (set_attr "ppro_uops" "few")])
886c62d1 7917\f
e075ae69
RH
7918;;- Logical AND instructions
7919
7920;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7921;; Note that this excludes ah.
7922
9b70259d
JH
7923(define_insn "*testdi_1_rex64"
7924 [(set (reg 17)
7925 (compare
7926 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7927 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7928 (const_int 0)))]
7929 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7930 "@
0f40f9f7
ZW
7931 test{l}\t{%k1, %k0|%k0, %k1}
7932 test{l}\t{%k1, %k0|%k0, %k1}
7933 test{q}\t{%1, %0|%0, %1}
7934 test{q}\t{%1, %0|%0, %1}
7935 test{q}\t{%1, %0|%0, %1}"
9b70259d
JH
7936 [(set_attr "type" "test")
7937 (set_attr "modrm" "0,1,0,1,1")
7938 (set_attr "mode" "SI,SI,DI,DI,DI")
7939 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9076b9c1
JH
7940
7941(define_insn "testsi_1"
7942 [(set (reg 17)
7943 (compare
16189740
RH
7944 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7945 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7946 (const_int 0)))]
9076b9c1 7947 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7948 "test{l}\t{%1, %0|%0, %1}"
6ef67412
JH
7949 [(set_attr "type" "test")
7950 (set_attr "modrm" "0,1,1")
7951 (set_attr "mode" "SI")
e075ae69
RH
7952 (set_attr "pent_pair" "uv,np,uv")])
7953
9076b9c1 7954(define_expand "testsi_ccno_1"
e075ae69 7955 [(set (reg:CCNO 17)
16189740 7956 (compare:CCNO
9076b9c1
JH
7957 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7958 (match_operand:SI 1 "nonmemory_operand" ""))
16189740 7959 (const_int 0)))]
a1cbdd7f 7960 ""
9076b9c1 7961 "")
16189740
RH
7962
7963(define_insn "*testhi_1"
7964 [(set (reg 17)
7965 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7966 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7967 (const_int 0)))]
7968 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 7969 "test{w}\t{%1, %0|%0, %1}"
6ef67412
JH
7970 [(set_attr "type" "test")
7971 (set_attr "modrm" "0,1,1")
7972 (set_attr "mode" "HI")
e075ae69
RH
7973 (set_attr "pent_pair" "uv,np,uv")])
7974
9076b9c1 7975(define_expand "testqi_ccz_1"
16189740 7976 [(set (reg:CCZ 17)
9076b9c1
JH
7977 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7978 (match_operand:QI 1 "nonmemory_operand" ""))
7979 (const_int 0)))]
16189740 7980 ""
9076b9c1 7981 "")
16189740 7982
9076b9c1
JH
7983(define_insn "*testqi_1"
7984 [(set (reg 17)
7985 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7986 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7987 (const_int 0)))]
7988 "ix86_match_ccmode (insn, CCNOmode)"
adc88131
JJ
7989{
7990 if (which_alternative == 3)
7991 {
7992 if (GET_CODE (operands[1]) == CONST_INT
7993 && (INTVAL (operands[1]) & 0xffffff00))
7994 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
0f40f9f7 7995 return "test{l}\t{%1, %k0|%k0, %1}";
adc88131 7996 }
0f40f9f7
ZW
7997 return "test{b}\t{%1, %0|%0, %1}";
7998}
6ef67412
JH
7999 [(set_attr "type" "test")
8000 (set_attr "modrm" "0,1,1,1")
8001 (set_attr "mode" "QI,QI,QI,SI")
8002 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 8003
9076b9c1
JH
8004(define_expand "testqi_ext_ccno_0"
8005 [(set (reg:CCNO 17)
8006 (compare:CCNO
16189740
RH
8007 (and:SI
8008 (zero_extract:SI
9076b9c1 8009 (match_operand 0 "ext_register_operand" "")
16189740
RH
8010 (const_int 8)
8011 (const_int 8))
9076b9c1 8012 (match_operand 1 "const_int_operand" ""))
16189740 8013 (const_int 0)))]
9076b9c1
JH
8014 ""
8015 "")
e075ae69 8016
9076b9c1
JH
8017(define_insn "*testqi_ext_0"
8018 [(set (reg 17)
8019 (compare
e075ae69
RH
8020 (and:SI
8021 (zero_extract:SI
d2836273 8022 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
8023 (const_int 8)
8024 (const_int 8))
8025 (match_operand 1 "const_int_operand" "n"))
8026 (const_int 0)))]
9076b9c1
JH
8027 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8028 && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8029 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
8030 [(set_attr "type" "test")
8031 (set_attr "mode" "QI")
8032 (set_attr "length_immediate" "1")
e075ae69
RH
8033 (set_attr "pent_pair" "np")])
8034
8035(define_insn "*testqi_ext_1"
16189740
RH
8036 [(set (reg 17)
8037 (compare
e075ae69
RH
8038 (and:SI
8039 (zero_extract:SI
d2836273 8040 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
8041 (const_int 8)
8042 (const_int 8))
8043 (zero_extend:SI
d2836273 8044 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
e075ae69 8045 (const_int 0)))]
d2836273 8046 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8047 "test{b}\t{%1, %h0|%h0, %1}"
d2836273
JH
8048 [(set_attr "type" "test")
8049 (set_attr "mode" "QI")])
8050
8051(define_insn "*testqi_ext_1_rex64"
8052 [(set (reg 17)
8053 (compare
8054 (and:SI
8055 (zero_extract:SI
8056 (match_operand 0 "ext_register_operand" "Q")
8057 (const_int 8)
8058 (const_int 8))
8059 (zero_extend:SI
3522082b 8060 (match_operand:QI 1 "register_operand" "Q")))
d2836273
JH
8061 (const_int 0)))]
8062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8063 "test{b}\t{%1, %h0|%h0, %1}"
6ef67412
JH
8064 [(set_attr "type" "test")
8065 (set_attr "mode" "QI")])
e075ae69
RH
8066
8067(define_insn "*testqi_ext_2"
16189740
RH
8068 [(set (reg 17)
8069 (compare
e075ae69
RH
8070 (and:SI
8071 (zero_extract:SI
d2836273 8072 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
8073 (const_int 8)
8074 (const_int 8))
8075 (zero_extract:SI
d2836273 8076 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
8077 (const_int 8)
8078 (const_int 8)))
8079 (const_int 0)))]
16189740 8080 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8081 "test{b}\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
8082 [(set_attr "type" "test")
8083 (set_attr "mode" "QI")])
e075ae69
RH
8084
8085;; Combine likes to form bit extractions for some tests. Humor it.
6343a50e 8086(define_insn "*testqi_ext_3"
16189740
RH
8087 [(set (reg 17)
8088 (compare (zero_extract:SI
8089 (match_operand 0 "nonimmediate_operand" "rm")
8090 (match_operand:SI 1 "const_int_operand" "")
8091 (match_operand:SI 2 "const_int_operand" ""))
8092 (const_int 0)))]
8093 "ix86_match_ccmode (insn, CCNOmode)
8094 && (GET_MODE (operands[0]) == SImode
9b70259d
JH
8095 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8096 || GET_MODE (operands[0]) == HImode
8097 || GET_MODE (operands[0]) == QImode)"
8098 "#")
8099
8100(define_insn "*testqi_ext_3_rex64"
8101 [(set (reg 17)
8102 (compare (zero_extract:DI
8103 (match_operand 0 "nonimmediate_operand" "rm")
8104 (match_operand:DI 1 "const_int_operand" "")
8105 (match_operand:DI 2 "const_int_operand" ""))
8106 (const_int 0)))]
1b0c37d7
ZW
8107 "TARGET_64BIT
8108 && ix86_match_ccmode (insn, CCNOmode)
9b70259d
JH
8109 && (GET_MODE (operands[0]) == SImode
8110 || GET_MODE (operands[0]) == DImode
16189740
RH
8111 || GET_MODE (operands[0]) == HImode
8112 || GET_MODE (operands[0]) == QImode)"
e075ae69 8113 "#")
4fce8e83 8114
e075ae69 8115(define_split
16189740 8116 [(set (reg 17)
9b70259d 8117 (compare (zero_extract
d5d6a58b 8118 (match_operand 0 "nonimmediate_operand" "")
9b70259d
JH
8119 (match_operand 1 "const_int_operand" "")
8120 (match_operand 2 "const_int_operand" ""))
16189740
RH
8121 (const_int 0)))]
8122 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 8123 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
e075ae69
RH
8124{
8125 HOST_WIDE_INT len = INTVAL (operands[1]);
8126 HOST_WIDE_INT pos = INTVAL (operands[2]);
8127 HOST_WIDE_INT mask;
8128 enum machine_mode mode;
886c62d1 8129
e075ae69
RH
8130 mode = GET_MODE (operands[0]);
8131 if (GET_CODE (operands[0]) == MEM)
5bc7cd8e 8132 {
e075ae69
RH
8133 /* ??? Combine likes to put non-volatile mem extractions in QImode
8134 no matter the size of the test. So find a mode that works. */
8135 if (! MEM_VOLATILE_P (operands[0]))
8136 {
8137 mode = smallest_mode_for_size (pos + len, MODE_INT);
f4ef873c 8138 operands[0] = adjust_address (operands[0], mode, 0);
e075ae69 8139 }
5bc7cd8e 8140 }
e075ae69 8141 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 8142 {
e075ae69
RH
8143 /* Small HImode tests can be converted to QImode. */
8144 mode = QImode;
8145 operands[0] = gen_lowpart (QImode, operands[0]);
5bc7cd8e
SC
8146 }
8147
e075ae69
RH
8148 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8149 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
886c62d1 8150
383252a7
AO
8151 operands[3] = gen_rtx_AND (mode, operands[0],
8152 GEN_INT (trunc_int_for_mode (mask, mode)));
0f40f9f7 8153})
886c62d1 8154
e075ae69
RH
8155;; %%% This used to optimize known byte-wide and operations to memory,
8156;; and sometimes to QImode registers. If this is considered useful,
8157;; it should be done with splitters.
8158
9b70259d
JH
8159(define_expand "anddi3"
8160 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8161 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8162 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8163 (clobber (reg:CC 17))]
8164 "TARGET_64BIT"
8165 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8166
8167(define_insn "*anddi_1_rex64"
8168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8169 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8170 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8171 (clobber (reg:CC 17))]
8172 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9b70259d
JH
8173{
8174 switch (get_attr_type (insn))
8175 {
8176 case TYPE_IMOVX:
8177 {
8178 enum machine_mode mode;
8179
8180 if (GET_CODE (operands[2]) != CONST_INT)
8181 abort ();
8182 if (INTVAL (operands[2]) == 0xff)
8183 mode = QImode;
8184 else if (INTVAL (operands[2]) == 0xffff)
8185 mode = HImode;
8186 else
8187 abort ();
8188
8189 operands[1] = gen_lowpart (mode, operands[1]);
8190 if (mode == QImode)
0f40f9f7 8191 return "movz{bq|x}\t{%1,%0|%0, %1}";
9b70259d 8192 else
0f40f9f7 8193 return "movz{wq|x}\t{%1,%0|%0, %1}";
9b70259d
JH
8194 }
8195
8196 default:
8197 if (! rtx_equal_p (operands[0], operands[1]))
8198 abort ();
8199 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 8200 return "and{l}\t{%k2, %k0|%k0, %k2}";
9b70259d 8201 else
0f40f9f7 8202 return "and{q}\t{%2, %0|%0, %2}";
9b70259d 8203 }
0f40f9f7 8204}
9b70259d
JH
8205 [(set_attr "type" "alu,alu,alu,imovx")
8206 (set_attr "length_immediate" "*,*,*,0")
8207 (set_attr "mode" "SI,DI,DI,DI")])
8208
8209(define_insn "*anddi_2"
8210 [(set (reg 17)
8211 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8212 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8213 (const_int 0)))
8214 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8215 (and:DI (match_dup 1) (match_dup 2)))]
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8217 && ix86_binary_operator_ok (AND, DImode, operands)"
8218 "@
0f40f9f7
ZW
8219 and{l}\t{%k2, %k0|%k0, %k2}
8220 and{q}\t{%2, %0|%0, %2}
8221 and{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "SI,DI,DI")])
8224
e075ae69
RH
8225(define_expand "andsi3"
8226 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8227 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8228 (match_operand:SI 2 "general_operand" "")))
8229 (clobber (reg:CC 17))]
8230 ""
8231 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8232
8233(define_insn "*andsi_1"
8234 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8235 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8236 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8237 (clobber (reg:CC 17))]
8238 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1 8239{
e075ae69 8240 switch (get_attr_type (insn))
886c62d1 8241 {
e075ae69
RH
8242 case TYPE_IMOVX:
8243 {
8244 enum machine_mode mode;
5bc7cd8e 8245
e075ae69
RH
8246 if (GET_CODE (operands[2]) != CONST_INT)
8247 abort ();
8248 if (INTVAL (operands[2]) == 0xff)
8249 mode = QImode;
8250 else if (INTVAL (operands[2]) == 0xffff)
8251 mode = HImode;
8252 else
8253 abort ();
8254
8255 operands[1] = gen_lowpart (mode, operands[1]);
8256 if (mode == QImode)
0f40f9f7 8257 return "movz{bl|x}\t{%1,%0|%0, %1}";
e075ae69 8258 else
0f40f9f7 8259 return "movz{wl|x}\t{%1,%0|%0, %1}";
e075ae69 8260 }
5bc7cd8e 8261
e075ae69
RH
8262 default:
8263 if (! rtx_equal_p (operands[0], operands[1]))
8264 abort ();
0f40f9f7 8265 return "and{l}\t{%2, %0|%0, %2}";
886c62d1 8266 }
0f40f9f7 8267}
6ef67412
JH
8268 [(set_attr "type" "alu,alu,imovx")
8269 (set_attr "length_immediate" "*,*,0")
8270 (set_attr "mode" "SI")])
8271
8272(define_split
05b432db 8273 [(set (match_operand 0 "register_operand" "")
9b70259d
JH
8274 (and (match_dup 0)
8275 (const_int -65536)))
6ef67412 8276 (clobber (reg:CC 17))]
3522082b 8277 "optimize_size"
6ef67412
JH
8278 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8279 "operands[1] = gen_lowpart (HImode, operands[0]);")
8280
8281(define_split
3522082b 8282 [(set (match_operand 0 "ext_register_operand" "")
5e1a2fc7 8283 (and (match_dup 0)
9b70259d 8284 (const_int -256)))
6ef67412 8285 (clobber (reg:CC 17))]
05b432db 8286 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8287 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8288 "operands[1] = gen_lowpart (QImode, operands[0]);")
8289
8290(define_split
3522082b 8291 [(set (match_operand 0 "ext_register_operand" "")
6ef67412
JH
8292 (and (match_dup 0)
8293 (const_int -65281)))
8294 (clobber (reg:CC 17))]
05b432db 8295 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
6ef67412
JH
8296 [(parallel [(set (zero_extract:SI (match_dup 0)
8297 (const_int 8)
8298 (const_int 8))
8299 (xor:SI
8300 (zero_extract:SI (match_dup 0)
8301 (const_int 8)
8302 (const_int 8))
8303 (zero_extract:SI (match_dup 0)
8304 (const_int 8)
8305 (const_int 8))))
8306 (clobber (reg:CC 17))])]
8307 "operands[0] = gen_lowpart (SImode, operands[0]);")
e075ae69 8308
9b70259d
JH
8309;; See comment for addsi_1_zext why we do use nonimmediate_operand
8310(define_insn "*andsi_1_zext"
8311 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (zero_extend:DI
8313 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8314 (match_operand:SI 2 "general_operand" "rim"))))
8315 (clobber (reg:CC 17))]
8316 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8317 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8320
e075ae69 8321(define_insn "*andsi_2"
16189740
RH
8322 [(set (reg 17)
8323 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8324 (match_operand:SI 2 "general_operand" "rim,ri"))
8325 (const_int 0)))
e075ae69
RH
8326 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8327 (and:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8328 "ix86_match_ccmode (insn, CCNOmode)
8329 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8330 "and{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8331 [(set_attr "type" "alu")
8332 (set_attr "mode" "SI")])
e075ae69 8333
9b70259d
JH
8334;; See comment for addsi_1_zext why we do use nonimmediate_operand
8335(define_insn "*andsi_2_zext"
8336 [(set (reg 17)
8337 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8338 (match_operand:SI 2 "general_operand" "rim"))
8339 (const_int 0)))
8340 (set (match_operand:DI 0 "register_operand" "=r")
8341 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8342 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8343 && ix86_binary_operator_ok (AND, SImode, operands)"
0f40f9f7 8344 "and{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8345 [(set_attr "type" "alu")
8346 (set_attr "mode" "SI")])
8347
e075ae69
RH
8348(define_expand "andhi3"
8349 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8350 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8351 (match_operand:HI 2 "general_operand" "")))
8352 (clobber (reg:CC 17))]
d9f32422 8353 "TARGET_HIMODE_MATH"
e075ae69
RH
8354 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8355
8356(define_insn "*andhi_1"
8357 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8358 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8359 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8360 (clobber (reg:CC 17))]
8361 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1 8362{
e075ae69 8363 switch (get_attr_type (insn))
886c62d1 8364 {
e075ae69
RH
8365 case TYPE_IMOVX:
8366 if (GET_CODE (operands[2]) != CONST_INT)
8367 abort ();
8368 if (INTVAL (operands[2]) == 0xff)
0f40f9f7 8369 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
e075ae69 8370 abort ();
886c62d1 8371
e075ae69
RH
8372 default:
8373 if (! rtx_equal_p (operands[0], operands[1]))
8374 abort ();
886c62d1 8375
0f40f9f7 8376 return "and{w}\t{%2, %0|%0, %2}";
5bc7cd8e 8377 }
0f40f9f7 8378}
6ef67412
JH
8379 [(set_attr "type" "alu,alu,imovx")
8380 (set_attr "length_immediate" "*,*,0")
8381 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 8382
e075ae69 8383(define_insn "*andhi_2"
16189740
RH
8384 [(set (reg 17)
8385 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8386 (match_operand:HI 2 "general_operand" "rim,ri"))
8387 (const_int 0)))
e075ae69
RH
8388 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8389 (and:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8390 "ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (AND, HImode, operands)"
0f40f9f7 8392 "and{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "HI")])
5bc7cd8e 8395
e075ae69
RH
8396(define_expand "andqi3"
8397 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8398 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8399 (match_operand:QI 2 "general_operand" "")))
8400 (clobber (reg:CC 17))]
d9f32422 8401 "TARGET_QIMODE_MATH"
e075ae69
RH
8402 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8403
8404;; %%% Potential partial reg stall on alternative 2. What to do?
8405(define_insn "*andqi_1"
7c6b971d 8406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 8407 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8408 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
e075ae69
RH
8409 (clobber (reg:CC 17))]
8410 "ix86_binary_operator_ok (AND, QImode, operands)"
8411 "@
0f40f9f7
ZW
8412 and{b}\t{%2, %0|%0, %2}
8413 and{b}\t{%2, %0|%0, %2}
8414 and{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
8415 [(set_attr "type" "alu")
8416 (set_attr "mode" "QI,QI,SI")])
e075ae69 8417
a1b8572c
JH
8418(define_insn "*andqi_1_slp"
8419 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8420 (and:QI (match_dup 0)
8421 (match_operand:QI 1 "general_operand" "qi,qmi")))
8422 (clobber (reg:CC 17))]
8423 ""
0f40f9f7 8424 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8425 [(set_attr "type" "alu1")
8426 (set_attr "mode" "QI")])
8427
e075ae69 8428(define_insn "*andqi_2"
16189740
RH
8429 [(set (reg 17)
8430 (compare (and:QI
8431 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8432 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8433 (const_int 0)))
e075ae69
RH
8434 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8435 (and:QI (match_dup 1) (match_dup 2)))]
16189740
RH
8436 "ix86_match_ccmode (insn, CCNOmode)
8437 && ix86_binary_operator_ok (AND, QImode, operands)"
adc88131
JJ
8438{
8439 if (which_alternative == 2)
8440 {
8441 if (GET_CODE (operands[2]) == CONST_INT
8442 && (INTVAL (operands[2]) & 0xffffff00))
8443 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
0f40f9f7 8444 return "and{l}\t{%2, %k0|%k0, %2}";
adc88131 8445 }
0f40f9f7
ZW
8446 return "and{b}\t{%2, %0|%0, %2}";
8447}
6ef67412
JH
8448 [(set_attr "type" "alu")
8449 (set_attr "mode" "QI,QI,SI")])
e075ae69 8450
a1b8572c
JH
8451(define_insn "*andqi_2_slp"
8452 [(set (reg 17)
8453 (compare (and:QI
8454 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8455 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8456 (const_int 0)))
8457 (set (strict_low_part (match_dup 0))
8458 (and:QI (match_dup 0) (match_dup 1)))]
8459 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8460 "and{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8461 [(set_attr "type" "alu1")
8462 (set_attr "mode" "QI")])
8463
e075ae69
RH
8464;; ??? A bug in recog prevents it from recognizing a const_int as an
8465;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8466;; for a QImode operand, which of course failed.
8467
8468(define_insn "andqi_ext_0"
d2836273 8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8470 (const_int 8)
8471 (const_int 8))
8472 (and:SI
8473 (zero_extract:SI
8474 (match_operand 1 "ext_register_operand" "0")
8475 (const_int 8)
8476 (const_int 8))
8477 (match_operand 2 "const_int_operand" "n")))
8478 (clobber (reg:CC 17))]
8479 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
0f40f9f7 8480 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8481 [(set_attr "type" "alu")
8482 (set_attr "length_immediate" "1")
8483 (set_attr "mode" "QI")])
e075ae69
RH
8484
8485;; Generated by peephole translating test to and. This shows up
8486;; often in fp comparisons.
8487
8488(define_insn "*andqi_ext_0_cc"
16189740
RH
8489 [(set (reg 17)
8490 (compare
e075ae69
RH
8491 (and:SI
8492 (zero_extract:SI
084e679a 8493 (match_operand 1 "ext_register_operand" "0")
3522082b 8494 (const_int 8)
e075ae69
RH
8495 (const_int 8))
8496 (match_operand 2 "const_int_operand" "n"))
8497 (const_int 0)))
d2836273 8498 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8499 (const_int 8)
8500 (const_int 8))
8501 (and:SI
8502 (zero_extract:SI
8503 (match_dup 1)
8504 (const_int 8)
8505 (const_int 8))
8506 (match_dup 2)))]
16189740
RH
8507 "ix86_match_ccmode (insn, CCNOmode)
8508 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
0f40f9f7 8509 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8510 [(set_attr "type" "alu")
8511 (set_attr "length_immediate" "1")
8512 (set_attr "mode" "QI")])
e075ae69
RH
8513
8514(define_insn "*andqi_ext_1"
d2836273 8515 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8516 (const_int 8)
8517 (const_int 8))
8518 (and:SI
8519 (zero_extract:SI
8520 (match_operand 1 "ext_register_operand" "0")
8521 (const_int 8)
8522 (const_int 8))
8523 (zero_extend:SI
d2836273 8524 (match_operand:QI 2 "general_operand" "Qm"))))
e075ae69 8525 (clobber (reg:CC 17))]
d2836273 8526 "!TARGET_64BIT"
0f40f9f7 8527 "and{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
8528 [(set_attr "type" "alu")
8529 (set_attr "length_immediate" "0")
8530 (set_attr "mode" "QI")])
8531
8532(define_insn "*andqi_ext_1_rex64"
8533 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8534 (const_int 8)
8535 (const_int 8))
8536 (and:SI
8537 (zero_extract:SI
8538 (match_operand 1 "ext_register_operand" "0")
8539 (const_int 8)
8540 (const_int 8))
8541 (zero_extend:SI
3522082b 8542 (match_operand 2 "ext_register_operand" "Q"))))
d2836273
JH
8543 (clobber (reg:CC 17))]
8544 "TARGET_64BIT"
0f40f9f7 8545 "and{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
8546 [(set_attr "type" "alu")
8547 (set_attr "length_immediate" "0")
8548 (set_attr "mode" "QI")])
e075ae69
RH
8549
8550(define_insn "*andqi_ext_2"
d2836273 8551 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
8552 (const_int 8)
8553 (const_int 8))
8554 (and:SI
8555 (zero_extract:SI
8556 (match_operand 1 "ext_register_operand" "%0")
8557 (const_int 8)
8558 (const_int 8))
8559 (zero_extract:SI
d2836273 8560 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
8561 (const_int 8)
8562 (const_int 8))))
8563 (clobber (reg:CC 17))]
8564 ""
0f40f9f7 8565 "and{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
8566 [(set_attr "type" "alu")
8567 (set_attr "length_immediate" "0")
8568 (set_attr "mode" "QI")])
886c62d1 8569\f
e075ae69 8570;; Logical inclusive OR instructions
57dbca5e 8571
e075ae69
RH
8572;; %%% This used to optimize known byte-wide and operations to memory.
8573;; If this is considered useful, it should be done with splitters.
8574
9b70259d
JH
8575(define_expand "iordi3"
8576 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8577 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8578 (match_operand:DI 2 "x86_64_general_operand" "")))
8579 (clobber (reg:CC 17))]
8580 "TARGET_64BIT"
8581 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8582
8583(define_insn "*iordi_1_rex64"
8584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8585 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8587 (clobber (reg:CC 17))]
8588 "TARGET_64BIT
8589 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8590 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8591 [(set_attr "type" "alu")
8592 (set_attr "mode" "DI")])
8593
8594(define_insn "*iordi_2_rex64"
8595 [(set (reg 17)
8596 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8597 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8598 (const_int 0)))
8599 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8600 (ior:DI (match_dup 1) (match_dup 2)))]
8601 "TARGET_64BIT
8602 && ix86_match_ccmode (insn, CCNOmode)
8603 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8604 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "DI")])
8607
8608(define_insn "*iordi_3_rex64"
8609 [(set (reg 17)
8610 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8611 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8612 (const_int 0)))
8613 (clobber (match_scratch:DI 0 "=r"))]
8614 "TARGET_64BIT
8615 && ix86_match_ccmode (insn, CCNOmode)
8616 && ix86_binary_operator_ok (IOR, DImode, operands)"
0f40f9f7 8617 "or{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8618 [(set_attr "type" "alu")
8619 (set_attr "mode" "DI")])
8620
8621
e075ae69
RH
8622(define_expand "iorsi3"
8623 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8624 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8625 (match_operand:SI 2 "general_operand" "")))
8626 (clobber (reg:CC 17))]
57dbca5e 8627 ""
e075ae69
RH
8628 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8629
8630(define_insn "*iorsi_1"
8631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8632 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8633 (match_operand:SI 2 "general_operand" "ri,rmi")))
8634 (clobber (reg:CC 17))]
8635 "ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8636 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "SI")])
e075ae69 8639
9b70259d
JH
8640;; See comment for addsi_1_zext why we do use nonimmediate_operand
8641(define_insn "*iorsi_1_zext"
8642 [(set (match_operand:DI 0 "register_operand" "=rm")
8643 (zero_extend:DI
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8645 (match_operand:SI 2 "general_operand" "rim"))))
8646 (clobber (reg:CC 17))]
8647 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8648 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652(define_insn "*iorsi_1_zext_imm"
8653 [(set (match_operand:DI 0 "register_operand" "=rm")
8654 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8655 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8656 (clobber (reg:CC 17))]
8657 "TARGET_64BIT"
0f40f9f7 8658 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8659 [(set_attr "type" "alu")
8660 (set_attr "mode" "SI")])
8661
e075ae69 8662(define_insn "*iorsi_2"
16189740
RH
8663 [(set (reg 17)
8664 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8665 (match_operand:SI 2 "general_operand" "rim,ri"))
8666 (const_int 0)))
e075ae69
RH
8667 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8668 (ior:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8669 "ix86_match_ccmode (insn, CCNOmode)
8670 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8671 "or{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8672 [(set_attr "type" "alu")
8673 (set_attr "mode" "SI")])
e075ae69 8674
9b70259d
JH
8675;; See comment for addsi_1_zext why we do use nonimmediate_operand
8676;; ??? Special case for immediate operand is missing - it is tricky.
8677(define_insn "*iorsi_2_zext"
8678 [(set (reg 17)
8679 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680 (match_operand:SI 2 "general_operand" "rim"))
8681 (const_int 0)))
8682 (set (match_operand:DI 0 "register_operand" "=r")
8683 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8686 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8687 [(set_attr "type" "alu")
8688 (set_attr "mode" "SI")])
8689
8690(define_insn "*iorsi_2_zext_imm"
8691 [(set (reg 17)
8692 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8694 (const_int 0)))
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8697 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, SImode, operands)"
0f40f9f7 8699 "or{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "SI")])
8702
d90ffc8d
JH
8703(define_insn "*iorsi_3"
8704 [(set (reg 17)
8705 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706 (match_operand:SI 2 "general_operand" "rim"))
8707 (const_int 0)))
8708 (clobber (match_scratch:SI 0 "=r"))]
8709 "ix86_match_ccmode (insn, CCNOmode)
8710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8711 "or{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8714
e075ae69
RH
8715(define_expand "iorhi3"
8716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8717 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8718 (match_operand:HI 2 "general_operand" "")))
8719 (clobber (reg:CC 17))]
d9f32422 8720 "TARGET_HIMODE_MATH"
e075ae69
RH
8721 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8722
8723(define_insn "*iorhi_1"
8724 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8725 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726 (match_operand:HI 2 "general_operand" "rmi,ri")))
8727 (clobber (reg:CC 17))]
8728 "ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8729 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8730 [(set_attr "type" "alu")
8731 (set_attr "mode" "HI")])
e075ae69 8732
e075ae69 8733(define_insn "*iorhi_2"
16189740
RH
8734 [(set (reg 17)
8735 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8736 (match_operand:HI 2 "general_operand" "rim,ri"))
8737 (const_int 0)))
e075ae69
RH
8738 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8739 (ior:HI (match_dup 1) (match_dup 2)))]
16189740
RH
8740 "ix86_match_ccmode (insn, CCNOmode)
8741 && ix86_binary_operator_ok (IOR, HImode, operands)"
0f40f9f7 8742 "or{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "HI")])
e075ae69 8745
d90ffc8d
JH
8746(define_insn "*iorhi_3"
8747 [(set (reg 17)
8748 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8749 (match_operand:HI 2 "general_operand" "rim"))
8750 (const_int 0)))
8751 (clobber (match_scratch:HI 0 "=r"))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8754 "or{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8757
e075ae69
RH
8758(define_expand "iorqi3"
8759 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8760 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8761 (match_operand:QI 2 "general_operand" "")))
8762 (clobber (reg:CC 17))]
d9f32422 8763 "TARGET_QIMODE_MATH"
e075ae69
RH
8764 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8765
8766;; %%% Potential partial reg stall on alternative 2. What to do?
8767(define_insn "*iorqi_1"
7c6b971d 8768 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 8769 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 8770 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
e075ae69
RH
8771 (clobber (reg:CC 17))]
8772 "ix86_binary_operator_ok (IOR, QImode, operands)"
8773 "@
0f40f9f7
ZW
8774 or{b}\t{%2, %0|%0, %2}
8775 or{b}\t{%2, %0|%0, %2}
8776 or{l}\t{%k2, %k0|%k0, %k2}"
6ef67412 8777 [(set_attr "type" "alu")
a1b8572c
JH
8778 (set_attr "mode" "QI,QI,SI")])
8779
8780(define_insn "*iorqi_1_slp"
8781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8782 (ior:QI (match_dup 0)
8783 (match_operand:QI 1 "general_operand" "qmi,qi")))
8784 (clobber (reg:CC 17))]
8785 ""
0f40f9f7 8786 "or{b}\t{%1, %0|%0, %1}"
a1b8572c 8787 [(set_attr "type" "alu1")
6ef67412 8788 (set_attr "mode" "QI")])
e075ae69
RH
8789
8790(define_insn "*iorqi_2"
16189740
RH
8791 [(set (reg 17)
8792 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8793 (match_operand:QI 2 "general_operand" "qim,qi"))
8794 (const_int 0)))
e075ae69
RH
8795 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8796 (ior:QI (match_dup 1) (match_dup 2)))]
16189740
RH
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && ix86_binary_operator_ok (IOR, QImode, operands)"
0f40f9f7 8799 "or{b}\t{%2, %0|%0, %2}"
6ef67412
JH
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI")])
d90ffc8d 8802
a1b8572c
JH
8803(define_insn "*iorqi_2_slp"
8804 [(set (reg 17)
8805 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8806 (match_operand:QI 1 "general_operand" "qim,qi"))
8807 (const_int 0)))
8808 (set (strict_low_part (match_dup 0))
8809 (ior:QI (match_dup 0) (match_dup 1)))]
8810 "ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 8811 "or{b}\t{%1, %0|%0, %1}"
a1b8572c
JH
8812 [(set_attr "type" "alu1")
8813 (set_attr "mode" "QI")])
8814
d90ffc8d
JH
8815(define_insn "*iorqi_3"
8816 [(set (reg 17)
8817 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8818 (match_operand:QI 2 "general_operand" "qim"))
8819 (const_int 0)))
7e08e190 8820 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
8821 "ix86_match_ccmode (insn, CCNOmode)
8822 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8823 "or{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8824 [(set_attr "type" "alu")
8825 (set_attr "mode" "QI")])
8826
e075ae69
RH
8827\f
8828;; Logical XOR instructions
a269a03c 8829
e075ae69
RH
8830;; %%% This used to optimize known byte-wide and operations to memory.
8831;; If this is considered useful, it should be done with splitters.
57dbca5e 8832
9b70259d
JH
8833(define_expand "xordi3"
8834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8835 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8836 (match_operand:DI 2 "x86_64_general_operand" "")))
8837 (clobber (reg:CC 17))]
8838 "TARGET_64BIT"
8839 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8840
8841(define_insn "*xordi_1_rex64"
8842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8843 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8845 (clobber (reg:CC 17))]
8846 "TARGET_64BIT
8847 && ix86_binary_operator_ok (XOR, DImode, operands)"
8848 "@
0f40f9f7
ZW
8849 xor{q}\t{%2, %0|%0, %2}
8850 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "DI,DI")])
8853
8854(define_insn "*xordi_2_rex64"
8855 [(set (reg 17)
8856 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8857 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8858 (const_int 0)))
8859 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8860 (xor:DI (match_dup 1) (match_dup 2)))]
8861 "TARGET_64BIT
8862 && ix86_match_ccmode (insn, CCNOmode)
8863 && ix86_binary_operator_ok (XOR, DImode, operands)"
8864 "@
0f40f9f7
ZW
8865 xor{q}\t{%2, %0|%0, %2}
8866 xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "DI,DI")])
8869
8870(define_insn "*xordi_3_rex64"
8871 [(set (reg 17)
8872 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8873 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8874 (const_int 0)))
8875 (clobber (match_scratch:DI 0 "=r"))]
8876 "TARGET_64BIT
8877 && ix86_match_ccmode (insn, CCNOmode)
8878 && ix86_binary_operator_ok (XOR, DImode, operands)"
0f40f9f7 8879 "xor{q}\t{%2, %0|%0, %2}"
9b70259d
JH
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "DI")])
8882
e075ae69
RH
8883(define_expand "xorsi3"
8884 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8885 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8886 (match_operand:SI 2 "general_operand" "")))
8887 (clobber (reg:CC 17))]
57dbca5e 8888 ""
e075ae69 8889 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
a269a03c 8890
e075ae69
RH
8891(define_insn "*xorsi_1"
8892 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8893 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8894 (match_operand:SI 2 "general_operand" "ri,rm")))
8895 (clobber (reg:CC 17))]
8896 "ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8897 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "SI")])
e075ae69 8900
9b70259d
JH
8901;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902;; Add speccase for immediates
8903(define_insn "*xorsi_1_zext"
8904 [(set (match_operand:DI 0 "register_operand" "=r")
8905 (zero_extend:DI
8906 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8907 (match_operand:SI 2 "general_operand" "rim"))))
8908 (clobber (reg:CC 17))]
8909 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8910 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI")])
8913
8914(define_insn "*xorsi_1_zext_imm"
8915 [(set (match_operand:DI 0 "register_operand" "=r")
8916 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8917 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8918 (clobber (reg:CC 17))]
8919 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8920 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8923
e075ae69 8924(define_insn "*xorsi_2"
16189740
RH
8925 [(set (reg 17)
8926 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8927 (match_operand:SI 2 "general_operand" "rim,ri"))
8928 (const_int 0)))
e075ae69
RH
8929 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8930 (xor:SI (match_dup 1) (match_dup 2)))]
16189740
RH
8931 "ix86_match_ccmode (insn, CCNOmode)
8932 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8933 "xor{l}\t{%2, %0|%0, %2}"
6ef67412
JH
8934 [(set_attr "type" "alu")
8935 (set_attr "mode" "SI")])
e075ae69 8936
9b70259d
JH
8937;; See comment for addsi_1_zext why we do use nonimmediate_operand
8938;; ??? Special case for immediate operand is missing - it is tricky.
8939(define_insn "*xorsi_2_zext"
8940 [(set (reg 17)
8941 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942 (match_operand:SI 2 "general_operand" "rim"))
8943 (const_int 0)))
8944 (set (match_operand:DI 0 "register_operand" "=r")
8945 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8946 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8947 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8948 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "SI")])
8951
8952(define_insn "*xorsi_2_zext_imm"
8953 [(set (reg 17)
8954 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8956 (const_int 0)))
8957 (set (match_operand:DI 0 "register_operand" "=r")
8958 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8960 && ix86_binary_operator_ok (XOR, SImode, operands)"
0f40f9f7 8961 "xor{l}\t{%2, %k0|%k0, %2}"
9b70259d
JH
8962 [(set_attr "type" "alu")
8963 (set_attr "mode" "SI")])
8964
d90ffc8d
JH
8965(define_insn "*xorsi_3"
8966 [(set (reg 17)
8967 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand:SI 2 "general_operand" "rim"))
8969 (const_int 0)))
8970 (clobber (match_scratch:SI 0 "=r"))]
8971 "ix86_match_ccmode (insn, CCNOmode)
8972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 8973 "xor{l}\t{%2, %0|%0, %2}"
d90ffc8d
JH
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "SI")])
8976
e075ae69
RH
8977(define_expand "xorhi3"
8978 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8979 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8980 (match_operand:HI 2 "general_operand" "")))
8981 (clobber (reg:CC 17))]
d9f32422 8982 "TARGET_HIMODE_MATH"
e075ae69
RH
8983 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8984
8985(define_insn "*xorhi_1"
8986 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8987 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8988 (match_operand:HI 2 "general_operand" "rmi,ri")))
8989 (clobber (reg:CC 17))]
8990 "ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 8991 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
8992 [(set_attr "type" "alu")
8993 (set_attr "mode" "HI")])
57dbca5e 8994
e075ae69 8995(define_insn "*xorhi_2"
16189740
RH
8996 [(set (reg 17)
8997 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:HI 2 "general_operand" "rim,ri"))
8999 (const_int 0)))
e075ae69
RH
9000 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9001 (xor:HI (match_dup 1) (match_dup 2)))]
16189740
RH
9002 "ix86_match_ccmode (insn, CCNOmode)
9003 && ix86_binary_operator_ok (XOR, HImode, operands)"
0f40f9f7 9004 "xor{w}\t{%2, %0|%0, %2}"
6ef67412
JH
9005 [(set_attr "type" "alu")
9006 (set_attr "mode" "HI")])
e075ae69 9007
d90ffc8d
JH
9008(define_insn "*xorhi_3"
9009 [(set (reg 17)
9010 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9011 (match_operand:HI 2 "general_operand" "rim"))
9012 (const_int 0)))
9013 (clobber (match_scratch:HI 0 "=r"))]
9014 "ix86_match_ccmode (insn, CCNOmode)
9015 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9016 "xor{w}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9017 [(set_attr "type" "alu")
9018 (set_attr "mode" "HI")])
9019
e075ae69
RH
9020(define_expand "xorqi3"
9021 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9022 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9023 (match_operand:QI 2 "general_operand" "")))
9024 (clobber (reg:CC 17))]
d9f32422 9025 "TARGET_QIMODE_MATH"
e075ae69
RH
9026 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9027
9028;; %%% Potential partial reg stall on alternative 2. What to do?
9029(define_insn "*xorqi_1"
7c6b971d 9030 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 9031 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 9032 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
e075ae69
RH
9033 (clobber (reg:CC 17))]
9034 "ix86_binary_operator_ok (XOR, QImode, operands)"
9035 "@
0f40f9f7
ZW
9036 xor{b}\t{%2, %0|%0, %2}
9037 xor{b}\t{%2, %0|%0, %2}
9038 xor{l}\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "QI,QI,SI")])
9041
a4414093 9042(define_insn "*xorqi_ext_1"
d2836273 9043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6ef67412
JH
9044 (const_int 8)
9045 (const_int 8))
9046 (xor:SI
9047 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9048 (const_int 8)
9049 (const_int 8))
d2836273 9050 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6ef67412
JH
9051 (const_int 8)
9052 (const_int 8))))
9053 (clobber (reg:CC 17))]
9054 ""
0f40f9f7 9055 "xor{b}\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
9056 [(set_attr "type" "alu")
9057 (set_attr "length_immediate" "0")
9058 (set_attr "mode" "QI")])
e075ae69 9059
7abd4e00 9060(define_insn "*xorqi_cc_1"
16189740
RH
9061 [(set (reg 17)
9062 (compare
e075ae69
RH
9063 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9064 (match_operand:QI 2 "general_operand" "qim,qi"))
9065 (const_int 0)))
9066 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9067 (xor:QI (match_dup 1) (match_dup 2)))]
16189740
RH
9068 "ix86_match_ccmode (insn, CCNOmode)
9069 && ix86_binary_operator_ok (XOR, QImode, operands)"
0f40f9f7 9070 "xor{b}\t{%2, %0|%0, %2}"
6ef67412
JH
9071 [(set_attr "type" "alu")
9072 (set_attr "mode" "QI")])
e075ae69 9073
d90ffc8d
JH
9074(define_insn "*xorqi_cc_2"
9075 [(set (reg 17)
9076 (compare
9077 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9078 (match_operand:QI 2 "general_operand" "qim"))
9079 (const_int 0)))
7e08e190 9080 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
9081 "ix86_match_ccmode (insn, CCNOmode)
9082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
0f40f9f7 9083 "xor{b}\t{%2, %0|%0, %2}"
d90ffc8d
JH
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "QI")])
9086
9076b9c1
JH
9087(define_insn "*xorqi_cc_ext_1"
9088 [(set (reg 17)
9089 (compare
e075ae69
RH
9090 (xor:SI
9091 (zero_extract:SI
9092 (match_operand 1 "ext_register_operand" "0")
9093 (const_int 8)
9094 (const_int 8))
9095 (match_operand:QI 2 "general_operand" "qmn"))
9096 (const_int 0)))
9097 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9098 (const_int 8)
9099 (const_int 8))
9100 (xor:SI
9101 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9102 (match_dup 2)))]
d2836273 9103 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9104 "xor{b}\t{%2, %h0|%h0, %2}"
d2836273
JH
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "QI")])
9107
9108(define_insn "*xorqi_cc_ext_1_rex64"
9109 [(set (reg 17)
9110 (compare
9111 (xor:SI
9112 (zero_extract:SI
9113 (match_operand 1 "ext_register_operand" "0")
9114 (const_int 8)
9115 (const_int 8))
9116 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9117 (const_int 0)))
9118 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119 (const_int 8)
9120 (const_int 8))
9121 (xor:SI
9122 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9123 (match_dup 2)))]
9124 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
0f40f9f7 9125 "xor{b}\t{%2, %h0|%h0, %2}"
6ef67412
JH
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "QI")])
9076b9c1
JH
9128
9129(define_expand "xorqi_cc_ext_1"
9130 [(parallel [
9131 (set (reg:CCNO 17)
9132 (compare:CCNO
9133 (xor:SI
9134 (zero_extract:SI
9135 (match_operand 1 "ext_register_operand" "")
9136 (const_int 8)
9137 (const_int 8))
9138 (match_operand:QI 2 "general_operand" ""))
9139 (const_int 0)))
9140 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9141 (const_int 8)
9142 (const_int 8))
9143 (xor:SI
9144 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9145 (match_dup 2)))])]
9146 ""
9147 "")
e075ae69
RH
9148\f
9149;; Negation instructions
57dbca5e 9150
06a964de
JH
9151(define_expand "negdi2"
9152 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2756c3d8 9153 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
06a964de
JH
9154 (clobber (reg:CC 17))])]
9155 ""
9156 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9157
9158(define_insn "*negdi2_1"
e075ae69
RH
9159 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9160 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9161 (clobber (reg:CC 17))]
d2836273
JH
9162 "!TARGET_64BIT
9163 && ix86_unary_operator_ok (NEG, DImode, operands)"
e075ae69 9164 "#")
886c62d1 9165
e075ae69
RH
9166(define_split
9167 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9168 (neg:DI (match_operand:DI 1 "general_operand" "")))
9169 (clobber (reg:CC 17))]
1b0c37d7 9170 "!TARGET_64BIT && reload_completed"
e075ae69 9171 [(parallel
16189740
RH
9172 [(set (reg:CCZ 17)
9173 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
e075ae69
RH
9174 (set (match_dup 0) (neg:SI (match_dup 2)))])
9175 (parallel
9176 [(set (match_dup 1)
7e08e190 9177 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9dcbdc7e
JH
9178 (match_dup 3))
9179 (const_int 0)))
e075ae69
RH
9180 (clobber (reg:CC 17))])
9181 (parallel
9182 [(set (match_dup 1)
9183 (neg:SI (match_dup 1)))
9184 (clobber (reg:CC 17))])]
9185 "split_di (operands+1, 1, operands+2, operands+3);
9186 split_di (operands+0, 1, operands+0, operands+1);")
886c62d1 9187
9b70259d
JH
9188(define_insn "*negdi2_1_rex64"
9189 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9190 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9191 (clobber (reg:CC 17))]
9192 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9193 "neg{q}\t%0"
9b70259d
JH
9194 [(set_attr "type" "negnot")
9195 (set_attr "mode" "DI")])
9196
9197;; The problem with neg is that it does not perform (compare x 0),
9198;; it really performs (compare 0 x), which leaves us with the zero
9199;; flag being the only useful item.
9200
9201(define_insn "*negdi2_cmpz_rex64"
9202 [(set (reg:CCZ 17)
9203 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9204 (const_int 0)))
9205 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9206 (neg:DI (match_dup 1)))]
9207 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
0f40f9f7 9208 "neg{q}\t%0"
9b70259d
JH
9209 [(set_attr "type" "negnot")
9210 (set_attr "mode" "DI")])
9211
9212
06a964de
JH
9213(define_expand "negsi2"
9214 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2756c3d8 9215 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
06a964de
JH
9216 (clobber (reg:CC 17))])]
9217 ""
9218 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9219
9220(define_insn "*negsi2_1"
2ae0f82c 9221 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69
RH
9222 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9223 (clobber (reg:CC 17))]
06a964de 9224 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9225 "neg{l}\t%0"
6ef67412
JH
9226 [(set_attr "type" "negnot")
9227 (set_attr "mode" "SI")])
e075ae69 9228
9b70259d
JH
9229;; Combine is quite creative about this pattern.
9230(define_insn "*negsi2_1_zext"
9231 [(set (match_operand:DI 0 "register_operand" "=r")
9232 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9233 (const_int 32)))
9234 (const_int 32)))
9235 (clobber (reg:CC 17))]
9236 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9237 "neg{l}\t%k0"
9b70259d
JH
9238 [(set_attr "type" "negnot")
9239 (set_attr "mode" "SI")])
9240
16189740
RH
9241;; The problem with neg is that it does not perform (compare x 0),
9242;; it really performs (compare 0 x), which leaves us with the zero
9243;; flag being the only useful item.
e075ae69 9244
16189740
RH
9245(define_insn "*negsi2_cmpz"
9246 [(set (reg:CCZ 17)
9247 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9248 (const_int 0)))
e075ae69
RH
9249 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9250 (neg:SI (match_dup 1)))]
06a964de 9251 "ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9252 "neg{l}\t%0"
6ef67412
JH
9253 [(set_attr "type" "negnot")
9254 (set_attr "mode" "SI")])
886c62d1 9255
9b70259d
JH
9256(define_insn "*negsi2_cmpz_zext"
9257 [(set (reg:CCZ 17)
9258 (compare:CCZ (lshiftrt:DI
9259 (neg:DI (ashift:DI
9260 (match_operand:DI 1 "register_operand" "0")
9261 (const_int 32)))
9262 (const_int 32))
9263 (const_int 0)))
9264 (set (match_operand:DI 0 "register_operand" "=r")
9265 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9266 (const_int 32)))
9267 (const_int 32)))]
9268 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
0f40f9f7 9269 "neg{l}\t%k0"
9b70259d
JH
9270 [(set_attr "type" "negnot")
9271 (set_attr "mode" "SI")])
9272
06a964de
JH
9273(define_expand "neghi2"
9274 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
2756c3d8 9275 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
06a964de 9276 (clobber (reg:CC 17))])]
d9f32422 9277 "TARGET_HIMODE_MATH"
06a964de
JH
9278 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9279
9280(define_insn "*neghi2_1"
2ae0f82c 9281 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69
RH
9282 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9283 (clobber (reg:CC 17))]
06a964de 9284 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9285 "neg{w}\t%0"
6ef67412
JH
9286 [(set_attr "type" "negnot")
9287 (set_attr "mode" "HI")])
e075ae69 9288
16189740
RH
9289(define_insn "*neghi2_cmpz"
9290 [(set (reg:CCZ 17)
9291 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9292 (const_int 0)))
e075ae69
RH
9293 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9294 (neg:HI (match_dup 1)))]
06a964de 9295 "ix86_unary_operator_ok (NEG, HImode, operands)"
0f40f9f7 9296 "neg{w}\t%0"
6ef67412
JH
9297 [(set_attr "type" "negnot")
9298 (set_attr "mode" "HI")])
886c62d1 9299
06a964de
JH
9300(define_expand "negqi2"
9301 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
2756c3d8 9302 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
06a964de 9303 (clobber (reg:CC 17))])]
d9f32422 9304 "TARGET_QIMODE_MATH"
06a964de
JH
9305 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9306
9307(define_insn "*negqi2_1"
2ae0f82c 9308 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69
RH
9309 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9310 (clobber (reg:CC 17))]
06a964de 9311 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9312 "neg{b}\t%0"
6ef67412
JH
9313 [(set_attr "type" "negnot")
9314 (set_attr "mode" "QI")])
e075ae69 9315
16189740
RH
9316(define_insn "*negqi2_cmpz"
9317 [(set (reg:CCZ 17)
9318 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9319 (const_int 0)))
e075ae69
RH
9320 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9321 (neg:QI (match_dup 1)))]
06a964de 9322 "ix86_unary_operator_ok (NEG, QImode, operands)"
0f40f9f7 9323 "neg{b}\t%0"
6ef67412
JH
9324 [(set_attr "type" "negnot")
9325 (set_attr "mode" "QI")])
886c62d1 9326
06a964de 9327;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 9328
06a964de
JH
9329(define_expand "negsf2"
9330 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2756c3d8 9331 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
06a964de
JH
9332 (clobber (reg:CC 17))])]
9333 "TARGET_80387"
b3298882
JH
9334 "if (TARGET_SSE)
9335 {
9336 /* In case operand is in memory, we will not use SSE. */
9337 if (memory_operand (operands[0], VOIDmode)
9338 && rtx_equal_p (operands[0], operands[1]))
9339 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9340 else
9341 {
9342 /* Using SSE is tricky, since we need bitwise negation of -0
9343 in register. */
9344 rtx reg = gen_reg_rtx (SFmode);
141e454b
JH
9345 rtx dest = operands[0];
9346
9347 operands[1] = force_reg (SFmode, operands[1]);
9348 operands[0] = force_reg (SFmode, operands[0]);
b3298882
JH
9349 emit_move_insn (reg,
9350 gen_lowpart (SFmode,
141e454b
JH
9351 GEN_INT (trunc_int_for_mode (0x80000000,
9352 SImode))));
b3298882 9353 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
141e454b
JH
9354 if (dest != operands[0])
9355 emit_move_insn (dest, operands[0]);
b3298882
JH
9356 }
9357 DONE;
9358 }
9359 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9360
9361(define_insn "negsf2_memory"
9362 [(set (match_operand:SF 0 "memory_operand" "=m")
9363 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9364 (clobber (reg:CC 17))]
9365 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9366 "#")
9367
9368(define_insn "negsf2_ifs"
141e454b 9369 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
b3298882 9370 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
141e454b 9371 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
b3298882 9372 (clobber (reg:CC 17))]
141e454b
JH
9373 "TARGET_SSE
9374 && (reload_in_progress || reload_completed
9375 || (register_operand (operands[0], VOIDmode)
9376 && register_operand (operands[1], VOIDmode)))"
b3298882
JH
9377 "#")
9378
9379(define_split
9380 [(set (match_operand:SF 0 "memory_operand" "")
9381 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9382 (use (match_operand:SF 2 "" ""))
9383 (clobber (reg:CC 17))]
9384 ""
9385 [(parallel [(set (match_dup 0)
9386 (neg:SF (match_dup 1)))
9387 (clobber (reg:CC 17))])])
9388
9389(define_split
9390 [(set (match_operand:SF 0 "register_operand" "")
9391 (neg:SF (match_operand:SF 1 "register_operand" "")))
9392 (use (match_operand:SF 2 "" ""))
9393 (clobber (reg:CC 17))]
9394 "reload_completed && !SSE_REG_P (operands[0])"
9395 [(parallel [(set (match_dup 0)
9396 (neg:SF (match_dup 1)))
9397 (clobber (reg:CC 17))])])
9398
9399(define_split
9400 [(set (match_operand:SF 0 "register_operand" "")
9401 (neg:SF (match_operand:SF 1 "register_operand" "")))
9402 (use (match_operand:SF 2 "register_operand" ""))
9403 (clobber (reg:CC 17))]
9404 "reload_completed && SSE_REG_P (operands[0])"
9405 [(set (subreg:TI (match_dup 0) 0)
9406 (xor:TI (subreg:TI (match_dup 1) 0)
9407 (subreg:TI (match_dup 2) 0)))]
b3298882
JH
9408{
9409 if (operands_match_p (operands[0], operands[2]))
9410 {
9411 rtx tmp;
9412 tmp = operands[1];
9413 operands[1] = operands[2];
9414 operands[2] = tmp;
9415 }
0f40f9f7 9416})
b3298882 9417
06a964de 9418
e20440c1
JH
9419;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9420;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9421;; to itself.
06a964de 9422(define_insn "*negsf2_if"
e20440c1
JH
9423 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9424 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1ce485ec 9425 (clobber (reg:CC 17))]
b3298882
JH
9426 "TARGET_80387 && !TARGET_SSE
9427 && ix86_unary_operator_ok (NEG, SFmode, operands)"
1ce485ec
JH
9428 "#")
9429
9430(define_split
9431 [(set (match_operand:SF 0 "register_operand" "")
9432 (neg:SF (match_operand:SF 1 "register_operand" "")))
9433 (clobber (reg:CC 17))]
9434 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9435 [(set (match_dup 0)
9436 (neg:SF (match_dup 1)))]
9437 "")
9438
9439(define_split
9440 [(set (match_operand:SF 0 "register_operand" "")
9441 (neg:SF (match_operand:SF 1 "register_operand" "")))
9442 (clobber (reg:CC 17))]
9443 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9444 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9445 (clobber (reg:CC 17))])]
383252a7 9446 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
1ce485ec
JH
9447 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9448
9449(define_split
9450 [(set (match_operand 0 "memory_operand" "")
9451 (neg (match_operand 1 "memory_operand" "")))
9452 (clobber (reg:CC 17))]
9453 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9454 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9455 (clobber (reg:CC 17))])]
1ce485ec
JH
9456{
9457 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9458
b3298882
JH
9459 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9460 if (size >= 12)
1ce485ec 9461 size = 10;
b72f00af 9462 operands[0] = adjust_address (operands[0], QImode, size - 1);
383252a7 9463 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
0f40f9f7 9464})
1ce485ec 9465
06a964de
JH
9466(define_expand "negdf2"
9467 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2756c3d8 9468 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
06a964de
JH
9469 (clobber (reg:CC 17))])]
9470 "TARGET_80387"
141e454b 9471 "if (TARGET_SSE2)
b3298882
JH
9472 {
9473 /* In case operand is in memory, we will not use SSE. */
9474 if (memory_operand (operands[0], VOIDmode)
9475 && rtx_equal_p (operands[0], operands[1]))
9476 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9477 else
9478 {
9479 /* Using SSE is tricky, since we need bitwise negation of -0
9480 in register. */
9481 rtx reg = gen_reg_rtx (DFmode);
9482#if HOST_BITS_PER_WIDE_INT >= 64
141e454b
JH
9483 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9484 DImode));
b3298882
JH
9485#else
9486 rtx imm = immed_double_const (0, 0x80000000, DImode);
9487#endif
141e454b
JH
9488 rtx dest = operands[0];
9489
9490 operands[1] = force_reg (DFmode, operands[1]);
9491 operands[0] = force_reg (DFmode, operands[0]);
b3298882
JH
9492 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9493 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
141e454b
JH
9494 if (dest != operands[0])
9495 emit_move_insn (dest, operands[0]);
b3298882
JH
9496 }
9497 DONE;
9498 }
9499 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9500
9501(define_insn "negdf2_memory"
9502 [(set (match_operand:DF 0 "memory_operand" "=m")
9503 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9504 (clobber (reg:CC 17))]
9505 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9506 "#")
9507
9508(define_insn "negdf2_ifs"
141e454b
JH
9509 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9510 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9511 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
b3298882 9512 (clobber (reg:CC 17))]
1b0c37d7 9513 "!TARGET_64BIT && TARGET_SSE2
141e454b
JH
9514 && (reload_in_progress || reload_completed
9515 || (register_operand (operands[0], VOIDmode)
9516 && register_operand (operands[1], VOIDmode)))"
9517 "#")
9518
9519(define_insn "*negdf2_ifs_rex64"
9520 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9521 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9522 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9523 (clobber (reg:CC 17))]
1b0c37d7 9524 "TARGET_64BIT && TARGET_SSE2
141e454b
JH
9525 && (reload_in_progress || reload_completed
9526 || (register_operand (operands[0], VOIDmode)
9527 && register_operand (operands[1], VOIDmode)))"
b3298882
JH
9528 "#")
9529
9530(define_split
9531 [(set (match_operand:DF 0 "memory_operand" "")
9532 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9533 (use (match_operand:DF 2 "" ""))
9534 (clobber (reg:CC 17))]
9535 ""
9536 [(parallel [(set (match_dup 0)
9537 (neg:DF (match_dup 1)))
9538 (clobber (reg:CC 17))])])
9539
9540(define_split
9541 [(set (match_operand:DF 0 "register_operand" "")
9542 (neg:DF (match_operand:DF 1 "register_operand" "")))
9543 (use (match_operand:DF 2 "" ""))
9544 (clobber (reg:CC 17))]
141e454b
JH
9545 "reload_completed && !SSE_REG_P (operands[0])
9546 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
b3298882
JH
9547 [(parallel [(set (match_dup 0)
9548 (neg:DF (match_dup 1)))
9549 (clobber (reg:CC 17))])])
9550
141e454b
JH
9551(define_split
9552 [(set (match_operand:DF 0 "register_operand" "")
9553 (neg:DF (match_operand:DF 1 "register_operand" "")))
9554 (use (match_operand:DF 2 "" ""))
9555 (clobber (reg:CC 17))]
1b0c37d7 9556 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
141e454b
JH
9557 [(parallel [(set (match_dup 0)
9558 (xor:DI (match_dup 1) (match_dup 2)))
9559 (clobber (reg:CC 17))])]
9560 "operands[0] = gen_lowpart (DImode, operands[0]);
9561 operands[1] = gen_lowpart (DImode, operands[1]);
9562 operands[2] = gen_lowpart (DImode, operands[2]);")
9563
b3298882
JH
9564(define_split
9565 [(set (match_operand:DF 0 "register_operand" "")
9566 (neg:DF (match_operand:DF 1 "register_operand" "")))
9567 (use (match_operand:DF 2 "register_operand" ""))
9568 (clobber (reg:CC 17))]
9569 "reload_completed && SSE_REG_P (operands[0])"
9570 [(set (subreg:TI (match_dup 0) 0)
9571 (xor:TI (subreg:TI (match_dup 1) 0)
9572 (subreg:TI (match_dup 2) 0)))]
b3298882
JH
9573{
9574 if (operands_match_p (operands[0], operands[2]))
9575 {
9576 rtx tmp;
9577 tmp = operands[1];
9578 operands[1] = operands[2];
9579 operands[2] = tmp;
9580 }
0f40f9f7 9581})
06a964de 9582
e20440c1
JH
9583;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9584;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9585;; to itself.
06a964de 9586(define_insn "*negdf2_if"
e20440c1
JH
9587 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9588 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1ce485ec 9589 (clobber (reg:CC 17))]
1b0c37d7 9590 "!TARGET_64BIT && TARGET_80387
141e454b
JH
9591 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9592 "#")
9593
9594;; FIXME: We should to allow integer registers here. Problem is that
9595;; we need another scratch register to get constant from.
9596;; Forcing constant to mem if no register available in peep2 should be
9597;; safe even for PIC mode, because of RIP relative addressing.
9598(define_insn "*negdf2_if_rex64"
9599 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9600 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9601 (clobber (reg:CC 17))]
1b0c37d7 9602 "TARGET_64BIT && TARGET_80387
141e454b 9603 && ix86_unary_operator_ok (NEG, DFmode, operands)"
1ce485ec
JH
9604 "#")
9605
9606(define_split
9607 [(set (match_operand:DF 0 "register_operand" "")
9608 (neg:DF (match_operand:DF 1 "register_operand" "")))
9609 (clobber (reg:CC 17))]
9610 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9611 [(set (match_dup 0)
9612 (neg:DF (match_dup 1)))]
9613 "")
9614
9615(define_split
9616 [(set (match_operand:DF 0 "register_operand" "")
9617 (neg:DF (match_operand:DF 1 "register_operand" "")))
9618 (clobber (reg:CC 17))]
1b0c37d7
ZW
9619 "!TARGET_64BIT && TARGET_80387 && reload_completed
9620 && !FP_REGNO_P (REGNO (operands[0]))"
1ce485ec
JH
9621 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9622 (clobber (reg:CC 17))])]
383252a7 9623 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
1ce485ec
JH
9624 split_di (operands+0, 1, operands+2, operands+3);")
9625
06a964de
JH
9626(define_expand "negxf2"
9627 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2756c3d8 9628 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
06a964de 9629 (clobber (reg:CC 17))])]
1b0c37d7 9630 "!TARGET_64BIT && TARGET_80387"
06a964de
JH
9631 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9632
2b589241
JH
9633(define_expand "negtf2"
9634 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9635 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9636 (clobber (reg:CC 17))])]
9637 "TARGET_80387"
9638 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9639
e20440c1
JH
9640;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9641;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9642;; to itself.
06a964de 9643(define_insn "*negxf2_if"
e20440c1
JH
9644 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9645 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1ce485ec 9646 (clobber (reg:CC 17))]
1b0c37d7 9647 "!TARGET_64BIT && TARGET_80387
1e07edd3 9648 && ix86_unary_operator_ok (NEG, XFmode, operands)"
1ce485ec
JH
9649 "#")
9650
9651(define_split
9652 [(set (match_operand:XF 0 "register_operand" "")
9653 (neg:XF (match_operand:XF 1 "register_operand" "")))
9654 (clobber (reg:CC 17))]
9655 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9656 [(set (match_dup 0)
9657 (neg:XF (match_dup 1)))]
9658 "")
9659
9660(define_split
9661 [(set (match_operand:XF 0 "register_operand" "")
9662 (neg:XF (match_operand:XF 1 "register_operand" "")))
9663 (clobber (reg:CC 17))]
9664 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9665 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9666 (clobber (reg:CC 17))])]
9667 "operands[1] = GEN_INT (0x8000);
141e454b
JH
9668 operands[0] = gen_rtx_REG (SImode,
9669 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1ce485ec 9670
2b589241
JH
9671;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9672;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9673;; to itself.
9674(define_insn "*negtf2_if"
9675 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9676 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9677 (clobber (reg:CC 17))]
9678 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9679 "#")
9680
9681(define_split
9682 [(set (match_operand:TF 0 "register_operand" "")
9683 (neg:TF (match_operand:TF 1 "register_operand" "")))
9684 (clobber (reg:CC 17))]
9685 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9686 [(set (match_dup 0)
9687 (neg:TF (match_dup 1)))]
9688 "")
9689
9690(define_split
9691 [(set (match_operand:TF 0 "register_operand" "")
9692 (neg:TF (match_operand:TF 1 "register_operand" "")))
9693 (clobber (reg:CC 17))]
9694 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9695 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9696 (clobber (reg:CC 17))])]
9697 "operands[1] = GEN_INT (0x8000);
141e454b
JH
9698 operands[0] = gen_rtx_REG (SImode,
9699 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
2b589241 9700
1ce485ec
JH
9701;; Conditionize these after reload. If they matches before reload, we
9702;; lose the clobber and ability to use integer instructions.
9703
9704(define_insn "*negsf2_1"
886c62d1 9705 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 9706 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 9707 "TARGET_80387 && reload_completed"
10195bd8 9708 "fchs"
e075ae69 9709 [(set_attr "type" "fsgn")
6ef67412 9710 (set_attr "mode" "SF")
e075ae69 9711 (set_attr "ppro_uops" "few")])
886c62d1 9712
1ce485ec 9713(define_insn "*negdf2_1"
886c62d1 9714 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 9715 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 9716 "TARGET_80387 && reload_completed"
10195bd8 9717 "fchs"
e075ae69 9718 [(set_attr "type" "fsgn")
6ef67412 9719 (set_attr "mode" "DF")
e075ae69 9720 (set_attr "ppro_uops" "few")])
886c62d1 9721
6343a50e 9722(define_insn "*negextendsfdf2"
886c62d1 9723 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
9724 (neg:DF (float_extend:DF
9725 (match_operand:SF 1 "register_operand" "0"))))]
886c62d1 9726 "TARGET_80387"
10195bd8 9727 "fchs"
e075ae69 9728 [(set_attr "type" "fsgn")
6ef67412 9729 (set_attr "mode" "DF")
e075ae69 9730 (set_attr "ppro_uops" "few")])
4fb21e90 9731
1ce485ec 9732(define_insn "*negxf2_1"
4fb21e90 9733 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 9734 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
1b0c37d7 9735 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10195bd8 9736 "fchs"
e075ae69 9737 [(set_attr "type" "fsgn")
6ef67412 9738 (set_attr "mode" "XF")
e075ae69
RH
9739 (set_attr "ppro_uops" "few")])
9740
6343a50e 9741(define_insn "*negextenddfxf2"
e075ae69
RH
9742 [(set (match_operand:XF 0 "register_operand" "=f")
9743 (neg:XF (float_extend:XF
9744 (match_operand:DF 1 "register_operand" "0"))))]
1b0c37d7 9745 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
9746 "fchs"
9747 [(set_attr "type" "fsgn")
6ef67412 9748 (set_attr "mode" "XF")
e075ae69 9749 (set_attr "ppro_uops" "few")])
4fb21e90 9750
6343a50e 9751(define_insn "*negextendsfxf2"
4fb21e90 9752 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
9753 (neg:XF (float_extend:XF
9754 (match_operand:SF 1 "register_operand" "0"))))]
1b0c37d7 9755 "!TARGET_64BIT && TARGET_80387"
10195bd8 9756 "fchs"
e075ae69 9757 [(set_attr "type" "fsgn")
6ef67412 9758 (set_attr "mode" "XF")
e075ae69 9759 (set_attr "ppro_uops" "few")])
2b589241
JH
9760
9761(define_insn "*negtf2_1"
9762 [(set (match_operand:TF 0 "register_operand" "=f")
9763 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9764 "TARGET_80387 && reload_completed"
9765 "fchs"
9766 [(set_attr "type" "fsgn")
9767 (set_attr "mode" "XF")
9768 (set_attr "ppro_uops" "few")])
9769
9770(define_insn "*negextenddftf2"
9771 [(set (match_operand:TF 0 "register_operand" "=f")
9772 (neg:TF (float_extend:TF
9773 (match_operand:DF 1 "register_operand" "0"))))]
9774 "TARGET_80387"
9775 "fchs"
9776 [(set_attr "type" "fsgn")
9777 (set_attr "mode" "XF")
9778 (set_attr "ppro_uops" "few")])
9779
9780(define_insn "*negextendsftf2"
9781 [(set (match_operand:TF 0 "register_operand" "=f")
9782 (neg:TF (float_extend:TF
9783 (match_operand:SF 1 "register_operand" "0"))))]
9784 "TARGET_80387"
9785 "fchs"
9786 [(set_attr "type" "fsgn")
9787 (set_attr "mode" "XF")
9788 (set_attr "ppro_uops" "few")])
886c62d1
JVA
9789\f
9790;; Absolute value instructions
9791
06a964de
JH
9792(define_expand "abssf2"
9793 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2756c3d8 9794 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
06a964de
JH
9795 (clobber (reg:CC 17))])]
9796 "TARGET_80387"
ca29d1dc
JH
9797 "if (TARGET_SSE)
9798 {
9799 /* In case operand is in memory, we will not use SSE. */
9800 if (memory_operand (operands[0], VOIDmode)
9801 && rtx_equal_p (operands[0], operands[1]))
9802 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9803 else
9804 {
9805 /* Using SSE is tricky, since we need bitwise negation of -0
9806 in register. */
9807 rtx reg = gen_reg_rtx (SFmode);
141e454b
JH
9808 rtx dest = operands[0];
9809
9810 operands[1] = force_reg (SFmode, operands[1]);
9811 operands[0] = force_reg (SFmode, operands[0]);
9812 emit_move_insn (reg,
9813 gen_lowpart (SFmode,
9814 GEN_INT (trunc_int_for_mode (0x80000000,
9815 SImode))));
ca29d1dc 9816 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
141e454b
JH
9817 if (dest != operands[0])
9818 emit_move_insn (dest, operands[0]);
ca29d1dc
JH
9819 }
9820 DONE;
9821 }
9822 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9823
9824(define_insn "abssf2_memory"
9825 [(set (match_operand:SF 0 "memory_operand" "=m")
9826 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9827 (clobber (reg:CC 17))]
9828 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9829 "#")
9830
9831(define_insn "abssf2_ifs"
141e454b 9832 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
ca29d1dc 9833 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
141e454b 9834 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
ca29d1dc 9835 (clobber (reg:CC 17))]
141e454b
JH
9836 "TARGET_SSE
9837 && (reload_in_progress || reload_completed
9838 || (register_operand (operands[0], VOIDmode)
9839 && register_operand (operands[1], VOIDmode)))"
ca29d1dc
JH
9840 "#")
9841
9842(define_split
9843 [(set (match_operand:SF 0 "memory_operand" "")
9844 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9845 (use (match_operand:SF 2 "" ""))
9846 (clobber (reg:CC 17))]
9847 ""
9848 [(parallel [(set (match_dup 0)
9849 (abs:SF (match_dup 1)))
9850 (clobber (reg:CC 17))])])
9851
9852(define_split
9853 [(set (match_operand:SF 0 "register_operand" "")
9854 (abs:SF (match_operand:SF 1 "register_operand" "")))
9855 (use (match_operand:SF 2 "" ""))
9856 (clobber (reg:CC 17))]
9857 "reload_completed && !SSE_REG_P (operands[0])"
9858 [(parallel [(set (match_dup 0)
9859 (abs:SF (match_dup 1)))
9860 (clobber (reg:CC 17))])])
9861
9862(define_split
9863 [(set (match_operand:SF 0 "register_operand" "")
9864 (abs:SF (match_operand:SF 1 "register_operand" "")))
9865 (use (match_operand:SF 2 "register_operand" ""))
9866 (clobber (reg:CC 17))]
9867 "reload_completed && SSE_REG_P (operands[0])"
9868 [(set (subreg:TI (match_dup 0) 0)
9869 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9870 (subreg:TI (match_dup 1) 0)))])
06a964de 9871
e20440c1
JH
9872;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9873;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9874;; to itself.
06a964de 9875(define_insn "*abssf2_if"
e20440c1
JH
9876 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9877 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1ce485ec 9878 (clobber (reg:CC 17))]
ca29d1dc 9879 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
1ce485ec
JH
9880 "#")
9881
9882(define_split
9883 [(set (match_operand:SF 0 "register_operand" "")
9884 (abs:SF (match_operand:SF 1 "register_operand" "")))
9885 (clobber (reg:CC 17))]
9886 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9887 [(set (match_dup 0)
9888 (abs:SF (match_dup 1)))]
9889 "")
9890
9891(define_split
9892 [(set (match_operand:SF 0 "register_operand" "")
9893 (abs:SF (match_operand:SF 1 "register_operand" "")))
9894 (clobber (reg:CC 17))]
9895 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9896 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9897 (clobber (reg:CC 17))])]
383252a7 9898 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1ce485ec
JH
9899 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9900
9901(define_split
9902 [(set (match_operand 0 "memory_operand" "")
9903 (abs (match_operand 1 "memory_operand" "")))
9904 (clobber (reg:CC 17))]
9905 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9906 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9907 (clobber (reg:CC 17))])]
1ce485ec
JH
9908{
9909 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9910
b3298882
JH
9911 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9912 if (size >= 12)
1ce485ec 9913 size = 10;
b72f00af 9914 operands[0] = adjust_address (operands[0], QImode, size - 1);
383252a7 9915 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
0f40f9f7 9916})
1ce485ec 9917
06a964de
JH
9918(define_expand "absdf2"
9919 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2756c3d8 9920 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
06a964de 9921 (clobber (reg:CC 17))])]
1ce485ec 9922 "TARGET_80387"
ca29d1dc
JH
9923 "if (TARGET_SSE2)
9924 {
9925 /* In case operand is in memory, we will not use SSE. */
9926 if (memory_operand (operands[0], VOIDmode)
9927 && rtx_equal_p (operands[0], operands[1]))
9928 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9929 else
9930 {
9931 /* Using SSE is tricky, since we need bitwise negation of -0
9932 in register. */
9933 rtx reg = gen_reg_rtx (DFmode);
9934#if HOST_BITS_PER_WIDE_INT >= 64
141e454b
JH
9935 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9936 DImode));
ca29d1dc
JH
9937#else
9938 rtx imm = immed_double_const (0, 0x80000000, DImode);
9939#endif
141e454b
JH
9940 rtx dest = operands[0];
9941
9942 operands[1] = force_reg (DFmode, operands[1]);
9943 operands[0] = force_reg (DFmode, operands[0]);
ca29d1dc
JH
9944 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9945 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
141e454b
JH
9946 if (dest != operands[0])
9947 emit_move_insn (dest, operands[0]);
ca29d1dc
JH
9948 }
9949 DONE;
9950 }
9951 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9952
9953(define_insn "absdf2_memory"
9954 [(set (match_operand:DF 0 "memory_operand" "=m")
9955 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9956 (clobber (reg:CC 17))]
9957 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9958 "#")
9959
9960(define_insn "absdf2_ifs"
141e454b 9961 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
ca29d1dc 9962 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
141e454b 9963 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
ca29d1dc 9964 (clobber (reg:CC 17))]
1b0c37d7 9965 "!TARGET_64BIT && TARGET_SSE2
141e454b
JH
9966 && (reload_in_progress || reload_completed
9967 || (register_operand (operands[0], VOIDmode)
9968 && register_operand (operands[1], VOIDmode)))"
9969 "#")
9970
9971(define_insn "*absdf2_ifs_rex64"
9972 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9973 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9974 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9975 (clobber (reg:CC 17))]
1b0c37d7 9976 "TARGET_64BIT && TARGET_SSE2
141e454b
JH
9977 && (reload_in_progress || reload_completed
9978 || (register_operand (operands[0], VOIDmode)
9979 && register_operand (operands[1], VOIDmode)))"
ca29d1dc
JH
9980 "#")
9981
9982(define_split
9983 [(set (match_operand:DF 0 "memory_operand" "")
9984 (abs:DF (match_operand:DF 1 "memory_operand" "")))
9985 (use (match_operand:DF 2 "" ""))
9986 (clobber (reg:CC 17))]
9987 ""
9988 [(parallel [(set (match_dup 0)
9989 (abs:DF (match_dup 1)))
9990 (clobber (reg:CC 17))])])
9991
9992(define_split
9993 [(set (match_operand:DF 0 "register_operand" "")
9994 (abs:DF (match_operand:DF 1 "register_operand" "")))
9995 (use (match_operand:DF 2 "" ""))
9996 (clobber (reg:CC 17))]
9997 "reload_completed && !SSE_REG_P (operands[0])"
9998 [(parallel [(set (match_dup 0)
9999 (abs:DF (match_dup 1)))
10000 (clobber (reg:CC 17))])])
10001
10002(define_split
10003 [(set (match_operand:DF 0 "register_operand" "")
10004 (abs:DF (match_operand:DF 1 "register_operand" "")))
10005 (use (match_operand:DF 2 "register_operand" ""))
10006 (clobber (reg:CC 17))]
10007 "reload_completed && SSE_REG_P (operands[0])"
10008 [(set (subreg:TI (match_dup 0) 0)
10009 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10010 (subreg:TI (match_dup 1) 0)))])
10011
06a964de 10012
e20440c1
JH
10013;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10014;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10015;; to itself.
06a964de 10016(define_insn "*absdf2_if"
e20440c1
JH
10017 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10018 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
06a964de 10019 (clobber (reg:CC 17))]
1b0c37d7 10020 "!TARGET_64BIT && TARGET_80387
141e454b
JH
10021 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10022 "#")
10023
10024;; FIXME: We should to allow integer registers here. Problem is that
10025;; we need another scratch register to get constant from.
10026;; Forcing constant to mem if no register available in peep2 should be
10027;; safe even for PIC mode, because of RIP relative addressing.
10028(define_insn "*absdf2_if_rex64"
10029 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10030 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10031 (clobber (reg:CC 17))]
1b0c37d7 10032 "TARGET_64BIT && TARGET_80387
141e454b 10033 && ix86_unary_operator_ok (ABS, DFmode, operands)"
1ce485ec
JH
10034 "#")
10035
10036(define_split
10037 [(set (match_operand:DF 0 "register_operand" "")
10038 (abs:DF (match_operand:DF 1 "register_operand" "")))
10039 (clobber (reg:CC 17))]
10040 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10041 [(set (match_dup 0)
10042 (abs:DF (match_dup 1)))]
10043 "")
10044
10045(define_split
10046 [(set (match_operand:DF 0 "register_operand" "")
10047 (abs:DF (match_operand:DF 1 "register_operand" "")))
10048 (clobber (reg:CC 17))]
1b0c37d7
ZW
10049 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10050 !FP_REGNO_P (REGNO (operands[0]))"
1ce485ec
JH
10051 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10052 (clobber (reg:CC 17))])]
383252a7 10053 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1ce485ec
JH
10054 split_di (operands+0, 1, operands+2, operands+3);")
10055
06a964de
JH
10056(define_expand "absxf2"
10057 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2756c3d8 10058 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
06a964de 10059 (clobber (reg:CC 17))])]
1b0c37d7 10060 "!TARGET_64BIT && TARGET_80387"
06a964de
JH
10061 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10062
2b589241
JH
10063(define_expand "abstf2"
10064 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10065 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10066 (clobber (reg:CC 17))])]
10067 "TARGET_80387"
10068 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10069
e20440c1
JH
10070;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10071;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10072;; to itself.
06a964de 10073(define_insn "*absxf2_if"
e20440c1
JH
10074 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10075 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1ce485ec 10076 (clobber (reg:CC 17))]
1b0c37d7 10077 "!TARGET_64BIT && TARGET_80387
1e07edd3 10078 && ix86_unary_operator_ok (ABS, XFmode, operands)"
1ce485ec
JH
10079 "#")
10080
10081(define_split
10082 [(set (match_operand:XF 0 "register_operand" "")
10083 (abs:XF (match_operand:XF 1 "register_operand" "")))
10084 (clobber (reg:CC 17))]
10085 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10086 [(set (match_dup 0)
10087 (abs:XF (match_dup 1)))]
10088 "")
10089
10090(define_split
10091 [(set (match_operand:XF 0 "register_operand" "")
10092 (abs:XF (match_operand:XF 1 "register_operand" "")))
10093 (clobber (reg:CC 17))]
10094 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10095 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10096 (clobber (reg:CC 17))])]
141e454b
JH
10097 "operands[1] = GEN_INT (~0x8000);
10098 operands[0] = gen_rtx_REG (SImode,
10099 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1ce485ec 10100
2b589241
JH
10101(define_insn "*abstf2_if"
10102 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10103 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10104 (clobber (reg:CC 17))]
10105 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10106 "#")
10107
10108(define_split
10109 [(set (match_operand:TF 0 "register_operand" "")
10110 (abs:TF (match_operand:TF 1 "register_operand" "")))
10111 (clobber (reg:CC 17))]
10112 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10113 [(set (match_dup 0)
10114 (abs:TF (match_dup 1)))]
10115 "")
10116
10117(define_split
10118 [(set (match_operand:TF 0 "register_operand" "")
10119 (abs:TF (match_operand:TF 1 "register_operand" "")))
10120 (clobber (reg:CC 17))]
10121 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10122 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10123 (clobber (reg:CC 17))])]
141e454b
JH
10124 "operands[1] = GEN_INT (~0x8000);
10125 operands[0] = gen_rtx_REG (SImode,
10126 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
2b589241 10127
1ce485ec 10128(define_insn "*abssf2_1"
886c62d1 10129 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 10130 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 10131 "TARGET_80387 && reload_completed"
2ae0f82c 10132 "fabs"
6ef67412
JH
10133 [(set_attr "type" "fsgn")
10134 (set_attr "mode" "SF")])
886c62d1 10135
1ce485ec 10136(define_insn "*absdf2_1"
886c62d1 10137 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 10138 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 10139 "TARGET_80387 && reload_completed"
2ae0f82c 10140 "fabs"
6ef67412
JH
10141 [(set_attr "type" "fsgn")
10142 (set_attr "mode" "DF")])
886c62d1 10143
6343a50e 10144(define_insn "*absextendsfdf2"
886c62d1 10145 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
10146 (abs:DF (float_extend:DF
10147 (match_operand:SF 1 "register_operand" "0"))))]
886c62d1 10148 "TARGET_80387"
2ae0f82c 10149 "fabs"
6ef67412
JH
10150 [(set_attr "type" "fsgn")
10151 (set_attr "mode" "DF")])
886c62d1 10152
1ce485ec 10153(define_insn "*absxf2_1"
4fb21e90 10154 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 10155 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
1b0c37d7 10156 "!TARGET_64BIT && TARGET_80387 && reload_completed"
2ae0f82c 10157 "fabs"
6ef67412
JH
10158 [(set_attr "type" "fsgn")
10159 (set_attr "mode" "DF")])
4fb21e90 10160
6343a50e 10161(define_insn "*absextenddfxf2"
4fb21e90 10162 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
10163 (abs:XF (float_extend:XF
10164 (match_operand:DF 1 "register_operand" "0"))))]
1b0c37d7 10165 "!TARGET_64BIT && TARGET_80387"
2ae0f82c 10166 "fabs"
6ef67412
JH
10167 [(set_attr "type" "fsgn")
10168 (set_attr "mode" "XF")])
a199fdd6 10169
6343a50e 10170(define_insn "*absextendsfxf2"
58733f96 10171 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
10172 (abs:XF (float_extend:XF
10173 (match_operand:SF 1 "register_operand" "0"))))]
1b0c37d7 10174 "!TARGET_64BIT && TARGET_80387"
e075ae69 10175 "fabs"
6ef67412
JH
10176 [(set_attr "type" "fsgn")
10177 (set_attr "mode" "XF")])
2b589241
JH
10178
10179(define_insn "*abstf2_1"
10180 [(set (match_operand:TF 0 "register_operand" "=f")
10181 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10182 "TARGET_80387 && reload_completed"
10183 "fabs"
10184 [(set_attr "type" "fsgn")
10185 (set_attr "mode" "DF")])
10186
10187(define_insn "*absextenddftf2"
10188 [(set (match_operand:TF 0 "register_operand" "=f")
10189 (abs:TF (float_extend:TF
10190 (match_operand:DF 1 "register_operand" "0"))))]
10191 "TARGET_80387"
10192 "fabs"
10193 [(set_attr "type" "fsgn")
10194 (set_attr "mode" "XF")])
10195
10196(define_insn "*absextendsftf2"
10197 [(set (match_operand:TF 0 "register_operand" "=f")
10198 (abs:TF (float_extend:TF
10199 (match_operand:SF 1 "register_operand" "0"))))]
10200 "TARGET_80387"
10201 "fabs"
10202 [(set_attr "type" "fsgn")
10203 (set_attr "mode" "XF")])
886c62d1 10204\f
e075ae69 10205;; One complement instructions
886c62d1 10206
9b70259d
JH
10207(define_expand "one_cmpldi2"
10208 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10209 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10210 "TARGET_64BIT"
10211 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10212
10213(define_insn "*one_cmpldi2_1_rex64"
10214 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10215 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10216 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
0f40f9f7 10217 "not{q}\t%0"
9b70259d
JH
10218 [(set_attr "type" "negnot")
10219 (set_attr "mode" "DI")])
10220
10221(define_insn "*one_cmpldi2_2_rex64"
10222 [(set (reg 17)
10223 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10224 (const_int 0)))
10225 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10226 (not:DI (match_dup 1)))]
10227 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10228 && ix86_unary_operator_ok (NOT, DImode, operands)"
10229 "#"
10230 [(set_attr "type" "alu1")
10231 (set_attr "mode" "DI")])
10232
10233(define_split
10234 [(set (reg 17)
10235 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10236 (const_int 0)))
10237 (set (match_operand:DI 0 "nonimmediate_operand" "")
10238 (not:DI (match_dup 1)))]
10239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10240 [(parallel [(set (reg:CCNO 17)
10241 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10242 (const_int 0)))
10243 (set (match_dup 0)
10244 (xor:DI (match_dup 1) (const_int -1)))])]
10245 "")
10246
06a964de 10247(define_expand "one_cmplsi2"
a1cbdd7f
JH
10248 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10249 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
10250 ""
10251 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10252
10253(define_insn "*one_cmplsi2_1"
2ae0f82c
SC
10254 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10255 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 10256 "ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 10257 "not{l}\t%0"
6ef67412
JH
10258 [(set_attr "type" "negnot")
10259 (set_attr "mode" "SI")])
bb524860 10260
9b70259d
JH
10261;; ??? Currently never generated - xor is used instead.
10262(define_insn "*one_cmplsi2_1_zext"
10263 [(set (match_operand:DI 0 "register_operand" "=r")
10264 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10265 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
0f40f9f7 10266 "not{l}\t%k0"
9b70259d
JH
10267 [(set_attr "type" "negnot")
10268 (set_attr "mode" "SI")])
10269
06a964de 10270(define_insn "*one_cmplsi2_2"
16189740
RH
10271 [(set (reg 17)
10272 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10273 (const_int 0)))
e075ae69
RH
10274 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10275 (not:SI (match_dup 1)))]
16189740
RH
10276 "ix86_match_ccmode (insn, CCNOmode)
10277 && ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 10278 "#"
6ef67412
JH
10279 [(set_attr "type" "alu1")
10280 (set_attr "mode" "SI")])
e075ae69
RH
10281
10282(define_split
16189740
RH
10283 [(set (reg 17)
10284 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10285 (const_int 0)))
e075ae69
RH
10286 (set (match_operand:SI 0 "nonimmediate_operand" "")
10287 (not:SI (match_dup 1)))]
16189740 10288 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
10289 [(parallel [(set (reg:CCNO 17)
10290 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10291 (const_int 0)))
10292 (set (match_dup 0)
10293 (xor:SI (match_dup 1) (const_int -1)))])]
10294 "")
886c62d1 10295
9b70259d
JH
10296;; ??? Currently never generated - xor is used instead.
10297(define_insn "*one_cmplsi2_2_zext"
10298 [(set (reg 17)
10299 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10300 (const_int 0)))
10301 (set (match_operand:DI 0 "register_operand" "=r")
10302 (zero_extend:DI (not:SI (match_dup 1))))]
10303 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10304 && ix86_unary_operator_ok (NOT, SImode, operands)"
10305 "#"
10306 [(set_attr "type" "alu1")
10307 (set_attr "mode" "SI")])
10308
10309(define_split
10310 [(set (reg 17)
10311 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10312 (const_int 0)))
10313 (set (match_operand:DI 0 "register_operand" "")
10314 (zero_extend:DI (not:SI (match_dup 1))))]
10315 "ix86_match_ccmode (insn, CCNOmode)"
10316 [(parallel [(set (reg:CCNO 17)
10317 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10318 (const_int 0)))
10319 (set (match_dup 0)
10320 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10321 "")
10322
06a964de 10323(define_expand "one_cmplhi2"
a1cbdd7f
JH
10324 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10325 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 10326 "TARGET_HIMODE_MATH"
06a964de
JH
10327 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10328
10329(define_insn "*one_cmplhi2_1"
2ae0f82c
SC
10330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10331 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 10332 "ix86_unary_operator_ok (NOT, HImode, operands)"
0f40f9f7 10333 "not{w}\t%0"
6ef67412
JH
10334 [(set_attr "type" "negnot")
10335 (set_attr "mode" "HI")])
bb524860 10336
06a964de 10337(define_insn "*one_cmplhi2_2"
16189740
RH
10338 [(set (reg 17)
10339 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10340 (const_int 0)))
e075ae69
RH
10341 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10342 (not:HI (match_dup 1)))]
16189740
RH
10343 "ix86_match_ccmode (insn, CCNOmode)
10344 && ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 10345 "#"
6ef67412
JH
10346 [(set_attr "type" "alu1")
10347 (set_attr "mode" "HI")])
e075ae69
RH
10348
10349(define_split
16189740
RH
10350 [(set (reg 17)
10351 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10352 (const_int 0)))
e075ae69
RH
10353 (set (match_operand:HI 0 "nonimmediate_operand" "")
10354 (not:HI (match_dup 1)))]
16189740 10355 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
10356 [(parallel [(set (reg:CCNO 17)
10357 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10358 (const_int 0)))
10359 (set (match_dup 0)
10360 (xor:HI (match_dup 1) (const_int -1)))])]
10361 "")
886c62d1 10362
e075ae69 10363;; %%% Potential partial reg stall on alternative 1. What to do?
06a964de 10364(define_expand "one_cmplqi2"
a1cbdd7f
JH
10365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10366 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 10367 "TARGET_QIMODE_MATH"
06a964de
JH
10368 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10369
10370(define_insn "*one_cmplqi2_1"
7c6b971d 10371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69 10372 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
a1cbdd7f 10373 "ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10374 "@
0f40f9f7
ZW
10375 not{b}\t%0
10376 not{l}\t%k0"
6ef67412
JH
10377 [(set_attr "type" "negnot")
10378 (set_attr "mode" "QI,SI")])
bb524860 10379
06a964de 10380(define_insn "*one_cmplqi2_2"
16189740
RH
10381 [(set (reg 17)
10382 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10383 (const_int 0)))
e075ae69
RH
10384 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10385 (not:QI (match_dup 1)))]
16189740
RH
10386 "ix86_match_ccmode (insn, CCNOmode)
10387 && ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 10388 "#"
6ef67412
JH
10389 [(set_attr "type" "alu1")
10390 (set_attr "mode" "QI")])
e075ae69
RH
10391
10392(define_split
16189740
RH
10393 [(set (reg 17)
10394 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10395 (const_int 0)))
e075ae69
RH
10396 (set (match_operand:QI 0 "nonimmediate_operand" "")
10397 (not:QI (match_dup 1)))]
16189740 10398 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
10399 [(parallel [(set (reg:CCNO 17)
10400 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10401 (const_int 0)))
10402 (set (match_dup 0)
10403 (xor:QI (match_dup 1) (const_int -1)))])]
10404 "")
886c62d1 10405\f
e075ae69 10406;; Arithmetic shift instructions
886c62d1
JVA
10407
10408;; DImode shifts are implemented using the i386 "shift double" opcode,
10409;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10410;; is variable, then the count is in %cl and the "imm" operand is dropped
10411;; from the assembler input.
e075ae69 10412;;
886c62d1
JVA
10413;; This instruction shifts the target reg/mem as usual, but instead of
10414;; shifting in zeros, bits are shifted in from reg operand. If the insn
10415;; is a left shift double, bits are taken from the high order bits of
10416;; reg, else if the insn is a shift right double, bits are taken from the
10417;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10418;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 10419;;
886c62d1
JVA
10420;; Since sh[lr]d does not change the `reg' operand, that is done
10421;; separately, making all shifts emit pairs of shift double and normal
10422;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10423;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 10424;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 10425;;
886c62d1
JVA
10426;; If the shift count is a constant, we need never emit more than one
10427;; shift pair, instead using moves and sign extension for counts greater
10428;; than 31.
10429
56c0e8fa 10430(define_expand "ashldi3"
371bc54b
JH
10431 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10432 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
3d117b30 10433 (match_operand:QI 2 "nonmemory_operand" "")))
e075ae69 10434 (clobber (reg:CC 17))])]
56c0e8fa 10435 ""
56c0e8fa 10436{
3d117b30 10437 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
56c0e8fa 10438 {
e075ae69
RH
10439 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10440 DONE;
56c0e8fa 10441 }
371bc54b
JH
10442 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10443 DONE;
0f40f9f7 10444})
56c0e8fa 10445
371bc54b
JH
10446(define_insn "*ashldi3_1_rex64"
10447 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10448 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
7c17f553 10449 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
371bc54b
JH
10450 (clobber (reg:CC 17))]
10451 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10452{
10453 switch (get_attr_type (insn))
10454 {
10455 case TYPE_ALU:
10456 if (operands[2] != const1_rtx)
10457 abort ();
10458 if (!rtx_equal_p (operands[0], operands[1]))
10459 abort ();
0f40f9f7 10460 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10461
10462 case TYPE_LEA:
10463 if (GET_CODE (operands[2]) != CONST_INT
10464 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10465 abort ();
10466 operands[1] = gen_rtx_MULT (DImode, operands[1],
10467 GEN_INT (1 << INTVAL (operands[2])));
0f40f9f7 10468 return "lea{q}\t{%a1, %0|%0, %a1}";
371bc54b
JH
10469
10470 default:
10471 if (REG_P (operands[2]))
0f40f9f7 10472 return "sal{q}\t{%b2, %0|%0, %b2}";
371bc54b
JH
10473 else if (GET_CODE (operands[2]) == CONST_INT
10474 && INTVAL (operands[2]) == 1
10475 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10476 return "sal{q}\t%0";
371bc54b 10477 else
0f40f9f7 10478 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10479 }
0f40f9f7 10480}
371bc54b
JH
10481 [(set (attr "type")
10482 (cond [(eq_attr "alternative" "1")
10483 (const_string "lea")
10484 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10485 (const_int 0))
10486 (match_operand 0 "register_operand" ""))
10487 (match_operand 2 "const1_operand" ""))
10488 (const_string "alu")
10489 ]
10490 (const_string "ishift")))
10491 (set_attr "mode" "DI")])
10492
10493;; Convert lea to the lea pattern to avoid flags dependency.
10494(define_split
10495 [(set (match_operand:DI 0 "register_operand" "")
10496 (ashift:DI (match_operand:DI 1 "register_operand" "")
10497 (match_operand:QI 2 "immediate_operand" "")))
10498 (clobber (reg:CC 17))]
1b0c37d7 10499 "TARGET_64BIT && reload_completed
371bc54b
JH
10500 && true_regnum (operands[0]) != true_regnum (operands[1])"
10501 [(set (match_dup 0)
10502 (mult:DI (match_dup 1)
10503 (match_dup 2)))]
383252a7
AO
10504 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10505 DImode));")
371bc54b
JH
10506
10507;; This pattern can't accept a variable shift count, since shifts by
10508;; zero don't affect the flags. We assume that shifts by constant
10509;; zero are optimized away.
10510(define_insn "*ashldi3_cmp_rex64"
10511 [(set (reg 17)
10512 (compare
10513 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10514 (match_operand:QI 2 "immediate_operand" "e"))
10515 (const_int 0)))
10516 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10517 (ashift:DI (match_dup 1) (match_dup 2)))]
10518 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10519 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
371bc54b
JH
10520{
10521 switch (get_attr_type (insn))
10522 {
10523 case TYPE_ALU:
10524 if (operands[2] != const1_rtx)
10525 abort ();
0f40f9f7 10526 return "add{q}\t{%0, %0|%0, %0}";
371bc54b
JH
10527
10528 default:
10529 if (REG_P (operands[2]))
0f40f9f7 10530 return "sal{q}\t{%b2, %0|%0, %b2}";
371bc54b
JH
10531 else if (GET_CODE (operands[2]) == CONST_INT
10532 && INTVAL (operands[2]) == 1
10533 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10534 return "sal{q}\t%0";
371bc54b 10535 else
0f40f9f7 10536 return "sal{q}\t{%2, %0|%0, %2}";
371bc54b 10537 }
0f40f9f7 10538}
371bc54b
JH
10539 [(set (attr "type")
10540 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10541 (const_int 0))
10542 (match_operand 0 "register_operand" ""))
10543 (match_operand 2 "const1_operand" ""))
10544 (const_string "alu")
10545 ]
10546 (const_string "ishift")))
10547 (set_attr "mode" "DI")])
10548
e075ae69
RH
10549(define_insn "ashldi3_1"
10550 [(set (match_operand:DI 0 "register_operand" "=r")
56c0e8fa 10551 (ashift:DI (match_operand:DI 1 "register_operand" "0")
e075ae69
RH
10552 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10553 (clobber (match_scratch:SI 3 "=&r"))
10554 (clobber (reg:CC 17))]
371bc54b 10555 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
10556 "#"
10557 [(set_attr "type" "multi")])
886c62d1 10558
e075ae69
RH
10559(define_insn "*ashldi3_2"
10560 [(set (match_operand:DI 0 "register_operand" "=r")
56c0e8fa 10561 (ashift:DI (match_operand:DI 1 "register_operand" "0")
e075ae69
RH
10562 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10563 (clobber (reg:CC 17))]
371bc54b 10564 "!TARGET_64BIT"
e075ae69
RH
10565 "#"
10566 [(set_attr "type" "multi")])
886c62d1 10567
e075ae69
RH
10568(define_split
10569 [(set (match_operand:DI 0 "register_operand" "")
10570 (ashift:DI (match_operand:DI 1 "register_operand" "")
10571 (match_operand:QI 2 "nonmemory_operand" "")))
10572 (clobber (match_scratch:SI 3 ""))
10573 (clobber (reg:CC 17))]
371bc54b 10574 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
e075ae69
RH
10575 [(const_int 0)]
10576 "ix86_split_ashldi (operands, operands[3]); DONE;")
47f59fd4 10577
e075ae69
RH
10578(define_split
10579 [(set (match_operand:DI 0 "register_operand" "")
10580 (ashift:DI (match_operand:DI 1 "register_operand" "")
10581 (match_operand:QI 2 "nonmemory_operand" "")))
10582 (clobber (reg:CC 17))]
371bc54b 10583 "!TARGET_64BIT && reload_completed"
e075ae69
RH
10584 [(const_int 0)]
10585 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6ec6d558 10586
e075ae69
RH
10587(define_insn "x86_shld_1"
10588 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10589 (ior:SI (ashift:SI (match_dup 0)
10590 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10591 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10592 (minus:QI (const_int 32) (match_dup 2)))))
10593 (clobber (reg:CC 17))]
6ec6d558 10594 ""
e075ae69 10595 "@
0f40f9f7
ZW
10596 shld{l}\t{%2, %1, %0|%0, %1, %2}
10597 shld{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 10598 [(set_attr "type" "ishift")
6ef67412
JH
10599 (set_attr "prefix_0f" "1")
10600 (set_attr "mode" "SI")
e075ae69 10601 (set_attr "pent_pair" "np")
309ada50 10602 (set_attr "athlon_decode" "vector")
e075ae69
RH
10603 (set_attr "ppro_uops" "few")])
10604
10605(define_expand "x86_shift_adj_1"
16189740
RH
10606 [(set (reg:CCZ 17)
10607 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10608 (const_int 32))
10609 (const_int 0)))
e075ae69 10610 (set (match_operand:SI 0 "register_operand" "")
16189740 10611 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
10612 (match_operand:SI 1 "register_operand" "")
10613 (match_dup 0)))
10614 (set (match_dup 1)
16189740 10615 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
10616 (match_operand:SI 3 "register_operand" "r")
10617 (match_dup 1)))]
10618 "TARGET_CMOVE"
6ec6d558
JH
10619 "")
10620
e075ae69
RH
10621(define_expand "x86_shift_adj_2"
10622 [(use (match_operand:SI 0 "register_operand" ""))
10623 (use (match_operand:SI 1 "register_operand" ""))
10624 (use (match_operand:QI 2 "register_operand" ""))]
886c62d1 10625 ""
e075ae69
RH
10626{
10627 rtx label = gen_label_rtx ();
10628 rtx tmp;
886c62d1 10629
16189740 10630 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
886c62d1 10631
16189740 10632 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
10633 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10634 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10635 gen_rtx_LABEL_REF (VOIDmode, label),
10636 pc_rtx);
10637 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10638 JUMP_LABEL (tmp) = label;
886c62d1 10639
e075ae69
RH
10640 emit_move_insn (operands[0], operands[1]);
10641 emit_move_insn (operands[1], const0_rtx);
886c62d1 10642
e075ae69
RH
10643 emit_label (label);
10644 LABEL_NUSES (label) = 1;
56c0e8fa
JVA
10645
10646 DONE;
0f40f9f7 10647})
56c0e8fa 10648
d525dfdf
JH
10649(define_expand "ashlsi3"
10650 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10651 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10652 (match_operand:QI 2 "nonmemory_operand" "")))
10653 (clobber (reg:CC 17))]
10654 ""
10655 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10656
10657(define_insn "*ashlsi3_1"
e075ae69
RH
10658 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10659 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10660 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10661 (clobber (reg:CC 17))]
d525dfdf 10662 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
2ae0f82c 10663{
e075ae69
RH
10664 switch (get_attr_type (insn))
10665 {
10666 case TYPE_ALU:
10667 if (operands[2] != const1_rtx)
10668 abort ();
10669 if (!rtx_equal_p (operands[0], operands[1]))
10670 abort ();
0f40f9f7 10671 return "add{l}\t{%0, %0|%0, %0}";
2ae0f82c 10672
e075ae69 10673 case TYPE_LEA:
0f40f9f7 10674 return "#";
2ae0f82c 10675
e075ae69
RH
10676 default:
10677 if (REG_P (operands[2]))
0f40f9f7 10678 return "sal{l}\t{%b2, %0|%0, %b2}";
8bad7136
JL
10679 else if (GET_CODE (operands[2]) == CONST_INT
10680 && INTVAL (operands[2]) == 1
10681 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10682 return "sal{l}\t%0";
e075ae69 10683 else
0f40f9f7 10684 return "sal{l}\t{%2, %0|%0, %2}";
e075ae69 10685 }
0f40f9f7 10686}
e075ae69
RH
10687 [(set (attr "type")
10688 (cond [(eq_attr "alternative" "1")
10689 (const_string "lea")
10690 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10691 (const_int 0))
10692 (match_operand 0 "register_operand" ""))
10693 (match_operand 2 "const1_operand" ""))
10694 (const_string "alu")
10695 ]
6ef67412
JH
10696 (const_string "ishift")))
10697 (set_attr "mode" "SI")])
e075ae69 10698
1c27d4b2
JH
10699;; Convert lea to the lea pattern to avoid flags dependency.
10700(define_split
58787064
JH
10701 [(set (match_operand 0 "register_operand" "")
10702 (ashift (match_operand 1 "register_operand" "")
ca4ae08d 10703 (match_operand:QI 2 "const_int_operand" "")))
1c27d4b2 10704 (clobber (reg:CC 17))]
abe24fb3
JH
10705 "reload_completed
10706 && true_regnum (operands[0]) != true_regnum (operands[1])"
58787064 10707 [(const_int 0)]
58787064
JH
10708{
10709 rtx pat;
10710 operands[0] = gen_lowpart (SImode, operands[0]);
10711 operands[1] = gen_lowpart (Pmode, operands[1]);
383252a7
AO
10712 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10713 Pmode));
58787064
JH
10714 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10715 if (Pmode != SImode)
10716 pat = gen_rtx_SUBREG (SImode, pat, 0);
10717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10718 DONE;
0f40f9f7 10719})
1c27d4b2 10720
371bc54b
JH
10721(define_insn "*ashlsi3_1_zext"
10722 [(set (match_operand:DI 0 "register_operand" "=r,r")
10723 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10724 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10725 (clobber (reg:CC 17))]
1b0c37d7 10726 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10727{
10728 switch (get_attr_type (insn))
10729 {
10730 case TYPE_ALU:
10731 if (operands[2] != const1_rtx)
10732 abort ();
0f40f9f7 10733 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10734
10735 case TYPE_LEA:
0f40f9f7 10736 return "#";
371bc54b
JH
10737
10738 default:
10739 if (REG_P (operands[2]))
0f40f9f7 10740 return "sal{l}\t{%b2, %k0|%k0, %b2}";
371bc54b
JH
10741 else if (GET_CODE (operands[2]) == CONST_INT
10742 && INTVAL (operands[2]) == 1
10743 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10744 return "sal{l}\t%k0";
371bc54b 10745 else
0f40f9f7 10746 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10747 }
0f40f9f7 10748}
371bc54b
JH
10749 [(set (attr "type")
10750 (cond [(eq_attr "alternative" "1")
10751 (const_string "lea")
10752 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10753 (const_int 0))
10754 (match_operand 2 "const1_operand" ""))
10755 (const_string "alu")
10756 ]
10757 (const_string "ishift")))
10758 (set_attr "mode" "SI")])
10759
10760;; Convert lea to the lea pattern to avoid flags dependency.
10761(define_split
10762 [(set (match_operand:DI 0 "register_operand" "")
10763 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10764 (match_operand:QI 2 "const_int_operand" ""))))
10765 (clobber (reg:CC 17))]
10766 "reload_completed
10767 && true_regnum (operands[0]) != true_regnum (operands[1])"
10768 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
371bc54b
JH
10769{
10770 operands[1] = gen_lowpart (Pmode, operands[1]);
383252a7
AO
10771 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10772 Pmode));
0f40f9f7 10773})
371bc54b 10774
28cefcd2
BS
10775;; This pattern can't accept a variable shift count, since shifts by
10776;; zero don't affect the flags. We assume that shifts by constant
10777;; zero are optimized away.
2c873473 10778(define_insn "*ashlsi3_cmp"
16189740
RH
10779 [(set (reg 17)
10780 (compare
e075ae69 10781 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
28cefcd2 10782 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
10783 (const_int 0)))
10784 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10785 (ashift:SI (match_dup 1) (match_dup 2)))]
9076b9c1 10786 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10787 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1 10788{
e075ae69 10789 switch (get_attr_type (insn))
886c62d1 10790 {
e075ae69
RH
10791 case TYPE_ALU:
10792 if (operands[2] != const1_rtx)
10793 abort ();
0f40f9f7 10794 return "add{l}\t{%0, %0|%0, %0}";
886c62d1 10795
e075ae69
RH
10796 default:
10797 if (REG_P (operands[2]))
0f40f9f7 10798 return "sal{l}\t{%b2, %0|%0, %b2}";
8bad7136
JL
10799 else if (GET_CODE (operands[2]) == CONST_INT
10800 && INTVAL (operands[2]) == 1
10801 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10802 return "sal{l}\t%0";
e075ae69 10803 else
0f40f9f7 10804 return "sal{l}\t{%2, %0|%0, %2}";
56c0e8fa 10805 }
0f40f9f7 10806}
e075ae69
RH
10807 [(set (attr "type")
10808 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10809 (const_int 0))
10810 (match_operand 0 "register_operand" ""))
10811 (match_operand 2 "const1_operand" ""))
10812 (const_string "alu")
10813 ]
6ef67412
JH
10814 (const_string "ishift")))
10815 (set_attr "mode" "SI")])
e075ae69 10816
371bc54b
JH
10817(define_insn "*ashlsi3_cmp_zext"
10818 [(set (reg 17)
10819 (compare
10820 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10821 (match_operand:QI 2 "immediate_operand" "I"))
10822 (const_int 0)))
10823 (set (match_operand:DI 0 "register_operand" "=r")
10824 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10825 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10826 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
371bc54b
JH
10827{
10828 switch (get_attr_type (insn))
10829 {
10830 case TYPE_ALU:
10831 if (operands[2] != const1_rtx)
10832 abort ();
0f40f9f7 10833 return "add{l}\t{%k0, %k0|%k0, %k0}";
371bc54b
JH
10834
10835 default:
10836 if (REG_P (operands[2]))
0f40f9f7 10837 return "sal{l}\t{%b2, %k0|%k0, %b2}";
371bc54b
JH
10838 else if (GET_CODE (operands[2]) == CONST_INT
10839 && INTVAL (operands[2]) == 1
10840 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10841 return "sal{l}\t%k0";
371bc54b 10842 else
0f40f9f7 10843 return "sal{l}\t{%2, %k0|%k0, %2}";
371bc54b 10844 }
0f40f9f7 10845}
371bc54b
JH
10846 [(set (attr "type")
10847 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10848 (const_int 0))
10849 (match_operand 2 "const1_operand" ""))
10850 (const_string "alu")
10851 ]
10852 (const_string "ishift")))
10853 (set_attr "mode" "SI")])
10854
d525dfdf
JH
10855(define_expand "ashlhi3"
10856 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10857 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10858 (match_operand:QI 2 "nonmemory_operand" "")))
10859 (clobber (reg:CC 17))]
d9f32422 10860 "TARGET_HIMODE_MATH"
d525dfdf
JH
10861 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10862
58787064
JH
10863(define_insn "*ashlhi3_1_lea"
10864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10865 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10866 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10867 (clobber (reg:CC 17))]
10868 "!TARGET_PARTIAL_REG_STALL
10869 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
58787064
JH
10870{
10871 switch (get_attr_type (insn))
10872 {
10873 case TYPE_LEA:
0f40f9f7 10874 return "#";
58787064
JH
10875 case TYPE_ALU:
10876 if (operands[2] != const1_rtx)
10877 abort ();
0f40f9f7 10878 return "add{w}\t{%0, %0|%0, %0}";
58787064
JH
10879
10880 default:
10881 if (REG_P (operands[2]))
0f40f9f7 10882 return "sal{w}\t{%b2, %0|%0, %b2}";
58787064
JH
10883 else if (GET_CODE (operands[2]) == CONST_INT
10884 && INTVAL (operands[2]) == 1
10885 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10886 return "sal{w}\t%0";
58787064 10887 else
0f40f9f7 10888 return "sal{w}\t{%2, %0|%0, %2}";
58787064 10889 }
0f40f9f7 10890}
58787064
JH
10891 [(set (attr "type")
10892 (cond [(eq_attr "alternative" "1")
10893 (const_string "lea")
10894 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10895 (const_int 0))
10896 (match_operand 0 "register_operand" ""))
10897 (match_operand 2 "const1_operand" ""))
10898 (const_string "alu")
10899 ]
10900 (const_string "ishift")))
10901 (set_attr "mode" "HI,SI")])
10902
d525dfdf 10903(define_insn "*ashlhi3_1"
e075ae69
RH
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10905 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10906 (match_operand:QI 2 "nonmemory_operand" "cI")))
10907 (clobber (reg:CC 17))]
58787064
JH
10908 "TARGET_PARTIAL_REG_STALL
10909 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
56c0e8fa 10910{
e075ae69
RH
10911 switch (get_attr_type (insn))
10912 {
10913 case TYPE_ALU:
10914 if (operands[2] != const1_rtx)
10915 abort ();
0f40f9f7 10916 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10917
e075ae69
RH
10918 default:
10919 if (REG_P (operands[2]))
0f40f9f7 10920 return "sal{w}\t{%b2, %0|%0, %b2}";
8bad7136
JL
10921 else if (GET_CODE (operands[2]) == CONST_INT
10922 && INTVAL (operands[2]) == 1
10923 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10924 return "sal{w}\t%0";
e075ae69 10925 else
0f40f9f7 10926 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10927 }
0f40f9f7 10928}
e075ae69
RH
10929 [(set (attr "type")
10930 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10931 (const_int 0))
10932 (match_operand 0 "register_operand" ""))
10933 (match_operand 2 "const1_operand" ""))
10934 (const_string "alu")
10935 ]
6ef67412
JH
10936 (const_string "ishift")))
10937 (set_attr "mode" "HI")])
bb62e19a 10938
28cefcd2
BS
10939;; This pattern can't accept a variable shift count, since shifts by
10940;; zero don't affect the flags. We assume that shifts by constant
10941;; zero are optimized away.
2c873473 10942(define_insn "*ashlhi3_cmp"
16189740
RH
10943 [(set (reg 17)
10944 (compare
e075ae69 10945 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
28cefcd2 10946 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
10947 (const_int 0)))
10948 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10949 (ashift:HI (match_dup 1) (match_dup 2)))]
9076b9c1 10950 "ix86_match_ccmode (insn, CCGOCmode)
16189740 10951 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
886c62d1 10952{
e075ae69
RH
10953 switch (get_attr_type (insn))
10954 {
10955 case TYPE_ALU:
10956 if (operands[2] != const1_rtx)
10957 abort ();
0f40f9f7 10958 return "add{w}\t{%0, %0|%0, %0}";
886c62d1 10959
e075ae69
RH
10960 default:
10961 if (REG_P (operands[2]))
0f40f9f7 10962 return "sal{w}\t{%b2, %0|%0, %b2}";
8bad7136
JL
10963 else if (GET_CODE (operands[2]) == CONST_INT
10964 && INTVAL (operands[2]) == 1
10965 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 10966 return "sal{w}\t%0";
e075ae69 10967 else
0f40f9f7 10968 return "sal{w}\t{%2, %0|%0, %2}";
e075ae69 10969 }
0f40f9f7 10970}
e075ae69
RH
10971 [(set (attr "type")
10972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973 (const_int 0))
10974 (match_operand 0 "register_operand" ""))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
6ef67412
JH
10978 (const_string "ishift")))
10979 (set_attr "mode" "HI")])
e075ae69 10980
d525dfdf
JH
10981(define_expand "ashlqi3"
10982 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10983 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10984 (match_operand:QI 2 "nonmemory_operand" "")))
10985 (clobber (reg:CC 17))]
d9f32422 10986 "TARGET_QIMODE_MATH"
d525dfdf
JH
10987 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10988
e075ae69 10989;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
10990
10991(define_insn "*ashlqi3_1_lea"
10992 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10993 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
91f9a498 10994 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
58787064
JH
10995 (clobber (reg:CC 17))]
10996 "!TARGET_PARTIAL_REG_STALL
10997 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
58787064
JH
10998{
10999 switch (get_attr_type (insn))
11000 {
11001 case TYPE_LEA:
0f40f9f7 11002 return "#";
58787064
JH
11003 case TYPE_ALU:
11004 if (operands[2] != const1_rtx)
11005 abort ();
1a06f5fe 11006 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 11007 return "add{l}\t{%k0, %k0|%k0, %k0}";
58787064 11008 else
0f40f9f7 11009 return "add{b}\t{%0, %0|%0, %0}";
58787064
JH
11010
11011 default:
11012 if (REG_P (operands[2]))
11013 {
11014 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11015 return "sal{l}\t{%b2, %k0|%k0, %b2}";
58787064 11016 else
0f40f9f7 11017 return "sal{b}\t{%b2, %0|%0, %b2}";
58787064
JH
11018 }
11019 else if (GET_CODE (operands[2]) == CONST_INT
11020 && INTVAL (operands[2]) == 1
11021 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11022 {
11023 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11024 return "sal{l}\t%0";
58787064 11025 else
0f40f9f7 11026 return "sal{b}\t%0";
58787064
JH
11027 }
11028 else
11029 {
11030 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11031 return "sal{l}\t{%2, %k0|%k0, %2}";
58787064 11032 else
0f40f9f7 11033 return "sal{b}\t{%2, %0|%0, %2}";
58787064
JH
11034 }
11035 }
0f40f9f7 11036}
58787064
JH
11037 [(set (attr "type")
11038 (cond [(eq_attr "alternative" "2")
11039 (const_string "lea")
11040 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11041 (const_int 0))
11042 (match_operand 0 "register_operand" ""))
11043 (match_operand 2 "const1_operand" ""))
11044 (const_string "alu")
11045 ]
11046 (const_string "ishift")))
11047 (set_attr "mode" "QI,SI,SI")])
11048
d525dfdf
JH
11049(define_insn "*ashlqi3_1"
11050 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69
RH
11051 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11052 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11053 (clobber (reg:CC 17))]
58787064
JH
11054 "TARGET_PARTIAL_REG_STALL
11055 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 11056{
e075ae69
RH
11057 switch (get_attr_type (insn))
11058 {
11059 case TYPE_ALU:
11060 if (operands[2] != const1_rtx)
11061 abort ();
1a06f5fe 11062 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
0f40f9f7 11063 return "add{l}\t{%k0, %k0|%k0, %k0}";
e075ae69 11064 else
0f40f9f7 11065 return "add{b}\t{%0, %0|%0, %0}";
886c62d1 11066
e075ae69
RH
11067 default:
11068 if (REG_P (operands[2]))
11069 {
1a06f5fe 11070 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11071 return "sal{l}\t{%b2, %k0|%k0, %b2}";
e075ae69 11072 else
0f40f9f7 11073 return "sal{b}\t{%b2, %0|%0, %b2}";
e075ae69 11074 }
8bad7136
JL
11075 else if (GET_CODE (operands[2]) == CONST_INT
11076 && INTVAL (operands[2]) == 1
11077 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11078 {
1a06f5fe 11079 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11080 return "sal{l}\t%0";
8bad7136 11081 else
0f40f9f7 11082 return "sal{b}\t%0";
8bad7136 11083 }
e075ae69
RH
11084 else
11085 {
1a06f5fe 11086 if (get_attr_mode (insn) == MODE_SI)
0f40f9f7 11087 return "sal{l}\t{%2, %k0|%k0, %2}";
e075ae69 11088 else
0f40f9f7 11089 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69
RH
11090 }
11091 }
0f40f9f7 11092}
e075ae69
RH
11093 [(set (attr "type")
11094 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11095 (const_int 0))
11096 (match_operand 0 "register_operand" ""))
11097 (match_operand 2 "const1_operand" ""))
11098 (const_string "alu")
11099 ]
6ef67412
JH
11100 (const_string "ishift")))
11101 (set_attr "mode" "QI,SI")])
e075ae69 11102
28cefcd2
BS
11103;; This pattern can't accept a variable shift count, since shifts by
11104;; zero don't affect the flags. We assume that shifts by constant
11105;; zero are optimized away.
2c873473 11106(define_insn "*ashlqi3_cmp"
16189740
RH
11107 [(set (reg 17)
11108 (compare
e075ae69 11109 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
28cefcd2 11110 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
11111 (const_int 0)))
11112 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11113 (ashift:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11114 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11115 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1 11116{
e075ae69
RH
11117 switch (get_attr_type (insn))
11118 {
11119 case TYPE_ALU:
11120 if (operands[2] != const1_rtx)
11121 abort ();
0f40f9f7 11122 return "add{b}\t{%0, %0|%0, %0}";
e075ae69
RH
11123
11124 default:
11125 if (REG_P (operands[2]))
0f40f9f7 11126 return "sal{b}\t{%b2, %0|%0, %b2}";
8bad7136
JL
11127 else if (GET_CODE (operands[2]) == CONST_INT
11128 && INTVAL (operands[2]) == 1
11129 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
0f40f9f7 11130 return "sal{b}\t%0";
e075ae69 11131 else
0f40f9f7 11132 return "sal{b}\t{%2, %0|%0, %2}";
e075ae69 11133 }
0f40f9f7 11134}
e075ae69
RH
11135 [(set (attr "type")
11136 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11137 (const_int 0))
11138 (match_operand 0 "register_operand" ""))
11139 (match_operand 2 "const1_operand" ""))
11140 (const_string "alu")
11141 ]
6ef67412
JH
11142 (const_string "ishift")))
11143 (set_attr "mode" "QI")])
886c62d1
JVA
11144
11145;; See comment above `ashldi3' about how this works.
11146
e075ae69 11147(define_expand "ashrdi3"
371bc54b
JH
11148 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11149 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11150 (match_operand:QI 2 "nonmemory_operand" "")))
e075ae69 11151 (clobber (reg:CC 17))])]
56c0e8fa 11152 ""
56c0e8fa 11153{
371bc54b 11154 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
56c0e8fa 11155 {
e075ae69
RH
11156 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11157 DONE;
56c0e8fa 11158 }
371bc54b
JH
11159 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11160 DONE;
0f40f9f7 11161})
2ae0f82c 11162
371bc54b
JH
11163(define_insn "ashrdi3_63_rex64"
11164 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11165 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11166 (match_operand:DI 2 "const_int_operand" "i,i")))
11167 (clobber (reg:CC 17))]
11168 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11169 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11170 "@
11171 {cqto|cqo}
0f40f9f7 11172 sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
11173 [(set_attr "type" "imovx,ishift")
11174 (set_attr "prefix_0f" "0,*")
11175 (set_attr "length_immediate" "0,*")
11176 (set_attr "modrm" "0,1")
11177 (set_attr "mode" "DI")])
11178
11179(define_insn "*ashrdi3_1_one_bit_rex64"
11180 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11181 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11182 (match_operand:QI 2 "const_int_1_operand" "")))
11183 (clobber (reg:CC 17))]
11184 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11185 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11186 "sar{q}\t%0"
371bc54b
JH
11187 [(set_attr "type" "ishift")
11188 (set (attr "length")
11189 (if_then_else (match_operand:DI 0 "register_operand" "")
11190 (const_string "2")
11191 (const_string "*")))])
11192
11193(define_insn "*ashrdi3_1_rex64"
11194 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11195 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7c17f553 11196 (match_operand:QI 2 "nonmemory_operand" "J,c")))
371bc54b
JH
11197 (clobber (reg:CC 17))]
11198 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11199 "@
0f40f9f7
ZW
11200 sar{q}\t{%2, %0|%0, %2}
11201 sar{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
11202 [(set_attr "type" "ishift")
11203 (set_attr "mode" "DI")])
11204
11205;; This pattern can't accept a variable shift count, since shifts by
11206;; zero don't affect the flags. We assume that shifts by constant
11207;; zero are optimized away.
11208(define_insn "*ashrdi3_one_bit_cmp_rex64"
11209 [(set (reg 17)
11210 (compare
11211 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11212 (match_operand:QI 2 "const_int_1_operand" ""))
11213 (const_int 0)))
11214 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11215 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11216 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11217 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11218 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 11219 "sar{q}\t%0"
371bc54b
JH
11220 [(set_attr "type" "ishift")
11221 (set (attr "length")
11222 (if_then_else (match_operand:DI 0 "register_operand" "")
11223 (const_string "2")
11224 (const_string "*")))])
11225
11226;; This pattern can't accept a variable shift count, since shifts by
11227;; zero don't affect the flags. We assume that shifts by constant
11228;; zero are optimized away.
11229(define_insn "*ashrdi3_cmp_rex64"
11230 [(set (reg 17)
11231 (compare
11232 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11233 (match_operand:QI 2 "const_int_operand" "n"))
11234 (const_int 0)))
11235 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11236 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11237 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11238 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
0f40f9f7 11239 "sar{q}\t{%2, %0|%0, %2}"
371bc54b
JH
11240 [(set_attr "type" "ishift")
11241 (set_attr "mode" "DI")])
11242
11243
e075ae69
RH
11244(define_insn "ashrdi3_1"
11245 [(set (match_operand:DI 0 "register_operand" "=r")
11246 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11247 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11248 (clobber (match_scratch:SI 3 "=&r"))
11249 (clobber (reg:CC 17))]
371bc54b 11250 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
11251 "#"
11252 [(set_attr "type" "multi")])
886c62d1 11253
e075ae69
RH
11254(define_insn "*ashrdi3_2"
11255 [(set (match_operand:DI 0 "register_operand" "=r")
11256 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11257 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11258 (clobber (reg:CC 17))]
371bc54b 11259 "!TARGET_64BIT"
e075ae69
RH
11260 "#"
11261 [(set_attr "type" "multi")])
886c62d1 11262
e075ae69
RH
11263(define_split
11264 [(set (match_operand:DI 0 "register_operand" "")
11265 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11266 (match_operand:QI 2 "nonmemory_operand" "")))
11267 (clobber (match_scratch:SI 3 ""))
11268 (clobber (reg:CC 17))]
371bc54b 11269 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
e075ae69
RH
11270 [(const_int 0)]
11271 "ix86_split_ashrdi (operands, operands[3]); DONE;")
886c62d1 11272
e075ae69
RH
11273(define_split
11274 [(set (match_operand:DI 0 "register_operand" "")
11275 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11276 (match_operand:QI 2 "nonmemory_operand" "")))
11277 (clobber (reg:CC 17))]
371bc54b 11278 "!TARGET_64BIT && reload_completed"
e075ae69
RH
11279 [(const_int 0)]
11280 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
886c62d1 11281
e075ae69
RH
11282(define_insn "x86_shrd_1"
11283 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11284 (ior:SI (ashiftrt:SI (match_dup 0)
11285 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11286 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11287 (minus:QI (const_int 32) (match_dup 2)))))
11288 (clobber (reg:CC 17))]
886c62d1 11289 ""
e075ae69 11290 "@
0f40f9f7
ZW
11291 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11292 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
e075ae69 11293 [(set_attr "type" "ishift")
6ef67412 11294 (set_attr "prefix_0f" "1")
e075ae69 11295 (set_attr "pent_pair" "np")
6ef67412
JH
11296 (set_attr "ppro_uops" "few")
11297 (set_attr "mode" "SI")])
e075ae69
RH
11298
11299(define_expand "x86_shift_adj_3"
11300 [(use (match_operand:SI 0 "register_operand" ""))
11301 (use (match_operand:SI 1 "register_operand" ""))
11302 (use (match_operand:QI 2 "register_operand" ""))]
11303 ""
886c62d1 11304{
e075ae69
RH
11305 rtx label = gen_label_rtx ();
11306 rtx tmp;
11307
16189740 11308 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
e075ae69 11309
16189740 11310 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
11311 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11312 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11313 gen_rtx_LABEL_REF (VOIDmode, label),
11314 pc_rtx);
11315 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11316 JUMP_LABEL (tmp) = label;
11317
11318 emit_move_insn (operands[0], operands[1]);
11319 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11320
11321 emit_label (label);
11322 LABEL_NUSES (label) = 1;
11323
11324 DONE;
0f40f9f7 11325})
886c62d1 11326
e075ae69
RH
11327(define_insn "ashrsi3_31"
11328 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11329 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11330 (match_operand:SI 2 "const_int_operand" "i,i")))
11331 (clobber (reg:CC 17))]
d525dfdf
JH
11332 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11333 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
11334 "@
11335 {cltd|cdq}
0f40f9f7 11336 sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11337 [(set_attr "type" "imovx,ishift")
11338 (set_attr "prefix_0f" "0,*")
11339 (set_attr "length_immediate" "0,*")
11340 (set_attr "modrm" "0,1")
11341 (set_attr "mode" "SI")])
e075ae69 11342
371bc54b
JH
11343(define_insn "*ashrsi3_31_zext"
11344 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11345 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11346 (match_operand:SI 2 "const_int_operand" "i,i"))))
11347 (clobber (reg:CC 17))]
1b0c37d7
ZW
11348 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11349 && INTVAL (operands[2]) == 31
11350 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
371bc54b
JH
11351 "@
11352 {cltd|cdq}
0f40f9f7 11353 sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11354 [(set_attr "type" "imovx,ishift")
11355 (set_attr "prefix_0f" "0,*")
11356 (set_attr "length_immediate" "0,*")
11357 (set_attr "modrm" "0,1")
11358 (set_attr "mode" "SI")])
11359
d525dfdf
JH
11360(define_expand "ashrsi3"
11361 [(set (match_operand:SI 0 "nonimmediate_operand" "")
155d8a47 11362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
d525dfdf
JH
11363 (match_operand:QI 2 "nonmemory_operand" "")))
11364 (clobber (reg:CC 17))]
11365 ""
11366 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11367
8bad7136
JL
11368(define_insn "*ashrsi3_1_one_bit"
11369 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11370 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11371 (match_operand:QI 2 "const_int_1_operand" "")))
11372 (clobber (reg:CC 17))]
11373 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11374 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11375 "sar{l}\t%0"
8bad7136
JL
11376 [(set_attr "type" "ishift")
11377 (set (attr "length")
11378 (if_then_else (match_operand:SI 0 "register_operand" "")
11379 (const_string "2")
11380 (const_string "*")))])
11381
371bc54b
JH
11382(define_insn "*ashrsi3_1_one_bit_zext"
11383 [(set (match_operand:DI 0 "register_operand" "=r")
11384 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11385 (match_operand:QI 2 "const_int_1_operand" ""))))
11386 (clobber (reg:CC 17))]
11387 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11388 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11389 "sar{l}\t%k0"
371bc54b
JH
11390 [(set_attr "type" "ishift")
11391 (set_attr "length" "2")])
11392
d525dfdf 11393(define_insn "*ashrsi3_1"
e075ae69
RH
11394 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11395 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11397 (clobber (reg:CC 17))]
d525dfdf 11398 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69 11399 "@
0f40f9f7
ZW
11400 sar{l}\t{%2, %0|%0, %2}
11401 sar{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11402 [(set_attr "type" "ishift")
11403 (set_attr "mode" "SI")])
886c62d1 11404
371bc54b
JH
11405(define_insn "*ashrsi3_1_zext"
11406 [(set (match_operand:DI 0 "register_operand" "=r,r")
11407 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11408 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11409 (clobber (reg:CC 17))]
11410 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11411 "@
0f40f9f7
ZW
11412 sar{l}\t{%2, %k0|%k0, %2}
11413 sar{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "SI")])
11416
8bad7136
JL
11417;; This pattern can't accept a variable shift count, since shifts by
11418;; zero don't affect the flags. We assume that shifts by constant
11419;; zero are optimized away.
2c873473 11420(define_insn "*ashrsi3_one_bit_cmp"
8bad7136
JL
11421 [(set (reg 17)
11422 (compare
11423 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11424 (match_operand:QI 2 "const_int_1_operand" ""))
11425 (const_int 0)))
11426 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11427 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11428 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11429 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11430 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11431 "sar{l}\t%0"
8bad7136
JL
11432 [(set_attr "type" "ishift")
11433 (set (attr "length")
11434 (if_then_else (match_operand:SI 0 "register_operand" "")
11435 (const_string "2")
11436 (const_string "*")))])
11437
371bc54b
JH
11438(define_insn "*ashrsi3_one_bit_cmp_zext"
11439 [(set (reg 17)
11440 (compare
11441 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11442 (match_operand:QI 2 "const_int_1_operand" ""))
11443 (const_int 0)))
11444 (set (match_operand:DI 0 "register_operand" "=r")
11445 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11447 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11448 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11449 "sar{l}\t%k0"
371bc54b
JH
11450 [(set_attr "type" "ishift")
11451 (set_attr "length" "2")])
11452
28cefcd2
BS
11453;; This pattern can't accept a variable shift count, since shifts by
11454;; zero don't affect the flags. We assume that shifts by constant
11455;; zero are optimized away.
2c873473 11456(define_insn "*ashrsi3_cmp"
16189740
RH
11457 [(set (reg 17)
11458 (compare
28cefcd2
BS
11459 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11460 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 11461 (const_int 0)))
28cefcd2 11462 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11463 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 11464 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11465 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11466 "sar{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11467 [(set_attr "type" "ishift")
11468 (set_attr "mode" "SI")])
886c62d1 11469
371bc54b
JH
11470(define_insn "*ashrsi3_cmp_zext"
11471 [(set (reg 17)
11472 (compare
11473 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11474 (match_operand:QI 2 "immediate_operand" "I"))
11475 (const_int 0)))
11476 (set (match_operand:DI 0 "register_operand" "=r")
11477 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11478 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11479 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
0f40f9f7 11480 "sar{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11481 [(set_attr "type" "ishift")
11482 (set_attr "mode" "SI")])
11483
d525dfdf
JH
11484(define_expand "ashrhi3"
11485 [(set (match_operand:HI 0 "nonimmediate_operand" "")
155d8a47 11486 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
d525dfdf
JH
11487 (match_operand:QI 2 "nonmemory_operand" "")))
11488 (clobber (reg:CC 17))]
d9f32422 11489 "TARGET_HIMODE_MATH"
d525dfdf
JH
11490 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11491
8bad7136
JL
11492(define_insn "*ashrhi3_1_one_bit"
11493 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11494 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11495 (match_operand:QI 2 "const_int_1_operand" "")))
11496 (clobber (reg:CC 17))]
11497 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11498 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11499 "sar{w}\t%0"
8bad7136
JL
11500 [(set_attr "type" "ishift")
11501 (set (attr "length")
3d117b30 11502 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11503 (const_string "2")
11504 (const_string "*")))])
11505
d525dfdf 11506(define_insn "*ashrhi3_1"
e075ae69
RH
11507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11508 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11509 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11510 (clobber (reg:CC 17))]
d525dfdf 11511 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
e075ae69 11512 "@
0f40f9f7
ZW
11513 sar{w}\t{%2, %0|%0, %2}
11514 sar{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11515 [(set_attr "type" "ishift")
11516 (set_attr "mode" "HI")])
886c62d1 11517
8bad7136
JL
11518;; This pattern can't accept a variable shift count, since shifts by
11519;; zero don't affect the flags. We assume that shifts by constant
11520;; zero are optimized away.
2c873473 11521(define_insn "*ashrhi3_one_bit_cmp"
8bad7136
JL
11522 [(set (reg 17)
11523 (compare
11524 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11525 (match_operand:QI 2 "const_int_1_operand" ""))
11526 (const_int 0)))
11527 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11528 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11529 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11530 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11531 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11532 "sar{w}\t%0"
8bad7136
JL
11533 [(set_attr "type" "ishift")
11534 (set (attr "length")
3d117b30 11535 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11536 (const_string "2")
11537 (const_string "*")))])
11538
28cefcd2
BS
11539;; This pattern can't accept a variable shift count, since shifts by
11540;; zero don't affect the flags. We assume that shifts by constant
11541;; zero are optimized away.
2c873473 11542(define_insn "*ashrhi3_cmp"
16189740
RH
11543 [(set (reg 17)
11544 (compare
28cefcd2
BS
11545 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11546 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 11547 (const_int 0)))
28cefcd2 11548 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11549 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 11550 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11551 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
0f40f9f7 11552 "sar{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11553 [(set_attr "type" "ishift")
11554 (set_attr "mode" "HI")])
886c62d1 11555
d525dfdf
JH
11556(define_expand "ashrqi3"
11557 [(set (match_operand:QI 0 "nonimmediate_operand" "")
155d8a47 11558 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
d525dfdf
JH
11559 (match_operand:QI 2 "nonmemory_operand" "")))
11560 (clobber (reg:CC 17))]
d9f32422 11561 "TARGET_QIMODE_MATH"
d525dfdf
JH
11562 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11563
8bad7136
JL
11564(define_insn "*ashrqi3_1_one_bit"
11565 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11566 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11567 (match_operand:QI 2 "const_int_1_operand" "")))
11568 (clobber (reg:CC 17))]
11569 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11570 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11571 "sar{b}\t%0"
8bad7136
JL
11572 [(set_attr "type" "ishift")
11573 (set (attr "length")
3d117b30 11574 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11575 (const_string "2")
11576 (const_string "*")))])
11577
d525dfdf 11578(define_insn "*ashrqi3_1"
e075ae69
RH
11579 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11580 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11581 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11582 (clobber (reg:CC 17))]
d525dfdf 11583 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
e075ae69 11584 "@
0f40f9f7
ZW
11585 sar{b}\t{%2, %0|%0, %2}
11586 sar{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11587 [(set_attr "type" "ishift")
11588 (set_attr "mode" "QI")])
886c62d1 11589
8bad7136
JL
11590;; This pattern can't accept a variable shift count, since shifts by
11591;; zero don't affect the flags. We assume that shifts by constant
11592;; zero are optimized away.
2c873473 11593(define_insn "*ashrqi3_one_bit_cmp"
8bad7136
JL
11594 [(set (reg 17)
11595 (compare
11596 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11597 (match_operand:QI 2 "const_int_1_operand" "I"))
11598 (const_int 0)))
11599 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11600 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11601 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11602 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11603 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11604 "sar{b}\t%0"
8bad7136
JL
11605 [(set_attr "type" "ishift")
11606 (set (attr "length")
3d117b30 11607 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11608 (const_string "2")
11609 (const_string "*")))])
11610
28cefcd2
BS
11611;; This pattern can't accept a variable shift count, since shifts by
11612;; zero don't affect the flags. We assume that shifts by constant
11613;; zero are optimized away.
2c873473 11614(define_insn "*ashrqi3_cmp"
16189740
RH
11615 [(set (reg 17)
11616 (compare
28cefcd2
BS
11617 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11618 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 11619 (const_int 0)))
28cefcd2 11620 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
e075ae69 11621 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 11622 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11623 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
0f40f9f7 11624 "sar{b}\t{%2, %0|%0, %2}"
6ef67412
JH
11625 [(set_attr "type" "ishift")
11626 (set_attr "mode" "QI")])
886c62d1 11627\f
e075ae69
RH
11628;; Logical shift instructions
11629
11630;; See comment above `ashldi3' about how this works.
11631
11632(define_expand "lshrdi3"
371bc54b
JH
11633 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11634 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11635 (match_operand:QI 2 "nonmemory_operand" "")))
e075ae69 11636 (clobber (reg:CC 17))])]
886c62d1 11637 ""
886c62d1 11638{
371bc54b 11639 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
886c62d1 11640 {
e075ae69
RH
11641 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11642 DONE;
886c62d1 11643 }
371bc54b
JH
11644 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11645 DONE;
0f40f9f7 11646})
886c62d1 11647
371bc54b
JH
11648(define_insn "*lshrdi3_1_one_bit_rex64"
11649 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11650 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const_int_1_operand" "")))
11652 (clobber (reg:CC 17))]
11653 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11654 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11655 "shr{q}\t%0"
371bc54b
JH
11656 [(set_attr "type" "ishift")
11657 (set (attr "length")
11658 (if_then_else (match_operand:DI 0 "register_operand" "")
11659 (const_string "2")
11660 (const_string "*")))])
11661
11662(define_insn "*lshrdi3_1_rex64"
11663 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11664 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11665 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11666 (clobber (reg:CC 17))]
11667 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11668 "@
0f40f9f7
ZW
11669 shr{q}\t{%2, %0|%0, %2}
11670 shr{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
11671 [(set_attr "type" "ishift")
11672 (set_attr "mode" "DI")])
11673
11674;; This pattern can't accept a variable shift count, since shifts by
11675;; zero don't affect the flags. We assume that shifts by constant
11676;; zero are optimized away.
11677(define_insn "*lshrdi3_cmp_one_bit_rex64"
11678 [(set (reg 17)
11679 (compare
11680 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11681 (match_operand:QI 2 "const_int_1_operand" ""))
11682 (const_int 0)))
11683 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11685 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11686 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11687 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11688 "shr{q}\t%0"
371bc54b
JH
11689 [(set_attr "type" "ishift")
11690 (set (attr "length")
11691 (if_then_else (match_operand:DI 0 "register_operand" "")
11692 (const_string "2")
11693 (const_string "*")))])
11694
11695;; This pattern can't accept a variable shift count, since shifts by
11696;; zero don't affect the flags. We assume that shifts by constant
11697;; zero are optimized away.
11698(define_insn "*lshrdi3_cmp_rex64"
11699 [(set (reg 17)
11700 (compare
11701 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11702 (match_operand:QI 2 "const_int_operand" "e"))
11703 (const_int 0)))
11704 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11705 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11706 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11707 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11708 "shr{q}\t{%2, %0|%0, %2}"
371bc54b
JH
11709 [(set_attr "type" "ishift")
11710 (set_attr "mode" "DI")])
11711
e075ae69
RH
11712(define_insn "lshrdi3_1"
11713 [(set (match_operand:DI 0 "register_operand" "=r")
11714 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11715 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11716 (clobber (match_scratch:SI 3 "=&r"))
11717 (clobber (reg:CC 17))]
1e07edd3 11718 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
11719 "#"
11720 [(set_attr "type" "multi")])
886c62d1 11721
e075ae69
RH
11722(define_insn "*lshrdi3_2"
11723 [(set (match_operand:DI 0 "register_operand" "=r")
11724 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11725 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11726 (clobber (reg:CC 17))]
1e07edd3 11727 "!TARGET_64BIT"
e075ae69
RH
11728 "#"
11729 [(set_attr "type" "multi")])
886c62d1 11730
e075ae69
RH
11731(define_split
11732 [(set (match_operand:DI 0 "register_operand" "")
11733 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11734 (match_operand:QI 2 "nonmemory_operand" "")))
11735 (clobber (match_scratch:SI 3 ""))
11736 (clobber (reg:CC 17))]
1e07edd3 11737 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
e075ae69
RH
11738 [(const_int 0)]
11739 "ix86_split_lshrdi (operands, operands[3]); DONE;")
886c62d1 11740
e075ae69
RH
11741(define_split
11742 [(set (match_operand:DI 0 "register_operand" "")
11743 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11744 (match_operand:QI 2 "nonmemory_operand" "")))
11745 (clobber (reg:CC 17))]
1e07edd3 11746 "!TARGET_64BIT && reload_completed"
e075ae69
RH
11747 [(const_int 0)]
11748 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
886c62d1 11749
d525dfdf
JH
11750(define_expand "lshrsi3"
11751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (reg:CC 17))]
11755 ""
11756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757
8bad7136
JL
11758(define_insn "*lshrsi3_1_one_bit"
11759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const_int_1_operand" "")))
11762 (clobber (reg:CC 17))]
11763 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11765 "shr{l}\t%0"
8bad7136
JL
11766 [(set_attr "type" "ishift")
11767 (set (attr "length")
11768 (if_then_else (match_operand:SI 0 "register_operand" "")
11769 (const_string "2")
11770 (const_string "*")))])
11771
371bc54b
JH
11772(define_insn "*lshrsi3_1_one_bit_zext"
11773 [(set (match_operand:DI 0 "register_operand" "=r")
11774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775 (match_operand:QI 2 "const_int_1_operand" "")))
11776 (clobber (reg:CC 17))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11779 "shr{l}\t%k0"
371bc54b
JH
11780 [(set_attr "type" "ishift")
11781 (set_attr "length" "2")])
11782
d525dfdf 11783(define_insn "*lshrsi3_1"
e075ae69
RH
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787 (clobber (reg:CC 17))]
d525dfdf 11788 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11789 "@
0f40f9f7
ZW
11790 shr{l}\t{%2, %0|%0, %2}
11791 shr{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11792 [(set_attr "type" "ishift")
11793 (set_attr "mode" "SI")])
886c62d1 11794
371bc54b
JH
11795(define_insn "*lshrsi3_1_zext"
11796 [(set (match_operand:DI 0 "register_operand" "=r,r")
11797 (zero_extend:DI
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800 (clobber (reg:CC 17))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802 "@
0f40f9f7
ZW
11803 shr{l}\t{%2, %k0|%k0, %2}
11804 shr{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
11805 [(set_attr "type" "ishift")
11806 (set_attr "mode" "SI")])
11807
8bad7136
JL
11808;; This pattern can't accept a variable shift count, since shifts by
11809;; zero don't affect the flags. We assume that shifts by constant
11810;; zero are optimized away.
2c873473 11811(define_insn "*lshrsi3_one_bit_cmp"
8bad7136
JL
11812 [(set (reg 17)
11813 (compare
11814 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const_int_1_operand" ""))
11816 (const_int 0)))
11817 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11819 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11820 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11822 "shr{l}\t%0"
8bad7136
JL
11823 [(set_attr "type" "ishift")
11824 (set (attr "length")
11825 (if_then_else (match_operand:SI 0 "register_operand" "")
11826 (const_string "2")
11827 (const_string "*")))])
11828
371bc54b
JH
11829(define_insn "*lshrsi3_cmp_one_bit_zext"
11830 [(set (reg 17)
11831 (compare
11832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833 (match_operand:QI 2 "const_int_1_operand" ""))
11834 (const_int 0)))
11835 (set (match_operand:DI 0 "register_operand" "=r")
11836 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11840 "shr{l}\t%k0"
371bc54b
JH
11841 [(set_attr "type" "ishift")
11842 (set_attr "length" "2")])
11843
28cefcd2
BS
11844;; This pattern can't accept a variable shift count, since shifts by
11845;; zero don't affect the flags. We assume that shifts by constant
11846;; zero are optimized away.
2c873473 11847(define_insn "*lshrsi3_cmp"
16189740
RH
11848 [(set (reg 17)
11849 (compare
28cefcd2
BS
11850 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 11852 (const_int 0)))
28cefcd2 11853 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 11854 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 11855 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11857 "shr{l}\t{%2, %0|%0, %2}"
6ef67412
JH
11858 [(set_attr "type" "ishift")
11859 (set_attr "mode" "SI")])
886c62d1 11860
371bc54b
JH
11861(define_insn "*lshrsi3_cmp_zext"
11862 [(set (reg 17)
11863 (compare
11864 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865 (match_operand:QI 2 "immediate_operand" "I"))
11866 (const_int 0)))
11867 (set (match_operand:DI 0 "register_operand" "=r")
11868 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11871 "shr{l}\t{%2, %k0|%k0, %2}"
371bc54b
JH
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "SI")])
11874
d525dfdf
JH
11875(define_expand "lshrhi3"
11876 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878 (match_operand:QI 2 "nonmemory_operand" "")))
11879 (clobber (reg:CC 17))]
d9f32422 11880 "TARGET_HIMODE_MATH"
d525dfdf
JH
11881 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882
8bad7136
JL
11883(define_insn "*lshrhi3_1_one_bit"
11884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const_int_1_operand" "")))
11887 (clobber (reg:CC 17))]
11888 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11890 "shr{w}\t%0"
8bad7136
JL
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
3d117b30 11893 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11894 (const_string "2")
11895 (const_string "*")))])
11896
d525dfdf 11897(define_insn "*lshrhi3_1"
e075ae69
RH
11898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901 (clobber (reg:CC 17))]
d525dfdf 11902 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69 11903 "@
0f40f9f7
ZW
11904 shr{w}\t{%2, %0|%0, %2}
11905 shr{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
886c62d1 11908
8bad7136
JL
11909;; This pattern can't accept a variable shift count, since shifts by
11910;; zero don't affect the flags. We assume that shifts by constant
11911;; zero are optimized away.
2c873473 11912(define_insn "*lshrhi3_one_bit_cmp"
8bad7136
JL
11913 [(set (reg 17)
11914 (compare
11915 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const_int_1_operand" ""))
11917 (const_int 0)))
11918 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11920 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11921 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11923 "shr{w}\t%0"
8bad7136
JL
11924 [(set_attr "type" "ishift")
11925 (set (attr "length")
11926 (if_then_else (match_operand:SI 0 "register_operand" "")
11927 (const_string "2")
11928 (const_string "*")))])
11929
28cefcd2
BS
11930;; This pattern can't accept a variable shift count, since shifts by
11931;; zero don't affect the flags. We assume that shifts by constant
11932;; zero are optimized away.
2c873473 11933(define_insn "*lshrhi3_cmp"
16189740
RH
11934 [(set (reg 17)
11935 (compare
28cefcd2
BS
11936 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 11938 (const_int 0)))
28cefcd2 11939 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 11940 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 11941 "ix86_match_ccmode (insn, CCGOCmode)
16189740 11942 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
0f40f9f7 11943 "shr{w}\t{%2, %0|%0, %2}"
6ef67412
JH
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "HI")])
886c62d1 11946
d525dfdf
JH
11947(define_expand "lshrqi3"
11948 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950 (match_operand:QI 2 "nonmemory_operand" "")))
11951 (clobber (reg:CC 17))]
d9f32422 11952 "TARGET_QIMODE_MATH"
d525dfdf
JH
11953 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954
8bad7136
JL
11955(define_insn "*lshrqi3_1_one_bit"
11956 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958 (match_operand:QI 2 "const_int_1_operand" "")))
11959 (clobber (reg:CC 17))]
11960 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 11962 "shr{b}\t%0"
8bad7136
JL
11963 [(set_attr "type" "ishift")
11964 (set (attr "length")
3d117b30 11965 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
11966 (const_string "2")
11967 (const_string "*")))])
11968
d525dfdf 11969(define_insn "*lshrqi3_1"
e075ae69
RH
11970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11971 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11973 (clobber (reg:CC 17))]
d525dfdf 11974 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
e075ae69 11975 "@
0f40f9f7
ZW
11976 shr{b}\t{%2, %0|%0, %2}
11977 shr{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "QI")])
886c62d1 11980
8bad7136
JL
11981;; This pattern can't accept a variable shift count, since shifts by
11982;; zero don't affect the flags. We assume that shifts by constant
11983;; zero are optimized away.
2c873473 11984(define_insn "*lshrqi2_one_bit_cmp"
8bad7136
JL
11985 [(set (reg 17)
11986 (compare
11987 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11988 (match_operand:QI 2 "const_int_1_operand" ""))
11989 (const_int 0)))
11990 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11991 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 11992 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
11993 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11994 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 11995 "shr{b}\t%0"
8bad7136
JL
11996 [(set_attr "type" "ishift")
11997 (set (attr "length")
11998 (if_then_else (match_operand:SI 0 "register_operand" "")
11999 (const_string "2")
12000 (const_string "*")))])
12001
28cefcd2
BS
12002;; This pattern can't accept a variable shift count, since shifts by
12003;; zero don't affect the flags. We assume that shifts by constant
12004;; zero are optimized away.
2c873473 12005(define_insn "*lshrqi2_cmp"
16189740
RH
12006 [(set (reg 17)
12007 (compare
28cefcd2
BS
12008 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 12010 (const_int 0)))
122ddbf9 12011 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 12012 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 12013 "ix86_match_ccmode (insn, CCGOCmode)
16189740 12014 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
0f40f9f7 12015 "shr{b}\t{%2, %0|%0, %2}"
6ef67412
JH
12016 [(set_attr "type" "ishift")
12017 (set_attr "mode" "QI")])
886c62d1 12018\f
e075ae69 12019;; Rotate instructions
886c62d1 12020
371bc54b
JH
12021(define_expand "rotldi3"
12022 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12023 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12024 (match_operand:QI 2 "nonmemory_operand" "")))
12025 (clobber (reg:CC 17))]
12026 "TARGET_64BIT"
12027 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12028
12029(define_insn "*rotlsi3_1_one_bit_rex64"
12030 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12031 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12032 (match_operand:QI 2 "const_int_1_operand" "")))
12033 (clobber (reg:CC 17))]
12034 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12035 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12036 "rol{q}\t%0"
371bc54b
JH
12037 [(set_attr "type" "ishift")
12038 (set (attr "length")
12039 (if_then_else (match_operand:DI 0 "register_operand" "")
12040 (const_string "2")
12041 (const_string "*")))])
12042
12043(define_insn "*rotldi3_1_rex64"
12044 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12045 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12046 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12047 (clobber (reg:CC 17))]
12048 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12049 "@
0f40f9f7
ZW
12050 rol{q}\t{%2, %0|%0, %2}
12051 rol{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "DI")])
12054
d525dfdf
JH
12055(define_expand "rotlsi3"
12056 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12057 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12058 (match_operand:QI 2 "nonmemory_operand" "")))
12059 (clobber (reg:CC 17))]
12060 ""
12061 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12062
8bad7136
JL
12063(define_insn "*rotlsi3_1_one_bit"
12064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12065 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12066 (match_operand:QI 2 "const_int_1_operand" "")))
12067 (clobber (reg:CC 17))]
12068 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12069 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12070 "rol{l}\t%0"
8bad7136
JL
12071 [(set_attr "type" "ishift")
12072 (set (attr "length")
12073 (if_then_else (match_operand:SI 0 "register_operand" "")
12074 (const_string "2")
12075 (const_string "*")))])
12076
371bc54b
JH
12077(define_insn "*rotlsi3_1_one_bit_zext"
12078 [(set (match_operand:DI 0 "register_operand" "=r")
12079 (zero_extend:DI
12080 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12081 (match_operand:QI 2 "const_int_1_operand" ""))))
12082 (clobber (reg:CC 17))]
12083 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12084 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12085 "rol{l}\t%k0"
371bc54b
JH
12086 [(set_attr "type" "ishift")
12087 (set_attr "length" "2")])
12088
d525dfdf 12089(define_insn "*rotlsi3_1"
e075ae69
RH
12090 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12091 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093 (clobber (reg:CC 17))]
d525dfdf 12094 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
e075ae69 12095 "@
0f40f9f7
ZW
12096 rol{l}\t{%2, %0|%0, %2}
12097 rol{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12098 [(set_attr "type" "ishift")
12099 (set_attr "mode" "SI")])
b4ac57ab 12100
371bc54b
JH
12101(define_insn "*rotlsi3_1_zext"
12102 [(set (match_operand:DI 0 "register_operand" "=r,r")
12103 (zero_extend:DI
12104 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12105 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12106 (clobber (reg:CC 17))]
12107 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12108 "@
0f40f9f7
ZW
12109 rol{l}\t{%2, %k0|%k0, %2}
12110 rol{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
12111 [(set_attr "type" "ishift")
12112 (set_attr "mode" "SI")])
12113
d525dfdf
JH
12114(define_expand "rotlhi3"
12115 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12116 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))
12118 (clobber (reg:CC 17))]
d9f32422 12119 "TARGET_HIMODE_MATH"
d525dfdf
JH
12120 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12121
8bad7136
JL
12122(define_insn "*rotlhi3_1_one_bit"
12123 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12124 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12125 (match_operand:QI 2 "const_int_1_operand" "")))
12126 (clobber (reg:CC 17))]
12127 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12128 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12129 "rol{w}\t%0"
8bad7136
JL
12130 [(set_attr "type" "ishift")
12131 (set (attr "length")
3d117b30 12132 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12133 (const_string "2")
12134 (const_string "*")))])
12135
d525dfdf 12136(define_insn "*rotlhi3_1"
e075ae69
RH
12137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12138 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140 (clobber (reg:CC 17))]
d525dfdf 12141 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
e075ae69 12142 "@
0f40f9f7
ZW
12143 rol{w}\t{%2, %0|%0, %2}
12144 rol{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "HI")])
47af5d50 12147
d525dfdf
JH
12148(define_expand "rotlqi3"
12149 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12150 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))
12152 (clobber (reg:CC 17))]
d9f32422 12153 "TARGET_QIMODE_MATH"
d525dfdf
JH
12154 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12155
8bad7136
JL
12156(define_insn "*rotlqi3_1_one_bit"
12157 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12158 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12159 (match_operand:QI 2 "const_int_1_operand" "")))
12160 (clobber (reg:CC 17))]
12161 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12162 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12163 "rol{b}\t%0"
8bad7136
JL
12164 [(set_attr "type" "ishift")
12165 (set (attr "length")
3d117b30 12166 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12167 (const_string "2")
12168 (const_string "*")))])
12169
d525dfdf 12170(define_insn "*rotlqi3_1"
e075ae69
RH
12171 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12172 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC 17))]
d525dfdf 12175 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
e075ae69 12176 "@
0f40f9f7
ZW
12177 rol{b}\t{%2, %0|%0, %2}
12178 rol{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12179 [(set_attr "type" "ishift")
12180 (set_attr "mode" "QI")])
47af5d50 12181
371bc54b
JH
12182(define_expand "rotrdi3"
12183 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12184 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12185 (match_operand:QI 2 "nonmemory_operand" "")))
12186 (clobber (reg:CC 17))]
12187 "TARGET_64BIT"
12188 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12189
12190(define_insn "*rotrdi3_1_one_bit_rex64"
12191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12192 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12193 (match_operand:QI 2 "const_int_1_operand" "")))
12194 (clobber (reg:CC 17))]
12195 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12196 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12197 "ror{q}\t%0"
371bc54b
JH
12198 [(set_attr "type" "ishift")
12199 (set (attr "length")
12200 (if_then_else (match_operand:DI 0 "register_operand" "")
12201 (const_string "2")
12202 (const_string "*")))])
12203
12204(define_insn "*rotrdi3_1_rex64"
12205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12206 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12207 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12208 (clobber (reg:CC 17))]
12209 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12210 "@
0f40f9f7
ZW
12211 ror{q}\t{%2, %0|%0, %2}
12212 ror{q}\t{%b2, %0|%0, %b2}"
371bc54b
JH
12213 [(set_attr "type" "ishift")
12214 (set_attr "mode" "DI")])
12215
d525dfdf
JH
12216(define_expand "rotrsi3"
12217 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12218 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12219 (match_operand:QI 2 "nonmemory_operand" "")))
12220 (clobber (reg:CC 17))]
12221 ""
12222 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12223
8bad7136
JL
12224(define_insn "*rotrsi3_1_one_bit"
12225 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12226 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227 (match_operand:QI 2 "const_int_1_operand" "")))
12228 (clobber (reg:CC 17))]
12229 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12230 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12231 "ror{l}\t%0"
8bad7136
JL
12232 [(set_attr "type" "ishift")
12233 (set (attr "length")
12234 (if_then_else (match_operand:SI 0 "register_operand" "")
12235 (const_string "2")
12236 (const_string "*")))])
12237
371bc54b
JH
12238(define_insn "*rotrsi3_1_one_bit_zext"
12239 [(set (match_operand:DI 0 "register_operand" "=r")
12240 (zero_extend:DI
12241 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12242 (match_operand:QI 2 "const_int_1_operand" ""))))
12243 (clobber (reg:CC 17))]
12244 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12245 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12246 "ror{l}\t%k0"
371bc54b
JH
12247 [(set_attr "type" "ishift")
12248 (set (attr "length")
12249 (if_then_else (match_operand:SI 0 "register_operand" "")
12250 (const_string "2")
12251 (const_string "*")))])
12252
d525dfdf 12253(define_insn "*rotrsi3_1"
e075ae69
RH
12254 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12255 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12256 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12257 (clobber (reg:CC 17))]
d525dfdf 12258 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
e075ae69 12259 "@
0f40f9f7
ZW
12260 ror{l}\t{%2, %0|%0, %2}
12261 ror{l}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "SI")])
47af5d50 12264
371bc54b
JH
12265(define_insn "*rotrsi3_1_zext"
12266 [(set (match_operand:DI 0 "register_operand" "=r,r")
12267 (zero_extend:DI
12268 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12269 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12270 (clobber (reg:CC 17))]
12271 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12272 "@
0f40f9f7
ZW
12273 ror{l}\t{%2, %k0|%k0, %2}
12274 ror{l}\t{%b2, %k0|%k0, %b2}"
371bc54b
JH
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "SI")])
12277
d525dfdf
JH
12278(define_expand "rotrhi3"
12279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12280 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12281 (match_operand:QI 2 "nonmemory_operand" "")))
12282 (clobber (reg:CC 17))]
d9f32422 12283 "TARGET_HIMODE_MATH"
d525dfdf
JH
12284 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12285
8bad7136
JL
12286(define_insn "*rotrhi3_one_bit"
12287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12288 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12289 (match_operand:QI 2 "const_int_1_operand" "")))
12290 (clobber (reg:CC 17))]
12291 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12292 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12293 "ror{w}\t%0"
8bad7136
JL
12294 [(set_attr "type" "ishift")
12295 (set (attr "length")
3d117b30 12296 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12297 (const_string "2")
12298 (const_string "*")))])
12299
d525dfdf 12300(define_insn "*rotrhi3"
e075ae69
RH
12301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12302 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12303 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12304 (clobber (reg:CC 17))]
d525dfdf 12305 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
e075ae69 12306 "@
0f40f9f7
ZW
12307 ror{w}\t{%2, %0|%0, %2}
12308 ror{w}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12309 [(set_attr "type" "ishift")
12310 (set_attr "mode" "HI")])
a199fdd6 12311
d525dfdf
JH
12312(define_expand "rotrqi3"
12313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12314 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12315 (match_operand:QI 2 "nonmemory_operand" "")))
12316 (clobber (reg:CC 17))]
d9f32422 12317 "TARGET_QIMODE_MATH"
d525dfdf
JH
12318 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12319
8bad7136
JL
12320(define_insn "*rotrqi3_1_one_bit"
12321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12322 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_int_1_operand" "")))
12324 (clobber (reg:CC 17))]
12325 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12326 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
0f40f9f7 12327 "ror{b}\t%0"
8bad7136
JL
12328 [(set_attr "type" "ishift")
12329 (set (attr "length")
3d117b30 12330 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
12331 (const_string "2")
12332 (const_string "*")))])
12333
d525dfdf 12334(define_insn "*rotrqi3_1"
e075ae69
RH
12335 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12336 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12337 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12338 (clobber (reg:CC 17))]
d525dfdf 12339 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
e075ae69 12340 "@
0f40f9f7
ZW
12341 ror{b}\t{%2, %0|%0, %2}
12342 ror{b}\t{%b2, %0|%0, %b2}"
6ef67412
JH
12343 [(set_attr "type" "ishift")
12344 (set_attr "mode" "QI")])
e075ae69
RH
12345\f
12346;; Bit set / bit test instructions
a199fdd6 12347
e075ae69
RH
12348(define_expand "extv"
12349 [(set (match_operand:SI 0 "register_operand" "")
12350 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12351 (match_operand:SI 2 "immediate_operand" "")
12352 (match_operand:SI 3 "immediate_operand" "")))]
12353 ""
e075ae69
RH
12354{
12355 /* Handle extractions from %ah et al. */
12356 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12357 FAIL;
a199fdd6 12358
e075ae69
RH
12359 /* From mips.md: extract_bit_field doesn't verify that our source
12360 matches the predicate, so check it again here. */
12361 if (! register_operand (operands[1], VOIDmode))
12362 FAIL;
0f40f9f7 12363})
a199fdd6 12364
e075ae69
RH
12365(define_expand "extzv"
12366 [(set (match_operand:SI 0 "register_operand" "")
12367 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12368 (match_operand:SI 2 "immediate_operand" "")
12369 (match_operand:SI 3 "immediate_operand" "")))]
12370 ""
e075ae69
RH
12371{
12372 /* Handle extractions from %ah et al. */
12373 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12374 FAIL;
a199fdd6 12375
e075ae69
RH
12376 /* From mips.md: extract_bit_field doesn't verify that our source
12377 matches the predicate, so check it again here. */
12378 if (! register_operand (operands[1], VOIDmode))
12379 FAIL;
0f40f9f7 12380})
a199fdd6 12381
e075ae69
RH
12382(define_expand "insv"
12383 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12384 (match_operand:SI 1 "immediate_operand" "")
12385 (match_operand:SI 2 "immediate_operand" ""))
12386 (match_operand:SI 3 "register_operand" ""))]
12387 ""
e075ae69
RH
12388{
12389 /* Handle extractions from %ah et al. */
12390 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12391 FAIL;
a199fdd6 12392
e075ae69
RH
12393 /* From mips.md: insert_bit_field doesn't verify that our source
12394 matches the predicate, so check it again here. */
12395 if (! register_operand (operands[0], VOIDmode))
12396 FAIL;
0f40f9f7 12397})
e075ae69
RH
12398
12399;; %%% bts, btr, btc, bt.
886c62d1
JVA
12400\f
12401;; Store-flag instructions.
12402
c572e5ba
JVA
12403;; For all sCOND expanders, also expand the compare or test insn that
12404;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12405
e075ae69
RH
12406;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12407;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12408;; way, which can later delete the movzx if only QImode is needed.
12409
c572e5ba 12410(define_expand "seq"
e075ae69
RH
12411 [(set (match_operand:SI 0 "register_operand" "")
12412 (eq:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12413 ""
3a3677ff 12414 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
c572e5ba 12415
c572e5ba 12416(define_expand "sne"
e075ae69
RH
12417 [(set (match_operand:SI 0 "register_operand" "")
12418 (ne:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12419 ""
3a3677ff 12420 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
c572e5ba 12421
c572e5ba 12422(define_expand "sgt"
e075ae69
RH
12423 [(set (match_operand:SI 0 "register_operand" "")
12424 (gt:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12425 ""
3a3677ff 12426 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
c572e5ba 12427
c572e5ba 12428(define_expand "sgtu"
e075ae69
RH
12429 [(set (match_operand:SI 0 "register_operand" "")
12430 (gtu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12431 ""
3a3677ff 12432 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
c572e5ba 12433
c572e5ba 12434(define_expand "slt"
e075ae69
RH
12435 [(set (match_operand:SI 0 "register_operand" "")
12436 (lt:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12437 ""
3a3677ff 12438 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
c572e5ba 12439
c572e5ba 12440(define_expand "sltu"
e075ae69
RH
12441 [(set (match_operand:SI 0 "register_operand" "")
12442 (ltu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12443 ""
3a3677ff 12444 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
c572e5ba 12445
c572e5ba 12446(define_expand "sge"
e075ae69
RH
12447 [(set (match_operand:SI 0 "register_operand" "")
12448 (ge:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12449 ""
3a3677ff 12450 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
c572e5ba 12451
c572e5ba 12452(define_expand "sgeu"
e075ae69
RH
12453 [(set (match_operand:SI 0 "register_operand" "")
12454 (geu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12455 ""
3a3677ff 12456 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
c572e5ba 12457
c572e5ba 12458(define_expand "sle"
e075ae69
RH
12459 [(set (match_operand:SI 0 "register_operand" "")
12460 (le:SI (reg:CC 17) (const_int 0)))]
c572e5ba 12461 ""
3a3677ff 12462 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
c572e5ba 12463
c785c660 12464(define_expand "sleu"
e075ae69
RH
12465 [(set (match_operand:SI 0 "register_operand" "")
12466 (leu:SI (reg:CC 17) (const_int 0)))]
c785c660 12467 ""
3a3677ff
RH
12468 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12469
12470(define_expand "sunordered"
12471 [(set (match_operand:SI 0 "register_operand" "")
12472 (unordered:SI (reg:CC 17) (const_int 0)))]
0644b628 12473 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12474 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12475
12476(define_expand "sordered"
12477 [(set (match_operand:SI 0 "register_operand" "")
12478 (ordered:SI (reg:CC 17) (const_int 0)))]
12479 "TARGET_80387"
12480 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12481
12482(define_expand "suneq"
12483 [(set (match_operand:SI 0 "register_operand" "")
12484 (uneq:SI (reg:CC 17) (const_int 0)))]
0644b628 12485 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12486 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12487
12488(define_expand "sunge"
12489 [(set (match_operand:SI 0 "register_operand" "")
12490 (unge:SI (reg:CC 17) (const_int 0)))]
0644b628 12491 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12492 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12493
12494(define_expand "sungt"
12495 [(set (match_operand:SI 0 "register_operand" "")
12496 (ungt:SI (reg:CC 17) (const_int 0)))]
0644b628 12497 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12498 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12499
12500(define_expand "sunle"
12501 [(set (match_operand:SI 0 "register_operand" "")
12502 (unle:SI (reg:CC 17) (const_int 0)))]
0644b628 12503 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12504 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12505
12506(define_expand "sunlt"
12507 [(set (match_operand:SI 0 "register_operand" "")
12508 (unlt:SI (reg:CC 17) (const_int 0)))]
0644b628 12509 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12510 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12511
12512(define_expand "sltgt"
12513 [(set (match_operand:SI 0 "register_operand" "")
12514 (ltgt:SI (reg:CC 17) (const_int 0)))]
0644b628 12515 "TARGET_80387 || TARGET_SSE"
3a3677ff 12516 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
c785c660 12517
e075ae69 12518(define_insn "*setcc_1"
a269a03c 12519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 12520 (match_operator:QI 1 "ix86_comparison_operator"
e075ae69
RH
12521 [(reg 17) (const_int 0)]))]
12522 ""
0f40f9f7 12523 "set%C1\t%0"
6ef67412
JH
12524 [(set_attr "type" "setcc")
12525 (set_attr "mode" "QI")])
a269a03c 12526
bd793c65 12527(define_insn "setcc_2"
e075ae69 12528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 12529 (match_operator:QI 1 "ix86_comparison_operator"
e075ae69
RH
12530 [(reg 17) (const_int 0)]))]
12531 ""
0f40f9f7 12532 "set%C1\t%0"
6ef67412
JH
12533 [(set_attr "type" "setcc")
12534 (set_attr "mode" "QI")])
e075ae69 12535
a46d1d38
JH
12536;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12537;; subsequent logical operations are used to imitate conditional moves.
12538;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12539;; it directly. Futher holding this value in pseudo register might bring
12540;; problem in implicit normalization in spill code.
12541;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12542;; instructions after reload by splitting the conditional move patterns.
12543
12544(define_insn "*sse_setccsf"
12545 [(set (match_operand:SF 0 "register_operand" "=x")
12546 (match_operator:SF 1 "sse_comparison_operator"
12547 [(match_operand:SF 2 "register_operand" "0")
12548 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12549 "TARGET_SSE && reload_completed"
0f40f9f7 12550 "cmp%D1ss\t{%3, %0|%0, %3}"
a46d1d38
JH
12551 [(set_attr "type" "sse")
12552 (set_attr "mode" "SF")])
12553
12554(define_insn "*sse_setccdf"
12555 [(set (match_operand:DF 0 "register_operand" "=Y")
12556 (match_operator:DF 1 "sse_comparison_operator"
12557 [(match_operand:DF 2 "register_operand" "0")
12558 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12559 "TARGET_SSE2 && reload_completed"
0f40f9f7 12560 "cmp%D1sd\t{%3, %0|%0, %3}"
a46d1d38
JH
12561 [(set_attr "type" "sse")
12562 (set_attr "mode" "DF")])
886c62d1
JVA
12563\f
12564;; Basic conditional jump instructions.
12565;; We ignore the overflow flag for signed branch instructions.
12566
c572e5ba 12567;; For all bCOND expanders, also expand the compare or test insn that
e075ae69 12568;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
c572e5ba
JVA
12569
12570(define_expand "beq"
e075ae69
RH
12571 [(set (pc)
12572 (if_then_else (match_dup 1)
c572e5ba
JVA
12573 (label_ref (match_operand 0 "" ""))
12574 (pc)))]
12575 ""
3a3677ff 12576 "ix86_expand_branch (EQ, operands[0]); DONE;")
c572e5ba 12577
c572e5ba 12578(define_expand "bne"
e075ae69
RH
12579 [(set (pc)
12580 (if_then_else (match_dup 1)
c572e5ba
JVA
12581 (label_ref (match_operand 0 "" ""))
12582 (pc)))]
12583 ""
3a3677ff 12584 "ix86_expand_branch (NE, operands[0]); DONE;")
886c62d1 12585
c572e5ba 12586(define_expand "bgt"
e075ae69
RH
12587 [(set (pc)
12588 (if_then_else (match_dup 1)
c572e5ba
JVA
12589 (label_ref (match_operand 0 "" ""))
12590 (pc)))]
12591 ""
3a3677ff 12592 "ix86_expand_branch (GT, operands[0]); DONE;")
c572e5ba 12593
c572e5ba 12594(define_expand "bgtu"
e075ae69
RH
12595 [(set (pc)
12596 (if_then_else (match_dup 1)
c572e5ba
JVA
12597 (label_ref (match_operand 0 "" ""))
12598 (pc)))]
12599 ""
3a3677ff 12600 "ix86_expand_branch (GTU, operands[0]); DONE;")
886c62d1 12601
886c62d1 12602(define_expand "blt"
e075ae69
RH
12603 [(set (pc)
12604 (if_then_else (match_dup 1)
886c62d1
JVA
12605 (label_ref (match_operand 0 "" ""))
12606 (pc)))]
12607 ""
3a3677ff 12608 "ix86_expand_branch (LT, operands[0]); DONE;")
886c62d1 12609
c572e5ba 12610(define_expand "bltu"
e075ae69
RH
12611 [(set (pc)
12612 (if_then_else (match_dup 1)
c572e5ba
JVA
12613 (label_ref (match_operand 0 "" ""))
12614 (pc)))]
12615 ""
3a3677ff 12616 "ix86_expand_branch (LTU, operands[0]); DONE;")
c572e5ba 12617
c572e5ba 12618(define_expand "bge"
e075ae69
RH
12619 [(set (pc)
12620 (if_then_else (match_dup 1)
c572e5ba
JVA
12621 (label_ref (match_operand 0 "" ""))
12622 (pc)))]
12623 ""
3a3677ff 12624 "ix86_expand_branch (GE, operands[0]); DONE;")
c572e5ba 12625
c572e5ba 12626(define_expand "bgeu"
e075ae69
RH
12627 [(set (pc)
12628 (if_then_else (match_dup 1)
c572e5ba
JVA
12629 (label_ref (match_operand 0 "" ""))
12630 (pc)))]
12631 ""
3a3677ff 12632 "ix86_expand_branch (GEU, operands[0]); DONE;")
886c62d1 12633
886c62d1 12634(define_expand "ble"
e075ae69
RH
12635 [(set (pc)
12636 (if_then_else (match_dup 1)
886c62d1
JVA
12637 (label_ref (match_operand 0 "" ""))
12638 (pc)))]
12639 ""
3a3677ff 12640 "ix86_expand_branch (LE, operands[0]); DONE;")
886c62d1 12641
c572e5ba 12642(define_expand "bleu"
e075ae69
RH
12643 [(set (pc)
12644 (if_then_else (match_dup 1)
c572e5ba
JVA
12645 (label_ref (match_operand 0 "" ""))
12646 (pc)))]
12647 ""
3a3677ff
RH
12648 "ix86_expand_branch (LEU, operands[0]); DONE;")
12649
12650(define_expand "bunordered"
12651 [(set (pc)
12652 (if_then_else (match_dup 1)
12653 (label_ref (match_operand 0 "" ""))
12654 (pc)))]
0644b628 12655 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12656 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12657
12658(define_expand "bordered"
12659 [(set (pc)
12660 (if_then_else (match_dup 1)
12661 (label_ref (match_operand 0 "" ""))
12662 (pc)))]
0644b628 12663 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12664 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12665
12666(define_expand "buneq"
12667 [(set (pc)
12668 (if_then_else (match_dup 1)
12669 (label_ref (match_operand 0 "" ""))
12670 (pc)))]
0644b628 12671 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12672 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12673
12674(define_expand "bunge"
12675 [(set (pc)
12676 (if_then_else (match_dup 1)
12677 (label_ref (match_operand 0 "" ""))
12678 (pc)))]
0644b628 12679 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12680 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12681
12682(define_expand "bungt"
12683 [(set (pc)
12684 (if_then_else (match_dup 1)
12685 (label_ref (match_operand 0 "" ""))
12686 (pc)))]
0644b628 12687 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12688 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12689
12690(define_expand "bunle"
12691 [(set (pc)
12692 (if_then_else (match_dup 1)
12693 (label_ref (match_operand 0 "" ""))
12694 (pc)))]
0644b628 12695 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12696 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12697
12698(define_expand "bunlt"
12699 [(set (pc)
12700 (if_then_else (match_dup 1)
12701 (label_ref (match_operand 0 "" ""))
12702 (pc)))]
0644b628 12703 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
12704 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12705
12706(define_expand "bltgt"
12707 [(set (pc)
12708 (if_then_else (match_dup 1)
12709 (label_ref (match_operand 0 "" ""))
12710 (pc)))]
0644b628 12711 "TARGET_80387 || TARGET_SSE"
3a3677ff 12712 "ix86_expand_branch (LTGT, operands[0]); DONE;")
886c62d1 12713
e075ae69
RH
12714(define_insn "*jcc_1"
12715 [(set (pc)
9076b9c1 12716 (if_then_else (match_operator 1 "ix86_comparison_operator"
e075ae69 12717 [(reg 17) (const_int 0)])
6ef67412 12718 (label_ref (match_operand 0 "" ""))
e075ae69
RH
12719 (pc)))]
12720 ""
0f40f9f7 12721 "%+j%C1\t%l0"
e075ae69 12722 [(set_attr "type" "ibr")
6ef67412
JH
12723 (set (attr "prefix_0f")
12724 (if_then_else (and (ge (minus (match_dup 0) (pc))
12725 (const_int -128))
12726 (lt (minus (match_dup 0) (pc))
12727 (const_int 124)))
12728 (const_int 0)
12729 (const_int 1)))])
e075ae69
RH
12730
12731(define_insn "*jcc_2"
12732 [(set (pc)
9076b9c1 12733 (if_then_else (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
12734 [(reg 17) (const_int 0)])
12735 (pc)
6ef67412 12736 (label_ref (match_operand 0 "" ""))))]
e075ae69 12737 ""
0f40f9f7 12738 "%+j%c1\t%l0"
e075ae69 12739 [(set_attr "type" "ibr")
6ef67412
JH
12740 (set (attr "prefix_0f")
12741 (if_then_else (and (ge (minus (match_dup 0) (pc))
12742 (const_int -128))
12743 (lt (minus (match_dup 0) (pc))
12744 (const_int 124)))
12745 (const_int 0)
12746 (const_int 1)))])
e075ae69 12747
3a3677ff
RH
12748;; Define combination compare-and-branch fp compare instructions to use
12749;; during early optimization. Splitting the operation apart early makes
12750;; for bad code when we want to reverse the operation.
12751
12752(define_insn "*fp_jcc_1"
12753 [(set (pc)
12754 (if_then_else (match_operator 0 "comparison_operator"
12755 [(match_operand 1 "register_operand" "f")
12756 (match_operand 2 "register_operand" "f")])
12757 (label_ref (match_operand 3 "" ""))
12758 (pc)))
12759 (clobber (reg:CCFP 18))
12760 (clobber (reg:CCFP 17))]
12761 "TARGET_CMOVE && TARGET_80387
0644b628 12762 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff 12763 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12764 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12765 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12766 "#")
12767
0644b628
JH
12768(define_insn "*fp_jcc_1_sse"
12769 [(set (pc)
12770 (if_then_else (match_operator 0 "comparison_operator"
12771 [(match_operand 1 "register_operand" "f#x,x#f")
12772 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12773 (label_ref (match_operand 3 "" ""))
12774 (pc)))
12775 (clobber (reg:CCFP 18))
12776 (clobber (reg:CCFP 17))]
12777 "TARGET_80387
12778 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12779 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12780 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12781 "#")
12782
12783(define_insn "*fp_jcc_1_sse_only"
12784 [(set (pc)
12785 (if_then_else (match_operator 0 "comparison_operator"
12786 [(match_operand 1 "register_operand" "x")
12787 (match_operand 2 "nonimmediate_operand" "xm")])
12788 (label_ref (match_operand 3 "" ""))
12789 (pc)))
12790 (clobber (reg:CCFP 18))
12791 (clobber (reg:CCFP 17))]
12792 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12793 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12794 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12795 "#")
12796
3a3677ff
RH
12797(define_insn "*fp_jcc_2"
12798 [(set (pc)
12799 (if_then_else (match_operator 0 "comparison_operator"
12800 [(match_operand 1 "register_operand" "f")
12801 (match_operand 2 "register_operand" "f")])
12802 (pc)
12803 (label_ref (match_operand 3 "" ""))))
12804 (clobber (reg:CCFP 18))
12805 (clobber (reg:CCFP 17))]
12806 "TARGET_CMOVE && TARGET_80387
0644b628 12807 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff 12808 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12809 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12810 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12811 "#")
12812
0644b628
JH
12813(define_insn "*fp_jcc_2_sse"
12814 [(set (pc)
12815 (if_then_else (match_operator 0 "comparison_operator"
12816 [(match_operand 1 "register_operand" "f#x,x#f")
12817 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12818 (pc)
12819 (label_ref (match_operand 3 "" ""))))
12820 (clobber (reg:CCFP 18))
12821 (clobber (reg:CCFP 17))]
12822 "TARGET_80387
12823 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12826 "#")
12827
12828(define_insn "*fp_jcc_2_sse_only"
12829 [(set (pc)
12830 (if_then_else (match_operator 0 "comparison_operator"
12831 [(match_operand 1 "register_operand" "x")
12832 (match_operand 2 "nonimmediate_operand" "xm")])
12833 (pc)
12834 (label_ref (match_operand 3 "" ""))))
12835 (clobber (reg:CCFP 18))
12836 (clobber (reg:CCFP 17))]
12837 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12838 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
0644b628
JH
12840 "#")
12841
3a3677ff
RH
12842(define_insn "*fp_jcc_3"
12843 [(set (pc)
b1cdafbb 12844 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12845 [(match_operand 1 "register_operand" "f")
12846 (match_operand 2 "nonimmediate_operand" "fm")])
12847 (label_ref (match_operand 3 "" ""))
12848 (pc)))
12849 (clobber (reg:CCFP 18))
12850 (clobber (reg:CCFP 17))
12851 (clobber (match_scratch:HI 4 "=a"))]
12852 "TARGET_80387
12853 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12854 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12855 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12856 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12857 operands[1], operands[2]) == CCFPmode
12858 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12859 "#")
12860
12861(define_insn "*fp_jcc_4"
12862 [(set (pc)
b1cdafbb 12863 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
12864 [(match_operand 1 "register_operand" "f")
12865 (match_operand 2 "nonimmediate_operand" "fm")])
12866 (pc)
12867 (label_ref (match_operand 3 "" ""))))
12868 (clobber (reg:CCFP 18))
12869 (clobber (reg:CCFP 17))
12870 (clobber (match_scratch:HI 4 "=a"))]
12871 "TARGET_80387
12872 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 12873 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
12874 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12875 && SELECT_CC_MODE (GET_CODE (operands[0]),
03598dea
JH
12876 operands[1], operands[2]) == CCFPmode
12877 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12878 "#")
12879
12880(define_insn "*fp_jcc_5"
12881 [(set (pc)
12882 (if_then_else (match_operator 0 "comparison_operator"
12883 [(match_operand 1 "register_operand" "f")
12884 (match_operand 2 "register_operand" "f")])
12885 (label_ref (match_operand 3 "" ""))
12886 (pc)))
12887 (clobber (reg:CCFP 18))
12888 (clobber (reg:CCFP 17))
12889 (clobber (match_scratch:HI 4 "=a"))]
12890 "TARGET_80387
12891 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12892 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12894 "#")
12895
12896(define_insn "*fp_jcc_6"
12897 [(set (pc)
12898 (if_then_else (match_operator 0 "comparison_operator"
12899 [(match_operand 1 "register_operand" "f")
12900 (match_operand 2 "register_operand" "f")])
12901 (pc)
12902 (label_ref (match_operand 3 "" ""))))
12903 (clobber (reg:CCFP 18))
12904 (clobber (reg:CCFP 17))
12905 (clobber (match_scratch:HI 4 "=a"))]
12906 "TARGET_80387
12907 && FLOAT_MODE_P (GET_MODE (operands[1]))
03598dea
JH
12908 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12909 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
3a3677ff
RH
12910 "#")
12911
12912(define_split
12913 [(set (pc)
12914 (if_then_else (match_operator 0 "comparison_operator"
12915 [(match_operand 1 "register_operand" "")
12916 (match_operand 2 "nonimmediate_operand" "")])
12917 (match_operand 3 "" "")
12918 (match_operand 4 "" "")))
12919 (clobber (reg:CCFP 18))
12920 (clobber (reg:CCFP 17))]
12921 "reload_completed"
9e7adcb3 12922 [(const_int 0)]
3a3677ff 12923{
03598dea 12924 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
9e7adcb3
JH
12925 operands[3], operands[4], NULL_RTX);
12926 DONE;
0f40f9f7 12927})
3a3677ff
RH
12928
12929(define_split
12930 [(set (pc)
12931 (if_then_else (match_operator 0 "comparison_operator"
12932 [(match_operand 1 "register_operand" "")
12933 (match_operand 2 "nonimmediate_operand" "")])
12934 (match_operand 3 "" "")
12935 (match_operand 4 "" "")))
12936 (clobber (reg:CCFP 18))
12937 (clobber (reg:CCFP 17))
12938 (clobber (match_scratch:HI 5 "=a"))]
12939 "reload_completed"
12940 [(set (pc)
12941 (if_then_else (match_dup 6)
12942 (match_dup 3)
12943 (match_dup 4)))]
3a3677ff 12944{
03598dea 12945 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
9e7adcb3
JH
12946 operands[3], operands[4], operands[5]);
12947 DONE;
0f40f9f7 12948})
886c62d1
JVA
12949\f
12950;; Unconditional and other jump instructions
12951
12952(define_insn "jump"
12953 [(set (pc)
12954 (label_ref (match_operand 0 "" "")))]
12955 ""
0f40f9f7 12956 "jmp\t%l0"
6ef67412 12957 [(set_attr "type" "ibr")])
886c62d1 12958
14f73b5a
JH
12959(define_expand "indirect_jump"
12960 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
886c62d1 12961 ""
14f73b5a
JH
12962 "")
12963
12964(define_insn "*indirect_jump"
12965 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12966 "!TARGET_64BIT"
12967 "jmp\t%A0"
12968 [(set_attr "type" "ibr")
12969 (set_attr "length_immediate" "0")])
12970
12971(define_insn "*indirect_jump_rtx64"
12972 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12973 "TARGET_64BIT"
0f40f9f7 12974 "jmp\t%A0"
6ef67412
JH
12975 [(set_attr "type" "ibr")
12976 (set_attr "length_immediate" "0")])
4801403e 12977
90675921 12978(define_expand "tablejump"
6eb791fc 12979 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
90675921
RH
12980 (use (label_ref (match_operand 1 "" "")))])]
12981 ""
12982{
12983 /* In PIC mode, the table entries are stored GOT-relative. Convert
12984 the relative address to an absolute address. */
12985 if (flag_pic)
12986 {
6eb791fc
JH
12987 if (TARGET_64BIT)
12988 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
12989 operands[1], NULL_RTX, 0,
12990 OPTAB_DIRECT);
12991 else
12992 {
12993 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
12994 operands[0], NULL_RTX, 1,
12995 OPTAB_DIRECT);
12996 current_function_uses_pic_offset_table = 1;
12997 }
90675921 12998 }
0f40f9f7 12999})
2bb7a0f5 13000
90675921 13001(define_insn "*tablejump_1"
2ae0f82c 13002 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
886c62d1 13003 (use (label_ref (match_operand 1 "" "")))]
14f73b5a
JH
13004 "!TARGET_64BIT"
13005 "jmp\t%A0"
13006 [(set_attr "type" "ibr")
13007 (set_attr "length_immediate" "0")])
13008
13009(define_insn "*tablejump_1_rtx64"
13010 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13011 (use (label_ref (match_operand 1 "" "")))]
13012 "TARGET_64BIT"
0f40f9f7 13013 "jmp\t%A0"
6ef67412
JH
13014 [(set_attr "type" "ibr")
13015 (set_attr "length_immediate" "0")])
e075ae69
RH
13016\f
13017;; Loop instruction
13018;;
13019;; This is all complicated by the fact that since this is a jump insn
13020;; we must handle our own reloads.
13021
5527bf14
RH
13022(define_expand "doloop_end"
13023 [(use (match_operand 0 "" "")) ; loop pseudo
13024 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13025 (use (match_operand 2 "" "")) ; max iterations
13026 (use (match_operand 3 "" "")) ; loop level
13027 (use (match_operand 4 "" ""))] ; label
1b0c37d7 13028 "!TARGET_64BIT && TARGET_USE_LOOP"
5527bf14
RH
13029 "
13030{
13031 /* Only use cloop on innermost loops. */
13032 if (INTVAL (operands[3]) > 1)
13033 FAIL;
13034 if (GET_MODE (operands[0]) != SImode)
13035 FAIL;
13036 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13037 operands[0]));
13038 DONE;
13039}")
e075ae69 13040
5527bf14 13041(define_insn "doloop_end_internal"
e075ae69 13042 [(set (pc)
5527bf14 13043 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
e075ae69
RH
13044 (const_int 1))
13045 (label_ref (match_operand 0 "" ""))
13046 (pc)))
5527bf14 13047 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
e075ae69
RH
13048 (plus:SI (match_dup 1)
13049 (const_int -1)))
13050 (clobber (match_scratch:SI 3 "=X,X,r"))
13051 (clobber (reg:CC 17))]
1b0c37d7 13052 "!TARGET_64BIT && TARGET_USE_LOOP"
e075ae69
RH
13053{
13054 if (which_alternative != 0)
0f40f9f7 13055 return "#";
e075ae69 13056 if (get_attr_length (insn) == 2)
0f40f9f7 13057 return "%+loop\t%l0";
e075ae69 13058 else
0f40f9f7
ZW
13059 return "dec{l}\t%1\;%+jne\t%l0";
13060}
6ef67412
JH
13061 [(set_attr "ppro_uops" "many")
13062 (set (attr "type")
e075ae69
RH
13063 (if_then_else (and (eq_attr "alternative" "0")
13064 (and (ge (minus (match_dup 0) (pc))
13065 (const_int -128))
13066 (lt (minus (match_dup 0) (pc))
13067 (const_int 124))))
6ef67412
JH
13068 (const_string "ibr")
13069 (const_string "multi")))])
e075ae69 13070
e075ae69
RH
13071(define_split
13072 [(set (pc)
13073 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13074 (const_int 1))
13075 (match_operand 0 "" "")
13076 (pc)))
5527bf14 13077 (set (match_dup 1)
e075ae69
RH
13078 (plus:SI (match_dup 1)
13079 (const_int -1)))
5527bf14 13080 (clobber (match_scratch:SI 2 ""))
e075ae69 13081 (clobber (reg:CC 17))]
1b0c37d7 13082 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13083 && reload_completed
13084 && REGNO (operands[1]) != 2"
13085 [(parallel [(set (reg:CCZ 17)
13086 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
e075ae69 13087 (const_int 0)))
5527bf14 13088 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
16189740 13089 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
13090 (match_dup 0)
13091 (pc)))]
13092 "")
13093
13094(define_split
13095 [(set (pc)
13096 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13097 (const_int 1))
13098 (match_operand 0 "" "")
13099 (pc)))
5527bf14 13100 (set (match_operand:SI 2 "nonimmediate_operand" "")
e075ae69
RH
13101 (plus:SI (match_dup 1)
13102 (const_int -1)))
13103 (clobber (match_scratch:SI 3 ""))
13104 (clobber (reg:CC 17))]
1b0c37d7 13105 "!TARGET_64BIT && TARGET_USE_LOOP
5527bf14
RH
13106 && reload_completed
13107 && (! REG_P (operands[2])
13108 || ! rtx_equal_p (operands[1], operands[2]))"
e075ae69 13109 [(set (match_dup 3) (match_dup 1))
16189740
RH
13110 (parallel [(set (reg:CCZ 17)
13111 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13112 (const_int 0)))
e075ae69
RH
13113 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13114 (set (match_dup 2) (match_dup 3))
16189740 13115 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
13116 (match_dup 0)
13117 (pc)))]
13118 "")
c50e5bc0
RH
13119
13120;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13121
13122(define_peephole2
13123 [(set (reg 17) (match_operand 0 "" ""))
13124 (set (match_operand:QI 1 "register_operand" "")
13125 (match_operator:QI 2 "ix86_comparison_operator"
13126 [(reg 17) (const_int 0)]))
13127 (set (match_operand 3 "q_regs_operand" "")
13128 (zero_extend (match_dup 1)))]
13129 "peep2_reg_dead_p (3, operands[1])
13130 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
653753c5 13131 [(set (match_dup 3) (const_int 0))
c50e5bc0
RH
13132 (set (match_dup 4) (match_dup 0))
13133 (set (strict_low_part (match_dup 5))
13134 (match_dup 2))]
13135 "operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13136 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));")
e075ae69
RH
13137\f
13138;; Call instructions.
2bb7a0f5 13139
cbbf65e0
RH
13140;; The predicates normally associated with named expanders are not properly
13141;; checked for calls. This is a bug in the generic code, but it isn't that
13142;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 13143
886c62d1
JVA
13144;; Call subroutine returning no value.
13145
2bb7a0f5 13146(define_expand "call_pop"
cbbf65e0
RH
13147 [(parallel [(call (match_operand:QI 0 "" "")
13148 (match_operand:SI 1 "" ""))
2bb7a0f5
RS
13149 (set (reg:SI 7)
13150 (plus:SI (reg:SI 7)
cbbf65e0 13151 (match_operand:SI 3 "" "")))])]
1e07edd3 13152 "!TARGET_64BIT"
2bb7a0f5 13153{
35e2d030
RH
13154 if (operands[3] == const0_rtx)
13155 {
32ee7d1d 13156 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
35e2d030
RH
13157 DONE;
13158 }
b848ded1
JH
13159 /* Static functions and indirect calls don't need
13160 current_function_uses_pic_offset_table. */
13161 if (flag_pic
2a4bbffa
RH
13162 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13163 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2bb7a0f5 13164 current_function_uses_pic_offset_table = 1;
e1ff012c 13165 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
cbbf65e0 13166 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1e07edd3
JH
13167 if (TARGET_64BIT)
13168 abort();
0f40f9f7 13169})
2bb7a0f5 13170
94bb5d0c 13171(define_insn "*call_pop_0"
e1ff012c 13172 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c
RH
13173 (match_operand:SI 1 "" ""))
13174 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 13175 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 13176 "!TARGET_64BIT"
94bb5d0c
RH
13177{
13178 if (SIBLING_CALL_P (insn))
0f40f9f7 13179 return "jmp\t%P0";
94bb5d0c 13180 else
0f40f9f7
ZW
13181 return "call\t%P0";
13182}
94bb5d0c
RH
13183 [(set_attr "type" "call")])
13184
cbbf65e0 13185(define_insn "*call_pop_1"
e1ff012c 13186 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 13187 (match_operand:SI 1 "" ""))
886c62d1 13188 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 13189 (match_operand:SI 2 "immediate_operand" "i")))]
1e07edd3 13190 "!TARGET_64BIT"
886c62d1 13191{
e1ff012c 13192 if (constant_call_address_operand (operands[0], Pmode))
94bb5d0c
RH
13193 {
13194 if (SIBLING_CALL_P (insn))
0f40f9f7 13195 return "jmp\t%P0";
94bb5d0c 13196 else
0f40f9f7 13197 return "call\t%P0";
94bb5d0c 13198 }
94bb5d0c 13199 if (SIBLING_CALL_P (insn))
0f40f9f7 13200 return "jmp\t%A0";
94bb5d0c 13201 else
0f40f9f7
ZW
13202 return "call\t%A0";
13203}
e075ae69 13204 [(set_attr "type" "call")])
886c62d1 13205
2bb7a0f5 13206(define_expand "call"
cbbf65e0 13207 [(call (match_operand:QI 0 "" "")
39d04363
JH
13208 (match_operand 1 "" ""))
13209 (use (match_operand 2 "" ""))]
2bb7a0f5
RS
13210 ;; Operand 1 not used on the i386.
13211 ""
2bb7a0f5 13212{
39d04363 13213 rtx insn;
b848ded1
JH
13214 /* Static functions and indirect calls don't need
13215 current_function_uses_pic_offset_table. */
13216 if (flag_pic
2a4bbffa
RH
13217 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13218 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2bb7a0f5 13219 current_function_uses_pic_offset_table = 1;
32ee7d1d 13220
e1ff012c 13221 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
cbbf65e0 13222 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
32ee7d1d
JH
13223 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13224 {
32ee7d1d
JH
13225 rtx reg = gen_rtx_REG (QImode, 0);
13226 emit_move_insn (reg, operands[2]);
39d04363 13227 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
32ee7d1d
JH
13228 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13229 DONE;
13230 }
39d04363
JH
13231 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13232 DONE;
0f40f9f7 13233})
2bb7a0f5 13234
32ee7d1d
JH
13235(define_expand "call_exp"
13236 [(call (match_operand:QI 0 "" "")
13237 (match_operand 1 "" ""))]
13238 ""
13239 "")
13240
94bb5d0c 13241(define_insn "*call_0"
32ee7d1d
JH
13242 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13243 (match_operand 1 "" ""))]
94bb5d0c 13244 ""
94bb5d0c
RH
13245{
13246 if (SIBLING_CALL_P (insn))
0f40f9f7 13247 return "jmp\t%P0";
94bb5d0c 13248 else
0f40f9f7
ZW
13249 return "call\t%P0";
13250}
94bb5d0c
RH
13251 [(set_attr "type" "call")])
13252
cbbf65e0 13253(define_insn "*call_1"
e1ff012c 13254 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
32ee7d1d 13255 (match_operand 1 "" ""))]
ac62a60e 13256 "!TARGET_64BIT"
32ee7d1d
JH
13257{
13258 if (constant_call_address_operand (operands[0], QImode))
13259 {
13260 if (SIBLING_CALL_P (insn))
0f40f9f7 13261 return "jmp\t%P0";
32ee7d1d 13262 else
0f40f9f7 13263 return "call\t%P0";
32ee7d1d
JH
13264 }
13265 if (SIBLING_CALL_P (insn))
0f40f9f7 13266 return "jmp\t%A0";
32ee7d1d 13267 else
0f40f9f7
ZW
13268 return "call\t%A0";
13269}
32ee7d1d
JH
13270 [(set_attr "type" "call")])
13271
13272(define_insn "*call_1_rex64"
13273 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13274 (match_operand 1 "" ""))]
ac62a60e 13275 "TARGET_64BIT"
886c62d1 13276{
94bb5d0c 13277 if (constant_call_address_operand (operands[0], QImode))
cbbf65e0
RH
13278 {
13279 if (SIBLING_CALL_P (insn))
0f40f9f7 13280 return "jmp\t%P0";
cbbf65e0 13281 else
0f40f9f7 13282 return "call\t%P0";
cbbf65e0 13283 }
cbbf65e0 13284 if (SIBLING_CALL_P (insn))
0f40f9f7 13285 return "jmp\t%A0";
cbbf65e0 13286 else
0f40f9f7
ZW
13287 return "call\t%A0";
13288}
e075ae69 13289 [(set_attr "type" "call")])
886c62d1
JVA
13290
13291;; Call subroutine, returning value in operand 0
13292;; (which must be a hard register).
13293
2bb7a0f5
RS
13294(define_expand "call_value_pop"
13295 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
13296 (call (match_operand:QI 1 "" "")
13297 (match_operand:SI 2 "" "")))
2bb7a0f5
RS
13298 (set (reg:SI 7)
13299 (plus:SI (reg:SI 7)
cbbf65e0 13300 (match_operand:SI 4 "" "")))])]
1e07edd3 13301 "!TARGET_64BIT"
2bb7a0f5 13302{
35e2d030
RH
13303 if (operands[4] == const0_rtx)
13304 {
32ee7d1d
JH
13305 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13306 constm1_rtx));
35e2d030
RH
13307 DONE;
13308 }
b848ded1
JH
13309 /* Static functions and indirect calls don't need
13310 current_function_uses_pic_offset_table. */
13311 if (flag_pic
2a4bbffa
RH
13312 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13313 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2bb7a0f5 13314 current_function_uses_pic_offset_table = 1;
e1ff012c 13315 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
cbbf65e0 13316 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
0f40f9f7 13317})
2bb7a0f5 13318
2bb7a0f5
RS
13319(define_expand "call_value"
13320 [(set (match_operand 0 "" "")
cbbf65e0 13321 (call (match_operand:QI 1 "" "")
39d04363
JH
13322 (match_operand:SI 2 "" "")))
13323 (use (match_operand:SI 3 "" ""))]
2bb7a0f5
RS
13324 ;; Operand 2 not used on the i386.
13325 ""
2bb7a0f5 13326{
39d04363 13327 rtx insn;
b848ded1
JH
13328 /* Static functions and indirect calls don't need
13329 current_function_uses_pic_offset_table. */
13330 if (flag_pic
2a4bbffa
RH
13331 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13332 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2bb7a0f5 13333 current_function_uses_pic_offset_table = 1;
e1ff012c 13334 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
cbbf65e0 13335 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
32ee7d1d
JH
13336 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13337 {
32ee7d1d
JH
13338 rtx reg = gen_rtx_REG (QImode, 0);
13339 emit_move_insn (reg, operands[3]);
13340 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
39d04363 13341 operands[2]));
32ee7d1d
JH
13342 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13343 DONE;
13344 }
39d04363
JH
13345 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13346 operands[2]));
13347 DONE;
0f40f9f7 13348})
2bb7a0f5 13349
32ee7d1d
JH
13350(define_expand "call_value_exp"
13351 [(set (match_operand 0 "" "")
13352 (call (match_operand:QI 1 "" "")
13353 (match_operand:SI 2 "" "")))]
13354 ""
13355 "")
13356
b840bfb0
MM
13357;; Call subroutine returning any type.
13358
576182a3 13359(define_expand "untyped_call"
b840bfb0 13360 [(parallel [(call (match_operand 0 "" "")
576182a3 13361 (const_int 0))
b840bfb0 13362 (match_operand 1 "" "")
576182a3
TW
13363 (match_operand 2 "" "")])]
13364 ""
576182a3 13365{
b840bfb0 13366 int i;
576182a3 13367
d8b679b9
RK
13368 /* In order to give reg-stack an easier job in validating two
13369 coprocessor registers as containing a possible return value,
13370 simply pretend the untyped call returns a complex long double
13371 value. */
74775c7a 13372
d8b679b9 13373 emit_call_insn (TARGET_80387
f64cecad 13374 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
32ee7d1d
JH
13375 operands[0], const0_rtx,
13376 GEN_INT (SSE_REGPARM_MAX - 1))
13377 : gen_call (operands[0], const0_rtx,
13378 GEN_INT (SSE_REGPARM_MAX - 1)));
576182a3 13379
b840bfb0 13380 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 13381 {
b840bfb0
MM
13382 rtx set = XVECEXP (operands[2], 0, i);
13383 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 13384 }
576182a3 13385
b840bfb0
MM
13386 /* The optimizer does not know that the call sets the function value
13387 registers we stored in the result block. We avoid problems by
13388 claiming that all hard registers are used and clobbered at this
13389 point. */
13390 emit_insn (gen_blockage ());
576182a3
TW
13391
13392 DONE;
0f40f9f7 13393})
e075ae69
RH
13394\f
13395;; Prologue and epilogue instructions
576182a3 13396
b840bfb0
MM
13397;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13398;; all of memory. This blocks insns from being moved across this point.
13399
13400(define_insn "blockage"
13401 [(unspec_volatile [(const_int 0)] 0)]
576182a3 13402 ""
90aec2cf 13403 ""
e075ae69 13404 [(set_attr "length" "0")])
576182a3 13405
886c62d1
JVA
13406;; Insn emitted into the body of a function to return from a function.
13407;; This is only done if the function's epilogue is known to be simple.
182a4620 13408;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 13409
5f3d14e3 13410(define_expand "return"
886c62d1 13411 [(return)]
5f3d14e3 13412 "ix86_can_use_return_insn_p ()"
9a7372d6
RH
13413{
13414 if (current_function_pops_args)
13415 {
13416 rtx popc = GEN_INT (current_function_pops_args);
13417 emit_jump_insn (gen_return_pop_internal (popc));
13418 DONE;
13419 }
0f40f9f7 13420})
5f3d14e3
SC
13421
13422(define_insn "return_internal"
13423 [(return)]
13424 "reload_completed"
90aec2cf 13425 "ret"
6ef67412
JH
13426 [(set_attr "length" "1")
13427 (set_attr "length_immediate" "0")
13428 (set_attr "modrm" "0")])
5f3d14e3 13429
6cd96118
SC
13430(define_insn "return_pop_internal"
13431 [(return)
13432 (use (match_operand:SI 0 "const_int_operand" ""))]
13433 "reload_completed"
0f40f9f7 13434 "ret\t%0"
6ef67412
JH
13435 [(set_attr "length" "3")
13436 (set_attr "length_immediate" "2")
13437 (set_attr "modrm" "0")])
6cd96118 13438
11837777
RH
13439(define_insn "return_indirect_internal"
13440 [(return)
13441 (use (match_operand:SI 0 "register_operand" "r"))]
13442 "reload_completed"
0f40f9f7 13443 "jmp\t%A0"
11837777
RH
13444 [(set_attr "type" "ibr")
13445 (set_attr "length_immediate" "0")])
13446
5f3d14e3
SC
13447(define_insn "nop"
13448 [(const_int 0)]
13449 ""
90aec2cf 13450 "nop"
e075ae69 13451 [(set_attr "length" "1")
6ef67412
JH
13452 (set_attr "length_immediate" "0")
13453 (set_attr "modrm" "0")
e075ae69 13454 (set_attr "ppro_uops" "one")])
5f3d14e3
SC
13455
13456(define_expand "prologue"
13457 [(const_int 1)]
13458 ""
e075ae69 13459 "ix86_expand_prologue (); DONE;")
5f3d14e3 13460
e075ae69 13461(define_insn "prologue_set_got"
69404d6f 13462 [(set (match_operand:SI 0 "register_operand" "=r")
c76aab11 13463 (unspec_volatile:SI
e075ae69
RH
13464 [(plus:SI (match_dup 0)
13465 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13466 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13467 (clobber (reg:CC 17))]
32ee7d1d 13468 "!TARGET_64BIT"
47d36400 13469{
e075ae69
RH
13470 if (GET_CODE (operands[2]) == LABEL_REF)
13471 operands[2] = XEXP (operands[2], 0);
13472 if (TARGET_DEEP_BRANCH_PREDICTION)
0f40f9f7 13473 return "add{l}\t{%1, %0|%0, %1}";
e075ae69 13474 else
0f40f9f7
ZW
13475 return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13476}
6ef67412 13477 [(set_attr "type" "alu")
d731a1da
JH
13478 ; Since this insn may have two constant operands, we must set the
13479 ; length manually.
13480 (set_attr "length_immediate" "4")
6ef67412 13481 (set_attr "mode" "SI")])
47d36400 13482
e075ae69 13483(define_insn "prologue_get_pc"
69404d6f 13484 [(set (match_operand:SI 0 "register_operand" "=r")
c76aab11 13485 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
1e07edd3 13486 "!TARGET_64BIT"
886c62d1 13487{
e075ae69
RH
13488 if (GET_CODE (operands[1]) == LABEL_REF)
13489 operands[1] = XEXP (operands[1], 0);
0f40f9f7 13490 output_asm_insn ("call\t%X1", operands);
e075ae69
RH
13491 if (! TARGET_DEEP_BRANCH_PREDICTION)
13492 {
0f40f9f7 13493 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
e075ae69
RH
13494 CODE_LABEL_NUMBER (operands[1]));
13495 }
13496 RET;
0f40f9f7 13497}
e075ae69 13498 [(set_attr "type" "multi")])
5f3d14e3 13499
e075ae69
RH
13500(define_expand "epilogue"
13501 [(const_int 1)]
13502 ""
cbbf65e0
RH
13503 "ix86_expand_epilogue (1); DONE;")
13504
13505(define_expand "sibcall_epilogue"
13506 [(const_int 1)]
13507 ""
13508 "ix86_expand_epilogue (0); DONE;")
e075ae69 13509
1020a5ab
RH
13510(define_expand "eh_return"
13511 [(use (match_operand 0 "register_operand" ""))
13512 (use (match_operand 1 "register_operand" ""))]
13513 ""
1020a5ab
RH
13514{
13515 rtx tmp, sa = operands[0], ra = operands[1];
13516
13517 /* Tricky bit: we write the address of the handler to which we will
13518 be returning into someone else's stack frame, one word below the
13519 stack address we wish to restore. */
13520 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13521 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13522 tmp = gen_rtx_MEM (Pmode, tmp);
13523 emit_move_insn (tmp, ra);
13524
d5d6a58b
RH
13525 if (Pmode == SImode)
13526 emit_insn (gen_eh_return_si (sa));
13527 else
13528 emit_insn (gen_eh_return_di (sa));
1020a5ab
RH
13529 emit_barrier ();
13530 DONE;
0f40f9f7 13531})
1020a5ab 13532
d5d6a58b
RH
13533(define_insn_and_split "eh_return_si"
13534 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
1b0c37d7 13535 "!TARGET_64BIT"
d5d6a58b
RH
13536 "#"
13537 "reload_completed"
13538 [(const_int 1)]
13539 "ix86_expand_epilogue (2); DONE;")
13540
13541(define_insn_and_split "eh_return_di"
13542 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
1b0c37d7 13543 "TARGET_64BIT"
1020a5ab
RH
13544 "#"
13545 "reload_completed"
13546 [(const_int 1)]
13547 "ix86_expand_epilogue (2); DONE;")
13548
e075ae69
RH
13549(define_insn "leave"
13550 [(set (reg:SI 7) (reg:SI 6))
f2042df3
RH
13551 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))
13552 (clobber (mem:BLK (scratch)))]
1e07edd3 13553 "!TARGET_64BIT"
e075ae69 13554 "leave"
6ef67412
JH
13555 [(set_attr "length_immediate" "0")
13556 (set_attr "length" "1")
13557 (set_attr "modrm" "0")
13558 (set_attr "modrm" "0")
0b5107cf 13559 (set_attr "athlon_decode" "vector")
e075ae69 13560 (set_attr "ppro_uops" "few")])
8362f420
JH
13561
13562(define_insn "leave_rex64"
13563 [(set (reg:DI 7) (reg:DI 6))
f2042df3
RH
13564 (set (reg:DI 6) (mem:DI (pre_dec:DI (reg:DI 7))))
13565 (clobber (mem:BLK (scratch)))]
8362f420
JH
13566 "TARGET_64BIT"
13567 "leave"
13568 [(set_attr "length_immediate" "0")
13569 (set_attr "length" "1")
13570 (set_attr "modrm" "0")
13571 (set_attr "modrm" "0")
13572 (set_attr "athlon_decode" "vector")
13573 (set_attr "ppro_uops" "few")])
e075ae69
RH
13574\f
13575(define_expand "ffssi2"
4cbfbb1b 13576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
e075ae69
RH
13577 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13578 ""
e075ae69
RH
13579{
13580 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13581 rtx in = operands[1];
13582
13583 if (TARGET_CMOVE)
5f3d14e3 13584 {
e075ae69
RH
13585 emit_move_insn (tmp, constm1_rtx);
13586 emit_insn (gen_ffssi_1 (out, in));
13587 emit_insn (gen_rtx_SET (VOIDmode, out,
13588 gen_rtx_IF_THEN_ELSE (SImode,
16189740 13589 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
e075ae69
RH
13590 const0_rtx),
13591 tmp,
13592 out)));
e0dc26ff
JH
13593 emit_insn (gen_addsi3 (out, out, const1_rtx));
13594 emit_move_insn (operands[0], out);
13595 }
13596
16189740
RH
13597 /* Pentium bsf instruction is extremly slow. The following code is
13598 recommended by the Intel Optimizing Manual as a reasonable replacement:
e0dc26ff
JH
13599 TEST EAX,EAX
13600 JZ SHORT BS2
13601 XOR ECX,ECX
13602 MOV DWORD PTR [TEMP+4],ECX
13603 SUB ECX,EAX
13604 AND EAX,ECX
13605 MOV DWORD PTR [TEMP],EAX
13606 FILD QWORD PTR [TEMP]
13607 FSTP QWORD PTR [TEMP]
13608 WAIT ; WAIT only needed for compatibility with
13609 ; earlier processors
13610 MOV ECX, DWORD PTR [TEMP+4]
13611 SHR ECX,20
13612 SUB ECX,3FFH
13613 TEST EAX,EAX ; clear zero flag
13614 BS2:
13615 Following piece of code expand ffs to similar beast.
13616 */
13617
13618 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13619 {
13620 rtx label = gen_label_rtx ();
13621 rtx lo, hi;
13622 rtx mem = assign_386_stack_local (DImode, 0);
13623 rtx fptmp = gen_reg_rtx (DFmode);
13624 split_di (&mem, 1, &lo, &hi);
13625
13626 emit_move_insn (out, const0_rtx);
13627
13628 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
13629
13630 emit_move_insn (hi, out);
13631 emit_insn (gen_subsi3 (out, out, in));
13632 emit_insn (gen_andsi3 (out, out, in));
13633 emit_move_insn (lo, out);
13634 emit_insn (gen_floatdidf2 (fptmp,mem));
13635 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13636 emit_move_insn (out, hi);
13637 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
16189740 13638 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
e0dc26ff
JH
13639
13640 emit_label (label);
13641 LABEL_NUSES (label) = 1;
13642
13643 emit_move_insn (operands[0], out);
5f3d14e3 13644 }
e075ae69 13645 else
5f3d14e3 13646 {
e075ae69
RH
13647 emit_move_insn (tmp, const0_rtx);
13648 emit_insn (gen_ffssi_1 (out, in));
13649 emit_insn (gen_rtx_SET (VOIDmode,
13650 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
16189740 13651 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
e075ae69
RH
13652 const0_rtx)));
13653 emit_insn (gen_negsi2 (tmp, tmp));
13654 emit_insn (gen_iorsi3 (out, out, tmp));
e0dc26ff
JH
13655 emit_insn (gen_addsi3 (out, out, const1_rtx));
13656 emit_move_insn (operands[0], out);
e075ae69 13657 }
e075ae69 13658 DONE;
0f40f9f7 13659})
886c62d1 13660
e075ae69 13661(define_insn "ffssi_1"
16189740
RH
13662 [(set (reg:CCZ 17)
13663 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13664 (const_int 0)))
e075ae69
RH
13665 (set (match_operand:SI 0 "register_operand" "=r")
13666 (unspec:SI [(match_dup 1)] 5))]
13667 ""
0f40f9f7 13668 "bsf{l}\t{%1, %0|%0, %1}"
6ef67412 13669 [(set_attr "prefix_0f" "1")
e075ae69
RH
13670 (set_attr "ppro_uops" "few")])
13671
13672;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13673;; and slower than the two-byte movzx insn needed to do the work in SImode.
13674\f
13675;; These patterns match the binary 387 instructions for addM3, subM3,
13676;; mulM3 and divM3. There are three patterns for each of DFmode and
13677;; SFmode. The first is the normal insn, the second the same insn but
13678;; with one operand a conversion, and the third the same insn but with
13679;; the other operand a conversion. The conversion may be SFmode or
13680;; SImode if the target mode DFmode, but only SImode if the target mode
13681;; is SFmode.
13682
caa6ec8d
JH
13683;; Gcc is slightly more smart about handling normal two address instructions
13684;; so use special patterns for add and mull.
13685(define_insn "*fop_sf_comm"
1deaa899 13686 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
caa6ec8d 13687 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
13688 [(match_operand:SF 1 "register_operand" "%0,0")
13689 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13690 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
13691 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
13692 "* return output_387_binary_op (insn, operands);"
13693 [(set (attr "type")
1deaa899
JH
13694 (if_then_else (eq_attr "alternative" "1")
13695 (const_string "sse")
13696 (if_then_else (match_operand:SF 3 "mult_operator" "")
13697 (const_string "fmul")
13698 (const_string "fop"))))
13699 (set_attr "mode" "SF")])
13700
13701(define_insn "*fop_sf_comm_sse"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 3 "binary_fp_operator"
13704 [(match_operand:SF 1 "register_operand" "%0")
13705 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13706 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set_attr "type" "sse")
6ef67412 13709 (set_attr "mode" "SF")])
caa6ec8d
JH
13710
13711(define_insn "*fop_df_comm"
1deaa899 13712 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
caa6ec8d 13713 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
13714 [(match_operand:DF 1 "register_operand" "%0,0")
13715 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13716 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
13717 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
13718 "* return output_387_binary_op (insn, operands);"
13719 [(set (attr "type")
1deaa899
JH
13720 (if_then_else (eq_attr "alternative" "1")
13721 (const_string "sse")
13722 (if_then_else (match_operand:SF 3 "mult_operator" "")
13723 (const_string "fmul")
13724 (const_string "fop"))))
13725 (set_attr "mode" "DF")])
13726
13727(define_insn "*fop_df_comm_sse"
13728 [(set (match_operand:DF 0 "register_operand" "=Y")
13729 (match_operator:DF 3 "binary_fp_operator"
13730 [(match_operand:DF 1 "register_operand" "%0")
13731 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13732 "TARGET_SSE2
13733 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13734 "* return output_387_binary_op (insn, operands);"
13735 [(set_attr "type" "sse")
6ef67412 13736 (set_attr "mode" "DF")])
caa6ec8d
JH
13737
13738(define_insn "*fop_xf_comm"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (match_operator:XF 3 "binary_fp_operator"
13741 [(match_operand:XF 1 "register_operand" "%0")
13742 (match_operand:XF 2 "register_operand" "f")]))]
1b0c37d7 13743 "!TARGET_64BIT && TARGET_80387
1e07edd3 13744 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
13745 "* return output_387_binary_op (insn, operands);"
13746 [(set (attr "type")
13747 (if_then_else (match_operand:XF 3 "mult_operator" "")
13748 (const_string "fmul")
6ef67412
JH
13749 (const_string "fop")))
13750 (set_attr "mode" "XF")])
caa6ec8d 13751
2b589241
JH
13752(define_insn "*fop_tf_comm"
13753 [(set (match_operand:TF 0 "register_operand" "=f")
13754 (match_operator:TF 3 "binary_fp_operator"
13755 [(match_operand:TF 1 "register_operand" "%0")
13756 (match_operand:TF 2 "register_operand" "f")]))]
13757 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13758 "* return output_387_binary_op (insn, operands);"
13759 [(set (attr "type")
13760 (if_then_else (match_operand:TF 3 "mult_operator" "")
13761 (const_string "fmul")
13762 (const_string "fop")))
13763 (set_attr "mode" "XF")])
13764
e075ae69 13765(define_insn "*fop_sf_1"
1deaa899 13766 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
e075ae69 13767 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
13768 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13769 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13770 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
caa6ec8d 13771 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
f97d9ec3 13772 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
13773 "* return output_387_binary_op (insn, operands);"
13774 [(set (attr "type")
1deaa899
JH
13775 (cond [(eq_attr "alternative" "2")
13776 (const_string "sse")
13777 (match_operand:SF 3 "mult_operator" "")
e075ae69
RH
13778 (const_string "fmul")
13779 (match_operand:SF 3 "div_operator" "")
13780 (const_string "fdiv")
13781 ]
6ef67412
JH
13782 (const_string "fop")))
13783 (set_attr "mode" "SF")])
e075ae69 13784
1deaa899
JH
13785(define_insn "*fop_sf_1_sse"
13786 [(set (match_operand:SF 0 "register_operand" "=x")
13787 (match_operator:SF 3 "binary_fp_operator"
13788 [(match_operand:SF 1 "register_operand" "0")
13789 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13790 "TARGET_SSE
13791 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13792 "* return output_387_binary_op (insn, operands);"
13793 [(set_attr "type" "sse")
13794 (set_attr "mode" "SF")])
13795
13796;; ??? Add SSE splitters for these!
e075ae69
RH
13797(define_insn "*fop_sf_2"
13798 [(set (match_operand:SF 0 "register_operand" "=f,f")
13799 (match_operator:SF 3 "binary_fp_operator"
13800 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13801 (match_operand:SF 2 "register_operand" "0,0")]))]
1deaa899 13802 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
e075ae69
RH
13803 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13804 [(set (attr "type")
13805 (cond [(match_operand:SF 3 "mult_operator" "")
13806 (const_string "fmul")
13807 (match_operand:SF 3 "div_operator" "")
13808 (const_string "fdiv")
13809 ]
13810 (const_string "fop")))
13811 (set_attr "fp_int_src" "true")
6ef67412
JH
13812 (set_attr "ppro_uops" "many")
13813 (set_attr "mode" "SI")])
e075ae69
RH
13814
13815(define_insn "*fop_sf_3"
13816 [(set (match_operand:SF 0 "register_operand" "=f,f")
13817 (match_operator:SF 3 "binary_fp_operator"
13818 [(match_operand:SF 1 "register_operand" "0,0")
13819 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1deaa899 13820 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
e075ae69
RH
13821 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13822 [(set (attr "type")
13823 (cond [(match_operand:SF 3 "mult_operator" "")
13824 (const_string "fmul")
13825 (match_operand:SF 3 "div_operator" "")
13826 (const_string "fdiv")
13827 ]
13828 (const_string "fop")))
13829 (set_attr "fp_int_src" "true")
6ef67412
JH
13830 (set_attr "ppro_uops" "many")
13831 (set_attr "mode" "SI")])
e075ae69
RH
13832
13833(define_insn "*fop_df_1"
1deaa899 13834 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
e075ae69 13835 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
13836 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
13837 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
13838 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
caa6ec8d 13839 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
f97d9ec3 13840 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
13841 "* return output_387_binary_op (insn, operands);"
13842 [(set (attr "type")
1deaa899
JH
13843 (cond [(eq_attr "alternative" "2")
13844 (const_string "sse")
13845 (match_operand:DF 3 "mult_operator" "")
e075ae69
RH
13846 (const_string "fmul")
13847 (match_operand:DF 3 "div_operator" "")
13848 (const_string "fdiv")
13849 ]
6ef67412
JH
13850 (const_string "fop")))
13851 (set_attr "mode" "DF")])
e075ae69 13852
1deaa899
JH
13853(define_insn "*fop_df_1_sse"
13854 [(set (match_operand:DF 0 "register_operand" "=Y")
13855 (match_operator:DF 3 "binary_fp_operator"
13856 [(match_operand:DF 1 "register_operand" "0")
13857 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13858 "TARGET_SSE
13859 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13860 "* return output_387_binary_op (insn, operands);"
13861 [(set_attr "type" "sse")])
13862
13863;; ??? Add SSE splitters for these!
e075ae69
RH
13864(define_insn "*fop_df_2"
13865 [(set (match_operand:DF 0 "register_operand" "=f,f")
13866 (match_operator:DF 3 "binary_fp_operator"
13867 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13868 (match_operand:DF 2 "register_operand" "0,0")]))]
1deaa899 13869 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
e075ae69
RH
13870 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13871 [(set (attr "type")
13872 (cond [(match_operand:DF 3 "mult_operator" "")
13873 (const_string "fmul")
13874 (match_operand:DF 3 "div_operator" "")
13875 (const_string "fdiv")
13876 ]
13877 (const_string "fop")))
13878 (set_attr "fp_int_src" "true")
6ef67412
JH
13879 (set_attr "ppro_uops" "many")
13880 (set_attr "mode" "SI")])
e075ae69
RH
13881
13882(define_insn "*fop_df_3"
13883 [(set (match_operand:DF 0 "register_operand" "=f,f")
13884 (match_operator:DF 3 "binary_fp_operator"
13885 [(match_operand:DF 1 "register_operand" "0,0")
13886 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1deaa899 13887 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
e075ae69
RH
13888 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13889 [(set (attr "type")
13890 (cond [(match_operand:DF 3 "mult_operator" "")
13891 (const_string "fmul")
13892 (match_operand:DF 3 "div_operator" "")
13893 (const_string "fdiv")
13894 ]
13895 (const_string "fop")))
13896 (set_attr "fp_int_src" "true")
6ef67412
JH
13897 (set_attr "ppro_uops" "many")
13898 (set_attr "mode" "SI")])
e075ae69
RH
13899
13900(define_insn "*fop_df_4"
13901 [(set (match_operand:DF 0 "register_operand" "=f,f")
13902 (match_operator:DF 3 "binary_fp_operator"
13903 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13904 (match_operand:DF 2 "register_operand" "0,f")]))]
f97d9ec3
JH
13905 "TARGET_80387
13906 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
13907 "* return output_387_binary_op (insn, operands);"
13908 [(set (attr "type")
13909 (cond [(match_operand:DF 3 "mult_operator" "")
13910 (const_string "fmul")
13911 (match_operand:DF 3 "div_operator" "")
13912 (const_string "fdiv")
13913 ]
6ef67412
JH
13914 (const_string "fop")))
13915 (set_attr "mode" "SF")])
e075ae69
RH
13916
13917(define_insn "*fop_df_5"
13918 [(set (match_operand:DF 0 "register_operand" "=f,f")
13919 (match_operator:DF 3 "binary_fp_operator"
13920 [(match_operand:DF 1 "register_operand" "0,f")
13921 (float_extend:DF
13922 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1deaa899 13923 "TARGET_80387 && !TARGET_SSE2"
e075ae69
RH
13924 "* return output_387_binary_op (insn, operands);"
13925 [(set (attr "type")
13926 (cond [(match_operand:DF 3 "mult_operator" "")
13927 (const_string "fmul")
13928 (match_operand:DF 3 "div_operator" "")
13929 (const_string "fdiv")
13930 ]
6ef67412
JH
13931 (const_string "fop")))
13932 (set_attr "mode" "SF")])
e075ae69
RH
13933
13934(define_insn "*fop_xf_1"
13935 [(set (match_operand:XF 0 "register_operand" "=f,f")
13936 (match_operator:XF 3 "binary_fp_operator"
13937 [(match_operand:XF 1 "register_operand" "0,f")
13938 (match_operand:XF 2 "register_operand" "f,0")]))]
1b0c37d7 13939 "!TARGET_64BIT && TARGET_80387
caa6ec8d 13940 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
e075ae69
RH
13941 "* return output_387_binary_op (insn, operands);"
13942 [(set (attr "type")
ca285e07 13943 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 13944 (const_string "fmul")
ca285e07 13945 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
13946 (const_string "fdiv")
13947 ]
6ef67412
JH
13948 (const_string "fop")))
13949 (set_attr "mode" "XF")])
e075ae69 13950
2b589241
JH
13951(define_insn "*fop_tf_1"
13952 [(set (match_operand:TF 0 "register_operand" "=f,f")
13953 (match_operator:TF 3 "binary_fp_operator"
13954 [(match_operand:TF 1 "register_operand" "0,f")
13955 (match_operand:TF 2 "register_operand" "f,0")]))]
13956 "TARGET_80387
13957 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13958 "* return output_387_binary_op (insn, operands);"
13959 [(set (attr "type")
13960 (cond [(match_operand:TF 3 "mult_operator" "")
13961 (const_string "fmul")
13962 (match_operand:TF 3 "div_operator" "")
13963 (const_string "fdiv")
13964 ]
13965 (const_string "fop")))
13966 (set_attr "mode" "XF")])
13967
e075ae69
RH
13968(define_insn "*fop_xf_2"
13969 [(set (match_operand:XF 0 "register_operand" "=f,f")
13970 (match_operator:XF 3 "binary_fp_operator"
13971 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13972 (match_operand:XF 2 "register_operand" "0,0")]))]
1b0c37d7 13973 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
e075ae69
RH
13974 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13975 [(set (attr "type")
ca285e07 13976 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 13977 (const_string "fmul")
ca285e07 13978 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
13979 (const_string "fdiv")
13980 ]
13981 (const_string "fop")))
13982 (set_attr "fp_int_src" "true")
6ef67412 13983 (set_attr "mode" "SI")
e075ae69
RH
13984 (set_attr "ppro_uops" "many")])
13985
2b589241
JH
13986(define_insn "*fop_tf_2"
13987 [(set (match_operand:TF 0 "register_operand" "=f,f")
13988 (match_operator:TF 3 "binary_fp_operator"
13989 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13990 (match_operand:TF 2 "register_operand" "0,0")]))]
13991 "TARGET_80387 && TARGET_USE_FIOP"
13992 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13993 [(set (attr "type")
13994 (cond [(match_operand:TF 3 "mult_operator" "")
13995 (const_string "fmul")
13996 (match_operand:TF 3 "div_operator" "")
13997 (const_string "fdiv")
13998 ]
13999 (const_string "fop")))
14000 (set_attr "fp_int_src" "true")
14001 (set_attr "mode" "SI")
14002 (set_attr "ppro_uops" "many")])
14003
e075ae69
RH
14004(define_insn "*fop_xf_3"
14005 [(set (match_operand:XF 0 "register_operand" "=f,f")
14006 (match_operator:XF 3 "binary_fp_operator"
14007 [(match_operand:XF 1 "register_operand" "0,0")
14008 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1b0c37d7 14009 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
e075ae69
RH
14010 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14011 [(set (attr "type")
ca285e07 14012 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14013 (const_string "fmul")
ca285e07 14014 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14015 (const_string "fdiv")
14016 ]
14017 (const_string "fop")))
14018 (set_attr "fp_int_src" "true")
6ef67412 14019 (set_attr "mode" "SI")
e075ae69
RH
14020 (set_attr "ppro_uops" "many")])
14021
2b589241
JH
14022(define_insn "*fop_tf_3"
14023 [(set (match_operand:TF 0 "register_operand" "=f,f")
14024 (match_operator:TF 3 "binary_fp_operator"
14025 [(match_operand:TF 1 "register_operand" "0,0")
14026 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14027 "TARGET_80387 && TARGET_USE_FIOP"
14028 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14029 [(set (attr "type")
14030 (cond [(match_operand:TF 3 "mult_operator" "")
14031 (const_string "fmul")
14032 (match_operand:TF 3 "div_operator" "")
14033 (const_string "fdiv")
14034 ]
14035 (const_string "fop")))
14036 (set_attr "fp_int_src" "true")
14037 (set_attr "mode" "SI")
14038 (set_attr "ppro_uops" "many")])
14039
e075ae69
RH
14040(define_insn "*fop_xf_4"
14041 [(set (match_operand:XF 0 "register_operand" "=f,f")
14042 (match_operator:XF 3 "binary_fp_operator"
14043 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14044 (match_operand:XF 2 "register_operand" "0,f")]))]
1b0c37d7 14045 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
14046 "* return output_387_binary_op (insn, operands);"
14047 [(set (attr "type")
ca285e07 14048 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14049 (const_string "fmul")
ca285e07 14050 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14051 (const_string "fdiv")
14052 ]
6ef67412
JH
14053 (const_string "fop")))
14054 (set_attr "mode" "SF")])
e075ae69 14055
2b589241
JH
14056(define_insn "*fop_tf_4"
14057 [(set (match_operand:TF 0 "register_operand" "=f,f")
14058 (match_operator:TF 3 "binary_fp_operator"
14059 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14060 (match_operand:TF 2 "register_operand" "0,f")]))]
14061 "TARGET_80387"
14062 "* return output_387_binary_op (insn, operands);"
14063 [(set (attr "type")
14064 (cond [(match_operand:TF 3 "mult_operator" "")
14065 (const_string "fmul")
14066 (match_operand:TF 3 "div_operator" "")
14067 (const_string "fdiv")
14068 ]
14069 (const_string "fop")))
14070 (set_attr "mode" "SF")])
14071
e075ae69
RH
14072(define_insn "*fop_xf_5"
14073 [(set (match_operand:XF 0 "register_operand" "=f,f")
14074 (match_operator:XF 3 "binary_fp_operator"
14075 [(match_operand:XF 1 "register_operand" "0,f")
14076 (float_extend:XF
14077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1b0c37d7 14078 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
14079 "* return output_387_binary_op (insn, operands);"
14080 [(set (attr "type")
ca285e07 14081 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14082 (const_string "fmul")
ca285e07 14083 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14084 (const_string "fdiv")
14085 ]
6ef67412
JH
14086 (const_string "fop")))
14087 (set_attr "mode" "SF")])
e075ae69 14088
2b589241
JH
14089(define_insn "*fop_tf_5"
14090 [(set (match_operand:TF 0 "register_operand" "=f,f")
14091 (match_operator:TF 3 "binary_fp_operator"
14092 [(match_operand:TF 1 "register_operand" "0,f")
14093 (float_extend:TF
14094 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14095 "TARGET_80387"
14096 "* return output_387_binary_op (insn, operands);"
14097 [(set (attr "type")
14098 (cond [(match_operand:TF 3 "mult_operator" "")
14099 (const_string "fmul")
14100 (match_operand:TF 3 "div_operator" "")
14101 (const_string "fdiv")
14102 ]
14103 (const_string "fop")))
14104 (set_attr "mode" "SF")])
14105
e075ae69
RH
14106(define_insn "*fop_xf_6"
14107 [(set (match_operand:XF 0 "register_operand" "=f,f")
14108 (match_operator:XF 3 "binary_fp_operator"
14109 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14110 (match_operand:XF 2 "register_operand" "0,f")]))]
1b0c37d7 14111 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
14112 "* return output_387_binary_op (insn, operands);"
14113 [(set (attr "type")
ca285e07 14114 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14115 (const_string "fmul")
ca285e07 14116 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14117 (const_string "fdiv")
14118 ]
6ef67412
JH
14119 (const_string "fop")))
14120 (set_attr "mode" "DF")])
e075ae69 14121
2b589241
JH
14122(define_insn "*fop_tf_6"
14123 [(set (match_operand:TF 0 "register_operand" "=f,f")
14124 (match_operator:TF 3 "binary_fp_operator"
14125 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14126 (match_operand:TF 2 "register_operand" "0,f")]))]
14127 "TARGET_80387"
14128 "* return output_387_binary_op (insn, operands);"
14129 [(set (attr "type")
14130 (cond [(match_operand:TF 3 "mult_operator" "")
14131 (const_string "fmul")
14132 (match_operand:TF 3 "div_operator" "")
14133 (const_string "fdiv")
14134 ]
14135 (const_string "fop")))
14136 (set_attr "mode" "DF")])
14137
e075ae69
RH
14138(define_insn "*fop_xf_7"
14139 [(set (match_operand:XF 0 "register_operand" "=f,f")
14140 (match_operator:XF 3 "binary_fp_operator"
14141 [(match_operand:XF 1 "register_operand" "0,f")
14142 (float_extend:XF
14143 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1b0c37d7 14144 "!TARGET_64BIT && TARGET_80387"
e075ae69
RH
14145 "* return output_387_binary_op (insn, operands);"
14146 [(set (attr "type")
ca285e07 14147 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 14148 (const_string "fmul")
ca285e07 14149 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
14150 (const_string "fdiv")
14151 ]
6ef67412
JH
14152 (const_string "fop")))
14153 (set_attr "mode" "DF")])
e075ae69 14154
2b589241
JH
14155(define_insn "*fop_tf_7"
14156 [(set (match_operand:TF 0 "register_operand" "=f,f")
14157 (match_operator:TF 3 "binary_fp_operator"
14158 [(match_operand:TF 1 "register_operand" "0,f")
14159 (float_extend:TF
14160 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14161 "TARGET_80387"
14162 "* return output_387_binary_op (insn, operands);"
14163 [(set (attr "type")
14164 (cond [(match_operand:TF 3 "mult_operator" "")
14165 (const_string "fmul")
14166 (match_operand:TF 3 "div_operator" "")
14167 (const_string "fdiv")
14168 ]
14169 (const_string "fop")))
14170 (set_attr "mode" "DF")])
14171
e075ae69
RH
14172(define_split
14173 [(set (match_operand 0 "register_operand" "")
14174 (match_operator 3 "binary_fp_operator"
14175 [(float (match_operand:SI 1 "register_operand" ""))
14176 (match_operand 2 "register_operand" "")]))]
14177 "TARGET_80387 && reload_completed
14178 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14179 [(const_int 0)]
4211a8fb
JH
14180{
14181 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14182 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14183 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14184 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14185 GET_MODE (operands[3]),
14186 operands[4],
14187 operands[2])));
14188 ix86_free_from_memory (GET_MODE (operands[1]));
14189 DONE;
0f40f9f7 14190})
e075ae69
RH
14191
14192(define_split
14193 [(set (match_operand 0 "register_operand" "")
14194 (match_operator 3 "binary_fp_operator"
14195 [(match_operand 1 "register_operand" "")
14196 (float (match_operand:SI 2 "register_operand" ""))]))]
14197 "TARGET_80387 && reload_completed
14198 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb 14199 [(const_int 0)]
4211a8fb
JH
14200{
14201 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14202 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14203 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 14204 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
14205 GET_MODE (operands[3]),
14206 operands[1],
14207 operands[4])));
14208 ix86_free_from_memory (GET_MODE (operands[2]));
14209 DONE;
0f40f9f7 14210})
e075ae69
RH
14211\f
14212;; FPU special functions.
14213
a8083431
JH
14214(define_expand "sqrtsf2"
14215 [(set (match_operand:SF 0 "register_operand" "")
14216 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
ca9a9b12 14217 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE"
a8083431
JH
14218{
14219 if (!TARGET_SSE)
14220 operands[1] = force_reg (SFmode, operands[1]);
0f40f9f7 14221})
a8083431
JH
14222
14223(define_insn "sqrtsf2_1"
ca9a9b12
JH
14224 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14225 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
a8083431
JH
14226 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14227 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
14228 "@
14229 fsqrt
0f40f9f7 14230 sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14231 [(set_attr "type" "fpspc,sse")
14232 (set_attr "mode" "SF,SF")
14233 (set_attr "athlon_decode" "direct,*")])
14234
14235(define_insn "sqrtsf2_1_sse_only"
ca9a9b12
JH
14236 [(set (match_operand:SF 0 "register_operand" "=x")
14237 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
a8083431 14238 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
0f40f9f7 14239 "sqrtss\t{%1, %0|%0, %1}"
a8083431
JH
14240 [(set_attr "type" "sse")
14241 (set_attr "mode" "SF")
14242 (set_attr "athlon_decode" "*")])
14243
14244(define_insn "sqrtsf2_i387"
e075ae69
RH
14245 [(set (match_operand:SF 0 "register_operand" "=f")
14246 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
a8083431
JH
14247 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14248 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
e075ae69 14249 "fsqrt"
0b5107cf 14250 [(set_attr "type" "fpspc")
6ef67412 14251 (set_attr "mode" "SF")
0b5107cf 14252 (set_attr "athlon_decode" "direct")])
e075ae69 14253
a8083431
JH
14254(define_expand "sqrtdf2"
14255 [(set (match_operand:DF 0 "register_operand" "")
14256 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14257 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
a8083431
JH
14258{
14259 if (!TARGET_SSE2)
2406cfed 14260 operands[1] = force_reg (DFmode, operands[1]);
0f40f9f7 14261})
a8083431
JH
14262
14263(define_insn "sqrtdf2_1"
14264 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14265 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14266 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14267 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
14268 "@
14269 fsqrt
0f40f9f7 14270 sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14271 [(set_attr "type" "fpspc,sse")
14272 (set_attr "mode" "DF,DF")
14273 (set_attr "athlon_decode" "direct,*")])
14274
14275(define_insn "sqrtdf2_1_sse_only"
14276 [(set (match_operand:DF 0 "register_operand" "=Y")
14277 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14278 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
0f40f9f7 14279 "sqrtsd\t{%1, %0|%0, %1}"
a8083431
JH
14280 [(set_attr "type" "sse")
14281 (set_attr "mode" "DF")
14282 (set_attr "athlon_decode" "*")])
14283
14284(define_insn "sqrtdf2_i387"
e075ae69
RH
14285 [(set (match_operand:DF 0 "register_operand" "=f")
14286 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14287 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
a8083431 14288 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
e075ae69 14289 "fsqrt"
0b5107cf 14290 [(set_attr "type" "fpspc")
6ef67412 14291 (set_attr "mode" "DF")
0b5107cf 14292 (set_attr "athlon_decode" "direct")])
e075ae69 14293
6343a50e 14294(define_insn "*sqrtextendsfdf2"
e075ae69
RH
14295 [(set (match_operand:DF 0 "register_operand" "=f")
14296 (sqrt:DF (float_extend:DF
14297 (match_operand:SF 1 "register_operand" "0"))))]
ca9a9b12 14298 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2"
e075ae69 14299 "fsqrt"
0b5107cf 14300 [(set_attr "type" "fpspc")
6ef67412 14301 (set_attr "mode" "DF")
0b5107cf 14302 (set_attr "athlon_decode" "direct")])
e075ae69
RH
14303
14304(define_insn "sqrtxf2"
14305 [(set (match_operand:XF 0 "register_operand" "=f")
14306 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1b0c37d7 14307 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
de6c5979 14308 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
e075ae69 14309 "fsqrt"
0b5107cf 14310 [(set_attr "type" "fpspc")
6ef67412 14311 (set_attr "mode" "XF")
0b5107cf 14312 (set_attr "athlon_decode" "direct")])
e075ae69 14313
2b589241
JH
14314(define_insn "sqrttf2"
14315 [(set (match_operand:TF 0 "register_operand" "=f")
14316 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14317 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
de6c5979 14318 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
2b589241
JH
14319 "fsqrt"
14320 [(set_attr "type" "fpspc")
14321 (set_attr "mode" "XF")
14322 (set_attr "athlon_decode" "direct")])
14323
6343a50e 14324(define_insn "*sqrtextenddfxf2"
e075ae69
RH
14325 [(set (match_operand:XF 0 "register_operand" "=f")
14326 (sqrt:XF (float_extend:XF
14327 (match_operand:DF 1 "register_operand" "0"))))]
1b0c37d7 14328 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
e075ae69 14329 "fsqrt"
0b5107cf 14330 [(set_attr "type" "fpspc")
6ef67412 14331 (set_attr "mode" "XF")
0b5107cf 14332 (set_attr "athlon_decode" "direct")])
e075ae69 14333
2b589241
JH
14334(define_insn "*sqrtextenddftf2"
14335 [(set (match_operand:TF 0 "register_operand" "=f")
14336 (sqrt:TF (float_extend:TF
14337 (match_operand:DF 1 "register_operand" "0"))))]
14338 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14339 "fsqrt"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "XF")
14342 (set_attr "athlon_decode" "direct")])
14343
6343a50e 14344(define_insn "*sqrtextendsfxf2"
e075ae69
RH
14345 [(set (match_operand:XF 0 "register_operand" "=f")
14346 (sqrt:XF (float_extend:XF
14347 (match_operand:SF 1 "register_operand" "0"))))]
1b0c37d7 14348 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
e075ae69 14349 "fsqrt"
0b5107cf 14350 [(set_attr "type" "fpspc")
6ef67412 14351 (set_attr "mode" "XF")
0b5107cf 14352 (set_attr "athlon_decode" "direct")])
e075ae69 14353
2b589241
JH
14354(define_insn "*sqrtextendsftf2"
14355 [(set (match_operand:TF 0 "register_operand" "=f")
14356 (sqrt:TF (float_extend:TF
14357 (match_operand:SF 1 "register_operand" "0"))))]
14358 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14359 "fsqrt"
14360 [(set_attr "type" "fpspc")
14361 (set_attr "mode" "XF")
14362 (set_attr "athlon_decode" "direct")])
14363
e075ae69
RH
14364(define_insn "sindf2"
14365 [(set (match_operand:DF 0 "register_operand" "=f")
14366 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
de6c5979
BL
14367 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14368 && flag_unsafe_math_optimizations"
e075ae69 14369 "fsin"
6ef67412
JH
14370 [(set_attr "type" "fpspc")
14371 (set_attr "mode" "DF")])
e075ae69
RH
14372
14373(define_insn "sinsf2"
14374 [(set (match_operand:SF 0 "register_operand" "=f")
14375 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
de6c5979
BL
14376 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14377 && flag_unsafe_math_optimizations"
e075ae69 14378 "fsin"
6ef67412
JH
14379 [(set_attr "type" "fpspc")
14380 (set_attr "mode" "SF")])
5f3d14e3 14381
6343a50e 14382(define_insn "*sinextendsfdf2"
e075ae69
RH
14383 [(set (match_operand:DF 0 "register_operand" "=f")
14384 (unspec:DF [(float_extend:DF
14385 (match_operand:SF 1 "register_operand" "0"))] 1))]
de6c5979
BL
14386 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14387 && flag_unsafe_math_optimizations"
e075ae69 14388 "fsin"
6ef67412
JH
14389 [(set_attr "type" "fpspc")
14390 (set_attr "mode" "DF")])
4f9ca067 14391
e075ae69
RH
14392(define_insn "sinxf2"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
1b0c37d7 14395 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
de6c5979 14396 && flag_unsafe_math_optimizations"
e075ae69 14397 "fsin"
6ef67412
JH
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "XF")])
5f3d14e3 14400
2b589241
JH
14401(define_insn "sintf2"
14402 [(set (match_operand:TF 0 "register_operand" "=f")
14403 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
de6c5979
BL
14404 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14405 && flag_unsafe_math_optimizations"
2b589241
JH
14406 "fsin"
14407 [(set_attr "type" "fpspc")
14408 (set_attr "mode" "XF")])
14409
e075ae69
RH
14410(define_insn "cosdf2"
14411 [(set (match_operand:DF 0 "register_operand" "=f")
14412 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
de6c5979
BL
14413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14414 && flag_unsafe_math_optimizations"
e075ae69 14415 "fcos"
6ef67412
JH
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "DF")])
bca7cce2 14418
e075ae69
RH
14419(define_insn "cossf2"
14420 [(set (match_operand:SF 0 "register_operand" "=f")
14421 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
de6c5979
BL
14422 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14423 && flag_unsafe_math_optimizations"
e075ae69 14424 "fcos"
6ef67412
JH
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "SF")])
bca7cce2 14427
6343a50e 14428(define_insn "*cosextendsfdf2"
e075ae69
RH
14429 [(set (match_operand:DF 0 "register_operand" "=f")
14430 (unspec:DF [(float_extend:DF
14431 (match_operand:SF 1 "register_operand" "0"))] 2))]
de6c5979
BL
14432 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14433 && flag_unsafe_math_optimizations"
e075ae69 14434 "fcos"
6ef67412
JH
14435 [(set_attr "type" "fpspc")
14436 (set_attr "mode" "DF")])
5f3d14e3 14437
e075ae69
RH
14438(define_insn "cosxf2"
14439 [(set (match_operand:XF 0 "register_operand" "=f")
14440 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
1e07edd3 14441 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
de6c5979 14442 && flag_unsafe_math_optimizations"
e075ae69 14443 "fcos"
6ef67412
JH
14444 [(set_attr "type" "fpspc")
14445 (set_attr "mode" "XF")])
2b589241
JH
14446
14447(define_insn "costf2"
14448 [(set (match_operand:TF 0 "register_operand" "=f")
14449 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
de6c5979
BL
14450 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14451 && flag_unsafe_math_optimizations"
2b589241
JH
14452 "fcos"
14453 [(set_attr "type" "fpspc")
14454 (set_attr "mode" "XF")])
e075ae69
RH
14455\f
14456;; Block operation instructions
886c62d1 14457
7c7ef435
JH
14458(define_insn "cld"
14459 [(set (reg:SI 19) (const_int 0))]
14460 ""
14461 "cld"
14462 [(set_attr "type" "cld")])
14463
886c62d1 14464(define_expand "movstrsi"
f90800f8
JH
14465 [(use (match_operand:BLK 0 "memory_operand" ""))
14466 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 14467 (use (match_operand:SI 2 "nonmemory_operand" ""))
f90800f8 14468 (use (match_operand:SI 3 "const_int_operand" ""))]
886c62d1 14469 ""
886c62d1 14470{
0945b39d
JH
14471 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14472 DONE;
14473 else
14474 FAIL;
0f40f9f7 14475})
79f05c19 14476
0945b39d
JH
14477(define_expand "movstrdi"
14478 [(use (match_operand:BLK 0 "memory_operand" ""))
14479 (use (match_operand:BLK 1 "memory_operand" ""))
14480 (use (match_operand:DI 2 "nonmemory_operand" ""))
14481 (use (match_operand:DI 3 "const_int_operand" ""))]
14482 "TARGET_64BIT"
0945b39d
JH
14483{
14484 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14485 DONE;
14486 else
14487 FAIL;
0f40f9f7 14488})
79f05c19 14489
0945b39d
JH
14490;; Most CPUs don't like single string operations
14491;; Handle this case here to simplify previous expander.
79f05c19 14492
0945b39d
JH
14493(define_expand "strmovdi_rex64"
14494 [(set (match_dup 2)
14495 (mem:DI (match_operand:DI 1 "register_operand" "")))
14496 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14497 (match_dup 2))
14498 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14499 (clobber (reg:CC 17))])
14500 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14501 (clobber (reg:CC 17))])]
14502 "TARGET_64BIT"
0945b39d
JH
14503{
14504 if (TARGET_SINGLE_STRINGOP || optimize_size)
79f05c19 14505 {
0945b39d
JH
14506 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14507 operands[1]));
14508 DONE;
79f05c19 14509 }
0945b39d
JH
14510 else
14511 operands[2] = gen_reg_rtx (DImode);
0f40f9f7 14512})
886c62d1 14513
56c0e8fa 14514
79f05c19
JH
14515(define_expand "strmovsi"
14516 [(set (match_dup 2)
14517 (mem:SI (match_operand:SI 1 "register_operand" "")))
14518 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14519 (match_dup 2))
14520 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14521 (clobber (reg:CC 17))])
14522 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14523 (clobber (reg:CC 17))])]
14524 ""
79f05c19 14525{
0945b39d
JH
14526 if (TARGET_64BIT)
14527 {
14528 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14529 DONE;
14530 }
79f05c19
JH
14531 if (TARGET_SINGLE_STRINGOP || optimize_size)
14532 {
14533 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14534 operands[1]));
14535 DONE;
14536 }
14537 else
14538 operands[2] = gen_reg_rtx (SImode);
0f40f9f7 14539})
79f05c19 14540
0945b39d
JH
14541(define_expand "strmovsi_rex64"
14542 [(set (match_dup 2)
14543 (mem:SI (match_operand:DI 1 "register_operand" "")))
14544 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14545 (match_dup 2))
14546 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14547 (clobber (reg:CC 17))])
14548 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14549 (clobber (reg:CC 17))])]
14550 "TARGET_64BIT"
0945b39d
JH
14551{
14552 if (TARGET_SINGLE_STRINGOP || optimize_size)
14553 {
14554 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14555 operands[1]));
14556 DONE;
14557 }
14558 else
14559 operands[2] = gen_reg_rtx (SImode);
0f40f9f7 14560})
0945b39d 14561
f90800f8
JH
14562(define_expand "strmovhi"
14563 [(set (match_dup 2)
14564 (mem:HI (match_operand:SI 1 "register_operand" "")))
14565 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14566 (match_dup 2))
14567 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14568 (clobber (reg:CC 17))])
14569 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14570 (clobber (reg:CC 17))])]
886c62d1 14571 ""
886c62d1 14572{
0945b39d
JH
14573 if (TARGET_64BIT)
14574 {
14575 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14576 DONE;
14577 }
f90800f8 14578 if (TARGET_SINGLE_STRINGOP || optimize_size)
886c62d1 14579 {
f90800f8
JH
14580 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14581 operands[1]));
14582 DONE;
14583 }
14584 else
14585 operands[2] = gen_reg_rtx (HImode);
0f40f9f7 14586})
886c62d1 14587
0945b39d
JH
14588(define_expand "strmovhi_rex64"
14589 [(set (match_dup 2)
14590 (mem:HI (match_operand:DI 1 "register_operand" "")))
14591 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14592 (match_dup 2))
14593 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14594 (clobber (reg:CC 17))])
14595 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14596 (clobber (reg:CC 17))])]
14597 "TARGET_64BIT"
0945b39d
JH
14598{
14599 if (TARGET_SINGLE_STRINGOP || optimize_size)
14600 {
14601 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14602 operands[1]));
14603 DONE;
14604 }
14605 else
14606 operands[2] = gen_reg_rtx (HImode);
0f40f9f7 14607})
0945b39d 14608
f90800f8
JH
14609(define_expand "strmovqi"
14610 [(set (match_dup 2)
14611 (mem:QI (match_operand:SI 1 "register_operand" "")))
14612 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14613 (match_dup 2))
14614 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14615 (clobber (reg:CC 17))])
14616 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14617 (clobber (reg:CC 17))])]
14618 ""
f90800f8 14619{
0945b39d
JH
14620 if (TARGET_64BIT)
14621 {
14622 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14623 DONE;
14624 }
f90800f8
JH
14625 if (TARGET_SINGLE_STRINGOP || optimize_size)
14626 {
14627 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14628 operands[1]));
14629 DONE;
886c62d1 14630 }
f90800f8
JH
14631 else
14632 operands[2] = gen_reg_rtx (QImode);
0f40f9f7 14633})
f90800f8 14634
0945b39d
JH
14635(define_expand "strmovqi_rex64"
14636 [(set (match_dup 2)
14637 (mem:QI (match_operand:DI 1 "register_operand" "")))
14638 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14639 (match_dup 2))
14640 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14641 (clobber (reg:CC 17))])
14642 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14643 (clobber (reg:CC 17))])]
1b0c37d7 14644 "TARGET_64BIT"
0945b39d
JH
14645{
14646 if (TARGET_SINGLE_STRINGOP || optimize_size)
14647 {
14648 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14649 operands[1]));
14650 DONE;
14651 }
14652 else
14653 operands[2] = gen_reg_rtx (QImode);
0f40f9f7 14654})
0945b39d
JH
14655
14656(define_insn "strmovdi_rex_1"
14657 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14658 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14659 (set (match_operand:DI 0 "register_operand" "=D")
14660 (plus:DI (match_dup 2)
14661 (const_int 8)))
14662 (set (match_operand:DI 1 "register_operand" "=S")
14663 (plus:DI (match_dup 3)
14664 (const_int 8)))
14665 (use (reg:SI 19))]
14666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14667 "movsq"
14668 [(set_attr "type" "str")
14669 (set_attr "mode" "DI")
14670 (set_attr "memory" "both")])
14671
79f05c19
JH
14672(define_insn "strmovsi_1"
14673 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14674 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14675 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 14676 (plus:SI (match_dup 2)
79f05c19
JH
14677 (const_int 4)))
14678 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 14679 (plus:SI (match_dup 3)
79f05c19
JH
14680 (const_int 4)))
14681 (use (reg:SI 19))]
0945b39d 14682 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 14683 "{movsl|movsd}"
0945b39d
JH
14684 [(set_attr "type" "str")
14685 (set_attr "mode" "SI")
14686 (set_attr "memory" "both")])
14687
14688(define_insn "strmovsi_rex_1"
14689 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14690 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14691 (set (match_operand:DI 0 "register_operand" "=D")
14692 (plus:DI (match_dup 2)
14693 (const_int 4)))
14694 (set (match_operand:DI 1 "register_operand" "=S")
14695 (plus:DI (match_dup 3)
14696 (const_int 4)))
14697 (use (reg:SI 19))]
14698 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
371bc54b 14699 "{movsl|movsd}"
79f05c19 14700 [(set_attr "type" "str")
6ef67412 14701 (set_attr "mode" "SI")
79f05c19
JH
14702 (set_attr "memory" "both")])
14703
f90800f8
JH
14704(define_insn "strmovhi_1"
14705 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14706 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14707 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 14708 (plus:SI (match_dup 2)
f90800f8
JH
14709 (const_int 2)))
14710 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 14711 (plus:SI (match_dup 3)
f90800f8
JH
14712 (const_int 2)))
14713 (use (reg:SI 19))]
0945b39d
JH
14714 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14715 "movsw"
14716 [(set_attr "type" "str")
14717 (set_attr "memory" "both")
14718 (set_attr "mode" "HI")])
14719
14720(define_insn "strmovhi_rex_1"
14721 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14722 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14723 (set (match_operand:DI 0 "register_operand" "=D")
14724 (plus:DI (match_dup 2)
14725 (const_int 2)))
14726 (set (match_operand:DI 1 "register_operand" "=S")
14727 (plus:DI (match_dup 3)
14728 (const_int 2)))
14729 (use (reg:SI 19))]
14730 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
14731 "movsw"
14732 [(set_attr "type" "str")
14733 (set_attr "memory" "both")
6ef67412 14734 (set_attr "mode" "HI")])
f90800f8
JH
14735
14736(define_insn "strmovqi_1"
14737 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14738 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14739 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 14740 (plus:SI (match_dup 2)
f90800f8
JH
14741 (const_int 1)))
14742 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 14743 (plus:SI (match_dup 3)
f90800f8
JH
14744 (const_int 1)))
14745 (use (reg:SI 19))]
0945b39d 14746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
f90800f8
JH
14747 "movsb"
14748 [(set_attr "type" "str")
6ef67412
JH
14749 (set_attr "memory" "both")
14750 (set_attr "mode" "QI")])
f90800f8 14751
0945b39d
JH
14752(define_insn "strmovqi_rex_1"
14753 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14754 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14755 (set (match_operand:DI 0 "register_operand" "=D")
14756 (plus:DI (match_dup 2)
14757 (const_int 1)))
14758 (set (match_operand:DI 1 "register_operand" "=S")
14759 (plus:DI (match_dup 3)
14760 (const_int 1)))
14761 (use (reg:SI 19))]
14762 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14763 "movsb"
14764 [(set_attr "type" "str")
14765 (set_attr "memory" "both")
14766 (set_attr "mode" "QI")])
14767
14768(define_insn "rep_movdi_rex64"
14769 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14770 (set (match_operand:DI 0 "register_operand" "=D")
14771 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14772 (const_int 3))
14773 (match_operand:DI 3 "register_operand" "0")))
14774 (set (match_operand:DI 1 "register_operand" "=S")
14775 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
14776 (match_operand:DI 4 "register_operand" "1")))
14777 (set (mem:BLK (match_dup 3))
14778 (mem:BLK (match_dup 4)))
14779 (use (match_dup 5))
14780 (use (reg:SI 19))]
14781 "TARGET_64BIT"
14782 "rep\;movsq|rep movsq"
14783 [(set_attr "type" "str")
14784 (set_attr "prefix_rep" "1")
14785 (set_attr "memory" "both")
14786 (set_attr "mode" "DI")])
14787
f90800f8
JH
14788(define_insn "rep_movsi"
14789 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 14790 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
14791 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
14792 (const_int 2))
14793 (match_operand:SI 3 "register_operand" "0")))
f90800f8 14794 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
14795 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
14796 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
14797 (set (mem:BLK (match_dup 3))
14798 (mem:BLK (match_dup 4)))
b1cdafbb 14799 (use (match_dup 5))
f90800f8 14800 (use (reg:SI 19))]
0945b39d
JH
14801 "!TARGET_64BIT"
14802 "rep\;movsl|rep movsd"
14803 [(set_attr "type" "str")
14804 (set_attr "prefix_rep" "1")
14805 (set_attr "memory" "both")
14806 (set_attr "mode" "SI")])
14807
14808(define_insn "rep_movsi_rex64"
14809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14810 (set (match_operand:DI 0 "register_operand" "=D")
14811 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14812 (const_int 2))
14813 (match_operand:DI 3 "register_operand" "0")))
14814 (set (match_operand:DI 1 "register_operand" "=S")
14815 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
14816 (match_operand:DI 4 "register_operand" "1")))
14817 (set (mem:BLK (match_dup 3))
14818 (mem:BLK (match_dup 4)))
14819 (use (match_dup 5))
14820 (use (reg:SI 19))]
14821 "TARGET_64BIT"
f90800f8
JH
14822 "rep\;movsl|rep movsd"
14823 [(set_attr "type" "str")
6ef67412
JH
14824 (set_attr "prefix_rep" "1")
14825 (set_attr "memory" "both")
14826 (set_attr "mode" "SI")])
f90800f8
JH
14827
14828(define_insn "rep_movqi"
14829 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 14830 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
14831 (plus:SI (match_operand:SI 3 "register_operand" "0")
14832 (match_operand:SI 5 "register_operand" "2")))
f90800f8 14833 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 14834 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
14835 (set (mem:BLK (match_dup 3))
14836 (mem:BLK (match_dup 4)))
b1cdafbb 14837 (use (match_dup 5))
f90800f8 14838 (use (reg:SI 19))]
0945b39d
JH
14839 "!TARGET_64BIT"
14840 "rep\;movsb|rep movsb"
14841 [(set_attr "type" "str")
14842 (set_attr "prefix_rep" "1")
14843 (set_attr "memory" "both")
14844 (set_attr "mode" "SI")])
14845
14846(define_insn "rep_movqi_rex64"
14847 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14848 (set (match_operand:DI 0 "register_operand" "=D")
14849 (plus:DI (match_operand:DI 3 "register_operand" "0")
14850 (match_operand:DI 5 "register_operand" "2")))
14851 (set (match_operand:DI 1 "register_operand" "=S")
14852 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
14853 (set (mem:BLK (match_dup 3))
14854 (mem:BLK (match_dup 4)))
14855 (use (match_dup 5))
14856 (use (reg:SI 19))]
14857 "TARGET_64BIT"
f90800f8
JH
14858 "rep\;movsb|rep movsb"
14859 [(set_attr "type" "str")
6ef67412
JH
14860 (set_attr "prefix_rep" "1")
14861 (set_attr "memory" "both")
14862 (set_attr "mode" "SI")])
886c62d1 14863
0ae40045 14864(define_expand "clrstrsi"
e2e52e1b 14865 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 14866 (use (match_operand:SI 1 "nonmemory_operand" ""))
0945b39d 14867 (use (match_operand 2 "const_int_operand" ""))]
0ae40045 14868 ""
0ae40045 14869{
0945b39d
JH
14870 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14871 DONE;
14872 else
14873 FAIL;
0f40f9f7 14874})
e2e52e1b 14875
0945b39d
JH
14876(define_expand "clrstrdi"
14877 [(use (match_operand:BLK 0 "memory_operand" ""))
14878 (use (match_operand:DI 1 "nonmemory_operand" ""))
14879 (use (match_operand 2 "const_int_operand" ""))]
14880 "TARGET_64BIT"
0945b39d
JH
14881{
14882 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14883 DONE;
14884 else
14885 FAIL;
0f40f9f7 14886})
e2e52e1b 14887
0945b39d
JH
14888;; Most CPUs don't like single string operations
14889;; Handle this case here to simplify previous expander.
79f05c19 14890
0945b39d
JH
14891(define_expand "strsetdi_rex64"
14892 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
14893 (match_operand:DI 1 "register_operand" ""))
14894 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14895 (clobber (reg:CC 17))])]
14896 "TARGET_64BIT"
0945b39d
JH
14897{
14898 if (TARGET_SINGLE_STRINGOP || optimize_size)
79f05c19 14899 {
0945b39d
JH
14900 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
14901 DONE;
79f05c19 14902 }
0f40f9f7 14903})
e2e52e1b 14904
79f05c19
JH
14905(define_expand "strsetsi"
14906 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
14907 (match_operand:SI 1 "register_operand" ""))
14908 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14909 (clobber (reg:CC 17))])]
14910 ""
79f05c19 14911{
0945b39d
JH
14912 if (TARGET_64BIT)
14913 {
14914 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
14915 DONE;
14916 }
14917 else if (TARGET_SINGLE_STRINGOP || optimize_size)
79f05c19
JH
14918 {
14919 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
14920 DONE;
14921 }
0f40f9f7 14922})
79f05c19 14923
0945b39d
JH
14924(define_expand "strsetsi_rex64"
14925 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
14926 (match_operand:SI 1 "register_operand" ""))
14927 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14928 (clobber (reg:CC 17))])]
14929 "TARGET_64BIT"
0945b39d
JH
14930{
14931 if (TARGET_SINGLE_STRINGOP || optimize_size)
14932 {
14933 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
14934 DONE;
14935 }
0f40f9f7 14936})
0945b39d 14937
e2e52e1b
JH
14938(define_expand "strsethi"
14939 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
14940 (match_operand:HI 1 "register_operand" ""))
14941 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14942 (clobber (reg:CC 17))])]
14943 ""
e2e52e1b 14944{
0945b39d
JH
14945 if (TARGET_64BIT)
14946 {
14947 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
14948 DONE;
14949 }
14950 else if (TARGET_SINGLE_STRINGOP || optimize_size)
e2e52e1b
JH
14951 {
14952 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
14953 DONE;
14954 }
0f40f9f7 14955})
0ae40045 14956
0945b39d
JH
14957(define_expand "strsethi_rex64"
14958 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
14959 (match_operand:HI 1 "register_operand" ""))
14960 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14961 (clobber (reg:CC 17))])]
14962 "TARGET_64BIT"
0945b39d
JH
14963{
14964 if (TARGET_SINGLE_STRINGOP || optimize_size)
14965 {
14966 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
14967 DONE;
14968 }
0f40f9f7 14969})
0945b39d 14970
e2e52e1b
JH
14971(define_expand "strsetqi"
14972 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
14973 (match_operand:QI 1 "register_operand" ""))
14974 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14975 (clobber (reg:CC 17))])]
14976 ""
e2e52e1b 14977{
0945b39d
JH
14978 if (TARGET_64BIT)
14979 {
14980 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
14981 DONE;
14982 }
14983 else if (TARGET_SINGLE_STRINGOP || optimize_size)
e2e52e1b
JH
14984 {
14985 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
14986 DONE;
14987 }
0f40f9f7 14988})
0ae40045 14989
0945b39d
JH
14990(define_expand "strsetqi_rex64"
14991 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
14992 (match_operand:QI 1 "register_operand" ""))
14993 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14994 (clobber (reg:CC 17))])]
14995 "TARGET_64BIT"
0945b39d
JH
14996{
14997 if (TARGET_SINGLE_STRINGOP || optimize_size)
14998 {
14999 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15000 DONE;
15001 }
0f40f9f7 15002})
0945b39d
JH
15003
15004(define_insn "strsetdi_rex_1"
15005 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15006 (match_operand:SI 2 "register_operand" "a"))
15007 (set (match_operand:DI 0 "register_operand" "=D")
15008 (plus:DI (match_dup 1)
15009 (const_int 8)))
15010 (use (reg:SI 19))]
15011 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15012 "stosq"
15013 [(set_attr "type" "str")
15014 (set_attr "memory" "store")
15015 (set_attr "mode" "DI")])
15016
79f05c19
JH
15017(define_insn "strsetsi_1"
15018 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15019 (match_operand:SI 2 "register_operand" "a"))
15020 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15021 (plus:SI (match_dup 1)
79f05c19
JH
15022 (const_int 4)))
15023 (use (reg:SI 19))]
0945b39d
JH
15024 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15025 "stosl|stosd"
15026 [(set_attr "type" "str")
15027 (set_attr "memory" "store")
15028 (set_attr "mode" "SI")])
15029
15030(define_insn "strsetsi_rex_1"
15031 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15032 (match_operand:SI 2 "register_operand" "a"))
15033 (set (match_operand:DI 0 "register_operand" "=D")
15034 (plus:DI (match_dup 1)
15035 (const_int 4)))
15036 (use (reg:SI 19))]
15037 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15038 "stosl|stosd"
79f05c19 15039 [(set_attr "type" "str")
6ef67412
JH
15040 (set_attr "memory" "store")
15041 (set_attr "mode" "SI")])
79f05c19 15042
e2e52e1b
JH
15043(define_insn "strsethi_1"
15044 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15045 (match_operand:HI 2 "register_operand" "a"))
15046 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15047 (plus:SI (match_dup 1)
e2e52e1b
JH
15048 (const_int 2)))
15049 (use (reg:SI 19))]
0945b39d
JH
15050 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15051 "stosw"
15052 [(set_attr "type" "str")
15053 (set_attr "memory" "store")
15054 (set_attr "mode" "HI")])
15055
15056(define_insn "strsethi_rex_1"
15057 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15058 (match_operand:HI 2 "register_operand" "a"))
15059 (set (match_operand:DI 0 "register_operand" "=D")
15060 (plus:DI (match_dup 1)
15061 (const_int 2)))
15062 (use (reg:SI 19))]
15063 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
15064 "stosw"
15065 [(set_attr "type" "str")
15066 (set_attr "memory" "store")
6ef67412 15067 (set_attr "mode" "HI")])
e2e52e1b
JH
15068
15069(define_insn "strsetqi_1"
15070 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15071 (match_operand:QI 2 "register_operand" "a"))
15072 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 15073 (plus:SI (match_dup 1)
e2e52e1b
JH
15074 (const_int 1)))
15075 (use (reg:SI 19))]
0945b39d
JH
15076 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15077 "stosb"
15078 [(set_attr "type" "str")
15079 (set_attr "memory" "store")
15080 (set_attr "mode" "QI")])
15081
15082(define_insn "strsetqi_rex_1"
15083 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15084 (match_operand:QI 2 "register_operand" "a"))
15085 (set (match_operand:DI 0 "register_operand" "=D")
15086 (plus:DI (match_dup 1)
15087 (const_int 1)))
15088 (use (reg:SI 19))]
15089 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
e2e52e1b
JH
15090 "stosb"
15091 [(set_attr "type" "str")
6ef67412
JH
15092 (set_attr "memory" "store")
15093 (set_attr "mode" "QI")])
e2e52e1b 15094
0945b39d
JH
15095(define_insn "rep_stosdi_rex64"
15096 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15097 (set (match_operand:DI 0 "register_operand" "=D")
15098 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15099 (const_int 3))
15100 (match_operand:DI 3 "register_operand" "0")))
15101 (set (mem:BLK (match_dup 3))
15102 (const_int 0))
15103 (use (match_operand:DI 2 "register_operand" "a"))
15104 (use (match_dup 4))
15105 (use (reg:SI 19))]
15106 "TARGET_64BIT"
15107 "rep\;stosq|rep stosq"
15108 [(set_attr "type" "str")
15109 (set_attr "prefix_rep" "1")
15110 (set_attr "memory" "store")
15111 (set_attr "mode" "DI")])
15112
e2e52e1b
JH
15113(define_insn "rep_stossi"
15114 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 15115 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15116 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15117 (const_int 2))
15118 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 15119 (set (mem:BLK (match_dup 3))
0ae40045 15120 (const_int 0))
b1cdafbb
JH
15121 (use (match_operand:SI 2 "register_operand" "a"))
15122 (use (match_dup 4))
e2e52e1b 15123 (use (reg:SI 19))]
0945b39d
JH
15124 "!TARGET_64BIT"
15125 "rep\;stosl|rep stosd"
15126 [(set_attr "type" "str")
15127 (set_attr "prefix_rep" "1")
15128 (set_attr "memory" "store")
15129 (set_attr "mode" "SI")])
15130
15131(define_insn "rep_stossi_rex64"
15132 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15133 (set (match_operand:DI 0 "register_operand" "=D")
15134 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15135 (const_int 2))
15136 (match_operand:DI 3 "register_operand" "0")))
15137 (set (mem:BLK (match_dup 3))
15138 (const_int 0))
15139 (use (match_operand:SI 2 "register_operand" "a"))
15140 (use (match_dup 4))
15141 (use (reg:SI 19))]
15142 "TARGET_64BIT"
e2e52e1b
JH
15143 "rep\;stosl|rep stosd"
15144 [(set_attr "type" "str")
6ef67412
JH
15145 (set_attr "prefix_rep" "1")
15146 (set_attr "memory" "store")
15147 (set_attr "mode" "SI")])
0ae40045 15148
e2e52e1b
JH
15149(define_insn "rep_stosqi"
15150 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 15151 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
15152 (plus:SI (match_operand:SI 3 "register_operand" "0")
15153 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
15154 (set (mem:BLK (match_dup 3))
15155 (const_int 0))
b1cdafbb
JH
15156 (use (match_operand:QI 2 "register_operand" "a"))
15157 (use (match_dup 4))
e2e52e1b 15158 (use (reg:SI 19))]
0945b39d
JH
15159 "!TARGET_64BIT"
15160 "rep\;stosb|rep stosb"
15161 [(set_attr "type" "str")
15162 (set_attr "prefix_rep" "1")
15163 (set_attr "memory" "store")
15164 (set_attr "mode" "QI")])
15165
15166(define_insn "rep_stosqi_rex64"
15167 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15168 (set (match_operand:DI 0 "register_operand" "=D")
15169 (plus:DI (match_operand:DI 3 "register_operand" "0")
15170 (match_operand:DI 4 "register_operand" "1")))
15171 (set (mem:BLK (match_dup 3))
15172 (const_int 0))
15173 (use (match_operand:QI 2 "register_operand" "a"))
15174 (use (match_dup 4))
15175 (use (reg:DI 19))]
15176 "TARGET_64BIT"
e2e52e1b
JH
15177 "rep\;stosb|rep stosb"
15178 [(set_attr "type" "str")
6ef67412
JH
15179 (set_attr "prefix_rep" "1")
15180 (set_attr "memory" "store")
15181 (set_attr "mode" "QI")])
0ae40045 15182
886c62d1 15183(define_expand "cmpstrsi"
e075ae69
RH
15184 [(set (match_operand:SI 0 "register_operand" "")
15185 (compare:SI (match_operand:BLK 1 "general_operand" "")
15186 (match_operand:BLK 2 "general_operand" "")))
0945b39d
JH
15187 (use (match_operand 3 "general_operand" ""))
15188 (use (match_operand 4 "immediate_operand" ""))]
886c62d1 15189 ""
886c62d1 15190{
e075ae69
RH
15191 rtx addr1, addr2, out, outlow, count, countreg, align;
15192
15193 out = operands[0];
15194 if (GET_CODE (out) != REG)
15195 out = gen_reg_rtx (SImode);
783cdf65
JVA
15196
15197 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15198 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
e075ae69
RH
15199
15200 count = operands[3];
d24b3457 15201 countreg = ix86_zero_extend_to_Pmode (count);
e075ae69
RH
15202
15203 /* %%% Iff we are testing strict equality, we can use known alignment
15204 to good advantage. This may be possible with combine, particularly
15205 once cc0 is dead. */
15206 align = operands[4];
783cdf65 15207
7c7ef435 15208 emit_insn (gen_cld ());
e075ae69
RH
15209 if (GET_CODE (count) == CONST_INT)
15210 {
15211 if (INTVAL (count) == 0)
15212 {
15213 emit_move_insn (operands[0], const0_rtx);
15214 DONE;
15215 }
0945b39d
JH
15216 if (TARGET_64BIT)
15217 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15218 addr1, addr2, countreg));
15219 else
15220 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15221 addr1, addr2, countreg));
e075ae69
RH
15222 }
15223 else
e2e52e1b 15224 {
0945b39d
JH
15225 if (TARGET_64BIT)
15226 {
15227 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15228 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15229 addr1, addr2, countreg));
15230 }
15231 else
15232 {
15233 emit_insn (gen_cmpsi_1 (countreg, countreg));
15234 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15235 addr1, addr2, countreg));
15236 }
e2e52e1b 15237 }
e075ae69
RH
15238
15239 outlow = gen_lowpart (QImode, out);
15240 emit_insn (gen_cmpintqi (outlow));
15241 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 15242
e075ae69
RH
15243 if (operands[0] != out)
15244 emit_move_insn (operands[0], out);
783cdf65 15245
e075ae69 15246 DONE;
0f40f9f7 15247})
886c62d1 15248
e075ae69
RH
15249;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15250
15251(define_expand "cmpintqi"
15252 [(set (match_dup 1)
15253 (gtu:QI (reg:CC 17) (const_int 0)))
15254 (set (match_dup 2)
15255 (ltu:QI (reg:CC 17) (const_int 0)))
15256 (parallel [(set (match_operand:QI 0 "register_operand" "")
15257 (minus:QI (match_dup 1)
15258 (match_dup 2)))
15259 (clobber (reg:CC 17))])]
15260 ""
15261 "operands[1] = gen_reg_rtx (QImode);
15262 operands[2] = gen_reg_rtx (QImode);")
15263
f76e3b05
JVA
15264;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15265;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 15266
0945b39d 15267(define_insn "cmpstrqi_nz_1"
e075ae69 15268 [(set (reg:CC 17)
b1cdafbb
JH
15269 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15270 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15271 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 15272 (use (match_operand:SI 3 "immediate_operand" "i"))
7c7ef435 15273 (use (reg:SI 19))
b1cdafbb
JH
15274 (clobber (match_operand:SI 0 "register_operand" "=S"))
15275 (clobber (match_operand:SI 1 "register_operand" "=D"))
15276 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
15277 "!TARGET_64BIT"
15278 "repz{\;| }cmpsb"
15279 [(set_attr "type" "str")
15280 (set_attr "mode" "QI")
15281 (set_attr "prefix_rep" "1")])
15282
15283(define_insn "cmpstrqi_nz_rex_1"
15284 [(set (reg:CC 17)
15285 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15286 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15287 (use (match_operand:DI 6 "register_operand" "2"))
15288 (use (match_operand:SI 3 "immediate_operand" "i"))
15289 (use (reg:SI 19))
15290 (clobber (match_operand:DI 0 "register_operand" "=S"))
15291 (clobber (match_operand:DI 1 "register_operand" "=D"))
15292 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15293 "TARGET_64BIT"
7c7ef435 15294 "repz{\;| }cmpsb"
e2e52e1b 15295 [(set_attr "type" "str")
6ef67412
JH
15296 (set_attr "mode" "QI")
15297 (set_attr "prefix_rep" "1")])
886c62d1 15298
e075ae69 15299;; The same, but the count is not known to not be zero.
886c62d1 15300
0945b39d 15301(define_insn "cmpstrqi_1"
e075ae69 15302 [(set (reg:CC 17)
b1cdafbb 15303 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 15304 (const_int 0))
2bed3391 15305 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 15306 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
15307 (const_int 0)))
15308 (use (match_operand:SI 3 "immediate_operand" "i"))
e2e52e1b 15309 (use (reg:CC 17))
7c7ef435 15310 (use (reg:SI 19))
b1cdafbb
JH
15311 (clobber (match_operand:SI 0 "register_operand" "=S"))
15312 (clobber (match_operand:SI 1 "register_operand" "=D"))
15313 (clobber (match_operand:SI 2 "register_operand" "=c"))]
0945b39d
JH
15314 "!TARGET_64BIT"
15315 "repz{\;| }cmpsb"
15316 [(set_attr "type" "str")
15317 (set_attr "mode" "QI")
15318 (set_attr "prefix_rep" "1")])
15319
15320(define_insn "cmpstrqi_rex_1"
15321 [(set (reg:CC 17)
15322 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15323 (const_int 0))
15324 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15325 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15326 (const_int 0)))
15327 (use (match_operand:SI 3 "immediate_operand" "i"))
15328 (use (reg:CC 17))
15329 (use (reg:SI 19))
15330 (clobber (match_operand:DI 0 "register_operand" "=S"))
15331 (clobber (match_operand:DI 1 "register_operand" "=D"))
15332 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15333 "TARGET_64BIT"
e2e52e1b
JH
15334 "repz{\;| }cmpsb"
15335 [(set_attr "type" "str")
6ef67412
JH
15336 (set_attr "mode" "QI")
15337 (set_attr "prefix_rep" "1")])
886c62d1 15338
e075ae69
RH
15339(define_expand "strlensi"
15340 [(set (match_operand:SI 0 "register_operand" "")
15341 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15342 (match_operand:QI 2 "immediate_operand" "")
0945b39d 15343 (match_operand 3 "immediate_operand" "")] 0))]
886c62d1 15344 ""
886c62d1 15345{
0945b39d
JH
15346 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15347 DONE;
15348 else
15349 FAIL;
0f40f9f7 15350})
e075ae69 15351
0945b39d
JH
15352(define_expand "strlendi"
15353 [(set (match_operand:DI 0 "register_operand" "")
15354 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15355 (match_operand:QI 2 "immediate_operand" "")
15356 (match_operand 3 "immediate_operand" "")] 0))]
15357 ""
0945b39d
JH
15358{
15359 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15360 DONE;
15361 else
15362 FAIL;
0f40f9f7 15363})
19c3fc24 15364
0945b39d 15365(define_insn "strlenqi_1"
e075ae69 15366 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 15367 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
0945b39d 15368 (match_operand:QI 2 "register_operand" "a")
e075ae69 15369 (match_operand:SI 3 "immediate_operand" "i")
0945b39d 15370 (match_operand:SI 4 "register_operand" "0")] 0))
7c7ef435 15371 (use (reg:SI 19))
b1cdafbb 15372 (clobber (match_operand:SI 1 "register_operand" "=D"))
e075ae69 15373 (clobber (reg:CC 17))]
0945b39d
JH
15374 "!TARGET_64BIT"
15375 "repnz{\;| }scasb"
15376 [(set_attr "type" "str")
15377 (set_attr "mode" "QI")
15378 (set_attr "prefix_rep" "1")])
15379
15380(define_insn "strlenqi_rex_1"
15381 [(set (match_operand:DI 0 "register_operand" "=&c")
15382 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15383 (match_operand:QI 2 "register_operand" "a")
15384 (match_operand:DI 3 "immediate_operand" "i")
15385 (match_operand:DI 4 "register_operand" "0")] 0))
15386 (use (reg:SI 19))
15387 (clobber (match_operand:DI 1 "register_operand" "=D"))
15388 (clobber (reg:CC 17))]
15389 "TARGET_64BIT"
7c7ef435 15390 "repnz{\;| }scasb"
e2e52e1b 15391 [(set_attr "type" "str")
6ef67412
JH
15392 (set_attr "mode" "QI")
15393 (set_attr "prefix_rep" "1")])
a3e991f2
ZW
15394
15395;; Peephole optimizations to clean up after cmpstr*. This should be
15396;; handled in combine, but it is not currently up to the task.
15397;; When used for their truth value, the cmpstr* expanders generate
15398;; code like this:
15399;;
15400;; repz cmpsb
15401;; seta %al
15402;; setb %dl
15403;; cmpb %al, %dl
15404;; jcc label
15405;;
15406;; The intermediate three instructions are unnecessary.
15407
15408;; This one handles cmpstr*_nz_1...
15409(define_peephole2
15410 [(parallel[
15411 (set (reg:CC 17)
15412 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15413 (mem:BLK (match_operand 5 "register_operand" ""))))
15414 (use (match_operand 6 "register_operand" ""))
15415 (use (match_operand:SI 3 "immediate_operand" ""))
15416 (use (reg:SI 19))
15417 (clobber (match_operand 0 "register_operand" ""))
15418 (clobber (match_operand 1 "register_operand" ""))
15419 (clobber (match_operand 2 "register_operand" ""))])
15420 (set (match_operand:QI 7 "register_operand" "")
15421 (gtu:QI (reg:CC 17) (const_int 0)))
15422 (set (match_operand:QI 8 "register_operand" "")
15423 (ltu:QI (reg:CC 17) (const_int 0)))
15424 (set (reg 17)
15425 (compare (match_dup 7) (match_dup 8)))
15426 ]
244ec848 15427 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2
ZW
15428 [(parallel[
15429 (set (reg:CC 17)
15430 (compare:CC (mem:BLK (match_dup 4))
15431 (mem:BLK (match_dup 5))))
15432 (use (match_dup 6))
15433 (use (match_dup 3))
15434 (use (reg:SI 19))
15435 (clobber (match_dup 0))
15436 (clobber (match_dup 1))
244ec848 15437 (clobber (match_dup 2))])]
a3e991f2
ZW
15438 "")
15439
15440;; ...and this one handles cmpstr*_1.
15441(define_peephole2
15442 [(parallel[
15443 (set (reg:CC 17)
15444 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15445 (const_int 0))
15446 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15447 (mem:BLK (match_operand 5 "register_operand" "")))
15448 (const_int 0)))
15449 (use (match_operand:SI 3 "immediate_operand" ""))
15450 (use (reg:CC 17))
15451 (use (reg:SI 19))
15452 (clobber (match_operand 0 "register_operand" ""))
15453 (clobber (match_operand 1 "register_operand" ""))
15454 (clobber (match_operand 2 "register_operand" ""))])
15455 (set (match_operand:QI 7 "register_operand" "")
15456 (gtu:QI (reg:CC 17) (const_int 0)))
15457 (set (match_operand:QI 8 "register_operand" "")
15458 (ltu:QI (reg:CC 17) (const_int 0)))
15459 (set (reg 17)
15460 (compare (match_dup 7) (match_dup 8)))
15461 ]
244ec848 15462 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
a3e991f2
ZW
15463 [(parallel[
15464 (set (reg:CC 17)
15465 (if_then_else:CC (ne (match_dup 6)
15466 (const_int 0))
15467 (compare:CC (mem:BLK (match_dup 4))
15468 (mem:BLK (match_dup 5)))
15469 (const_int 0)))
15470 (use (match_dup 3))
15471 (use (reg:CC 17))
15472 (use (reg:SI 19))
15473 (clobber (match_dup 0))
15474 (clobber (match_dup 1))
244ec848 15475 (clobber (match_dup 2))])]
a3e991f2
ZW
15476 "")
15477
15478
e075ae69
RH
15479\f
15480;; Conditional move instructions.
726e2d54 15481
885a70fd
JH
15482(define_expand "movdicc_rex64"
15483 [(set (match_operand:DI 0 "register_operand" "")
15484 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15485 (match_operand:DI 2 "x86_64_general_operand" "")
15486 (match_operand:DI 3 "x86_64_general_operand" "")))]
15487 "TARGET_64BIT"
15488 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15489
e74061a9 15490(define_insn "x86_movdicc_0_m1_rex64"
885a70fd
JH
15491 [(set (match_operand:DI 0 "register_operand" "=r")
15492 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15493 (const_int -1)
15494 (const_int 0)))
15495 (clobber (reg:CC 17))]
15496 "TARGET_64BIT"
0f40f9f7 15497 "sbb{q}\t%0, %0"
885a70fd
JH
15498 ; Since we don't have the proper number of operands for an alu insn,
15499 ; fill in all the blanks.
15500 [(set_attr "type" "alu")
15501 (set_attr "memory" "none")
15502 (set_attr "imm_disp" "false")
15503 (set_attr "mode" "DI")
15504 (set_attr "length_immediate" "0")])
15505
15506(define_insn "*movdicc_c_rex64"
15507 [(set (match_operand:DI 0 "register_operand" "=r,r")
15508 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15509 [(reg 17) (const_int 0)])
15510 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15511 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15512 "TARGET_64BIT && TARGET_CMOVE
15513 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15514 "@
0f40f9f7
ZW
15515 cmov%C1\t{%2, %0|%0, %2}
15516 cmov%c1\t{%3, %0|%0, %3}"
885a70fd
JH
15517 [(set_attr "type" "icmov")
15518 (set_attr "mode" "DI")])
15519
e075ae69 15520(define_expand "movsicc"
6a4a5d95 15521 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
15522 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15523 (match_operand:SI 2 "general_operand" "")
15524 (match_operand:SI 3 "general_operand" "")))]
15525 ""
15526 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 15527
e075ae69
RH
15528;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15529;; the register first winds up with `sbbl $0,reg', which is also weird.
15530;; So just document what we're doing explicitly.
15531
15532(define_insn "x86_movsicc_0_m1"
15533 [(set (match_operand:SI 0 "register_operand" "=r")
15534 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15535 (const_int -1)
15536 (const_int 0)))
15537 (clobber (reg:CC 17))]
15538 ""
0f40f9f7 15539 "sbb{l}\t%0, %0"
e075ae69
RH
15540 ; Since we don't have the proper number of operands for an alu insn,
15541 ; fill in all the blanks.
15542 [(set_attr "type" "alu")
15543 (set_attr "memory" "none")
15544 (set_attr "imm_disp" "false")
6ef67412
JH
15545 (set_attr "mode" "SI")
15546 (set_attr "length_immediate" "0")])
e075ae69 15547
6343a50e 15548(define_insn "*movsicc_noc"
e075ae69 15549 [(set (match_operand:SI 0 "register_operand" "=r,r")
9076b9c1 15550 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
15551 [(reg 17) (const_int 0)])
15552 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15553 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
15554 "TARGET_CMOVE
15555 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 15556 "@
0f40f9f7
ZW
15557 cmov%C1\t{%2, %0|%0, %2}
15558 cmov%c1\t{%3, %0|%0, %3}"
6ef67412
JH
15559 [(set_attr "type" "icmov")
15560 (set_attr "mode" "SI")])
726e2d54 15561
726e2d54
JW
15562(define_expand "movhicc"
15563 [(set (match_operand:HI 0 "register_operand" "")
15564 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15565 (match_operand:HI 2 "nonimmediate_operand" "")
15566 (match_operand:HI 3 "nonimmediate_operand" "")))]
d9f32422 15567 "TARGET_CMOVE && TARGET_HIMODE_MATH"
e075ae69 15568 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 15569
6343a50e 15570(define_insn "*movhicc_noc"
e075ae69 15571 [(set (match_operand:HI 0 "register_operand" "=r,r")
9076b9c1 15572 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
15573 [(reg 17) (const_int 0)])
15574 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15575 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
15576 "TARGET_CMOVE
15577 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 15578 "@
0f40f9f7
ZW
15579 cmov%C1\t{%2, %0|%0, %2}
15580 cmov%c1\t{%3, %0|%0, %3}"
6ef67412
JH
15581 [(set_attr "type" "icmov")
15582 (set_attr "mode" "HI")])
726e2d54 15583
56710e42 15584(define_expand "movsfcc"
726e2d54 15585 [(set (match_operand:SF 0 "register_operand" "")
56710e42 15586 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
15587 (match_operand:SF 2 "register_operand" "")
15588 (match_operand:SF 3 "register_operand" "")))]
726e2d54 15589 "TARGET_CMOVE"
e075ae69 15590 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 15591
6343a50e 15592(define_insn "*movsfcc_1"
7093c9ea 15593 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
e075ae69
RH
15594 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15595 [(reg 17) (const_int 0)])
7093c9ea
JH
15596 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15597 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15598 "TARGET_CMOVE
15599 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 15600 "@
0f40f9f7
ZW
15601 fcmov%F1\t{%2, %0|%0, %2}
15602 fcmov%f1\t{%3, %0|%0, %3}
15603 cmov%C1\t{%2, %0|%0, %2}
15604 cmov%c1\t{%3, %0|%0, %3}"
7093c9ea
JH
15605 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15606 (set_attr "mode" "SF,SF,SI,SI")])
56710e42
SC
15607
15608(define_expand "movdfcc"
726e2d54 15609 [(set (match_operand:DF 0 "register_operand" "")
56710e42 15610 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
15611 (match_operand:DF 2 "register_operand" "")
15612 (match_operand:DF 3 "register_operand" "")))]
726e2d54 15613 "TARGET_CMOVE"
e075ae69 15614 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 15615
6343a50e 15616(define_insn "*movdfcc_1"
7093c9ea 15617 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
e075ae69
RH
15618 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15619 [(reg 17) (const_int 0)])
7093c9ea
JH
15620 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15621 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1b0c37d7 15622 "!TARGET_64BIT && TARGET_CMOVE
7093c9ea 15623 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69 15624 "@
0f40f9f7
ZW
15625 fcmov%F1\t{%2, %0|%0, %2}
15626 fcmov%f1\t{%3, %0|%0, %3}
7093c9ea
JH
15627 #
15628 #"
15629 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 15630 (set_attr "mode" "DF")])
56710e42 15631
1e07edd3
JH
15632(define_insn "*movdfcc_1_rex64"
15633 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15634 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15635 [(reg 17) (const_int 0)])
15636 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15637 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1b0c37d7 15638 "TARGET_64BIT && TARGET_CMOVE
1e07edd3
JH
15639 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15640 "@
0f40f9f7
ZW
15641 fcmov%F1\t{%2, %0|%0, %2}
15642 fcmov%f1\t{%3, %0|%0, %3}
15643 cmov%C1\t{%2, %0|%0, %2}
15644 cmov%c1\t{%3, %0|%0, %3}"
1e07edd3
JH
15645 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15646 (set_attr "mode" "DF")])
15647
7093c9ea
JH
15648(define_split
15649 [(set (match_operand:DF 0 "register_operand" "")
15650 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15651 [(match_operand 4 "" "") (const_int 0)])
15652 (match_operand:DF 2 "nonimmediate_operand" "")
15653 (match_operand:DF 3 "nonimmediate_operand" "")))]
1b0c37d7 15654 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
7093c9ea
JH
15655 [(set (match_dup 2)
15656 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15657 (match_dup 5)
15658 (match_dup 7)))
15659 (set (match_dup 3)
15660 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15661 (match_dup 6)
15662 (match_dup 8)))]
15663 "split_di (operands+2, 1, operands+5, operands+6);
15664 split_di (operands+3, 1, operands+7, operands+8);
15665 split_di (operands, 1, operands+2, operands+3);")
15666
56710e42 15667(define_expand "movxfcc"
726e2d54 15668 [(set (match_operand:XF 0 "register_operand" "")
56710e42 15669 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
15670 (match_operand:XF 2 "register_operand" "")
15671 (match_operand:XF 3 "register_operand" "")))]
1b0c37d7 15672 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69 15673 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 15674
2b589241
JH
15675(define_expand "movtfcc"
15676 [(set (match_operand:TF 0 "register_operand" "")
15677 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15678 (match_operand:TF 2 "register_operand" "")
15679 (match_operand:TF 3 "register_operand" "")))]
15680 "TARGET_CMOVE"
15681 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15682
6343a50e 15683(define_insn "*movxfcc_1"
3aeae608 15684 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69
RH
15685 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15686 [(reg 17) (const_int 0)])
3aeae608
JW
15687 (match_operand:XF 2 "register_operand" "f,0")
15688 (match_operand:XF 3 "register_operand" "0,f")))]
1b0c37d7 15689 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69 15690 "@
0f40f9f7
ZW
15691 fcmov%F1\t{%2, %0|%0, %2}
15692 fcmov%f1\t{%3, %0|%0, %3}"
6ef67412
JH
15693 [(set_attr "type" "fcmov")
15694 (set_attr "mode" "XF")])
2b589241
JH
15695
15696(define_insn "*movtfcc_1"
15697 [(set (match_operand:TF 0 "register_operand" "=f,f")
15698 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15699 [(reg 17) (const_int 0)])
15700 (match_operand:TF 2 "register_operand" "f,0")
15701 (match_operand:TF 3 "register_operand" "0,f")))]
15702 "TARGET_CMOVE"
15703 "@
0f40f9f7
ZW
15704 fcmov%F1\t{%2, %0|%0, %2}
15705 fcmov%f1\t{%3, %0|%0, %3}"
2b589241
JH
15706 [(set_attr "type" "fcmov")
15707 (set_attr "mode" "XF")])
7ada6625
JH
15708
15709(define_expand "minsf3"
15710 [(parallel [
15711 (set (match_operand:SF 0 "register_operand" "")
15712 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15713 (match_operand:SF 2 "nonimmediate_operand" ""))
15714 (match_dup 1)
15715 (match_dup 2)))
15716 (clobber (reg:CC 17))])]
15717 "TARGET_SSE"
15718 "")
15719
15720(define_insn "*minsf"
15721 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15722 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15723 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15724 (match_dup 1)
15725 (match_dup 2)))
15726 (clobber (reg:CC 17))]
15727 "TARGET_SSE && TARGET_IEEE_FP"
15728 "#")
15729
15730(define_insn "*minsf_nonieee"
15731 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15732 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
15733 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15734 (match_dup 1)
15735 (match_dup 2)))
15736 (clobber (reg:CC 17))]
15737 "TARGET_SSE && !TARGET_IEEE_FP"
15738 "#")
15739
15740(define_split
15741 [(set (match_operand:SF 0 "register_operand" "")
15742 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15743 (match_operand:SF 2 "nonimmediate_operand" ""))
138b7342
JH
15744 (match_operand:SF 3 "register_operand" "")
15745 (match_operand:SF 4 "nonimmediate_operand" "")))
ef6257cd
JH
15746 (clobber (reg:CC 17))]
15747 "SSE_REG_P (operands[0]) && reload_completed
15748 && ((operands_match_p (operands[1], operands[3])
15749 && operands_match_p (operands[2], operands[4]))
15750 || (operands_match_p (operands[1], operands[4])
15751 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15752 [(set (match_dup 0)
15753 (if_then_else:SF (lt (match_dup 1)
15754 (match_dup 2))
15755 (match_dup 1)
15756 (match_dup 2)))])
15757
15758;; We can't represent the LT test directly. Do this by swapping the operands.
ef6257cd 15759
7ada6625
JH
15760(define_split
15761 [(set (match_operand:SF 0 "register_operand" "")
15762 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15763 (match_operand:SF 2 "register_operand" ""))
ef6257cd
JH
15764 (match_operand:DF 3 "register_operand" "")
15765 (match_operand:DF 4 "register_operand" "")))
15766 (clobber (reg:CC 17))]
15767 "FP_REG_P (operands[0]) && reload_completed
15768 && ((operands_match_p (operands[1], operands[3])
15769 && operands_match_p (operands[2], operands[4]))
15770 || (operands_match_p (operands[1], operands[4])
15771 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15772 [(set (reg:CCFP 17)
15773 (compare:CCFP (match_dup 2)
15774 (match_dup 1)))
15775 (set (match_dup 0)
15776 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
15777 (match_dup 1)
15778 (match_dup 2)))])
15779
15780(define_insn "*minsf_sse"
15781 [(set (match_operand:SF 0 "register_operand" "=x")
15782 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
15783 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15784 (match_dup 1)
15785 (match_dup 2)))]
15786 "TARGET_SSE && reload_completed"
0f40f9f7 15787 "minss\t{%2, %0|%0, %2}"
7ada6625
JH
15788 [(set_attr "type" "sse")
15789 (set_attr "mode" "SF")])
15790
15791(define_expand "mindf3"
15792 [(parallel [
15793 (set (match_operand:DF 0 "register_operand" "")
15794 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15795 (match_operand:DF 2 "nonimmediate_operand" ""))
15796 (match_dup 1)
15797 (match_dup 2)))
15798 (clobber (reg:CC 17))])]
15799 "TARGET_SSE2"
15800 "#")
15801
15802(define_insn "*mindf"
15803 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15804 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15805 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15806 (match_dup 1)
15807 (match_dup 2)))
15808 (clobber (reg:CC 17))]
15809 "TARGET_SSE2 && TARGET_IEEE_FP"
15810 "#")
15811
15812(define_insn "*mindf_nonieee"
15813 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15814 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
15815 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15816 (match_dup 1)
15817 (match_dup 2)))
15818 (clobber (reg:CC 17))]
15819 "TARGET_SSE2 && !TARGET_IEEE_FP"
15820 "#")
15821
15822(define_split
15823 [(set (match_operand:DF 0 "register_operand" "")
15824 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15825 (match_operand:DF 2 "nonimmediate_operand" ""))
ef6257cd
JH
15826 (match_operand:DF 3 "register_operand" "")
15827 (match_operand:DF 4 "nonimmediate_operand" "")))
15828 (clobber (reg:CC 17))]
15829 "SSE_REG_P (operands[0]) && reload_completed
15830 && ((operands_match_p (operands[1], operands[3])
15831 && operands_match_p (operands[2], operands[4]))
15832 || (operands_match_p (operands[1], operands[4])
15833 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15834 [(set (match_dup 0)
15835 (if_then_else:DF (lt (match_dup 1)
15836 (match_dup 2))
15837 (match_dup 1)
15838 (match_dup 2)))])
15839
15840;; We can't represent the LT test directly. Do this by swapping the operands.
15841(define_split
15842 [(set (match_operand:DF 0 "register_operand" "")
15843 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15844 (match_operand:DF 2 "register_operand" ""))
ef6257cd
JH
15845 (match_operand:DF 3 "register_operand" "")
15846 (match_operand:DF 4 "register_operand" "")))
15847 (clobber (reg:CC 17))]
15848 "FP_REG_P (operands[0]) && reload_completed
15849 && ((operands_match_p (operands[1], operands[3])
15850 && operands_match_p (operands[2], operands[4]))
15851 || (operands_match_p (operands[1], operands[4])
15852 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15853 [(set (reg:CCFP 17)
15854 (compare:CCFP (match_dup 2)
15855 (match_dup 2)))
15856 (set (match_dup 0)
15857 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
15858 (match_dup 1)
15859 (match_dup 2)))])
15860
15861(define_insn "*mindf_sse"
15862 [(set (match_operand:DF 0 "register_operand" "=Y")
15863 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
15864 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15865 (match_dup 1)
15866 (match_dup 2)))]
15867 "TARGET_SSE2 && reload_completed"
0f40f9f7 15868 "minsd\t{%2, %0|%0, %2}"
7ada6625
JH
15869 [(set_attr "type" "sse")
15870 (set_attr "mode" "DF")])
15871
15872(define_expand "maxsf3"
15873 [(parallel [
15874 (set (match_operand:SF 0 "register_operand" "")
15875 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15876 (match_operand:SF 2 "nonimmediate_operand" ""))
15877 (match_dup 1)
15878 (match_dup 2)))
15879 (clobber (reg:CC 17))])]
15880 "TARGET_SSE"
15881 "#")
15882
15883(define_insn "*maxsf"
15884 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15885 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
15886 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
15887 (match_dup 1)
15888 (match_dup 2)))
15889 (clobber (reg:CC 17))]
15890 "TARGET_SSE && TARGET_IEEE_FP"
15891 "#")
15892
15893(define_insn "*maxsf_nonieee"
15894 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15895 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
15896 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15897 (match_dup 1)
15898 (match_dup 2)))
15899 (clobber (reg:CC 17))]
15900 "TARGET_SSE && !TARGET_IEEE_FP"
15901 "#")
15902
15903(define_split
15904 [(set (match_operand:SF 0 "register_operand" "")
15905 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15906 (match_operand:SF 2 "nonimmediate_operand" ""))
ef6257cd
JH
15907 (match_operand:SF 3 "register_operand" "")
15908 (match_operand:SF 4 "nonimmediate_operand" "")))
15909 (clobber (reg:CC 17))]
15910 "SSE_REG_P (operands[0]) && reload_completed
15911 && ((operands_match_p (operands[1], operands[3])
15912 && operands_match_p (operands[2], operands[4]))
15913 || (operands_match_p (operands[1], operands[4])
15914 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15915 [(set (match_dup 0)
15916 (if_then_else:SF (gt (match_dup 1)
15917 (match_dup 2))
15918 (match_dup 1)
15919 (match_dup 2)))])
15920
15921(define_split
15922 [(set (match_operand:SF 0 "register_operand" "")
15923 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15924 (match_operand:SF 2 "register_operand" ""))
ef6257cd
JH
15925 (match_operand:SF 3 "register_operand" "")
15926 (match_operand:SF 4 "register_operand" "")))
15927 (clobber (reg:CC 17))]
15928 "FP_REG_P (operands[0]) && reload_completed
15929 && ((operands_match_p (operands[1], operands[3])
15930 && operands_match_p (operands[2], operands[4]))
15931 || (operands_match_p (operands[1], operands[4])
15932 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15933 [(set (reg:CCFP 17)
15934 (compare:CCFP (match_dup 1)
15935 (match_dup 2)))
15936 (set (match_dup 0)
15937 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
15938 (match_dup 1)
15939 (match_dup 2)))])
15940
15941(define_insn "*maxsf_sse"
15942 [(set (match_operand:SF 0 "register_operand" "=x")
15943 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
15944 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15945 (match_dup 1)
15946 (match_dup 2)))]
15947 "TARGET_SSE && reload_completed"
0f40f9f7 15948 "maxss\t{%2, %0|%0, %2}"
7ada6625
JH
15949 [(set_attr "type" "sse")
15950 (set_attr "mode" "SF")])
15951
15952(define_expand "maxdf3"
15953 [(parallel [
15954 (set (match_operand:DF 0 "register_operand" "")
15955 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15956 (match_operand:DF 2 "nonimmediate_operand" ""))
15957 (match_dup 1)
15958 (match_dup 2)))
15959 (clobber (reg:CC 17))])]
15960 "TARGET_SSE2"
15961 "#")
15962
15963(define_insn "*maxdf"
15964 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15965 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15966 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
15967 (match_dup 1)
15968 (match_dup 2)))
15969 (clobber (reg:CC 17))]
15970 "TARGET_SSE2 && TARGET_IEEE_FP"
15971 "#")
15972
15973(define_insn "*maxdf_nonieee"
15974 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15975 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
15976 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15977 (match_dup 1)
15978 (match_dup 2)))
15979 (clobber (reg:CC 17))]
15980 "TARGET_SSE2 && !TARGET_IEEE_FP"
15981 "#")
15982
15983(define_split
15984 [(set (match_operand:DF 0 "register_operand" "")
15985 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15986 (match_operand:DF 2 "nonimmediate_operand" ""))
ef6257cd
JH
15987 (match_operand:DF 3 "register_operand" "")
15988 (match_operand:DF 4 "nonimmediate_operand" "")))
15989 (clobber (reg:CC 17))]
15990 "SSE_REG_P (operands[0]) && reload_completed
15991 && ((operands_match_p (operands[1], operands[3])
15992 && operands_match_p (operands[2], operands[4]))
15993 || (operands_match_p (operands[1], operands[4])
15994 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
15995 [(set (match_dup 0)
15996 (if_then_else:DF (gt (match_dup 1)
15997 (match_dup 2))
15998 (match_dup 1)
15999 (match_dup 2)))])
16000
16001(define_split
16002 [(set (match_operand:DF 0 "register_operand" "")
16003 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16004 (match_operand:DF 2 "register_operand" ""))
ef6257cd
JH
16005 (match_operand:DF 3 "register_operand" "")
16006 (match_operand:DF 4 "register_operand" "")))
16007 (clobber (reg:CC 17))]
16008 "FP_REG_P (operands[0]) && reload_completed
16009 && ((operands_match_p (operands[1], operands[3])
16010 && operands_match_p (operands[2], operands[4]))
16011 || (operands_match_p (operands[1], operands[4])
16012 && operands_match_p (operands[2], operands[3])))"
7ada6625
JH
16013 [(set (reg:CCFP 17)
16014 (compare:CCFP (match_dup 1)
16015 (match_dup 2)))
16016 (set (match_dup 0)
16017 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16018 (match_dup 1)
16019 (match_dup 2)))])
16020
16021(define_insn "*maxdf_sse"
16022 [(set (match_operand:DF 0 "register_operand" "=Y")
16023 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16024 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16025 (match_dup 1)
16026 (match_dup 2)))]
16027 "TARGET_SSE2 && reload_completed"
0f40f9f7 16028 "maxsd\t{%2, %0|%0, %2}"
7ada6625
JH
16029 [(set_attr "type" "sse")
16030 (set_attr "mode" "DF")])
e075ae69
RH
16031\f
16032;; Misc patterns (?)
726e2d54 16033
e075ae69
RH
16034;; This pattern exists to put a dependancy on all ebp-based memory accesses.
16035;; Otherwise there will be nothing to keep
16036;;
16037;; [(set (reg ebp) (reg esp))]
16038;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16039;; (clobber (eflags)]
16040;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16041;;
16042;; in proper program order.
8362f420
JH
16043(define_expand "pro_epilogue_adjust_stack"
16044 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16045 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16046 (match_operand:SI 2 "immediate_operand" "i,i")))
f2042df3
RH
16047 (clobber (reg:CC 17))
16048 (clobber (mem:BLK (scratch)))])]
8362f420 16049 ""
8362f420
JH
16050{
16051 if (TARGET_64BIT)
16052 {
f2042df3
RH
16053 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16054 (operands[0], operands[1], operands[2]));
8362f420
JH
16055 DONE;
16056 }
0f40f9f7 16057})
726e2d54 16058
8362f420 16059(define_insn "*pro_epilogue_adjust_stack_1"
1c71e60e
JH
16060 [(set (match_operand:SI 0 "register_operand" "=r,r")
16061 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16062 (match_operand:SI 2 "immediate_operand" "i,i")))
f2042df3
RH
16063 (clobber (reg:CC 17))
16064 (clobber (mem:BLK (scratch)))]
8362f420 16065 "!TARGET_64BIT"
e075ae69 16066{
1c71e60e 16067 switch (get_attr_type (insn))
e075ae69 16068 {
1c71e60e 16069 case TYPE_IMOV:
0f40f9f7 16070 return "mov{l}\t{%1, %0|%0, %1}";
1c71e60e
JH
16071
16072 case TYPE_ALU:
16073 if (GET_CODE (operands[2]) == CONST_INT
16074 && (INTVAL (operands[2]) == 128
16075 || (INTVAL (operands[2]) < 0
16076 && INTVAL (operands[2]) != -128)))
16077 {
16078 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 16079 return "sub{l}\t{%2, %0|%0, %2}";
1c71e60e 16080 }
0f40f9f7 16081 return "add{l}\t{%2, %0|%0, %2}";
1c71e60e
JH
16082
16083 case TYPE_LEA:
16084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 16085 return "lea{l}\t{%a2, %0|%0, %a2}";
1c71e60e
JH
16086
16087 default:
16088 abort ();
e075ae69 16089 }
0f40f9f7 16090}
1c71e60e
JH
16091 [(set (attr "type")
16092 (cond [(eq_attr "alternative" "0")
16093 (const_string "alu")
16094 (match_operand:SI 2 "const0_operand" "")
16095 (const_string "imov")
16096 ]
6ef67412
JH
16097 (const_string "lea")))
16098 (set_attr "mode" "SI")])
578b58f5 16099
8362f420
JH
16100(define_insn "pro_epilogue_adjust_stack_rex64"
16101 [(set (match_operand:DI 0 "register_operand" "=r,r")
16102 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16103 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
f2042df3
RH
16104 (clobber (reg:CC 17))
16105 (clobber (mem:BLK (scratch)))]
8362f420 16106 "TARGET_64BIT"
8362f420
JH
16107{
16108 switch (get_attr_type (insn))
16109 {
16110 case TYPE_IMOV:
0f40f9f7 16111 return "mov{q}\t{%1, %0|%0, %1}";
8362f420
JH
16112
16113 case TYPE_ALU:
16114 if (GET_CODE (operands[2]) == CONST_INT
16115 && (INTVAL (operands[2]) == 128
16116 || (INTVAL (operands[2]) < 0
16117 && INTVAL (operands[2]) != -128)))
16118 {
16119 operands[2] = GEN_INT (-INTVAL (operands[2]));
0f40f9f7 16120 return "sub{q}\t{%2, %0|%0, %2}";
8362f420 16121 }
0f40f9f7 16122 return "add{q}\t{%2, %0|%0, %2}";
8362f420
JH
16123
16124 case TYPE_LEA:
16125 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
0f40f9f7 16126 return "lea{q}\t{%a2, %0|%0, %a2}";
8362f420
JH
16127
16128 default:
16129 abort ();
16130 }
0f40f9f7 16131}
8362f420
JH
16132 [(set (attr "type")
16133 (cond [(eq_attr "alternative" "0")
16134 (const_string "alu")
16135 (match_operand:DI 2 "const0_operand" "")
16136 (const_string "imov")
16137 ]
16138 (const_string "lea")))
16139 (set_attr "mode" "DI")])
16140
16141
0073023d
JH
16142;; Placeholder for the conditional moves. This one is split eighter to SSE
16143;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16144;; fact is that compares supported by the cmp??ss instructions are exactly
16145;; swapped of those supported by cmove sequence.
fa9f36a1
JH
16146;; The EQ/NE comparisons also needs bit care, since they are not directly
16147;; supported by i387 comparisons and we do need to emit two conditional moves
16148;; in tandem.
0073023d
JH
16149
16150(define_insn "sse_movsfcc"
16151 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16152 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16153 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16154 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16155 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16156 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
bf71a4f8 16157 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
0073023d 16158 (clobber (reg:CC 17))]
fa9f36a1
JH
16159 "TARGET_SSE
16160 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16161 && (!TARGET_IEEE_FP
16162 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16163 "#")
16164
16165(define_insn "sse_movsfcc_eq"
16166 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16167 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16168 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16169 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16170 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
f021d6fc 16171 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
fa9f36a1 16172 (clobber (reg:CC 17))]
0073023d
JH
16173 "TARGET_SSE
16174 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16175 "#")
16176
16177(define_insn "sse_movdfcc"
16178 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16179 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16180 [(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16181 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16182 (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16183 (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
bf71a4f8 16184 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
0073023d
JH
16185 (clobber (reg:CC 17))]
16186 "TARGET_SSE2
fa9f36a1
JH
16187 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16188 && (!TARGET_IEEE_FP
16189 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16190 "#")
16191
16192(define_insn "sse_movdfcc_eq"
16193 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16194 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16195 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16196 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16197 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16198 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16199 (clobber (reg:CC 17))]
16200 "TARGET_SSE
0073023d
JH
16201 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16202 "#")
16203
16204;; For non-sse moves just expand the usual cmove sequence.
16205(define_split
16206 [(set (match_operand 0 "register_operand" "")
16207 (if_then_else (match_operator 1 "comparison_operator"
16208 [(match_operand 4 "nonimmediate_operand" "")
16209 (match_operand 5 "register_operand" "")])
16210 (match_operand 2 "nonimmediate_operand" "")
16211 (match_operand 3 "nonimmediate_operand" "")))
16212 (clobber (match_operand 6 "" ""))
16213 (clobber (reg:CC 17))]
16214 "!SSE_REG_P (operands[0]) && reload_completed
16215 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16216 [(const_int 0)]
0073023d
JH
16217{
16218 ix86_compare_op0 = operands[5];
16219 ix86_compare_op1 = operands[4];
16220 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16221 VOIDmode, operands[5], operands[4]);
16222 ix86_expand_fp_movcc (operands);
16223 DONE;
0f40f9f7 16224})
0073023d
JH
16225
16226;; Split SSE based conditional move into seqence:
16227;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16228;; and op2, op0 - zero op2 if comparison was false
16229;; nand op0, op3 - load op3 to op0 if comparison was false
16230;; or op2, op0 - get the non-zero one into the result.
16231(define_split
16232 [(set (match_operand 0 "register_operand" "")
16233 (if_then_else (match_operator 1 "sse_comparison_operator"
16234 [(match_operand 4 "register_operand" "")
16235 (match_operand 5 "nonimmediate_operand" "")])
16236 (match_operand 2 "register_operand" "")
16237 (match_operand 3 "register_operand" "")))
bf71a4f8 16238 (clobber (match_operand 6 "" ""))
0073023d
JH
16239 (clobber (reg:CC 17))]
16240 "SSE_REG_P (operands[0]) && reload_completed"
16241 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16242 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
f021d6fc
JH
16243 (subreg:TI (match_dup 4) 0)))
16244 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
0073023d
JH
16245 (subreg:TI (match_dup 3) 0)))
16246 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16247 (subreg:TI (match_dup 7) 0)))]
0073023d
JH
16248{
16249 PUT_MODE (operands[1], GET_MODE (operands[0]));
f021d6fc 16250 if (operands_match_p (operands[0], operands[4]))
0073023d
JH
16251 operands[6] = operands[4], operands[7] = operands[2];
16252 else
f021d6fc 16253 operands[6] = operands[2], operands[7] = operands[4];
0f40f9f7 16254})
0073023d
JH
16255
16256;; Special case of conditional move we can handle effectivly.
16257;; Do not brother with the integer/floating point case, since these are
16258;; bot considerably slower, unlike in the generic case.
16259(define_insn "*sse_movsfcc_const0_1"
16260 [(set (match_operand:SF 0 "register_operand" "=x")
16261 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16262 [(match_operand:SF 4 "register_operand" "0")
16263 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16264 (match_operand:SF 2 "register_operand" "x")
16265 (match_operand:SF 3 "const0_operand" "X")))]
16266 "TARGET_SSE"
16267 "#")
16268
16269(define_insn "*sse_movsfcc_const0_2"
16270 [(set (match_operand:SF 0 "register_operand" "=x")
16271 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16272 [(match_operand:SF 4 "register_operand" "0")
16273 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16274 (match_operand:SF 2 "const0_operand" "x")
16275 (match_operand:SF 3 "register_operand" "X")))]
16276 "TARGET_SSE"
16277 "#")
16278
16279(define_insn "*sse_movsfcc_const0_3"
16280 [(set (match_operand:SF 0 "register_operand" "=x")
16281 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16282 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16283 (match_operand:SF 5 "register_operand" "0")])
16284 (match_operand:SF 2 "register_operand" "x")
16285 (match_operand:SF 3 "const0_operand" "X")))]
16286 "TARGET_SSE"
16287 "#")
16288
16289(define_insn "*sse_movsfcc_const0_4"
16290 [(set (match_operand:SF 0 "register_operand" "=x")
16291 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16292 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16293 (match_operand:SF 5 "register_operand" "0")])
16294 (match_operand:SF 2 "const0_operand" "x")
16295 (match_operand:SF 3 "register_operand" "X")))]
16296 "TARGET_SSE"
16297 "#")
16298
16299(define_insn "*sse_movdfcc_const0_1"
16300 [(set (match_operand:SF 0 "register_operand" "=x")
16301 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16302 [(match_operand:SF 4 "register_operand" "0")
16303 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16304 (match_operand:SF 2 "register_operand" "x")
16305 (match_operand:SF 3 "const0_operand" "X")))]
16306 "TARGET_SSE2"
16307 "#")
16308
16309(define_insn "*sse_movdfcc_const0_2"
16310 [(set (match_operand:SF 0 "register_operand" "=x")
16311 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16312 [(match_operand:SF 4 "register_operand" "0")
16313 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16314 (match_operand:SF 2 "const0_operand" "x")
16315 (match_operand:SF 3 "register_operand" "X")))]
16316 "TARGET_SSE2"
16317 "#")
16318
16319(define_insn "*sse_movdfcc_const0_3"
16320 [(set (match_operand:SF 0 "register_operand" "=x")
16321 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16322 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16323 (match_operand:SF 5 "register_operand" "0")])
16324 (match_operand:SF 2 "register_operand" "x")
16325 (match_operand:SF 3 "const0_operand" "X")))]
16326 "TARGET_SSE2"
16327 "#")
16328
16329(define_insn "*sse_movdfcc_const0_4"
16330 [(set (match_operand:SF 0 "register_operand" "=x")
16331 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16332 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16333 (match_operand:SF 5 "register_operand" "0")])
16334 (match_operand:SF 2 "const0_operand" "x")
16335 (match_operand:SF 3 "register_operand" "X")))]
16336 "TARGET_SSE2"
16337 "#")
16338
16339(define_split
16340 [(set (match_operand 0 "register_operand" "")
16341 (if_then_else (match_operator 1 "comparison_operator"
16342 [(match_operand 4 "register_operand" "")
16343 (match_operand 5 "nonimmediate_operand" "")])
16344 (match_operand 2 "nonmemory_operand" "")
16345 (match_operand 3 "nonmemory_operand" "")))]
16346 "SSE_REG_P (operands[0]) && reload_completed
16347 && (const0_operand (operands[2], GET_MODE (operands[0]))
16348 || const0_operand (operands[3], GET_MODE (operands[0])))"
16349 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16350 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16351 (subreg:TI (match_dup 7) 0)))]
0073023d
JH
16352{
16353 PUT_MODE (operands[1], GET_MODE (operands[0]));
16354 if (!sse_comparison_operator (operands[1], VOIDmode))
16355 {
16356 rtx tmp = operands[5];
16357 operands[5] = operands[4];
16358 operands[4] = tmp;
16359 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16360 }
16361 if (const0_operand (operands[2], GET_MODE (operands[0])))
16362 {
16363 operands[7] = operands[3];
16364 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16365 0));
16366 }
16367 else
16368 {
16369 operands[7] = operands[2];
16370 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16371 }
0f40f9f7 16372})
0073023d 16373
885a70fd
JH
16374(define_expand "allocate_stack_worker"
16375 [(match_operand:SI 0 "register_operand" "")]
16376 "TARGET_STACK_PROBE"
885a70fd
JH
16377{
16378 if (TARGET_64BIT)
16379 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16380 else
16381 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16382 DONE;
0f40f9f7 16383})
885a70fd
JH
16384
16385(define_insn "allocate_stack_worker_1"
578b58f5
RK
16386 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16387 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
e075ae69
RH
16388 (clobber (match_dup 0))
16389 (clobber (reg:CC 17))]
1b0c37d7 16390 "!TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 16391 "call\t__alloca"
885a70fd
JH
16392 [(set_attr "type" "multi")
16393 (set_attr "length" "5")])
16394
16395(define_insn "allocate_stack_worker_rex64"
16396 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16397 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16398 (clobber (match_dup 0))
16399 (clobber (reg:CC 17))]
1b0c37d7 16400 "TARGET_64BIT && TARGET_STACK_PROBE"
0f40f9f7 16401 "call\t__alloca"
e075ae69
RH
16402 [(set_attr "type" "multi")
16403 (set_attr "length" "5")])
578b58f5
RK
16404
16405(define_expand "allocate_stack"
e075ae69
RH
16406 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16407 (minus:SI (reg:SI 7)
16408 (match_operand:SI 1 "general_operand" "")))
16409 (clobber (reg:CC 17))])
16410 (parallel [(set (reg:SI 7)
16411 (minus:SI (reg:SI 7) (match_dup 1)))
16412 (clobber (reg:CC 17))])]
16413 "TARGET_STACK_PROBE"
578b58f5
RK
16414{
16415#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
16416 if (GET_CODE (operands[1]) == CONST_INT
16417 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 16418 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 16419 operands[1]));
578b58f5
RK
16420 else
16421#endif
16422 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 16423 operands[1])));
578b58f5 16424
e9a25f70
JL
16425 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16426 DONE;
0f40f9f7 16427})
e31ca113 16428
fb754025
AG
16429(define_expand "builtin_setjmp_receiver"
16430 [(label_ref (match_operand 0 "" ""))]
1b0c37d7 16431 "!TARGET_64BIT && flag_pic"
fb754025
AG
16432{
16433 load_pic_register ();
16434 DONE;
0f40f9f7 16435})
e9e80858
JH
16436\f
16437;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16438
16439(define_split
16440 [(set (match_operand 0 "register_operand" "")
16441 (match_operator 3 "promotable_binary_operator"
16442 [(match_operand 1 "register_operand" "")
2247f6ed 16443 (match_operand 2 "aligned_operand" "")]))
e9e80858
JH
16444 (clobber (reg:CC 17))]
16445 "! TARGET_PARTIAL_REG_STALL && reload_completed
16446 && ((GET_MODE (operands[0]) == HImode
16447 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16448 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16449 || (GET_MODE (operands[0]) == QImode
16450 && (TARGET_PROMOTE_QImode || optimize_size)))"
16451 [(parallel [(set (match_dup 0)
16452 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16453 (clobber (reg:CC 17))])]
16454 "operands[0] = gen_lowpart (SImode, operands[0]);
16455 operands[1] = gen_lowpart (SImode, operands[1]);
16456 if (GET_CODE (operands[3]) != ASHIFT)
16457 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 16458 PUT_MODE (operands[3], SImode);")
e9e80858
JH
16459
16460(define_split
16189740
RH
16461 [(set (reg 17)
16462 (compare (and (match_operand 1 "aligned_operand" "")
16463 (match_operand 2 "const_int_operand" ""))
16464 (const_int 0)))
e9e80858
JH
16465 (set (match_operand 0 "register_operand" "")
16466 (and (match_dup 1) (match_dup 2)))]
16467 "! TARGET_PARTIAL_REG_STALL && reload_completed
16189740 16468 && ix86_match_ccmode (insn, CCNOmode)
e9e80858
JH
16469 && (GET_MODE (operands[0]) == HImode
16470 || (GET_MODE (operands[0]) == QImode
16471 && (TARGET_PROMOTE_QImode || optimize_size)))"
16472 [(parallel [(set (reg:CCNO 17)
16473 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16474 (const_int 0)))
16475 (set (match_dup 0)
16476 (and:SI (match_dup 1) (match_dup 2)))])]
d9f0b960 16477 "operands[2]
383252a7
AO
16478 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16479 & GET_MODE_MASK (GET_MODE (operands[0])),
16480 SImode));
d9f0b960
RH
16481 operands[0] = gen_lowpart (SImode, operands[0]);
16482 operands[1] = gen_lowpart (SImode, operands[1]);")
e9e80858
JH
16483
16484(define_split
16189740
RH
16485 [(set (reg 17)
16486 (compare (and (match_operand 0 "aligned_operand" "")
16487 (match_operand 1 "const_int_operand" ""))
16488 (const_int 0)))]
e9e80858 16489 "! TARGET_PARTIAL_REG_STALL && reload_completed
16189740 16490 && ix86_match_ccmode (insn, CCNOmode)
e9e80858
JH
16491 && (GET_MODE (operands[0]) == HImode
16492 || (GET_MODE (operands[0]) == QImode
16493 && (TARGET_PROMOTE_QImode || optimize_size)))"
16494 [(set (reg:CCNO 17)
16495 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16496 (const_int 0)))]
d9f0b960 16497 "operands[1]
383252a7
AO
16498 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16499 & GET_MODE_MASK (GET_MODE (operands[0])),
16500 SImode));
d9f0b960 16501 operands[0] = gen_lowpart (SImode, operands[0]);")
e9e80858
JH
16502
16503(define_split
16504 [(set (match_operand 0 "register_operand" "")
16505 (neg (match_operand 1 "register_operand" "")))
16506 (clobber (reg:CC 17))]
16507 "! TARGET_PARTIAL_REG_STALL && reload_completed
16508 && (GET_MODE (operands[0]) == HImode
16509 || (GET_MODE (operands[0]) == QImode
16510 && (TARGET_PROMOTE_QImode || optimize_size)))"
16511 [(parallel [(set (match_dup 0)
16512 (neg:SI (match_dup 1)))
16513 (clobber (reg:CC 17))])]
16514 "operands[0] = gen_lowpart (SImode, operands[0]);
16515 operands[1] = gen_lowpart (SImode, operands[1]);")
16516
16517(define_split
16518 [(set (match_operand 0 "register_operand" "")
16519 (not (match_operand 1 "register_operand" "")))]
16520 "! TARGET_PARTIAL_REG_STALL && reload_completed
16521 && (GET_MODE (operands[0]) == HImode
16522 || (GET_MODE (operands[0]) == QImode
16523 && (TARGET_PROMOTE_QImode || optimize_size)))"
16524 [(set (match_dup 0)
16525 (not:SI (match_dup 1)))]
16526 "operands[0] = gen_lowpart (SImode, operands[0]);
16527 operands[1] = gen_lowpart (SImode, operands[1]);")
16528
16529(define_split
16530 [(set (match_operand 0 "register_operand" "")
16531 (if_then_else (match_operator 1 "comparison_operator"
16532 [(reg 17) (const_int 0)])
16533 (match_operand 2 "register_operand" "")
16534 (match_operand 3 "register_operand" "")))]
16535 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16536 && (GET_MODE (operands[0]) == HImode
16537 || (GET_MODE (operands[0]) == QImode
16538 && (TARGET_PROMOTE_QImode || optimize_size)))"
16539 [(set (match_dup 0)
16540 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16541 "operands[0] = gen_lowpart (SImode, operands[0]);
16542 operands[2] = gen_lowpart (SImode, operands[2]);
16543 operands[3] = gen_lowpart (SImode, operands[3]);")
16544
e075ae69
RH
16545\f
16546;; RTL Peephole optimizations, run before sched2. These primarily look to
16547;; transform a complex memory operation into two memory to register operations.
16548
16549;; Don't push memory operands
16550(define_peephole2
3071fab5
RH
16551 [(set (match_operand:SI 0 "push_operand" "")
16552 (match_operand:SI 1 "memory_operand" ""))
16553 (match_scratch:SI 2 "r")]
e075ae69
RH
16554 "! optimize_size && ! TARGET_PUSH_MEMORY"
16555 [(set (match_dup 2) (match_dup 1))
16556 (set (match_dup 0) (match_dup 2))]
16557 "")
16558
cc2e591b
JH
16559(define_peephole2
16560 [(set (match_operand:DI 0 "push_operand" "")
16561 (match_operand:DI 1 "memory_operand" ""))
16562 (match_scratch:DI 2 "r")]
16563 "! optimize_size && ! TARGET_PUSH_MEMORY"
16564 [(set (match_dup 2) (match_dup 1))
16565 (set (match_dup 0) (match_dup 2))]
16566 "")
16567
e9e80858
JH
16568;; We need to handle SFmode only, because DFmode and XFmode is split to
16569;; SImode pushes.
16570(define_peephole2
16571 [(set (match_operand:SF 0 "push_operand" "")
16572 (match_operand:SF 1 "memory_operand" ""))
16573 (match_scratch:SF 2 "r")]
16574 "! optimize_size && ! TARGET_PUSH_MEMORY"
16575 [(set (match_dup 2) (match_dup 1))
16576 (set (match_dup 0) (match_dup 2))]
16577 "")
16578
e075ae69 16579(define_peephole2
3071fab5
RH
16580 [(set (match_operand:HI 0 "push_operand" "")
16581 (match_operand:HI 1 "memory_operand" ""))
16582 (match_scratch:HI 2 "r")]
e075ae69
RH
16583 "! optimize_size && ! TARGET_PUSH_MEMORY"
16584 [(set (match_dup 2) (match_dup 1))
16585 (set (match_dup 0) (match_dup 2))]
16586 "")
16587
16588(define_peephole2
3071fab5
RH
16589 [(set (match_operand:QI 0 "push_operand" "")
16590 (match_operand:QI 1 "memory_operand" ""))
16591 (match_scratch:QI 2 "q")]
e075ae69
RH
16592 "! optimize_size && ! TARGET_PUSH_MEMORY"
16593 [(set (match_dup 2) (match_dup 1))
16594 (set (match_dup 0) (match_dup 2))]
16595 "")
16596
16597;; Don't move an immediate directly to memory when the instruction
16598;; gets too big.
16599(define_peephole2
16600 [(match_scratch:SI 1 "r")
16601 (set (match_operand:SI 0 "memory_operand" "")
16602 (const_int 0))]
23280139 16603 "! optimize_size
591702de 16604 && ! TARGET_USE_MOV0
23280139
RH
16605 && TARGET_SPLIT_LONG_MOVES
16606 && get_attr_length (insn) >= ix86_cost->large_insn
16607 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
16608 [(parallel [(set (match_dup 1) (const_int 0))
16609 (clobber (reg:CC 17))])
16610 (set (match_dup 0) (match_dup 1))]
16611 "")
16612
16613(define_peephole2
16614 [(match_scratch:HI 1 "r")
16615 (set (match_operand:HI 0 "memory_operand" "")
16616 (const_int 0))]
23280139 16617 "! optimize_size
591702de 16618 && ! TARGET_USE_MOV0
23280139
RH
16619 && TARGET_SPLIT_LONG_MOVES
16620 && get_attr_length (insn) >= ix86_cost->large_insn
16621 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 16622 [(parallel [(set (match_dup 2) (const_int 0))
e075ae69
RH
16623 (clobber (reg:CC 17))])
16624 (set (match_dup 0) (match_dup 1))]
591702de 16625 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
e075ae69
RH
16626
16627(define_peephole2
16628 [(match_scratch:QI 1 "q")
16629 (set (match_operand:QI 0 "memory_operand" "")
16630 (const_int 0))]
23280139 16631 "! optimize_size
591702de 16632 && ! TARGET_USE_MOV0
23280139
RH
16633 && TARGET_SPLIT_LONG_MOVES
16634 && get_attr_length (insn) >= ix86_cost->large_insn
16635 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 16636 [(parallel [(set (match_dup 2) (const_int 0))
e075ae69
RH
16637 (clobber (reg:CC 17))])
16638 (set (match_dup 0) (match_dup 1))]
591702de 16639 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
e075ae69
RH
16640
16641(define_peephole2
16642 [(match_scratch:SI 2 "r")
16643 (set (match_operand:SI 0 "memory_operand" "")
16644 (match_operand:SI 1 "immediate_operand" ""))]
23280139
RH
16645 "! optimize_size
16646 && get_attr_length (insn) >= ix86_cost->large_insn
16647 && TARGET_SPLIT_LONG_MOVES"
e075ae69
RH
16648 [(set (match_dup 2) (match_dup 1))
16649 (set (match_dup 0) (match_dup 2))]
16650 "")
16651
16652(define_peephole2
16653 [(match_scratch:HI 2 "r")
16654 (set (match_operand:HI 0 "memory_operand" "")
16655 (match_operand:HI 1 "immediate_operand" ""))]
16656 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16657 && TARGET_SPLIT_LONG_MOVES"
16658 [(set (match_dup 2) (match_dup 1))
16659 (set (match_dup 0) (match_dup 2))]
16660 "")
16661
16662(define_peephole2
16663 [(match_scratch:QI 2 "q")
16664 (set (match_operand:QI 0 "memory_operand" "")
16665 (match_operand:QI 1 "immediate_operand" ""))]
16666 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16667 && TARGET_SPLIT_LONG_MOVES"
16668 [(set (match_dup 2) (match_dup 1))
16669 (set (match_dup 0) (match_dup 2))]
16670 "")
16671
16672;; Don't compare memory with zero, load and use a test instead.
16673(define_peephole2
16189740
RH
16674 [(set (reg 17)
16675 (compare (match_operand:SI 0 "memory_operand" "")
16676 (const_int 0)))
3071fab5 16677 (match_scratch:SI 3 "r")]
16189740
RH
16678 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16679 [(set (match_dup 3) (match_dup 0))
16680 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
e075ae69
RH
16681 "")
16682
16683;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16684;; Don't split NOTs with a displacement operand, because resulting XOR
16685;; will not be pariable anyway.
16686;;
16687;; On AMD K6, NOT is vector decoded with memory operand that can not be
16688;; represented using a modRM byte. The XOR replacement is long decoded,
16689;; so this split helps here as well.
16690;;
23280139
RH
16691;; Note: Can't do this as a regular split because we can't get proper
16692;; lifetime information then.
e075ae69
RH
16693
16694(define_peephole2
d5d6a58b
RH
16695 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16696 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
e075ae69 16697 "!optimize_size
23280139 16698 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
16699 && ((TARGET_PENTIUM
16700 && (GET_CODE (operands[0]) != MEM
16701 || !memory_displacement_operand (operands[0], SImode)))
16702 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16703 [(parallel [(set (match_dup 0)
16704 (xor:SI (match_dup 1) (const_int -1)))
16705 (clobber (reg:CC 17))])]
16706 "")
16707
16708(define_peephole2
d5d6a58b
RH
16709 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16710 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
e075ae69 16711 "!optimize_size
23280139 16712 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
16713 && ((TARGET_PENTIUM
16714 && (GET_CODE (operands[0]) != MEM
16715 || !memory_displacement_operand (operands[0], HImode)))
16716 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16717 [(parallel [(set (match_dup 0)
16718 (xor:HI (match_dup 1) (const_int -1)))
16719 (clobber (reg:CC 17))])]
16720 "")
16721
16722(define_peephole2
d5d6a58b
RH
16723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16724 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
e075ae69 16725 "!optimize_size
23280139 16726 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
16727 && ((TARGET_PENTIUM
16728 && (GET_CODE (operands[0]) != MEM
16729 || !memory_displacement_operand (operands[0], QImode)))
16730 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16731 [(parallel [(set (match_dup 0)
16732 (xor:QI (match_dup 1) (const_int -1)))
16733 (clobber (reg:CC 17))])]
16734 "")
16735
16736;; Non pairable "test imm, reg" instructions can be translated to
16737;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16738;; byte opcode instead of two, have a short form for byte operands),
16739;; so do it for other CPUs as well. Given that the value was dead,
16740;; this should not create any new dependancies. Pass on the sub-word
16741;; versions if we're concerned about partial register stalls.
16742
16743(define_peephole2
16189740
RH
16744 [(set (reg 17)
16745 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16746 (match_operand:SI 1 "immediate_operand" ""))
16747 (const_int 0)))]
16748 "ix86_match_ccmode (insn, CCNOmode)
16749 && (true_regnum (operands[0]) != 0
16750 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
e075ae69
RH
16751 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16752 [(parallel
16753 [(set (reg:CCNO 17)
16754 (compare:CCNO (and:SI (match_dup 0)
16755 (match_dup 1))
16756 (const_int 0)))
16757 (set (match_dup 0)
16758 (and:SI (match_dup 0) (match_dup 1)))])]
16759 "")
16760
e9e80858
JH
16761;; We don't need to handle HImode case, because it will be promoted to SImode
16762;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
16763
16764(define_peephole2
16189740
RH
16765 [(set (reg 17)
16766 (compare (and:QI (match_operand:QI 0 "register_operand" "")
16767 (match_operand:QI 1 "immediate_operand" ""))
16768 (const_int 0)))]
e075ae69 16769 "! TARGET_PARTIAL_REG_STALL
16189740 16770 && ix86_match_ccmode (insn, CCNOmode)
e075ae69
RH
16771 && true_regnum (operands[0]) != 0
16772 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16773 [(parallel
16774 [(set (reg:CCNO 17)
16775 (compare:CCNO (and:QI (match_dup 0)
16776 (match_dup 1))
16777 (const_int 0)))
16778 (set (match_dup 0)
16779 (and:QI (match_dup 0) (match_dup 1)))])]
16780 "")
16781
16782(define_peephole2
16189740
RH
16783 [(set (reg 17)
16784 (compare
e075ae69
RH
16785 (and:SI
16786 (zero_extract:SI
3522082b 16787 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
16788 (const_int 8)
16789 (const_int 8))
3522082b 16790 (match_operand 1 "const_int_operand" ""))
e075ae69
RH
16791 (const_int 0)))]
16792 "! TARGET_PARTIAL_REG_STALL
16189740 16793 && ix86_match_ccmode (insn, CCNOmode)
e075ae69
RH
16794 && true_regnum (operands[0]) != 0
16795 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16796 [(parallel [(set (reg:CCNO 17)
16797 (compare:CCNO
16798 (and:SI
16799 (zero_extract:SI
16800 (match_dup 0)
16801 (const_int 8)
16802 (const_int 8))
16803 (match_dup 1))
16804 (const_int 0)))
16805 (set (zero_extract:SI (match_dup 0)
16806 (const_int 8)
16807 (const_int 8))
16808 (and:SI
16809 (zero_extract:SI
16810 (match_dup 0)
16811 (const_int 8)
16812 (const_int 8))
16813 (match_dup 1)))])]
16814 "")
16815
16816;; Don't do logical operations with memory inputs.
16817(define_peephole2
16818 [(match_scratch:SI 2 "r")
16819 (parallel [(set (match_operand:SI 0 "register_operand" "")
16820 (match_operator:SI 3 "arith_or_logical_operator"
16821 [(match_dup 0)
16822 (match_operand:SI 1 "memory_operand" "")]))
16823 (clobber (reg:CC 17))])]
16824 "! optimize_size && ! TARGET_READ_MODIFY"
16825 [(set (match_dup 2) (match_dup 1))
16826 (parallel [(set (match_dup 0)
16827 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16828 (clobber (reg:CC 17))])]
16829 "")
16830
16831(define_peephole2
16832 [(match_scratch:SI 2 "r")
16833 (parallel [(set (match_operand:SI 0 "register_operand" "")
16834 (match_operator:SI 3 "arith_or_logical_operator"
16835 [(match_operand:SI 1 "memory_operand" "")
16836 (match_dup 0)]))
16837 (clobber (reg:CC 17))])]
16838 "! optimize_size && ! TARGET_READ_MODIFY"
16839 [(set (match_dup 2) (match_dup 1))
16840 (parallel [(set (match_dup 0)
16841 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16842 (clobber (reg:CC 17))])]
16843 "")
16844
16845; Don't do logical operations with memory outputs
16846;
16847; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16848; instruction into two 1-uop insns plus a 2-uop insn. That last has
16849; the same decoder scheduling characteristics as the original.
16850
16851(define_peephole2
16852 [(match_scratch:SI 2 "r")
16853 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16854 (match_operator:SI 3 "arith_or_logical_operator"
16855 [(match_dup 0)
16856 (match_operand:SI 1 "nonmemory_operand" "")]))
16857 (clobber (reg:CC 17))])]
16858 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16859 [(set (match_dup 2) (match_dup 0))
16860 (parallel [(set (match_dup 2)
16861 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16862 (clobber (reg:CC 17))])
16863 (set (match_dup 0) (match_dup 2))]
16864 "")
16865
16866(define_peephole2
16867 [(match_scratch:SI 2 "r")
16868 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16869 (match_operator:SI 3 "arith_or_logical_operator"
16870 [(match_operand:SI 1 "nonmemory_operand" "")
16871 (match_dup 0)]))
16872 (clobber (reg:CC 17))])]
16873 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16874 [(set (match_dup 2) (match_dup 0))
16875 (parallel [(set (match_dup 2)
16876 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16877 (clobber (reg:CC 17))])
16878 (set (match_dup 0) (match_dup 2))]
16879 "")
16880
16881;; Attempt to always use XOR for zeroing registers.
16882(define_peephole2
16883 [(set (match_operand 0 "register_operand" "")
16884 (const_int 0))]
16885 "(GET_MODE (operands[0]) == QImode
16886 || GET_MODE (operands[0]) == HImode
cc2e591b
JH
16887 || GET_MODE (operands[0]) == SImode
16888 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
e075ae69 16889 && (! TARGET_USE_MOV0 || optimize_size)
23280139 16890 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
16891 [(parallel [(set (match_dup 0) (const_int 0))
16892 (clobber (reg:CC 17))])]
cc2e591b
JH
16893 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16894 true_regnum (operands[0]));")
d3a923ee 16895
6ef67412
JH
16896(define_peephole2
16897 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16898 (const_int 0))]
16899 "(GET_MODE (operands[0]) == QImode
16900 || GET_MODE (operands[0]) == HImode)
16901 && (! TARGET_USE_MOV0 || optimize_size)
16902 && peep2_regno_dead_p (0, FLAGS_REG)"
16903 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16904 (clobber (reg:CC 17))])])
16905
e075ae69
RH
16906;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16907(define_peephole2
591702de 16908 [(set (match_operand 0 "register_operand" "")
e075ae69 16909 (const_int -1))]
591702de 16910 "(GET_MODE (operands[0]) == HImode
cc2e591b
JH
16911 || GET_MODE (operands[0]) == SImode
16912 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
591702de 16913 && (optimize_size || TARGET_PENTIUM)
23280139 16914 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 16915 [(parallel [(set (match_dup 0) (const_int -1))
e075ae69 16916 (clobber (reg:CC 17))])]
cc2e591b
JH
16917 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16918 true_regnum (operands[0]));")
1c27d4b2
JH
16919
16920;; Attempt to convert simple leas to adds. These can be created by
16921;; move expanders.
16922(define_peephole2
16923 [(set (match_operand:SI 0 "register_operand" "")
16924 (plus:SI (match_dup 0)
16925 (match_operand:SI 1 "nonmemory_operand" "")))]
23280139 16926 "peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2
JH
16927 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16928 (clobber (reg:CC 17))])]
16929 "")
16930
cc2e591b
JH
16931(define_peephole2
16932 [(set (match_operand:SI 0 "register_operand" "")
16933 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16934 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16935 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
16936 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16937 (clobber (reg:CC 17))])]
16938 "operands[2] = gen_lowpart (SImode, operands[2]);")
16939
16940(define_peephole2
16941 [(set (match_operand:DI 0 "register_operand" "")
16942 (plus:DI (match_dup 0)
16943 (match_operand:DI 1 "x86_64_general_operand" "")))]
16944 "peep2_regno_dead_p (0, FLAGS_REG)"
16945 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
16946 (clobber (reg:CC 17))])]
16947 "")
16948
1c27d4b2
JH
16949(define_peephole2
16950 [(set (match_operand:SI 0 "register_operand" "")
16951 (mult:SI (match_dup 0)
cc2e591b 16952 (match_operand:SI 1 "const_int_operand" "")))]
23280139
RH
16953 "exact_log2 (INTVAL (operands[1])) >= 0
16954 && peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2
JH
16955 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16956 (clobber (reg:CC 17))])]
16957 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
bdeb029c 16958
cc2e591b
JH
16959(define_peephole2
16960 [(set (match_operand:DI 0 "register_operand" "")
16961 (mult:DI (match_dup 0)
16962 (match_operand:DI 1 "const_int_operand" "")))]
16963 "exact_log2 (INTVAL (operands[1])) >= 0
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
16966 (clobber (reg:CC 17))])]
16967 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16968
16969(define_peephole2
16970 [(set (match_operand:SI 0 "register_operand" "")
16971 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16972 (match_operand:DI 2 "const_int_operand" "")) 0))]
16973 "exact_log2 (INTVAL (operands[1])) >= 0
16974 && REGNO (operands[0]) == REGNO (operands[1])
16975 && peep2_regno_dead_p (0, FLAGS_REG)"
16976 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16977 (clobber (reg:CC 17))])]
16978 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16979
bdeb029c
JH
16980;; The ESP adjustments can be done by the push and pop instructions. Resulting
16981;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
16982;; many CPUs it is also faster, since special hardware to avoid esp
16983;; dependancies is present.
16984
16985;; While some of these converisons may be done using splitters, we use peepholes
16986;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
16987
16988;; Convert prologue esp substractions to push.
16989;; We need register to push. In order to keep verify_flow_info happy we have
16990;; two choices
16991;; - use scratch and clobber it in order to avoid dependencies
16992;; - use already live register
16993;; We can't use the second way right now, since there is no reliable way how to
16994;; verify that given register is live. First choice will also most likely in
16995;; fewer dependencies. On the place of esp adjustments it is very likely that
16996;; call clobbered registers are dead. We may want to use base pointer as an
16997;; alternative when no register is available later.
16998
16999(define_peephole2
17000 [(match_scratch:SI 0 "r")
17001 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
f2042df3
RH
17002 (clobber (reg:CC 17))
17003 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17004 "optimize_size || !TARGET_SUB_ESP_4"
17005 [(clobber (match_dup 0))
17006 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
f2042df3 17007 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
17008
17009(define_peephole2
17010 [(match_scratch:SI 0 "r")
17011 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
f2042df3
RH
17012 (clobber (reg:CC 17))
17013 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17014 "optimize_size || !TARGET_SUB_ESP_8"
17015 [(clobber (match_dup 0))
17016 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17017 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
f2042df3 17018 (clobber (mem:BLK (scratch)))])])
bdeb029c
JH
17019
17020;; Convert esp substractions to push.
17021(define_peephole2
17022 [(match_scratch:SI 0 "r")
17023 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17024 (clobber (reg:CC 17))])]
17025 "optimize_size || !TARGET_SUB_ESP_4"
17026 [(clobber (match_dup 0))
17027 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17028
17029(define_peephole2
17030 [(match_scratch:SI 0 "r")
17031 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17032 (clobber (reg:CC 17))])]
17033 "optimize_size || !TARGET_SUB_ESP_8"
17034 [(clobber (match_dup 0))
17035 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17036 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17037
17038;; Convert epilogue deallocator to pop.
17039(define_peephole2
17040 [(match_scratch:SI 0 "r")
17041 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
f2042df3
RH
17042 (clobber (reg:CC 17))
17043 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17044 "optimize_size || !TARGET_ADD_ESP_4"
17045 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17046 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
f2042df3 17047 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17048 "")
17049
17050;; Two pops case is tricky, since pop causes dependency on destination register.
17051;; We use two registers if available.
17052(define_peephole2
17053 [(match_scratch:SI 0 "r")
17054 (match_scratch:SI 1 "r")
17055 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
f2042df3
RH
17056 (clobber (reg:CC 17))
17057 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17058 "optimize_size || !TARGET_ADD_ESP_8"
17059 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17060 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
f2042df3 17061 (clobber (mem:BLK (scratch)))])
bdeb029c
JH
17062 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17063 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17064 "")
17065
17066(define_peephole2
17067 [(match_scratch:SI 0 "r")
17068 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
f2042df3
RH
17069 (clobber (reg:CC 17))
17070 (clobber (mem:BLK (scratch)))])]
bdeb029c
JH
17071 "optimize_size"
17072 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17073 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
f2042df3 17074 (clobber (mem:BLK (scratch)))])
bdeb029c
JH
17075 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17076 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17077 "")
17078
17079;; Convert esp additions to pop.
17080(define_peephole2
17081 [(match_scratch:SI 0 "r")
17082 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17083 (clobber (reg:CC 17))])]
17084 ""
17085 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17086 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17087 "")
17088
17089;; Two pops case is tricky, since pop causes dependency on destination register.
17090;; We use two registers if available.
17091(define_peephole2
17092 [(match_scratch:SI 0 "r")
17093 (match_scratch:SI 1 "r")
17094 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17095 (clobber (reg:CC 17))])]
17096 ""
17097 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17098 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17099 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17100 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17101 "")
17102
17103(define_peephole2
17104 [(match_scratch:SI 0 "r")
17105 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17106 (clobber (reg:CC 17))])]
17107 "optimize_size"
17108 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17109 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17110 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17111 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17112 "")
69404d6f 17113\f
9dcbdc7e
JH
17114;; Convert compares with 1 to shorter inc/dec operations when CF is not
17115;; required and register dies.
17116(define_peephole2
17117 [(set (reg 17)
17118 (compare (match_operand:SI 0 "register_operand" "")
17119 (match_operand:SI 1 "incdec_operand" "")))]
17120 "ix86_match_ccmode (insn, CCGCmode)
17121 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17122 [(parallel [(set (reg:CCGC 17)
265dab10 17123 (compare:CCGC (match_dup 0)
7e08e190 17124 (match_dup 1)))
9dcbdc7e 17125 (clobber (match_dup 0))])]
7e08e190 17126 "")
9dcbdc7e
JH
17127
17128(define_peephole2
17129 [(set (reg 17)
17130 (compare (match_operand:HI 0 "register_operand" "")
17131 (match_operand:HI 1 "incdec_operand" "")))]
17132 "ix86_match_ccmode (insn, CCGCmode)
17133 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17134 [(parallel [(set (reg:CCGC 17)
265dab10 17135 (compare:CCGC (match_dup 0)
7e08e190 17136 (match_dup 1)))
9dcbdc7e 17137 (clobber (match_dup 0))])]
7e08e190 17138 "")
9dcbdc7e
JH
17139
17140(define_peephole2
17141 [(set (reg 17)
17142 (compare (match_operand:QI 0 "register_operand" "")
17143 (match_operand:QI 1 "incdec_operand" "")))]
17144 "ix86_match_ccmode (insn, CCGCmode)
17145 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17146 [(parallel [(set (reg:CCGC 17)
265dab10 17147 (compare:CCGC (match_dup 0)
7e08e190 17148 (match_dup 1)))
9dcbdc7e 17149 (clobber (match_dup 0))])]
7e08e190 17150 "")
9dcbdc7e
JH
17151
17152;; Convert compares with 128 to shorter add -128
17153(define_peephole2
17154 [(set (reg 17)
17155 (compare (match_operand:SI 0 "register_operand" "")
17156 (const_int 128)))]
7e08e190 17157 "ix86_match_ccmode (insn, CCGCmode)
9dcbdc7e 17158 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7e08e190
JH
17159 [(parallel [(set (reg:CCGC 17)
17160 (compare:CCGC (match_dup 0)
17161 (const_int 128)))
9dcbdc7e
JH
17162 (clobber (match_dup 0))])]
17163 "")
17164
17165(define_peephole2
17166 [(set (reg 17)
17167 (compare (match_operand:HI 0 "register_operand" "")
17168 (const_int 128)))]
7e08e190 17169 "ix86_match_ccmode (insn, CCGCmode)
9dcbdc7e 17170 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7e08e190
JH
17171 [(parallel [(set (reg:CCGC 17)
17172 (compare:CCGC (match_dup 0)
17173 (const_int 128)))
9dcbdc7e
JH
17174 (clobber (match_dup 0))])]
17175 "")
17176\f
cc2e591b
JH
17177(define_peephole2
17178 [(match_scratch:DI 0 "r")
17179 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
f2042df3
RH
17180 (clobber (reg:CC 17))
17181 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17182 "optimize_size || !TARGET_SUB_ESP_4"
17183 [(clobber (match_dup 0))
17184 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
f2042df3 17185 (clobber (mem:BLK (scratch)))])])
cc2e591b
JH
17186
17187(define_peephole2
17188 [(match_scratch:DI 0 "r")
17189 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
f2042df3
RH
17190 (clobber (reg:CC 17))
17191 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17192 "optimize_size || !TARGET_SUB_ESP_8"
17193 [(clobber (match_dup 0))
17194 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17195 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
f2042df3 17196 (clobber (mem:BLK (scratch)))])])
cc2e591b
JH
17197
17198;; Convert esp substractions to push.
17199(define_peephole2
17200 [(match_scratch:DI 0 "r")
17201 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17202 (clobber (reg:CC 17))])]
17203 "optimize_size || !TARGET_SUB_ESP_4"
17204 [(clobber (match_dup 0))
17205 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17206
17207(define_peephole2
17208 [(match_scratch:DI 0 "r")
17209 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17210 (clobber (reg:CC 17))])]
17211 "optimize_size || !TARGET_SUB_ESP_8"
17212 [(clobber (match_dup 0))
17213 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17214 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17215
17216;; Convert epilogue deallocator to pop.
17217(define_peephole2
17218 [(match_scratch:DI 0 "r")
17219 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
f2042df3
RH
17220 (clobber (reg:CC 17))
17221 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17222 "optimize_size || !TARGET_ADD_ESP_4"
17223 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17224 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
f2042df3 17225 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17226 "")
17227
17228;; Two pops case is tricky, since pop causes dependency on destination register.
17229;; We use two registers if available.
17230(define_peephole2
17231 [(match_scratch:DI 0 "r")
17232 (match_scratch:DI 1 "r")
17233 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
f2042df3
RH
17234 (clobber (reg:CC 17))
17235 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17236 "optimize_size || !TARGET_ADD_ESP_8"
17237 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17238 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
f2042df3 17239 (clobber (mem:BLK (scratch)))])
cc2e591b
JH
17240 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17241 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17242 "")
17243
17244(define_peephole2
17245 [(match_scratch:DI 0 "r")
17246 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
f2042df3
RH
17247 (clobber (reg:CC 17))
17248 (clobber (mem:BLK (scratch)))])]
cc2e591b
JH
17249 "optimize_size"
17250 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17251 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
f2042df3 17252 (clobber (mem:BLK (scratch)))])
cc2e591b
JH
17253 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17254 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17255 "")
17256
17257;; Convert esp additions to pop.
17258(define_peephole2
17259 [(match_scratch:DI 0 "r")
17260 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17261 (clobber (reg:CC 17))])]
17262 ""
17263 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17264 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17265 "")
17266
17267;; Two pops case is tricky, since pop causes dependency on destination register.
17268;; We use two registers if available.
17269(define_peephole2
17270 [(match_scratch:DI 0 "r")
17271 (match_scratch:DI 1 "r")
17272 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17273 (clobber (reg:CC 17))])]
17274 ""
17275 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17276 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17277 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17278 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17279 "")
17280
17281(define_peephole2
17282 [(match_scratch:DI 0 "r")
17283 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17284 (clobber (reg:CC 17))])]
17285 "optimize_size"
17286 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17287 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17288 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17289 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17290 "")
17291\f
69404d6f
RH
17292;; Call-value patterns last so that the wildcard operand does not
17293;; disrupt insn-recog's switch tables.
17294
94bb5d0c
RH
17295(define_insn "*call_value_pop_0"
17296 [(set (match_operand 0 "" "")
e1ff012c 17297 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c
RH
17298 (match_operand:SI 2 "" "")))
17299 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 17300 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 17301 "!TARGET_64BIT"
94bb5d0c
RH
17302{
17303 if (SIBLING_CALL_P (insn))
0f40f9f7 17304 return "jmp\t%P1";
94bb5d0c 17305 else
0f40f9f7
ZW
17306 return "call\t%P1";
17307}
94bb5d0c
RH
17308 [(set_attr "type" "callv")])
17309
69404d6f
RH
17310(define_insn "*call_value_pop_1"
17311 [(set (match_operand 0 "" "")
e1ff012c 17312 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 17313 (match_operand:SI 2 "" "")))
69404d6f 17314 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 17315 (match_operand:SI 3 "immediate_operand" "i")))]
1e07edd3 17316 "!TARGET_64BIT"
69404d6f 17317{
94bb5d0c
RH
17318 if (constant_call_address_operand (operands[1], QImode))
17319 {
17320 if (SIBLING_CALL_P (insn))
0f40f9f7 17321 return "jmp\t%P1";
94bb5d0c 17322 else
0f40f9f7 17323 return "call\t%P1";
94bb5d0c 17324 }
94bb5d0c 17325 if (SIBLING_CALL_P (insn))
0f40f9f7 17326 return "jmp\t%A1";
94bb5d0c 17327 else
0f40f9f7
ZW
17328 return "call\t%A1";
17329}
94bb5d0c
RH
17330 [(set_attr "type" "callv")])
17331
17332(define_insn "*call_value_0"
17333 [(set (match_operand 0 "" "")
e1ff012c 17334 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c 17335 (match_operand:SI 2 "" "")))]
32ee7d1d 17336 "!TARGET_64BIT"
32ee7d1d
JH
17337{
17338 if (SIBLING_CALL_P (insn))
0f40f9f7 17339 return "jmp\t%P1";
32ee7d1d 17340 else
0f40f9f7
ZW
17341 return "call\t%P1";
17342}
32ee7d1d
JH
17343 [(set_attr "type" "callv")])
17344
17345(define_insn "*call_value_0_rex64"
17346 [(set (match_operand 0 "" "")
17347 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17348 (match_operand:DI 2 "const_int_operand" "")))]
17349 "TARGET_64BIT"
94bb5d0c
RH
17350{
17351 if (SIBLING_CALL_P (insn))
0f40f9f7 17352 return "jmp\t%P1";
94bb5d0c 17353 else
0f40f9f7
ZW
17354 return "call\t%P1";
17355}
69404d6f
RH
17356 [(set_attr "type" "callv")])
17357
69404d6f
RH
17358(define_insn "*call_value_1"
17359 [(set (match_operand 0 "" "")
e1ff012c 17360 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 17361 (match_operand:SI 2 "" "")))]
32ee7d1d 17362 "!TARGET_64BIT"
32ee7d1d
JH
17363{
17364 if (constant_call_address_operand (operands[1], QImode))
17365 {
17366 if (SIBLING_CALL_P (insn))
0f40f9f7 17367 return "jmp\t%P1";
32ee7d1d 17368 else
0f40f9f7 17369 return "call\t%P1";
32ee7d1d
JH
17370 }
17371 if (SIBLING_CALL_P (insn))
0f40f9f7 17372 return "jmp\t%*%1";
32ee7d1d 17373 else
0f40f9f7
ZW
17374 return "call\t%*%1";
17375}
32ee7d1d
JH
17376 [(set_attr "type" "callv")])
17377
17378(define_insn "*call_value_1_rex64"
17379 [(set (match_operand 0 "" "")
17380 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17381 (match_operand:DI 2 "" "")))]
17382 "TARGET_64BIT"
69404d6f 17383{
94bb5d0c 17384 if (constant_call_address_operand (operands[1], QImode))
cbbf65e0
RH
17385 {
17386 if (SIBLING_CALL_P (insn))
0f40f9f7 17387 return "jmp\t%P1";
cbbf65e0 17388 else
0f40f9f7 17389 return "call\t%P1";
cbbf65e0 17390 }
cbbf65e0 17391 if (SIBLING_CALL_P (insn))
0f40f9f7 17392 return "jmp\t%A1";
cbbf65e0 17393 else
0f40f9f7
ZW
17394 return "call\t%A1";
17395}
69404d6f 17396 [(set_attr "type" "callv")])
9e3e266c
GM
17397\f
17398(define_insn "trap"
17399 [(trap_if (const_int 1) (const_int 5))]
17400 ""
0f40f9f7 17401 "int\t$5")
9e3e266c
GM
17402
17403;;; ix86 doesn't have conditional trap instructions, but we fake them
17404;;; for the sake of bounds checking. By emitting bounds checks as
17405;;; conditional traps rather than as conditional jumps around
17406;;; unconditional traps we avoid introducing spurious basic-block
17407;;; boundaries and facilitate elimination of redundant checks. In
17408;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17409;;; interrupt 5.
17410;;;
17411;;; FIXME: Static branch prediction rules for ix86 are such that
17412;;; forward conditional branches predict as untaken. As implemented
17413;;; below, pseudo conditional traps violate that rule. We should use
17414;;; .pushsection/.popsection to place all of the `int 5's in a special
17415;;; section loaded at the end of the text segment and branch forward
17416;;; there on bounds-failure, and then jump back immediately (in case
17417;;; the system chooses to ignore bounds violations, or to report
17418;;; violations and continue execution).
17419
17420(define_expand "conditional_trap"
17421 [(trap_if (match_operator 0 "comparison_operator"
17422 [(match_dup 2) (const_int 0)])
17423 (match_operand 1 "const_int_operand" ""))]
17424 ""
9e3e266c
GM
17425{
17426 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
a1b8572c 17427 ix86_expand_compare (GET_CODE (operands[0]),
df4ae160 17428 NULL, NULL),
9e3e266c
GM
17429 operands[1]));
17430 DONE;
0f40f9f7 17431})
9e3e266c 17432
0f40f9f7 17433(define_insn "*conditional_trap_1"
9e3e266c
GM
17434 [(trap_if (match_operator 0 "comparison_operator"
17435 [(reg 17) (const_int 0)])
17436 (match_operand 1 "const_int_operand" ""))]
17437 ""
9e3e266c
GM
17438{
17439 operands[2] = gen_label_rtx ();
0f40f9f7
ZW
17440 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17441 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
9e3e266c
GM
17442 CODE_LABEL_NUMBER (operands[2]));
17443 RET;
0f40f9f7 17444})
915119a5
BS
17445
17446 ;; Pentium III SIMD instructions.
17447
17448;; Moves for SSE/MMX regs.
17449
17450(define_insn "movv4sf_internal"
17451 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17452 (match_operand:V4SF 1 "general_operand" "xm,x"))]
17453 "TARGET_SSE"
17454 ;; @@@ let's try to use movaps here.
0f40f9f7 17455 "movaps\t{%1, %0|%0, %1}"
915119a5
BS
17456 [(set_attr "type" "sse")])
17457
17458(define_insn "movv4si_internal"
17459 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17460 (match_operand:V4SI 1 "general_operand" "xm,x"))]
17461 "TARGET_SSE"
17462 ;; @@@ let's try to use movaps here.
0f40f9f7 17463 "movaps\t{%1, %0|%0, %1}"
915119a5
BS
17464 [(set_attr "type" "sse")])
17465
17466(define_insn "movv8qi_internal"
17467 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17468 (match_operand:V8QI 1 "general_operand" "ym,y"))]
17469 "TARGET_MMX"
0f40f9f7 17470 "movq\t{%1, %0|%0, %1}"
915119a5
BS
17471 [(set_attr "type" "mmx")])
17472
17473(define_insn "movv4hi_internal"
17474 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17475 (match_operand:V4HI 1 "general_operand" "ym,y"))]
17476 "TARGET_MMX"
0f40f9f7 17477 "movq\t{%1, %0|%0, %1}"
915119a5
BS
17478 [(set_attr "type" "mmx")])
17479
17480(define_insn "movv2si_internal"
17481 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17482 (match_operand:V2SI 1 "general_operand" "ym,y"))]
17483 "TARGET_MMX"
0f40f9f7 17484 "movq\t{%1, %0|%0, %1}"
915119a5
BS
17485 [(set_attr "type" "mmx")])
17486
47f339cf
BS
17487(define_insn "movv2sf_internal"
17488 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17489 (match_operand:V2SF 1 "general_operand" "ym,y"))]
17490 "TARGET_3DNOW"
17491 "movq\\t{%1, %0|%0, %1}"
17492 [(set_attr "type" "mmx")])
17493
915119a5
BS
17494(define_expand "movti"
17495 [(set (match_operand:TI 0 "general_operand" "")
17496 (match_operand:TI 1 "general_operand" ""))]
17497 "TARGET_SSE"
915119a5
BS
17498{
17499 /* For constants other than zero into memory. We do not know how the
17500 instructions used to build constants modify the upper 64 bits
17501 of the register, once we have that information we may be able
17502 to handle some of them more efficiently. */
17503 if ((reload_in_progress | reload_completed) == 0
17504 && register_operand (operands[0], TImode)
17505 && CONSTANT_P (operands[1]))
17506 {
17507 rtx addr = gen_reg_rtx (Pmode);
17508
17509 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
17510 operands[1] = gen_rtx_MEM (TImode, addr);
17511 }
17512
17513 /* Make operand1 a register if it isn't already. */
17514 if ((reload_in_progress | reload_completed) == 0
17515 && !register_operand (operands[0], TImode)
17516 && !register_operand (operands[1], TImode)
17517 && operands[1] != CONST0_RTX (TImode))
17518 {
17519 rtx temp = force_reg (TImode, operands[1]);
17520 emit_move_insn (operands[0], temp);
17521 DONE;
17522 }
0f40f9f7 17523})
915119a5
BS
17524
17525(define_expand "movv4sf"
17526 [(set (match_operand:V4SF 0 "general_operand" "")
17527 (match_operand:V4SF 1 "general_operand" ""))]
17528 "TARGET_SSE"
915119a5
BS
17529{
17530 /* For constants other than zero into memory. We do not know how the
17531 instructions used to build constants modify the upper 64 bits
17532 of the register, once we have that information we may be able
17533 to handle some of them more efficiently. */
17534 if ((reload_in_progress | reload_completed) == 0
17535 && register_operand (operands[0], V4SFmode)
17536 && CONSTANT_P (operands[1]))
17537 {
17538 rtx addr = gen_reg_rtx (Pmode);
17539
17540 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
17541 operands[1] = gen_rtx_MEM (V4SFmode, addr);
17542 }
17543
17544 /* Make operand1 a register if it isn't already. */
17545 if ((reload_in_progress | reload_completed) == 0
17546 && !register_operand (operands[0], V4SFmode)
17547 && !register_operand (operands[1], V4SFmode)
17548 && operands[1] != CONST0_RTX (V4SFmode))
17549 {
17550 rtx temp = force_reg (V4SFmode, operands[1]);
17551 emit_move_insn (operands[0], temp);
17552 DONE;
17553 }
0f40f9f7 17554})
915119a5
BS
17555
17556(define_expand "movv4si"
17557 [(set (match_operand:V4SI 0 "general_operand" "")
17558 (match_operand:V4SI 1 "general_operand" ""))]
17559 "TARGET_MMX"
915119a5
BS
17560{
17561 /* For constants other than zero into memory. We do not know how the
17562 instructions used to build constants modify the upper 64 bits
17563 of the register, once we have that information we may be able
17564 to handle some of them more efficiently. */
17565 if ((reload_in_progress | reload_completed) == 0
17566 && register_operand (operands[0], V4SImode)
17567 && CONSTANT_P (operands[1]))
17568 {
17569 rtx addr = gen_reg_rtx (Pmode);
17570
17571 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
17572 operands[1] = gen_rtx_MEM (V4SImode, addr);
17573 }
17574
17575 /* Make operand1 a register if it isn't already. */
17576 if ((reload_in_progress | reload_completed) == 0
17577 && !register_operand (operands[0], V4SImode)
17578 && !register_operand (operands[1], V4SImode)
17579 && operands[1] != CONST0_RTX (V4SImode))
17580 {
17581 rtx temp = force_reg (V4SImode, operands[1]);
17582 emit_move_insn (operands[0], temp);
17583 DONE;
17584 }
0f40f9f7 17585})
915119a5
BS
17586
17587(define_expand "movv2si"
17588 [(set (match_operand:V2SI 0 "general_operand" "")
17589 (match_operand:V2SI 1 "general_operand" ""))]
17590 "TARGET_MMX"
915119a5
BS
17591{
17592 /* For constants other than zero into memory. We do not know how the
17593 instructions used to build constants modify the upper 64 bits
17594 of the register, once we have that information we may be able
17595 to handle some of them more efficiently. */
17596 if ((reload_in_progress | reload_completed) == 0
17597 && register_operand (operands[0], V2SImode)
17598 && CONSTANT_P (operands[1]))
17599 {
17600 rtx addr = gen_reg_rtx (Pmode);
17601
17602 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
17603 operands[1] = gen_rtx_MEM (V2SImode, addr);
17604 }
17605
17606 /* Make operand1 a register if it isn't already. */
17607 if ((reload_in_progress | reload_completed) == 0
17608 && !register_operand (operands[0], V2SImode)
17609 && !register_operand (operands[1], V2SImode)
17610 && operands[1] != CONST0_RTX (V2SImode))
17611 {
17612 rtx temp = force_reg (V2SImode, operands[1]);
17613 emit_move_insn (operands[0], temp);
17614 DONE;
17615 }
0f40f9f7 17616})
915119a5
BS
17617
17618(define_expand "movv4hi"
17619 [(set (match_operand:V4HI 0 "general_operand" "")
17620 (match_operand:V4HI 1 "general_operand" ""))]
17621 "TARGET_MMX"
915119a5
BS
17622{
17623 /* For constants other than zero into memory. We do not know how the
17624 instructions used to build constants modify the upper 64 bits
17625 of the register, once we have that information we may be able
17626 to handle some of them more efficiently. */
17627 if ((reload_in_progress | reload_completed) == 0
17628 && register_operand (operands[0], V4HImode)
17629 && CONSTANT_P (operands[1]))
17630 {
17631 rtx addr = gen_reg_rtx (Pmode);
17632
17633 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
17634 operands[1] = gen_rtx_MEM (V4HImode, addr);
17635 }
17636
17637 /* Make operand1 a register if it isn't already. */
17638 if ((reload_in_progress | reload_completed) == 0
17639 && !register_operand (operands[0], V4HImode)
17640 && !register_operand (operands[1], V4HImode)
17641 && operands[1] != CONST0_RTX (V4HImode))
17642 {
17643 rtx temp = force_reg (V4HImode, operands[1]);
17644 emit_move_insn (operands[0], temp);
17645 DONE;
17646 }
0f40f9f7 17647})
915119a5
BS
17648
17649(define_expand "movv8qi"
17650 [(set (match_operand:V8QI 0 "general_operand" "")
17651 (match_operand:V8QI 1 "general_operand" ""))]
17652 "TARGET_MMX"
915119a5
BS
17653{
17654 /* For constants other than zero into memory. We do not know how the
17655 instructions used to build constants modify the upper 64 bits
17656 of the register, once we have that information we may be able
17657 to handle some of them more efficiently. */
17658 if ((reload_in_progress | reload_completed) == 0
17659 && register_operand (operands[0], V8QImode)
17660 && CONSTANT_P (operands[1]))
17661 {
17662 rtx addr = gen_reg_rtx (Pmode);
17663
17664 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
17665 operands[1] = gen_rtx_MEM (V8QImode, addr);
17666 }
17667
17668 /* Make operand1 a register if it isn't already. */
17669 if ((reload_in_progress | reload_completed) == 0
17670 && !register_operand (operands[0], V8QImode)
17671 && !register_operand (operands[1], V8QImode)
17672 && operands[1] != CONST0_RTX (V8QImode))
17673 {
17674 rtx temp = force_reg (V8QImode, operands[1]);
17675 emit_move_insn (operands[0], temp);
17676 DONE;
17677 }
0f40f9f7 17678})
915119a5 17679
47f339cf
BS
17680(define_expand "movv2sf"
17681 [(set (match_operand:V2SF 0 "general_operand" "")
17682 (match_operand:V2SF 1 "general_operand" ""))]
17683 "TARGET_3DNOW"
17684 "
17685{
17686 /* For constants other than zero into memory. We do not know how the
17687 instructions used to build constants modify the upper 64 bits
17688 of the register, once we have that information we may be able
17689 to handle some of them more efficiently. */
17690 if ((reload_in_progress | reload_completed) == 0
17691 && register_operand (operands[0], V2SFmode)
17692 && CONSTANT_P (operands[1]))
17693 {
17694 rtx addr = gen_reg_rtx (Pmode);
17695
17696 emit_move_insn (addr,
17697 XEXP (force_const_mem (V2SFmode, operands[1]), 0));
17698 operands[1] = gen_rtx_MEM (V2SFmode, addr);
17699 }
17700
17701 /* Make operand1 a register is it isn't already. */
17702 if ((reload_in_progress | reload_completed) == 0
17703 && !register_operand (operands[0], V2SFmode)
17704 && !register_operand (operands[1], V2SFmode)
17705 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
17706 && operands[1] != CONST0_RTX (V2SFmode))
17707 {
17708 rtx temp = force_reg (V2SFmode, operands[1]);
17709 emit_move_insn (operands[0], temp);
17710 DONE;
17711 }
17712}")
17713
915119a5
BS
17714(define_insn_and_split "*pushti"
17715 [(set (match_operand:TI 0 "push_operand" "=<")
17716 (match_operand:TI 1 "nonmemory_operand" "x"))]
17717 "TARGET_SSE"
17718 "#"
17719 ""
17720 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17721 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17722 ""
17723 [(set_attr "type" "sse")])
17724
17725(define_insn_and_split "*pushv4sf"
17726 [(set (match_operand:V4SF 0 "push_operand" "=<")
17727 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17728 "TARGET_SSE"
17729 "#"
17730 ""
17731 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17732 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17733 ""
17734 [(set_attr "type" "sse")])
17735
17736(define_insn_and_split "*pushv4si"
17737 [(set (match_operand:V4SI 0 "push_operand" "=<")
17738 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17739 "TARGET_SSE"
17740 "#"
17741 ""
17742 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17743 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17744 ""
17745 [(set_attr "type" "sse")])
17746
17747(define_insn_and_split "*pushv2si"
17748 [(set (match_operand:V2SI 0 "push_operand" "=<")
17749 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17750 "TARGET_MMX"
17751 "#"
17752 ""
17753 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17754 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17755 ""
17756 [(set_attr "type" "mmx")])
17757
17758(define_insn_and_split "*pushv4hi"
17759 [(set (match_operand:V4HI 0 "push_operand" "=<")
17760 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17761 "TARGET_MMX"
17762 "#"
17763 ""
17764 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17765 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17766 ""
17767 [(set_attr "type" "mmx")])
17768
17769(define_insn_and_split "*pushv8qi"
17770 [(set (match_operand:V8QI 0 "push_operand" "=<")
17771 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17772 "TARGET_MMX"
17773 "#"
17774 ""
17775 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17776 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17777 ""
17778 [(set_attr "type" "mmx")])
17779
47f339cf
BS
17780(define_insn_and_split "*pushv2sf"
17781 [(set (match_operand:V2SF 0 "push_operand" "=<")
17782 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
17783 "TARGET_3DNOW"
17784 "#"
17785 ""
17786 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17787 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
17788 ""
17789 [(set_attr "type" "mmx")])
17790
915119a5
BS
17791(define_insn "movti_internal"
17792 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
17793 (match_operand:TI 1 "general_operand" "xm,x"))]
17794 "TARGET_SSE"
17795 "@
0f40f9f7
ZW
17796 movaps\t{%1, %0|%0, %1}
17797 movaps\t{%1, %0|%0, %1}"
915119a5
BS
17798 [(set_attr "type" "sse")])
17799
17800;; These two patterns are useful for specifying exactly whether to use
17801;; movaps or movups
17802(define_insn "sse_movaps"
17803 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17804 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
17805 "TARGET_SSE"
17806 "@
0f40f9f7
ZW
17807 movaps\t{%1, %0|%0, %1}
17808 movaps\t{%1, %0|%0, %1}"
915119a5
BS
17809 [(set_attr "type" "sse")])
17810
17811(define_insn "sse_movups"
17812 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17813 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
17814 "TARGET_SSE"
17815 "@
0f40f9f7
ZW
17816 movups\t{%1, %0|%0, %1}
17817 movups\t{%1, %0|%0, %1}"
915119a5
BS
17818 [(set_attr "type" "sse")])
17819
17820
17821;; SSE Strange Moves.
17822
17823(define_insn "sse_movmskps"
17824 [(set (match_operand:SI 0 "register_operand" "=r")
17825 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
17826 "TARGET_SSE"
0f40f9f7 17827 "movmskps\t{%1, %0|%0, %1}"
915119a5
BS
17828 [(set_attr "type" "sse")])
17829
17830(define_insn "mmx_pmovmskb"
17831 [(set (match_operand:SI 0 "register_operand" "=r")
17832 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
47f339cf 17833 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 17834 "pmovmskb\t{%1, %0|%0, %1}"
915119a5
BS
17835 [(set_attr "type" "sse")])
17836
17837(define_insn "mmx_maskmovq"
17838 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17839 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17840 (match_operand:V8QI 2 "register_operand" "y")] 32))]
47f339cf 17841 "TARGET_SSE || TARGET_3DNOW_A"
915119a5 17842 ;; @@@ check ordering of operands in intel/nonintel syntax
0f40f9f7 17843 "maskmovq\t{%2, %1|%1, %2}"
915119a5
BS
17844 [(set_attr "type" "sse")])
17845
17846(define_insn "sse_movntv4sf"
17847 [(set (match_operand:V4SF 0 "memory_operand" "=m")
17848 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
17849 "TARGET_SSE"
0f40f9f7 17850 "movntps\t{%1, %0|%0, %1}"
915119a5
BS
17851 [(set_attr "type" "sse")])
17852
17853(define_insn "sse_movntdi"
17854 [(set (match_operand:DI 0 "memory_operand" "=m")
332316cd 17855 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
47f339cf 17856 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 17857 "movntq\t{%1, %0|%0, %1}"
915119a5
BS
17858 [(set_attr "type" "sse")])
17859
17860(define_insn "sse_movhlps"
17861 [(set (match_operand:V4SF 0 "register_operand" "=x")
17862 (vec_merge:V4SF
17863 (match_operand:V4SF 1 "register_operand" "0")
17864 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17865 (parallel [(const_int 2)
17866 (const_int 3)
17867 (const_int 0)
17868 (const_int 1)]))
17869 (const_int 3)))]
17870 "TARGET_SSE"
0f40f9f7 17871 "movhlps\t{%2, %0|%0, %2}"
915119a5
BS
17872 [(set_attr "type" "sse")])
17873
17874(define_insn "sse_movlhps"
17875 [(set (match_operand:V4SF 0 "register_operand" "=x")
17876 (vec_merge:V4SF
17877 (match_operand:V4SF 1 "register_operand" "0")
17878 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17879 (parallel [(const_int 2)
17880 (const_int 3)
17881 (const_int 0)
17882 (const_int 1)]))
17883 (const_int 12)))]
17884 "TARGET_SSE"
0f40f9f7 17885 "movlhps\t{%2, %0|%0, %2}"
915119a5
BS
17886 [(set_attr "type" "sse")])
17887
17888(define_insn "sse_movhps"
17889 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17890 (vec_merge:V4SF
17891 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17892 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17893 (const_int 12)))]
17894 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
0f40f9f7 17895 "movhps\t{%2, %0|%0, %2}"
915119a5
BS
17896 [(set_attr "type" "sse")])
17897
17898(define_insn "sse_movlps"
17899 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17900 (vec_merge:V4SF
17901 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17902 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17903 (const_int 3)))]
17904 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
0f40f9f7 17905 "movlps\t{%2, %0|%0, %2}"
915119a5
BS
17906 [(set_attr "type" "sse")])
17907
17908(define_insn "sse_loadss"
17909 [(set (match_operand:V4SF 0 "register_operand" "=x")
17910 (vec_merge:V4SF
17911 (match_operand:V4SF 1 "memory_operand" "m")
17912 (vec_duplicate:V4SF (float:SF (const_int 0)))
17913 (const_int 1)))]
17914 "TARGET_SSE"
0f40f9f7 17915 "movss\t{%1, %0|%0, %1}"
915119a5
BS
17916 [(set_attr "type" "sse")])
17917
17918(define_insn "sse_movss"
17919 [(set (match_operand:V4SF 0 "register_operand" "=x")
17920 (vec_merge:V4SF
17921 (match_operand:V4SF 1 "register_operand" "0")
17922 (match_operand:V4SF 2 "register_operand" "x")
17923 (const_int 1)))]
17924 "TARGET_SSE"
0f40f9f7 17925 "movss\t{%2, %0|%0, %2}"
915119a5
BS
17926 [(set_attr "type" "sse")])
17927
17928(define_insn "sse_storess"
17929 [(set (match_operand:SF 0 "memory_operand" "=m")
17930 (vec_select:SF
17931 (match_operand:V4SF 1 "register_operand" "x")
17932 (parallel [(const_int 0)])))]
17933 "TARGET_SSE"
0f40f9f7 17934 "movss\t{%1, %0|%0, %1}"
915119a5
BS
17935 [(set_attr "type" "sse")])
17936
17937(define_insn "sse_shufps"
17938 [(set (match_operand:V4SF 0 "register_operand" "=x")
17939 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
17940 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
17941 (match_operand:SI 3 "immediate_operand" "i")] 41))]
17942 "TARGET_SSE"
17943 ;; @@@ check operand order for intel/nonintel syntax
0f40f9f7 17944 "shufps\t{%3, %2, %0|%0, %2, %3}"
915119a5
BS
17945 [(set_attr "type" "sse")])
17946
17947
17948;; SSE arithmetic
17949
17950(define_insn "addv4sf3"
17951 [(set (match_operand:V4SF 0 "register_operand" "=x")
17952 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17953 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17954 "TARGET_SSE"
0f40f9f7 17955 "addps\t{%2, %0|%0, %2}"
915119a5
BS
17956 [(set_attr "type" "sse")])
17957
17958(define_insn "vmaddv4sf3"
17959 [(set (match_operand:V4SF 0 "register_operand" "=x")
17960 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17961 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17962 (match_dup 1)
17963 (const_int 1)))]
17964 "TARGET_SSE"
0f40f9f7 17965 "addss\t{%2, %0|%0, %2}"
915119a5
BS
17966 [(set_attr "type" "sse")])
17967
17968(define_insn "subv4sf3"
17969 [(set (match_operand:V4SF 0 "register_operand" "=x")
17970 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17971 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17972 "TARGET_SSE"
0f40f9f7 17973 "subps\t{%2, %0|%0, %2}"
915119a5
BS
17974 [(set_attr "type" "sse")])
17975
17976(define_insn "vmsubv4sf3"
17977 [(set (match_operand:V4SF 0 "register_operand" "=x")
17978 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17979 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17980 (match_dup 1)
17981 (const_int 1)))]
17982 "TARGET_SSE"
0f40f9f7 17983 "subss\t{%2, %0|%0, %2}"
915119a5
BS
17984 [(set_attr "type" "sse")])
17985
17986(define_insn "mulv4sf3"
17987 [(set (match_operand:V4SF 0 "register_operand" "=x")
17988 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17989 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17990 "TARGET_SSE"
0f40f9f7 17991 "mulps\t{%2, %0|%0, %2}"
915119a5
BS
17992 [(set_attr "type" "sse")])
17993
17994(define_insn "vmmulv4sf3"
17995 [(set (match_operand:V4SF 0 "register_operand" "=x")
17996 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17997 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17998 (match_dup 1)
17999 (const_int 1)))]
18000 "TARGET_SSE"
0f40f9f7 18001 "mulss\t{%2, %0|%0, %2}"
915119a5
BS
18002 [(set_attr "type" "sse")])
18003
18004(define_insn "divv4sf3"
18005 [(set (match_operand:V4SF 0 "register_operand" "=x")
18006 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18007 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18008 "TARGET_SSE"
0f40f9f7 18009 "divps\t{%2, %0|%0, %2}"
915119a5
BS
18010 [(set_attr "type" "sse")])
18011
18012(define_insn "vmdivv4sf3"
18013 [(set (match_operand:V4SF 0 "register_operand" "=x")
18014 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18015 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18016 (match_dup 1)
18017 (const_int 1)))]
18018 "TARGET_SSE"
0f40f9f7 18019 "divss\t{%2, %0|%0, %2}"
915119a5
BS
18020 [(set_attr "type" "sse")])
18021
18022
18023;; SSE square root/reciprocal
18024
18025(define_insn "rcpv4sf2"
18026 [(set (match_operand:V4SF 0 "register_operand" "=x")
18027 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
18028 "TARGET_SSE"
0f40f9f7 18029 "rcpps\t{%1, %0|%0, %1}"
915119a5
BS
18030 [(set_attr "type" "sse")])
18031
18032(define_insn "vmrcpv4sf2"
18033 [(set (match_operand:V4SF 0 "register_operand" "=x")
18034 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
18035 (match_operand:V4SF 2 "register_operand" "0")
18036 (const_int 1)))]
18037 "TARGET_SSE"
0f40f9f7 18038 "rcpss\t{%1, %0|%0, %1}"
915119a5
BS
18039 [(set_attr "type" "sse")])
18040
18041(define_insn "rsqrtv4sf2"
18042 [(set (match_operand:V4SF 0 "register_operand" "=x")
18043 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
18044 "TARGET_SSE"
0f40f9f7 18045 "rsqrtps\t{%1, %0|%0, %1}"
915119a5
BS
18046 [(set_attr "type" "sse")])
18047
18048(define_insn "vmrsqrtv4sf2"
18049 [(set (match_operand:V4SF 0 "register_operand" "=x")
18050 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
18051 (match_operand:V4SF 2 "register_operand" "0")
18052 (const_int 1)))]
18053 "TARGET_SSE"
0f40f9f7 18054 "rsqrtss\t{%1, %0|%0, %1}"
915119a5
BS
18055 [(set_attr "type" "sse")])
18056
18057(define_insn "sqrtv4sf2"
18058 [(set (match_operand:V4SF 0 "register_operand" "=x")
18059 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
18060 "TARGET_SSE"
0f40f9f7 18061 "sqrtps\t{%1, %0|%0, %1}"
915119a5
BS
18062 [(set_attr "type" "sse")])
18063
18064(define_insn "vmsqrtv4sf2"
18065 [(set (match_operand:V4SF 0 "register_operand" "=x")
18066 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
18067 (match_operand:V4SF 2 "register_operand" "0")
18068 (const_int 1)))]
18069 "TARGET_SSE"
0f40f9f7 18070 "sqrtss\t{%1, %0|%0, %1}"
915119a5
BS
18071 [(set_attr "type" "sse")])
18072
18073
18074;; SSE logical operations.
18075
18076;; These are not called andti3 etc. because we really really don't want
18077;; the compiler to widen DImode ands to TImode ands and then try to move
18078;; into DImode subregs of SSE registers, and them together, and move out
18079;; of DImode subregs again!
18080
c679d048
JH
18081(define_insn "*sse_andti3_df_1"
18082 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18083 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18084 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18085 "TARGET_SSE2"
0f40f9f7 18086 "andpd\t{%2, %0|%0, %2}"
c679d048
JH
18087 [(set_attr "type" "sse")])
18088
18089(define_insn "*sse_andti3_df_2"
18090 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18091 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18092 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18093 "TARGET_SSE2"
0f40f9f7 18094 "andpd\t{%2, %0|%0, %2}"
c679d048
JH
18095 [(set_attr "type" "sse")])
18096
18097(define_insn "*sse_andti3_sf_1"
18098 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18099 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18100 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18101 "TARGET_SSE"
0f40f9f7 18102 "andps\t{%2, %0|%0, %2}"
c679d048
JH
18103 [(set_attr "type" "sse")])
18104
18105(define_insn "*sse_andti3_sf_2"
18106 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18107 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18108 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18109 "TARGET_SSE"
0f40f9f7 18110 "andps\t{%2, %0|%0, %2}"
c679d048
JH
18111 [(set_attr "type" "sse")])
18112
915119a5
BS
18113(define_insn "sse_andti3"
18114 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048 18115 (and:TI (match_operand:TI 1 "register_operand" "%0")
915119a5 18116 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 18117 "TARGET_SSE && !TARGET_SSE2"
0f40f9f7 18118 "andps\t{%2, %0|%0, %2}"
915119a5
BS
18119 [(set_attr "type" "sse")])
18120
c679d048
JH
18121(define_insn "*sse_andti3_sse2"
18122 [(set (match_operand:TI 0 "register_operand" "=x")
18123 (and:TI (match_operand:TI 1 "register_operand" "%0")
18124 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18125 "TARGET_SSE2"
0f40f9f7 18126 "pand\t{%2, %0|%0, %2}"
c679d048
JH
18127 [(set_attr "type" "sse")])
18128
18129(define_insn "*sse_nandti3_df"
18130 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18131 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18132 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18133 "TARGET_SSE2"
0f40f9f7 18134 "andnpd\t{%2, %0|%0, %2}"
c679d048
JH
18135 [(set_attr "type" "sse")])
18136
18137(define_insn "*sse_nandti3_sf"
18138 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18139 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18140 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18141 "TARGET_SSE"
0f40f9f7 18142 "andnps\t{%2, %0|%0, %2}"
c679d048
JH
18143 [(set_attr "type" "sse")])
18144
915119a5
BS
18145(define_insn "sse_nandti3"
18146 [(set (match_operand:TI 0 "register_operand" "=x")
18147 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18148 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 18149 "TARGET_SSE && !TARGET_SSE2"
0f40f9f7 18150 "andnps\t{%2, %0|%0, %2}"
915119a5
BS
18151 [(set_attr "type" "sse")])
18152
c679d048
JH
18153(define_insn "*sse_nandti3_sse2"
18154 [(set (match_operand:TI 0 "register_operand" "=x")
18155 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18156 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18157 "TARGET_SSE2"
0f40f9f7 18158 "pnand\t{%2, %0|%0, %2}"
c679d048
JH
18159 [(set_attr "type" "sse")])
18160
18161(define_insn "*sse_iorti3_df_1"
18162 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18163 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18164 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18165 "TARGET_SSE2"
0f40f9f7 18166 "orpd\t{%2, %0|%0, %2}"
c679d048
JH
18167 [(set_attr "type" "sse")])
18168
18169(define_insn "*sse_iorti3_df_2"
18170 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18171 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18172 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18173 "TARGET_SSE2"
0f40f9f7 18174 "orpd\t{%2, %0|%0, %2}"
c679d048
JH
18175 [(set_attr "type" "sse")])
18176
18177(define_insn "*sse_iorti3_sf_1"
18178 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18179 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18180 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18181 "TARGET_SSE"
0f40f9f7 18182 "orps\t{%2, %0|%0, %2}"
c679d048
JH
18183 [(set_attr "type" "sse")])
18184
18185(define_insn "*sse_iorti3_sf_2"
18186 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18187 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18188 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18189 "TARGET_SSE"
0f40f9f7 18190 "orps\t{%2, %0|%0, %2}"
c679d048
JH
18191 [(set_attr "type" "sse")])
18192
915119a5
BS
18193(define_insn "sse_iorti3"
18194 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048
JH
18195 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18196 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18197 "TARGET_SSE && !TARGET_SSE2"
0f40f9f7 18198 "orps\t{%2, %0|%0, %2}"
c679d048
JH
18199 [(set_attr "type" "sse")])
18200
18201(define_insn "*sse_iorti3_sse2"
18202 [(set (match_operand:TI 0 "register_operand" "=x")
18203 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18204 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18205 "TARGET_SSE2"
0f40f9f7 18206 "por\t{%2, %0|%0, %2}"
c679d048
JH
18207 [(set_attr "type" "sse")])
18208
18209(define_insn "*sse_xorti3_df_1"
18210 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18211 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18212 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18213 "TARGET_SSE2"
0f40f9f7 18214 "xorpd\t{%2, %0|%0, %2}"
c679d048
JH
18215 [(set_attr "type" "sse")])
18216
18217(define_insn "*sse_xorti3_df_2"
18218 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18219 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18220 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18221 "TARGET_SSE2"
0f40f9f7 18222 "xorpd\t{%2, %0|%0, %2}"
c679d048
JH
18223 [(set_attr "type" "sse")])
18224
18225(define_insn "*sse_xorti3_sf_1"
18226 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18227 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18228 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18229 "TARGET_SSE"
0f40f9f7 18230 "xorps\t{%2, %0|%0, %2}"
c679d048
JH
18231 [(set_attr "type" "sse")])
18232
18233(define_insn "*sse_xorti3_sf_2"
18234 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18235 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
915119a5
BS
18236 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18237 "TARGET_SSE"
0f40f9f7 18238 "xorps\t{%2, %0|%0, %2}"
915119a5
BS
18239 [(set_attr "type" "sse")])
18240
18241(define_insn "sse_xorti3"
18242 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048 18243 (xor:TI (match_operand:TI 1 "register_operand" "%0")
915119a5 18244 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 18245 "TARGET_SSE && !TARGET_SSE2"
0f40f9f7 18246 "xorps\t{%2, %0|%0, %2}"
915119a5
BS
18247 [(set_attr "type" "sse")])
18248
c679d048
JH
18249(define_insn "*sse_xorti3_sse2"
18250 [(set (match_operand:TI 0 "register_operand" "=x")
18251 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18252 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18253 "TARGET_SSE2"
0f40f9f7 18254 "pxor\t{%2, %0|%0, %2}"
c679d048
JH
18255 [(set_attr "type" "sse")])
18256
915119a5
BS
18257;; Use xor, but don't show input operands so they aren't live before
18258;; this insn.
18259(define_insn "sse_clrti"
18260 [(set (match_operand:TI 0 "register_operand" "=x")
18261 (unspec:TI [(const_int 0)] 45))]
18262 "TARGET_SSE"
0f40f9f7 18263 "xorps\t{%0, %0|%0, %0}"
915119a5
BS
18264 [(set_attr "type" "sse")])
18265
18266
18267;; SSE mask-generating compares
18268
18269(define_insn "maskcmpv4sf3"
18270 [(set (match_operand:V4SI 0 "register_operand" "=x")
18271 (match_operator:V4SI 3 "sse_comparison_operator"
18272 [(match_operand:V4SF 1 "register_operand" "0")
18273 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
18274 "TARGET_SSE"
0f40f9f7 18275 "cmp%D3ps\t{%2, %0|%0, %2}"
915119a5
BS
18276 [(set_attr "type" "sse")])
18277
18278(define_insn "maskncmpv4sf3"
18279 [(set (match_operand:V4SI 0 "register_operand" "=x")
18280 (not:V4SI
18281 (match_operator:V4SI 3 "sse_comparison_operator"
18282 [(match_operand:V4SF 1 "register_operand" "0")
18283 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
18284 "TARGET_SSE"
0f40f9f7 18285 "cmpn%D3ps\t{%2, %0|%0, %2}"
915119a5
BS
18286 [(set_attr "type" "sse")])
18287
18288(define_insn "vmmaskcmpv4sf3"
18289 [(set (match_operand:V4SI 0 "register_operand" "=x")
18290 (vec_merge:V4SI
18291 (match_operator:V4SI 3 "sse_comparison_operator"
18292 [(match_operand:V4SF 1 "register_operand" "0")
18293 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
18294 (match_dup 1)
18295 (const_int 1)))]
18296 "TARGET_SSE"
0f40f9f7 18297 "cmp%D3ss\t{%2, %0|%0, %2}"
915119a5
BS
18298 [(set_attr "type" "sse")])
18299
18300(define_insn "vmmaskncmpv4sf3"
18301 [(set (match_operand:V4SI 0 "register_operand" "=x")
18302 (vec_merge:V4SI
18303 (not:V4SI
18304 (match_operator:V4SI 3 "sse_comparison_operator"
18305 [(match_operand:V4SF 1 "register_operand" "0")
18306 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
18307 (subreg:V4SI (match_dup 1) 0)
18308 (const_int 1)))]
18309 "TARGET_SSE"
0f40f9f7 18310 "cmp%D3ss\t{%2, %0|%0, %2}"
915119a5
BS
18311 [(set_attr "type" "sse")])
18312
18313(define_insn "sse_comi"
18314 [(set (reg:CCFP 17)
18315 (match_operator:CCFP 2 "sse_comparison_operator"
18316 [(vec_select:SF
18317 (match_operand:V4SF 0 "register_operand" "x")
18318 (parallel [(const_int 0)]))
18319 (vec_select:SF
18320 (match_operand:V4SF 1 "register_operand" "x")
18321 (parallel [(const_int 0)]))]))]
18322 "TARGET_SSE"
21e1b5f1 18323 "comiss\t{%1, %0|%0, %1}"
915119a5
BS
18324 [(set_attr "type" "sse")])
18325
18326(define_insn "sse_ucomi"
18327 [(set (reg:CCFPU 17)
18328 (match_operator:CCFPU 2 "sse_comparison_operator"
18329 [(vec_select:SF
18330 (match_operand:V4SF 0 "register_operand" "x")
18331 (parallel [(const_int 0)]))
18332 (vec_select:SF
18333 (match_operand:V4SF 1 "register_operand" "x")
18334 (parallel [(const_int 0)]))]))]
18335 "TARGET_SSE"
21e1b5f1 18336 "ucomiss\t{%1, %0|%0, %1}"
915119a5
BS
18337 [(set_attr "type" "sse")])
18338
18339
18340;; SSE unpack
18341
18342(define_insn "sse_unpckhps"
18343 [(set (match_operand:V4SF 0 "register_operand" "=x")
18344 (vec_merge:V4SF
18345 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18346 (parallel [(const_int 2)
18347 (const_int 0)
18348 (const_int 3)
18349 (const_int 1)]))
21e1b5f1 18350 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
915119a5
BS
18351 (parallel [(const_int 0)
18352 (const_int 2)
18353 (const_int 1)
18354 (const_int 3)]))
18355 (const_int 5)))]
18356 "TARGET_SSE"
0f40f9f7 18357 "unpckhps\t{%2, %0|%0, %2}"
915119a5
BS
18358 [(set_attr "type" "sse")])
18359
18360(define_insn "sse_unpcklps"
18361 [(set (match_operand:V4SF 0 "register_operand" "=x")
18362 (vec_merge:V4SF
18363 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18364 (parallel [(const_int 0)
18365 (const_int 2)
18366 (const_int 1)
18367 (const_int 3)]))
21e1b5f1 18368 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
915119a5
BS
18369 (parallel [(const_int 2)
18370 (const_int 0)
18371 (const_int 3)
18372 (const_int 1)]))
18373 (const_int 5)))]
18374 "TARGET_SSE"
0f40f9f7 18375 "unpcklps\t{%2, %0|%0, %2}"
915119a5
BS
18376 [(set_attr "type" "sse")])
18377
18378
18379;; SSE min/max
18380
18381(define_insn "smaxv4sf3"
18382 [(set (match_operand:V4SF 0 "register_operand" "=x")
18383 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18384 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18385 "TARGET_SSE"
0f40f9f7 18386 "maxps\t{%2, %0|%0, %2}"
915119a5
BS
18387 [(set_attr "type" "sse")])
18388
18389(define_insn "vmsmaxv4sf3"
18390 [(set (match_operand:V4SF 0 "register_operand" "=x")
18391 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18392 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18393 (match_dup 1)
18394 (const_int 1)))]
18395 "TARGET_SSE"
0f40f9f7 18396 "maxss\t{%2, %0|%0, %2}"
915119a5
BS
18397 [(set_attr "type" "sse")])
18398
18399(define_insn "sminv4sf3"
18400 [(set (match_operand:V4SF 0 "register_operand" "=x")
18401 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18402 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18403 "TARGET_SSE"
0f40f9f7 18404 "minps\t{%2, %0|%0, %2}"
915119a5
BS
18405 [(set_attr "type" "sse")])
18406
18407(define_insn "vmsminv4sf3"
18408 [(set (match_operand:V4SF 0 "register_operand" "=x")
18409 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18410 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18411 (match_dup 1)
18412 (const_int 1)))]
18413 "TARGET_SSE"
0f40f9f7 18414 "minss\t{%2, %0|%0, %2}"
915119a5
BS
18415 [(set_attr "type" "sse")])
18416
18417
18418;; SSE <-> integer/MMX conversions
18419
18420(define_insn "cvtpi2ps"
18421 [(set (match_operand:V4SF 0 "register_operand" "=x")
18422 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18423 (vec_duplicate:V4SF
18424 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
18425 (const_int 12)))]
18426 "TARGET_SSE"
0f40f9f7 18427 "cvtpi2ps\t{%2, %0|%0, %2}"
915119a5
BS
18428 [(set_attr "type" "sse")])
18429
18430(define_insn "cvtps2pi"
18431 [(set (match_operand:V2SI 0 "register_operand" "=y")
18432 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18433 (parallel
18434 [(const_int 0)
18435 (const_int 1)])))]
18436 "TARGET_SSE"
0f40f9f7 18437 "cvtps2pi\t{%1, %0|%0, %1}"
915119a5
BS
18438 [(set_attr "type" "sse")])
18439
18440(define_insn "cvttps2pi"
18441 [(set (match_operand:V2SI 0 "register_operand" "=y")
18442 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18443 (parallel
18444 [(const_int 0)
18445 (const_int 1)])))]
18446 "TARGET_SSE"
0f40f9f7 18447 "cvttps2pi\t{%1, %0|%0, %1}"
915119a5
BS
18448 [(set_attr "type" "sse")])
18449
18450(define_insn "cvtsi2ss"
18451 [(set (match_operand:V4SF 0 "register_operand" "=x")
18452 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18453 (vec_duplicate:V4SF
18454 (float:SF (match_operand:SI 2 "register_operand" "rm")))
18455 (const_int 15)))]
18456 "TARGET_SSE"
0f40f9f7 18457 "cvtsi2ss\t{%2, %0|%0, %2}"
915119a5
BS
18458 [(set_attr "type" "sse")])
18459
18460(define_insn "cvtss2si"
21e1b5f1 18461 [(set (match_operand:SI 0 "register_operand" "=r")
915119a5
BS
18462 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18463 (parallel [(const_int 0)])))]
18464 "TARGET_SSE"
0f40f9f7 18465 "cvtss2si\t{%1, %0|%0, %1}"
915119a5
BS
18466 [(set_attr "type" "sse")])
18467
18468(define_insn "cvttss2si"
21e1b5f1 18469 [(set (match_operand:SI 0 "register_operand" "=r")
915119a5
BS
18470 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18471 (parallel [(const_int 0)])))]
18472 "TARGET_SSE"
0f40f9f7 18473 "cvttss2si\t{%1, %0|%0, %1}"
915119a5
BS
18474 [(set_attr "type" "sse")])
18475
18476
18477;; MMX insns
18478
18479;; MMX arithmetic
18480
18481(define_insn "addv8qi3"
18482 [(set (match_operand:V8QI 0 "register_operand" "=y")
18483 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18484 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18485 "TARGET_MMX"
0f40f9f7 18486 "paddb\t{%2, %0|%0, %2}"
915119a5
BS
18487 [(set_attr "type" "mmx")])
18488
18489(define_insn "addv4hi3"
18490 [(set (match_operand:V4HI 0 "register_operand" "=y")
18491 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18492 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18493 "TARGET_MMX"
0f40f9f7 18494 "paddw\t{%2, %0|%0, %2}"
915119a5
BS
18495 [(set_attr "type" "mmx")])
18496
18497(define_insn "addv2si3"
18498 [(set (match_operand:V2SI 0 "register_operand" "=y")
18499 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18500 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18501 "TARGET_MMX"
0f40f9f7 18502 "paddd\t{%2, %0|%0, %2}"
915119a5
BS
18503 [(set_attr "type" "mmx")])
18504
18505(define_insn "ssaddv8qi3"
18506 [(set (match_operand:V8QI 0 "register_operand" "=y")
18507 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18508 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18509 "TARGET_MMX"
0f40f9f7 18510 "paddsb\t{%2, %0|%0, %2}"
915119a5
BS
18511 [(set_attr "type" "mmx")])
18512
18513(define_insn "ssaddv4hi3"
18514 [(set (match_operand:V4HI 0 "register_operand" "=y")
18515 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18516 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18517 "TARGET_MMX"
0f40f9f7 18518 "paddsw\t{%2, %0|%0, %2}"
915119a5
BS
18519 [(set_attr "type" "mmx")])
18520
18521(define_insn "usaddv8qi3"
18522 [(set (match_operand:V8QI 0 "register_operand" "=y")
18523 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18524 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18525 "TARGET_MMX"
0f40f9f7 18526 "paddusb\t{%2, %0|%0, %2}"
915119a5
BS
18527 [(set_attr "type" "mmx")])
18528
18529(define_insn "usaddv4hi3"
18530 [(set (match_operand:V4HI 0 "register_operand" "=y")
18531 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18532 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18533 "TARGET_MMX"
0f40f9f7 18534 "paddusw\t{%2, %0|%0, %2}"
915119a5
BS
18535 [(set_attr "type" "mmx")])
18536
18537(define_insn "subv8qi3"
18538 [(set (match_operand:V8QI 0 "register_operand" "=y")
18539 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18540 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18541 "TARGET_MMX"
0f40f9f7 18542 "psubb\t{%2, %0|%0, %2}"
915119a5
BS
18543 [(set_attr "type" "mmx")])
18544
18545(define_insn "subv4hi3"
18546 [(set (match_operand:V4HI 0 "register_operand" "=y")
18547 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18548 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18549 "TARGET_MMX"
0f40f9f7 18550 "psubw\t{%2, %0|%0, %2}"
915119a5
BS
18551 [(set_attr "type" "mmx")])
18552
18553(define_insn "subv2si3"
18554 [(set (match_operand:V2SI 0 "register_operand" "=y")
18555 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18556 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18557 "TARGET_MMX"
0f40f9f7 18558 "psubd\t{%2, %0|%0, %2}"
915119a5
BS
18559 [(set_attr "type" "mmx")])
18560
18561(define_insn "sssubv8qi3"
18562 [(set (match_operand:V8QI 0 "register_operand" "=y")
18563 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18564 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18565 "TARGET_MMX"
0f40f9f7 18566 "psubsb\t{%2, %0|%0, %2}"
915119a5
BS
18567 [(set_attr "type" "mmx")])
18568
18569(define_insn "sssubv4hi3"
18570 [(set (match_operand:V4HI 0 "register_operand" "=y")
18571 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18572 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18573 "TARGET_MMX"
0f40f9f7 18574 "psubsw\t{%2, %0|%0, %2}"
915119a5
BS
18575 [(set_attr "type" "mmx")])
18576
18577(define_insn "ussubv8qi3"
18578 [(set (match_operand:V8QI 0 "register_operand" "=y")
18579 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18580 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18581 "TARGET_MMX"
0f40f9f7 18582 "psubusb\t{%2, %0|%0, %2}"
915119a5
BS
18583 [(set_attr "type" "mmx")])
18584
18585(define_insn "ussubv4hi3"
18586 [(set (match_operand:V4HI 0 "register_operand" "=y")
18587 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18588 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18589 "TARGET_MMX"
0f40f9f7 18590 "psubusw\t{%2, %0|%0, %2}"
915119a5
BS
18591 [(set_attr "type" "mmx")])
18592
18593(define_insn "mulv4hi3"
18594 [(set (match_operand:V4HI 0 "register_operand" "=y")
18595 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18596 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18597 "TARGET_MMX"
0f40f9f7 18598 "pmullw\t{%2, %0|%0, %2}"
915119a5
BS
18599 [(set_attr "type" "mmx")])
18600
18601(define_insn "smulv4hi3_highpart"
18602 [(set (match_operand:V4HI 0 "register_operand" "=y")
18603 (truncate:V4HI
18604 (lshiftrt:V4SI
18605 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18606 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18607 (const_int 16))))]
18608 "TARGET_MMX"
0f40f9f7 18609 "pmulhw\t{%2, %0|%0, %2}"
915119a5
BS
18610 [(set_attr "type" "mmx")])
18611
18612(define_insn "umulv4hi3_highpart"
18613 [(set (match_operand:V4HI 0 "register_operand" "=y")
18614 (truncate:V4HI
18615 (lshiftrt:V4SI
18616 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18617 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18618 (const_int 16))))]
47f339cf 18619 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18620 "pmulhuw\t{%2, %0|%0, %2}"
915119a5
BS
18621 [(set_attr "type" "mmx")])
18622
18623(define_insn "mmx_pmaddwd"
18624 [(set (match_operand:V2SI 0 "register_operand" "=y")
18625 (plus:V2SI
18626 (mult:V2SI
18627 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18628 (parallel [(const_int 0)
18629 (const_int 2)])))
18630 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18631 (parallel [(const_int 0)
18632 (const_int 2)]))))
18633 (mult:V2SI
18634 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18635 (parallel [(const_int 1)
18636 (const_int 3)])))
18637 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18638 (parallel [(const_int 1)
18639 (const_int 3)]))))))]
18640 "TARGET_MMX"
0f40f9f7 18641 "pmaddwd\t{%2, %0|%0, %2}"
915119a5
BS
18642 [(set_attr "type" "mmx")])
18643
18644
18645;; MMX logical operations
18646;; Note we don't want to declare these as regular iordi3 insns to prevent
18647;; normal code that also wants to use the FPU from getting broken.
18648;; The UNSPECs are there to prevent the combiner from getting overly clever.
18649(define_insn "mmx_iordi3"
18650 [(set (match_operand:DI 0 "register_operand" "=y")
18651 (unspec:DI
18652 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18653 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18654 "TARGET_MMX"
0f40f9f7 18655 "por\t{%2, %0|%0, %2}"
915119a5
BS
18656 [(set_attr "type" "mmx")])
18657
18658(define_insn "mmx_xordi3"
18659 [(set (match_operand:DI 0 "register_operand" "=y")
18660 (unspec:DI
18661 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18662 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18663 "TARGET_MMX"
0f40f9f7 18664 "pxor\t{%2, %0|%0, %2}"
915119a5
BS
18665 [(set_attr "type" "mmx")])
18666
18667;; Same as pxor, but don't show input operands so that we don't think
18668;; they are live.
18669(define_insn "mmx_clrdi"
18670 [(set (match_operand:DI 0 "register_operand" "=y")
18671 (unspec:DI [(const_int 0)] 45))]
18672 "TARGET_MMX"
0f40f9f7 18673 "pxor\t{%0, %0|%0, %0}"
915119a5
BS
18674 [(set_attr "type" "mmx")])
18675
18676(define_insn "mmx_anddi3"
18677 [(set (match_operand:DI 0 "register_operand" "=y")
18678 (unspec:DI
18679 [(and:DI (match_operand:DI 1 "register_operand" "0")
18680 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18681 "TARGET_MMX"
0f40f9f7 18682 "pand\t{%2, %0|%0, %2}"
915119a5
BS
18683 [(set_attr "type" "mmx")])
18684
18685(define_insn "mmx_nanddi3"
18686 [(set (match_operand:DI 0 "register_operand" "=y")
18687 (unspec:DI
18688 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18689 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18690 "TARGET_MMX"
0f40f9f7 18691 "pandn\t{%2, %0|%0, %2}"
915119a5
BS
18692 [(set_attr "type" "mmx")])
18693
18694
18695;; MMX unsigned averages/sum of absolute differences
18696
18697(define_insn "mmx_uavgv8qi3"
18698 [(set (match_operand:V8QI 0 "register_operand" "=y")
18699 (ashiftrt:V8QI
18700 (plus:V8QI (plus:V8QI
18701 (match_operand:V8QI 1 "register_operand" "0")
18702 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18703 (vec_const:V8QI (parallel [(const_int 1)
18704 (const_int 1)
18705 (const_int 1)
18706 (const_int 1)
18707 (const_int 1)
18708 (const_int 1)
18709 (const_int 1)
18710 (const_int 1)])))
18711 (const_int 1)))]
47f339cf 18712 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18713 "pavgb\t{%2, %0|%0, %2}"
915119a5
BS
18714 [(set_attr "type" "sse")])
18715
18716(define_insn "mmx_uavgv4hi3"
18717 [(set (match_operand:V4HI 0 "register_operand" "=y")
18718 (ashiftrt:V4HI
18719 (plus:V4HI (plus:V4HI
18720 (match_operand:V4HI 1 "register_operand" "0")
18721 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18722 (vec_const:V4HI (parallel [(const_int 1)
18723 (const_int 1)
18724 (const_int 1)
18725 (const_int 1)])))
18726 (const_int 1)))]
47f339cf 18727 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18728 "pavgw\t{%2, %0|%0, %2}"
915119a5
BS
18729 [(set_attr "type" "sse")])
18730
18731(define_insn "mmx_psadbw"
18732 [(set (match_operand:V8QI 0 "register_operand" "=y")
332316cd
BS
18733 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18734 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
47f339cf 18735 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18736 "psadbw\t{%2, %0|%0, %2}"
915119a5
BS
18737 [(set_attr "type" "sse")])
18738
18739
18740;; MMX insert/extract/shuffle
18741
18742(define_insn "mmx_pinsrw"
18743 [(set (match_operand:V4HI 0 "register_operand" "=y")
18744 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18745 (vec_duplicate:V4HI
18746 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18747 (match_operand:SI 3 "immediate_operand" "i")))]
47f339cf 18748 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18749 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
915119a5
BS
18750 [(set_attr "type" "sse")])
18751
18752(define_insn "mmx_pextrw"
18753 [(set (match_operand:SI 0 "register_operand" "=r")
18754 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18755 (parallel
18756 [(match_operand:SI 2 "immediate_operand" "i")]))))]
47f339cf 18757 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18758 "pextrw\t{%2, %1, %0|%0, %1, %2}"
915119a5
BS
18759 [(set_attr "type" "sse")])
18760
18761(define_insn "mmx_pshufw"
18762 [(set (match_operand:V4HI 0 "register_operand" "=y")
18763 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18764 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18765 (match_operand:SI 3 "immediate_operand" "i")] 41))]
47f339cf 18766 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18767 "pshufw\t{%3, %2, %0|%0, %2, %3}"
915119a5
BS
18768 [(set_attr "type" "sse")])
18769
18770
18771;; MMX mask-generating comparisons
18772
18773(define_insn "eqv8qi3"
18774 [(set (match_operand:V8QI 0 "register_operand" "=y")
18775 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18776 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18777 "TARGET_MMX"
0f40f9f7 18778 "pcmpeqb\t{%2, %0|%0, %2}"
915119a5
BS
18779 [(set_attr "type" "mmx")])
18780
18781(define_insn "eqv4hi3"
18782 [(set (match_operand:V4HI 0 "register_operand" "=y")
18783 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18784 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18785 "TARGET_MMX"
0f40f9f7 18786 "pcmpeqw\t{%2, %0|%0, %2}"
915119a5
BS
18787 [(set_attr "type" "mmx")])
18788
18789(define_insn "eqv2si3"
18790 [(set (match_operand:V2SI 0 "register_operand" "=y")
18791 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18792 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18793 "TARGET_MMX"
0f40f9f7 18794 "pcmpeqd\t{%2, %0|%0, %2}"
915119a5
BS
18795 [(set_attr "type" "mmx")])
18796
18797(define_insn "gtv8qi3"
18798 [(set (match_operand:V8QI 0 "register_operand" "=y")
18799 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18800 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18801 "TARGET_MMX"
0f40f9f7 18802 "pcmpgtb\t{%2, %0|%0, %2}"
915119a5
BS
18803 [(set_attr "type" "mmx")])
18804
18805(define_insn "gtv4hi3"
18806 [(set (match_operand:V4HI 0 "register_operand" "=y")
18807 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18808 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18809 "TARGET_MMX"
0f40f9f7 18810 "pcmpgtw\t{%2, %0|%0, %2}"
915119a5
BS
18811 [(set_attr "type" "mmx")])
18812
18813(define_insn "gtv2si3"
18814 [(set (match_operand:V2SI 0 "register_operand" "=y")
18815 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18816 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18817 "TARGET_MMX"
0f40f9f7 18818 "pcmpgtd\t{%2, %0|%0, %2}"
915119a5
BS
18819 [(set_attr "type" "mmx")])
18820
18821
18822;; MMX max/min insns
18823
18824(define_insn "umaxv8qi3"
18825 [(set (match_operand:V8QI 0 "register_operand" "=y")
18826 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18827 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
47f339cf 18828 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18829 "pmaxub\t{%2, %0|%0, %2}"
915119a5
BS
18830 [(set_attr "type" "sse")])
18831
18832(define_insn "smaxv4hi3"
18833 [(set (match_operand:V4HI 0 "register_operand" "=y")
18834 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18835 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
47f339cf 18836 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18837 "pmaxsw\t{%2, %0|%0, %2}"
915119a5
BS
18838 [(set_attr "type" "sse")])
18839
18840(define_insn "uminv8qi3"
18841 [(set (match_operand:V8QI 0 "register_operand" "=y")
18842 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18843 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
47f339cf 18844 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18845 "pminub\t{%2, %0|%0, %2}"
915119a5
BS
18846 [(set_attr "type" "sse")])
18847
18848(define_insn "sminv4hi3"
18849 [(set (match_operand:V4HI 0 "register_operand" "=y")
18850 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18851 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
47f339cf 18852 "TARGET_SSE || TARGET_3DNOW_A"
0f40f9f7 18853 "pminsw\t{%2, %0|%0, %2}"
915119a5
BS
18854 [(set_attr "type" "sse")])
18855
18856
18857;; MMX shifts
18858
18859(define_insn "ashrv4hi3"
18860 [(set (match_operand:V4HI 0 "register_operand" "=y")
18861 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18862 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18863 "TARGET_MMX"
0f40f9f7 18864 "psraw\t{%2, %0|%0, %2}"
915119a5
BS
18865 [(set_attr "type" "mmx")])
18866
18867(define_insn "ashrv2si3"
18868 [(set (match_operand:V2SI 0 "register_operand" "=y")
18869 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18870 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18871 "TARGET_MMX"
0f40f9f7 18872 "psrad\t{%2, %0|%0, %2}"
915119a5
BS
18873 [(set_attr "type" "mmx")])
18874
18875(define_insn "lshrv4hi3"
18876 [(set (match_operand:V4HI 0 "register_operand" "=y")
18877 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18878 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18879 "TARGET_MMX"
0f40f9f7 18880 "psrlw\t{%2, %0|%0, %2}"
915119a5
BS
18881 [(set_attr "type" "mmx")])
18882
18883(define_insn "lshrv2si3"
18884 [(set (match_operand:V2SI 0 "register_operand" "=y")
18885 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18886 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18887 "TARGET_MMX"
0f40f9f7 18888 "psrld\t{%2, %0|%0, %2}"
915119a5
BS
18889 [(set_attr "type" "mmx")])
18890
18891;; See logical MMX insns.
18892(define_insn "mmx_lshrdi3"
18893 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
18894 (unspec:DI
18895 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
18896 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
915119a5 18897 "TARGET_MMX"
0f40f9f7 18898 "psrlq\t{%2, %0|%0, %2}"
915119a5
BS
18899 [(set_attr "type" "mmx")])
18900
18901(define_insn "ashlv4hi3"
18902 [(set (match_operand:V4HI 0 "register_operand" "=y")
18903 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
18904 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18905 "TARGET_MMX"
0f40f9f7 18906 "psllw\t{%2, %0|%0, %2}"
915119a5
BS
18907 [(set_attr "type" "mmx")])
18908
18909(define_insn "ashlv2si3"
18910 [(set (match_operand:V2SI 0 "register_operand" "=y")
18911 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
18912 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18913 "TARGET_MMX"
0f40f9f7 18914 "pslld\t{%2, %0|%0, %2}"
915119a5
BS
18915 [(set_attr "type" "mmx")])
18916
18917;; See logical MMX insns.
18918(define_insn "mmx_ashldi3"
18919 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
18920 (unspec:DI
18921 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
18922 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
915119a5 18923 "TARGET_MMX"
0f40f9f7 18924 "psllq\t{%2, %0|%0, %2}"
915119a5
BS
18925 [(set_attr "type" "mmx")])
18926
18927
18928;; MMX pack/unpack insns.
18929
18930(define_insn "mmx_packsswb"
18931 [(set (match_operand:V8QI 0 "register_operand" "=y")
18932 (vec_concat:V8QI
18933 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18934 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18935 "TARGET_MMX"
0f40f9f7 18936 "packsswb\t{%2, %0|%0, %2}"
915119a5
BS
18937 [(set_attr "type" "mmx")])
18938
18939(define_insn "mmx_packssdw"
18940 [(set (match_operand:V4HI 0 "register_operand" "=y")
18941 (vec_concat:V4HI
18942 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
18943 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
18944 "TARGET_MMX"
0f40f9f7 18945 "packssdw\t{%2, %0|%0, %2}"
915119a5
BS
18946 [(set_attr "type" "mmx")])
18947
18948(define_insn "mmx_packuswb"
18949 [(set (match_operand:V8QI 0 "register_operand" "=y")
18950 (vec_concat:V8QI
18951 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18952 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18953 "TARGET_MMX"
0f40f9f7 18954 "packuswb\t{%2, %0|%0, %2}"
915119a5
BS
18955 [(set_attr "type" "mmx")])
18956
18957(define_insn "mmx_punpckhbw"
18958 [(set (match_operand:V8QI 0 "register_operand" "=y")
18959 (vec_merge:V8QI
18960 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
18961 (parallel [(const_int 4)
18962 (const_int 0)
18963 (const_int 5)
18964 (const_int 1)
18965 (const_int 6)
18966 (const_int 2)
18967 (const_int 7)
18968 (const_int 3)]))
18969 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
18970 (parallel [(const_int 0)
18971 (const_int 4)
18972 (const_int 1)
18973 (const_int 5)
18974 (const_int 2)
18975 (const_int 6)
18976 (const_int 3)
18977 (const_int 7)]))
18978 (const_int 85)))]
18979 "TARGET_MMX"
0f40f9f7 18980 "punpckhbw\t{%2, %0|%0, %2}"
915119a5
BS
18981 [(set_attr "type" "mmx")])
18982
18983(define_insn "mmx_punpckhwd"
18984 [(set (match_operand:V4HI 0 "register_operand" "=y")
18985 (vec_merge:V4HI
18986 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
18987 (parallel [(const_int 0)
18988 (const_int 2)
18989 (const_int 1)
18990 (const_int 3)]))
18991 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
18992 (parallel [(const_int 2)
18993 (const_int 0)
18994 (const_int 3)
18995 (const_int 1)]))
18996 (const_int 5)))]
18997 "TARGET_MMX"
0f40f9f7 18998 "punpckhwd\t{%2, %0|%0, %2}"
915119a5
BS
18999 [(set_attr "type" "mmx")])
19000
19001(define_insn "mmx_punpckhdq"
19002 [(set (match_operand:V2SI 0 "register_operand" "=y")
19003 (vec_merge:V2SI
19004 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19005 (parallel [(const_int 0)
19006 (const_int 1)]))
19007 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19008 (parallel [(const_int 1)
19009 (const_int 0)]))
19010 (const_int 1)))]
19011 "TARGET_MMX"
0f40f9f7 19012 "punpckhdq\t{%2, %0|%0, %2}"
915119a5
BS
19013 [(set_attr "type" "mmx")])
19014
19015(define_insn "mmx_punpcklbw"
19016 [(set (match_operand:V8QI 0 "register_operand" "=y")
19017 (vec_merge:V8QI
19018 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19019 (parallel [(const_int 0)
19020 (const_int 4)
19021 (const_int 1)
19022 (const_int 5)
19023 (const_int 2)
19024 (const_int 6)
19025 (const_int 3)
19026 (const_int 7)]))
19027 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19028 (parallel [(const_int 4)
19029 (const_int 0)
19030 (const_int 5)
19031 (const_int 1)
19032 (const_int 6)
19033 (const_int 2)
19034 (const_int 7)
19035 (const_int 3)]))
19036 (const_int 85)))]
19037 "TARGET_MMX"
0f40f9f7 19038 "punpcklbw\t{%2, %0|%0, %2}"
915119a5
BS
19039 [(set_attr "type" "mmx")])
19040
19041(define_insn "mmx_punpcklwd"
19042 [(set (match_operand:V4HI 0 "register_operand" "=y")
19043 (vec_merge:V4HI
19044 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19045 (parallel [(const_int 2)
19046 (const_int 0)
19047 (const_int 3)
19048 (const_int 1)]))
19049 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19050 (parallel [(const_int 0)
19051 (const_int 2)
19052 (const_int 1)
19053 (const_int 3)]))
19054 (const_int 5)))]
19055 "TARGET_MMX"
0f40f9f7 19056 "punpcklwd\t{%2, %0|%0, %2}"
915119a5
BS
19057 [(set_attr "type" "mmx")])
19058
19059(define_insn "mmx_punpckldq"
19060 [(set (match_operand:V2SI 0 "register_operand" "=y")
19061 (vec_merge:V2SI
19062 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19063 (parallel [(const_int 1)
19064 (const_int 0)]))
19065 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19066 (parallel [(const_int 0)
19067 (const_int 1)]))
19068 (const_int 1)))]
19069 "TARGET_MMX"
0f40f9f7 19070 "punpckldq\t{%2, %0|%0, %2}"
915119a5
BS
19071 [(set_attr "type" "mmx")])
19072
19073
19074;; Miscellaneous stuff
19075
19076(define_insn "emms"
19077 [(unspec_volatile [(const_int 0)] 31)
19078 (clobber (reg:XF 8))
19079 (clobber (reg:XF 9))
19080 (clobber (reg:XF 10))
19081 (clobber (reg:XF 11))
19082 (clobber (reg:XF 12))
19083 (clobber (reg:XF 13))
19084 (clobber (reg:XF 14))
19085 (clobber (reg:XF 15))
915119a5
BS
19086 (clobber (reg:DI 29))
19087 (clobber (reg:DI 30))
19088 (clobber (reg:DI 31))
19089 (clobber (reg:DI 32))
19090 (clobber (reg:DI 33))
bd793c65
BS
19091 (clobber (reg:DI 34))
19092 (clobber (reg:DI 35))
19093 (clobber (reg:DI 36))]
915119a5
BS
19094 "TARGET_MMX"
19095 "emms"
bd793c65
BS
19096 [(set_attr "type" "mmx")
19097 (set_attr "memory" "unknown")])
915119a5
BS
19098
19099(define_insn "ldmxcsr"
19100 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19101 "TARGET_MMX"
0f40f9f7 19102 "ldmxcsr\t%0"
915119a5
BS
19103 [(set_attr "type" "mmx")])
19104
19105(define_insn "stmxcsr"
19106 [(set (match_operand:SI 0 "memory_operand" "=m")
19107 (unspec_volatile:SI [(const_int 0)] 40))]
19108 "TARGET_MMX"
0f40f9f7 19109 "stmxcsr\t%0"
915119a5
BS
19110 [(set_attr "type" "mmx")])
19111
19112(define_expand "sfence"
19113 [(set (match_dup 0)
19114 (unspec:BLK [(match_dup 0)] 44))]
47f339cf 19115 "TARGET_SSE || TARGET_3DNOW_A"
915119a5
BS
19116{
19117 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19118 MEM_VOLATILE_P (operands[0]) = 1;
0f40f9f7 19119})
915119a5
BS
19120
19121(define_insn "*sfence_insn"
19122 [(set (match_operand:BLK 0 "" "")
19123 (unspec:BLK [(match_dup 0)] 44))]
47f339cf 19124 "TARGET_SSE || TARGET_3DNOW_A"
915119a5 19125 "sfence"
bd793c65
BS
19126 [(set_attr "type" "sse")
19127 (set_attr "memory" "unknown")])
915119a5
BS
19128
19129(define_insn "prefetch"
19130 [(unspec [(match_operand:SI 0 "address_operand" "p")
332316cd 19131 (match_operand:SI 1 "immediate_operand" "n")] 35)]
47f339cf 19132 "TARGET_SSE || TARGET_3DNOW_A"
915119a5
BS
19133{
19134 switch (INTVAL (operands[1]))
19135 {
19136 case 0:
0f40f9f7 19137 return "prefetchnta\t%a0";
915119a5 19138 case 1:
0f40f9f7 19139 return "prefetcht0\t%a0";
915119a5 19140 case 2:
0f40f9f7 19141 return "prefetcht1\t%a0";
915119a5 19142 case 3:
0f40f9f7 19143 return "prefetcht2\t%a0";
915119a5
BS
19144 default:
19145 abort ();
19146 }
0f40f9f7 19147}
915119a5
BS
19148 [(set_attr "type" "sse")])
19149
ad919812
JH
19150(define_expand "sse_prologue_save"
19151 [(parallel [(set (match_operand:BLK 0 "" "")
19152 (unspec:BLK [(reg:DI 21)
19153 (reg:DI 22)
19154 (reg:DI 23)
19155 (reg:DI 24)
19156 (reg:DI 25)
19157 (reg:DI 26)
19158 (reg:DI 27)
19159 (reg:DI 28)] 13))
19160 (use (match_operand:DI 1 "register_operand" ""))
19161 (use (match_operand:DI 2 "immediate_operand" ""))
19162 (use (label_ref:DI (match_operand 3 "" "")))])]
19163 "TARGET_64BIT"
19164 "")
19165
19166(define_insn "*sse_prologue_save_insn"
19167 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19168 (match_operand:DI 4 "const_int_operand" "n")))
19169 (unspec:BLK [(reg:DI 21)
19170 (reg:DI 22)
19171 (reg:DI 23)
19172 (reg:DI 24)
19173 (reg:DI 25)
19174 (reg:DI 26)
19175 (reg:DI 27)
19176 (reg:DI 28)] 13))
19177 (use (match_operand:DI 1 "register_operand" "r"))
19178 (use (match_operand:DI 2 "const_int_operand" "i"))
19179 (use (label_ref:DI (match_operand 3 "" "X")))]
19180 "TARGET_64BIT
19181 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19182 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19183 "*
19184{
19185 int i;
19186 operands[0] = gen_rtx_MEM (Pmode,
19187 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19188 output_asm_insn (\"jmp\\t%A1\", operands);
19189 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19190 {
19191 operands[4] = adjust_address (operands[0], DImode, i*16);
19192 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19193 PUT_MODE (operands[4], TImode);
19194 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19195 output_asm_insn (\"rex\", operands);
19196 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19197 }
19198 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19199 CODE_LABEL_NUMBER (operands[3]));
19200 RET;
19201}
19202 "
19203 [(set_attr "type" "other")
19204 (set_attr "length_immediate" "0")
19205 (set_attr "length_address" "0")
19206 (set_attr "length" "135")
19207 (set_attr "memory" "store")
19208 (set_attr "modrm" "0")
19209 (set_attr "mode" "DI")])
47f339cf
BS
19210
19211;; 3Dnow! instructions
19212
19213(define_insn "addv2sf3"
19214 [(set (match_operand:V2SF 0 "register_operand" "=y")
19215 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19216 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19217 "TARGET_3DNOW"
19218 "pfadd\\t{%2, %0|%0, %2}"
19219 [(set_attr "type" "mmx")])
19220
19221(define_insn "subv2sf3"
19222 [(set (match_operand:V2SF 0 "register_operand" "=y")
19223 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19224 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19225 "TARGET_3DNOW"
19226 "pfsub\\t{%2, %0|%0, %2}"
19227 [(set_attr "type" "mmx")])
19228
19229(define_insn "subrv2sf3"
19230 [(set (match_operand:V2SF 0 "register_operand" "=y")
19231 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19232 (match_operand:V2SF 1 "register_operand" "0")))]
19233 "TARGET_3DNOW"
19234 "pfsubr\\t{%2, %0|%0, %2}"
19235 [(set_attr "type" "mmx")])
19236
19237(define_insn "gtv2sf3"
19238 [(set (match_operand:V2SI 0 "register_operand" "=y")
19239 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19240 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19241 "TARGET_3DNOW"
19242 "pfcmpgt\\t{%2, %0|%0, %2}"
19243 [(set_attr "type" "mmx")])
19244
19245(define_insn "gev2sf3"
19246 [(set (match_operand:V2SI 0 "register_operand" "=y")
19247 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19248 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19249 "TARGET_3DNOW"
19250 "pfcmpge\\t{%2, %0|%0, %2}"
19251 [(set_attr "type" "mmx")])
19252
19253(define_insn "eqv2sf3"
19254 [(set (match_operand:V2SI 0 "register_operand" "=y")
19255 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19256 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19257 "TARGET_3DNOW"
19258 "pfcmpeq\\t{%2, %0|%0, %2}"
19259 [(set_attr "type" "mmx")])
19260
19261(define_insn "pfmaxv2sf3"
19262 [(set (match_operand:V2SF 0 "register_operand" "=y")
19263 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19264 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19265 "TARGET_3DNOW"
19266 "pfmax\\t{%2, %0|%0, %2}"
19267 [(set_attr "type" "mmx")])
19268
19269(define_insn "pfminv2sf3"
19270 [(set (match_operand:V2SF 0 "register_operand" "=y")
19271 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19272 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19273 "TARGET_3DNOW"
19274 "pfmin\\t{%2, %0|%0, %2}"
19275 [(set_attr "type" "mmx")])
19276
19277(define_insn "mulv2sf3"
19278 [(set (match_operand:V2SF 0 "register_operand" "=y")
19279 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19280 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19281 "TARGET_3DNOW"
19282 "pfmul\\t{%2, %0|%0, %2}"
19283 [(set_attr "type" "mmx")])
19284
19285(define_insn "femms"
19286 [(unspec_volatile [(const_int 0)] 46)
19287 (clobber (reg:XF 8))
19288 (clobber (reg:XF 9))
19289 (clobber (reg:XF 10))
19290 (clobber (reg:XF 11))
19291 (clobber (reg:XF 12))
19292 (clobber (reg:XF 13))
19293 (clobber (reg:XF 14))
19294 (clobber (reg:XF 15))
19295 (clobber (reg:DI 29))
19296 (clobber (reg:DI 30))
19297 (clobber (reg:DI 31))
19298 (clobber (reg:DI 32))
19299 (clobber (reg:DI 33))
19300 (clobber (reg:DI 34))
19301 (clobber (reg:DI 35))
19302 (clobber (reg:DI 36))]
19303 "TARGET_3DNOW"
19304 "femms"
19305 [(set_attr "type" "mmx")])
19306
19307(define_insn "prefetch_3dnow"
19308 [(unspec [(match_operand:SI 0 "address_operand" "p")] 47)]
19309 "TARGET_3DNOW"
19310 "prefetch\\t%a0"
19311 [(set_attr "type" "mmx")])
19312
19313(define_insn "prefetchw"
19314 [(unspec [(match_operand:SI 0 "address_operand" "p")] 48)]
19315 "TARGET_3DNOW"
19316 "prefetchw\\t%a0"
19317 [(set_attr "type" "mmx")])
19318
19319(define_insn "pf2id"
19320 [(set (match_operand:V2SI 0 "register_operand" "=y")
19321 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19322 "TARGET_3DNOW"
19323 "pf2id\\t{%1, %0|%0, %1}"
19324 [(set_attr "type" "mmx")])
19325
19326(define_insn "pf2iw"
19327 [(set (match_operand:V2SI 0 "register_operand" "=y")
19328 (sign_extend:V2SI
19329 (ss_truncate:V2HI
19330 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19331 "TARGET_3DNOW_A"
19332 "pf2iw\\t{%1, %0|%0, %1}"
19333 [(set_attr "type" "mmx")])
19334
19335(define_insn "pfacc"
19336 [(set (match_operand:V2SF 0 "register_operand" "=y")
19337 (vec_concat:V2SF
19338 (plus:SF
19339 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19340 (parallel [(const_int 0)]))
19341 (vec_select:SF (match_dup 1)
19342 (parallel [(const_int 1)])))
19343 (plus:SF
19344 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19345 (parallel [(const_int 0)]))
19346 (vec_select:SF (match_dup 2)
19347 (parallel [(const_int 1)])))))]
19348 "TARGET_3DNOW"
19349 "pfacc\\t{%2, %0|%0, %2}"
19350 [(set_attr "type" "mmx")])
19351
19352(define_insn "pfnacc"
19353 [(set (match_operand:V2SF 0 "register_operand" "=y")
19354 (vec_concat:V2SF
19355 (minus:SF
19356 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19357 (parallel [(const_int 0)]))
19358 (vec_select:SF (match_dup 1)
19359 (parallel [(const_int 1)])))
19360 (minus:SF
19361 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19362 (parallel [(const_int 0)]))
19363 (vec_select:SF (match_dup 2)
19364 (parallel [(const_int 1)])))))]
19365 "TARGET_3DNOW_A"
19366 "pfnacc\\t{%2, %0|%0, %2}"
19367 [(set_attr "type" "mmx")])
19368
19369(define_insn "pfpnacc"
19370 [(set (match_operand:V2SF 0 "register_operand" "=y")
19371 (vec_concat:V2SF
19372 (minus:SF
19373 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19374 (parallel [(const_int 0)]))
19375 (vec_select:SF (match_dup 1)
19376 (parallel [(const_int 1)])))
19377 (plus:SF
19378 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19379 (parallel [(const_int 0)]))
19380 (vec_select:SF (match_dup 2)
19381 (parallel [(const_int 1)])))))]
19382 "TARGET_3DNOW_A"
19383 "pfpnacc\\t{%2, %0|%0, %2}"
19384 [(set_attr "type" "mmx")])
19385
19386(define_insn "pi2fw"
19387 [(set (match_operand:V2SF 0 "register_operand" "=y")
19388 (float:V2SF
19389 (vec_concat:V2SI
19390 (sign_extend:SI
19391 (truncate:HI
19392 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19393 (parallel [(const_int 0)]))))
19394 (sign_extend:SI
19395 (truncate:HI
19396 (vec_select:SI (match_dup 1)
19397 (parallel [(const_int 1)])))))))]
19398 "TARGET_3DNOW_A"
19399 "pi2fw\\t{%1, %0|%0, %1}"
19400 [(set_attr "type" "mmx")])
19401
19402(define_insn "floatv2si2"
19403 [(set (match_operand:V2SF 0 "register_operand" "=y")
19404 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19405 "TARGET_3DNOW"
19406 "pi2fd\\t{%1, %0|%0, %1}"
19407 [(set_attr "type" "mmx")])
19408
19409;; This insn is identical to pavgb in operation, but the opcode is
19410;; different. To avoid accidentally matching pavgb, use an unspec.
19411
19412(define_insn "pavgusb"
19413 [(set (match_operand:V8QI 0 "register_operand" "=y")
19414 (unspec:V8QI
19415 [(match_operand:V8QI 1 "register_operand" "0")
19416 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19417 "TARGET_3DNOW"
19418 "pavgusb\\t{%2, %0|%0, %2}"
19419 [(set_attr "type" "mmx")])
19420
19421;; 3DNow reciprical and sqrt
19422
19423(define_insn "pfrcpv2sf2"
19424 [(set (match_operand:V2SF 0 "register_operand" "=y")
19425 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19426 "TARGET_3DNOW"
19427 "pfrcp\\t{%1, %0|%0, %1}"
19428 [(set_attr "type" "mmx")])
19429
19430(define_insn "pfrcpit1v2sf3"
19431 [(set (match_operand:V2SF 0 "register_operand" "=y")
19432 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19433 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19434 "TARGET_3DNOW"
19435 "pfrcpit1\\t{%2, %0|%0, %2}"
19436 [(set_attr "type" "mmx")])
19437
19438(define_insn "pfrcpit2v2sf3"
19439 [(set (match_operand:V2SF 0 "register_operand" "=y")
19440 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19441 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19442 "TARGET_3DNOW"
19443 "pfrcpit2\\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "mmx")])
19445
19446(define_insn "pfrsqrtv2sf2"
19447 [(set (match_operand:V2SF 0 "register_operand" "=y")
19448 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19449 "TARGET_3DNOW"
19450 "pfrsqrt\\t{%1, %0|%0, %1}"
19451 [(set_attr "type" "mmx")])
19452
19453(define_insn "pfrsqit1v2sf3"
19454 [(set (match_operand:V2SF 0 "register_operand" "=y")
19455 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19456 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19457 "TARGET_3DNOW"
19458 "pfrsqit1\\t{%2, %0|%0, %2}"
19459 [(set_attr "type" "mmx")])
19460
19461(define_insn "pmulhrwv4hi3"
19462 [(set (match_operand:V4HI 0 "register_operand" "=y")
19463 (truncate:V4HI
19464 (lshiftrt:V4SI
19465 (plus:V4SI
19466 (mult:V4SI
19467 (sign_extend:V4SI
19468 (match_operand:V4HI 1 "register_operand" "0"))
19469 (sign_extend:V4SI
19470 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19471 (vec_const:V4SI
19472 (parallel [(const_int 0x8000)
19473 (const_int 0x8000)
19474 (const_int 0x8000)
19475 (const_int 0x8000)])))
19476 (const_int 16))))]
19477 "TARGET_3DNOW"
19478 "pmulhrw\\t{%2, %0|%0, %2}"
19479 [(set_attr "type" "mmx")])
19480
19481(define_insn "pswapdv2si2"
19482 [(set (match_operand:V2SI 0 "register_operand" "=y")
19483 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19484 (parallel [(const_int 1) (const_int 0)])))]
19485 "TARGET_3DNOW_A"
19486 "pswapd\\t{%1, %0|%0, %1}"
19487 [(set_attr "type" "mmx")])
19488
19489(define_insn "pswapdv2sf2"
19490 [(set (match_operand:V2SF 0 "register_operand" "=y")
19491 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19492 (parallel [(const_int 1) (const_int 0)])))]
19493 "TARGET_3DNOW_A"
19494 "pswapd\\t{%1, %0|%0, %1}"
19495 [(set_attr "type" "mmx")])