]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i386/i386.md
i386.c (ix86_expand_fp_movcc): Do not attempt to construct SSE based conditional...
[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.
915119a5
BS
76
77;; For SSE/MMX support:
78;; 30 This is `fix', guaranteed to be truncating.
79;; 31 This is a `emms' operation.
80;; 32 This is a `maskmov' operation.
81;; 33 This is a `movmsk' operation.
82;; 34 This is a `non-temporal' move.
83;; 35 This is a `prefetch' operation.
84;; 36 This is used to distinguish COMISS from UCOMISS.
85;; 37 This is a `ldmxcsr' operation.
86;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
87;; 39 This is a forced `movups' instruction (rather than whatever movti does)
88;; 40 This is a `stmxcsr' operation.
89;; 41 This is a `shuffle' operation.
90;; 42 This is a `rcp' operation.
91;; 43 This is a `rsqsrt' operation.
92;; 44 This is a `sfence' operation.
93;; 45 This is a noop to prevent excessive combiner cleverness.
94
6343a50e
ZW
95;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
96;; from i386.c.
97
2ae0f82c 98\f
e075ae69
RH
99;; Processor type. This attribute must exactly match the processor_type
100;; enumeration in i386.h.
b4e89e2d 101(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
e075ae69 102 (const (symbol_ref "ix86_cpu")))
2ae0f82c 103
e075ae69
RH
104;; A basic instruction type. Refinements due to arguments to be
105;; provided in other attributes.
a269a03c 106(define_attr "type"
915119a5 107 "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"
e075ae69
RH
108 (const_string "other"))
109
6ef67412 110;; Main data type used by the insn
2b04e52b 111(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
6ef67412
JH
112 (const_string "unknown"))
113
114;; Set for i387 operations.
115(define_attr "i387" ""
116 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
117 (const_int 1)
118 (const_int 0)))
119
120;; The (bounding maximum) length of an instruction immediate.
121(define_attr "length_immediate" ""
bd793c65 122 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
6ef67412
JH
123 (const_int 0)
124 (eq_attr "i387" "1")
125 (const_int 0)
126 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
127 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
128 (eq_attr "type" "imov,test")
129 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
130 (eq_attr "type" "call")
131 (if_then_else (match_operand 0 "constant_call_address_operand" "")
132 (const_int 4)
133 (const_int 0))
134 (eq_attr "type" "callv")
135 (if_then_else (match_operand 1 "constant_call_address_operand" "")
136 (const_int 4)
137 (const_int 0))
138 (eq_attr "type" "ibr")
139 (if_then_else (and (ge (minus (match_dup 0) (pc))
140 (const_int -128))
141 (lt (minus (match_dup 0) (pc))
142 (const_int 124)))
143 (const_int 1)
144 (const_int 4))
145 ]
146 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
e075ae69 147
6ef67412
JH
148;; The (bounding maximum) length of an instruction address.
149(define_attr "length_address" ""
150 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
151 (const_int 0)
152 (and (eq_attr "type" "call")
153 (match_operand 1 "constant_call_address_operand" ""))
154 (const_int 0)
155 (and (eq_attr "type" "callv")
156 (match_operand 1 "constant_call_address_operand" ""))
157 (const_int 0)
158 ]
159 (symbol_ref "ix86_attr_length_address_default (insn)")))
160
161;; Set when length prefix is used.
162(define_attr "prefix_data16" ""
163 (if_then_else (eq_attr "mode" "HI")
164 (const_int 1)
165 (const_int 0)))
166
167;; Set when string REP prefix is used.
168(define_attr "prefix_rep" "" (const_int 0))
169
170;; Set when 0f opcode prefix is used.
171(define_attr "prefix_0f" ""
bd793c65 172 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
6ef67412
JH
173 (const_int 1)
174 (const_int 0)))
175
176;; Set when modrm byte is used.
177(define_attr "modrm" ""
178 (cond [(eq_attr "type" "str,cld")
179 (const_int 0)
180 (eq_attr "i387" "1")
181 (const_int 0)
e075ae69
RH
182 (and (eq_attr "type" "incdec")
183 (ior (match_operand:SI 1 "register_operand" "")
184 (match_operand:HI 1 "register_operand" "")))
6ef67412 185 (const_int 0)
e075ae69
RH
186 (and (eq_attr "type" "push")
187 (not (match_operand 1 "memory_operand" "")))
6ef67412 188 (const_int 0)
e075ae69
RH
189 (and (eq_attr "type" "pop")
190 (not (match_operand 0 "memory_operand" "")))
6ef67412 191 (const_int 0)
e075ae69
RH
192 (and (eq_attr "type" "imov")
193 (and (match_operand 0 "register_operand" "")
194 (match_operand 1 "immediate_operand" "")))
6ef67412 195 (const_int 0)
e075ae69 196 ]
6ef67412
JH
197 (const_int 1)))
198
199;; The (bounding maximum) length of an instruction in bytes.
200(define_attr "length" ""
201 (cond [(eq_attr "type" "other,multi")
202 (const_int 16)
203 ]
204 (plus (plus (attr "modrm")
205 (plus (attr "prefix_0f")
206 (plus (attr "i387")
207 (const_int 1))))
208 (plus (attr "prefix_rep")
209 (plus (attr "prefix_data16")
210 (plus (attr "length_immediate")
211 (attr "length_address")))))))
e075ae69
RH
212
213;; The `memory' attribute is `none' if no memory is referenced, `load' or
214;; `store' if there is a simple memory reference therein, or `unknown'
215;; if the instruction is complex.
216
217(define_attr "memory" "none,load,store,both,unknown"
7c7ef435 218 (cond [(eq_attr "type" "other,multi,str")
e075ae69 219 (const_string "unknown")
7c7ef435 220 (eq_attr "type" "lea,fcmov,fpspc,cld")
e075ae69
RH
221 (const_string "none")
222 (eq_attr "type" "push")
223 (if_then_else (match_operand 1 "memory_operand" "")
224 (const_string "both")
225 (const_string "store"))
226 (eq_attr "type" "pop,setcc")
227 (if_then_else (match_operand 0 "memory_operand" "")
228 (const_string "both")
229 (const_string "load"))
6ef67412 230 (eq_attr "type" "icmp,test")
e075ae69
RH
231 (if_then_else (ior (match_operand 0 "memory_operand" "")
232 (match_operand 1 "memory_operand" ""))
233 (const_string "load")
234 (const_string "none"))
235 (eq_attr "type" "ibr")
236 (if_then_else (match_operand 0 "memory_operand" "")
237 (const_string "load")
238 (const_string "none"))
239 (eq_attr "type" "call")
240 (if_then_else (match_operand 0 "constant_call_address_operand" "")
241 (const_string "none")
242 (const_string "load"))
243 (eq_attr "type" "callv")
244 (if_then_else (match_operand 1 "constant_call_address_operand" "")
245 (const_string "none")
246 (const_string "load"))
247 (and (eq_attr "type" "alu1,negnot")
a269a03c 248 (match_operand 1 "memory_operand" ""))
e075ae69
RH
249 (const_string "both")
250 (and (match_operand 0 "memory_operand" "")
251 (match_operand 1 "memory_operand" ""))
252 (const_string "both")
253 (match_operand 0 "memory_operand" "")
254 (const_string "store")
255 (match_operand 1 "memory_operand" "")
256 (const_string "load")
915119a5 257 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
e075ae69
RH
258 (match_operand 2 "memory_operand" ""))
259 (const_string "load")
260 (and (eq_attr "type" "icmov")
261 (match_operand 3 "memory_operand" ""))
262 (const_string "load")
263 ]
a269a03c
JC
264 (const_string "none")))
265
e075ae69
RH
266;; Indicates if an instruction has both an immediate and a displacement.
267
268(define_attr "imm_disp" "false,true,unknown"
269 (cond [(eq_attr "type" "other,multi")
270 (const_string "unknown")
6ef67412 271 (and (eq_attr "type" "icmp,test,imov")
e075ae69
RH
272 (and (match_operand 0 "memory_displacement_operand" "")
273 (match_operand 1 "immediate_operand" "")))
274 (const_string "true")
275 (and (eq_attr "type" "alu,ishift,imul,idiv")
276 (and (match_operand 0 "memory_displacement_operand" "")
277 (match_operand 2 "immediate_operand" "")))
278 (const_string "true")
279 ]
280 (const_string "false")))
281
282;; Indicates if an FP operation has an integer source.
283
284(define_attr "fp_int_src" "false,true"
285 (const_string "false"))
286
287;; Describe a user's asm statement.
288(define_asm_attributes
289 [(set_attr "length" "128")
290 (set_attr "type" "multi")])
291\f
292;; Pentium Scheduling
293;;
294;; The Pentium is an in-order core with two integer pipelines.
295
6ef67412
JH
296;; True for insns that behave like prefixed insns on the Pentium.
297(define_attr "pent_prefix" "false,true"
298 (if_then_else (ior (eq_attr "prefix_0f" "1")
299 (ior (eq_attr "prefix_data16" "1")
300 (eq_attr "prefix_rep" "1")))
301 (const_string "true")
302 (const_string "false")))
303
e075ae69
RH
304;; Categorize how an instruction slots.
305
306;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
307;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
308;; rules, because it results in noticeably better code on non-MMX Pentium
309;; and doesn't hurt much on MMX. (Prefixed instructions are not very
310;; common, so the scheduler usualy has a non-prefixed insn to pair).
311
312(define_attr "pent_pair" "uv,pu,pv,np"
313 (cond [(eq_attr "imm_disp" "true")
314 (const_string "np")
6ef67412
JH
315 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
316 (and (eq_attr "type" "pop,push")
317 (eq_attr "memory" "!both")))
318 (if_then_else (eq_attr "pent_prefix" "true")
e075ae69
RH
319 (const_string "pu")
320 (const_string "uv"))
321 (eq_attr "type" "ibr")
322 (const_string "pv")
323 (and (eq_attr "type" "ishift")
324 (match_operand 2 "const_int_operand" ""))
325 (const_string "pu")
e075ae69
RH
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
328 (const_string "pv")
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
331 (const_string "pv")
332 ]
333 (const_string "np")))
334
335;; Rough readiness numbers. Fine tuning happens in i386.c.
336;;
337;; u describes pipe U
338;; v describes pipe V
339;; uv describes either pipe U or V for those that can issue to either
340;; np describes not paring
341;; fpu describes fpu
342;; fpm describes fp insns of different types are not pipelined.
343;;
344;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
2ae0f82c 345
e075ae69
RH
346(define_function_unit "pent_np" 1 0
347 (and (eq_attr "cpu" "pentium")
348 (eq_attr "type" "imul"))
349 11 11)
36cf4bcf 350
e075ae69
RH
351(define_function_unit "pent_mul" 1 1
352 (and (eq_attr "cpu" "pentium")
353 (eq_attr "type" "imul"))
354 11 11)
36cf4bcf 355
7c7ef435
JH
356;; Rep movs takes minimally 12 cycles.
357(define_function_unit "pent_np" 1 0
358 (and (eq_attr "cpu" "pentium")
359 (eq_attr "type" "str"))
360 12 12)
361
e075ae69
RH
362; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
363(define_function_unit "pent_np" 1 0
364 (and (eq_attr "cpu" "pentium")
365 (eq_attr "type" "idiv"))
366 46 46)
367
368; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
369; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
370; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
371; The integer <-> fp conversion is not modeled correctly. Fild behaves
372; like normal fp operation and fist takes 6 cycles.
373
374(define_function_unit "fpu" 1 0
375 (and (eq_attr "cpu" "pentium")
376 (and (eq_attr "type" "fmov")
2b589241
JH
377 (and (eq_attr "memory" "load,store")
378 (eq_attr "mode" "XF"))))
e075ae69
RH
379 3 3)
380
381(define_function_unit "pent_np" 1 0
382 (and (eq_attr "cpu" "pentium")
383 (and (eq_attr "type" "fmov")
2b589241
JH
384 (and (eq_attr "memory" "load,store")
385 (eq_attr "mode" "XF"))))
e075ae69
RH
386 3 3)
387
388(define_function_unit "fpu" 1 0
389 (and (eq_attr "cpu" "pentium")
390 (and (eq_attr "type" "fmov")
391 (ior (match_operand 1 "immediate_operand" "")
392 (eq_attr "memory" "store"))))
393 2 2)
36cf4bcf 394
e075ae69
RH
395(define_function_unit "pent_np" 1 0
396 (and (eq_attr "cpu" "pentium")
397 (and (eq_attr "type" "fmov")
398 (ior (match_operand 1 "immediate_operand" "")
399 (eq_attr "memory" "store"))))
400 2 2)
2ae0f82c 401
7c7ef435
JH
402(define_function_unit "pent_np" 1 0
403 (and (eq_attr "cpu" "pentium")
404 (eq_attr "type" "cld"))
405 2 2)
406
e075ae69
RH
407(define_function_unit "fpu" 1 0
408 (and (eq_attr "cpu" "pentium")
409 (and (eq_attr "type" "fmov")
410 (eq_attr "memory" "none,load")))
411 1 1)
412
413; Read/Modify/Write instructions usually take 3 cycles.
414(define_function_unit "pent_u" 1 0
415 (and (eq_attr "cpu" "pentium")
416 (and (eq_attr "type" "alu,alu1,ishift")
417 (and (eq_attr "pent_pair" "pu")
418 (eq_attr "memory" "both"))))
419 3 3)
420
421(define_function_unit "pent_uv" 2 0
422 (and (eq_attr "cpu" "pentium")
423 (and (eq_attr "type" "alu,alu1,ishift")
424 (and (eq_attr "pent_pair" "!np")
425 (eq_attr "memory" "both"))))
426 3 3)
427
428(define_function_unit "pent_np" 1 0
429 (and (eq_attr "cpu" "pentium")
430 (and (eq_attr "type" "alu,alu1,negnot,ishift")
431 (and (eq_attr "pent_pair" "np")
432 (eq_attr "memory" "both"))))
433 3 3)
434
435; Read/Modify or Modify/Write instructions usually take 2 cycles.
436(define_function_unit "pent_u" 1 0
437 (and (eq_attr "cpu" "pentium")
438 (and (eq_attr "type" "alu,ishift")
439 (and (eq_attr "pent_pair" "pu")
440 (eq_attr "memory" "load,store"))))
441 2 2)
2ae0f82c 442
e075ae69
RH
443(define_function_unit "pent_uv" 2 0
444 (and (eq_attr "cpu" "pentium")
445 (and (eq_attr "type" "alu,ishift")
446 (and (eq_attr "pent_pair" "!np")
447 (eq_attr "memory" "load,store"))))
448 2 2)
2ae0f82c 449
e075ae69
RH
450(define_function_unit "pent_np" 1 0
451 (and (eq_attr "cpu" "pentium")
452 (and (eq_attr "type" "alu,ishift")
453 (and (eq_attr "pent_pair" "np")
454 (eq_attr "memory" "load,store"))))
455 2 2)
36cf4bcf 456
e075ae69
RH
457; Insns w/o memory operands and move instructions usually take one cycle.
458(define_function_unit "pent_u" 1 0
459 (and (eq_attr "cpu" "pentium")
460 (eq_attr "pent_pair" "pu"))
461 1 1)
462
463(define_function_unit "pent_v" 1 0
464 (and (eq_attr "cpu" "pentium")
465 (eq_attr "pent_pair" "pv"))
466 1 1)
467
468(define_function_unit "pent_uv" 2 0
469 (and (eq_attr "cpu" "pentium")
470 (eq_attr "pent_pair" "!np"))
471 1 1)
472
473(define_function_unit "pent_np" 1 0
474 (and (eq_attr "cpu" "pentium")
475 (eq_attr "pent_pair" "np"))
476 1 1)
477
478; Pairable insns only conflict with other non-pairable insns.
479(define_function_unit "pent_np" 1 0
480 (and (eq_attr "cpu" "pentium")
481 (and (eq_attr "type" "alu,alu1,ishift")
482 (and (eq_attr "pent_pair" "!np")
483 (eq_attr "memory" "both"))))
484 3 3
485 [(eq_attr "pent_pair" "np")])
486
487(define_function_unit "pent_np" 1 0
488 (and (eq_attr "cpu" "pentium")
489 (and (eq_attr "type" "alu,alu1,ishift")
490 (and (eq_attr "pent_pair" "!np")
491 (eq_attr "memory" "load,store"))))
492 2 2
493 [(eq_attr "pent_pair" "np")])
494
495(define_function_unit "pent_np" 1 0
496 (and (eq_attr "cpu" "pentium")
497 (eq_attr "pent_pair" "!np"))
498 1 1
499 [(eq_attr "pent_pair" "np")])
500
501; Floating point instructions usually blocks cycle longer when combined with
502; integer instructions, because of the inpaired fxch instruction.
503(define_function_unit "pent_np" 1 0
504 (and (eq_attr "cpu" "pentium")
505 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
506 2 2
507 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
508
509(define_function_unit "fpu" 1 0
510 (and (eq_attr "cpu" "pentium")
511 (eq_attr "type" "fcmp,fxch,fsgn"))
512 1 1)
513
514; Addition takes 3 cycles; assume other random cruft does as well.
515; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
516(define_function_unit "fpu" 1 0
517 (and (eq_attr "cpu" "pentium")
518 (eq_attr "type" "fop,fop1"))
519 3 1)
520
521; Multiplication takes 3 cycles and is only half pipelined.
522(define_function_unit "fpu" 1 0
523 (and (eq_attr "cpu" "pentium")
524 (eq_attr "type" "fmul"))
525 3 1)
526
527(define_function_unit "pent_mul" 1 1
528 (and (eq_attr "cpu" "pentium")
529 (eq_attr "type" "fmul"))
530 2 2)
36cf4bcf 531
e075ae69
RH
532; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
533; They can overlap with integer insns. Only the last two cycles can overlap
534; with other fp insns. Only fsin/fcos can overlap with multiplies.
535; Only last two cycles of fsin/fcos can overlap with other instructions.
536(define_function_unit "fpu" 1 0
537 (and (eq_attr "cpu" "pentium")
538 (eq_attr "type" "fdiv"))
539 39 37)
540
541(define_function_unit "pent_mul" 1 1
542 (and (eq_attr "cpu" "pentium")
543 (eq_attr "type" "fdiv"))
544 39 39)
545
546(define_function_unit "fpu" 1 0
547 (and (eq_attr "cpu" "pentium")
548 (eq_attr "type" "fpspc"))
549 70 68)
550
551(define_function_unit "pent_mul" 1 1
552 (and (eq_attr "cpu" "pentium")
553 (eq_attr "type" "fpspc"))
554 70 70)
555\f
556;; Pentium Pro/PII Scheduling
557;;
558;; The PPro has an out-of-order core, but the instruction decoders are
559;; naturally in-order and asymmetric. We get best performance by scheduling
560;; for the decoders, for in doing so we give the oo execution unit the
561;; most choices.
562
563;; Categorize how many uops an ia32 instruction evaluates to:
564;; one -- an instruction with 1 uop can be decoded by any of the
565;; three decoders.
566;; few -- an instruction with 1 to 4 uops can be decoded only by
567;; decoder 0.
568;; many -- a complex instruction may take an unspecified number of
569;; cycles to decode in decoder 0.
570
571(define_attr "ppro_uops" "one,few,many"
7c7ef435 572 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
e075ae69 573 (const_string "many")
7c7ef435 574 (eq_attr "type" "icmov,fcmov,str,cld")
e075ae69
RH
575 (const_string "few")
576 (eq_attr "type" "imov")
577 (if_then_else (eq_attr "memory" "store,both")
578 (const_string "few")
579 (const_string "one"))
580 (eq_attr "memory" "!none")
581 (const_string "few")
582 ]
583 (const_string "one")))
584
585;; Rough readiness numbers. Fine tuning happens in i386.c.
586;;
587;; p0 describes port 0.
588;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
589;; p2 describes port 2 for loads.
590;; p34 describes ports 3 and 4 for stores.
591;; fpu describes the fpu accessed via port 0.
592;; ??? It is less than clear if there are separate fadd and fmul units
593;; that could operate in parallel.
594;;
595;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
596
597(define_function_unit "ppro_p0" 1 0
598 (and (eq_attr "cpu" "pentiumpro")
7c7ef435 599 (eq_attr "type" "ishift,lea,ibr,cld"))
e075ae69
RH
600 1 1)
601
602(define_function_unit "ppro_p0" 1 0
603 (and (eq_attr "cpu" "pentiumpro")
604 (eq_attr "type" "imul"))
605 4 1)
606
607;; ??? Does the divider lock out the pipe while it works,
608;; or is there a disconnected unit?
609(define_function_unit "ppro_p0" 1 0
610 (and (eq_attr "cpu" "pentiumpro")
611 (eq_attr "type" "idiv"))
612 17 17)
36cf4bcf 613
e075ae69
RH
614(define_function_unit "ppro_p0" 1 0
615 (and (eq_attr "cpu" "pentiumpro")
616 (eq_attr "type" "fop,fop1,fsgn"))
617 3 1)
618
619(define_function_unit "ppro_p0" 1 0
620 (and (eq_attr "cpu" "pentiumpro")
621 (eq_attr "type" "fcmov"))
622 2 1)
623
624(define_function_unit "ppro_p0" 1 0
625 (and (eq_attr "cpu" "pentiumpro")
626 (eq_attr "type" "fcmp"))
627 1 1)
628
629(define_function_unit "ppro_p0" 1 0
630 (and (eq_attr "cpu" "pentiumpro")
631 (eq_attr "type" "fmov"))
632 1 1)
633
634(define_function_unit "ppro_p0" 1 0
635 (and (eq_attr "cpu" "pentiumpro")
636 (eq_attr "type" "fmul"))
637 5 1)
638
639(define_function_unit "ppro_p0" 1 0
640 (and (eq_attr "cpu" "pentiumpro")
641 (eq_attr "type" "fdiv,fpspc"))
642 56 1)
643
644(define_function_unit "ppro_p01" 2 0
645 (and (eq_attr "cpu" "pentiumpro")
646 (eq_attr "type" "!imov,fmov"))
647 1 1)
648
649(define_function_unit "ppro_p01" 2 0
650 (and (and (eq_attr "cpu" "pentiumpro")
651 (eq_attr "type" "imov,fmov"))
652 (eq_attr "memory" "none"))
653 1 1)
654
655(define_function_unit "ppro_p2" 1 0
656 (and (eq_attr "cpu" "pentiumpro")
657 (ior (eq_attr "type" "pop")
658 (eq_attr "memory" "load,both")))
659 3 1)
660
661(define_function_unit "ppro_p34" 1 0
662 (and (eq_attr "cpu" "pentiumpro")
663 (ior (eq_attr "type" "push")
664 (eq_attr "memory" "store,both")))
665 1 1)
666
667(define_function_unit "fpu" 1 0
668 (and (eq_attr "cpu" "pentiumpro")
669 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
670 1 1)
671
672(define_function_unit "fpu" 1 0
673 (and (eq_attr "cpu" "pentiumpro")
674 (eq_attr "type" "fmul"))
675 5 2)
676
677(define_function_unit "fpu" 1 0
678 (and (eq_attr "cpu" "pentiumpro")
679 (eq_attr "type" "fdiv,fpspc"))
680 56 56)
681
682;; imul uses the fpu. ??? does it have the same throughput as fmul?
683(define_function_unit "fpu" 1 0
684 (and (eq_attr "cpu" "pentiumpro")
685 (eq_attr "type" "imul"))
686 4 1)
687\f
688;; AMD K6/K6-2 Scheduling
689;;
690;; The K6 has similar architecture to PPro. Important difference is, that
691;; there are only two decoders and they seems to be much slower than execution
692;; units. So we have to pay much more attention to proper decoding for
693;; schedulers. We share most of scheduler code for PPro in i386.c
694;;
695;; The fp unit is not pipelined and do one operation per two cycles including
696;; the FXCH.
697;;
698;; alu describes both ALU units (ALU-X and ALU-Y).
699;; alux describes X alu unit
700;; fpu describes FPU unit
701;; load describes load unit.
702;; branch describes branch unit.
703;; store decsribes store unit. This unit is not modelled completely and only
704;; used to model lea operation. Otherwise it lie outside of the critical
705;; path.
706;;
707;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
36cf4bcf 708
e075ae69 709;; The decoder specification is in the PPro section above!
2ae0f82c 710
e075ae69
RH
711;; Shift instructions and certain arithmetic are issued only to X pipe.
712(define_function_unit "k6_alux" 1 0
713 (and (eq_attr "cpu" "k6")
7c7ef435 714 (eq_attr "type" "ishift,alu1,negnot,cld"))
e075ae69 715 1 1)
2ae0f82c 716
e075ae69
RH
717;; The QI mode arithmetic is issued to X pipe only.
718(define_function_unit "k6_alux" 1 0
719 (and (eq_attr "cpu" "k6")
6ef67412 720 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
e075ae69
RH
721 (match_operand:QI 0 "general_operand" "")))
722 1 1)
a269a03c 723
e075ae69
RH
724(define_function_unit "k6_alu" 2 0
725 (and (eq_attr "cpu" "k6")
6ef67412 726 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
e075ae69 727 1 1)
a269a03c 728
e075ae69
RH
729(define_function_unit "k6_alu" 2 0
730 (and (eq_attr "cpu" "k6")
731 (and (eq_attr "type" "imov")
732 (eq_attr "memory" "none")))
733 1 1)
a269a03c 734
e075ae69 735(define_function_unit "k6_branch" 1 0
a269a03c 736 (and (eq_attr "cpu" "k6")
e075ae69
RH
737 (eq_attr "type" "call,callv,ibr"))
738 1 1)
a269a03c 739
e075ae69
RH
740;; Load unit have two cycle latency, but we take care for it in adjust_cost
741(define_function_unit "k6_load" 1 0
a269a03c 742 (and (eq_attr "cpu" "k6")
e075ae69
RH
743 (ior (eq_attr "type" "pop")
744 (eq_attr "memory" "load,both")))
745 1 1)
a269a03c 746
7c7ef435
JH
747(define_function_unit "k6_load" 1 0
748 (and (eq_attr "cpu" "k6")
749 (and (eq_attr "type" "str")
750 (eq_attr "memory" "load,both")))
751 10 10)
752
e075ae69
RH
753;; Lea have two instructions, so latency is probably 2
754(define_function_unit "k6_store" 1 0
755 (and (eq_attr "cpu" "k6")
756 (eq_attr "type" "lea"))
757 2 1)
a269a03c 758
7c7ef435
JH
759(define_function_unit "k6_store" 1 0
760 (and (eq_attr "cpu" "k6")
761 (eq_attr "type" "str"))
762 10 10)
763
e075ae69
RH
764(define_function_unit "k6_store" 1 0
765 (and (eq_attr "cpu" "k6")
766 (ior (eq_attr "type" "push")
767 (eq_attr "memory" "store,both")))
768 1 1)
a269a03c 769
e075ae69
RH
770(define_function_unit "k6_fpu" 1 1
771 (and (eq_attr "cpu" "k6")
772 (eq_attr "type" "fop,fop1,fmov,fcmp"))
773 2 2)
a269a03c 774
e075ae69
RH
775(define_function_unit "k6_fpu" 1 1
776 (and (eq_attr "cpu" "k6")
777 (eq_attr "type" "fmul"))
778 2 2)
a269a03c 779
e075ae69
RH
780;; ??? Guess
781(define_function_unit "k6_fpu" 1 1
782 (and (eq_attr "cpu" "k6")
783 (eq_attr "type" "fdiv,fpspc"))
784 56 56)
a269a03c 785
e075ae69
RH
786(define_function_unit "k6_alu" 2 0
787 (and (eq_attr "cpu" "k6")
788 (eq_attr "type" "imul"))
789 2 2)
a269a03c 790
e075ae69
RH
791(define_function_unit "k6_alux" 1 0
792 (and (eq_attr "cpu" "k6")
793 (eq_attr "type" "imul"))
794 2 2)
a269a03c 795
e075ae69
RH
796;; ??? Guess
797(define_function_unit "k6_alu" 2 0
798 (and (eq_attr "cpu" "k6")
799 (eq_attr "type" "idiv"))
800 17 17)
2ae0f82c 801
e075ae69
RH
802(define_function_unit "k6_alux" 1 0
803 (and (eq_attr "cpu" "k6")
804 (eq_attr "type" "idiv"))
805 17 17)
886c62d1 806\f
309ada50
JH
807;; AMD Athlon Scheduling
808;;
809;; The Athlon does contain three pipelined FP units, three integer units and
810;; three address generation units.
811;;
812;; The predecode logic is determining boundaries of instructions in the 64
813;; byte cache line. So the cache line straddling problem of K6 might be issue
814;; here as well, but it is not noted in the documentation.
815;;
816;; Three DirectPath instructions decoders and only one VectorPath decoder
817;; is available. They can decode three DirectPath instructions or one VectorPath
818;; instruction per cycle.
819;; Decoded macro instructions are then passed to 72 entry instruction control
820;; unit, that passes
821;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
822;;
823;; The load/store queue unit is not attached to the schedulers but
824;; communicates with all the execution units seperately instead.
825
826(define_attr "athlon_decode" "direct,vector"
0b5107cf 827 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
309ada50
JH
828 (const_string "vector")
829 (and (eq_attr "type" "push")
830 (match_operand 1 "memory_operand" ""))
831 (const_string "vector")
832 (and (eq_attr "type" "fmov")
2b589241
JH
833 (and (eq_attr "memory" "load,store")
834 (eq_attr "mode" "XF")))
309ada50
JH
835 (const_string "vector")]
836 (const_string "direct")))
837
838(define_function_unit "athlon_vectordec" 1 0
839 (and (eq_attr "cpu" "athlon")
840 (eq_attr "athlon_decode" "vector"))
841 1 1)
842
843(define_function_unit "athlon_directdec" 3 0
844 (and (eq_attr "cpu" "athlon")
845 (eq_attr "athlon_decode" "direct"))
846 1 1)
847
848(define_function_unit "athlon_vectordec" 1 0
849 (and (eq_attr "cpu" "athlon")
850 (eq_attr "athlon_decode" "direct"))
851 1 1 [(eq_attr "athlon_decode" "vector")])
852
853(define_function_unit "athlon_ieu" 3 0
854 (and (eq_attr "cpu" "athlon")
6ef67412 855 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
309ada50
JH
856 1 1)
857
7c7ef435
JH
858(define_function_unit "athlon_ieu" 3 0
859 (and (eq_attr "cpu" "athlon")
860 (eq_attr "type" "str"))
861 15 15)
862
309ada50
JH
863(define_function_unit "athlon_ieu" 3 0
864 (and (eq_attr "cpu" "athlon")
865 (eq_attr "type" "imul"))
0b5107cf 866 5 0)
309ada50
JH
867
868(define_function_unit "athlon_ieu" 3 0
869 (and (eq_attr "cpu" "athlon")
870 (eq_attr "type" "idiv"))
0b5107cf 871 42 0)
309ada50
JH
872
873(define_function_unit "athlon_muldiv" 1 0
874 (and (eq_attr "cpu" "athlon")
875 (eq_attr "type" "imul"))
876 5 0)
877
878(define_function_unit "athlon_muldiv" 1 0
879 (and (eq_attr "cpu" "athlon")
880 (eq_attr "type" "idiv"))
0b5107cf 881 42 42)
309ada50 882
0b5107cf 883(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
309ada50
JH
884 (cond [(eq_attr "type" "fop,fop1,fcmp")
885 (const_string "add")
0b5107cf 886 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
309ada50 887 (const_string "mul")
0b5107cf 888 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
309ada50 889 (const_string "store")
0b5107cf
JH
890 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
891 (const_string "any")
309ada50
JH
892 (and (eq_attr "type" "fmov")
893 (ior (match_operand:SI 1 "register_operand" "")
894 (match_operand 1 "immediate_operand" "")))
895 (const_string "store")
896 (eq_attr "type" "fmov")
0b5107cf 897 (const_string "muladd")]
309ada50
JH
898 (const_string "none")))
899
0b5107cf
JH
900;; We use latencies 1 for definitions. This is OK to model colisions
901;; in execution units. The real latencies are modeled in the "fp" pipeline.
902
903;; fsin, fcos: 96-192
904;; fsincos: 107-211
905;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
906(define_function_unit "athlon_fp" 3 0
309ada50 907 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
908 (eq_attr "type" "fpspc"))
909 100 1)
309ada50 910
0b5107cf
JH
911;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
912(define_function_unit "athlon_fp" 3 0
309ada50 913 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
914 (eq_attr "type" "fdiv"))
915 24 1)
916
917(define_function_unit "athlon_fp" 3 0
918 (and (eq_attr "cpu" "athlon")
919 (eq_attr "type" "fop,fop1,fmul"))
309ada50
JH
920 4 1)
921
0b5107cf
JH
922;; XFmode loads are slow.
923;; XFmode store is slow too (8 cycles), but we don't need to model it, because
924;; there are no dependent instructions.
925
926(define_function_unit "athlon_fp" 3 0
309ada50
JH
927 (and (eq_attr "cpu" "athlon")
928 (and (eq_attr "type" "fmov")
2b589241
JH
929 (and (eq_attr "memory" "load")
930 (eq_attr "mode" "XF"))))
0b5107cf
JH
931 10 1)
932
933(define_function_unit "athlon_fp" 3 0
934 (and (eq_attr "cpu" "athlon")
935 (eq_attr "type" "fmov,fsgn"))
309ada50
JH
936 2 1)
937
0b5107cf
JH
938;; fcmp and ftst instructions
939(define_function_unit "athlon_fp" 3 0
940 (and (eq_attr "cpu" "athlon")
941 (and (eq_attr "type" "fcmp")
942 (eq_attr "athlon_decode" "direct")))
943 3 1)
944
945;; fcmpi instructions.
946(define_function_unit "athlon_fp" 3 0
947 (and (eq_attr "cpu" "athlon")
948 (and (eq_attr "type" "fcmp")
949 (eq_attr "athlon_decode" "vector")))
950 3 1)
951
952(define_function_unit "athlon_fp" 3 0
953 (and (eq_attr "cpu" "athlon")
954 (eq_attr "type" "fcmov"))
955 7 1)
956
957(define_function_unit "athlon_fp_mul" 1 0
958 (and (eq_attr "cpu" "athlon")
959 (eq_attr "athlon_fpunits" "mul"))
960 1 1)
961
962(define_function_unit "athlon_fp_add" 1 0
963 (and (eq_attr "cpu" "athlon")
964 (eq_attr "athlon_fpunits" "add"))
965 1 1)
966
309ada50
JH
967(define_function_unit "athlon_fp_muladd" 2 0
968 (and (eq_attr "cpu" "athlon")
0b5107cf
JH
969 (eq_attr "athlon_fpunits" "muladd,mul,add"))
970 1 1)
309ada50
JH
971
972(define_function_unit "athlon_fp_store" 1 0
973 (and (eq_attr "cpu" "athlon")
0b5107cf 974 (eq_attr "athlon_fpunits" "store"))
309ada50
JH
975 1 1)
976
0b5107cf
JH
977;; We don't need to model the Adress Generation Unit, since we don't model
978;; the re-order buffer yet and thus we never schedule more than three operations
979;; at time. Later we may want to experiment with MD_SCHED macros modeling the
980;; decoders independently on the functional units.
981
982;(define_function_unit "athlon_agu" 3 0
983; (and (eq_attr "cpu" "athlon")
984; (and (eq_attr "memory" "!none")
985; (eq_attr "athlon_fpunits" "none")))
986; 1 1)
987
988;; Model load unit to avoid too long sequences of loads. We don't need to
989;; model store queue, since it is hardly going to be bottleneck.
990
991(define_function_unit "athlon_load" 2 0
309ada50 992 (and (eq_attr "cpu" "athlon")
0b5107cf 993 (eq_attr "memory" "load,both"))
309ada50
JH
994 1 1)
995
996\f
e075ae69 997;; Compare instructions.
886c62d1 998
e075ae69 999;; All compare insns have expanders that save the operands away without
c572e5ba 1000;; actually generating RTL. The bCOND or sCOND (emitted immediately
e075ae69 1001;; after the cmp) will actually emit the cmpM.
886c62d1 1002
e075ae69
RH
1003(define_expand "cmpdi"
1004 [(set (reg:CC 17)
1005 (compare:CC (match_operand:DI 0 "general_operand" "")
1006 (match_operand:DI 1 "general_operand" "")))]
c572e5ba
JVA
1007 ""
1008 "
1009{
e075ae69
RH
1010 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1011 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1012 operands[0] = force_reg (DImode, operands[0]);
1013 ix86_compare_op0 = operands[0];
1014 ix86_compare_op1 = operands[1];
c572e5ba
JVA
1015 DONE;
1016}")
1017
e075ae69
RH
1018(define_expand "cmpsi"
1019 [(set (reg:CC 17)
1020 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1021 (match_operand:SI 1 "general_operand" "")))]
c572e5ba
JVA
1022 ""
1023 "
1024{
e075ae69
RH
1025 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1026 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1027 operands[0] = force_reg (SImode, operands[0]);
1028 ix86_compare_op0 = operands[0];
1029 ix86_compare_op1 = operands[1];
c572e5ba
JVA
1030 DONE;
1031}")
1032
e075ae69
RH
1033(define_expand "cmphi"
1034 [(set (reg:CC 17)
1035 (compare:CC (match_operand:HI 0 "general_operand" "")
1036 (match_operand:HI 1 "general_operand" "")))]
c572e5ba
JVA
1037 ""
1038 "
1039{
e075ae69
RH
1040 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1041 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1042 operands[0] = force_reg (HImode, operands[0]);
1043 ix86_compare_op0 = operands[0];
1044 ix86_compare_op1 = operands[1];
c572e5ba
JVA
1045 DONE;
1046}")
1047
e075ae69
RH
1048(define_expand "cmpqi"
1049 [(set (reg:CC 17)
1050 (compare:CC (match_operand:QI 0 "general_operand" "")
1051 (match_operand:QI 1 "general_operand" "")))]
d9f32422 1052 "TARGET_QIMODE_MATH"
c572e5ba
JVA
1053 "
1054{
e075ae69
RH
1055 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1056 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1057 operands[0] = force_reg (QImode, operands[0]);
1058 ix86_compare_op0 = operands[0];
1059 ix86_compare_op1 = operands[1];
c572e5ba 1060 DONE;
886c62d1
JVA
1061}")
1062
9076b9c1
JH
1063(define_insn "*cmpsi_ccno_1"
1064 [(set (reg 17)
1065 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1066 (match_operand:SI 1 "const0_operand" "n,n")))]
1067 "ix86_match_ccmode (insn, CCNOmode)"
16189740
RH
1068 "@
1069 test{l}\\t{%0, %0|%0, %0}
1070 cmp{l}\\t{%1, %0|%0, %1}"
6ef67412
JH
1071 [(set_attr "type" "test,icmp")
1072 (set_attr "length_immediate" "0,1")
1073 (set_attr "mode" "SI")])
16189740 1074
9076b9c1
JH
1075(define_insn "*cmpsi_minus_1"
1076 [(set (reg 17)
1077 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1078 (match_operand:SI 1 "general_operand" "ri,mr"))
1079 (const_int 0)))]
1080 "ix86_match_ccmode (insn, CCGOCmode)"
1081 "cmp{l}\\t{%1, %0|%0, %1}"
1082 [(set_attr "type" "icmp")
6ef67412 1083 (set_attr "mode" "SI")])
886c62d1 1084
9076b9c1 1085(define_expand "cmpsi_1"
e075ae69
RH
1086 [(set (reg:CC 17)
1087 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1088 (match_operand:SI 1 "general_operand" "ri,mr")))]
9076b9c1
JH
1089 ""
1090 "")
1091
1092(define_insn "*cmpsi_1_insn"
1093 [(set (reg 17)
1094 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1095 (match_operand:SI 1 "general_operand" "ri,mr")))]
1096 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1097 && ix86_match_ccmode (insn, CCmode)"
e075ae69 1098 "cmp{l}\\t{%1, %0|%0, %1}"
6ef67412
JH
1099 [(set_attr "type" "icmp")
1100 (set_attr "mode" "SI")])
886c62d1 1101
9076b9c1 1102(define_insn "*cmphi_ccno_1"
16189740
RH
1103 [(set (reg 17)
1104 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1105 (match_operand:HI 1 "const0_operand" "n,n")))]
1106 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
1107 "@
1108 test{w}\\t{%0, %0|%0, %0}
1109 cmp{w}\\t{%1, %0|%0, %1}"
6ef67412
JH
1110 [(set_attr "type" "test,icmp")
1111 (set_attr "length_immediate" "0,1")
1112 (set_attr "mode" "HI")])
886c62d1 1113
9076b9c1
JH
1114(define_insn "*cmphi_minus_1"
1115 [(set (reg 17)
1116 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1117 (match_operand:HI 1 "general_operand" "ri,mr"))
1118 (const_int 0)))]
1119 "ix86_match_ccmode (insn, CCGOCmode)"
e075ae69 1120 "cmp{w}\\t{%1, %0|%0, %1}"
6ef67412
JH
1121 [(set_attr "type" "icmp")
1122 (set_attr "mode" "HI")])
e075ae69 1123
9076b9c1
JH
1124(define_insn "*cmphi_1"
1125 [(set (reg 17)
1126 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1127 (match_operand:HI 1 "general_operand" "ri,mr")))]
1128 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1129 && ix86_match_ccmode (insn, CCmode)"
1130 "cmp{w}\\t{%1, %0|%0, %1}"
1131 [(set_attr "type" "icmp")
1132 (set_attr "mode" "HI")])
16189740
RH
1133
1134(define_insn "*cmpqi_ccno_1"
9076b9c1
JH
1135 [(set (reg 17)
1136 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1137 (match_operand:QI 1 "const0_operand" "n,n")))]
1138 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
1139 "@
1140 test{b}\\t{%0, %0|%0, %0}
1141 cmp{b}\\t{$0, %0|%0, 0}"
6ef67412
JH
1142 [(set_attr "type" "test,icmp")
1143 (set_attr "length_immediate" "0,1")
1144 (set_attr "mode" "QI")])
886c62d1 1145
16189740 1146(define_insn "*cmpqi_1"
9076b9c1
JH
1147 [(set (reg 17)
1148 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1149 (match_operand:QI 1 "general_operand" "qi,mq")))]
1150 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1151 && ix86_match_ccmode (insn, CCmode)"
e075ae69 1152 "cmp{b}\\t{%1, %0|%0, %1}"
6ef67412
JH
1153 [(set_attr "type" "icmp")
1154 (set_attr "mode" "QI")])
e075ae69 1155
9076b9c1
JH
1156(define_insn "*cmpqi_minus_1"
1157 [(set (reg 17)
d70401eb
JJ
1158 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1159 (match_operand:QI 1 "general_operand" "qi,mq"))
9076b9c1
JH
1160 (const_int 0)))]
1161 "ix86_match_ccmode (insn, CCGOCmode)"
5efdd890 1162 "cmp{b}\\t{%1, %0|%0, %1}"
9076b9c1
JH
1163 [(set_attr "type" "icmp")
1164 (set_attr "mode" "QI")])
1165
e075ae69 1166(define_insn "*cmpqi_ext_1"
9076b9c1
JH
1167 [(set (reg 17)
1168 (compare
d2836273 1169 (match_operand:QI 0 "general_operand" "Qm")
e075ae69
RH
1170 (subreg:QI
1171 (zero_extract:SI
d2836273 1172 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1173 (const_int 8)
1174 (const_int 8)) 0)))]
d2836273
JH
1175 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1176 "cmp{b}\\t{%h1, %0|%0, %h1}"
1177 [(set_attr "type" "icmp")
1178 (set_attr "mode" "QI")])
1179
1180(define_insn "*cmpqi_ext_1_rex64"
1181 [(set (reg 17)
1182 (compare
1183 (match_operand:QI 0 "ext_register_operand" "Q")
1184 (subreg:QI
1185 (zero_extract:SI
1186 (match_operand 1 "ext_register_operand" "Q")
1187 (const_int 8)
1188 (const_int 8)) 0)))]
1189 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
e075ae69 1190 "cmp{b}\\t{%h1, %0|%0, %h1}"
6ef67412
JH
1191 [(set_attr "type" "icmp")
1192 (set_attr "mode" "QI")])
e075ae69
RH
1193
1194(define_insn "*cmpqi_ext_2"
16189740
RH
1195 [(set (reg 17)
1196 (compare
e075ae69
RH
1197 (subreg:QI
1198 (zero_extract:SI
d2836273 1199 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1200 (const_int 8)
1201 (const_int 8)) 0)
1202 (match_operand:QI 1 "const0_operand" "n")))]
16189740 1203 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 1204 "test{b}\\t%h0, %h0"
6ef67412
JH
1205 [(set_attr "type" "test")
1206 (set_attr "length_immediate" "0")
1207 (set_attr "mode" "QI")])
e075ae69 1208
9076b9c1 1209(define_expand "cmpqi_ext_3"
e075ae69
RH
1210 [(set (reg:CC 17)
1211 (compare:CC
1212 (subreg:QI
1213 (zero_extract:SI
d2836273 1214 (match_operand 0 "ext_register_operand" "")
e075ae69
RH
1215 (const_int 8)
1216 (const_int 8)) 0)
d2836273 1217 (match_operand:QI 1 "general_operand" "")))]
e075ae69 1218 ""
9076b9c1
JH
1219 "")
1220
1221(define_insn "cmpqi_ext_3_insn"
1222 [(set (reg 17)
1223 (compare
1224 (subreg:QI
1225 (zero_extract:SI
d2836273 1226 (match_operand 0 "ext_register_operand" "Q")
9076b9c1
JH
1227 (const_int 8)
1228 (const_int 8)) 0)
d2836273
JH
1229 (match_operand:QI 1 "general_operand" "Qmn")))]
1230 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1231 "cmp{b}\\t{%1, %h0|%h0, %1}"
1232 [(set_attr "type" "icmp")
1233 (set_attr "mode" "QI")])
1234
1235(define_insn "cmpqi_ext_3_insn_rex64"
1236 [(set (reg 17)
1237 (compare
1238 (subreg:QI
1239 (zero_extract:SI
1240 (match_operand 0 "ext_register_operand" "Q")
1241 (const_int 8)
1242 (const_int 8)) 0)
1243 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1244 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
e075ae69 1245 "cmp{b}\\t{%1, %h0|%h0, %1}"
6ef67412
JH
1246 [(set_attr "type" "icmp")
1247 (set_attr "mode" "QI")])
e075ae69
RH
1248
1249(define_insn "*cmpqi_ext_4"
9076b9c1
JH
1250 [(set (reg 17)
1251 (compare
e075ae69
RH
1252 (subreg:QI
1253 (zero_extract:SI
d2836273 1254 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
1255 (const_int 8)
1256 (const_int 8)) 0)
1257 (subreg:QI
1258 (zero_extract:SI
d2836273 1259 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
1260 (const_int 8)
1261 (const_int 8)) 0)))]
9076b9c1 1262 "ix86_match_ccmode (insn, CCmode)"
e075ae69 1263 "cmp{b}\\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
1264 [(set_attr "type" "icmp")
1265 (set_attr "mode" "QI")])
e075ae69
RH
1266
1267;; These implement float point compares.
1268;; %%% See if we can get away with VOIDmode operands on the actual insns,
1269;; which would allow mix and match FP modes on the compares. Which is what
1270;; the old patterns did, but with many more of them.
c572e5ba 1271
e075ae69
RH
1272(define_expand "cmpxf"
1273 [(set (reg:CC 17)
1274 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1275 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1e07edd3 1276 "TARGET_80387 && !TARGET_64BIT"
c572e5ba
JVA
1277 "
1278{
e075ae69
RH
1279 ix86_compare_op0 = operands[0];
1280 ix86_compare_op1 = operands[1];
c572e5ba 1281 DONE;
886c62d1 1282}")
4fb21e90 1283
2b589241
JH
1284(define_expand "cmptf"
1285 [(set (reg:CC 17)
1286 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1287 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1288 "TARGET_80387"
1289 "
1290{
1291 ix86_compare_op0 = operands[0];
1292 ix86_compare_op1 = operands[1];
1293 DONE;
1294}")
1295
e075ae69
RH
1296(define_expand "cmpdf"
1297 [(set (reg:CC 17)
1298 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1299 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
0644b628 1300 "TARGET_80387 || TARGET_SSE2"
4fb21e90
JVA
1301 "
1302{
e075ae69
RH
1303 ix86_compare_op0 = operands[0];
1304 ix86_compare_op1 = operands[1];
4fb21e90
JVA
1305 DONE;
1306}")
886c62d1 1307
e075ae69
RH
1308(define_expand "cmpsf"
1309 [(set (reg:CC 17)
1310 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1311 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
0644b628 1312 "TARGET_80387 || TARGET_SSE"
c572e5ba
JVA
1313 "
1314{
e075ae69
RH
1315 ix86_compare_op0 = operands[0];
1316 ix86_compare_op1 = operands[1];
c572e5ba
JVA
1317 DONE;
1318}")
1319
e075ae69
RH
1320;; FP compares, step 1:
1321;; Set the FP condition codes.
1322;;
1323;; CCFPmode compare with exceptions
1324;; CCFPUmode compare with no exceptions
fe4435d9 1325
e075ae69
RH
1326;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1327;; and that fp moves clobber the condition codes, and that there is
1328;; currently no way to describe this fact to reg-stack. So there are
1329;; no splitters yet for this.
c572e5ba 1330
e075ae69
RH
1331;; %%% YIKES! This scheme does not retain a strong connection between
1332;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1333;; work! Only allow tos/mem with tos in op 0.
1334;;
1335;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1336;; things aren't as bad as they sound...
886c62d1 1337
e075ae69
RH
1338(define_insn "*cmpfp_0"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1340 (unspec:HI
1341 [(compare:CCFP (match_operand 1 "register_operand" "f")
1342 (match_operand 2 "const0_operand" "X"))] 9))]
1343 "TARGET_80387
1344 && FLOAT_MODE_P (GET_MODE (operands[1]))
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346 "*
c572e5ba 1347{
e075ae69
RH
1348 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1349 return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1350 else
1351 return \"ftst\;fnstsw\\t%0\";
1352}"
6ef67412
JH
1353 [(set_attr "type" "multi")
1354 (set_attr "mode" "unknownfp")])
c572e5ba 1355
e075ae69
RH
1356;; We may not use "#" to split and emit these, since the REG_DEAD notes
1357;; used to manage the reg stack popping would not be preserved.
886c62d1 1358
e075ae69
RH
1359(define_insn "*cmpfp_2_sf"
1360 [(set (reg:CCFP 18)
1361 (compare:CCFP
1362 (match_operand:SF 0 "register_operand" "f")
1363 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
cac58785 1364 "TARGET_80387"
e075ae69 1365 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1366 [(set_attr "type" "fcmp")
1367 (set_attr "mode" "SF")])
4fb21e90 1368
6343a50e 1369(define_insn "*cmpfp_2_sf_1"
e075ae69
RH
1370 [(set (match_operand:HI 0 "register_operand" "=a")
1371 (unspec:HI
1372 [(compare:CCFP
1373 (match_operand:SF 1 "register_operand" "f")
1374 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
4fb21e90 1375 "TARGET_80387"
e075ae69 1376 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1377 [(set_attr "type" "fcmp")
1378 (set_attr "mode" "SF")])
e075ae69
RH
1379
1380(define_insn "*cmpfp_2_df"
1381 [(set (reg:CCFP 18)
1382 (compare:CCFP
1383 (match_operand:DF 0 "register_operand" "f")
1384 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
926b3fae 1385 "TARGET_80387"
e075ae69 1386 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1387 [(set_attr "type" "fcmp")
1388 (set_attr "mode" "DF")])
926b3fae 1389
6343a50e 1390(define_insn "*cmpfp_2_df_1"
e075ae69
RH
1391 [(set (match_operand:HI 0 "register_operand" "=a")
1392 (unspec:HI
1393 [(compare:CCFP
1394 (match_operand:DF 1 "register_operand" "f")
1395 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
4fb21e90 1396 "TARGET_80387"
e075ae69 1397 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1398 [(set_attr "type" "multi")
1399 (set_attr "mode" "DF")])
e075ae69
RH
1400
1401(define_insn "*cmpfp_2_xf"
1402 [(set (reg:CCFP 18)
1403 (compare:CCFP
1404 (match_operand:XF 0 "register_operand" "f")
1405 (match_operand:XF 1 "register_operand" "f")))]
1e07edd3 1406 "TARGET_80387 && !TARGET_64BIT"
e075ae69 1407 "* return output_fp_compare (insn, operands, 0, 0);"
6ef67412
JH
1408 [(set_attr "type" "fcmp")
1409 (set_attr "mode" "XF")])
9ec36da5 1410
2b589241
JH
1411(define_insn "*cmpfp_2_tf"
1412 [(set (reg:CCFP 18)
1413 (compare:CCFP
1414 (match_operand:TF 0 "register_operand" "f")
1415 (match_operand:TF 1 "register_operand" "f")))]
1416 "TARGET_80387"
1417 "* return output_fp_compare (insn, operands, 0, 0);"
1418 [(set_attr "type" "fcmp")
1419 (set_attr "mode" "XF")])
1420
6343a50e 1421(define_insn "*cmpfp_2_xf_1"
e075ae69
RH
1422 [(set (match_operand:HI 0 "register_operand" "=a")
1423 (unspec:HI
1424 [(compare:CCFP
1425 (match_operand:XF 1 "register_operand" "f")
1426 (match_operand:XF 2 "register_operand" "f"))] 9))]
1e07edd3 1427 "TARGET_80387 && !TARGET_64BIT"
e075ae69 1428 "* return output_fp_compare (insn, operands, 2, 0);"
6ef67412
JH
1429 [(set_attr "type" "multi")
1430 (set_attr "mode" "XF")])
e075ae69 1431
2b589241
JH
1432(define_insn "*cmpfp_2_tf_1"
1433 [(set (match_operand:HI 0 "register_operand" "=a")
1434 (unspec:HI
1435 [(compare:CCFP
1436 (match_operand:TF 1 "register_operand" "f")
1437 (match_operand:TF 2 "register_operand" "f"))] 9))]
1438 "TARGET_80387"
1439 "* return output_fp_compare (insn, operands, 2, 0);"
1440 [(set_attr "type" "multi")
1441 (set_attr "mode" "XF")])
1442
e075ae69
RH
1443(define_insn "*cmpfp_2u"
1444 [(set (reg:CCFPU 18)
1445 (compare:CCFPU
1446 (match_operand 0 "register_operand" "f")
1447 (match_operand 1 "register_operand" "f")))]
1448 "TARGET_80387
1449 && FLOAT_MODE_P (GET_MODE (operands[0]))
1450 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1451 "* return output_fp_compare (insn, operands, 0, 1);"
6ef67412
JH
1452 [(set_attr "type" "fcmp")
1453 (set_attr "mode" "unknownfp")])
4fb21e90 1454
6343a50e 1455(define_insn "*cmpfp_2u_1"
e075ae69
RH
1456 [(set (match_operand:HI 0 "register_operand" "=a")
1457 (unspec:HI
1458 [(compare:CCFPU
1459 (match_operand 1 "register_operand" "f")
1460 (match_operand 2 "register_operand" "f"))] 9))]
08a7baac 1461 "TARGET_80387
e075ae69
RH
1462 && FLOAT_MODE_P (GET_MODE (operands[1]))
1463 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1464 "* return output_fp_compare (insn, operands, 2, 1);"
6ef67412
JH
1465 [(set_attr "type" "multi")
1466 (set_attr "mode" "unknownfp")])
08a7baac 1467
e075ae69
RH
1468;; Patterns to match the SImode-in-memory ficom instructions.
1469;;
1470;; %%% Play games with accepting gp registers, as otherwise we have to
1471;; force them to memory during rtl generation, which is no good. We
1472;; can get rid of this once we teach reload to do memory input reloads
1473;; via pushes.
1474
6343a50e 1475(define_insn "*ficom_1"
e075ae69
RH
1476 [(set (reg:CCFP 18)
1477 (compare:CCFP
1478 (match_operand 0 "register_operand" "f,f")
1479 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1480 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1481 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1482 "#")
08a7baac 1483
e075ae69
RH
1484;; Split the not-really-implemented gp register case into a
1485;; push-op-pop sequence.
1486;;
1487;; %%% This is most efficient, but am I gonna get in trouble
1488;; for separating cc0_setter and cc0_user?
2bb7a0f5 1489
e075ae69
RH
1490(define_split
1491 [(set (reg:CCFP 18)
1492 (compare:CCFP
1493 (match_operand:SF 0 "register_operand" "")
1494 (float (match_operand:SI 1 "register_operand" ""))))]
1495 "0 && TARGET_80387 && reload_completed"
1496 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1497 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1498 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1499 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1500 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1501 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1502
1503;; FP compares, step 2
1504;; Move the fpsw to ax.
1505
1506(define_insn "x86_fnstsw_1"
1507 [(set (match_operand:HI 0 "register_operand" "=a")
1508 (unspec:HI [(reg 18)] 9))]
2ae0f82c 1509 "TARGET_80387"
e075ae69
RH
1510 "fnstsw\\t%0"
1511 [(set_attr "length" "2")
6ef67412
JH
1512 (set_attr "mode" "SI")
1513 (set_attr "i387" "1")
e075ae69
RH
1514 (set_attr "ppro_uops" "few")])
1515
1516;; FP compares, step 3
1517;; Get ax into flags, general case.
1518
1519(define_insn "x86_sahf_1"
1520 [(set (reg:CC 17)
1521 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1e07edd3 1522 "!TARGET_64BIT"
e075ae69
RH
1523 "sahf"
1524 [(set_attr "length" "1")
0b5107cf 1525 (set_attr "athlon_decode" "vector")
6ef67412 1526 (set_attr "mode" "SI")
e075ae69
RH
1527 (set_attr "ppro_uops" "one")])
1528
1529;; Pentium Pro can do steps 1 through 3 in one go.
1530
1531(define_insn "*cmpfp_i"
1532 [(set (reg:CCFP 17)
1533 (compare:CCFP (match_operand 0 "register_operand" "f")
1534 (match_operand 1 "register_operand" "f")))]
1535 "TARGET_80387 && TARGET_CMOVE
0644b628 1536 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69
RH
1537 && FLOAT_MODE_P (GET_MODE (operands[0]))
1538 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1539 "* return output_fp_compare (insn, operands, 1, 0);"
309ada50 1540 [(set_attr "type" "fcmp")
6ef67412 1541 (set_attr "mode" "unknownfp")
309ada50 1542 (set_attr "athlon_decode" "vector")])
e075ae69 1543
0644b628
JH
1544(define_insn "*cmpfp_i_sse"
1545 [(set (reg:CCFP 17)
1546 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1547 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1548 "TARGET_80387
1549 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1550 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1551 "* return output_fp_compare (insn, operands, 1, 0);"
1552 [(set_attr "type" "fcmp,sse")
1553 (set_attr "mode" "unknownfp")
1554 (set_attr "athlon_decode" "vector")])
1555
1556(define_insn "*cmpfp_i_sse_only"
1557 [(set (reg:CCFP 17)
1558 (compare:CCFP (match_operand 0 "register_operand" "x")
1559 (match_operand 1 "nonimmediate_operand" "xm")))]
1560 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1561 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1562 "* return output_fp_compare (insn, operands, 1, 0);"
1563 [(set_attr "type" "sse")
1564 (set_attr "mode" "unknownfp")
1565 (set_attr "athlon_decode" "vector")])
1566
e075ae69
RH
1567(define_insn "*cmpfp_iu"
1568 [(set (reg:CCFPU 17)
1569 (compare:CCFPU (match_operand 0 "register_operand" "f")
1570 (match_operand 1 "register_operand" "f")))]
1571 "TARGET_80387 && TARGET_CMOVE
0644b628 1572 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
e075ae69
RH
1573 && FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1575 "* return output_fp_compare (insn, operands, 1, 1);"
309ada50 1576 [(set_attr "type" "fcmp")
6ef67412 1577 (set_attr "mode" "unknownfp")
309ada50 1578 (set_attr "athlon_decode" "vector")])
0644b628
JH
1579
1580(define_insn "*cmpfp_iu_sse"
1581 [(set (reg:CCFPU 17)
1582 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1583 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1584 "TARGET_80387
1585 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1586 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1587 "* return output_fp_compare (insn, operands, 1, 1);"
1588 [(set_attr "type" "fcmp,sse")
1589 (set_attr "mode" "unknownfp")
1590 (set_attr "athlon_decode" "vector")])
1591
1592(define_insn "*cmpfp_iu_sse_only"
1593 [(set (reg:CCFPU 17)
1594 (compare:CCFPU (match_operand 0 "register_operand" "x")
1595 (match_operand 1 "nonimmediate_operand" "xm")))]
1596 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, 1, 1);"
1599 [(set_attr "type" "sse")
1600 (set_attr "mode" "unknownfp")
1601 (set_attr "athlon_decode" "vector")])
e075ae69
RH
1602\f
1603;; Move instructions.
2ae0f82c 1604
e075ae69 1605;; General case of fullword move.
886c62d1 1606
e075ae69
RH
1607(define_expand "movsi"
1608 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1609 (match_operand:SI 1 "general_operand" ""))]
1610 ""
1611 "ix86_expand_move (SImode, operands); DONE;")
08a7baac 1612
e075ae69
RH
1613;; Push/pop instructions. They are separate since autoinc/dec is not a
1614;; general_operand.
1615;;
1616;; %%% We don't use a post-inc memory reference because x86 is not a
1617;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1618;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1619;; targets without our curiosities, and it is just as easy to represent
1620;; this differently.
886c62d1 1621
a4414093 1622(define_insn "*pushsi2"
e075ae69 1623 [(set (match_operand:SI 0 "push_operand" "=<")
2c5a510c 1624 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
e075ae69
RH
1625 ""
1626 "push{l}\\t%1"
6ef67412
JH
1627 [(set_attr "type" "push")
1628 (set_attr "mode" "SI")])
4fb21e90 1629
bdeb029c
JH
1630(define_insn "*pushsi2_prologue"
1631 [(set (match_operand:SI 0 "push_operand" "=<")
1632 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1633 (set (reg:SI 6) (reg:SI 6))]
1634 ""
1635 "push{l}\\t%1"
6ef67412
JH
1636 [(set_attr "type" "push")
1637 (set_attr "mode" "SI")])
bdeb029c
JH
1638
1639(define_insn "*popsi1_epilogue"
1640 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1641 (mem:SI (reg:SI 7)))
1642 (set (reg:SI 7)
1643 (plus:SI (reg:SI 7) (const_int 4)))
1644 (set (reg:SI 6) (reg:SI 6))]
1e07edd3 1645 "!TARGET_64BIT"
bdeb029c 1646 "pop{l}\\t%0"
6ef67412
JH
1647 [(set_attr "type" "pop")
1648 (set_attr "mode" "SI")])
bdeb029c 1649
e075ae69
RH
1650(define_insn "popsi1"
1651 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1652 (mem:SI (reg:SI 7)))
1653 (set (reg:SI 7)
1654 (plus:SI (reg:SI 7) (const_int 4)))]
1e07edd3 1655 "!TARGET_64BIT"
e075ae69 1656 "pop{l}\\t%0"
6ef67412
JH
1657 [(set_attr "type" "pop")
1658 (set_attr "mode" "SI")])
c572e5ba 1659
591702de
JH
1660(define_insn "*movsi_xor"
1661 [(set (match_operand:SI 0 "register_operand" "=r")
1662 (match_operand:SI 1 "const0_operand" "i"))
e075ae69 1663 (clobber (reg:CC 17))]
591702de
JH
1664 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1665 "xor{l}\\t{%0, %0|%0, %0}"
1666 [(set_attr "type" "alu1")
6ef67412
JH
1667 (set_attr "mode" "SI")
1668 (set_attr "length_immediate" "0")])
591702de
JH
1669
1670(define_insn "*movsi_or"
1671 [(set (match_operand:SI 0 "register_operand" "=r")
1672 (match_operand:SI 1 "immediate_operand" "i"))
1673 (clobber (reg:CC 17))]
1674 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1675 && INTVAL (operands[1]) == -1
1676 && (TARGET_PENTIUM || optimize_size)"
e075ae69 1677 "*
c572e5ba 1678{
591702de 1679 operands[1] = constm1_rtx;
406df25c 1680 return \"or{l}\\t{%1, %0|%0, %1}\";
a269a03c 1681}"
591702de 1682 [(set_attr "type" "alu1")
6ef67412
JH
1683 (set_attr "mode" "SI")
1684 (set_attr "length_immediate" "1")])
e075ae69 1685
591702de 1686(define_insn "*movsi_1"
915119a5
BS
1687 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r")
1688 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))]
e075ae69 1689 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1
JVA
1690 "*
1691{
e075ae69 1692 switch (get_attr_type (insn))
886c62d1 1693 {
915119a5
BS
1694 case TYPE_MMX:
1695 return \"movd\\t{%1, %0|%0, %1}\";
1696
e075ae69
RH
1697 case TYPE_LEA:
1698 return \"lea{l}\\t{%1, %0|%0, %1}\";
915119a5 1699
e075ae69
RH
1700 default:
1701 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1702 abort();
1703 return \"mov{l}\\t{%1, %0|%0, %1}\";
886c62d1 1704 }
a269a03c 1705}"
e075ae69 1706 [(set (attr "type")
915119a5
BS
1707 (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
1708 (match_operand:SI 1 "mmx_reg_operand" ""))
1709 (const_string "mmx")
1710 (and (ne (symbol_ref "flag_pic") (const_int 0))
e075ae69
RH
1711 (match_operand:SI 1 "symbolic_operand" ""))
1712 (const_string "lea")
1713 ]
6ef67412 1714 (const_string "imov")))
915119a5 1715 (set_attr "modrm" "0,*,0,*,*,*")
6ef67412 1716 (set_attr "mode" "SI")])
e075ae69
RH
1717
1718(define_insn "*swapsi"
1719 [(set (match_operand:SI 0 "register_operand" "+r")
1720 (match_operand:SI 1 "register_operand" "+r"))
1721 (set (match_dup 1)
1722 (match_dup 0))]
2bb7a0f5 1723 ""
e075ae69
RH
1724 "xchg{l}\\t%1, %0"
1725 [(set_attr "type" "imov")
1726 (set_attr "pent_pair" "np")
0b5107cf 1727 (set_attr "athlon_decode" "vector")
6ef67412
JH
1728 (set_attr "mode" "SI")
1729 (set_attr "modrm" "0")
e075ae69 1730 (set_attr "ppro_uops" "few")])
886c62d1 1731
e075ae69
RH
1732(define_expand "movhi"
1733 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1734 (match_operand:HI 1 "general_operand" ""))]
ca097615 1735 ""
e075ae69 1736 "ix86_expand_move (HImode, operands); DONE;")
2f2a49e8 1737
a4414093 1738(define_insn "*pushhi2"
e075ae69 1739 [(set (match_operand:HI 0 "push_operand" "=<,<")
2c5a510c 1740 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1e07edd3 1741 "!TARGET_64BIT"
e075ae69
RH
1742 "@
1743 push{w}\\t{|WORD PTR }%1
1744 push{w}\\t%1"
6ef67412
JH
1745 [(set_attr "type" "push")
1746 (set_attr "mode" "HI")])
e075ae69 1747
a4414093 1748(define_insn "*pophi1"
e075ae69
RH
1749 [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1750 (mem:HI (reg:SI 7)))
1751 (set (reg:SI 7)
1752 (plus:SI (reg:SI 7) (const_int 2)))]
1e07edd3 1753 "!TARGET_64BIT"
e075ae69 1754 "pop{w}\\t%0"
6ef67412
JH
1755 [(set_attr "type" "pop")
1756 (set_attr "mode" "HI")])
e075ae69
RH
1757
1758(define_insn "*movhi_1"
6ef67412
JH
1759 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1760 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
e075ae69 1761 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1
JVA
1762 "*
1763{
e075ae69 1764 switch (get_attr_type (insn))
886c62d1 1765 {
e075ae69
RH
1766 case TYPE_IMOVX:
1767 /* movzwl is faster than movw on p2 due to partial word stalls,
1768 though not as fast as an aligned movl. */
1769 return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1770 default:
6ef67412 1771 if (get_attr_mode (insn) == MODE_SI)
e075ae69
RH
1772 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1773 else
1774 return \"mov{w}\\t{%1, %0|%0, %1}\";
886c62d1 1775 }
a269a03c 1776}"
e075ae69 1777 [(set (attr "type")
6ef67412 1778 (cond [(and (eq_attr "alternative" "0,1")
0b5107cf
JH
1779 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1780 (const_int 0))
1781 (eq (symbol_ref "TARGET_HIMODE_MATH")
1782 (const_int 0))))
369e59b1 1783 (const_string "imov")
6ef67412 1784 (and (eq_attr "alternative" "2,3,4")
2247f6ed 1785 (match_operand:HI 1 "aligned_operand" ""))
e075ae69
RH
1786 (const_string "imov")
1787 (and (ne (symbol_ref "TARGET_MOVX")
1788 (const_int 0))
6ef67412 1789 (eq_attr "alternative" "0,1,3,4"))
e075ae69
RH
1790 (const_string "imovx")
1791 ]
1792 (const_string "imov")))
6ef67412 1793 (set (attr "mode")
e075ae69 1794 (cond [(eq_attr "type" "imovx")
6ef67412
JH
1795 (const_string "SI")
1796 (and (eq_attr "alternative" "2,3,4")
369e59b1 1797 (match_operand:HI 1 "aligned_operand" ""))
6ef67412
JH
1798 (const_string "SI")
1799 (and (eq_attr "alternative" "0,1")
0b5107cf
JH
1800 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1801 (const_int 0))
1802 (eq (symbol_ref "TARGET_HIMODE_MATH")
1803 (const_int 0))))
6ef67412 1804 (const_string "SI")
e075ae69 1805 ]
6ef67412
JH
1806 (const_string "HI")))
1807 (set_attr "modrm" "0,*,*,0,*,*")])
e075ae69
RH
1808
1809(define_insn "*swaphi_1"
1810 [(set (match_operand:HI 0 "register_operand" "+r")
1811 (match_operand:HI 1 "register_operand" "+r"))
1812 (set (match_dup 1)
1813 (match_dup 0))]
1814 "TARGET_PARTIAL_REG_STALL"
1815 "xchg{w}\\t%1, %0"
1816 [(set_attr "type" "imov")
1817 (set_attr "pent_pair" "np")
6ef67412
JH
1818 (set_attr "mode" "HI")
1819 (set_attr "modrm" "0")
e075ae69
RH
1820 (set_attr "ppro_uops" "few")])
1821
1822(define_insn "*swaphi_2"
1823 [(set (match_operand:HI 0 "register_operand" "+r")
1824 (match_operand:HI 1 "register_operand" "+r"))
1825 (set (match_dup 1)
1826 (match_dup 0))]
1827 "! TARGET_PARTIAL_REG_STALL"
1828 "xchg{l}\\t%k1, %k0"
1829 [(set_attr "type" "imov")
e075ae69 1830 (set_attr "pent_pair" "np")
6ef67412
JH
1831 (set_attr "mode" "SI")
1832 (set_attr "modrm" "0")
e075ae69 1833 (set_attr "ppro_uops" "few")])
886c62d1 1834
2f2a49e8 1835(define_expand "movstricthi"
e075ae69 1836 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2f2a49e8 1837 (match_operand:HI 1 "general_operand" ""))]
e075ae69 1838 "! TARGET_PARTIAL_REG_STALL"
2f2a49e8
MM
1839 "
1840{
1841 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
1842 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1843 operands[1] = force_reg (HImode, operands[1]);
2f2a49e8
MM
1844}")
1845
e075ae69 1846(define_insn "*movstricthi_1"
fc524c1c 1847 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
e075ae69
RH
1848 (match_operand:HI 1 "general_operand" "rn,m"))]
1849 "! TARGET_PARTIAL_REG_STALL
1850 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1851 "mov{w}\\t{%1, %0|%0, %1}"
6ef67412
JH
1852 [(set_attr "type" "imov")
1853 (set_attr "mode" "HI")])
1854
1855(define_insn "*movstricthi_xor"
208b0ab1 1856 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
6ef67412
JH
1857 (match_operand:HI 1 "const0_operand" "i"))
1858 (clobber (reg:CC 17))]
1859 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1860 "xor{w}\\t{%0, %0|%0, %0}"
1861 [(set_attr "type" "alu1")
1862 (set_attr "mode" "HI")
1863 (set_attr "length_immediate" "0")])
886c62d1 1864
2f2a49e8 1865(define_expand "movqi"
4cbfbb1b 1866 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2f2a49e8
MM
1867 (match_operand:QI 1 "general_operand" ""))]
1868 ""
e075ae69
RH
1869 "ix86_expand_move (QImode, operands); DONE;")
1870
1871;; emit_push_insn when it calls move_by_pieces requires an insn to
1872;; "push a byte". But actually we use pushw, which has the effect
1873;; of rounding the amount pushed up to a halfword.
1874
a4414093 1875(define_insn "*pushqi2"
e075ae69 1876 [(set (match_operand:QI 0 "push_operand" "=<,<")
2c5a510c 1877 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1e07edd3 1878 "!TARGET_64BIT"
e075ae69
RH
1879 "@
1880 push{w}\\t{|word ptr }%1
1881 push{w}\\t%w1"
1882 [(set_attr "type" "push")
6ef67412 1883 (set_attr "mode" "HI")])
e075ae69 1884
a4414093 1885(define_insn "*popqi1"
e075ae69
RH
1886 [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1887 (mem:QI (reg:SI 7)))
1888 (set (reg:SI 7)
1889 (plus:SI (reg:SI 7) (const_int 2)))]
1e07edd3 1890 "!TARGET_64BIT"
e075ae69
RH
1891 "pop{w}\\t%0"
1892 [(set_attr "type" "pop")
6ef67412 1893 (set_attr "mode" "HI")])
e075ae69 1894
0b5107cf
JH
1895;; Situation is quite tricky about when to choose full sized (SImode) move
1896;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1897;; partial register dependency machines (such as AMD Athlon), where QImode
1898;; moves issue extra dependency and for partial register stalls machines
1899;; that don't use QImode patterns (and QImode move cause stall on the next
1900;; instruction).
1901;;
1902;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1903;; register stall machines with, where we use QImode instructions, since
1904;; partial register stall can be caused there. Then we use movzx.
e075ae69 1905(define_insn "*movqi_1"
0b5107cf
JH
1906 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1907 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
e075ae69 1908 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
886c62d1
JVA
1909 "*
1910{
e075ae69 1911 switch (get_attr_type (insn))
b76c90cf 1912 {
e075ae69 1913 case TYPE_IMOVX:
1a06f5fe 1914 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
e075ae69
RH
1915 abort ();
1916 return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1917 default:
6ef67412 1918 if (get_attr_mode (insn) == MODE_SI)
e075ae69 1919 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
b76c90cf 1920 else
e075ae69 1921 return \"mov{b}\\t{%1, %0|%0, %1}\";
b76c90cf 1922 }
e075ae69
RH
1923}"
1924 [(set (attr "type")
0b5107cf
JH
1925 (cond [(and (eq_attr "alternative" "3")
1926 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1927 (const_int 0))
1928 (eq (symbol_ref "TARGET_QIMODE_MATH")
1929 (const_int 0))))
1930 (const_string "imov")
1931 (eq_attr "alternative" "3,5")
e075ae69
RH
1932 (const_string "imovx")
1933 (and (ne (symbol_ref "TARGET_MOVX")
1934 (const_int 0))
0b5107cf 1935 (eq_attr "alternative" "2"))
e075ae69
RH
1936 (const_string "imovx")
1937 ]
1938 (const_string "imov")))
6ef67412
JH
1939 (set (attr "mode")
1940 (cond [(eq_attr "alternative" "3,4,5")
1941 (const_string "SI")
1942 (eq_attr "alternative" "6")
1943 (const_string "QI")
1944 (eq_attr "type" "imovx")
1945 (const_string "SI")
0b5107cf 1946 (and (eq_attr "type" "imov")
6ef67412 1947 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
1948 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1949 (const_int 0))))
6ef67412 1950 (const_string "SI")
0b5107cf
JH
1951 ;; Avoid partial register stalls when not using QImode arithmetic
1952 (and (eq_attr "type" "imov")
6ef67412 1953 (and (eq_attr "alternative" "0,1,2")
0b5107cf
JH
1954 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1955 (const_int 0))
1956 (eq (symbol_ref "TARGET_QIMODE_MATH")
1957 (const_int 0)))))
6ef67412
JH
1958 (const_string "SI")
1959 ]
1960 (const_string "QI")))])
e075ae69
RH
1961
1962(define_expand "reload_outqi"
1963 [(parallel [(match_operand:QI 0 "" "=m")
1964 (match_operand:QI 1 "register_operand" "r")
1965 (match_operand:QI 2 "register_operand" "=&q")])]
1966 ""
1967 "
1968{
1969 rtx op0, op1, op2;
1970 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
886c62d1 1971
e075ae69
RH
1972 if (reg_overlap_mentioned_p (op2, op0))
1973 abort ();
1974 if (! q_regs_operand (op1, QImode))
1975 {
1976 emit_insn (gen_movqi (op2, op1));
1977 op1 = op2;
1978 }
1979 emit_insn (gen_movqi (op0, op1));
1980 DONE;
886c62d1
JVA
1981}")
1982
e075ae69
RH
1983(define_insn "*swapqi"
1984 [(set (match_operand:QI 0 "register_operand" "+r")
1985 (match_operand:QI 1 "register_operand" "+r"))
1986 (set (match_dup 1)
1987 (match_dup 0))]
1988 ""
1989 "xchg{b}\\t%1, %0"
1990 [(set_attr "type" "imov")
1991 (set_attr "pent_pair" "np")
6ef67412
JH
1992 (set_attr "mode" "QI")
1993 (set_attr "modrm" "0")
e075ae69 1994 (set_attr "ppro_uops" "few")])
886c62d1 1995
2f2a49e8 1996(define_expand "movstrictqi"
4cbfbb1b 1997 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2f2a49e8 1998 (match_operand:QI 1 "general_operand" ""))]
e075ae69 1999 "! TARGET_PARTIAL_REG_STALL"
2f2a49e8
MM
2000 "
2001{
2002 /* Don't generate memory->memory moves, go through a register */
e075ae69
RH
2003 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2004 operands[1] = force_reg (QImode, operands[1]);
2f2a49e8
MM
2005}")
2006
e075ae69 2007(define_insn "*movstrictqi_1"
2ae0f82c 2008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
c0f06344 2009 (match_operand:QI 1 "general_operand" "*qn,m"))]
e075ae69
RH
2010 "! TARGET_PARTIAL_REG_STALL
2011 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2012 "mov{b}\\t{%1, %0|%0, %1}"
6ef67412
JH
2013 [(set_attr "type" "imov")
2014 (set_attr "mode" "QI")])
2015
2016(define_insn "*movstrictqi_xor"
5e6d6bf0 2017 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
6ef67412
JH
2018 (match_operand:QI 1 "const0_operand" "i"))
2019 (clobber (reg:CC 17))]
2020 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2021 "xor{b}\\t{%0, %0|%0, %0}"
2022 [(set_attr "type" "alu1")
2023 (set_attr "mode" "QI")
2024 (set_attr "length_immediate" "0")])
e075ae69
RH
2025
2026(define_insn "*movsi_extv_1"
d2836273
JH
2027 [(set (match_operand:SI 0 "register_operand" "=R")
2028 (sign_extract:SI (match_operand:SI 1 "ext_register_operand" "Q")
e075ae69
RH
2029 (const_int 8)
2030 (const_int 8)))]
2031 ""
2032 "movs{bl|x}\\t{%h1, %0|%0, %h1}"
6ef67412
JH
2033 [(set_attr "type" "imovx")
2034 (set_attr "mode" "SI")])
e075ae69
RH
2035
2036(define_insn "*movhi_extv_1"
d2836273
JH
2037 [(set (match_operand:HI 0 "register_operand" "=R")
2038 (sign_extract:HI (match_operand:SI 1 "ext_register_operand" "Q")
e075ae69
RH
2039 (const_int 8)
2040 (const_int 8)))]
2041 ""
2042 "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
6ef67412
JH
2043 [(set_attr "type" "imovx")
2044 (set_attr "mode" "SI")])
e075ae69
RH
2045
2046(define_insn "*movqi_extv_1"
7c6b971d
JH
2047 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
2048 (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
e075ae69
RH
2049 (const_int 8)
2050 (const_int 8)))]
2051 ""
886c62d1
JVA
2052 "*
2053{
e075ae69 2054 switch (get_attr_type (insn))
886c62d1 2055 {
e075ae69
RH
2056 case TYPE_IMOVX:
2057 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2058 default:
2059 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
886c62d1 2060 }
e075ae69
RH
2061}"
2062 [(set (attr "type")
2063 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2064 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2065 (ne (symbol_ref "TARGET_MOVX")
2066 (const_int 0))))
2067 (const_string "imovx")
6ef67412
JH
2068 (const_string "imov")))
2069 (set (attr "mode")
2070 (if_then_else (eq_attr "type" "imovx")
2071 (const_string "SI")
2072 (const_string "QI")))])
e075ae69
RH
2073
2074(define_insn "*movsi_extzv_1"
d2836273
JH
2075 [(set (match_operand:SI 0 "register_operand" "=R")
2076 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
2077 (const_int 8)
2078 (const_int 8)))]
2079 ""
2080 "movz{bl|x}\\t{%h1, %0|%0, %h1}"
6ef67412
JH
2081 [(set_attr "type" "imovx")
2082 (set_attr "mode" "SI")])
886c62d1 2083
d2836273
JH
2084(define_insn "*movqi_extzv_2"
2085 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2086 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
e075ae69
RH
2087 (const_int 8)
2088 (const_int 8)) 0))]
d2836273 2089 "!TARGET_64BIT"
f31fce3f
JW
2090 "*
2091{
e075ae69 2092 switch (get_attr_type (insn))
f31fce3f 2093 {
e075ae69
RH
2094 case TYPE_IMOVX:
2095 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2096 default:
2097 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2098 }
2099}"
2100 [(set (attr "type")
2101 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2102 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2103 (ne (symbol_ref "TARGET_MOVX")
2104 (const_int 0))))
2105 (const_string "imovx")
6ef67412
JH
2106 (const_string "imov")))
2107 (set (attr "mode")
2108 (if_then_else (eq_attr "type" "imovx")
2109 (const_string "SI")
2110 (const_string "QI")))])
e075ae69 2111
d2836273
JH
2112(define_insn "*movqi_extzv_2_rex64"
2113 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2114 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2115 (const_int 8)
2116 (const_int 8)) 0))]
2117 "TARGET_64BIT"
2118 "*
2119{
2120 switch (get_attr_type (insn))
2121 {
2122 case TYPE_IMOVX:
2123 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2124 default:
2125 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2126 }
2127}"
2128 [(set (attr "type")
2129 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2130 (ne (symbol_ref "TARGET_MOVX")
2131 (const_int 0)))
2132 (const_string "imovx")
2133 (const_string "imov")))
2134 (set (attr "mode")
2135 (if_then_else (eq_attr "type" "imovx")
2136 (const_string "SI")
2137 (const_string "QI")))])
2138
e075ae69 2139(define_insn "*movsi_insv_1"
d2836273 2140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2141 (const_int 8)
2142 (const_int 8))
d2836273
JH
2143 (match_operand:SI 1 "nonimmediate_operand" "Qm"))]
2144 "!TARGET_64BIT"
2145 "mov{b}\\t{%b1, %h0|%h0, %b1}"
2146 [(set_attr "type" "imov")
2147 (set_attr "mode" "QI")])
2148
2149(define_insn "*movsi_insv_1_rex64"
2150 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2151 (const_int 8)
2152 (const_int 8))
2153 (match_operand:SI 1 "ext_register_operand" "Q"))]
2154 "TARGET_64BIT"
e075ae69 2155 "mov{b}\\t{%b1, %h0|%h0, %b1}"
6ef67412
JH
2156 [(set_attr "type" "imov")
2157 (set_attr "mode" "QI")])
e075ae69
RH
2158
2159(define_insn "*movqi_insv_2"
d2836273 2160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
e075ae69
RH
2161 (const_int 8)
2162 (const_int 8))
d2836273 2163 (and:SI (lshiftrt:SI (match_operand:SI 1 "ext_register_operand" "Q")
e075ae69
RH
2164 (const_int 8))
2165 (const_int 255)))]
2166 ""
2167 "mov{b}\\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
2168 [(set_attr "type" "imov")
2169 (set_attr "mode" "QI")])
f31fce3f 2170
e075ae69 2171(define_expand "movdi"
4cbfbb1b 2172 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
2173 (match_operand:DI 1 "general_operand" ""))]
2174 ""
2175 "ix86_expand_move (DImode, operands); DONE;")
f31fce3f 2176
e075ae69
RH
2177(define_insn "*pushdi"
2178 [(set (match_operand:DI 0 "push_operand" "=<")
2c5a510c 2179 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1e07edd3 2180 "!TARGET_64BIT"
e075ae69 2181 "#")
f31fce3f 2182
e075ae69 2183(define_insn "*movdi_2"
915119a5
BS
2184 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y")
2185 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))]
1e07edd3
JH
2186 "!TARGET_64BIT
2187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
915119a5
BS
2188 "@
2189 #
2190 #
2191 movq\\t{%1, %0|%0, %1}
2192 movq\\t{%1, %0|%0, %1}"
2193 [(set_attr "type" "*,*,mmx,mmx")])
dc0f0eb8 2194
e075ae69
RH
2195(define_split
2196 [(set (match_operand:DI 0 "push_operand" "")
2197 (match_operand:DI 1 "general_operand" ""))]
1e07edd3 2198 "reload_completed && ! MMX_REG_P (operands[1]) && !TARGET_64BIT"
2450a057
JH
2199 [(const_int 0)]
2200 "if (!ix86_split_long_move (operands)) abort (); DONE;")
f31fce3f 2201
e075ae69 2202;; %%% This multiword shite has got to go.
e075ae69 2203(define_split
c76aab11 2204 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69 2205 (match_operand:DI 1 "general_operand" ""))]
915119a5 2206 "reload_completed && ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])"
2450a057
JH
2207 [(set (match_dup 2) (match_dup 5))
2208 (set (match_dup 3) (match_dup 6))]
2209 "if (ix86_split_long_move (operands)) DONE;")
e075ae69 2210
0be5d99f 2211(define_expand "movsf"
4cbfbb1b 2212 [(set (match_operand:SF 0 "nonimmediate_operand" "")
0be5d99f
MM
2213 (match_operand:SF 1 "general_operand" ""))]
2214 ""
e075ae69
RH
2215 "ix86_expand_move (SFmode, operands); DONE;")
2216
2217(define_insn "*pushsf"
446988df 2218 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
c6e95f34 2219 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
e075ae69
RH
2220 ""
2221 "*
0be5d99f 2222{
e075ae69 2223 switch (which_alternative)
0be5d99f 2224 {
e075ae69
RH
2225 case 0:
2226 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2227 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2228 operands[2] = stack_pointer_rtx;
2229 operands[3] = GEN_INT (4);
2230 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2231 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
e075ae69 2232 else
7ebb782b 2233 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
0bb6c81b 2234
e075ae69
RH
2235 case 1:
2236 return \"push{l}\\t%1\";
446988df
JH
2237 case 2:
2238 return \"#\";
e075ae69
RH
2239
2240 default:
2241 abort ();
0bb6c81b 2242 }
e075ae69 2243}"
446988df
JH
2244 [(set_attr "type" "multi,push,multi")
2245 (set_attr "mode" "SF,SI,SF")])
0be5d99f 2246
d7a29404
JH
2247(define_split
2248 [(set (match_operand:SF 0 "push_operand" "")
2249 (match_operand:SF 1 "memory_operand" ""))]
2250 "reload_completed
2251 && GET_CODE (operands[1]) == MEM
2252 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2253 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2254 [(set (match_dup 0)
2255 (match_dup 1))]
2256 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2257
2258
e075ae69
RH
2259;; %%% Kill this when call knows how to work this out.
2260(define_split
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "register_operand" ""))]
446988df 2263 "ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
2264 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2265 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2266
2267(define_insn "*movsf_1"
2b04e52b
JH
2268 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2269 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
d7a29404
JH
2270 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2271 && (reload_in_progress || reload_completed
2272 || GET_CODE (operands[1]) != CONST_DOUBLE
2273 || memory_operand (operands[0], SFmode))"
886c62d1
JVA
2274 "*
2275{
e075ae69 2276 switch (which_alternative)
886c62d1 2277 {
e075ae69 2278 case 0:
0c174a68
AB
2279 if (REG_P (operands[1])
2280 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2281 return \"fstp\\t%y0\";
e075ae69 2282 else if (STACK_TOP_P (operands[0]))
7ebb782b 2283 return \"fld%z1\\t%y1\";
886c62d1 2284 else
7ebb782b 2285 return \"fst\\t%y0\";
886c62d1 2286
e075ae69
RH
2287 case 1:
2288 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2289 return \"fstp%z0\\t%y0\";
886c62d1 2290 else
7ebb782b 2291 return \"fst%z0\\t%y0\";
886c62d1 2292
e075ae69
RH
2293 case 2:
2294 switch (standard_80387_constant_p (operands[1]))
2295 {
2296 case 1:
2297 return \"fldz\";
2298 case 2:
2299 return \"fld1\";
2300 }
2301 abort();
886c62d1 2302
e075ae69
RH
2303 case 3:
2304 case 4:
e075ae69 2305 return \"mov{l}\\t{%1, %0|%0, %1}\";
446988df 2306 case 5:
2b04e52b 2307 return \"pxor\\t%0, %0\";
446988df 2308 case 6:
2b04e52b 2309 if (TARGET_PARTIAL_REG_DEPENDENCY)
79005df5 2310 return \"movaps\\t{%1, %0|%0, %1}\";
2b04e52b
JH
2311 else
2312 return \"movss\\t{%1, %0|%0, %1}\";
2313 case 7:
2314 case 8:
446988df 2315 return \"movss\\t{%1, %0|%0, %1}\";
886c62d1 2316
e075ae69
RH
2317 default:
2318 abort();
2319 }
2ae0f82c 2320}"
2b04e52b
JH
2321 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2322 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
d7a29404 2323
a4414093 2324(define_insn "*swapsf"
e075ae69
RH
2325 [(set (match_operand:SF 0 "register_operand" "+f")
2326 (match_operand:SF 1 "register_operand" "+f"))
0be5d99f
MM
2327 (set (match_dup 1)
2328 (match_dup 0))]
446988df 2329 "reload_completed || !TARGET_SSE2"
0be5d99f
MM
2330 "*
2331{
2332 if (STACK_TOP_P (operands[0]))
e075ae69 2333 return \"fxch\\t%1\";
0be5d99f 2334 else
e075ae69
RH
2335 return \"fxch\\t%0\";
2336}"
6ef67412
JH
2337 [(set_attr "type" "fxch")
2338 (set_attr "mode" "SF")])
0be5d99f 2339
e075ae69 2340(define_expand "movdf"
4cbfbb1b 2341 [(set (match_operand:DF 0 "nonimmediate_operand" "")
e075ae69
RH
2342 (match_operand:DF 1 "general_operand" ""))]
2343 ""
2344 "ix86_expand_move (DFmode, operands); DONE;")
55953cea 2345
8fcaaa80
JH
2346;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2347;; Size of pushdf using integer insturctions is 2+2*memory operand size
2348;; On the average, pushdf using integers can be still shorter. Allow this
2349;; pattern for optimize_size too.
2350
0b5107cf 2351(define_insn "*pushdf_nointeger"
446988df 2352 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
c6e95f34 2353 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
0b5107cf
JH
2354 "!TARGET_INTEGER_DFMODE_MOVES"
2355 "*
2356{
2357 switch (which_alternative)
2358 {
2359 case 0:
2360 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2361 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2362 operands[2] = stack_pointer_rtx;
2363 operands[3] = GEN_INT (8);
2364 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2365 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2366 else
2367 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2368
2369 case 1:
2370 case 2:
446988df 2371 case 3:
0b5107cf
JH
2372 return \"#\";
2373
2374 default:
2375 abort ();
2376 }
2377}"
6ef67412 2378 [(set_attr "type" "multi")
446988df 2379 (set_attr "mode" "DF,SI,SI,DF")])
0b5107cf
JH
2380
2381(define_insn "*pushdf_integer"
446988df
JH
2382 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2383 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
0b5107cf 2384 "TARGET_INTEGER_DFMODE_MOVES"
f31fce3f
JW
2385 "*
2386{
e075ae69 2387 switch (which_alternative)
f31fce3f 2388 {
e075ae69
RH
2389 case 0:
2390 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2391 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2392 operands[2] = stack_pointer_rtx;
2393 operands[3] = GEN_INT (8);
2394 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2395 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
f31fce3f 2396 else
7ebb782b 2397 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
dc0f0eb8 2398
e075ae69 2399 case 1:
446988df 2400 case 2:
e075ae69 2401 return \"#\";
dc0f0eb8 2402
e075ae69
RH
2403 default:
2404 abort ();
2405 }
2406}"
6ef67412 2407 [(set_attr "type" "multi")
446988df 2408 (set_attr "mode" "DF,SI,DF")])
f31fce3f 2409
e075ae69 2410;; %%% Kill this when call knows how to work this out.
f72b27a5
JH
2411(define_split
2412 [(set (match_operand:DF 0 "push_operand" "")
e075ae69 2413 (match_operand:DF 1 "register_operand" ""))]
446988df 2414 "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
2415 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2416 (set (mem:DF (reg:SI 7)) (match_dup 1))]
f72b27a5 2417 "")
f31fce3f 2418
e075ae69
RH
2419(define_split
2420 [(set (match_operand:DF 0 "push_operand" "")
0be5d99f 2421 (match_operand:DF 1 "general_operand" ""))]
e075ae69 2422 "reload_completed"
2450a057
JH
2423 [(const_int 0)]
2424 "if (!ix86_split_long_move (operands)) abort (); DONE;")
0be5d99f 2425
8fcaaa80
JH
2426;; Moving is usually shorter when only FP registers are used. This separate
2427;; movdf pattern avoids the use of integer registers for FP operations
2428;; when optimizing for size.
2429
2430(define_insn "*movdf_nointeger"
2b04e52b
JH
2431 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2432 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
8fcaaa80 2433 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
0b5107cf 2434 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
d7a29404
JH
2435 && (reload_in_progress || reload_completed
2436 || GET_CODE (operands[1]) != CONST_DOUBLE
2437 || memory_operand (operands[0], DFmode))"
8fcaaa80
JH
2438 "*
2439{
2440 switch (which_alternative)
2441 {
2442 case 0:
2443 if (REG_P (operands[1])
2444 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2445 return \"fstp\\t%y0\";
2446 else if (STACK_TOP_P (operands[0]))
2447 return \"fld%z1\\t%y1\";
2448 else
2449 return \"fst\\t%y0\";
2450
2451 case 1:
2452 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2453 return \"fstp%z0\\t%y0\";
2454 else
2455 return \"fst%z0\\t%y0\";
2456
2457 case 2:
2458 switch (standard_80387_constant_p (operands[1]))
2459 {
2460 case 1:
2461 return \"fldz\";
2462 case 2:
2463 return \"fld1\";
2464 }
2465 abort();
2466
2467 case 3:
2468 case 4:
2469 return \"#\";
446988df 2470 case 5:
2b04e52b 2471 return \"pxor\\t%0, %0\";
446988df 2472 case 6:
2b04e52b 2473 if (TARGET_PARTIAL_REG_DEPENDENCY)
79005df5 2474 return \"movapd\\t{%1, %0|%0, %1}\";
2b04e52b
JH
2475 else
2476 return \"movsd\\t{%1, %0|%0, %1}\";
2477 case 7:
2478 case 8:
2479 return \"movsd\\t{%1, %0|%0, %1}\";
8fcaaa80
JH
2480
2481 default:
2482 abort();
2483 }
2484}"
2b04e52b
JH
2485 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2486 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
8fcaaa80
JH
2487
2488(define_insn "*movdf_integer"
2b04e52b
JH
2489 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2490 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
8fcaaa80 2491 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
0b5107cf 2492 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
d7a29404
JH
2493 && (reload_in_progress || reload_completed
2494 || GET_CODE (operands[1]) != CONST_DOUBLE
2495 || memory_operand (operands[0], DFmode))"
886c62d1
JVA
2496 "*
2497{
e075ae69 2498 switch (which_alternative)
886c62d1 2499 {
e075ae69 2500 case 0:
0c174a68
AB
2501 if (REG_P (operands[1])
2502 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2503 return \"fstp\\t%y0\";
e075ae69 2504 else if (STACK_TOP_P (operands[0]))
7ebb782b 2505 return \"fld%z1\\t%y1\";
886c62d1 2506 else
7ebb782b 2507 return \"fst\\t%y0\";
886c62d1 2508
e075ae69
RH
2509 case 1:
2510 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2511 return \"fstp%z0\\t%y0\";
886c62d1 2512 else
7ebb782b 2513 return \"fst%z0\\t%y0\";
886c62d1 2514
e075ae69
RH
2515 case 2:
2516 switch (standard_80387_constant_p (operands[1]))
2517 {
2518 case 1:
2519 return \"fldz\";
2520 case 2:
2521 return \"fld1\";
2522 }
2523 abort();
886c62d1 2524
e075ae69
RH
2525 case 3:
2526 case 4:
e075ae69 2527 return \"#\";
886c62d1 2528
446988df 2529 case 5:
2b04e52b 2530 return \"pxor\\t%0, %0\";
446988df 2531 case 6:
2b04e52b
JH
2532 if (TARGET_PARTIAL_REG_DEPENDENCY)
2533 return \"movapd\\t{%1, %0|%0, %1}\";
2534 else
2535 return \"movsd\\t{%1, %0|%0, %1}\";
2536 case 7:
2537 case 8:
446988df
JH
2538 return \"movsd\\t{%1, %0|%0, %1}\";
2539
e075ae69
RH
2540 default:
2541 abort();
2542 }
2ae0f82c 2543}"
2b04e52b
JH
2544 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2545 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2ae0f82c 2546
e075ae69
RH
2547(define_split
2548 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2549 (match_operand:DF 1 "general_operand" ""))]
2550 "reload_completed
2551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
446988df 2552 && ! (ANY_FP_REG_P (operands[0]) ||
e075ae69 2553 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2554 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2555 && ! (ANY_FP_REG_P (operands[1]) ||
e075ae69 2556 (GET_CODE (operands[1]) == SUBREG
446988df 2557 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2450a057
JH
2558 [(set (match_dup 2) (match_dup 5))
2559 (set (match_dup 3) (match_dup 6))]
2560 "if (ix86_split_long_move (operands)) DONE;")
886c62d1 2561
a4414093 2562(define_insn "*swapdf"
e075ae69
RH
2563 [(set (match_operand:DF 0 "register_operand" "+f")
2564 (match_operand:DF 1 "register_operand" "+f"))
0be5d99f
MM
2565 (set (match_dup 1)
2566 (match_dup 0))]
446988df 2567 "reload_completed || !TARGET_SSE2"
0be5d99f
MM
2568 "*
2569{
2570 if (STACK_TOP_P (operands[0]))
e075ae69 2571 return \"fxch\\t%1\";
0be5d99f 2572 else
e075ae69
RH
2573 return \"fxch\\t%0\";
2574}"
6ef67412
JH
2575 [(set_attr "type" "fxch")
2576 (set_attr "mode" "DF")])
e075ae69
RH
2577
2578(define_expand "movxf"
4cbfbb1b 2579 [(set (match_operand:XF 0 "nonimmediate_operand" "")
e075ae69 2580 (match_operand:XF 1 "general_operand" ""))]
1e07edd3 2581 "!TARGET_64BIT"
e075ae69 2582 "ix86_expand_move (XFmode, operands); DONE;")
0be5d99f 2583
2b589241
JH
2584(define_expand "movtf"
2585 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2586 (match_operand:TF 1 "general_operand" ""))]
2587 ""
2588 "ix86_expand_move (TFmode, operands); DONE;")
2589
8fcaaa80
JH
2590;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2591;; Size of pushdf using integer insturctions is 3+3*memory operand size
2592;; Pushing using integer instructions is longer except for constants
2593;; and direct memory references.
2594;; (assuming that any given constant is pushed only once, but this ought to be
2595;; handled elsewhere).
2596
2597(define_insn "*pushxf_nointeger"
1e07edd3 2598 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2c5a510c 2599 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
1e07edd3 2600 "optimize_size && !TARGET_64BIT"
8fcaaa80
JH
2601 "*
2602{
2603 switch (which_alternative)
2604 {
2605 case 0:
2606 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2607 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2608 operands[2] = stack_pointer_rtx;
2609 operands[3] = GEN_INT (12);
2610 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2611 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2612 else
2613 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2614
2615 case 1:
2616 case 2:
2617 return \"#\";
2618
2619 default:
2620 abort ();
2621 }
2622}"
6ef67412
JH
2623 [(set_attr "type" "multi")
2624 (set_attr "mode" "XF,SI,SI")])
8fcaaa80 2625
2b589241
JH
2626(define_insn "*pushtf_nointeger"
2627 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2628 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2629 "optimize_size"
2630 "*
2631{
2632 switch (which_alternative)
2633 {
2634 case 0:
2635 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2636 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2637 operands[2] = stack_pointer_rtx;
2638 operands[3] = GEN_INT (16);
2639 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2640 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2641 else
2642 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2643
2644 case 1:
2645 case 2:
2646 return \"#\";
2647
2648 default:
2649 abort ();
2650 }
2651}"
2652 [(set_attr "type" "multi")
2653 (set_attr "mode" "XF,SI,SI")])
2654
8fcaaa80 2655(define_insn "*pushxf_integer"
2450a057 2656 [(set (match_operand:XF 0 "push_operand" "=<,<")
1e07edd3
JH
2657 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2658 "!optimize_size && !TARGET_64BIT"
f31fce3f
JW
2659 "*
2660{
8fcaaa80
JH
2661 switch (which_alternative)
2662 {
2663 case 0:
2664 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2665 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2666 operands[2] = stack_pointer_rtx;
2667 operands[3] = GEN_INT (12);
2668 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2669 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2670 else
2671 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2672
2673 case 1:
2674 return \"#\";
2675
2676 default:
2677 abort ();
2678 }
e075ae69 2679}"
6ef67412
JH
2680 [(set_attr "type" "multi")
2681 (set_attr "mode" "XF,SI")])
f31fce3f 2682
2b589241
JH
2683(define_insn "*pushtf_integer"
2684 [(set (match_operand:TF 0 "push_operand" "=<,<")
2685 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2686 "!optimize_size"
2687 "*
2688{
2689 switch (which_alternative)
2690 {
2691 case 0:
2692 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2693 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2694 operands[2] = stack_pointer_rtx;
2695 operands[3] = GEN_INT (16);
2696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2697 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2698 else
2699 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2700
2701 case 1:
2702 return \"#\";
2703
2704 default:
2705 abort ();
2706 }
2707}"
2708 [(set_attr "type" "multi")
2709 (set_attr "mode" "XF,SI")])
2710
2450a057 2711(define_split
2b589241
JH
2712 [(set (match_operand 0 "push_operand" "")
2713 (match_operand 1 "general_operand" ""))]
2450a057 2714 "reload_completed
2b589241
JH
2715 && (GET_MODE (operands[0]) == XFmode
2716 || GET_MODE (operands[0]) == TFmode
2717 || GET_MODE (operands[0]) == DFmode)
446988df 2718 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
2450a057
JH
2719 [(const_int 0)]
2720 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2721
f72b27a5
JH
2722(define_split
2723 [(set (match_operand:XF 0 "push_operand" "")
e075ae69 2724 (match_operand:XF 1 "register_operand" ""))]
446988df 2725 "ANY_FP_REGNO_P (REGNO (operands[1]))"
e075ae69
RH
2726 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2727 (set (mem:XF (reg:SI 7)) (match_dup 1))])
f31fce3f 2728
2b589241
JH
2729(define_split
2730 [(set (match_operand:TF 0 "push_operand" "")
2731 (match_operand:TF 1 "register_operand" ""))]
446988df 2732 "ANY_FP_REGNO_P (REGNO (operands[1]))"
2b589241
JH
2733 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2734 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2735
8fcaaa80
JH
2736;; Do not use integer registers when optimizing for size
2737(define_insn "*movxf_nointeger"
2738 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2739 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2740 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1e07edd3 2741 && !TARGET_64BIT
d7a29404
JH
2742 && optimize_size
2743 && (reload_in_progress || reload_completed
2744 || GET_CODE (operands[1]) != CONST_DOUBLE
2745 || memory_operand (operands[0], XFmode))"
8fcaaa80 2746 "*
0be5d99f 2747{
8fcaaa80
JH
2748 switch (which_alternative)
2749 {
2750 case 0:
2751 if (REG_P (operands[1])
2752 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2753 return \"fstp\\t%y0\";
2754 else if (STACK_TOP_P (operands[0]))
2755 return \"fld%z1\\t%y1\";
2756 else
2757 return \"fst\\t%y0\";
0be5d99f 2758
8fcaaa80
JH
2759 case 1:
2760 /* There is no non-popping store to memory for XFmode. So if
2761 we need one, follow the store with a load. */
2762 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2763 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2764 else
2765 return \"fstp%z0\\t%y0\";
2766
2767 case 2:
2768 switch (standard_80387_constant_p (operands[1]))
2769 {
2770 case 1:
2771 return \"fldz\";
2772 case 2:
2773 return \"fld1\";
2774 }
2775 break;
2776
2777 case 3: case 4:
2778 return \"#\";
2779 }
2780 abort();
2781}"
6ef67412
JH
2782 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2783 (set_attr "mode" "XF,XF,XF,SI,SI")])
8fcaaa80 2784
2b589241
JH
2785(define_insn "*movtf_nointeger"
2786 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2787 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2788 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789 && optimize_size
2790 && (reload_in_progress || reload_completed
2791 || GET_CODE (operands[1]) != CONST_DOUBLE
2792 || memory_operand (operands[0], TFmode))"
2793 "*
2794{
2795 switch (which_alternative)
2796 {
2797 case 0:
2798 if (REG_P (operands[1])
2799 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800 return \"fstp\\t%y0\";
2801 else if (STACK_TOP_P (operands[0]))
2802 return \"fld%z1\\t%y1\";
2803 else
2804 return \"fst\\t%y0\";
2805
2806 case 1:
2807 /* There is no non-popping store to memory for XFmode. So if
2808 we need one, follow the store with a load. */
2809 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2810 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2811 else
2812 return \"fstp%z0\\t%y0\";
2813
2814 case 2:
2815 switch (standard_80387_constant_p (operands[1]))
2816 {
2817 case 1:
2818 return \"fldz\";
2819 case 2:
2820 return \"fld1\";
2821 }
2822 break;
2823
2824 case 3: case 4:
2825 return \"#\";
2826 }
2827 abort();
2828}"
2829 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2830 (set_attr "mode" "XF,XF,XF,SI,SI")])
2831
8fcaaa80
JH
2832(define_insn "*movxf_integer"
2833 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2834 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2835 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1e07edd3 2836 && !TARGET_64BIT
d7a29404
JH
2837 && !optimize_size
2838 && (reload_in_progress || reload_completed
2839 || GET_CODE (operands[1]) != CONST_DOUBLE
2840 || memory_operand (operands[0], XFmode))"
4fb21e90
JVA
2841 "*
2842{
e075ae69 2843 switch (which_alternative)
4fb21e90 2844 {
e075ae69 2845 case 0:
0c174a68
AB
2846 if (REG_P (operands[1])
2847 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2848 return \"fstp\\t%y0\";
e075ae69 2849 else if (STACK_TOP_P (operands[0]))
7ebb782b 2850 return \"fld%z1\\t%y1\";
4fb21e90 2851 else
7ebb782b 2852 return \"fst\\t%y0\";
4fb21e90 2853
e075ae69
RH
2854 case 1:
2855 /* There is no non-popping store to memory for XFmode. So if
2856 we need one, follow the store with a load. */
2857 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 2858 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
e075ae69 2859 else
7ebb782b 2860 return \"fstp%z0\\t%y0\";
2f17722a 2861
e075ae69
RH
2862 case 2:
2863 switch (standard_80387_constant_p (operands[1]))
2864 {
2865 case 1:
2866 return \"fldz\";
2867 case 2:
2868 return \"fld1\";
2869 }
2870 break;
467403ca
RH
2871
2872 case 3: case 4:
2873 return \"#\";
4fb21e90 2874 }
e075ae69
RH
2875 abort();
2876}"
6ef67412
JH
2877 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2878 (set_attr "mode" "XF,XF,XF,SI,SI")])
4fb21e90 2879
2b589241
JH
2880(define_insn "*movtf_integer"
2881 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2882 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2883 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2884 && !optimize_size
2885 && (reload_in_progress || reload_completed
2886 || GET_CODE (operands[1]) != CONST_DOUBLE
2887 || memory_operand (operands[0], TFmode))"
2888 "*
2889{
2890 switch (which_alternative)
2891 {
2892 case 0:
2893 if (REG_P (operands[1])
2894 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2895 return \"fstp\\t%y0\";
2896 else if (STACK_TOP_P (operands[0]))
2897 return \"fld%z1\\t%y1\";
2898 else
2899 return \"fst\\t%y0\";
2900
2901 case 1:
2902 /* There is no non-popping store to memory for XFmode. So if
2903 we need one, follow the store with a load. */
2904 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2905 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2906 else
2907 return \"fstp%z0\\t%y0\";
2908
2909 case 2:
2910 switch (standard_80387_constant_p (operands[1]))
2911 {
2912 case 1:
2913 return \"fldz\";
2914 case 2:
2915 return \"fld1\";
2916 }
2917 break;
2918
2919 case 3: case 4:
2920 return \"#\";
2921 }
2922 abort();
2923}"
2924 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2925 (set_attr "mode" "XF,XF,XF,SI,SI")])
2926
467403ca 2927(define_split
2b589241
JH
2928 [(set (match_operand 0 "nonimmediate_operand" "")
2929 (match_operand 1 "general_operand" ""))]
2450a057 2930 "reload_completed
8fcaaa80 2931 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2b589241 2932 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
446988df 2933 && ! (ANY_FP_REG_P (operands[0]) ||
8fcaaa80 2934 (GET_CODE (operands[0]) == SUBREG
446988df
JH
2935 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2936 && ! (ANY_FP_REG_P (operands[1]) ||
8fcaaa80 2937 (GET_CODE (operands[1]) == SUBREG
446988df 2938 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2450a057
JH
2939 [(set (match_dup 2) (match_dup 5))
2940 (set (match_dup 3) (match_dup 6))
2941 (set (match_dup 4) (match_dup 7))]
2942 "if (ix86_split_long_move (operands)) DONE;")
467403ca 2943
d7a29404 2944(define_split
2b589241
JH
2945 [(set (match_operand 0 "register_operand" "")
2946 (match_operand 1 "memory_operand" ""))]
d7a29404
JH
2947 "reload_completed
2948 && GET_CODE (operands[1]) == MEM
2b04e52b
JH
2949 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
2950 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
d7a29404
JH
2951 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2952 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2b04e52b
JH
2953 && (!(SSE_REG_P (operands[0]) ||
2954 (GET_CODE (operands[0]) == SUBREG
2955 && SSE_REG_P (SUBREG_REG (operands[0]))))
2956 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2957 && (!(FP_REG_P (operands[0]) ||
2958 (GET_CODE (operands[0]) == SUBREG
2959 && FP_REG_P (SUBREG_REG (operands[0]))))
2960 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
d7a29404
JH
2961 [(set (match_dup 0)
2962 (match_dup 1))]
2963 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2964
e075ae69
RH
2965(define_insn "swapxf"
2966 [(set (match_operand:XF 0 "register_operand" "+f")
2967 (match_operand:XF 1 "register_operand" "+f"))
0be5d99f
MM
2968 (set (match_dup 1)
2969 (match_dup 0))]
2970 ""
2971 "*
2972{
2973 if (STACK_TOP_P (operands[0]))
e075ae69 2974 return \"fxch\\t%1\";
0be5d99f 2975 else
e075ae69
RH
2976 return \"fxch\\t%0\";
2977}"
0b5107cf 2978 [(set_attr "type" "fxch")
6ef67412 2979 (set_attr "mode" "XF")])
2b589241
JH
2980
2981(define_insn "swaptf"
2982 [(set (match_operand:TF 0 "register_operand" "+f")
2983 (match_operand:TF 1 "register_operand" "+f"))
2984 (set (match_dup 1)
2985 (match_dup 0))]
2986 ""
2987 "*
2988{
2989 if (STACK_TOP_P (operands[0]))
2990 return \"fxch\\t%1\";
2991 else
2992 return \"fxch\\t%0\";
2993}"
2994 [(set_attr "type" "fxch")
2995 (set_attr "mode" "XF")])
886c62d1 2996\f
e075ae69 2997;; Zero extension instructions
886c62d1 2998
8f7661f2
JH
2999(define_expand "zero_extendhisi2"
3000 [(set (match_operand:SI 0 "register_operand" "")
3001 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
d626200a 3002 ""
8f7661f2 3003 "
e075ae69 3004{
8f7661f2 3005 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2ae0f82c 3006 {
8f7661f2
JH
3007 operands[1] = force_reg (HImode, operands[1]);
3008 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3009 DONE;
2ae0f82c 3010 }
8f7661f2 3011}")
886c62d1 3012
8f7661f2
JH
3013(define_insn "zero_extendhisi2_and"
3014 [(set (match_operand:SI 0 "register_operand" "=r")
3015 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
e075ae69 3016 (clobber (reg:CC 17))]
8f7661f2
JH
3017 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018 "#"
6ef67412
JH
3019 [(set_attr "type" "alu1")
3020 (set_attr "mode" "SI")])
2ae0f82c
SC
3021
3022(define_split
3023 [(set (match_operand:SI 0 "register_operand" "")
8f7661f2 3024 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
e075ae69 3025 (clobber (reg:CC 17))]
8f7661f2
JH
3026 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
e075ae69 3028 (clobber (reg:CC 17))])]
d626200a
JL
3029 "")
3030
8f7661f2
JH
3031(define_insn "*zero_extendhisi2_movzwl"
3032 [(set (match_operand:SI 0 "register_operand" "=r")
3033 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3034 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035 "movz{wl|x}\\t{%1, %0|%0, %1}"
6ef67412
JH
3036 [(set_attr "type" "imovx")
3037 (set_attr "mode" "SI")])
8f7661f2
JH
3038
3039(define_expand "zero_extendqihi2"
3040 [(parallel
3041 [(set (match_operand:HI 0 "register_operand" "")
3042 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043 (clobber (reg:CC 17))])]
e075ae69 3044 ""
8f7661f2
JH
3045 "")
3046
3047(define_insn "*zero_extendqihi2_and"
3048 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3050 (clobber (reg:CC 17))]
3051 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3052 "#"
6ef67412
JH
3053 [(set_attr "type" "alu1")
3054 (set_attr "mode" "HI")])
8f7661f2
JH
3055
3056(define_insn "*zero_extendqihi2_movzbw_and"
3057 [(set (match_operand:HI 0 "register_operand" "=r,r")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3059 (clobber (reg:CC 17))]
3060 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3061 "#"
6ef67412
JH
3062 [(set_attr "type" "imovx,alu1")
3063 (set_attr "mode" "HI")])
886c62d1 3064
8f7661f2
JH
3065(define_insn "*zero_extendqihi2_movzbw"
3066 [(set (match_operand:HI 0 "register_operand" "=r")
3067 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
1c27d4b2 3068 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
8f7661f2 3069 "movz{bw|x}\\t{%1, %0|%0, %1}"
6ef67412
JH
3070 [(set_attr "type" "imovx")
3071 (set_attr "mode" "HI")])
8f7661f2
JH
3072
3073;; For the movzbw case strip only the clobber
2ae0f82c
SC
3074(define_split
3075 [(set (match_operand:HI 0 "register_operand" "")
e075ae69
RH
3076 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3077 (clobber (reg:CC 17))]
8f7661f2
JH
3078 "reload_completed
3079 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3080 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3081 [(set (match_operand:HI 0 "register_operand" "")
3082 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2ae0f82c 3083
8f7661f2
JH
3084;; When source and destination does not overlap, clear destination
3085;; first and then do the movb
2ae0f82c
SC
3086(define_split
3087 [(set (match_operand:HI 0 "register_operand" "")
8f7661f2 3088 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
e075ae69
RH
3089 (clobber (reg:CC 17))]
3090 "reload_completed
1a06f5fe 3091 && ANY_QI_REG_P (operands[0])
8f7661f2
JH
3092 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3093 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3094 [(set (match_dup 0) (const_int 0))
3095 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3096 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3097
8f7661f2 3098;; Rest is handled by single and.
2ae0f82c
SC
3099(define_split
3100 [(set (match_operand:HI 0 "register_operand" "")
e075ae69
RH
3101 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3102 (clobber (reg:CC 17))]
3103 "reload_completed
8f7661f2
JH
3104 && true_regnum (operands[0]) == true_regnum (operands[1])"
3105 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
e075ae69 3106 (clobber (reg:CC 17))])]
d626200a
JL
3107 "")
3108
8f7661f2
JH
3109(define_expand "zero_extendqisi2"
3110 [(parallel
3111 [(set (match_operand:SI 0 "register_operand" "")
3112 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113 (clobber (reg:CC 17))])]
e075ae69 3114 ""
8f7661f2
JH
3115 "")
3116
3117(define_insn "*zero_extendqisi2_and"
3118 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3119 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3120 (clobber (reg:CC 17))]
3121 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3122 "#"
6ef67412
JH
3123 [(set_attr "type" "alu1")
3124 (set_attr "mode" "SI")])
8f7661f2
JH
3125
3126(define_insn "*zero_extendqisi2_movzbw_and"
3127 [(set (match_operand:SI 0 "register_operand" "=r,r")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3129 (clobber (reg:CC 17))]
3130 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3131 "#"
6ef67412
JH
3132 [(set_attr "type" "imovx,alu1")
3133 (set_attr "mode" "SI")])
2ae0f82c 3134
8f7661f2
JH
3135(define_insn "*zero_extendqisi2_movzbw"
3136 [(set (match_operand:SI 0 "register_operand" "=r")
3137 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3138 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3139 "movz{bl|x}\\t{%1, %0|%0, %1}"
6ef67412
JH
3140 [(set_attr "type" "imovx")
3141 (set_attr "mode" "SI")])
8f7661f2
JH
3142
3143;; For the movzbl case strip only the clobber
3144(define_split
3145 [(set (match_operand:SI 0 "register_operand" "")
3146 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3147 (clobber (reg:CC 17))]
3148 "reload_completed
3149 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
1a06f5fe 3150 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
8f7661f2
JH
3151 [(set (match_dup 0)
3152 (zero_extend:SI (match_dup 1)))])
3153
3154;; When source and destination does not overlap, clear destination
3155;; first and then do the movb
2ae0f82c
SC
3156(define_split
3157 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
3158 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3159 (clobber (reg:CC 17))]
3160 "reload_completed
1a06f5fe
JH
3161 && ANY_QI_REG_P (operands[0])
3162 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
8f7661f2 3163 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
e075ae69 3164 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8f7661f2
JH
3165 [(set (match_dup 0) (const_int 0))
3166 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3167 "operands[2] = gen_lowpart (QImode, operands[0]);")
2ae0f82c 3168
8f7661f2 3169;; Rest is handled by single and.
2ae0f82c
SC
3170(define_split
3171 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
3172 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3173 (clobber (reg:CC 17))]
3174 "reload_completed
8f7661f2
JH
3175 && true_regnum (operands[0]) == true_regnum (operands[1])"
3176 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
e075ae69
RH
3177 (clobber (reg:CC 17))])]
3178 "")
2ae0f82c 3179
e075ae69 3180;; %%% Kill me once multi-word ops are sane.
9c530261 3181(define_insn "zero_extendsidi2"
bb62e19a 3182 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
e075ae69
RH
3183 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
3184 (clobber (reg:CC 17))]
9c530261 3185 ""
6ef67412
JH
3186 "#"
3187 [(set_attr "mode" "SI")])
2ae0f82c 3188
bb62e19a
JH
3189(define_split
3190 [(set (match_operand:DI 0 "register_operand" "")
e075ae69
RH
3191 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192 (clobber (reg:CC 17))]
1e07edd3
JH
3193 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])
3194 && !TARGET_64BIT"
591702de 3195 [(set (match_dup 4) (const_int 0))]
bb62e19a
JH
3196 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197
3198(define_split
3199 [(set (match_operand:DI 0 "nonimmediate_operand" "")
e075ae69
RH
3200 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201 (clobber (reg:CC 17))]
bb62e19a
JH
3202 "reload_completed"
3203 [(set (match_dup 3) (match_dup 1))
591702de 3204 (set (match_dup 4) (const_int 0))]
bb62e19a 3205 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
886c62d1 3206\f
e075ae69 3207;; Sign extension instructions
886c62d1 3208
886c62d1 3209(define_insn "extendsidi2"
e075ae69
RH
3210 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3211 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
6b29b0e2
JW
3212 (clobber (reg:CC 17))
3213 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
886c62d1 3214 ""
724d568a
JH
3215 "#")
3216
3217;; Extend to memory case when source register does die.
3218(define_split
3219 [(set (match_operand:DI 0 "memory_operand" "")
3220 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3221 (clobber (reg:CC 17))
3222 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3223 "(reload_completed
724d568a
JH
3224 && dead_or_set_p (insn, operands[1])
3225 && !reg_mentioned_p (operands[1], operands[0]))"
3226 [(set (match_dup 3) (match_dup 1))
e075ae69
RH
3227 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3228 (clobber (reg:CC 17))])
724d568a
JH
3229 (set (match_dup 4) (match_dup 1))]
3230 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232;; Extend to memory case when source register does not die.
3233(define_split
3234 [(set (match_operand:DI 0 "memory_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3236 (clobber (reg:CC 17))
3237 (clobber (match_operand:SI 2 "register_operand" ""))]
d7a29404 3238 "reload_completed"
724d568a
JH
3239 [(const_int 0)]
3240 "
9c530261 3241{
724d568a
JH
3242 split_di (&operands[0], 1, &operands[3], &operands[4]);
3243
3244 emit_move_insn (operands[3], operands[1]);
3245
3246 /* Generate a cltd if possible and doing so it profitable. */
3247 if (true_regnum (operands[1]) == 0
3248 && true_regnum (operands[2]) == 1
e075ae69 3249 && (optimize_size || TARGET_USE_CLTD))
71a247f0 3250 {
e075ae69 3251 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
724d568a
JH
3252 }
3253 else
3254 {
3255 emit_move_insn (operands[2], operands[1]);
e075ae69 3256 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
71a247f0 3257 }
724d568a
JH
3258 emit_move_insn (operands[4], operands[2]);
3259 DONE;
3260}")
9c530261 3261
724d568a
JH
3262;; Extend to register case. Optimize case where source and destination
3263;; registers match and cases where we can use cltd.
3264(define_split
3265 [(set (match_operand:DI 0 "register_operand" "")
3266 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
6b29b0e2
JW
3267 (clobber (reg:CC 17))
3268 (clobber (match_scratch:SI 2 ""))]
724d568a
JH
3269 "reload_completed"
3270 [(const_int 0)]
3271 "
3272{
3273 split_di (&operands[0], 1, &operands[3], &operands[4]);
3274
3275 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3276 emit_move_insn (operands[3], operands[1]);
9c530261 3277
724d568a
JH
3278 /* Generate a cltd if possible and doing so it profitable. */
3279 if (true_regnum (operands[3]) == 0
e075ae69 3280 && (optimize_size || TARGET_USE_CLTD))
724d568a 3281 {
e075ae69 3282 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
724d568a
JH
3283 DONE;
3284 }
3285
3286 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3287 emit_move_insn (operands[4], operands[1]);
3288
e075ae69 3289 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
724d568a 3290 DONE;
9c530261 3291}")
886c62d1 3292
886c62d1 3293(define_insn "extendhisi2"
e075ae69
RH
3294 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3295 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
886c62d1
JVA
3296 ""
3297 "*
3298{
6ef67412 3299 switch (get_attr_prefix_0f (insn))
e075ae69 3300 {
6ef67412 3301 case 0:
e075ae69
RH
3302 return \"{cwtl|cwde}\";
3303 default:
3304 return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
3305 }
3306}"
3307 [(set_attr "type" "imovx")
6ef67412
JH
3308 (set_attr "mode" "SI")
3309 (set (attr "prefix_0f")
3310 ;; movsx is short decodable while cwtl is vector decoded.
3311 (if_then_else (and (eq_attr "cpu" "!k6")
3312 (eq_attr "alternative" "0"))
3313 (const_string "0")
3314 (const_string "1")))
3315 (set (attr "modrm")
3316 (if_then_else (eq_attr "prefix_0f" "0")
3317 (const_string "0")
3318 (const_string "1")))])
886c62d1
JVA
3319
3320(define_insn "extendqihi2"
e075ae69
RH
3321 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3322 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
886c62d1
JVA
3323 ""
3324 "*
3325{
6ef67412 3326 switch (get_attr_prefix_0f (insn))
e075ae69 3327 {
6ef67412 3328 case 0:
e075ae69
RH
3329 return \"{cbtw|cbw}\";
3330 default:
3331 return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
3332 }
3333}"
3334 [(set_attr "type" "imovx")
6ef67412
JH
3335 (set_attr "mode" "HI")
3336 (set (attr "prefix_0f")
3337 ;; movsx is short decodable while cwtl is vector decoded.
3338 (if_then_else (and (eq_attr "cpu" "!k6")
3339 (eq_attr "alternative" "0"))
3340 (const_string "0")
3341 (const_string "1")))
3342 (set (attr "modrm")
3343 (if_then_else (eq_attr "prefix_0f" "0")
3344 (const_string "0")
3345 (const_string "1")))])
886c62d1
JVA
3346
3347(define_insn "extendqisi2"
2ae0f82c
SC
3348 [(set (match_operand:SI 0 "register_operand" "=r")
3349 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
886c62d1 3350 ""
e075ae69 3351 "movs{bl|x}\\t{%1,%0|%0, %1}"
6ef67412
JH
3352 [(set_attr "type" "imovx")
3353 (set_attr "mode" "SI")])
886c62d1
JVA
3354\f
3355;; Conversions between float and double.
3356
e075ae69
RH
3357;; These are all no-ops in the model used for the 80387. So just
3358;; emit moves.
6a4a5d95 3359
e075ae69 3360;; %%% Kill these when call knows how to work out a DFmode push earlier.
6343a50e 3361(define_insn "*dummy_extendsfdf2"
e075ae69 3362 [(set (match_operand:DF 0 "push_operand" "=<")
42a0aa6f 3363 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
e075ae69
RH
3364 "0"
3365 "#")
6a4a5d95
JW
3366
3367(define_split
e075ae69
RH
3368 [(set (match_operand:DF 0 "push_operand" "")
3369 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3370 "FP_REGNO_P (REGNO (operands[1]))"
3371 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3372 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
0fcad513 3373
6343a50e 3374(define_insn "*dummy_extendsfxf2"
e075ae69
RH
3375 [(set (match_operand:XF 0 "push_operand" "=<")
3376 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3377 "0"
3378 "#")
e4ad1003
JW
3379
3380(define_split
e075ae69
RH
3381 [(set (match_operand:XF 0 "push_operand" "")
3382 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3383 "FP_REGNO_P (REGNO (operands[1]))"
3384 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2b589241
JH
3385 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3386
3387(define_insn "*dummy_extendsftf2"
3388 [(set (match_operand:TF 0 "push_operand" "=<")
3389 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3390 "0"
3391 "#")
3392
3393(define_split
3394 [(set (match_operand:TF 0 "push_operand" "")
3395 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3396 "FP_REGNO_P (REGNO (operands[1]))"
3397 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3398 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4fb21e90 3399
6343a50e 3400(define_insn "*dummy_extenddfxf2"
e075ae69
RH
3401 [(set (match_operand:XF 0 "push_operand" "=<")
3402 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3403 "0"
3404 "#")
e4ad1003
JW
3405
3406(define_split
e075ae69
RH
3407 [(set (match_operand:XF 0 "push_operand" "")
3408 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
3409 "FP_REGNO_P (REGNO (operands[1]))"
3410 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2b589241
JH
3411 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3412
3413(define_insn "*dummy_extenddftf2"
3414 [(set (match_operand:TF 0 "push_operand" "=<")
3415 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3416 "0"
3417 "#")
3418
3419(define_split
3420 [(set (match_operand:TF 0 "push_operand" "")
3421 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3422 "FP_REGNO_P (REGNO (operands[1]))"
3423 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3424 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4fb21e90 3425
f97d9ec3
JH
3426(define_expand "extendsfdf2"
3427 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3428 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
42a0aa6f 3429 "TARGET_80387 || TARGET_SSE2"
f97d9ec3
JH
3430 "
3431{
3432 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3433 operands[1] = force_reg (SFmode, operands[1]);
f97d9ec3
JH
3434}")
3435
3436(define_insn "*extendsfdf2_1"
a811cc63
JH
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3438 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
42a0aa6f 3439 "(TARGET_80387 || TARGET_SSE2)
f97d9ec3 3440 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4fb21e90
JVA
3441 "*
3442{
e075ae69 3443 switch (which_alternative)
4fb21e90 3444 {
e075ae69 3445 case 0:
0c174a68
AB
3446 if (REG_P (operands[1])
3447 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3448 return \"fstp\\t%y0\";
e075ae69 3449 else if (STACK_TOP_P (operands[0]))
7ebb782b 3450 return \"fld%z1\\t%y1\";
e075ae69 3451 else
7ebb782b 3452 return \"fst\\t%y0\";
886c62d1 3453
e075ae69
RH
3454 case 1:
3455 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3456 return \"fstp%z0\\t%y0\";
10195bd8 3457
e075ae69 3458 else
7ebb782b 3459 return \"fst%z0\\t%y0\";
42a0aa6f 3460 case 2:
42a0aa6f 3461 return \"cvtss2sd\\t{%1, %0|%0, %1}\";
4fb21e90 3462
e075ae69
RH
3463 default:
3464 abort ();
3465 }
3466}"
a811cc63
JH
3467 [(set_attr "type" "fmov,fmov,sse")
3468 (set_attr "mode" "SF,XF,DF")])
42a0aa6f
JH
3469
3470(define_insn "*extendsfdf2_1_sse_only"
3471 [(set (match_operand:DF 0 "register_operand" "=Y")
3472 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3473 "!TARGET_80387 && TARGET_SSE2
3474 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3475 "cvtss2sd\\t{%1, %0|%0, %1}"
3476 [(set_attr "type" "sse")
3477 (set_attr "mode" "DF")])
e075ae69 3478
f97d9ec3
JH
3479(define_expand "extendsfxf2"
3480 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
1e07edd3 3482 "TARGET_80387 && !TARGET_64BIT"
f97d9ec3
JH
3483 "
3484{
3485 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3486 operands[1] = force_reg (SFmode, operands[1]);
f97d9ec3
JH
3487}")
3488
3489(define_insn "*extendsfxf2_1"
e075ae69
RH
3490 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3491 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
1e07edd3 3492 "TARGET_80387 && !TARGET_64BIT
f97d9ec3 3493 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
e075ae69 3494 "*
10195bd8 3495{
e075ae69
RH
3496 switch (which_alternative)
3497 {
3498 case 0:
0c174a68
AB
3499 if (REG_P (operands[1])
3500 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3501 return \"fstp\\t%y0\";
e075ae69 3502 else if (STACK_TOP_P (operands[0]))
7ebb782b 3503 return \"fld%z1\\t%y1\";
e075ae69 3504 else
7ebb782b 3505 return \"fst\\t%y0\";
886c62d1 3506
e075ae69
RH
3507 case 1:
3508 /* There is no non-popping store to memory for XFmode. So if
3509 we need one, follow the store with a load. */
3510 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3511 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
e075ae69 3512 else
7ebb782b 3513 return \"fstp%z0\\t%y0\";
886c62d1 3514
e075ae69
RH
3515 default:
3516 abort ();
3517 }
3518}"
6ef67412
JH
3519 [(set_attr "type" "fmov")
3520 (set_attr "mode" "SF,XF")])
886c62d1 3521
2b589241
JH
3522(define_expand "extendsftf2"
3523 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3524 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3525 "TARGET_80387"
3526 "
3527{
3528 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3529 operands[1] = force_reg (SFmode, operands[1]);
3530}")
3531
3532(define_insn "*extendsftf2_1"
3533 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3534 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3535 "TARGET_80387
3536 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3537 "*
3538{
3539 switch (which_alternative)
3540 {
3541 case 0:
3542 if (REG_P (operands[1])
3543 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3544 return \"fstp\\t%y0\";
3545 else if (STACK_TOP_P (operands[0]))
3546 return \"fld%z1\\t%y1\";
3547 else
3548 return \"fst\\t%y0\";
3549
3550 case 1:
3551 /* There is no non-popping store to memory for XFmode. So if
3552 we need one, follow the store with a load. */
3553 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3554 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3555 else
3556 return \"fstp%z0\\t%y0\";
3557
3558 default:
3559 abort ();
3560 }
3561}"
3562 [(set_attr "type" "fmov")
3563 (set_attr "mode" "SF,XF")])
3564
f97d9ec3
JH
3565(define_expand "extenddfxf2"
3566 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3567 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
1e07edd3 3568 "TARGET_80387 && !TARGET_64BIT"
f97d9ec3
JH
3569 "
3570{
3571 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
34289d57 3572 operands[1] = force_reg (DFmode, operands[1]);
f97d9ec3
JH
3573}")
3574
3575(define_insn "*extenddfxf2_1"
e075ae69
RH
3576 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3577 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
1e07edd3 3578 "TARGET_80387 && !TARGET_64BIT
f97d9ec3 3579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
e075ae69
RH
3580 "*
3581{
3582 switch (which_alternative)
3583 {
3584 case 0:
0c174a68
AB
3585 if (REG_P (operands[1])
3586 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3587 return \"fstp\\t%y0\";
e075ae69 3588 else if (STACK_TOP_P (operands[0]))
7ebb782b 3589 return \"fld%z1\\t%y1\";
e075ae69 3590 else
7ebb782b 3591 return \"fst\\t%y0\";
bc725565 3592
e075ae69
RH
3593 case 1:
3594 /* There is no non-popping store to memory for XFmode. So if
3595 we need one, follow the store with a load. */
3596 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3597 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
e075ae69 3598 else
7ebb782b 3599 return \"fstp%z0\\t%y0\";
bc725565 3600
e075ae69
RH
3601 default:
3602 abort ();
3603 }
3604}"
6ef67412
JH
3605 [(set_attr "type" "fmov")
3606 (set_attr "mode" "DF,XF")])
bc725565 3607
2b589241
JH
3608(define_expand "extenddftf2"
3609 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3610 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3611 "TARGET_80387"
3612 "
3613{
3614 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3615 operands[1] = force_reg (DFmode, operands[1]);
3616}")
3617
3618(define_insn "*extenddftf2_1"
3619 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3620 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3621 "TARGET_80387
3622 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3623 "*
3624{
3625 switch (which_alternative)
3626 {
3627 case 0:
3628 if (REG_P (operands[1])
3629 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3630 return \"fstp\\t%y0\";
3631 else if (STACK_TOP_P (operands[0]))
3632 return \"fld%z1\\t%y1\";
3633 else
3634 return \"fst\\t%y0\";
3635
3636 case 1:
3637 /* There is no non-popping store to memory for XFmode. So if
3638 we need one, follow the store with a load. */
3639 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3640 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3641 else
3642 return \"fstp%z0\\t%y0\";
3643
3644 default:
3645 abort ();
3646 }
3647}"
3648 [(set_attr "type" "fmov")
3649 (set_attr "mode" "DF,XF")])
3650
e075ae69
RH
3651;; %%% This seems bad bad news.
3652;; This cannot output into an f-reg because there is no way to be sure
3653;; of truncating in that case. Otherwise this is just like a simple move
3654;; insn. So we pretend we can output to a reg in order to get better
3655;; register preferencing, but we really use a stack slot.
886c62d1 3656
e075ae69
RH
3657(define_expand "truncdfsf2"
3658 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3659 (float_truncate:SF
3660 (match_operand:DF 1 "register_operand" "")))
3661 (clobber (match_dup 2))])]
42a0aa6f
JH
3662 "TARGET_80387 || TARGET_SSE2"
3663 "
3664 if (TARGET_80387)
3665 operands[2] = assign_386_stack_local (SFmode, 0);
3666 else
3667 {
3668 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3669 DONE;
3670 }
3671")
bc725565 3672
e075ae69 3673(define_insn "*truncdfsf2_1"
42a0aa6f 3674 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f")
e075ae69
RH
3675 (float_truncate:SF
3676 (match_operand:DF 1 "register_operand" "f,0")))
42a0aa6f
JH
3677 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3678 "TARGET_80387 && !TARGET_SSE2"
e075ae69
RH
3679 "*
3680{
3681 switch (which_alternative)
3682 {
3683 case 0:
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3685 return \"fstp%z0\\t%y0\";
e075ae69 3686 else
7ebb782b 3687 return \"fst%z0\\t%y0\";
e075ae69 3688 case 1:
7ebb782b 3689 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
e075ae69
RH
3690 }
3691 abort ();
3692}"
6ef67412 3693 [(set_attr "type" "fmov,multi")
42a0aa6f
JH
3694 (set_attr "mode" "SF,SF")])
3695
3696(define_insn "*truncdfsf2_1_sse"
79005df5 3697 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f,Y")
42a0aa6f
JH
3698 (float_truncate:SF
3699 (match_operand:DF 1 "nonimmediate_operand" "f,0,mY")))
3700 (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))]
3701 "TARGET_80387 && TARGET_SSE2"
3702 "*
3703{
3704 switch (which_alternative)
3705 {
3706 case 0:
3707 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708 return \"fstp%z0\\t%y0\";
3709 else
3710 return \"fst%z0\\t%y0\";
3711 case 1:
3712 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3713 case 2:
3714 case 3:
3715 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3716 }
3717 abort ();
3718}"
3719 [(set_attr "type" "fmov,multi,sse")
3720 (set_attr "mode" "SF,SF,DF")])
53b5ce19 3721
e075ae69 3722(define_insn "*truncdfsf2_2"
79005df5 3723 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
42a0aa6f 3724 (float_truncate:SF
79005df5
JH
3725 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3726 "TARGET_80387 && TARGET_SSE2
3727 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
42a0aa6f
JH
3728 "*
3729{
3730 switch (which_alternative)
3731 {
3732 case 0:
79005df5
JH
3733 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3734 case 1:
42a0aa6f
JH
3735 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736 return \"fstp%z0\\t%y0\";
3737 else
3738 return \"fst%z0\\t%y0\";
42a0aa6f
JH
3739 }
3740}"
79005df5
JH
3741 [(set_attr "type" "sse,fmov")
3742 (set_attr "mode" "DF,SF")])
42a0aa6f
JH
3743
3744(define_insn "truncdfsf2_3"
3745 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
e075ae69
RH
3746 (float_truncate:SF
3747 (match_operand:DF 1 "register_operand" "f")))]
53b5ce19 3748 "TARGET_80387"
e075ae69
RH
3749 "*
3750{
3751 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3752 return \"fstp%z0\\t%y0\";
e075ae69 3753 else
7ebb782b 3754 return \"fst%z0\\t%y0\";
e075ae69 3755}"
6ef67412
JH
3756 [(set_attr "type" "fmov")
3757 (set_attr "mode" "SF")])
53b5ce19 3758
42a0aa6f
JH
3759(define_insn "truncdfsf2_sse_only"
3760 [(set (match_operand:SF 0 "register_operand" "=Y")
3761 (float_truncate:SF
3762 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3763 "!TARGET_80387 && TARGET_SSE2"
3764 "cvtsd2ss\\t{%1, %0|%0, %1}"
3765 [(set_attr "type" "sse")
3766 (set_attr "mode" "DF")])
3767
53b5ce19 3768(define_split
e075ae69
RH
3769 [(set (match_operand:SF 0 "memory_operand" "")
3770 (float_truncate:SF
3771 (match_operand:DF 1 "register_operand" "")))
3772 (clobber (match_operand:SF 2 "memory_operand" ""))]
3773 "TARGET_80387"
3774 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
53b5ce19
JW
3775 "")
3776
42a0aa6f
JH
3777(define_split
3778 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3779 (float_truncate:SF
3780 (match_operand:DF 1 "nonimmediate_operand" "")))
3781 (clobber (match_operand 2 "" ""))]
3782 "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
3783 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3784 "")
3785
53b5ce19
JW
3786(define_split
3787 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
3788 (float_truncate:SF
3789 (match_operand:DF 1 "register_operand" "")))
3790 (clobber (match_operand:SF 2 "memory_operand" ""))]
42a0aa6f
JH
3791 "TARGET_80387 && reload_completed
3792 && FP_REG_P (operands[0])"
e075ae69
RH
3793 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3794 (set (match_dup 0) (match_dup 2))]
53b5ce19
JW
3795 "")
3796
e075ae69
RH
3797(define_expand "truncxfsf2"
3798 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3799 (float_truncate:SF
3800 (match_operand:XF 1 "register_operand" "")))
3801 (clobber (match_dup 2))])]
1e07edd3 3802 "TARGET_80387 && !TARGET_64BIT"
e075ae69 3803 "operands[2] = assign_386_stack_local (SFmode, 0);")
53b5ce19 3804
e075ae69
RH
3805(define_insn "*truncxfsf2_1"
3806 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3807 (float_truncate:SF
3808 (match_operand:XF 1 "register_operand" "f,0")))
c76aab11 3809 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
1e07edd3 3810 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
3811 "*
3812{
3813 switch (which_alternative)
3814 {
3815 case 0:
3816 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3817 return \"fstp%z0\\t%y0\";
e075ae69 3818 else
7ebb782b 3819 return \"fst%z0\\t%y0\";
e075ae69 3820 case 1:
7ebb782b 3821 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
e075ae69
RH
3822 }
3823 abort ();
3824}"
6ef67412
JH
3825 [(set_attr "type" "fmov,multi")
3826 (set_attr "mode" "SF")])
886c62d1 3827
e075ae69 3828(define_insn "*truncxfsf2_2"
dd80b906 3829 [(set (match_operand:SF 0 "memory_operand" "=m")
e075ae69
RH
3830 (float_truncate:SF
3831 (match_operand:XF 1 "register_operand" "f")))]
1e07edd3 3832 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
3833 "*
3834{
3835 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3836 return \"fstp%z0\\t%y0\";
e075ae69 3837 else
7ebb782b 3838 return \"fst%z0\\t%y0\";
e075ae69 3839}"
6ef67412
JH
3840 [(set_attr "type" "fmov")
3841 (set_attr "mode" "SF")])
bc725565
JW
3842
3843(define_split
e075ae69
RH
3844 [(set (match_operand:SF 0 "memory_operand" "")
3845 (float_truncate:SF
3846 (match_operand:XF 1 "register_operand" "")))
3847 (clobber (match_operand:SF 2 "memory_operand" ""))]
3848 "TARGET_80387"
3849 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
886c62d1
JVA
3850 "")
3851
bc725565 3852(define_split
6a4a5d95 3853 [(set (match_operand:SF 0 "register_operand" "")
e075ae69
RH
3854 (float_truncate:SF
3855 (match_operand:XF 1 "register_operand" "")))
3856 (clobber (match_operand:SF 2 "memory_operand" ""))]
bc725565 3857 "TARGET_80387 && reload_completed"
e075ae69
RH
3858 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3859 (set (match_dup 0) (match_dup 2))]
886c62d1
JVA
3860 "")
3861
2b589241
JH
3862(define_expand "trunctfsf2"
3863 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3864 (float_truncate:SF
3865 (match_operand:TF 1 "register_operand" "")))
3866 (clobber (match_dup 2))])]
3867 "TARGET_80387"
3868 "operands[2] = assign_386_stack_local (SFmode, 0);")
3869
3870(define_insn "*trunctfsf2_1"
3871 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3872 (float_truncate:SF
3873 (match_operand:TF 1 "register_operand" "f,0")))
3874 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3875 "TARGET_80387"
3876 "*
3877{
3878 switch (which_alternative)
3879 {
3880 case 0:
3881 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882 return \"fstp%z0\\t%y0\";
3883 else
3884 return \"fst%z0\\t%y0\";
3885 case 1:
3886 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3887 }
3888 abort ();
3889}"
3890 [(set_attr "type" "fmov,multi")
3891 (set_attr "mode" "SF")])
3892
1e07edd3 3893(define_insn "*trunctfsf2_2"
2b589241
JH
3894 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3895 (float_truncate:SF
3896 (match_operand:TF 1 "register_operand" "f")))]
3897 "TARGET_80387"
3898 "*
3899{
3900 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3901 return \"fstp%z0\\t%y0\";
3902 else
3903 return \"fst%z0\\t%y0\";
3904}"
3905 [(set_attr "type" "fmov")
3906 (set_attr "mode" "SF")])
3907
3908(define_split
3909 [(set (match_operand:SF 0 "memory_operand" "")
3910 (float_truncate:SF
3911 (match_operand:TF 1 "register_operand" "")))
3912 (clobber (match_operand:SF 2 "memory_operand" ""))]
3913 "TARGET_80387"
3914 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3915 "")
3916
3917(define_split
3918 [(set (match_operand:SF 0 "register_operand" "")
3919 (float_truncate:SF
3920 (match_operand:TF 1 "register_operand" "")))
3921 (clobber (match_operand:SF 2 "memory_operand" ""))]
3922 "TARGET_80387 && reload_completed"
3923 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3924 (set (match_dup 0) (match_dup 2))]
3925 "")
3926
3927
e075ae69
RH
3928(define_expand "truncxfdf2"
3929 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3930 (float_truncate:DF
3931 (match_operand:XF 1 "register_operand" "")))
3932 (clobber (match_dup 2))])]
1e07edd3 3933 "TARGET_80387 && !TARGET_64BIT"
e075ae69 3934 "operands[2] = assign_386_stack_local (DFmode, 0);")
bc725565 3935
e075ae69
RH
3936(define_insn "*truncxfdf2_1"
3937 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3938 (float_truncate:DF
3939 (match_operand:XF 1 "register_operand" "f,0")))
c76aab11 3940 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
1e07edd3 3941 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
3942 "*
3943{
3944 switch (which_alternative)
3945 {
3946 case 0:
3947 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3948 return \"fstp%z0\\t%y0\";
e075ae69 3949 else
7ebb782b 3950 return \"fst%z0\\t%y0\";
e075ae69 3951 case 1:
7ebb782b 3952 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
e075ae69
RH
3953 }
3954 abort ();
3955}"
6ef67412
JH
3956 [(set_attr "type" "fmov,multi")
3957 (set_attr "mode" "DF")])
bc725565 3958
e075ae69
RH
3959(define_insn "*truncxfdf2_2"
3960 [(set (match_operand:DF 0 "memory_operand" "=m")
3961 (float_truncate:DF
3962 (match_operand:XF 1 "register_operand" "f")))]
1e07edd3 3963 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
3964 "*
3965{
3966 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
7ebb782b 3967 return \"fstp%z0\\t%y0\";
e075ae69 3968 else
7ebb782b 3969 return \"fst%z0\\t%y0\";
e075ae69 3970}"
6ef67412
JH
3971 [(set_attr "type" "fmov")
3972 (set_attr "mode" "DF")])
bc725565
JW
3973
3974(define_split
e075ae69
RH
3975 [(set (match_operand:DF 0 "memory_operand" "")
3976 (float_truncate:DF
3977 (match_operand:XF 1 "register_operand" "")))
3978 (clobber (match_operand:DF 2 "memory_operand" ""))]
ca285e07
JH
3979 "TARGET_80387"
3980 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4fb21e90
JVA
3981 "")
3982
bc725565 3983(define_split
6a4a5d95 3984 [(set (match_operand:DF 0 "register_operand" "")
e075ae69
RH
3985 (float_truncate:DF
3986 (match_operand:XF 1 "register_operand" "")))
3987 (clobber (match_operand:DF 2 "memory_operand" ""))]
bc725565 3988 "TARGET_80387 && reload_completed"
ca285e07 3989 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
e075ae69 3990 (set (match_dup 0) (match_dup 2))]
4fb21e90 3991 "")
ca285e07 3992
2b589241
JH
3993(define_expand "trunctfdf2"
3994 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3995 (float_truncate:DF
3996 (match_operand:TF 1 "register_operand" "")))
3997 (clobber (match_dup 2))])]
3998 "TARGET_80387"
3999 "operands[2] = assign_386_stack_local (DFmode, 0);")
4000
4001(define_insn "*trunctfdf2_1"
4002 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
4003 (float_truncate:DF
4004 (match_operand:TF 1 "register_operand" "f,0")))
4005 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
4006 "TARGET_80387"
4007 "*
4008{
4009 switch (which_alternative)
4010 {
4011 case 0:
4012 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4013 return \"fstp%z0\\t%y0\";
4014 else
4015 return \"fst%z0\\t%y0\";
4016 case 1:
4017 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
4018 }
4019 abort ();
4020}"
4021 [(set_attr "type" "fmov,multi")
4022 (set_attr "mode" "DF")])
4023
3d117b30 4024(define_insn "*trunctfdf2_2"
2b589241
JH
4025 [(set (match_operand:DF 0 "memory_operand" "=m")
4026 (float_truncate:DF
4027 (match_operand:TF 1 "register_operand" "f")))]
4028 "TARGET_80387"
4029 "*
4030{
4031 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032 return \"fstp%z0\\t%y0\";
4033 else
4034 return \"fst%z0\\t%y0\";
4035}"
4036 [(set_attr "type" "fmov")
4037 (set_attr "mode" "DF")])
4038
4039(define_split
4040 [(set (match_operand:DF 0 "memory_operand" "")
4041 (float_truncate:DF
4042 (match_operand:TF 1 "register_operand" "")))
4043 (clobber (match_operand:DF 2 "memory_operand" ""))]
4044 "TARGET_80387"
4045 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4046 "")
4047
4048(define_split
4049 [(set (match_operand:DF 0 "register_operand" "")
4050 (float_truncate:DF
4051 (match_operand:TF 1 "register_operand" "")))
4052 (clobber (match_operand:DF 2 "memory_operand" ""))]
4053 "TARGET_80387 && reload_completed"
4054 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4055 (set (match_dup 0) (match_dup 2))]
4056 "")
4057
e075ae69
RH
4058\f
4059;; %%% Break up all these bad boys.
4fb21e90 4060
e075ae69
RH
4061;; Signed conversion to DImode.
4062
2b589241
JH
4063(define_expand "fix_truncxfdi2"
4064 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4065 (fix:DI (match_operand:XF 1 "register_operand" "")))
4066 (clobber (match_dup 2))
4067 (clobber (match_dup 3))
4068 (clobber (match_scratch:SI 4 ""))
4069 (clobber (match_scratch:XF 5 ""))])]
1e07edd3 4070 "TARGET_80387 && !TARGET_64BIT"
2b589241
JH
4071 "operands[2] = assign_386_stack_local (SImode, 0);
4072 operands[3] = assign_386_stack_local (DImode, 1);")
4073
4074(define_expand "fix_trunctfdi2"
e075ae69 4075 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2b589241 4076 (fix:DI (match_operand:TF 1 "register_operand" "")))
e075ae69
RH
4077 (clobber (match_dup 2))
4078 (clobber (match_dup 3))
4079 (clobber (match_scratch:SI 4 ""))
2b589241 4080 (clobber (match_scratch:TF 5 ""))])]
bc725565 4081 "TARGET_80387"
e075ae69
RH
4082 "operands[2] = assign_386_stack_local (SImode, 0);
4083 operands[3] = assign_386_stack_local (DImode, 1);")
bc725565 4084
e075ae69
RH
4085(define_expand "fix_truncdfdi2"
4086 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087 (fix:DI (match_operand:DF 1 "register_operand" "")))
4088 (clobber (match_dup 2))
4089 (clobber (match_dup 3))
4090 (clobber (match_scratch:SI 4 ""))
a05924f9 4091 (clobber (match_scratch:DF 5 ""))])]
53b5ce19 4092 "TARGET_80387"
e075ae69
RH
4093 "operands[2] = assign_386_stack_local (SImode, 0);
4094 operands[3] = assign_386_stack_local (DImode, 1);")
53b5ce19 4095
e075ae69
RH
4096(define_expand "fix_truncsfdi2"
4097 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4098 (fix:DI (match_operand:SF 1 "register_operand" "")))
4099 (clobber (match_dup 2))
4100 (clobber (match_dup 3))
4101 (clobber (match_scratch:SI 4 ""))
a05924f9 4102 (clobber (match_scratch:SF 5 ""))])]
53b5ce19 4103 "TARGET_80387"
e075ae69
RH
4104 "operands[2] = assign_386_stack_local (SImode, 0);
4105 operands[3] = assign_386_stack_local (DImode, 1);")
4106
4107(define_insn "*fix_truncdi_1"
c76aab11 4108 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4109 (fix:DI (match_operand 1 "register_operand" "f,f")))
c76aab11
RH
4110 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4111 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
a05924f9
JH
4112 (clobber (match_scratch:SI 4 "=&r,&r"))
4113 (clobber (match_scratch 5 "=&f,&f"))]
e075ae69
RH
4114 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
4115 "* return output_fix_trunc (insn, operands);"
4116 [(set_attr "type" "multi")])
53b5ce19 4117
e075ae69
RH
4118(define_split
4119 [(set (match_operand:DI 0 "register_operand" "")
4120 (fix:DI (match_operand 1 "register_operand" "")))
4121 (clobber (match_operand:SI 2 "memory_operand" ""))
4122 (clobber (match_operand:DI 3 "memory_operand" ""))
4123 (clobber (match_scratch:SI 4 ""))
a05924f9 4124 (clobber (match_scratch 5 ""))]
e075ae69
RH
4125 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
4126 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
4127 (clobber (match_dup 2))
4128 (clobber (match_dup 3))
4129 (clobber (match_dup 4))
4130 (clobber (match_dup 5))])
4131 (set (match_dup 0) (match_dup 3))]
53b5ce19
JW
4132 "")
4133
e075ae69 4134;; Signed conversion to SImode.
53b5ce19 4135
e075ae69
RH
4136(define_expand "fix_truncxfsi2"
4137 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4138 (fix:SI (match_operand:XF 1 "register_operand" "")))
4139 (clobber (match_dup 2))
4140 (clobber (match_dup 3))
4141 (clobber (match_scratch:SI 4 ""))])]
1e07edd3 4142 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
4143 "operands[2] = assign_386_stack_local (SImode, 0);
4144 operands[3] = assign_386_stack_local (SImode, 1);")
53b5ce19 4145
2b589241
JH
4146(define_expand "fix_trunctfsi2"
4147 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4148 (fix:SI (match_operand:TF 1 "register_operand" "")))
4149 (clobber (match_dup 2))
4150 (clobber (match_dup 3))
4151 (clobber (match_scratch:SI 4 ""))])]
4152 "TARGET_80387"
4153 "operands[2] = assign_386_stack_local (SImode, 0);
4154 operands[3] = assign_386_stack_local (SImode, 1);")
4155
e075ae69
RH
4156(define_expand "fix_truncdfsi2"
4157 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4158 (fix:SI (match_operand:DF 1 "register_operand" "")))
4159 (clobber (match_dup 2))
4160 (clobber (match_dup 3))
4161 (clobber (match_scratch:SI 4 ""))])]
42a0aa6f
JH
4162 "TARGET_80387 || TARGET_SSE2"
4163 "
4164{
4165 if (TARGET_SSE2)
4166 {
ca9a9b12 4167 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
b1675dbd
JH
4168 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4169 if (out != operands[0])
4170 emit_move_insn (operands[0], out);
42a0aa6f
JH
4171 DONE;
4172 }
4173 else
4174 {
4175 operands[2] = assign_386_stack_local (SImode, 0);
4176 operands[3] = assign_386_stack_local (SImode, 1);
4177 }
4178}")
886c62d1 4179
e075ae69
RH
4180(define_expand "fix_truncsfsi2"
4181 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4182 (fix:SI (match_operand:SF 1 "register_operand" "")))
4183 (clobber (match_dup 2))
4184 (clobber (match_dup 3))
4185 (clobber (match_scratch:SI 4 ""))])]
42a0aa6f
JH
4186 "TARGET_80387 || TARGET_SSE"
4187 "
4188{
4189 if (TARGET_SSE2)
4190 {
ca9a9b12 4191 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
b1675dbd
JH
4192 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4193 if (out != operands[0])
4194 emit_move_insn (operands[0], out);
42a0aa6f
JH
4195 DONE;
4196 }
4197 else
4198 {
4199 operands[2] = assign_386_stack_local (SImode, 0);
4200 operands[3] = assign_386_stack_local (SImode, 1);
4201 }
4202}")
e075ae69
RH
4203
4204(define_insn "*fix_truncsi_1"
c76aab11 4205 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
e075ae69 4206 (fix:SI (match_operand 1 "register_operand" "f,f")))
c76aab11
RH
4207 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4208 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
e075ae69 4209 (clobber (match_scratch:SI 4 "=&r,r"))]
42a0aa6f
JH
4210 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4211 && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
e075ae69
RH
4212 "* return output_fix_trunc (insn, operands);"
4213 [(set_attr "type" "multi")])
bc725565 4214
42a0aa6f
JH
4215;; When SSE available, it is always faster to use it!
4216(define_insn "fix_truncsfsi_sse"
4217 [(set (match_operand:SI 0 "register_operand" "=r")
4218 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4219 "TARGET_SSE"
4220 "cvttss2si\\t{%1, %0|%0, %1}"
4221 [(set_attr "type" "sse")])
4222
4223(define_insn "fix_truncdfsi_sse"
4224 [(set (match_operand:SI 0 "register_operand" "=r")
4225 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4226 "TARGET_SSE2"
4227 "cvttsd2si\\t{%1, %0|%0, %1}"
4228 [(set_attr "type" "sse")])
4229
e075ae69
RH
4230(define_split
4231 [(set (match_operand:SI 0 "register_operand" "")
4232 (fix:SI (match_operand 1 "register_operand" "")))
4233 (clobber (match_operand:SI 2 "memory_operand" ""))
4234 (clobber (match_operand:SI 3 "memory_operand" ""))
4235 (clobber (match_scratch:SI 4 ""))]
4236 "reload_completed"
4237 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
4238 (clobber (match_dup 2))
4239 (clobber (match_dup 3))
4240 (clobber (match_dup 4))])
4241 (set (match_dup 0) (match_dup 3))]
bc725565 4242 "")
4fb21e90 4243
46d21d2c
JW
4244;; Signed conversion to HImode.
4245
4246(define_expand "fix_truncxfhi2"
4247 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4248 (fix:HI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (match_dup 2))
4250 (clobber (match_dup 3))
4251 (clobber (match_scratch:SI 4 ""))])]
4252 "TARGET_80387"
4253 "operands[2] = assign_386_stack_local (SImode, 0);
4254 operands[3] = assign_386_stack_local (HImode, 1);")
4255
2b589241
JH
4256(define_expand "fix_trunctfhi2"
4257 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4258 (fix:HI (match_operand:TF 1 "register_operand" "")))
4259 (clobber (match_dup 2))
4260 (clobber (match_dup 3))
4261 (clobber (match_scratch:SI 4 ""))])]
4262 "TARGET_80387"
4263 "operands[2] = assign_386_stack_local (SImode, 0);
4264 operands[3] = assign_386_stack_local (HImode, 1);")
4265
46d21d2c
JW
4266(define_expand "fix_truncdfhi2"
4267 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4268 (fix:HI (match_operand:DF 1 "register_operand" "")))
4269 (clobber (match_dup 2))
4270 (clobber (match_dup 3))
4271 (clobber (match_scratch:SI 4 ""))])]
42a0aa6f 4272 "TARGET_80387 && !TARGET_SSE2"
46d21d2c
JW
4273 "operands[2] = assign_386_stack_local (SImode, 0);
4274 operands[3] = assign_386_stack_local (HImode, 1);")
4275
4276(define_expand "fix_truncsfhi2"
4277 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4278 (fix:HI (match_operand:SF 1 "register_operand" "")))
4279 (clobber (match_dup 2))
4280 (clobber (match_dup 3))
4281 (clobber (match_scratch:SI 4 ""))])]
42a0aa6f 4282 "TARGET_80387 && !TARGET_SSE"
46d21d2c
JW
4283 "operands[2] = assign_386_stack_local (SImode, 0);
4284 operands[3] = assign_386_stack_local (HImode, 1);")
4285
4286(define_insn "*fix_trunchi_1"
4287 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4288 (fix:HI (match_operand 1 "register_operand" "f,f")))
4289 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4290 (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
4291 (clobber (match_scratch:SI 4 "=&r,r"))]
42a0aa6f
JH
4292 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4293 && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
46d21d2c
JW
4294 "* return output_fix_trunc (insn, operands);"
4295 [(set_attr "type" "multi")])
4296
4297(define_split
4298 [(set (match_operand:HI 0 "register_operand" "")
4299 (fix:HI (match_operand 1 "register_operand" "")))
4300 (clobber (match_operand:SI 2 "memory_operand" ""))
4301 (clobber (match_operand:HI 3 "memory_operand" ""))
4302 (clobber (match_scratch:SI 4 ""))]
4303 "reload_completed"
4304 [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
4305 (clobber (match_dup 2))
4306 (clobber (match_dup 3))
4307 (clobber (match_dup 4))])
4308 (set (match_dup 0) (match_dup 3))]
4309 "")
4310
42a0aa6f
JH
4311;; %%% Kill these when reload knows how to do it.
4312(define_split
4313 [(set (match_operand 0 "register_operand" "")
4314 (fix (match_operand 1 "register_operand" "")))]
4315 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
4316 && FP_REG_P (operands[1])"
4317 [(const_int 0)]
4318 "
4319{
4320 operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
4321 operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
4322 emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
4323 emit_move_insn (operands[0], operands[2]);
4324 ix86_free_from_memory (GET_MODE (operands[0]));
4325 DONE;
4326}")
4327
e075ae69
RH
4328;; %% Not used yet.
4329(define_insn "x86_fnstcw_1"
c76aab11
RH
4330 [(set (match_operand:HI 0 "memory_operand" "=m")
4331 (unspec:HI [(reg:HI 18)] 11))]
e1f998ad 4332 "TARGET_80387"
e075ae69 4333 "fnstcw\\t%0"
6ef67412
JH
4334 [(set_attr "length" "2")
4335 (set_attr "mode" "HI")
4336 (set_attr "i387" "1")
e075ae69 4337 (set_attr "ppro_uops" "few")])
bc725565 4338
e075ae69
RH
4339(define_insn "x86_fldcw_1"
4340 [(set (reg:HI 18)
c76aab11 4341 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
bc725565 4342 "TARGET_80387"
e075ae69 4343 "fldcw\\t%0"
6ef67412
JH
4344 [(set_attr "length" "2")
4345 (set_attr "mode" "HI")
4346 (set_attr "i387" "1")
0b5107cf 4347 (set_attr "athlon_decode" "vector")
e075ae69
RH
4348 (set_attr "ppro_uops" "few")])
4349\f
4350;; Conversion between fixed point and floating point.
886c62d1 4351
e075ae69
RH
4352;; Even though we only accept memory inputs, the backend _really_
4353;; wants to be able to do this between registers.
4354
155d8a47
JW
4355(define_insn "floathisf2"
4356 [(set (match_operand:SF 0 "register_operand" "=f,f")
4357 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
42a0aa6f 4358 "TARGET_80387 && !TARGET_SSE"
155d8a47
JW
4359 "@
4360 fild%z1\\t%1
4361 #"
4362 [(set_attr "type" "fmov,multi")
6ef67412 4363 (set_attr "mode" "SF")
155d8a47
JW
4364 (set_attr "fp_int_src" "true")])
4365
42a0aa6f
JH
4366(define_expand "floatsisf2"
4367 [(set (match_operand:SF 0 "register_operand" "")
4368 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4369 "TARGET_SSE || TARGET_80387"
4370 "")
4371
4372(define_insn "*floatsisf2_i387"
4373 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4374 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4375 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
e075ae69
RH
4376 "@
4377 fild%z1\\t%1
42a0aa6f
JH
4378 #
4379 cvtsi2ss\\t{%1, %0|%0, %1}"
4380 [(set_attr "type" "fmov,multi,sse")
4381 (set_attr "mode" "SF")
4382 (set_attr "fp_int_src" "true")])
4383
4384(define_insn "*floatsisf2_sse"
4385 [(set (match_operand:SF 0 "register_operand" "=x")
4386 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4387 "TARGET_80387 && TARGET_SSE"
4388 "cvtsi2ss\\t{%1, %0|%0, %1}"
4389 [(set_attr "type" "sse")
6ef67412 4390 (set_attr "mode" "SF")
e075ae69 4391 (set_attr "fp_int_src" "true")])
bc725565 4392
e075ae69
RH
4393(define_insn "floatdisf2"
4394 [(set (match_operand:SF 0 "register_operand" "=f,f")
4395 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4396 "TARGET_80387"
4397 "@
4398 fild%z1\\t%1
4399 #"
4400 [(set_attr "type" "fmov,multi")
6ef67412 4401 (set_attr "mode" "SF")
e075ae69 4402 (set_attr "fp_int_src" "true")])
bc725565 4403
155d8a47
JW
4404(define_insn "floathidf2"
4405 [(set (match_operand:DF 0 "register_operand" "=f,f")
4406 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
42a0aa6f 4407 "TARGET_80387 && !TARGET_SSE2"
155d8a47
JW
4408 "@
4409 fild%z1\\t%1
4410 #"
4411 [(set_attr "type" "fmov,multi")
6ef67412 4412 (set_attr "mode" "DF")
155d8a47
JW
4413 (set_attr "fp_int_src" "true")])
4414
42a0aa6f
JH
4415(define_expand "floatsidf2"
4416 [(set (match_operand:DF 0 "register_operand" "")
4417 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4418 ""
4419 "")
4420
4421(define_insn "*floatsidf2_i387"
4422 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4423 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4424 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
e075ae69
RH
4425 "@
4426 fild%z1\\t%1
42a0aa6f
JH
4427 #
4428 cvtsi2sd\\t{%1, %0|%0, %1}"
4429 [(set_attr "type" "fmov,multi,sse")
4430 (set_attr "mode" "DF")
4431 (set_attr "fp_int_src" "true")])
4432
4433(define_insn "*floatsidf2_sse"
4434 [(set (match_operand:DF 0 "register_operand" "=Y")
4435 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4436 "TARGET_SSE2"
4437 "cvtsi2sd\\t{%1, %0|%0, %1}"
4438 [(set_attr "type" "sse")
6ef67412 4439 (set_attr "mode" "DF")
e075ae69 4440 (set_attr "fp_int_src" "true")])
e1f998ad 4441
e075ae69
RH
4442(define_insn "floatdidf2"
4443 [(set (match_operand:DF 0 "register_operand" "=f,f")
4444 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
42a0aa6f 4445 "TARGET_80387 && TARGET_SSE2"
e075ae69
RH
4446 "@
4447 fild%z1\\t%1
4448 #"
4449 [(set_attr "type" "fmov,multi")
6ef67412 4450 (set_attr "mode" "DF")
e075ae69 4451 (set_attr "fp_int_src" "true")])
bc725565 4452
155d8a47
JW
4453(define_insn "floathixf2"
4454 [(set (match_operand:XF 0 "register_operand" "=f,f")
4455 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
1e07edd3 4456 "TARGET_80387 && !TARGET_64BIT"
155d8a47
JW
4457 "@
4458 fild%z1\\t%1
4459 #"
4460 [(set_attr "type" "fmov,multi")
6ef67412 4461 (set_attr "mode" "XF")
155d8a47
JW
4462 (set_attr "fp_int_src" "true")])
4463
2b589241
JH
4464(define_insn "floathitf2"
4465 [(set (match_operand:TF 0 "register_operand" "=f,f")
4466 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4467 "TARGET_80387"
4468 "@
4469 fild%z1\\t%1
4470 #"
4471 [(set_attr "type" "fmov,multi")
4472 (set_attr "mode" "XF")
4473 (set_attr "fp_int_src" "true")])
4474
e075ae69
RH
4475(define_insn "floatsixf2"
4476 [(set (match_operand:XF 0 "register_operand" "=f,f")
4477 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
1e07edd3 4478 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
4479 "@
4480 fild%z1\\t%1
4481 #"
4482 [(set_attr "type" "fmov,multi")
6ef67412 4483 (set_attr "mode" "XF")
e075ae69 4484 (set_attr "fp_int_src" "true")])
53b5ce19 4485
2b589241
JH
4486(define_insn "floatsitf2"
4487 [(set (match_operand:TF 0 "register_operand" "=f,f")
4488 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4489 "TARGET_80387"
4490 "@
4491 fild%z1\\t%1
4492 #"
4493 [(set_attr "type" "fmov,multi")
4494 (set_attr "mode" "XF")
4495 (set_attr "fp_int_src" "true")])
4496
e075ae69 4497(define_insn "floatdixf2"
53b5ce19 4498 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69 4499 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
1e07edd3 4500 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
4501 "@
4502 fild%z1\\t%1
4503 #"
4504 [(set_attr "type" "fmov,multi")
6ef67412 4505 (set_attr "mode" "XF")
e075ae69 4506 (set_attr "fp_int_src" "true")])
53b5ce19 4507
2b589241
JH
4508(define_insn "floatditf2"
4509 [(set (match_operand:TF 0 "register_operand" "=f,f")
4510 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4511 "TARGET_80387"
4512 "@
4513 fild%z1\\t%1
4514 #"
4515 [(set_attr "type" "fmov,multi")
4516 (set_attr "mode" "XF")
4517 (set_attr "fp_int_src" "true")])
4518
e075ae69 4519;; %%% Kill these when reload knows how to do it.
155d8a47
JW
4520(define_split
4521 [(set (match_operand 0 "register_operand" "")
4211a8fb 4522 (float (match_operand 1 "register_operand" "")))]
bf71a4f8
JH
4523 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
4524 && FP_REG_P (operands[0])"
4211a8fb
JH
4525 [(const_int 0)]
4526 "
4527{
4528 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4529 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4530 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4531 ix86_free_from_memory (GET_MODE (operands[1]));
4532 DONE;
4533}")
e075ae69
RH
4534\f
4535;; Add instructions
53b5ce19 4536
e075ae69
RH
4537;; %%% define_expand from the very first?
4538;; %%% splits for addsidi3
4539; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4540; (plus:DI (match_operand:DI 1 "general_operand" "")
4541; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
e1f998ad 4542
e075ae69
RH
4543(define_insn "adddi3"
4544 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4545 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4546 (match_operand:DI 2 "general_operand" "roiF,riF")))
4547 (clobber (reg:CC 17))]
4548 ""
bc725565
JW
4549 "#")
4550
4551(define_split
e075ae69 4552 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 4553 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69
RH
4554 (match_operand:DI 2 "general_operand" "")))
4555 (clobber (reg:CC 17))]
1e07edd3 4556 "reload_completed && !TARGET_64BIT"
7e08e190 4557 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
e075ae69
RH
4558 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4559 (parallel [(set (match_dup 3)
7e08e190 4560 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9dcbdc7e
JH
4561 (match_dup 4))
4562 (match_dup 5)))
e075ae69
RH
4563 (clobber (reg:CC 17))])]
4564 "split_di (operands+0, 1, operands+0, operands+3);
4565 split_di (operands+1, 1, operands+1, operands+4);
4566 split_di (operands+2, 1, operands+2, operands+5);")
4567
7abd4e00 4568(define_insn "*addsi3_carry"
e075ae69 4569 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9dcbdc7e
JH
4570 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4571 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4572 (match_operand:SI 2 "general_operand" "ri,rm")))
e075ae69 4573 (clobber (reg:CC 17))]
d525dfdf 4574 "ix86_binary_operator_ok (PLUS, SImode, operands)"
e075ae69
RH
4575 "adc{l}\\t{%2, %0|%0, %2}"
4576 [(set_attr "type" "alu")
4577 (set_attr "pent_pair" "pu")
6ef67412 4578 (set_attr "mode" "SI")
e075ae69 4579 (set_attr "ppro_uops" "few")])
4fb21e90 4580
7e08e190
JH
4581(define_insn "*addsi3_cc"
4582 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4583 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
4584 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4585 (plus:SI (match_dup 1) (match_dup 2)))]
265dab10 4586 "ix86_binary_operator_ok (PLUS, SImode, operands)"
7e08e190 4587 "add{l}\\t{%2, %0|%0, %2}"
265dab10 4588 [(set_attr "type" "alu")
7e08e190
JH
4589 (set_attr "mode" "SI")])
4590
4591(define_insn "addqi3_cc"
4592 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4593 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
4594 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4595 (plus:QI (match_dup 1) (match_dup 2)))]
4596 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4597 "add{b}\\t{%2, %0|%0, %2}"
4598 [(set_attr "type" "alu")
4599 (set_attr "mode" "QI")])
265dab10 4600
e075ae69
RH
4601(define_expand "addsi3"
4602 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4603 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4604 (match_operand:SI 2 "general_operand" "")))
4605 (clobber (reg:CC 17))])]
4606 ""
4607 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
886c62d1 4608
ad678cb0 4609(define_insn "*lea_0"
e075ae69 4610 [(set (match_operand:SI 0 "register_operand" "=r")
ad678cb0 4611 (match_operand:SI 1 "address_operand" "p"))]
f58acb67 4612 ""
ad678cb0 4613 "lea{l}\\t{%a1, %0|%0, %a1}"
6ef67412
JH
4614 [(set_attr "type" "lea")
4615 (set_attr "mode" "SI")])
2ae0f82c 4616
58787064
JH
4617;; The lea patterns for non-Pmodes needs to be matched by several
4618;; insns converted to real lea by splitters.
4619
4620(define_insn_and_split "*lea_general_1"
4621 [(set (match_operand 0 "register_operand" "=r")
4622 (plus (plus (match_operand 1 "register_operand" "r")
4623 (match_operand 2 "register_operand" "r"))
4624 (match_operand 3 "immediate_operand" "i")))]
4625 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4626 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4627 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4628 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4629 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4630 || GET_MODE (operands[3]) == VOIDmode)"
4631 "#"
cb694d2c 4632 "&& reload_completed"
58787064
JH
4633 [(const_int 0)]
4634 "
4635{
4636 rtx pat;
4637 operands[0] = gen_lowpart (SImode, operands[0]);
4638 operands[1] = gen_lowpart (Pmode, operands[1]);
4639 operands[2] = gen_lowpart (Pmode, operands[2]);
4640 operands[3] = gen_lowpart (Pmode, operands[3]);
4641 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4642 operands[3]);
4643 if (Pmode != SImode)
4644 pat = gen_rtx_SUBREG (SImode, pat, 0);
4645 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4646 DONE;
4647}"
4648 [(set_attr "type" "lea")
4649 (set_attr "mode" "SI")])
4650
4651(define_insn_and_split "*lea_general_2"
4652 [(set (match_operand 0 "register_operand" "=r")
4653 (plus (mult (match_operand 1 "register_operand" "r")
4654 (match_operand 2 "const248_operand" "i"))
4655 (match_operand 3 "nonmemory_operand" "ri")))]
4656 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4657 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4658 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4659 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4660 || GET_MODE (operands[3]) == VOIDmode)"
4661 "#"
cb694d2c 4662 "&& reload_completed"
58787064
JH
4663 [(const_int 0)]
4664 "
4665{
4666 rtx pat;
4667 operands[0] = gen_lowpart (SImode, operands[0]);
4668 operands[1] = gen_lowpart (Pmode, operands[1]);
4669 operands[3] = gen_lowpart (Pmode, operands[3]);
4670 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4671 operands[3]);
4672 if (Pmode != SImode)
4673 pat = gen_rtx_SUBREG (SImode, pat, 0);
4674 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4675 DONE;
4676}"
4677 [(set_attr "type" "lea")
4678 (set_attr "mode" "SI")])
4679
4680(define_insn_and_split "*lea_general_3"
4681 [(set (match_operand 0 "register_operand" "=r")
4682 (plus (plus (mult (match_operand 1 "register_operand" "r")
4683 (match_operand 2 "const248_operand" "i"))
4684 (match_operand 3 "register_operand" "r"))
4685 (match_operand 4 "immediate_operand" "i")))]
4686 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4687 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4688 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4689 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4690 "#"
cb694d2c 4691 "&& reload_completed"
58787064
JH
4692 [(const_int 0)]
4693 "
4694{
4695 rtx pat;
4696 operands[0] = gen_lowpart (SImode, operands[0]);
4697 operands[1] = gen_lowpart (Pmode, operands[1]);
4698 operands[3] = gen_lowpart (Pmode, operands[3]);
4699 operands[4] = gen_lowpart (Pmode, operands[4]);
4700 pat = gen_rtx_PLUS (Pmode,
4701 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4702 operands[2]),
4703 operands[3]),
4704 operands[4]);
4705 if (Pmode != SImode)
4706 pat = gen_rtx_SUBREG (SImode, pat, 0);
4707 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4708 DONE;
4709}"
4710 [(set_attr "type" "lea")
4711 (set_attr "mode" "SI")])
4712
e075ae69
RH
4713(define_insn "*addsi_1"
4714 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
4715 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
4716 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
4717 (clobber (reg:CC 17))]
4718 "ix86_binary_operator_ok (PLUS, SImode, operands)"
2ae0f82c
SC
4719 "*
4720{
e075ae69 4721 switch (get_attr_type (insn))
2ae0f82c 4722 {
e075ae69
RH
4723 case TYPE_LEA:
4724 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
4725 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
2ae0f82c 4726
e075ae69
RH
4727 case TYPE_INCDEC:
4728 if (! rtx_equal_p (operands[0], operands[1]))
4729 abort ();
4730 if (operands[2] == const1_rtx)
4731 return \"inc{l}\\t%0\";
4732 else if (operands[2] == constm1_rtx)
4733 return \"dec{l}\\t%0\";
2ae0f82c 4734 else
e075ae69 4735 abort();
2ae0f82c 4736
e075ae69
RH
4737 default:
4738 if (! rtx_equal_p (operands[0], operands[1]))
4739 abort ();
2ae0f82c 4740
e075ae69
RH
4741 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4742 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4743 if (GET_CODE (operands[2]) == CONST_INT
4744 && (INTVAL (operands[2]) == 128
4745 || (INTVAL (operands[2]) < 0
4746 && INTVAL (operands[2]) != -128)))
4747 {
4748 operands[2] = GEN_INT (-INTVAL (operands[2]));
4749 return \"sub{l}\\t{%2, %0|%0, %2}\";
4750 }
4751 return \"add{l}\\t{%2, %0|%0, %2}\";
4752 }
4753}"
4754 [(set (attr "type")
4755 (cond [(eq_attr "alternative" "2")
4756 (const_string "lea")
4757 ; Current assemblers are broken and do not allow @GOTOFF in
4758 ; ought but a memory context.
4759 (match_operand:SI 2 "pic_symbolic_operand" "")
4760 (const_string "lea")
4761 (match_operand:SI 2 "incdec_operand" "")
4762 (const_string "incdec")
4763 ]
6ef67412
JH
4764 (const_string "alu")))
4765 (set_attr "mode" "SI")])
e075ae69 4766
1c27d4b2
JH
4767;; Convert lea to the lea pattern to avoid flags dependency.
4768(define_split
58787064
JH
4769 [(set (match_operand 0 "register_operand" "")
4770 (plus (match_operand 1 "register_operand" "")
4771 (match_operand 2 "nonmemory_operand" "")))
1c27d4b2 4772 (clobber (reg:CC 17))]
abe24fb3
JH
4773 "reload_completed
4774 && true_regnum (operands[0]) != true_regnum (operands[1])"
58787064
JH
4775 [(const_int 0)]
4776 "
4777{
4778 rtx pat;
58787064
JH
4779 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
4780 may confuse gen_lowpart. */
4781 if (GET_MODE (operands[0]) != Pmode)
4782 {
4783 operands[1] = gen_lowpart (Pmode, operands[1]);
4784 operands[2] = gen_lowpart (Pmode, operands[2]);
4785 }
91f9a498 4786 operands[0] = gen_lowpart (SImode, operands[0]);
58787064
JH
4787 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
4788 if (Pmode != SImode)
4789 pat = gen_rtx_SUBREG (SImode, pat, 0);
4790 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4791 DONE;
4792}")
1c27d4b2 4793
e075ae69 4794(define_insn "*addsi_2"
16189740
RH
4795 [(set (reg 17)
4796 (compare
e075ae69
RH
4797 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4798 (match_operand:SI 2 "general_operand" "rmni,rni"))
4799 (const_int 0)))
4800 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4801 (plus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 4802 "ix86_match_ccmode (insn, CCGOCmode)
16189740 4803 && ix86_binary_operator_ok (PLUS, SImode, operands)
e075ae69
RH
4804 /* Current assemblers are broken and do not allow @GOTOFF in
4805 ought but a memory context. */
4806 && ! pic_symbolic_operand (operands[2], VOIDmode)"
886c62d1
JVA
4807 "*
4808{
e075ae69 4809 switch (get_attr_type (insn))
96f218bb 4810 {
e075ae69
RH
4811 case TYPE_INCDEC:
4812 if (! rtx_equal_p (operands[0], operands[1]))
4813 abort ();
4814 if (operands[2] == const1_rtx)
4815 return \"inc{l}\\t%0\";
4816 else if (operands[2] == constm1_rtx)
4817 return \"dec{l}\\t%0\";
96f218bb 4818 else
e075ae69 4819 abort();
96f218bb 4820
e075ae69
RH
4821 default:
4822 if (! rtx_equal_p (operands[0], operands[1]))
4823 abort ();
4824 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4825 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4826 if (GET_CODE (operands[2]) == CONST_INT
4827 && (INTVAL (operands[2]) == 128
4828 || (INTVAL (operands[2]) < 0
4829 && INTVAL (operands[2]) != -128)))
4830 {
4831 operands[2] = GEN_INT (-INTVAL (operands[2]));
4832 return \"sub{l}\\t{%2, %0|%0, %2}\";
4833 }
4834 return \"add{l}\\t{%2, %0|%0, %2}\";
9c530261 4835 }
a269a03c 4836}"
e075ae69
RH
4837 [(set (attr "type")
4838 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4839 (const_string "incdec")
6ef67412
JH
4840 (const_string "alu")))
4841 (set_attr "mode" "SI")])
e075ae69
RH
4842
4843(define_insn "*addsi_3"
d90ffc8d 4844 [(set (reg 17)
7e08e190
JH
4845 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
4846 (match_operand:SI 1 "nonimmediate_operand" "%0")))
d90ffc8d 4847 (clobber (match_scratch:SI 0 "=r"))]
7e08e190 4848 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
4849 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4850 /* Current assemblers are broken and do not allow @GOTOFF in
4851 ought but a memory context. */
4852 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4853 "*
4854{
4855 switch (get_attr_type (insn))
4856 {
4857 case TYPE_INCDEC:
4858 if (! rtx_equal_p (operands[0], operands[1]))
4859 abort ();
4860 if (operands[2] == const1_rtx)
4861 return \"inc{l}\\t%0\";
4862 else if (operands[2] == constm1_rtx)
4863 return \"dec{l}\\t%0\";
4864 else
4865 abort();
4866
4867 default:
4868 if (! rtx_equal_p (operands[0], operands[1]))
4869 abort ();
4870 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4871 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4872 if (GET_CODE (operands[2]) == CONST_INT
4873 && (INTVAL (operands[2]) == 128
4874 || (INTVAL (operands[2]) < 0
4875 && INTVAL (operands[2]) != -128)))
4876 {
4877 operands[2] = GEN_INT (-INTVAL (operands[2]));
4878 return \"sub{l}\\t{%2, %0|%0, %2}\";
4879 }
4880 return \"add{l}\\t{%2, %0|%0, %2}\";
4881 }
4882}"
4883 [(set (attr "type")
4884 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4885 (const_string "incdec")
4886 (const_string "alu")))
4887 (set_attr "mode" "SI")])
4888
7e08e190
JH
4889; For comparisons agains 1, -1 and 128, we may generate better code
4890; by converting cmp to add, inc or dec as done by peephole2. This pattern
4891; is matched then. We can't accept general immediate, because for
4892; case of overflows, the result is messed up.
4893; This pattern also don't hold of 0x80000000, since the value overflows
4894; when negated.
4895; Also carry flag is reversed compared to cmp, so this converison is valid
4896; only for comparisons not depending on it.
d90ffc8d 4897(define_insn "*addsi_4"
9076b9c1 4898 [(set (reg 17)
7e08e190
JH
4899 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
4900 (match_operand:SI 2 "const_int_operand" "n")))
4901 (clobber (match_scratch:SI 0 "=rm"))]
4902 "ix86_match_ccmode (insn, CCGCmode)
4903 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
4904 "*
4905{
4906 switch (get_attr_type (insn))
4907 {
4908 case TYPE_INCDEC:
4909 if (operands[2] == constm1_rtx)
4910 return \"inc{l}\\t%0\";
4911 else if (operands[2] == const1_rtx)
4912 return \"dec{l}\\t%0\";
4913 else
4914 abort();
e075ae69 4915
7e08e190
JH
4916 default:
4917 if (! rtx_equal_p (operands[0], operands[1]))
4918 abort ();
4919 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4920 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4921 if ((INTVAL (operands[2]) == -128
4922 || (INTVAL (operands[2]) > 0
4923 && INTVAL (operands[2]) != 128)))
4924 return \"sub{l}\\t{%2, %0|%0, %2}\";
4925 operands[2] = GEN_INT (-INTVAL (operands[2]));
4926 return \"add{l}\\t{%2, %0|%0, %2}\";
4927 }
4928}"
4929 [(set (attr "type")
4930 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4931 (const_string "incdec")
4932 (const_string "alu")))
d90ffc8d
JH
4933 (set_attr "mode" "SI")])
4934
7e08e190 4935(define_insn "*addsi_5"
9076b9c1
JH
4936 [(set (reg 17)
4937 (compare
4938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
4939 (match_operand:SI 2 "general_operand" "rmni"))
4940 (const_int 0)))
4941 (clobber (match_scratch:SI 0 "=r"))]
4942 "ix86_match_ccmode (insn, CCGOCmode)
4943 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4944 /* Current assemblers are broken and do not allow @GOTOFF in
4945 ought but a memory context. */
4946 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4947 "*
4948{
4949 switch (get_attr_type (insn))
4950 {
4951 case TYPE_INCDEC:
4952 if (! rtx_equal_p (operands[0], operands[1]))
4953 abort ();
4954 if (operands[2] == const1_rtx)
4955 return \"inc{l}\\t%0\";
4956 else if (operands[2] == constm1_rtx)
4957 return \"dec{l}\\t%0\";
4958 else
4959 abort();
4960
4961 default:
4962 if (! rtx_equal_p (operands[0], operands[1]))
4963 abort ();
4964 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4965 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4966 if (GET_CODE (operands[2]) == CONST_INT
4967 && (INTVAL (operands[2]) == 128
4968 || (INTVAL (operands[2]) < 0
4969 && INTVAL (operands[2]) != -128)))
4970 {
4971 operands[2] = GEN_INT (-INTVAL (operands[2]));
4972 return \"sub{l}\\t{%2, %0|%0, %2}\";
4973 }
4974 return \"add{l}\\t{%2, %0|%0, %2}\";
4975 }
4976}"
4977 [(set (attr "type")
4978 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4979 (const_string "incdec")
4980 (const_string "alu")))
4981 (set_attr "mode" "SI")])
4982
2ae0f82c 4983(define_expand "addhi3"
4cbfbb1b 4984 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69
RH
4985 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4986 (match_operand:HI 2 "general_operand" "")))
4987 (clobber (reg:CC 17))])]
d9f32422 4988 "TARGET_HIMODE_MATH"
e075ae69 4989 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
2ae0f82c 4990
e075ae69
RH
4991;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
4992;; type optimizations enabled by define-splits. This is not important
4993;; for PII, and in fact harmful because of partial register stalls.
4994
58787064
JH
4995(define_insn "*addhi_1_lea"
4996 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4997 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
4998 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
4999 (clobber (reg:CC 17))]
5000 "!TARGET_PARTIAL_REG_STALL
5001 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5002 "*
5003{
5004 switch (get_attr_type (insn))
5005 {
5006 case TYPE_LEA:
5007 return \"#\";
5008 case TYPE_INCDEC:
5009 if (operands[2] == const1_rtx)
5010 return \"inc{w}\\t%0\";
5011 else if (operands[2] == constm1_rtx
5012 || (GET_CODE (operands[2]) == CONST_INT
5013 && INTVAL (operands[2]) == 65535))
5014 return \"dec{w}\\t%0\";
5015 abort();
5016
5017 default:
5018 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5019 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5020 if (GET_CODE (operands[2]) == CONST_INT
5021 && (INTVAL (operands[2]) == 128
5022 || (INTVAL (operands[2]) < 0
5023 && INTVAL (operands[2]) != -128)))
5024 {
5025 operands[2] = GEN_INT (-INTVAL (operands[2]));
5026 return \"sub{w}\\t{%2, %0|%0, %2}\";
5027 }
5028 return \"add{w}\\t{%2, %0|%0, %2}\";
5029 }
5030}"
5031 [(set (attr "type")
5032 (if_then_else (eq_attr "alternative" "2")
5033 (const_string "lea")
5034 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5035 (const_string "incdec")
5036 (const_string "alu"))))
5037 (set_attr "mode" "HI,HI,SI")])
5038
e075ae69
RH
5039(define_insn "*addhi_1"
5040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5041 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5042 (match_operand:HI 2 "general_operand" "ri,rm")))
5043 (clobber (reg:CC 17))]
58787064
JH
5044 "TARGET_PARTIAL_REG_STALL
5045 && ix86_binary_operator_ok (PLUS, HImode, operands)"
886c62d1
JVA
5046 "*
5047{
e075ae69 5048 switch (get_attr_type (insn))
7c802a40 5049 {
e075ae69
RH
5050 case TYPE_INCDEC:
5051 if (operands[2] == const1_rtx)
5052 return \"inc{w}\\t%0\";
5053 else if (operands[2] == constm1_rtx
5054 || (GET_CODE (operands[2]) == CONST_INT
5055 && INTVAL (operands[2]) == 65535))
5056 return \"dec{w}\\t%0\";
5057 abort();
7c802a40 5058
e075ae69
RH
5059 default:
5060 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5061 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5062 if (GET_CODE (operands[2]) == CONST_INT
5063 && (INTVAL (operands[2]) == 128
5064 || (INTVAL (operands[2]) < 0
5065 && INTVAL (operands[2]) != -128)))
5066 {
5067 operands[2] = GEN_INT (-INTVAL (operands[2]));
5068 return \"sub{w}\\t{%2, %0|%0, %2}\";
5069 }
5070 return \"add{w}\\t{%2, %0|%0, %2}\";
7c802a40 5071 }
e075ae69
RH
5072}"
5073 [(set (attr "type")
5074 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5075 (const_string "incdec")
6ef67412
JH
5076 (const_string "alu")))
5077 (set_attr "mode" "HI")])
7c802a40 5078
e075ae69 5079(define_insn "*addhi_2"
16189740
RH
5080 [(set (reg 17)
5081 (compare
e075ae69
RH
5082 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5083 (match_operand:HI 2 "general_operand" "rmni,rni"))
5084 (const_int 0)))
5085 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5086 (plus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 5087 "ix86_match_ccmode (insn, CCGOCmode)
16189740 5088 && ix86_binary_operator_ok (PLUS, HImode, operands)"
e075ae69
RH
5089 "*
5090{
5091 switch (get_attr_type (insn))
b980bec0 5092 {
e075ae69
RH
5093 case TYPE_INCDEC:
5094 if (operands[2] == const1_rtx)
5095 return \"inc{w}\\t%0\";
5096 else if (operands[2] == constm1_rtx
5097 || (GET_CODE (operands[2]) == CONST_INT
5098 && INTVAL (operands[2]) == 65535))
5099 return \"dec{w}\\t%0\";
5100 abort();
b980bec0 5101
e075ae69
RH
5102 default:
5103 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5104 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5105 if (GET_CODE (operands[2]) == CONST_INT
5106 && (INTVAL (operands[2]) == 128
5107 || (INTVAL (operands[2]) < 0
5108 && INTVAL (operands[2]) != -128)))
5109 {
5110 operands[2] = GEN_INT (-INTVAL (operands[2]));
5111 return \"sub{w}\\t{%2, %0|%0, %2}\";
5112 }
5113 return \"add{w}\\t{%2, %0|%0, %2}\";
b980bec0 5114 }
e075ae69
RH
5115}"
5116 [(set (attr "type")
5117 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5118 (const_string "incdec")
6ef67412
JH
5119 (const_string "alu")))
5120 (set_attr "mode" "HI")])
e075ae69
RH
5121
5122(define_insn "*addhi_3"
d90ffc8d 5123 [(set (reg 17)
7e08e190
JH
5124 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5125 (match_operand:HI 1 "nonimmediate_operand" "%0")))
d90ffc8d 5126 (clobber (match_scratch:HI 0 "=r"))]
7e08e190 5127 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
5128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5129 "*
5130{
5131 switch (get_attr_type (insn))
5132 {
5133 case TYPE_INCDEC:
5134 if (operands[2] == const1_rtx)
5135 return \"inc{w}\\t%0\";
5136 else if (operands[2] == constm1_rtx
5137 || (GET_CODE (operands[2]) == CONST_INT
5138 && INTVAL (operands[2]) == 65535))
5139 return \"dec{w}\\t%0\";
5140 abort();
5141
5142 default:
5143 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5144 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5145 if (GET_CODE (operands[2]) == CONST_INT
5146 && (INTVAL (operands[2]) == 128
5147 || (INTVAL (operands[2]) < 0
5148 && INTVAL (operands[2]) != -128)))
5149 {
5150 operands[2] = GEN_INT (-INTVAL (operands[2]));
5151 return \"sub{w}\\t{%2, %0|%0, %2}\";
5152 }
5153 return \"add{w}\\t{%2, %0|%0, %2}\";
5154 }
5155}"
5156 [(set (attr "type")
5157 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5158 (const_string "incdec")
5159 (const_string "alu")))
5160 (set_attr "mode" "HI")])
5161
7e08e190 5162; See comments above addsi_3_imm for details.
d90ffc8d 5163(define_insn "*addhi_4"
9076b9c1 5164 [(set (reg 17)
7e08e190
JH
5165 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5166 (match_operand:HI 2 "const_int_operand" "n")))
5167 (clobber (match_scratch:HI 0 "=rm"))]
5168 "ix86_match_ccmode (insn, CCGCmode)
5169 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5170 "*
5171{
5172 switch (get_attr_type (insn))
5173 {
5174 case TYPE_INCDEC:
5175 if (operands[2] == constm1_rtx
5176 || (GET_CODE (operands[2]) == CONST_INT
5177 && INTVAL (operands[2]) == 65535))
5178 return \"inc{w}\\t%0\";
5179 else if (operands[2] == const1_rtx)
5180 return \"dec{w}\\t%0\";
5181 else
5182 abort();
5183
5184 default:
5185 if (! rtx_equal_p (operands[0], operands[1]))
5186 abort ();
5187 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5188 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5189 if ((INTVAL (operands[2]) == -128
5190 || (INTVAL (operands[2]) > 0
5191 && INTVAL (operands[2]) != 128)))
5192 return \"sub{w}\\t{%2, %0|%0, %2}\";
5193 operands[2] = GEN_INT (-INTVAL (operands[2]));
5194 return \"add{w}\\t{%2, %0|%0, %2}\";
5195 }
5196}"
5197 [(set (attr "type")
5198 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5199 (const_string "incdec")
5200 (const_string "alu")))
5201 (set_attr "mode" "SI")])
b980bec0 5202
d90ffc8d 5203
7e08e190 5204(define_insn "*addhi_5"
9076b9c1
JH
5205 [(set (reg 17)
5206 (compare
5207 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5208 (match_operand:HI 2 "general_operand" "rmni"))
5209 (const_int 0)))
5210 (clobber (match_scratch:HI 0 "=r"))]
5211 "ix86_match_ccmode (insn, CCGOCmode)
5212 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5213 "*
5214{
5215 switch (get_attr_type (insn))
5216 {
5217 case TYPE_INCDEC:
5218 if (operands[2] == const1_rtx)
5219 return \"inc{w}\\t%0\";
5220 else if (operands[2] == constm1_rtx
5221 || (GET_CODE (operands[2]) == CONST_INT
5222 && INTVAL (operands[2]) == 65535))
5223 return \"dec{w}\\t%0\";
5224 abort();
5225
5226 default:
5227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5229 if (GET_CODE (operands[2]) == CONST_INT
5230 && (INTVAL (operands[2]) == 128
5231 || (INTVAL (operands[2]) < 0
5232 && INTVAL (operands[2]) != -128)))
5233 {
5234 operands[2] = GEN_INT (-INTVAL (operands[2]));
5235 return \"sub{w}\\t{%2, %0|%0, %2}\";
5236 }
5237 return \"add{w}\\t{%2, %0|%0, %2}\";
5238 }
5239}"
5240 [(set (attr "type")
5241 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5242 (const_string "incdec")
5243 (const_string "alu")))
5244 (set_attr "mode" "HI")])
5245
e075ae69 5246(define_expand "addqi3"
4cbfbb1b
JH
5247 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5248 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69
RH
5249 (match_operand:QI 2 "general_operand" "")))
5250 (clobber (reg:CC 17))])]
d9f32422 5251 "TARGET_QIMODE_MATH"
e075ae69
RH
5252 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5253
5254;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
5255(define_insn "*addqi_1_lea"
5256 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5257 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5258 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
5259 (clobber (reg:CC 17))]
5260 "!TARGET_PARTIAL_REG_STALL
5261 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5262 "*
5263{
5264 int widen = (which_alternative == 2);
5265 switch (get_attr_type (insn))
5266 {
5267 case TYPE_LEA:
5268 return \"#\";
5269 case TYPE_INCDEC:
5270 if (operands[2] == const1_rtx)
5271 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5272 else if (operands[2] == constm1_rtx
5273 || (GET_CODE (operands[2]) == CONST_INT
5274 && INTVAL (operands[2]) == 255))
5275 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5276 abort();
5277
5278 default:
5279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5280 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5281 if (GET_CODE (operands[2]) == CONST_INT
5282 && (INTVAL (operands[2]) == 128
5283 || (INTVAL (operands[2]) < 0
5284 && INTVAL (operands[2]) != -128)))
5285 {
5286 operands[2] = GEN_INT (-INTVAL (operands[2]));
5287 if (widen)
5288 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5289 else
5290 return \"sub{b}\\t{%2, %0|%0, %2}\";
5291 }
5292 if (widen)
5293 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5294 else
5295 return \"add{b}\\t{%2, %0|%0, %2}\";
5296 }
5297}"
5298 [(set (attr "type")
5299 (if_then_else (eq_attr "alternative" "3")
5300 (const_string "lea")
adc88131 5301 (if_then_else (match_operand:QI 2 "incdec_operand" "")
58787064
JH
5302 (const_string "incdec")
5303 (const_string "alu"))))
adc88131 5304 (set_attr "mode" "QI,QI,SI,SI")])
58787064 5305
e075ae69 5306(define_insn "*addqi_1"
7c6b971d 5307 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 5308 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 5309 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
e075ae69 5310 (clobber (reg:CC 17))]
58787064
JH
5311 "TARGET_PARTIAL_REG_STALL
5312 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
5313 "*
5314{
5315 int widen = (which_alternative == 2);
5316 switch (get_attr_type (insn))
5bc7cd8e 5317 {
e075ae69
RH
5318 case TYPE_INCDEC:
5319 if (operands[2] == const1_rtx)
5320 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5321 else if (operands[2] == constm1_rtx
5322 || (GET_CODE (operands[2]) == CONST_INT
5323 && INTVAL (operands[2]) == 255))
5324 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5325 abort();
5bc7cd8e 5326
e075ae69
RH
5327 default:
5328 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5329 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5330 if (GET_CODE (operands[2]) == CONST_INT
5331 && (INTVAL (operands[2]) == 128
5332 || (INTVAL (operands[2]) < 0
5333 && INTVAL (operands[2]) != -128)))
5bc7cd8e 5334 {
e075ae69
RH
5335 operands[2] = GEN_INT (-INTVAL (operands[2]));
5336 if (widen)
5337 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5338 else
5339 return \"sub{b}\\t{%2, %0|%0, %2}\";
5bc7cd8e 5340 }
e075ae69
RH
5341 if (widen)
5342 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5343 else
5344 return \"add{b}\\t{%2, %0|%0, %2}\";
5bc7cd8e 5345 }
e075ae69
RH
5346}"
5347 [(set (attr "type")
5348 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5349 (const_string "incdec")
6ef67412
JH
5350 (const_string "alu")))
5351 (set_attr "mode" "QI,QI,SI")])
e075ae69
RH
5352
5353(define_insn "*addqi_2"
16189740
RH
5354 [(set (reg 17)
5355 (compare
e075ae69
RH
5356 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5357 (match_operand:QI 2 "general_operand" "qmni,qni"))
5358 (const_int 0)))
5359 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5360 (plus:QI (match_dup 1) (match_dup 2)))]
9076b9c1 5361 "ix86_match_ccmode (insn, CCGOCmode)
16189740 5362 && ix86_binary_operator_ok (PLUS, QImode, operands)"
e075ae69
RH
5363 "*
5364{
5365 switch (get_attr_type (insn))
5366 {
5367 case TYPE_INCDEC:
5368 if (operands[2] == const1_rtx)
5369 return \"inc{b}\\t%0\";
5370 else if (operands[2] == constm1_rtx
5371 || (GET_CODE (operands[2]) == CONST_INT
5372 && INTVAL (operands[2]) == 255))
5373 return \"dec{b}\\t%0\";
5374 abort();
5bc7cd8e 5375
e075ae69
RH
5376 default:
5377 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5378 if (GET_CODE (operands[2]) == CONST_INT
5379 && INTVAL (operands[2]) < 0)
5380 {
5381 operands[2] = GEN_INT (-INTVAL (operands[2]));
5382 return \"sub{b}\\t{%2, %0|%0, %2}\";
5383 }
5384 return \"add{b}\\t{%2, %0|%0, %2}\";
5385 }
a269a03c 5386}"
e075ae69
RH
5387 [(set (attr "type")
5388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5389 (const_string "incdec")
6ef67412
JH
5390 (const_string "alu")))
5391 (set_attr "mode" "QI")])
e075ae69
RH
5392
5393(define_insn "*addqi_3"
d90ffc8d 5394 [(set (reg 17)
7e08e190
JH
5395 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
5396 (match_operand:QI 1 "nonimmediate_operand" "%0")))
5397 (clobber (match_scratch:QI 0 "=q"))]
5398 "ix86_match_ccmode (insn, CCZmode)
d90ffc8d
JH
5399 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5400 "*
5401{
5402 switch (get_attr_type (insn))
5403 {
5404 case TYPE_INCDEC:
5405 if (operands[2] == const1_rtx)
5406 return \"inc{b}\\t%0\";
5407 else if (operands[2] == constm1_rtx
5408 || (GET_CODE (operands[2]) == CONST_INT
5409 && INTVAL (operands[2]) == 255))
5410 return \"dec{b}\\t%0\";
5411 abort();
5412
5413 default:
5414 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5415 if (GET_CODE (operands[2]) == CONST_INT
5416 && INTVAL (operands[2]) < 0)
5417 {
5418 operands[2] = GEN_INT (-INTVAL (operands[2]));
5419 return \"sub{b}\\t{%2, %0|%0, %2}\";
5420 }
5421 return \"add{b}\\t{%2, %0|%0, %2}\";
5422 }
5423}"
5424 [(set (attr "type")
5425 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5426 (const_string "incdec")
5427 (const_string "alu")))
5428 (set_attr "mode" "QI")])
5429
7e08e190 5430; See comments above addsi_3_imm for details.
d90ffc8d 5431(define_insn "*addqi_4"
9076b9c1 5432 [(set (reg 17)
7e08e190
JH
5433 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
5434 (match_operand:QI 2 "const_int_operand" "n")))
5435 (clobber (match_scratch:QI 0 "=qm"))]
5436 "ix86_match_ccmode (insn, CCGCmode)
5437 && (INTVAL (operands[2]) & 0xff) != 0x80"
5438 "*
5439{
5440 switch (get_attr_type (insn))
5441 {
5442 case TYPE_INCDEC:
5443 if (operands[2] == constm1_rtx
5444 || (GET_CODE (operands[2]) == CONST_INT
5445 && INTVAL (operands[2]) == 255))
5446 return \"inc{b}\\t%0\";
5447 else if (operands[2] == const1_rtx)
5448 return \"dec{b}\\t%0\";
5449 else
5450 abort();
5451
5452 default:
5453 if (! rtx_equal_p (operands[0], operands[1]))
5454 abort ();
5455 if (INTVAL (operands[2]) < 0)
5456 {
5457 operands[2] = GEN_INT (-INTVAL (operands[2]));
5458 return \"add{b}\\t{%2, %0|%0, %2}\";
5459 }
5460 return \"sub{b}\\t{%2, %0|%0, %2}\";
5461 }
5462}"
5463 [(set (attr "type")
5464 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5465 (const_string "incdec")
5466 (const_string "alu")))
6ef67412 5467 (set_attr "mode" "QI")])
886c62d1 5468
9dcbdc7e 5469
d90ffc8d 5470(define_insn "*addqi_5"
9076b9c1
JH
5471 [(set (reg 17)
5472 (compare
5473 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
5474 (match_operand:QI 2 "general_operand" "qmni"))
5475 (const_int 0)))
7e08e190 5476 (clobber (match_scratch:QI 0 "=q"))]
9076b9c1
JH
5477 "ix86_match_ccmode (insn, CCGOCmode)
5478 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5479 "*
5480{
5481 switch (get_attr_type (insn))
5482 {
5483 case TYPE_INCDEC:
5484 if (operands[2] == const1_rtx)
5485 return \"inc{b}\\t%0\";
5486 else if (operands[2] == constm1_rtx
5487 || (GET_CODE (operands[2]) == CONST_INT
5488 && INTVAL (operands[2]) == 255))
5489 return \"dec{b}\\t%0\";
5490 abort();
5491
5492 default:
5493 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5494 if (GET_CODE (operands[2]) == CONST_INT
5495 && INTVAL (operands[2]) < 0)
5496 {
5497 operands[2] = GEN_INT (-INTVAL (operands[2]));
5498 return \"sub{b}\\t{%2, %0|%0, %2}\";
5499 }
5500 return \"add{b}\\t{%2, %0|%0, %2}\";
5501 }
5502}"
5503 [(set (attr "type")
5504 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5505 (const_string "incdec")
5506 (const_string "alu")))
5507 (set_attr "mode" "QI")])
5508
e075ae69
RH
5509
5510(define_insn "addqi_ext_1"
5511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5512 (const_int 8)
5513 (const_int 8))
5514 (plus:SI
5515 (zero_extract:SI
5516 (match_operand 1 "ext_register_operand" "0")
5517 (const_int 8)
5518 (const_int 8))
5519 (match_operand:QI 2 "general_operand" "qmn")))
5520 (clobber (reg:CC 17))]
d2836273
JH
5521 "!TARGET_64BIT"
5522 "*
5523{
5524 switch (get_attr_type (insn))
5525 {
5526 case TYPE_INCDEC:
5527 if (operands[2] == const1_rtx)
5528 return \"inc{b}\\t%h0\";
5529 else if (operands[2] == constm1_rtx
5530 || (GET_CODE (operands[2]) == CONST_INT
5531 && INTVAL (operands[2]) == 255))
5532 return \"dec{b}\\t%h0\";
5533 abort();
5534
5535 default:
5536 return \"add{b}\\t{%2, %h0|%h0, %2}\";
5537 }
5538}"
5539 [(set (attr "type")
5540 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5541 (const_string "incdec")
5542 (const_string "alu")))
5543 (set_attr "mode" "QI")])
5544
5545(define_insn "*addqi_ext_1_rex64"
5546 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5547 (const_int 8)
5548 (const_int 8))
5549 (plus:SI
5550 (zero_extract:SI
5551 (match_operand 1 "ext_register_operand" "0")
5552 (const_int 8)
5553 (const_int 8))
5554 (match_operand:QI 2 "nonmemory_operand" "Qn")))
5555 (clobber (reg:CC 17))]
5556 "TARGET_64BIT"
e075ae69
RH
5557 "*
5558{
5559 switch (get_attr_type (insn))
5560 {
5561 case TYPE_INCDEC:
5562 if (operands[2] == const1_rtx)
5563 return \"inc{b}\\t%h0\";
5564 else if (operands[2] == constm1_rtx
5565 || (GET_CODE (operands[2]) == CONST_INT
5566 && INTVAL (operands[2]) == 255))
5567 return \"dec{b}\\t%h0\";
5568 abort();
886c62d1 5569
e075ae69
RH
5570 default:
5571 return \"add{b}\\t{%2, %h0|%h0, %2}\";
5572 }
a269a03c 5573}"
e075ae69
RH
5574 [(set (attr "type")
5575 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5576 (const_string "incdec")
6ef67412
JH
5577 (const_string "alu")))
5578 (set_attr "mode" "QI")])
e075ae69
RH
5579
5580(define_insn "*addqi_ext_2"
d2836273 5581 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
5582 (const_int 8)
5583 (const_int 8))
5584 (plus:SI
5585 (zero_extract:SI
5586 (match_operand 1 "ext_register_operand" "%0")
5587 (const_int 8)
5588 (const_int 8))
5589 (zero_extract:SI
d2836273 5590 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
5591 (const_int 8)
5592 (const_int 8))))
5593 (clobber (reg:CC 17))]
5594 ""
5595 "add{b}\\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "QI")])
886c62d1 5598
886c62d1
JVA
5599;; The patterns that match these are at the end of this file.
5600
4fb21e90
JVA
5601(define_expand "addxf3"
5602 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
5603 (plus:XF (match_operand:XF 1 "register_operand" "")
5604 (match_operand:XF 2 "register_operand" "")))]
1e07edd3 5605 "TARGET_80387 && !TARGET_64BIT"
4fb21e90
JVA
5606 "")
5607
2b589241
JH
5608(define_expand "addtf3"
5609 [(set (match_operand:TF 0 "register_operand" "")
5610 (plus:TF (match_operand:TF 1 "register_operand" "")
5611 (match_operand:TF 2 "register_operand" "")))]
5612 "TARGET_80387"
5613 "")
5614
886c62d1
JVA
5615(define_expand "adddf3"
5616 [(set (match_operand:DF 0 "register_operand" "")
06a964de 5617 (plus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 5618 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 5619 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
5620 "")
5621
5622(define_expand "addsf3"
5623 [(set (match_operand:SF 0 "register_operand" "")
06a964de 5624 (plus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 5625 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 5626 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
5627 "")
5628\f
e075ae69 5629;; Subtract instructions
a269a03c 5630
e075ae69
RH
5631;; %%% define_expand from the very first?
5632;; %%% splits for subsidi3
2ae0f82c 5633
f58acb67 5634(define_insn "subdi3"
e075ae69 5635 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4cbfbb1b 5636 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
5637 (match_operand:DI 2 "general_operand" "roiF,riF")))
5638 (clobber (reg:CC 17))]
acb94fa1 5639 ""
e075ae69 5640 "#")
9c530261 5641
e075ae69
RH
5642(define_split
5643 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4cbfbb1b 5644 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
e075ae69
RH
5645 (match_operand:DI 2 "general_operand" "")))
5646 (clobber (reg:CC 17))]
1e07edd3 5647 "reload_completed && !TARGET_64BIT"
9dcbdc7e 5648 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
e075ae69
RH
5649 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
5650 (parallel [(set (match_dup 3)
5651 (minus:SI (match_dup 4)
9dcbdc7e
JH
5652 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5653 (match_dup 5))))
e075ae69
RH
5654 (clobber (reg:CC 17))])]
5655 "split_di (operands+0, 1, operands+0, operands+3);
5656 split_di (operands+1, 1, operands+1, operands+4);
5657 split_di (operands+2, 1, operands+2, operands+5);")
5658
7e08e190 5659(define_insn "subsi3_carry"
e075ae69
RH
5660 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5661 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9dcbdc7e
JH
5662 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5663 (match_operand:SI 2 "general_operand" "ri,rm"))))
e075ae69 5664 (clobber (reg:CC 17))]
d525dfdf 5665 "ix86_binary_operator_ok (MINUS, SImode, operands)"
e075ae69
RH
5666 "sbb{l}\\t{%2, %0|%0, %2}"
5667 [(set_attr "type" "alu")
5668 (set_attr "pent_pair" "pu")
6ef67412
JH
5669 (set_attr "ppro_uops" "few")
5670 (set_attr "mode" "SI")])
886c62d1 5671
2ae0f82c 5672(define_expand "subsi3"
e075ae69
RH
5673 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5674 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5675 (match_operand:SI 2 "general_operand" "")))
5676 (clobber (reg:CC 17))])]
886c62d1 5677 ""
e075ae69 5678 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
2ae0f82c 5679
e075ae69 5680(define_insn "*subsi_1"
2ae0f82c
SC
5681 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5682 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
5683 (match_operand:SI 2 "general_operand" "ri,rm")))
5684 (clobber (reg:CC 17))]
5685 "ix86_binary_operator_ok (MINUS, SImode, operands)"
5686 "sub{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
5687 [(set_attr "type" "alu")
5688 (set_attr "mode" "SI")])
e075ae69
RH
5689
5690(define_insn "*subsi_2"
16189740
RH
5691 [(set (reg 17)
5692 (compare
e075ae69
RH
5693 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5694 (match_operand:SI 2 "general_operand" "ri,rm"))
5695 (const_int 0)))
5696 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5697 (minus:SI (match_dup 1) (match_dup 2)))]
9076b9c1 5698 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d
JH
5699 && ix86_binary_operator_ok (MINUS, SImode, operands)"
5700 "sub{l}\\t{%2, %0|%0, %2}"
5701 [(set_attr "type" "alu")
5702 (set_attr "mode" "SI")])
5703
5704(define_insn "*subsi_3"
5705 [(set (reg 17)
5706 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
5707 (match_operand:SI 2 "general_operand" "ri,rm")))
5708 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5709 (minus:SI (match_dup 1) (match_dup 2)))]
16189740
RH
5710 "ix86_match_ccmode (insn, CCmode)
5711 && ix86_binary_operator_ok (MINUS, SImode, operands)"
e075ae69 5712 "sub{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
5713 [(set_attr "type" "alu")
5714 (set_attr "mode" "SI")])
886c62d1 5715
2ae0f82c 5716(define_expand "subhi3"
4cbfbb1b 5717 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
e075ae69
RH
5718 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5719 (match_operand:HI 2 "general_operand" "")))
5720 (clobber (reg:CC 17))])]
d9f32422 5721 "TARGET_HIMODE_MATH"
e075ae69 5722 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
2ae0f82c 5723
e075ae69 5724(define_insn "*subhi_1"
2ae0f82c 5725 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
87fd1847 5726 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
5727 (match_operand:HI 2 "general_operand" "ri,rm")))
5728 (clobber (reg:CC 17))]
2ae0f82c 5729 "ix86_binary_operator_ok (MINUS, HImode, operands)"
e075ae69 5730 "sub{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
5731 [(set_attr "type" "alu")
5732 (set_attr "mode" "HI")])
e075ae69
RH
5733
5734(define_insn "*subhi_2"
16189740
RH
5735 [(set (reg 17)
5736 (compare
e075ae69
RH
5737 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5738 (match_operand:HI 2 "general_operand" "ri,rm"))
5739 (const_int 0)))
5740 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5741 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 5742 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d
JH
5743 && ix86_binary_operator_ok (MINUS, HImode, operands)"
5744 "sub{w}\\t{%2, %0|%0, %2}"
5745 [(set_attr "type" "alu")
5746 (set_attr "mode" "HI")])
5747
5748(define_insn "*subhi_3"
5749 [(set (reg 17)
5750 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
5751 (match_operand:HI 2 "general_operand" "ri,rm")))
5752 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5753 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
5754 "ix86_match_ccmode (insn, CCmode)
5755 && ix86_binary_operator_ok (MINUS, HImode, operands)"
e075ae69 5756 "sub{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
5757 [(set_attr "type" "alu")
5758 (set_attr "mode" "HI")])
886c62d1 5759
2ae0f82c 5760(define_expand "subqi3"
4cbfbb1b
JH
5761 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5762 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
e075ae69
RH
5763 (match_operand:QI 2 "general_operand" "")))
5764 (clobber (reg:CC 17))])]
d9f32422 5765 "TARGET_QIMODE_MATH"
e075ae69 5766 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
2ae0f82c 5767
e075ae69 5768(define_insn "*subqi_1"
2ae0f82c
SC
5769 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5770 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
e075ae69
RH
5771 (match_operand:QI 2 "general_operand" "qn,qmn")))
5772 (clobber (reg:CC 17))]
5773 "ix86_binary_operator_ok (MINUS, QImode, operands)"
5774 "sub{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
5775 [(set_attr "type" "alu")
5776 (set_attr "mode" "QI")])
e075ae69
RH
5777
5778(define_insn "*subqi_2"
16189740
RH
5779 [(set (reg 17)
5780 (compare
e075ae69
RH
5781 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5782 (match_operand:QI 2 "general_operand" "qi,qm"))
5783 (const_int 0)))
5784 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5785 (minus:HI (match_dup 1) (match_dup 2)))]
9076b9c1 5786 "ix86_match_ccmode (insn, CCGOCmode)
d90ffc8d
JH
5787 && ix86_binary_operator_ok (MINUS, QImode, operands)"
5788 "sub{b}\\t{%2, %0|%0, %2}"
5789 [(set_attr "type" "alu")
5790 (set_attr "mode" "QI")])
5791
5792(define_insn "*subqi_3"
5793 [(set (reg 17)
5794 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
5795 (match_operand:QI 2 "general_operand" "qi,qm")))
5796 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5797 (minus:HI (match_dup 1) (match_dup 2)))]
16189740
RH
5798 "ix86_match_ccmode (insn, CCmode)
5799 && ix86_binary_operator_ok (MINUS, QImode, operands)"
e075ae69 5800 "sub{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
5801 [(set_attr "type" "alu")
5802 (set_attr "mode" "QI")])
2ae0f82c 5803
886c62d1
JVA
5804;; The patterns that match these are at the end of this file.
5805
4fb21e90
JVA
5806(define_expand "subxf3"
5807 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
5808 (minus:XF (match_operand:XF 1 "register_operand" "")
5809 (match_operand:XF 2 "register_operand" "")))]
1e07edd3 5810 "TARGET_80387 && !TARGET_64BIT"
4fb21e90
JVA
5811 "")
5812
2b589241
JH
5813(define_expand "subtf3"
5814 [(set (match_operand:TF 0 "register_operand" "")
5815 (minus:TF (match_operand:TF 1 "register_operand" "")
5816 (match_operand:TF 2 "register_operand" "")))]
5817 "TARGET_80387"
5818 "")
5819
886c62d1
JVA
5820(define_expand "subdf3"
5821 [(set (match_operand:DF 0 "register_operand" "")
06a964de 5822 (minus:DF (match_operand:DF 1 "register_operand" "")
886c62d1 5823 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 5824 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
5825 "")
5826
5827(define_expand "subsf3"
5828 [(set (match_operand:SF 0 "register_operand" "")
06a964de 5829 (minus:SF (match_operand:SF 1 "register_operand" "")
886c62d1 5830 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 5831 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
5832 "")
5833\f
e075ae69 5834;; Multiply instructions
886c62d1 5835
d525dfdf
JH
5836(define_expand "mulsi3"
5837 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5838 (mult:SI (match_operand:SI 1 "register_operand" "")
5839 (match_operand:SI 2 "general_operand" "")))
5840 (clobber (reg:CC 17))])]
5841 ""
5842 "")
5843
5844(define_insn "*mulsi3_1"
e075ae69
RH
5845 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5846 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
5847 (match_operand:SI 2 "general_operand" "K,i,mr")))
5848 (clobber (reg:CC 17))]
d525dfdf 5849 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
20819a09
MM
5850 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
5851 ; there are two ways of writing the exact same machine instruction
5852 ; in assembly language. One, for example, is:
5853 ;
5854 ; imul $12, %eax
5855 ;
5856 ; while the other is:
5857 ;
5858 ; imul $12, %eax, %eax
5859 ;
5860 ; The first is simply short-hand for the latter. But, some assemblers,
5861 ; like the SCO OSR5 COFF assembler, don't handle the first form.
e075ae69
RH
5862 "@
5863 imul{l}\\t{%2, %1, %0|%0, %1, %2}
20819a09 5864 imul{l}\\t{%2, %1, %0|%0, %1, %2}
e075ae69
RH
5865 imul{l}\\t{%2, %0|%0, %2}"
5866 [(set_attr "type" "imul")
6ef67412
JH
5867 (set_attr "prefix_0f" "0,0,1")
5868 (set_attr "mode" "SI")])
886c62d1 5869
d525dfdf
JH
5870(define_expand "mulhi3"
5871 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5872 (mult:HI (match_operand:HI 1 "register_operand" "")
5873 (match_operand:HI 2 "general_operand" "")))
5874 (clobber (reg:CC 17))])]
d9f32422 5875 "TARGET_HIMODE_MATH"
d525dfdf
JH
5876 "")
5877
5878(define_insn "*mulhi3_1"
6ef67412
JH
5879 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
5880 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
5881 (match_operand:HI 2 "general_operand" "K,i,mr")))
e075ae69 5882 (clobber (reg:CC 17))]
d525dfdf 5883 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
e075ae69
RH
5884 ; %%% There was a note about "Assembler has weird restrictions",
5885 ; concerning alternative 1 when op1 == op0. True?
5886 "@
6ef67412 5887 imul{w}\\t{%2, %1, %0|%0, %1, %2}
e075ae69
RH
5888 imul{w}\\t{%2, %1, %0|%0, %1, %2}
5889 imul{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
5890 [(set_attr "type" "imul")
5891 (set_attr "prefix_0f" "0,0,1")
5892 (set_attr "mode" "HI")])
886c62d1 5893
765a46f9
JH
5894(define_insn "mulqi3"
5895 [(set (match_operand:QI 0 "register_operand" "=a")
5896 (mult:QI (match_operand:QI 1 "register_operand" "%0")
5897 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5898 (clobber (reg:CC 17))]
d9f32422 5899 "TARGET_QIMODE_MATH"
765a46f9 5900 "mul{b}\\t%2"
6ef67412
JH
5901 [(set_attr "type" "imul")
5902 (set_attr "length_immediate" "0")
5903 (set_attr "mode" "QI")])
765a46f9 5904
4b71cd6e 5905(define_insn "umulqihi3"
2ae0f82c
SC
5906 [(set (match_operand:HI 0 "register_operand" "=a")
5907 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
e075ae69
RH
5908 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5909 (clobber (reg:CC 17))]
d9f32422 5910 "TARGET_QIMODE_MATH"
e075ae69 5911 "mul{b}\\t%2"
6ef67412
JH
5912 [(set_attr "type" "imul")
5913 (set_attr "length_immediate" "0")
5914 (set_attr "mode" "QI")])
886c62d1 5915
4b71cd6e 5916(define_insn "mulqihi3"
2ae0f82c
SC
5917 [(set (match_operand:HI 0 "register_operand" "=a")
5918 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
e075ae69
RH
5919 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5920 (clobber (reg:CC 17))]
d9f32422 5921 "TARGET_QIMODE_MATH"
e075ae69 5922 "imul{b}\\t%2"
6ef67412
JH
5923 [(set_attr "type" "imul")
5924 (set_attr "length_immediate" "0")
5925 (set_attr "mode" "QI")])
4b71cd6e 5926
1e07edd3
JH
5927(define_insn "umulsi3"
5928 [(set (match_operand:SI 0 "register_operand" "=a")
5929 (mult:SI (match_operand:SI 1 "register_operand" "%0")
5930 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5931 (clobber (match_operand:SI 3 "register_operand" "=d"))
5932 (clobber (reg:CC 17))]
5933 ""
5934 "mul{l}\\t%2"
5935 [(set_attr "type" "imul")
5936 (set_attr "ppro_uops" "few")
5937 (set_attr "length_immediate" "0")
5938 (set_attr "mode" "SI")])
5939
5940;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
4b71cd6e
MM
5941(define_insn "umulsidi3"
5942 [(set (match_operand:DI 0 "register_operand" "=A")
5943 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
e075ae69
RH
5944 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5945 (clobber (reg:CC 17))]
1e07edd3 5946 "!TARGET_64BIT"
e075ae69
RH
5947 "mul{l}\\t%2"
5948 [(set_attr "type" "imul")
6ef67412
JH
5949 (set_attr "ppro_uops" "few")
5950 (set_attr "length_immediate" "0")
5951 (set_attr "mode" "SI")])
4b71cd6e
MM
5952
5953(define_insn "mulsidi3"
5954 [(set (match_operand:DI 0 "register_operand" "=A")
5955 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
e075ae69
RH
5956 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5957 (clobber (reg:CC 17))]
1e07edd3 5958 "!TARGET_64BIT"
e075ae69 5959 "imul{l}\\t%2"
6ef67412
JH
5960 [(set_attr "type" "imul")
5961 (set_attr "length_immediate" "0")
5962 (set_attr "mode" "SI")])
2f2a49e8 5963
34c659e2 5964(define_insn "umulsi3_highpart"
2f2a49e8 5965 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
5966 (truncate:SI
5967 (lshiftrt:DI
5968 (mult:DI (zero_extend:DI
5969 (match_operand:SI 1 "register_operand" "%a"))
5970 (zero_extend:DI
5971 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5972 (const_int 32))))
5973 (clobber (match_scratch:SI 3 "=a"))
5974 (clobber (reg:CC 17))]
1e07edd3 5975 "!TARGET_64BIT"
e075ae69
RH
5976 "mul{l}\\t%2"
5977 [(set_attr "type" "imul")
6ef67412
JH
5978 (set_attr "ppro_uops" "few")
5979 (set_attr "length_immediate" "0")
5980 (set_attr "mode" "SI")])
2f2a49e8 5981
34c659e2 5982(define_insn "smulsi3_highpart"
2f2a49e8 5983 [(set (match_operand:SI 0 "register_operand" "=d")
e075ae69
RH
5984 (truncate:SI
5985 (lshiftrt:DI
5986 (mult:DI (sign_extend:DI
5987 (match_operand:SI 1 "register_operand" "%a"))
5988 (sign_extend:DI
5989 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5990 (const_int 32))))
5991 (clobber (match_scratch:SI 3 "=a"))
5992 (clobber (reg:CC 17))]
5993 ""
5994 "imul{l}\\t%2"
5995 [(set_attr "type" "imul")
6ef67412
JH
5996 (set_attr "ppro_uops" "few")
5997 (set_attr "mode" "SI")])
4b71cd6e 5998
886c62d1
JVA
5999;; The patterns that match these are at the end of this file.
6000
4fb21e90
JVA
6001(define_expand "mulxf3"
6002 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6003 (mult:XF (match_operand:XF 1 "register_operand" "")
6004 (match_operand:XF 2 "register_operand" "")))]
1e07edd3 6005 "TARGET_80387 && !TARGET_64BIT"
4fb21e90
JVA
6006 "")
6007
2b589241
JH
6008(define_expand "multf3"
6009 [(set (match_operand:TF 0 "register_operand" "")
6010 (mult:TF (match_operand:TF 1 "register_operand" "")
6011 (match_operand:TF 2 "register_operand" "")))]
6012 "TARGET_80387"
6013 "")
6014
886c62d1
JVA
6015(define_expand "muldf3"
6016 [(set (match_operand:DF 0 "register_operand" "")
2ae0f82c 6017 (mult:DF (match_operand:DF 1 "register_operand" "")
886c62d1 6018 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 6019 "TARGET_80387 || TARGET_SSE2"
886c62d1
JVA
6020 "")
6021
6022(define_expand "mulsf3"
6023 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 6024 (mult:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6025 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 6026 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
6027 "")
6028\f
e075ae69 6029;; Divide instructions
886c62d1
JVA
6030
6031(define_insn "divqi3"
2ae0f82c
SC
6032 [(set (match_operand:QI 0 "register_operand" "=a")
6033 (div:QI (match_operand:HI 1 "register_operand" "0")
e075ae69
RH
6034 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6035 (clobber (reg:CC 17))]
d9f32422 6036 "TARGET_QIMODE_MATH"
e075ae69
RH
6037 "idiv{b}\\t%2"
6038 [(set_attr "type" "idiv")
6ef67412 6039 (set_attr "mode" "QI")
e075ae69 6040 (set_attr "ppro_uops" "few")])
886c62d1
JVA
6041
6042(define_insn "udivqi3"
2ae0f82c
SC
6043 [(set (match_operand:QI 0 "register_operand" "=a")
6044 (udiv:QI (match_operand:HI 1 "register_operand" "0")
e075ae69
RH
6045 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6046 (clobber (reg:CC 17))]
d9f32422 6047 "TARGET_QIMODE_MATH"
e075ae69
RH
6048 "div{b}\\t%2"
6049 [(set_attr "type" "idiv")
6ef67412 6050 (set_attr "mode" "QI")
e075ae69 6051 (set_attr "ppro_uops" "few")])
886c62d1
JVA
6052
6053;; The patterns that match these are at the end of this file.
6054
4fb21e90
JVA
6055(define_expand "divxf3"
6056 [(set (match_operand:XF 0 "register_operand" "")
2ae0f82c
SC
6057 (div:XF (match_operand:XF 1 "register_operand" "")
6058 (match_operand:XF 2 "register_operand" "")))]
1e07edd3 6059 "TARGET_80387 && !TARGET_64BIT"
886c62d1
JVA
6060 "")
6061
2b589241
JH
6062(define_expand "divtf3"
6063 [(set (match_operand:TF 0 "register_operand" "")
6064 (div:TF (match_operand:TF 1 "register_operand" "")
6065 (match_operand:TF 2 "register_operand" "")))]
6066 "TARGET_80387"
6067 "")
6068
a78cb986
SC
6069(define_expand "divdf3"
6070 [(set (match_operand:DF 0 "register_operand" "")
6071 (div:DF (match_operand:DF 1 "register_operand" "")
6072 (match_operand:DF 2 "nonimmediate_operand" "")))]
1deaa899 6073 "TARGET_80387 || TARGET_SSE2"
a78cb986
SC
6074 "")
6075
886c62d1
JVA
6076(define_expand "divsf3"
6077 [(set (match_operand:SF 0 "register_operand" "")
2ae0f82c 6078 (div:SF (match_operand:SF 1 "register_operand" "")
886c62d1 6079 (match_operand:SF 2 "nonimmediate_operand" "")))]
1deaa899 6080 "TARGET_80387 || TARGET_SSE"
886c62d1
JVA
6081 "")
6082\f
6083;; Remainder instructions.
40745eec
JH
6084(define_expand "divmodsi4"
6085 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6086 (div:SI (match_operand:SI 1 "register_operand" "")
6087 (match_operand:SI 2 "nonimmediate_operand" "")))
6088 (set (match_operand:SI 3 "register_operand" "")
6089 (mod:SI (match_dup 1) (match_dup 2)))
6090 (clobber (reg:CC 17))])]
6091 ""
6092 "")
6093
6094;; Allow to come the parameter in eax or edx to avoid extra moves.
6095;; Penalize eax case sligthly because it results in worse scheduling
6096;; of code.
6097(define_insn "*divmodsi4_nocltd"
6098 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
6099 (div:SI (match_operand:SI 2 "register_operand" "1,0")
6100 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
6101 (set (match_operand:SI 1 "register_operand" "=&d,&d")
6102 (mod:SI (match_dup 2) (match_dup 3)))
6103 (clobber (reg:CC 17))]
6104 "!optimize_size && !TARGET_USE_CLTD"
6105 "#"
6106 [(set_attr "type" "multi")])
886c62d1 6107
40745eec 6108(define_insn "*divmodsi4_cltd"
2bb7a0f5 6109 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec
JH
6110 (div:SI (match_operand:SI 2 "register_operand" "a")
6111 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6112 (set (match_operand:SI 1 "register_operand" "=&d")
6113 (mod:SI (match_dup 2) (match_dup 3)))
e075ae69 6114 (clobber (reg:CC 17))]
40745eec
JH
6115 "optimize_size || TARGET_USE_CLTD"
6116 "#"
e075ae69
RH
6117 [(set_attr "type" "multi")])
6118
6343a50e 6119(define_insn "*divmodsi_noext"
e075ae69 6120 [(set (match_operand:SI 0 "register_operand" "=a")
40745eec 6121 (div:SI (match_operand:SI 1 "register_operand" "0")
e075ae69
RH
6122 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6123 (set (match_operand:SI 3 "register_operand" "=d")
6124 (mod:SI (match_dup 1) (match_dup 2)))
40745eec 6125 (use (match_operand:SI 4 "register_operand" "3"))
e075ae69
RH
6126 (clobber (reg:CC 17))]
6127 ""
6128 "idiv{l}\\t%2"
6129 [(set_attr "type" "idiv")
6ef67412 6130 (set_attr "mode" "SI")
e075ae69
RH
6131 (set_attr "ppro_uops" "few")])
6132
6133(define_split
6134 [(set (match_operand:SI 0 "register_operand" "")
6135 (div:SI (match_operand:SI 1 "register_operand" "")
6136 (match_operand:SI 2 "nonimmediate_operand" "")))
6137 (set (match_operand:SI 3 "register_operand" "")
6138 (mod:SI (match_dup 1) (match_dup 2)))
6139 (clobber (reg:CC 17))]
6140 "reload_completed"
6141 [(parallel [(set (match_dup 3)
6142 (ashiftrt:SI (match_dup 4) (const_int 31)))
6143 (clobber (reg:CC 17))])
6144 (parallel [(set (match_dup 0)
40745eec 6145 (div:SI (reg:SI 0) (match_dup 2)))
e075ae69 6146 (set (match_dup 3)
40745eec 6147 (mod:SI (reg:SI 0) (match_dup 2)))
e075ae69
RH
6148 (use (match_dup 3))
6149 (clobber (reg:CC 17))])]
6150 "
886c62d1 6151{
e075ae69 6152 /* Avoid use of cltd in favour of a mov+shift. */
40745eec 6153 if (!TARGET_USE_CLTD && !optimize_size)
e075ae69 6154 {
40745eec
JH
6155 if (true_regnum (operands[1]))
6156 emit_move_insn (operands[0], operands[1]);
6157 else
6158 emit_move_insn (operands[3], operands[1]);
e075ae69
RH
6159 operands[4] = operands[3];
6160 }
6161 else
40745eec
JH
6162 {
6163 if (true_regnum (operands[1]))
6164 abort();
6165 operands[4] = operands[1];
6166 }
e075ae69 6167}")
e075ae69 6168;; %%% Split me.
886c62d1 6169(define_insn "divmodhi4"
2bb7a0f5
RS
6170 [(set (match_operand:HI 0 "register_operand" "=a")
6171 (div:HI (match_operand:HI 1 "register_operand" "0")
2ae0f82c 6172 (match_operand:HI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 6173 (set (match_operand:HI 3 "register_operand" "=&d")
e075ae69
RH
6174 (mod:HI (match_dup 1) (match_dup 2)))
6175 (clobber (reg:CC 17))]
d9f32422 6176 "TARGET_HIMODE_MATH"
e075ae69 6177 "cwtd\;idiv{w}\\t%2"
6ef67412
JH
6178 [(set_attr "type" "multi")
6179 (set_attr "length_immediate" "0")
6180 (set_attr "mode" "SI")])
886c62d1 6181
886c62d1 6182(define_insn "udivmodsi4"
2bb7a0f5
RS
6183 [(set (match_operand:SI 0 "register_operand" "=a")
6184 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 6185 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 6186 (set (match_operand:SI 3 "register_operand" "=&d")
e075ae69
RH
6187 (umod:SI (match_dup 1) (match_dup 2)))
6188 (clobber (reg:CC 17))]
886c62d1 6189 ""
e075ae69 6190 "xor{l}\\t%3, %3\;div{l}\\t%2"
6ef67412
JH
6191 [(set_attr "type" "multi")
6192 (set_attr "length_immediate" "0")
6193 (set_attr "mode" "SI")])
886c62d1 6194
6343a50e 6195(define_insn "*udivmodsi4_noext"
2bb7a0f5 6196 [(set (match_operand:SI 0 "register_operand" "=a")
e075ae69 6197 (udiv:SI (match_operand:SI 1 "register_operand" "0")
2ae0f82c 6198 (match_operand:SI 2 "nonimmediate_operand" "rm")))
2bb7a0f5 6199 (set (match_operand:SI 3 "register_operand" "=d")
e075ae69
RH
6200 (umod:SI (match_dup 1) (match_dup 2)))
6201 (use (match_dup 3))
6202 (clobber (reg:CC 17))]
886c62d1 6203 ""
e075ae69
RH
6204 "div{l}\\t%2"
6205 [(set_attr "type" "idiv")
6ef67412
JH
6206 (set_attr "ppro_uops" "few")
6207 (set_attr "mode" "SI")])
886c62d1 6208
e075ae69
RH
6209(define_split
6210 [(set (match_operand:SI 0 "register_operand" "")
6211 (udiv:SI (match_operand:SI 1 "register_operand" "")
6212 (match_operand:SI 2 "nonimmediate_operand" "")))
6213 (set (match_operand:SI 3 "register_operand" "")
6214 (umod:SI (match_dup 1) (match_dup 2)))
6215 (clobber (reg:CC 17))]
6216 "reload_completed"
591702de 6217 [(set (match_dup 3) (const_int 0))
e075ae69
RH
6218 (parallel [(set (match_dup 0)
6219 (udiv:SI (match_dup 1) (match_dup 2)))
6220 (set (match_dup 3)
6221 (umod:SI (match_dup 1) (match_dup 2)))
6222 (use (match_dup 3))
6223 (clobber (reg:CC 17))])]
6224 "")
886c62d1 6225
e075ae69 6226(define_expand "udivmodhi4"
591702de 6227 [(set (match_dup 4) (const_int 0))
40745eec
JH
6228 (parallel [(set (match_operand:HI 0 "register_operand" "")
6229 (udiv:HI (match_operand:HI 1 "register_operand" "")
6230 (match_operand:HI 2 "nonimmediate_operand" "")))
6231 (set (match_operand:HI 3 "register_operand" "")
e075ae69
RH
6232 (umod:HI (match_dup 1) (match_dup 2)))
6233 (use (match_dup 4))
6234 (clobber (reg:CC 17))])]
d9f32422 6235 "TARGET_HIMODE_MATH"
e075ae69 6236 "operands[4] = gen_reg_rtx (HImode);")
886c62d1 6237
6343a50e 6238(define_insn "*udivmodhi_noext"
e075ae69
RH
6239 [(set (match_operand:HI 0 "register_operand" "=a")
6240 (udiv:HI (match_operand:HI 1 "register_operand" "0")
6241 (match_operand:HI 2 "nonimmediate_operand" "rm")))
6242 (set (match_operand:HI 3 "register_operand" "=d")
6243 (umod:HI (match_dup 1) (match_dup 2)))
6244 (use (match_operand:HI 4 "register_operand" "3"))
6245 (clobber (reg:CC 17))]
6246 ""
6247 "div{w}\\t%2"
6248 [(set_attr "type" "idiv")
6ef67412 6249 (set_attr "mode" "HI")
e075ae69
RH
6250 (set_attr "ppro_uops" "few")])
6251
6252;; We can not use div/idiv for double division, because it causes
6253;; "division by zero" on the overflow and that's not what we expect
6254;; from truncate. Because true (non truncating) double division is
6255;; never generated, we can't create this insn anyway.
6256;
6257;(define_insn ""
6258; [(set (match_operand:SI 0 "register_operand" "=a")
6259; (truncate:SI
6260; (udiv:DI (match_operand:DI 1 "register_operand" "A")
6261; (zero_extend:DI
6262; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
6263; (set (match_operand:SI 3 "register_operand" "=d")
6264; (truncate:SI
6265; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
6266; (clobber (reg:CC 17))]
6267; ""
6268; "div{l}\\t{%2, %0|%0, %2}"
6269; [(set_attr "type" "idiv")
6270; (set_attr "ppro_uops" "few")])
886c62d1 6271\f
e075ae69
RH
6272;;- Logical AND instructions
6273
6274;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
6275;; Note that this excludes ah.
6276
9076b9c1
JH
6277
6278(define_insn "testsi_1"
6279 [(set (reg 17)
6280 (compare
16189740
RH
6281 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
6282 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
6283 (const_int 0)))]
9076b9c1 6284 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 6285 "test{l}\\t{%1, %0|%0, %1}"
6ef67412
JH
6286 [(set_attr "type" "test")
6287 (set_attr "modrm" "0,1,1")
6288 (set_attr "mode" "SI")
e075ae69
RH
6289 (set_attr "pent_pair" "uv,np,uv")])
6290
9076b9c1 6291(define_expand "testsi_ccno_1"
e075ae69 6292 [(set (reg:CCNO 17)
16189740 6293 (compare:CCNO
9076b9c1
JH
6294 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
6295 (match_operand:SI 1 "nonmemory_operand" ""))
16189740 6296 (const_int 0)))]
a1cbdd7f 6297 ""
9076b9c1 6298 "")
16189740
RH
6299
6300(define_insn "*testhi_1"
6301 [(set (reg 17)
6302 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
6303 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
6304 (const_int 0)))]
6305 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 6306 "test{w}\\t{%1, %0|%0, %1}"
6ef67412
JH
6307 [(set_attr "type" "test")
6308 (set_attr "modrm" "0,1,1")
6309 (set_attr "mode" "HI")
e075ae69
RH
6310 (set_attr "pent_pair" "uv,np,uv")])
6311
9076b9c1 6312(define_expand "testqi_ccz_1"
16189740 6313 [(set (reg:CCZ 17)
9076b9c1
JH
6314 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
6315 (match_operand:QI 1 "nonmemory_operand" ""))
6316 (const_int 0)))]
16189740 6317 ""
9076b9c1 6318 "")
16189740 6319
9076b9c1
JH
6320(define_insn "*testqi_1"
6321 [(set (reg 17)
6322 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
6323 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
6324 (const_int 0)))]
6325 "ix86_match_ccmode (insn, CCNOmode)"
adc88131
JJ
6326 "*
6327{
6328 if (which_alternative == 3)
6329 {
6330 if (GET_CODE (operands[1]) == CONST_INT
6331 && (INTVAL (operands[1]) & 0xffffff00))
6332 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
6333 return \"test{l}\\t{%1, %k0|%k0, %1}\";
6334 }
6335 return \"test{b}\\t{%1, %0|%0, %1}\";
6336}"
6ef67412
JH
6337 [(set_attr "type" "test")
6338 (set_attr "modrm" "0,1,1,1")
6339 (set_attr "mode" "QI,QI,QI,SI")
6340 (set_attr "pent_pair" "uv,np,uv,np")])
e075ae69 6341
9076b9c1
JH
6342(define_expand "testqi_ext_ccno_0"
6343 [(set (reg:CCNO 17)
6344 (compare:CCNO
16189740
RH
6345 (and:SI
6346 (zero_extract:SI
9076b9c1 6347 (match_operand 0 "ext_register_operand" "")
16189740
RH
6348 (const_int 8)
6349 (const_int 8))
9076b9c1 6350 (match_operand 1 "const_int_operand" ""))
16189740 6351 (const_int 0)))]
9076b9c1
JH
6352 ""
6353 "")
e075ae69 6354
9076b9c1
JH
6355(define_insn "*testqi_ext_0"
6356 [(set (reg 17)
6357 (compare
e075ae69
RH
6358 (and:SI
6359 (zero_extract:SI
d2836273 6360 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
6361 (const_int 8)
6362 (const_int 8))
6363 (match_operand 1 "const_int_operand" "n"))
6364 (const_int 0)))]
9076b9c1
JH
6365 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
6366 && ix86_match_ccmode (insn, CCNOmode)"
e075ae69 6367 "test{b}\\t{%1, %h0|%h0, %1}"
6ef67412
JH
6368 [(set_attr "type" "test")
6369 (set_attr "mode" "QI")
6370 (set_attr "length_immediate" "1")
e075ae69
RH
6371 (set_attr "pent_pair" "np")])
6372
6373(define_insn "*testqi_ext_1"
16189740
RH
6374 [(set (reg 17)
6375 (compare
e075ae69
RH
6376 (and:SI
6377 (zero_extract:SI
d2836273 6378 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
6379 (const_int 8)
6380 (const_int 8))
6381 (zero_extend:SI
d2836273 6382 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
e075ae69 6383 (const_int 0)))]
d2836273
JH
6384 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
6385 "test{b}\\t{%1, %h0|%h0, %1}"
6386 [(set_attr "type" "test")
6387 (set_attr "mode" "QI")])
6388
6389(define_insn "*testqi_ext_1_rex64"
6390 [(set (reg 17)
6391 (compare
6392 (and:SI
6393 (zero_extract:SI
6394 (match_operand 0 "ext_register_operand" "Q")
6395 (const_int 8)
6396 (const_int 8))
6397 (zero_extend:SI
6398 (match_operand:QI 1 "ext_register_operand" "Q")))
6399 (const_int 0)))]
6400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
e075ae69 6401 "test{b}\\t{%1, %h0|%h0, %1}"
6ef67412
JH
6402 [(set_attr "type" "test")
6403 (set_attr "mode" "QI")])
e075ae69
RH
6404
6405(define_insn "*testqi_ext_2"
16189740
RH
6406 [(set (reg 17)
6407 (compare
e075ae69
RH
6408 (and:SI
6409 (zero_extract:SI
d2836273 6410 (match_operand 0 "ext_register_operand" "Q")
e075ae69
RH
6411 (const_int 8)
6412 (const_int 8))
6413 (zero_extract:SI
d2836273 6414 (match_operand 1 "ext_register_operand" "Q")
e075ae69
RH
6415 (const_int 8)
6416 (const_int 8)))
6417 (const_int 0)))]
16189740 6418 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69 6419 "test{b}\\t{%h1, %h0|%h0, %h1}"
6ef67412
JH
6420 [(set_attr "type" "test")
6421 (set_attr "mode" "QI")])
e075ae69
RH
6422
6423;; Combine likes to form bit extractions for some tests. Humor it.
6343a50e 6424(define_insn "*testqi_ext_3"
16189740
RH
6425 [(set (reg 17)
6426 (compare (zero_extract:SI
6427 (match_operand 0 "nonimmediate_operand" "rm")
6428 (match_operand:SI 1 "const_int_operand" "")
6429 (match_operand:SI 2 "const_int_operand" ""))
6430 (const_int 0)))]
6431 "ix86_match_ccmode (insn, CCNOmode)
6432 && (GET_MODE (operands[0]) == SImode
6433 || GET_MODE (operands[0]) == HImode
6434 || GET_MODE (operands[0]) == QImode)"
e075ae69 6435 "#")
4fce8e83 6436
e075ae69 6437(define_split
16189740
RH
6438 [(set (reg 17)
6439 (compare (zero_extract:SI
6440 (match_operand 0 "nonimmediate_operand" "rm")
6441 (match_operand:SI 1 "const_int_operand" "")
6442 (match_operand:SI 2 "const_int_operand" ""))
6443 (const_int 0)))]
6444 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
6445 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
6446 "
6447{
6448 HOST_WIDE_INT len = INTVAL (operands[1]);
6449 HOST_WIDE_INT pos = INTVAL (operands[2]);
6450 HOST_WIDE_INT mask;
6451 enum machine_mode mode;
886c62d1 6452
e075ae69
RH
6453 mode = GET_MODE (operands[0]);
6454 if (GET_CODE (operands[0]) == MEM)
5bc7cd8e 6455 {
e075ae69
RH
6456 /* ??? Combine likes to put non-volatile mem extractions in QImode
6457 no matter the size of the test. So find a mode that works. */
6458 if (! MEM_VOLATILE_P (operands[0]))
6459 {
6460 mode = smallest_mode_for_size (pos + len, MODE_INT);
6461 operands[0] = change_address (operands[0], mode, NULL_RTX);
6462 }
5bc7cd8e 6463 }
e075ae69 6464 else if (mode == HImode && pos + len <= 8)
5bc7cd8e 6465 {
e075ae69
RH
6466 /* Small HImode tests can be converted to QImode. */
6467 mode = QImode;
6468 operands[0] = gen_lowpart (QImode, operands[0]);
5bc7cd8e
SC
6469 }
6470
e075ae69
RH
6471 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
6472 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
886c62d1 6473
e075ae69
RH
6474 operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
6475}")
886c62d1 6476
e075ae69
RH
6477;; %%% This used to optimize known byte-wide and operations to memory,
6478;; and sometimes to QImode registers. If this is considered useful,
6479;; it should be done with splitters.
6480
6481(define_expand "andsi3"
6482 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6483 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
6484 (match_operand:SI 2 "general_operand" "")))
6485 (clobber (reg:CC 17))]
6486 ""
6487 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
6488
6489(define_insn "*andsi_1"
6490 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
6491 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
6492 (match_operand:SI 2 "general_operand" "ri,rm,L")))
6493 (clobber (reg:CC 17))]
6494 "ix86_binary_operator_ok (AND, SImode, operands)"
886c62d1
JVA
6495 "*
6496{
e075ae69 6497 switch (get_attr_type (insn))
886c62d1 6498 {
e075ae69
RH
6499 case TYPE_IMOVX:
6500 {
6501 enum machine_mode mode;
5bc7cd8e 6502
e075ae69
RH
6503 if (GET_CODE (operands[2]) != CONST_INT)
6504 abort ();
6505 if (INTVAL (operands[2]) == 0xff)
6506 mode = QImode;
6507 else if (INTVAL (operands[2]) == 0xffff)
6508 mode = HImode;
6509 else
6510 abort ();
6511
6512 operands[1] = gen_lowpart (mode, operands[1]);
6513 if (mode == QImode)
6514 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
6515 else
6516 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
6517 }
5bc7cd8e 6518
e075ae69
RH
6519 default:
6520 if (! rtx_equal_p (operands[0], operands[1]))
6521 abort ();
e075ae69 6522 return \"and{l}\\t{%2, %0|%0, %2}\";
886c62d1 6523 }
a269a03c 6524}"
6ef67412
JH
6525 [(set_attr "type" "alu,alu,imovx")
6526 (set_attr "length_immediate" "*,*,0")
6527 (set_attr "mode" "SI")])
6528
6529(define_split
6530 [(set (match_operand:SI 0 "register_operand" "")
6531 (and:SI (match_dup 0)
6532 (const_int -65536)))
6533 (clobber (reg:CC 17))]
6534 "optimize_size"
6535 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6536 "operands[1] = gen_lowpart (HImode, operands[0]);")
6537
6538(define_split
5e1a2fc7
JJ
6539 [(set (match_operand 0 "q_regs_operand" "")
6540 (and (match_dup 0)
6ef67412
JH
6541 (const_int -256)))
6542 (clobber (reg:CC 17))]
6543 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6544 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6545 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6546 "operands[1] = gen_lowpart (QImode, operands[0]);")
6547
6548(define_split
5e1a2fc7 6549 [(set (match_operand 0 "q_regs_operand" "")
6ef67412
JH
6550 (and (match_dup 0)
6551 (const_int -65281)))
6552 (clobber (reg:CC 17))]
6553 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6554 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6555 [(parallel [(set (zero_extract:SI (match_dup 0)
6556 (const_int 8)
6557 (const_int 8))
6558 (xor:SI
6559 (zero_extract:SI (match_dup 0)
6560 (const_int 8)
6561 (const_int 8))
6562 (zero_extract:SI (match_dup 0)
6563 (const_int 8)
6564 (const_int 8))))
6565 (clobber (reg:CC 17))])]
6566 "operands[0] = gen_lowpart (SImode, operands[0]);")
e075ae69
RH
6567
6568(define_insn "*andsi_2"
16189740
RH
6569 [(set (reg 17)
6570 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6571 (match_operand:SI 2 "general_operand" "rim,ri"))
6572 (const_int 0)))
e075ae69
RH
6573 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6574 (and:SI (match_dup 1) (match_dup 2)))]
16189740
RH
6575 "ix86_match_ccmode (insn, CCNOmode)
6576 && ix86_binary_operator_ok (AND, SImode, operands)"
e075ae69 6577 "and{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
6578 [(set_attr "type" "alu")
6579 (set_attr "mode" "SI")])
e075ae69
RH
6580
6581(define_expand "andhi3"
6582 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6583 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
6584 (match_operand:HI 2 "general_operand" "")))
6585 (clobber (reg:CC 17))]
d9f32422 6586 "TARGET_HIMODE_MATH"
e075ae69
RH
6587 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
6588
6589(define_insn "*andhi_1"
6590 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6591 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
6592 (match_operand:HI 2 "general_operand" "ri,rm,L")))
6593 (clobber (reg:CC 17))]
6594 "ix86_binary_operator_ok (AND, HImode, operands)"
886c62d1
JVA
6595 "*
6596{
e075ae69 6597 switch (get_attr_type (insn))
886c62d1 6598 {
e075ae69
RH
6599 case TYPE_IMOVX:
6600 if (GET_CODE (operands[2]) != CONST_INT)
6601 abort ();
6602 if (INTVAL (operands[2]) == 0xff)
6603 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
6604 abort ();
886c62d1 6605
e075ae69
RH
6606 default:
6607 if (! rtx_equal_p (operands[0], operands[1]))
6608 abort ();
886c62d1 6609
e075ae69 6610 return \"and{w}\\t{%2, %0|%0, %2}\";
5bc7cd8e 6611 }
e075ae69 6612}"
6ef67412
JH
6613 [(set_attr "type" "alu,alu,imovx")
6614 (set_attr "length_immediate" "*,*,0")
6615 (set_attr "mode" "HI,HI,SI")])
5bc7cd8e 6616
e075ae69 6617(define_insn "*andhi_2"
16189740
RH
6618 [(set (reg 17)
6619 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6620 (match_operand:HI 2 "general_operand" "rim,ri"))
6621 (const_int 0)))
e075ae69
RH
6622 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6623 (and:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6624 "ix86_match_ccmode (insn, CCNOmode)
6625 && ix86_binary_operator_ok (AND, HImode, operands)"
e075ae69 6626 "and{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
6627 [(set_attr "type" "alu")
6628 (set_attr "mode" "HI")])
5bc7cd8e 6629
e075ae69
RH
6630(define_expand "andqi3"
6631 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6632 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
6633 (match_operand:QI 2 "general_operand" "")))
6634 (clobber (reg:CC 17))]
d9f32422 6635 "TARGET_QIMODE_MATH"
e075ae69
RH
6636 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
6637
6638;; %%% Potential partial reg stall on alternative 2. What to do?
6639(define_insn "*andqi_1"
7c6b971d 6640 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
e075ae69 6641 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 6642 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
e075ae69
RH
6643 (clobber (reg:CC 17))]
6644 "ix86_binary_operator_ok (AND, QImode, operands)"
6645 "@
6646 and{b}\\t{%2, %0|%0, %2}
6647 and{b}\\t{%2, %0|%0, %2}
6648 and{l}\\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
6649 [(set_attr "type" "alu")
6650 (set_attr "mode" "QI,QI,SI")])
e075ae69 6651
a1b8572c
JH
6652(define_insn "*andqi_1_slp"
6653 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6654 (and:QI (match_dup 0)
6655 (match_operand:QI 1 "general_operand" "qi,qmi")))
6656 (clobber (reg:CC 17))]
6657 ""
6658 "and{b}\\t{%1, %0|%0, %1}"
6659 [(set_attr "type" "alu1")
6660 (set_attr "mode" "QI")])
6661
e075ae69 6662(define_insn "*andqi_2"
16189740
RH
6663 [(set (reg 17)
6664 (compare (and:QI
6665 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6666 (match_operand:QI 2 "general_operand" "qim,qi,i"))
6667 (const_int 0)))
e075ae69
RH
6668 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
6669 (and:QI (match_dup 1) (match_dup 2)))]
16189740
RH
6670 "ix86_match_ccmode (insn, CCNOmode)
6671 && ix86_binary_operator_ok (AND, QImode, operands)"
adc88131
JJ
6672 "*
6673{
6674 if (which_alternative == 2)
6675 {
6676 if (GET_CODE (operands[2]) == CONST_INT
6677 && (INTVAL (operands[2]) & 0xffffff00))
6678 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
6679 return \"and{l}\\t{%2, %k0|%k0, %2}\";
6680 }
6681 return \"and{b}\\t{%2, %0|%0, %2}\";
6682}"
6ef67412
JH
6683 [(set_attr "type" "alu")
6684 (set_attr "mode" "QI,QI,SI")])
e075ae69 6685
a1b8572c
JH
6686(define_insn "*andqi_2_slp"
6687 [(set (reg 17)
6688 (compare (and:QI
6689 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6690 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
6691 (const_int 0)))
6692 (set (strict_low_part (match_dup 0))
6693 (and:QI (match_dup 0) (match_dup 1)))]
6694 "ix86_match_ccmode (insn, CCNOmode)"
6695 "and{b}\\t{%1, %0|%0, %1}"
6696 [(set_attr "type" "alu1")
6697 (set_attr "mode" "QI")])
6698
e075ae69
RH
6699;; ??? A bug in recog prevents it from recognizing a const_int as an
6700;; operand to zero_extend in andqi_ext_1. It was checking explicitly
6701;; for a QImode operand, which of course failed.
6702
6703(define_insn "andqi_ext_0"
d2836273 6704 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6705 (const_int 8)
6706 (const_int 8))
6707 (and:SI
6708 (zero_extract:SI
6709 (match_operand 1 "ext_register_operand" "0")
6710 (const_int 8)
6711 (const_int 8))
6712 (match_operand 2 "const_int_operand" "n")))
6713 (clobber (reg:CC 17))]
6714 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6715 "and{b}\\t{%2, %h0|%h0, %2}"
6ef67412
JH
6716 [(set_attr "type" "alu")
6717 (set_attr "length_immediate" "1")
6718 (set_attr "mode" "QI")])
e075ae69
RH
6719
6720;; Generated by peephole translating test to and. This shows up
6721;; often in fp comparisons.
6722
6723(define_insn "*andqi_ext_0_cc"
16189740
RH
6724 [(set (reg 17)
6725 (compare
e075ae69
RH
6726 (and:SI
6727 (zero_extract:SI
084e679a 6728 (match_operand 1 "ext_register_operand" "0")
d2836273 6729 (const_int 8)
e075ae69
RH
6730 (const_int 8))
6731 (match_operand 2 "const_int_operand" "n"))
6732 (const_int 0)))
d2836273 6733 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6734 (const_int 8)
6735 (const_int 8))
6736 (and:SI
6737 (zero_extract:SI
6738 (match_dup 1)
6739 (const_int 8)
6740 (const_int 8))
6741 (match_dup 2)))]
16189740
RH
6742 "ix86_match_ccmode (insn, CCNOmode)
6743 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
e075ae69 6744 "and{b}\\t{%2, %h0|%h0, %2}"
6ef67412
JH
6745 [(set_attr "type" "alu")
6746 (set_attr "length_immediate" "1")
6747 (set_attr "mode" "QI")])
e075ae69
RH
6748
6749(define_insn "*andqi_ext_1"
d2836273 6750 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6751 (const_int 8)
6752 (const_int 8))
6753 (and:SI
6754 (zero_extract:SI
6755 (match_operand 1 "ext_register_operand" "0")
6756 (const_int 8)
6757 (const_int 8))
6758 (zero_extend:SI
d2836273 6759 (match_operand:QI 2 "general_operand" "Qm"))))
e075ae69 6760 (clobber (reg:CC 17))]
d2836273
JH
6761 "!TARGET_64BIT"
6762 "and{b}\\t{%2, %h0|%h0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "length_immediate" "0")
6765 (set_attr "mode" "QI")])
6766
6767(define_insn "*andqi_ext_1_rex64"
6768 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6769 (const_int 8)
6770 (const_int 8))
6771 (and:SI
6772 (zero_extract:SI
6773 (match_operand 1 "ext_register_operand" "0")
6774 (const_int 8)
6775 (const_int 8))
6776 (zero_extend:SI
6777 (match_operand:QI 2 "ext_register_operand" "Q"))))
6778 (clobber (reg:CC 17))]
6779 "TARGET_64BIT"
e075ae69 6780 "and{b}\\t{%2, %h0|%h0, %2}"
6ef67412
JH
6781 [(set_attr "type" "alu")
6782 (set_attr "length_immediate" "0")
6783 (set_attr "mode" "QI")])
e075ae69
RH
6784
6785(define_insn "*andqi_ext_2"
d2836273 6786 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
e075ae69
RH
6787 (const_int 8)
6788 (const_int 8))
6789 (and:SI
6790 (zero_extract:SI
6791 (match_operand 1 "ext_register_operand" "%0")
6792 (const_int 8)
6793 (const_int 8))
6794 (zero_extract:SI
d2836273 6795 (match_operand 2 "ext_register_operand" "Q")
e075ae69
RH
6796 (const_int 8)
6797 (const_int 8))))
6798 (clobber (reg:CC 17))]
6799 ""
6800 "and{b}\\t{%h2, %h0|%h0, %h2}"
6ef67412
JH
6801 [(set_attr "type" "alu")
6802 (set_attr "length_immediate" "0")
6803 (set_attr "mode" "QI")])
886c62d1 6804\f
e075ae69 6805;; Logical inclusive OR instructions
57dbca5e 6806
e075ae69
RH
6807;; %%% This used to optimize known byte-wide and operations to memory.
6808;; If this is considered useful, it should be done with splitters.
6809
6810(define_expand "iorsi3"
6811 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6812 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
6813 (match_operand:SI 2 "general_operand" "")))
6814 (clobber (reg:CC 17))]
57dbca5e 6815 ""
e075ae69
RH
6816 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
6817
6818(define_insn "*iorsi_1"
6819 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6820 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6821 (match_operand:SI 2 "general_operand" "ri,rmi")))
6822 (clobber (reg:CC 17))]
6823 "ix86_binary_operator_ok (IOR, SImode, operands)"
6824 "or{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "SI")])
e075ae69
RH
6827
6828(define_insn "*iorsi_2"
16189740
RH
6829 [(set (reg 17)
6830 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6831 (match_operand:SI 2 "general_operand" "rim,ri"))
6832 (const_int 0)))
e075ae69
RH
6833 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6834 (ior:SI (match_dup 1) (match_dup 2)))]
16189740
RH
6835 "ix86_match_ccmode (insn, CCNOmode)
6836 && ix86_binary_operator_ok (IOR, SImode, operands)"
e075ae69 6837 "or{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "SI")])
e075ae69 6840
d90ffc8d
JH
6841(define_insn "*iorsi_3"
6842 [(set (reg 17)
6843 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6844 (match_operand:SI 2 "general_operand" "rim"))
6845 (const_int 0)))
6846 (clobber (match_scratch:SI 0 "=r"))]
6847 "ix86_match_ccmode (insn, CCNOmode)
6848 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6849 "or{l}\\t{%2, %0|%0, %2}"
6850 [(set_attr "type" "alu")
6851 (set_attr "mode" "SI")])
6852
e075ae69
RH
6853(define_expand "iorhi3"
6854 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6855 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
6856 (match_operand:HI 2 "general_operand" "")))
6857 (clobber (reg:CC 17))]
d9f32422 6858 "TARGET_HIMODE_MATH"
e075ae69
RH
6859 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
6860
6861(define_insn "*iorhi_1"
6862 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6863 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6864 (match_operand:HI 2 "general_operand" "rmi,ri")))
6865 (clobber (reg:CC 17))]
6866 "ix86_binary_operator_ok (IOR, HImode, operands)"
6867 "or{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
6868 [(set_attr "type" "alu")
6869 (set_attr "mode" "HI")])
e075ae69 6870
e075ae69 6871(define_insn "*iorhi_2"
16189740
RH
6872 [(set (reg 17)
6873 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6874 (match_operand:HI 2 "general_operand" "rim,ri"))
6875 (const_int 0)))
e075ae69
RH
6876 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6877 (ior:HI (match_dup 1) (match_dup 2)))]
16189740
RH
6878 "ix86_match_ccmode (insn, CCNOmode)
6879 && ix86_binary_operator_ok (IOR, HImode, operands)"
e075ae69 6880 "or{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
6881 [(set_attr "type" "alu")
6882 (set_attr "mode" "HI")])
e075ae69 6883
d90ffc8d
JH
6884(define_insn "*iorhi_3"
6885 [(set (reg 17)
6886 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6887 (match_operand:HI 2 "general_operand" "rim"))
6888 (const_int 0)))
6889 (clobber (match_scratch:HI 0 "=r"))]
6890 "ix86_match_ccmode (insn, CCNOmode)
6891 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6892 "or{w}\\t{%2, %0|%0, %2}"
6893 [(set_attr "type" "alu")
6894 (set_attr "mode" "HI")])
6895
e075ae69
RH
6896(define_expand "iorqi3"
6897 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6898 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
6899 (match_operand:QI 2 "general_operand" "")))
6900 (clobber (reg:CC 17))]
d9f32422 6901 "TARGET_QIMODE_MATH"
e075ae69
RH
6902 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
6903
6904;; %%% Potential partial reg stall on alternative 2. What to do?
6905(define_insn "*iorqi_1"
7c6b971d 6906 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 6907 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 6908 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
e075ae69
RH
6909 (clobber (reg:CC 17))]
6910 "ix86_binary_operator_ok (IOR, QImode, operands)"
6911 "@
6912 or{b}\\t{%2, %0|%0, %2}
6913 or{b}\\t{%2, %0|%0, %2}
6914 or{l}\\t{%k2, %k0|%k0, %k2}"
6ef67412 6915 [(set_attr "type" "alu")
a1b8572c
JH
6916 (set_attr "mode" "QI,QI,SI")])
6917
6918(define_insn "*iorqi_1_slp"
6919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
6920 (ior:QI (match_dup 0)
6921 (match_operand:QI 1 "general_operand" "qmi,qi")))
6922 (clobber (reg:CC 17))]
6923 ""
6924 "or{b}\\t{%1, %0|%0, %1}"
6925 [(set_attr "type" "alu1")
6ef67412 6926 (set_attr "mode" "QI")])
e075ae69
RH
6927
6928(define_insn "*iorqi_2"
16189740
RH
6929 [(set (reg 17)
6930 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6931 (match_operand:QI 2 "general_operand" "qim,qi"))
6932 (const_int 0)))
e075ae69
RH
6933 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6934 (ior:QI (match_dup 1) (match_dup 2)))]
16189740
RH
6935 "ix86_match_ccmode (insn, CCNOmode)
6936 && ix86_binary_operator_ok (IOR, QImode, operands)"
e075ae69 6937 "or{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
6938 [(set_attr "type" "alu")
6939 (set_attr "mode" "QI")])
d90ffc8d 6940
a1b8572c
JH
6941(define_insn "*iorqi_2_slp"
6942 [(set (reg 17)
6943 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6944 (match_operand:QI 1 "general_operand" "qim,qi"))
6945 (const_int 0)))
6946 (set (strict_low_part (match_dup 0))
6947 (ior:QI (match_dup 0) (match_dup 1)))]
6948 "ix86_match_ccmode (insn, CCNOmode)"
6949 "or{b}\\t{%1, %0|%0, %1}"
6950 [(set_attr "type" "alu1")
6951 (set_attr "mode" "QI")])
6952
d90ffc8d
JH
6953(define_insn "*iorqi_3"
6954 [(set (reg 17)
6955 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6956 (match_operand:QI 2 "general_operand" "qim"))
6957 (const_int 0)))
7e08e190 6958 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
6959 "ix86_match_ccmode (insn, CCNOmode)
6960 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6961 "or{b}\\t{%2, %0|%0, %2}"
6962 [(set_attr "type" "alu")
6963 (set_attr "mode" "QI")])
6964
e075ae69
RH
6965\f
6966;; Logical XOR instructions
a269a03c 6967
e075ae69
RH
6968;; %%% This used to optimize known byte-wide and operations to memory.
6969;; If this is considered useful, it should be done with splitters.
57dbca5e 6970
e075ae69
RH
6971(define_expand "xorsi3"
6972 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6973 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
6974 (match_operand:SI 2 "general_operand" "")))
6975 (clobber (reg:CC 17))]
57dbca5e 6976 ""
e075ae69 6977 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
a269a03c 6978
e075ae69
RH
6979(define_insn "*xorsi_1"
6980 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6981 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6982 (match_operand:SI 2 "general_operand" "ri,rm")))
6983 (clobber (reg:CC 17))]
6984 "ix86_binary_operator_ok (XOR, SImode, operands)"
6985 "xor{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
6986 [(set_attr "type" "alu")
6987 (set_attr "mode" "SI")])
e075ae69
RH
6988
6989(define_insn "*xorsi_2"
16189740
RH
6990 [(set (reg 17)
6991 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6992 (match_operand:SI 2 "general_operand" "rim,ri"))
6993 (const_int 0)))
e075ae69
RH
6994 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6995 (xor:SI (match_dup 1) (match_dup 2)))]
16189740
RH
6996 "ix86_match_ccmode (insn, CCNOmode)
6997 && ix86_binary_operator_ok (XOR, SImode, operands)"
e075ae69 6998 "xor{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
6999 [(set_attr "type" "alu")
7000 (set_attr "mode" "SI")])
e075ae69 7001
d90ffc8d
JH
7002(define_insn "*xorsi_3"
7003 [(set (reg 17)
7004 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7005 (match_operand:SI 2 "general_operand" "rim"))
7006 (const_int 0)))
7007 (clobber (match_scratch:SI 0 "=r"))]
7008 "ix86_match_ccmode (insn, CCNOmode)
7009 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7010 "xor{l}\\t{%2, %0|%0, %2}"
7011 [(set_attr "type" "alu")
7012 (set_attr "mode" "SI")])
7013
e075ae69
RH
7014(define_expand "xorhi3"
7015 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7016 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
7017 (match_operand:HI 2 "general_operand" "")))
7018 (clobber (reg:CC 17))]
d9f32422 7019 "TARGET_HIMODE_MATH"
e075ae69
RH
7020 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
7021
7022(define_insn "*xorhi_1"
7023 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
7024 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7025 (match_operand:HI 2 "general_operand" "rmi,ri")))
7026 (clobber (reg:CC 17))]
7027 "ix86_binary_operator_ok (XOR, HImode, operands)"
7028 "xor{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
7029 [(set_attr "type" "alu")
7030 (set_attr "mode" "HI")])
57dbca5e 7031
e075ae69 7032(define_insn "*xorhi_2"
16189740
RH
7033 [(set (reg 17)
7034 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7035 (match_operand:HI 2 "general_operand" "rim,ri"))
7036 (const_int 0)))
e075ae69
RH
7037 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7038 (xor:HI (match_dup 1) (match_dup 2)))]
16189740
RH
7039 "ix86_match_ccmode (insn, CCNOmode)
7040 && ix86_binary_operator_ok (XOR, HImode, operands)"
e075ae69 7041 "xor{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
7042 [(set_attr "type" "alu")
7043 (set_attr "mode" "HI")])
e075ae69 7044
d90ffc8d
JH
7045(define_insn "*xorhi_3"
7046 [(set (reg 17)
7047 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7048 (match_operand:HI 2 "general_operand" "rim"))
7049 (const_int 0)))
7050 (clobber (match_scratch:HI 0 "=r"))]
7051 "ix86_match_ccmode (insn, CCNOmode)
7052 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7053 "xor{w}\\t{%2, %0|%0, %2}"
7054 [(set_attr "type" "alu")
7055 (set_attr "mode" "HI")])
7056
e075ae69
RH
7057(define_expand "xorqi3"
7058 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7059 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
7060 (match_operand:QI 2 "general_operand" "")))
7061 (clobber (reg:CC 17))]
d9f32422 7062 "TARGET_QIMODE_MATH"
e075ae69
RH
7063 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
7064
7065;; %%% Potential partial reg stall on alternative 2. What to do?
7066(define_insn "*xorqi_1"
7c6b971d 7067 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
e075ae69 7068 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7c6b971d 7069 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
e075ae69
RH
7070 (clobber (reg:CC 17))]
7071 "ix86_binary_operator_ok (XOR, QImode, operands)"
7072 "@
7073 xor{b}\\t{%2, %0|%0, %2}
7074 xor{b}\\t{%2, %0|%0, %2}
7075 xor{l}\\t{%k2, %k0|%k0, %k2}"
6ef67412
JH
7076 [(set_attr "type" "alu")
7077 (set_attr "mode" "QI,QI,SI")])
7078
a4414093 7079(define_insn "*xorqi_ext_1"
d2836273 7080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6ef67412
JH
7081 (const_int 8)
7082 (const_int 8))
7083 (xor:SI
7084 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
7085 (const_int 8)
7086 (const_int 8))
d2836273 7087 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6ef67412
JH
7088 (const_int 8)
7089 (const_int 8))))
7090 (clobber (reg:CC 17))]
7091 ""
7092 "xor{b}\\t{%h2, %h0|%h0, %h2}"
7093 [(set_attr "type" "alu")
7094 (set_attr "length_immediate" "0")
7095 (set_attr "mode" "QI")])
e075ae69 7096
7abd4e00 7097(define_insn "*xorqi_cc_1"
16189740
RH
7098 [(set (reg 17)
7099 (compare
e075ae69
RH
7100 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7101 (match_operand:QI 2 "general_operand" "qim,qi"))
7102 (const_int 0)))
7103 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7104 (xor:QI (match_dup 1) (match_dup 2)))]
16189740
RH
7105 "ix86_match_ccmode (insn, CCNOmode)
7106 && ix86_binary_operator_ok (XOR, QImode, operands)"
e075ae69 7107 "xor{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
7108 [(set_attr "type" "alu")
7109 (set_attr "mode" "QI")])
e075ae69 7110
d90ffc8d
JH
7111(define_insn "*xorqi_cc_2"
7112 [(set (reg 17)
7113 (compare
7114 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7115 (match_operand:QI 2 "general_operand" "qim"))
7116 (const_int 0)))
7e08e190 7117 (clobber (match_scratch:QI 0 "=q"))]
d90ffc8d
JH
7118 "ix86_match_ccmode (insn, CCNOmode)
7119 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7120 "xor{b}\\t{%2, %0|%0, %2}"
7121 [(set_attr "type" "alu")
7122 (set_attr "mode" "QI")])
7123
9076b9c1
JH
7124(define_insn "*xorqi_cc_ext_1"
7125 [(set (reg 17)
7126 (compare
e075ae69
RH
7127 (xor:SI
7128 (zero_extract:SI
7129 (match_operand 1 "ext_register_operand" "0")
7130 (const_int 8)
7131 (const_int 8))
7132 (match_operand:QI 2 "general_operand" "qmn"))
7133 (const_int 0)))
7134 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
7135 (const_int 8)
7136 (const_int 8))
7137 (xor:SI
7138 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
7139 (match_dup 2)))]
d2836273
JH
7140 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7141 "xor{b}\\t{%2, %h0|%h0, %2}"
7142 [(set_attr "type" "alu")
7143 (set_attr "mode" "QI")])
7144
7145(define_insn "*xorqi_cc_ext_1_rex64"
7146 [(set (reg 17)
7147 (compare
7148 (xor:SI
7149 (zero_extract:SI
7150 (match_operand 1 "ext_register_operand" "0")
7151 (const_int 8)
7152 (const_int 8))
7153 (match_operand:QI 2 "nonmemory_operand" "Qn"))
7154 (const_int 0)))
7155 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7156 (const_int 8)
7157 (const_int 8))
7158 (xor:SI
7159 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
7160 (match_dup 2)))]
7161 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
e075ae69 7162 "xor{b}\\t{%2, %h0|%h0, %2}"
6ef67412
JH
7163 [(set_attr "type" "alu")
7164 (set_attr "mode" "QI")])
9076b9c1
JH
7165
7166(define_expand "xorqi_cc_ext_1"
7167 [(parallel [
7168 (set (reg:CCNO 17)
7169 (compare:CCNO
7170 (xor:SI
7171 (zero_extract:SI
7172 (match_operand 1 "ext_register_operand" "")
7173 (const_int 8)
7174 (const_int 8))
7175 (match_operand:QI 2 "general_operand" ""))
7176 (const_int 0)))
7177 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
7178 (const_int 8)
7179 (const_int 8))
7180 (xor:SI
7181 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
7182 (match_dup 2)))])]
7183 ""
7184 "")
e075ae69
RH
7185\f
7186;; Negation instructions
57dbca5e 7187
e075ae69 7188;; %%% define_expand from the very first?
886c62d1 7189
06a964de
JH
7190(define_expand "negdi2"
7191 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
2756c3d8 7192 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
06a964de
JH
7193 (clobber (reg:CC 17))])]
7194 ""
7195 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
7196
7197(define_insn "*negdi2_1"
e075ae69
RH
7198 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
7199 (neg:DI (match_operand:DI 1 "general_operand" "0")))
7200 (clobber (reg:CC 17))]
d2836273
JH
7201 "!TARGET_64BIT
7202 && ix86_unary_operator_ok (NEG, DImode, operands)"
e075ae69 7203 "#")
886c62d1 7204
e075ae69
RH
7205(define_split
7206 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7207 (neg:DI (match_operand:DI 1 "general_operand" "")))
7208 (clobber (reg:CC 17))]
d2836273
JH
7209 "reload_completed
7210 && !TARGET_64BIT"
e075ae69 7211 [(parallel
16189740
RH
7212 [(set (reg:CCZ 17)
7213 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
e075ae69
RH
7214 (set (match_dup 0) (neg:SI (match_dup 2)))])
7215 (parallel
7216 [(set (match_dup 1)
7e08e190 7217 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9dcbdc7e
JH
7218 (match_dup 3))
7219 (const_int 0)))
e075ae69
RH
7220 (clobber (reg:CC 17))])
7221 (parallel
7222 [(set (match_dup 1)
7223 (neg:SI (match_dup 1)))
7224 (clobber (reg:CC 17))])]
7225 "split_di (operands+1, 1, operands+2, operands+3);
7226 split_di (operands+0, 1, operands+0, operands+1);")
886c62d1 7227
06a964de
JH
7228(define_expand "negsi2"
7229 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
2756c3d8 7230 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
06a964de
JH
7231 (clobber (reg:CC 17))])]
7232 ""
7233 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
7234
7235(define_insn "*negsi2_1"
2ae0f82c 7236 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69
RH
7237 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
7238 (clobber (reg:CC 17))]
06a964de 7239 "ix86_unary_operator_ok (NEG, SImode, operands)"
e075ae69 7240 "neg{l}\\t%0"
6ef67412
JH
7241 [(set_attr "type" "negnot")
7242 (set_attr "mode" "SI")])
e075ae69 7243
16189740
RH
7244;; The problem with neg is that it does not perform (compare x 0),
7245;; it really performs (compare 0 x), which leaves us with the zero
7246;; flag being the only useful item.
e075ae69 7247
16189740
RH
7248(define_insn "*negsi2_cmpz"
7249 [(set (reg:CCZ 17)
7250 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7251 (const_int 0)))
e075ae69
RH
7252 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7253 (neg:SI (match_dup 1)))]
06a964de 7254 "ix86_unary_operator_ok (NEG, SImode, operands)"
e075ae69 7255 "neg{l}\\t%0"
6ef67412
JH
7256 [(set_attr "type" "negnot")
7257 (set_attr "mode" "SI")])
886c62d1 7258
06a964de
JH
7259(define_expand "neghi2"
7260 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
2756c3d8 7261 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
06a964de 7262 (clobber (reg:CC 17))])]
d9f32422 7263 "TARGET_HIMODE_MATH"
06a964de
JH
7264 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
7265
7266(define_insn "*neghi2_1"
2ae0f82c 7267 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69
RH
7268 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
7269 (clobber (reg:CC 17))]
06a964de 7270 "ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 7271 "neg{w}\\t%0"
6ef67412
JH
7272 [(set_attr "type" "negnot")
7273 (set_attr "mode" "HI")])
e075ae69 7274
16189740
RH
7275(define_insn "*neghi2_cmpz"
7276 [(set (reg:CCZ 17)
7277 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7278 (const_int 0)))
e075ae69
RH
7279 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7280 (neg:HI (match_dup 1)))]
06a964de 7281 "ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 7282 "neg{w}\\t%0"
6ef67412
JH
7283 [(set_attr "type" "negnot")
7284 (set_attr "mode" "HI")])
886c62d1 7285
06a964de
JH
7286(define_expand "negqi2"
7287 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
2756c3d8 7288 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
06a964de 7289 (clobber (reg:CC 17))])]
d9f32422 7290 "TARGET_QIMODE_MATH"
06a964de
JH
7291 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
7292
7293(define_insn "*negqi2_1"
2ae0f82c 7294 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69
RH
7295 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
7296 (clobber (reg:CC 17))]
06a964de 7297 "ix86_unary_operator_ok (NEG, QImode, operands)"
e075ae69 7298 "neg{b}\\t%0"
6ef67412
JH
7299 [(set_attr "type" "negnot")
7300 (set_attr "mode" "QI")])
e075ae69 7301
16189740
RH
7302(define_insn "*negqi2_cmpz"
7303 [(set (reg:CCZ 17)
7304 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7305 (const_int 0)))
e075ae69
RH
7306 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7307 (neg:QI (match_dup 1)))]
06a964de 7308 "ix86_unary_operator_ok (NEG, QImode, operands)"
e075ae69 7309 "neg{b}\\t%0"
6ef67412
JH
7310 [(set_attr "type" "negnot")
7311 (set_attr "mode" "QI")])
886c62d1 7312
06a964de 7313;; Changing of sign for FP values is doable using integer unit too.
1ce485ec 7314
06a964de
JH
7315(define_expand "negsf2"
7316 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2756c3d8 7317 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
06a964de
JH
7318 (clobber (reg:CC 17))])]
7319 "TARGET_80387"
7320 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
7321
e20440c1
JH
7322;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7323;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7324;; to itself.
06a964de 7325(define_insn "*negsf2_if"
e20440c1
JH
7326 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7327 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1ce485ec 7328 (clobber (reg:CC 17))]
06a964de 7329 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
1ce485ec
JH
7330 "#")
7331
7332(define_split
7333 [(set (match_operand:SF 0 "register_operand" "")
7334 (neg:SF (match_operand:SF 1 "register_operand" "")))
7335 (clobber (reg:CC 17))]
7336 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7337 [(set (match_dup 0)
7338 (neg:SF (match_dup 1)))]
7339 "")
7340
7341(define_split
7342 [(set (match_operand:SF 0 "register_operand" "")
7343 (neg:SF (match_operand:SF 1 "register_operand" "")))
7344 (clobber (reg:CC 17))]
7345 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7346 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7347 (clobber (reg:CC 17))])]
7348 "operands[1] = GEN_INT (0x80000000);
7349 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7350
7351(define_split
7352 [(set (match_operand 0 "memory_operand" "")
7353 (neg (match_operand 1 "memory_operand" "")))
7354 (clobber (reg:CC 17))]
7355 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7356 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7357 (clobber (reg:CC 17))])]
7358 "
7359{
7360 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7361
7362 /* XFmode's size is 12, but only 10 bytes are used. */
7363 if (size == 12)
7364 size = 10;
7365 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7366 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7367 operands[1] = GEN_INT (0x80);
7368}")
7369
06a964de
JH
7370(define_expand "negdf2"
7371 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2756c3d8 7372 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
06a964de
JH
7373 (clobber (reg:CC 17))])]
7374 "TARGET_80387"
7375 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
7376
e20440c1
JH
7377;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7378;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7379;; to itself.
06a964de 7380(define_insn "*negdf2_if"
e20440c1
JH
7381 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7382 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1ce485ec 7383 (clobber (reg:CC 17))]
06a964de 7384 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
1ce485ec
JH
7385 "#")
7386
7387(define_split
7388 [(set (match_operand:DF 0 "register_operand" "")
7389 (neg:DF (match_operand:DF 1 "register_operand" "")))
7390 (clobber (reg:CC 17))]
7391 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7392 [(set (match_dup 0)
7393 (neg:DF (match_dup 1)))]
7394 "")
7395
7396(define_split
7397 [(set (match_operand:DF 0 "register_operand" "")
7398 (neg:DF (match_operand:DF 1 "register_operand" "")))
7399 (clobber (reg:CC 17))]
7400 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7401 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
7402 (clobber (reg:CC 17))])]
7403 "operands[4] = GEN_INT (0x80000000);
7404 split_di (operands+0, 1, operands+2, operands+3);")
7405
06a964de
JH
7406(define_expand "negxf2"
7407 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2756c3d8 7408 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
06a964de 7409 (clobber (reg:CC 17))])]
1e07edd3 7410 "TARGET_80387 && !TARGET_64BIT"
06a964de
JH
7411 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
7412
2b589241
JH
7413(define_expand "negtf2"
7414 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7415 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7416 (clobber (reg:CC 17))])]
7417 "TARGET_80387"
7418 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
7419
e20440c1
JH
7420;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7421;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7422;; to itself.
06a964de 7423(define_insn "*negxf2_if"
e20440c1
JH
7424 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7425 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1ce485ec 7426 (clobber (reg:CC 17))]
1e07edd3
JH
7427 "TARGET_80387 && !TARGET_64BIT
7428 && ix86_unary_operator_ok (NEG, XFmode, operands)"
1ce485ec
JH
7429 "#")
7430
7431(define_split
7432 [(set (match_operand:XF 0 "register_operand" "")
7433 (neg:XF (match_operand:XF 1 "register_operand" "")))
7434 (clobber (reg:CC 17))]
7435 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7436 [(set (match_dup 0)
7437 (neg:XF (match_dup 1)))]
7438 "")
7439
7440(define_split
7441 [(set (match_operand:XF 0 "register_operand" "")
7442 (neg:XF (match_operand:XF 1 "register_operand" "")))
7443 (clobber (reg:CC 17))]
7444 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7445 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7446 (clobber (reg:CC 17))])]
7447 "operands[1] = GEN_INT (0x8000);
7448 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7449
2b589241
JH
7450;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7451;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7452;; to itself.
7453(define_insn "*negtf2_if"
7454 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7455 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7456 (clobber (reg:CC 17))]
7457 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
7458 "#")
7459
7460(define_split
7461 [(set (match_operand:TF 0 "register_operand" "")
7462 (neg:TF (match_operand:TF 1 "register_operand" "")))
7463 (clobber (reg:CC 17))]
7464 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7465 [(set (match_dup 0)
7466 (neg:TF (match_dup 1)))]
7467 "")
7468
7469(define_split
7470 [(set (match_operand:TF 0 "register_operand" "")
7471 (neg:TF (match_operand:TF 1 "register_operand" "")))
7472 (clobber (reg:CC 17))]
7473 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7474 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7475 (clobber (reg:CC 17))])]
7476 "operands[1] = GEN_INT (0x8000);
7477 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7478
1ce485ec
JH
7479;; Conditionize these after reload. If they matches before reload, we
7480;; lose the clobber and ability to use integer instructions.
7481
7482(define_insn "*negsf2_1"
886c62d1 7483 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 7484 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 7485 "TARGET_80387 && reload_completed"
10195bd8 7486 "fchs"
e075ae69 7487 [(set_attr "type" "fsgn")
6ef67412 7488 (set_attr "mode" "SF")
e075ae69 7489 (set_attr "ppro_uops" "few")])
886c62d1 7490
1ce485ec 7491(define_insn "*negdf2_1"
886c62d1 7492 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 7493 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 7494 "TARGET_80387 && reload_completed"
10195bd8 7495 "fchs"
e075ae69 7496 [(set_attr "type" "fsgn")
6ef67412 7497 (set_attr "mode" "DF")
e075ae69 7498 (set_attr "ppro_uops" "few")])
886c62d1 7499
6343a50e 7500(define_insn "*negextendsfdf2"
886c62d1 7501 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
7502 (neg:DF (float_extend:DF
7503 (match_operand:SF 1 "register_operand" "0"))))]
886c62d1 7504 "TARGET_80387"
10195bd8 7505 "fchs"
e075ae69 7506 [(set_attr "type" "fsgn")
6ef67412 7507 (set_attr "mode" "DF")
e075ae69 7508 (set_attr "ppro_uops" "few")])
4fb21e90 7509
1ce485ec 7510(define_insn "*negxf2_1"
4fb21e90 7511 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 7512 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
1e07edd3 7513 "TARGET_80387 && !TARGET_64BIT && reload_completed"
10195bd8 7514 "fchs"
e075ae69 7515 [(set_attr "type" "fsgn")
6ef67412 7516 (set_attr "mode" "XF")
e075ae69
RH
7517 (set_attr "ppro_uops" "few")])
7518
6343a50e 7519(define_insn "*negextenddfxf2"
e075ae69
RH
7520 [(set (match_operand:XF 0 "register_operand" "=f")
7521 (neg:XF (float_extend:XF
7522 (match_operand:DF 1 "register_operand" "0"))))]
1e07edd3 7523 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
7524 "fchs"
7525 [(set_attr "type" "fsgn")
6ef67412 7526 (set_attr "mode" "XF")
e075ae69 7527 (set_attr "ppro_uops" "few")])
4fb21e90 7528
6343a50e 7529(define_insn "*negextendsfxf2"
4fb21e90 7530 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
7531 (neg:XF (float_extend:XF
7532 (match_operand:SF 1 "register_operand" "0"))))]
1e07edd3 7533 "TARGET_80387 && !TARGET_64BIT"
10195bd8 7534 "fchs"
e075ae69 7535 [(set_attr "type" "fsgn")
6ef67412 7536 (set_attr "mode" "XF")
e075ae69 7537 (set_attr "ppro_uops" "few")])
2b589241
JH
7538
7539(define_insn "*negtf2_1"
7540 [(set (match_operand:TF 0 "register_operand" "=f")
7541 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
7542 "TARGET_80387 && reload_completed"
7543 "fchs"
7544 [(set_attr "type" "fsgn")
7545 (set_attr "mode" "XF")
7546 (set_attr "ppro_uops" "few")])
7547
7548(define_insn "*negextenddftf2"
7549 [(set (match_operand:TF 0 "register_operand" "=f")
7550 (neg:TF (float_extend:TF
7551 (match_operand:DF 1 "register_operand" "0"))))]
7552 "TARGET_80387"
7553 "fchs"
7554 [(set_attr "type" "fsgn")
7555 (set_attr "mode" "XF")
7556 (set_attr "ppro_uops" "few")])
7557
7558(define_insn "*negextendsftf2"
7559 [(set (match_operand:TF 0 "register_operand" "=f")
7560 (neg:TF (float_extend:TF
7561 (match_operand:SF 1 "register_operand" "0"))))]
7562 "TARGET_80387"
7563 "fchs"
7564 [(set_attr "type" "fsgn")
7565 (set_attr "mode" "XF")
7566 (set_attr "ppro_uops" "few")])
886c62d1
JVA
7567\f
7568;; Absolute value instructions
7569
06a964de
JH
7570(define_expand "abssf2"
7571 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
2756c3d8 7572 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
06a964de
JH
7573 (clobber (reg:CC 17))])]
7574 "TARGET_80387"
ca29d1dc
JH
7575 "if (TARGET_SSE)
7576 {
7577 /* In case operand is in memory, we will not use SSE. */
7578 if (memory_operand (operands[0], VOIDmode)
7579 && rtx_equal_p (operands[0], operands[1]))
7580 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
7581 else
7582 {
7583 /* Using SSE is tricky, since we need bitwise negation of -0
7584 in register. */
7585 rtx reg = gen_reg_rtx (SFmode);
7586 emit_move_insn (reg, gen_lowpart (SFmode, GEN_INT (0x80000000)));
7587 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
7588 }
7589 DONE;
7590 }
7591 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
7592
7593(define_insn "abssf2_memory"
7594 [(set (match_operand:SF 0 "memory_operand" "=m")
7595 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
7596 (clobber (reg:CC 17))]
7597 "ix86_unary_operator_ok (ABS, SFmode, operands)"
7598 "#")
7599
7600(define_insn "abssf2_ifs"
7601 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,r#xf")
7602 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
7603 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*X#x,*X#x"))
7604 (clobber (reg:CC 17))]
7605 "TARGET_SSE"
7606 "#")
7607
7608(define_split
7609 [(set (match_operand:SF 0 "memory_operand" "")
7610 (abs:SF (match_operand:SF 1 "memory_operand" "")))
7611 (use (match_operand:SF 2 "" ""))
7612 (clobber (reg:CC 17))]
7613 ""
7614 [(parallel [(set (match_dup 0)
7615 (abs:SF (match_dup 1)))
7616 (clobber (reg:CC 17))])])
7617
7618(define_split
7619 [(set (match_operand:SF 0 "register_operand" "")
7620 (abs:SF (match_operand:SF 1 "register_operand" "")))
7621 (use (match_operand:SF 2 "" ""))
7622 (clobber (reg:CC 17))]
7623 "reload_completed && !SSE_REG_P (operands[0])"
7624 [(parallel [(set (match_dup 0)
7625 (abs:SF (match_dup 1)))
7626 (clobber (reg:CC 17))])])
7627
7628(define_split
7629 [(set (match_operand:SF 0 "register_operand" "")
7630 (abs:SF (match_operand:SF 1 "register_operand" "")))
7631 (use (match_operand:SF 2 "register_operand" ""))
7632 (clobber (reg:CC 17))]
7633 "reload_completed && SSE_REG_P (operands[0])"
7634 [(set (subreg:TI (match_dup 0) 0)
7635 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
7636 (subreg:TI (match_dup 1) 0)))])
06a964de 7637
e20440c1
JH
7638;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7639;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7640;; to itself.
06a964de 7641(define_insn "*abssf2_if"
e20440c1
JH
7642 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7643 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1ce485ec 7644 (clobber (reg:CC 17))]
ca29d1dc 7645 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
1ce485ec
JH
7646 "#")
7647
7648(define_split
7649 [(set (match_operand:SF 0 "register_operand" "")
7650 (abs:SF (match_operand:SF 1 "register_operand" "")))
7651 (clobber (reg:CC 17))]
7652 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
7653 [(set (match_dup 0)
7654 (abs:SF (match_dup 1)))]
7655 "")
7656
7657(define_split
7658 [(set (match_operand:SF 0 "register_operand" "")
7659 (abs:SF (match_operand:SF 1 "register_operand" "")))
7660 (clobber (reg:CC 17))]
7661 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7662 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7663 (clobber (reg:CC 17))])]
7664 "operands[1] = GEN_INT (~0x80000000);
7665 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7666
7667(define_split
7668 [(set (match_operand 0 "memory_operand" "")
7669 (abs (match_operand 1 "memory_operand" "")))
7670 (clobber (reg:CC 17))]
7671 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7672 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7673 (clobber (reg:CC 17))])]
7674 "
7675{
7676 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7677
7678 /* XFmode's size is 12, but only 10 bytes are used. */
7679 if (size == 12)
7680 size = 10;
7681 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7682 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7683 operands[1] = GEN_INT (~0x80);
7684}")
7685
06a964de
JH
7686(define_expand "absdf2"
7687 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
2756c3d8 7688 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
06a964de 7689 (clobber (reg:CC 17))])]
1ce485ec 7690 "TARGET_80387"
ca29d1dc
JH
7691 "if (TARGET_SSE2)
7692 {
7693 /* In case operand is in memory, we will not use SSE. */
7694 if (memory_operand (operands[0], VOIDmode)
7695 && rtx_equal_p (operands[0], operands[1]))
7696 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
7697 else
7698 {
7699 /* Using SSE is tricky, since we need bitwise negation of -0
7700 in register. */
7701 rtx reg = gen_reg_rtx (DFmode);
7702#if HOST_BITS_PER_WIDE_INT >= 64
7703 rtx imm = gen_reg_rtx (GEN_INT (0x80000000));
7704#else
7705 rtx imm = immed_double_const (0, 0x80000000, DImode);
7706#endif
7707 emit_move_insn (reg, gen_lowpart (DFmode, imm));
7708 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
7709 }
7710 DONE;
7711 }
7712 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
7713
7714(define_insn "absdf2_memory"
7715 [(set (match_operand:DF 0 "memory_operand" "=m")
7716 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
7717 (clobber (reg:CC 17))]
7718 "ix86_unary_operator_ok (ABS, DFmode, operands)"
7719 "#")
7720
7721(define_insn "absdf2_ifs"
7722 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,f#Yr,r#Yf")
7723 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
7724 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*X#Y,*X#Y"))
7725 (clobber (reg:CC 17))]
7726 "TARGET_SSE2"
7727 "#")
7728
7729(define_split
7730 [(set (match_operand:DF 0 "memory_operand" "")
7731 (abs:DF (match_operand:DF 1 "memory_operand" "")))
7732 (use (match_operand:DF 2 "" ""))
7733 (clobber (reg:CC 17))]
7734 ""
7735 [(parallel [(set (match_dup 0)
7736 (abs:DF (match_dup 1)))
7737 (clobber (reg:CC 17))])])
7738
7739(define_split
7740 [(set (match_operand:DF 0 "register_operand" "")
7741 (abs:DF (match_operand:DF 1 "register_operand" "")))
7742 (use (match_operand:DF 2 "" ""))
7743 (clobber (reg:CC 17))]
7744 "reload_completed && !SSE_REG_P (operands[0])"
7745 [(parallel [(set (match_dup 0)
7746 (abs:DF (match_dup 1)))
7747 (clobber (reg:CC 17))])])
7748
7749(define_split
7750 [(set (match_operand:DF 0 "register_operand" "")
7751 (abs:DF (match_operand:DF 1 "register_operand" "")))
7752 (use (match_operand:DF 2 "register_operand" ""))
7753 (clobber (reg:CC 17))]
7754 "reload_completed && SSE_REG_P (operands[0])"
7755 [(set (subreg:TI (match_dup 0) 0)
7756 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
7757 (subreg:TI (match_dup 1) 0)))])
7758
06a964de 7759
e20440c1
JH
7760;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7761;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7762;; to itself.
06a964de 7763(define_insn "*absdf2_if"
e20440c1
JH
7764 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7765 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
06a964de
JH
7766 (clobber (reg:CC 17))]
7767 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
1ce485ec
JH
7768 "#")
7769
7770(define_split
7771 [(set (match_operand:DF 0 "register_operand" "")
7772 (abs:DF (match_operand:DF 1 "register_operand" "")))
7773 (clobber (reg:CC 17))]
7774 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7775 [(set (match_dup 0)
7776 (abs:DF (match_dup 1)))]
7777 "")
7778
7779(define_split
7780 [(set (match_operand:DF 0 "register_operand" "")
7781 (abs:DF (match_operand:DF 1 "register_operand" "")))
7782 (clobber (reg:CC 17))]
7783 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7784 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
7785 (clobber (reg:CC 17))])]
7786 "operands[4] = GEN_INT (~0x80000000);
7787 split_di (operands+0, 1, operands+2, operands+3);")
7788
06a964de
JH
7789(define_expand "absxf2"
7790 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
2756c3d8 7791 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
06a964de 7792 (clobber (reg:CC 17))])]
1e07edd3 7793 "TARGET_80387 && !TARGET_64BIT"
06a964de
JH
7794 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
7795
2b589241
JH
7796(define_expand "abstf2"
7797 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7798 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7799 (clobber (reg:CC 17))])]
7800 "TARGET_80387"
7801 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
7802
e20440c1
JH
7803;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7804;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7805;; to itself.
06a964de 7806(define_insn "*absxf2_if"
e20440c1
JH
7807 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7808 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1ce485ec 7809 (clobber (reg:CC 17))]
1e07edd3
JH
7810 "TARGET_80387 && !TARGET_64BIT
7811 && ix86_unary_operator_ok (ABS, XFmode, operands)"
1ce485ec
JH
7812 "#")
7813
7814(define_split
7815 [(set (match_operand:XF 0 "register_operand" "")
7816 (abs:XF (match_operand:XF 1 "register_operand" "")))
7817 (clobber (reg:CC 17))]
7818 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7819 [(set (match_dup 0)
7820 (abs:XF (match_dup 1)))]
7821 "")
7822
7823(define_split
7824 [(set (match_operand:XF 0 "register_operand" "")
7825 (abs:XF (match_operand:XF 1 "register_operand" "")))
7826 (clobber (reg:CC 17))]
7827 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7828 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7829 (clobber (reg:CC 17))])]
7830 "operands[1] = GEN_INT (~0x8000);
7831 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7832
2b589241
JH
7833(define_insn "*abstf2_if"
7834 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7835 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7836 (clobber (reg:CC 17))]
7837 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
7838 "#")
7839
7840(define_split
7841 [(set (match_operand:TF 0 "register_operand" "")
7842 (abs:TF (match_operand:TF 1 "register_operand" "")))
7843 (clobber (reg:CC 17))]
7844 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7845 [(set (match_dup 0)
7846 (abs:TF (match_dup 1)))]
7847 "")
7848
7849(define_split
7850 [(set (match_operand:TF 0 "register_operand" "")
7851 (abs:TF (match_operand:TF 1 "register_operand" "")))
7852 (clobber (reg:CC 17))]
7853 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7854 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7855 (clobber (reg:CC 17))])]
7856 "operands[1] = GEN_INT (~0x8000);
7857 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7858
1ce485ec 7859(define_insn "*abssf2_1"
886c62d1 7860 [(set (match_operand:SF 0 "register_operand" "=f")
2ae0f82c 7861 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
1ce485ec 7862 "TARGET_80387 && reload_completed"
2ae0f82c 7863 "fabs"
6ef67412
JH
7864 [(set_attr "type" "fsgn")
7865 (set_attr "mode" "SF")])
886c62d1 7866
1ce485ec 7867(define_insn "*absdf2_1"
886c62d1 7868 [(set (match_operand:DF 0 "register_operand" "=f")
2ae0f82c 7869 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
1ce485ec 7870 "TARGET_80387 && reload_completed"
2ae0f82c 7871 "fabs"
6ef67412
JH
7872 [(set_attr "type" "fsgn")
7873 (set_attr "mode" "DF")])
886c62d1 7874
6343a50e 7875(define_insn "*absextendsfdf2"
886c62d1 7876 [(set (match_operand:DF 0 "register_operand" "=f")
e075ae69
RH
7877 (abs:DF (float_extend:DF
7878 (match_operand:SF 1 "register_operand" "0"))))]
886c62d1 7879 "TARGET_80387"
2ae0f82c 7880 "fabs"
6ef67412
JH
7881 [(set_attr "type" "fsgn")
7882 (set_attr "mode" "DF")])
886c62d1 7883
1ce485ec 7884(define_insn "*absxf2_1"
4fb21e90 7885 [(set (match_operand:XF 0 "register_operand" "=f")
2ae0f82c 7886 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
1e07edd3 7887 "TARGET_80387 && !TARGET_64BIT && reload_completed"
2ae0f82c 7888 "fabs"
6ef67412
JH
7889 [(set_attr "type" "fsgn")
7890 (set_attr "mode" "DF")])
4fb21e90 7891
6343a50e 7892(define_insn "*absextenddfxf2"
4fb21e90 7893 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
7894 (abs:XF (float_extend:XF
7895 (match_operand:DF 1 "register_operand" "0"))))]
1e07edd3 7896 "TARGET_80387 && !TARGET_64BIT"
2ae0f82c 7897 "fabs"
6ef67412
JH
7898 [(set_attr "type" "fsgn")
7899 (set_attr "mode" "XF")])
a199fdd6 7900
6343a50e 7901(define_insn "*absextendsfxf2"
58733f96 7902 [(set (match_operand:XF 0 "register_operand" "=f")
e075ae69
RH
7903 (abs:XF (float_extend:XF
7904 (match_operand:SF 1 "register_operand" "0"))))]
1e07edd3 7905 "TARGET_80387 && !TARGET_64BIT"
e075ae69 7906 "fabs"
6ef67412
JH
7907 [(set_attr "type" "fsgn")
7908 (set_attr "mode" "XF")])
2b589241
JH
7909
7910(define_insn "*abstf2_1"
7911 [(set (match_operand:TF 0 "register_operand" "=f")
7912 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
7913 "TARGET_80387 && reload_completed"
7914 "fabs"
7915 [(set_attr "type" "fsgn")
7916 (set_attr "mode" "DF")])
7917
7918(define_insn "*absextenddftf2"
7919 [(set (match_operand:TF 0 "register_operand" "=f")
7920 (abs:TF (float_extend:TF
7921 (match_operand:DF 1 "register_operand" "0"))))]
7922 "TARGET_80387"
7923 "fabs"
7924 [(set_attr "type" "fsgn")
7925 (set_attr "mode" "XF")])
7926
7927(define_insn "*absextendsftf2"
7928 [(set (match_operand:TF 0 "register_operand" "=f")
7929 (abs:TF (float_extend:TF
7930 (match_operand:SF 1 "register_operand" "0"))))]
7931 "TARGET_80387"
7932 "fabs"
7933 [(set_attr "type" "fsgn")
7934 (set_attr "mode" "XF")])
886c62d1 7935\f
e075ae69 7936;; One complement instructions
886c62d1 7937
06a964de 7938(define_expand "one_cmplsi2"
a1cbdd7f
JH
7939 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7940 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
06a964de
JH
7941 ""
7942 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
7943
7944(define_insn "*one_cmplsi2_1"
2ae0f82c
SC
7945 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7946 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 7947 "ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 7948 "not{l}\\t%0"
6ef67412
JH
7949 [(set_attr "type" "negnot")
7950 (set_attr "mode" "SI")])
bb524860 7951
06a964de 7952(define_insn "*one_cmplsi2_2"
16189740
RH
7953 [(set (reg 17)
7954 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7955 (const_int 0)))
e075ae69
RH
7956 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7957 (not:SI (match_dup 1)))]
16189740
RH
7958 "ix86_match_ccmode (insn, CCNOmode)
7959 && ix86_unary_operator_ok (NOT, SImode, operands)"
e075ae69 7960 "#"
6ef67412
JH
7961 [(set_attr "type" "alu1")
7962 (set_attr "mode" "SI")])
e075ae69
RH
7963
7964(define_split
16189740
RH
7965 [(set (reg 17)
7966 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
7967 (const_int 0)))
e075ae69
RH
7968 (set (match_operand:SI 0 "nonimmediate_operand" "")
7969 (not:SI (match_dup 1)))]
16189740 7970 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
7971 [(parallel [(set (reg:CCNO 17)
7972 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
7973 (const_int 0)))
7974 (set (match_dup 0)
7975 (xor:SI (match_dup 1) (const_int -1)))])]
7976 "")
886c62d1 7977
06a964de 7978(define_expand "one_cmplhi2"
a1cbdd7f
JH
7979 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7980 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
d9f32422 7981 "TARGET_HIMODE_MATH"
06a964de
JH
7982 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
7983
7984(define_insn "*one_cmplhi2_1"
2ae0f82c
SC
7985 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7986 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
a1cbdd7f 7987 "ix86_unary_operator_ok (NOT, HImode, operands)"
e075ae69 7988 "not{w}\\t%0"
6ef67412
JH
7989 [(set_attr "type" "negnot")
7990 (set_attr "mode" "HI")])
bb524860 7991
06a964de 7992(define_insn "*one_cmplhi2_2"
16189740
RH
7993 [(set (reg 17)
7994 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7995 (const_int 0)))
e075ae69
RH
7996 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7997 (not:HI (match_dup 1)))]
16189740
RH
7998 "ix86_match_ccmode (insn, CCNOmode)
7999 && ix86_unary_operator_ok (NEG, HImode, operands)"
e075ae69 8000 "#"
6ef67412
JH
8001 [(set_attr "type" "alu1")
8002 (set_attr "mode" "HI")])
e075ae69
RH
8003
8004(define_split
16189740
RH
8005 [(set (reg 17)
8006 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
8007 (const_int 0)))
e075ae69
RH
8008 (set (match_operand:HI 0 "nonimmediate_operand" "")
8009 (not:HI (match_dup 1)))]
16189740 8010 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
8011 [(parallel [(set (reg:CCNO 17)
8012 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
8013 (const_int 0)))
8014 (set (match_dup 0)
8015 (xor:HI (match_dup 1) (const_int -1)))])]
8016 "")
886c62d1 8017
e075ae69 8018;; %%% Potential partial reg stall on alternative 1. What to do?
06a964de 8019(define_expand "one_cmplqi2"
a1cbdd7f
JH
8020 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8021 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
d9f32422 8022 "TARGET_QIMODE_MATH"
06a964de
JH
8023 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
8024
8025(define_insn "*one_cmplqi2_1"
7c6b971d 8026 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69 8027 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
a1cbdd7f 8028 "ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69
RH
8029 "@
8030 not{b}\\t%0
8031 not{l}\\t%k0"
6ef67412
JH
8032 [(set_attr "type" "negnot")
8033 (set_attr "mode" "QI,SI")])
bb524860 8034
06a964de 8035(define_insn "*one_cmplqi2_2"
16189740
RH
8036 [(set (reg 17)
8037 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
8038 (const_int 0)))
e075ae69
RH
8039 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8040 (not:QI (match_dup 1)))]
16189740
RH
8041 "ix86_match_ccmode (insn, CCNOmode)
8042 && ix86_unary_operator_ok (NOT, QImode, operands)"
e075ae69 8043 "#"
6ef67412
JH
8044 [(set_attr "type" "alu1")
8045 (set_attr "mode" "QI")])
e075ae69
RH
8046
8047(define_split
16189740
RH
8048 [(set (reg 17)
8049 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
8050 (const_int 0)))
e075ae69
RH
8051 (set (match_operand:QI 0 "nonimmediate_operand" "")
8052 (not:QI (match_dup 1)))]
16189740 8053 "ix86_match_ccmode (insn, CCNOmode)"
e075ae69
RH
8054 [(parallel [(set (reg:CCNO 17)
8055 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
8056 (const_int 0)))
8057 (set (match_dup 0)
8058 (xor:QI (match_dup 1) (const_int -1)))])]
8059 "")
886c62d1 8060\f
e075ae69 8061;; Arithmetic shift instructions
886c62d1
JVA
8062
8063;; DImode shifts are implemented using the i386 "shift double" opcode,
8064;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8065;; is variable, then the count is in %cl and the "imm" operand is dropped
8066;; from the assembler input.
e075ae69 8067;;
886c62d1
JVA
8068;; This instruction shifts the target reg/mem as usual, but instead of
8069;; shifting in zeros, bits are shifted in from reg operand. If the insn
8070;; is a left shift double, bits are taken from the high order bits of
8071;; reg, else if the insn is a shift right double, bits are taken from the
8072;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8073;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
e075ae69 8074;;
886c62d1
JVA
8075;; Since sh[lr]d does not change the `reg' operand, that is done
8076;; separately, making all shifts emit pairs of shift double and normal
8077;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8078;; support a 63 bit shift, each shift where the count is in a reg expands
f58acb67 8079;; to a pair of shifts, a branch, a shift by 32 and a label.
e075ae69 8080;;
886c62d1
JVA
8081;; If the shift count is a constant, we need never emit more than one
8082;; shift pair, instead using moves and sign extension for counts greater
8083;; than 31.
8084
56c0e8fa 8085(define_expand "ashldi3"
3d117b30
JH
8086 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8087 (ashift:DI (match_operand:DI 1 "register_operand" "")
8088 (match_operand:QI 2 "nonmemory_operand" "")))
e075ae69 8089 (clobber (reg:CC 17))])]
56c0e8fa
JVA
8090 ""
8091 "
8092{
3d117b30 8093 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
56c0e8fa 8094 {
e075ae69
RH
8095 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
8096 DONE;
56c0e8fa 8097 }
3d117b30 8098 ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;
56c0e8fa
JVA
8099}")
8100
e075ae69
RH
8101(define_insn "ashldi3_1"
8102 [(set (match_operand:DI 0 "register_operand" "=r")
56c0e8fa 8103 (ashift:DI (match_operand:DI 1 "register_operand" "0")
e075ae69
RH
8104 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8105 (clobber (match_scratch:SI 3 "=&r"))
8106 (clobber (reg:CC 17))]
8107 "TARGET_CMOVE"
8108 "#"
8109 [(set_attr "type" "multi")])
886c62d1 8110
e075ae69
RH
8111(define_insn "*ashldi3_2"
8112 [(set (match_operand:DI 0 "register_operand" "=r")
56c0e8fa 8113 (ashift:DI (match_operand:DI 1 "register_operand" "0")
e075ae69
RH
8114 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8115 (clobber (reg:CC 17))]
56c0e8fa 8116 ""
e075ae69
RH
8117 "#"
8118 [(set_attr "type" "multi")])
886c62d1 8119
e075ae69
RH
8120(define_split
8121 [(set (match_operand:DI 0 "register_operand" "")
8122 (ashift:DI (match_operand:DI 1 "register_operand" "")
8123 (match_operand:QI 2 "nonmemory_operand" "")))
8124 (clobber (match_scratch:SI 3 ""))
8125 (clobber (reg:CC 17))]
d7a29404 8126 "TARGET_CMOVE && reload_completed"
e075ae69
RH
8127 [(const_int 0)]
8128 "ix86_split_ashldi (operands, operands[3]); DONE;")
47f59fd4 8129
e075ae69
RH
8130(define_split
8131 [(set (match_operand:DI 0 "register_operand" "")
8132 (ashift:DI (match_operand:DI 1 "register_operand" "")
8133 (match_operand:QI 2 "nonmemory_operand" "")))
8134 (clobber (reg:CC 17))]
d7a29404 8135 "reload_completed"
e075ae69
RH
8136 [(const_int 0)]
8137 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
6ec6d558 8138
e075ae69
RH
8139(define_insn "x86_shld_1"
8140 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
8141 (ior:SI (ashift:SI (match_dup 0)
8142 (match_operand:QI 2 "nonmemory_operand" "I,c"))
8143 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
8144 (minus:QI (const_int 32) (match_dup 2)))))
8145 (clobber (reg:CC 17))]
6ec6d558 8146 ""
e075ae69
RH
8147 "@
8148 shld{l}\\t{%2, %1, %0|%0, %1, %2}
8149 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
8150 [(set_attr "type" "ishift")
6ef67412
JH
8151 (set_attr "prefix_0f" "1")
8152 (set_attr "mode" "SI")
e075ae69 8153 (set_attr "pent_pair" "np")
309ada50 8154 (set_attr "athlon_decode" "vector")
e075ae69
RH
8155 (set_attr "ppro_uops" "few")])
8156
8157(define_expand "x86_shift_adj_1"
16189740
RH
8158 [(set (reg:CCZ 17)
8159 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8160 (const_int 32))
8161 (const_int 0)))
e075ae69 8162 (set (match_operand:SI 0 "register_operand" "")
16189740 8163 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
8164 (match_operand:SI 1 "register_operand" "")
8165 (match_dup 0)))
8166 (set (match_dup 1)
16189740 8167 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
8168 (match_operand:SI 3 "register_operand" "r")
8169 (match_dup 1)))]
8170 "TARGET_CMOVE"
6ec6d558
JH
8171 "")
8172
e075ae69
RH
8173(define_expand "x86_shift_adj_2"
8174 [(use (match_operand:SI 0 "register_operand" ""))
8175 (use (match_operand:SI 1 "register_operand" ""))
8176 (use (match_operand:QI 2 "register_operand" ""))]
886c62d1 8177 ""
e075ae69
RH
8178 "
8179{
8180 rtx label = gen_label_rtx ();
8181 rtx tmp;
886c62d1 8182
16189740 8183 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
886c62d1 8184
16189740 8185 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
8186 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8187 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8188 gen_rtx_LABEL_REF (VOIDmode, label),
8189 pc_rtx);
8190 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8191 JUMP_LABEL (tmp) = label;
886c62d1 8192
e075ae69
RH
8193 emit_move_insn (operands[0], operands[1]);
8194 emit_move_insn (operands[1], const0_rtx);
886c62d1 8195
e075ae69
RH
8196 emit_label (label);
8197 LABEL_NUSES (label) = 1;
56c0e8fa
JVA
8198
8199 DONE;
8200}")
8201
d525dfdf
JH
8202(define_expand "ashlsi3"
8203 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8204 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
8205 (match_operand:QI 2 "nonmemory_operand" "")))
8206 (clobber (reg:CC 17))]
8207 ""
8208 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
8209
8210(define_insn "*ashlsi3_1"
e075ae69
RH
8211 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8212 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
8213 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8214 (clobber (reg:CC 17))]
d525dfdf 8215 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
2ae0f82c
SC
8216 "*
8217{
e075ae69
RH
8218 switch (get_attr_type (insn))
8219 {
8220 case TYPE_ALU:
8221 if (operands[2] != const1_rtx)
8222 abort ();
8223 if (!rtx_equal_p (operands[0], operands[1]))
8224 abort ();
8225 return \"add{l}\\t{%0, %0|%0, %0}\";
2ae0f82c 8226
e075ae69 8227 case TYPE_LEA:
3d117b30 8228 return \"#\";
2ae0f82c 8229
e075ae69
RH
8230 default:
8231 if (REG_P (operands[2]))
8232 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
8bad7136
JL
8233 else if (GET_CODE (operands[2]) == CONST_INT
8234 && INTVAL (operands[2]) == 1
8235 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8236 return \"sal{l}\\t%0\";
e075ae69
RH
8237 else
8238 return \"sal{l}\\t{%2, %0|%0, %2}\";
8239 }
8240}"
8241 [(set (attr "type")
8242 (cond [(eq_attr "alternative" "1")
8243 (const_string "lea")
8244 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8245 (const_int 0))
8246 (match_operand 0 "register_operand" ""))
8247 (match_operand 2 "const1_operand" ""))
8248 (const_string "alu")
8249 ]
6ef67412
JH
8250 (const_string "ishift")))
8251 (set_attr "mode" "SI")])
e075ae69 8252
1c27d4b2
JH
8253;; Convert lea to the lea pattern to avoid flags dependency.
8254(define_split
58787064
JH
8255 [(set (match_operand 0 "register_operand" "")
8256 (ashift (match_operand 1 "register_operand" "")
ca4ae08d 8257 (match_operand:QI 2 "const_int_operand" "")))
1c27d4b2 8258 (clobber (reg:CC 17))]
abe24fb3
JH
8259 "reload_completed
8260 && true_regnum (operands[0]) != true_regnum (operands[1])"
58787064
JH
8261 [(const_int 0)]
8262 "
8263{
8264 rtx pat;
8265 operands[0] = gen_lowpart (SImode, operands[0]);
8266 operands[1] = gen_lowpart (Pmode, operands[1]);
8267 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
8268 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
8269 if (Pmode != SImode)
8270 pat = gen_rtx_SUBREG (SImode, pat, 0);
8271 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
8272 DONE;
8273}")
1c27d4b2 8274
28cefcd2
BS
8275;; This pattern can't accept a variable shift count, since shifts by
8276;; zero don't affect the flags. We assume that shifts by constant
8277;; zero are optimized away.
2c873473 8278(define_insn "*ashlsi3_cmp"
16189740
RH
8279 [(set (reg 17)
8280 (compare
e075ae69 8281 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
28cefcd2 8282 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
8283 (const_int 0)))
8284 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8285 (ashift:SI (match_dup 1) (match_dup 2)))]
9076b9c1 8286 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8287 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
886c62d1
JVA
8288 "*
8289{
e075ae69 8290 switch (get_attr_type (insn))
886c62d1 8291 {
e075ae69
RH
8292 case TYPE_ALU:
8293 if (operands[2] != const1_rtx)
8294 abort ();
8295 return \"add{l}\\t{%0, %0|%0, %0}\";
886c62d1 8296
e075ae69
RH
8297 default:
8298 if (REG_P (operands[2]))
8299 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
8bad7136
JL
8300 else if (GET_CODE (operands[2]) == CONST_INT
8301 && INTVAL (operands[2]) == 1
8302 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8303 return \"sal{l}\\t%0\";
e075ae69
RH
8304 else
8305 return \"sal{l}\\t{%2, %0|%0, %2}\";
56c0e8fa 8306 }
e075ae69
RH
8307}"
8308 [(set (attr "type")
8309 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8310 (const_int 0))
8311 (match_operand 0 "register_operand" ""))
8312 (match_operand 2 "const1_operand" ""))
8313 (const_string "alu")
8314 ]
6ef67412
JH
8315 (const_string "ishift")))
8316 (set_attr "mode" "SI")])
e075ae69 8317
d525dfdf
JH
8318(define_expand "ashlhi3"
8319 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8320 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
8321 (match_operand:QI 2 "nonmemory_operand" "")))
8322 (clobber (reg:CC 17))]
d9f32422 8323 "TARGET_HIMODE_MATH"
d525dfdf
JH
8324 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
8325
58787064
JH
8326(define_insn "*ashlhi3_1_lea"
8327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8328 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
8329 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8330 (clobber (reg:CC 17))]
8331 "!TARGET_PARTIAL_REG_STALL
8332 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8333 "*
8334{
8335 switch (get_attr_type (insn))
8336 {
8337 case TYPE_LEA:
8338 return \"#\";
8339 case TYPE_ALU:
8340 if (operands[2] != const1_rtx)
8341 abort ();
8342 return \"add{w}\\t{%0, %0|%0, %0}\";
8343
8344 default:
8345 if (REG_P (operands[2]))
8346 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8347 else if (GET_CODE (operands[2]) == CONST_INT
8348 && INTVAL (operands[2]) == 1
8349 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8350 return \"sal{w}\\t%0\";
8351 else
8352 return \"sal{w}\\t{%2, %0|%0, %2}\";
8353 }
8354}"
8355 [(set (attr "type")
8356 (cond [(eq_attr "alternative" "1")
8357 (const_string "lea")
8358 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8359 (const_int 0))
8360 (match_operand 0 "register_operand" ""))
8361 (match_operand 2 "const1_operand" ""))
8362 (const_string "alu")
8363 ]
8364 (const_string "ishift")))
8365 (set_attr "mode" "HI,SI")])
8366
d525dfdf 8367(define_insn "*ashlhi3_1"
e075ae69
RH
8368 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8369 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8370 (match_operand:QI 2 "nonmemory_operand" "cI")))
8371 (clobber (reg:CC 17))]
58787064
JH
8372 "TARGET_PARTIAL_REG_STALL
8373 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
56c0e8fa
JVA
8374 "*
8375{
e075ae69
RH
8376 switch (get_attr_type (insn))
8377 {
8378 case TYPE_ALU:
8379 if (operands[2] != const1_rtx)
8380 abort ();
8381 return \"add{w}\\t{%0, %0|%0, %0}\";
886c62d1 8382
e075ae69
RH
8383 default:
8384 if (REG_P (operands[2]))
8385 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8bad7136
JL
8386 else if (GET_CODE (operands[2]) == CONST_INT
8387 && INTVAL (operands[2]) == 1
8388 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8389 return \"sal{w}\\t%0\";
e075ae69
RH
8390 else
8391 return \"sal{w}\\t{%2, %0|%0, %2}\";
8392 }
8393}"
8394 [(set (attr "type")
8395 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8396 (const_int 0))
8397 (match_operand 0 "register_operand" ""))
8398 (match_operand 2 "const1_operand" ""))
8399 (const_string "alu")
8400 ]
6ef67412
JH
8401 (const_string "ishift")))
8402 (set_attr "mode" "HI")])
bb62e19a 8403
28cefcd2
BS
8404;; This pattern can't accept a variable shift count, since shifts by
8405;; zero don't affect the flags. We assume that shifts by constant
8406;; zero are optimized away.
2c873473 8407(define_insn "*ashlhi3_cmp"
16189740
RH
8408 [(set (reg 17)
8409 (compare
e075ae69 8410 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
28cefcd2 8411 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
8412 (const_int 0)))
8413 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8414 (ashift:HI (match_dup 1) (match_dup 2)))]
9076b9c1 8415 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8416 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
886c62d1
JVA
8417 "*
8418{
e075ae69
RH
8419 switch (get_attr_type (insn))
8420 {
8421 case TYPE_ALU:
8422 if (operands[2] != const1_rtx)
8423 abort ();
8424 return \"add{w}\\t{%0, %0|%0, %0}\";
886c62d1 8425
e075ae69
RH
8426 default:
8427 if (REG_P (operands[2]))
8428 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8bad7136
JL
8429 else if (GET_CODE (operands[2]) == CONST_INT
8430 && INTVAL (operands[2]) == 1
8431 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8432 return \"sal{w}\\t%0\";
e075ae69
RH
8433 else
8434 return \"sal{w}\\t{%2, %0|%0, %2}\";
8435 }
8436}"
8437 [(set (attr "type")
8438 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8439 (const_int 0))
8440 (match_operand 0 "register_operand" ""))
8441 (match_operand 2 "const1_operand" ""))
8442 (const_string "alu")
8443 ]
6ef67412
JH
8444 (const_string "ishift")))
8445 (set_attr "mode" "HI")])
e075ae69 8446
d525dfdf
JH
8447(define_expand "ashlqi3"
8448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8449 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
8450 (match_operand:QI 2 "nonmemory_operand" "")))
8451 (clobber (reg:CC 17))]
d9f32422 8452 "TARGET_QIMODE_MATH"
d525dfdf
JH
8453 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
8454
e075ae69 8455;; %%% Potential partial reg stall on alternative 2. What to do?
58787064
JH
8456
8457(define_insn "*ashlqi3_1_lea"
8458 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
8459 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
91f9a498 8460 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
58787064
JH
8461 (clobber (reg:CC 17))]
8462 "!TARGET_PARTIAL_REG_STALL
8463 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8464 "*
8465{
8466 switch (get_attr_type (insn))
8467 {
8468 case TYPE_LEA:
8469 return \"#\";
8470 case TYPE_ALU:
8471 if (operands[2] != const1_rtx)
8472 abort ();
1a06f5fe 8473 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
58787064
JH
8474 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8475 else
8476 return \"add{b}\\t{%0, %0|%0, %0}\";
8477
8478 default:
8479 if (REG_P (operands[2]))
8480 {
8481 if (get_attr_mode (insn) == MODE_SI)
8482 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
8483 else
8484 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8485 }
8486 else if (GET_CODE (operands[2]) == CONST_INT
8487 && INTVAL (operands[2]) == 1
8488 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8489 {
8490 if (get_attr_mode (insn) == MODE_SI)
8491 return \"sal{l}\\t%0\";
8492 else
8493 return \"sal{b}\\t%0\";
8494 }
8495 else
8496 {
8497 if (get_attr_mode (insn) == MODE_SI)
8498 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8499 else
8500 return \"sal{b}\\t{%2, %0|%0, %2}\";
8501 }
8502 }
8503}"
8504 [(set (attr "type")
8505 (cond [(eq_attr "alternative" "2")
8506 (const_string "lea")
8507 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8508 (const_int 0))
8509 (match_operand 0 "register_operand" ""))
8510 (match_operand 2 "const1_operand" ""))
8511 (const_string "alu")
8512 ]
8513 (const_string "ishift")))
8514 (set_attr "mode" "QI,SI,SI")])
8515
d525dfdf
JH
8516(define_insn "*ashlqi3_1"
8517 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
e075ae69
RH
8518 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8519 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8520 (clobber (reg:CC 17))]
58787064
JH
8521 "TARGET_PARTIAL_REG_STALL
8522 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1
JVA
8523 "*
8524{
e075ae69
RH
8525 switch (get_attr_type (insn))
8526 {
8527 case TYPE_ALU:
8528 if (operands[2] != const1_rtx)
8529 abort ();
1a06f5fe 8530 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
e075ae69
RH
8531 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8532 else
8533 return \"add{b}\\t{%0, %0|%0, %0}\";
886c62d1 8534
e075ae69
RH
8535 default:
8536 if (REG_P (operands[2]))
8537 {
1a06f5fe 8538 if (get_attr_mode (insn) == MODE_SI)
f6fbeda8 8539 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
e075ae69
RH
8540 else
8541 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8542 }
8bad7136
JL
8543 else if (GET_CODE (operands[2]) == CONST_INT
8544 && INTVAL (operands[2]) == 1
8545 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8546 {
1a06f5fe 8547 if (get_attr_mode (insn) == MODE_SI)
8bad7136
JL
8548 return \"sal{l}\\t%0\";
8549 else
8550 return \"sal{b}\\t%0\";
8551 }
e075ae69
RH
8552 else
8553 {
1a06f5fe 8554 if (get_attr_mode (insn) == MODE_SI)
f6fbeda8 8555 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
e075ae69
RH
8556 else
8557 return \"sal{b}\\t{%2, %0|%0, %2}\";
8558 }
8559 }
8560}"
8561 [(set (attr "type")
8562 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8563 (const_int 0))
8564 (match_operand 0 "register_operand" ""))
8565 (match_operand 2 "const1_operand" ""))
8566 (const_string "alu")
8567 ]
6ef67412
JH
8568 (const_string "ishift")))
8569 (set_attr "mode" "QI,SI")])
e075ae69 8570
28cefcd2
BS
8571;; This pattern can't accept a variable shift count, since shifts by
8572;; zero don't affect the flags. We assume that shifts by constant
8573;; zero are optimized away.
2c873473 8574(define_insn "*ashlqi3_cmp"
16189740
RH
8575 [(set (reg 17)
8576 (compare
e075ae69 8577 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
28cefcd2 8578 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69
RH
8579 (const_int 0)))
8580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8581 (ashift:QI (match_dup 1) (match_dup 2)))]
9076b9c1 8582 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8583 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
886c62d1
JVA
8584 "*
8585{
e075ae69
RH
8586 switch (get_attr_type (insn))
8587 {
8588 case TYPE_ALU:
8589 if (operands[2] != const1_rtx)
8590 abort ();
8591 return \"add{b}\\t{%0, %0|%0, %0}\";
8592
8593 default:
8594 if (REG_P (operands[2]))
8595 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8bad7136
JL
8596 else if (GET_CODE (operands[2]) == CONST_INT
8597 && INTVAL (operands[2]) == 1
8598 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8599 return \"sal{b}\\t%0\";
e075ae69
RH
8600 else
8601 return \"sal{b}\\t{%2, %0|%0, %2}\";
8602 }
8603}"
8604 [(set (attr "type")
8605 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8606 (const_int 0))
8607 (match_operand 0 "register_operand" ""))
8608 (match_operand 2 "const1_operand" ""))
8609 (const_string "alu")
8610 ]
6ef67412
JH
8611 (const_string "ishift")))
8612 (set_attr "mode" "QI")])
886c62d1
JVA
8613
8614;; See comment above `ashldi3' about how this works.
8615
e075ae69
RH
8616(define_expand "ashrdi3"
8617 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8618 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8619 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8620 (clobber (reg:CC 17))])]
56c0e8fa
JVA
8621 ""
8622 "
8623{
e075ae69 8624 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
56c0e8fa 8625 {
e075ae69
RH
8626 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
8627 DONE;
56c0e8fa 8628 }
2ae0f82c
SC
8629}")
8630
e075ae69
RH
8631(define_insn "ashrdi3_1"
8632 [(set (match_operand:DI 0 "register_operand" "=r")
8633 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8634 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8635 (clobber (match_scratch:SI 3 "=&r"))
8636 (clobber (reg:CC 17))]
8637 "TARGET_CMOVE"
8638 "#"
8639 [(set_attr "type" "multi")])
886c62d1 8640
e075ae69
RH
8641(define_insn "*ashrdi3_2"
8642 [(set (match_operand:DI 0 "register_operand" "=r")
8643 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8644 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8645 (clobber (reg:CC 17))]
56c0e8fa 8646 ""
e075ae69
RH
8647 "#"
8648 [(set_attr "type" "multi")])
886c62d1 8649
e075ae69
RH
8650(define_split
8651 [(set (match_operand:DI 0 "register_operand" "")
8652 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8653 (match_operand:QI 2 "nonmemory_operand" "")))
8654 (clobber (match_scratch:SI 3 ""))
8655 (clobber (reg:CC 17))]
d7a29404 8656 "TARGET_CMOVE && reload_completed"
e075ae69
RH
8657 [(const_int 0)]
8658 "ix86_split_ashrdi (operands, operands[3]); DONE;")
886c62d1 8659
e075ae69
RH
8660(define_split
8661 [(set (match_operand:DI 0 "register_operand" "")
8662 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8663 (match_operand:QI 2 "nonmemory_operand" "")))
8664 (clobber (reg:CC 17))]
d7a29404 8665 "reload_completed"
e075ae69
RH
8666 [(const_int 0)]
8667 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
886c62d1 8668
e075ae69
RH
8669(define_insn "x86_shrd_1"
8670 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
8671 (ior:SI (ashiftrt:SI (match_dup 0)
8672 (match_operand:QI 2 "nonmemory_operand" "I,c"))
8673 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
8674 (minus:QI (const_int 32) (match_dup 2)))))
8675 (clobber (reg:CC 17))]
886c62d1 8676 ""
e075ae69
RH
8677 "@
8678 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
8679 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
8680 [(set_attr "type" "ishift")
6ef67412 8681 (set_attr "prefix_0f" "1")
e075ae69 8682 (set_attr "pent_pair" "np")
6ef67412
JH
8683 (set_attr "ppro_uops" "few")
8684 (set_attr "mode" "SI")])
e075ae69
RH
8685
8686(define_expand "x86_shift_adj_3"
8687 [(use (match_operand:SI 0 "register_operand" ""))
8688 (use (match_operand:SI 1 "register_operand" ""))
8689 (use (match_operand:QI 2 "register_operand" ""))]
8690 ""
8691 "
886c62d1 8692{
e075ae69
RH
8693 rtx label = gen_label_rtx ();
8694 rtx tmp;
8695
16189740 8696 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
e075ae69 8697
16189740 8698 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
e075ae69
RH
8699 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8700 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8701 gen_rtx_LABEL_REF (VOIDmode, label),
8702 pc_rtx);
8703 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8704 JUMP_LABEL (tmp) = label;
8705
8706 emit_move_insn (operands[0], operands[1]);
8707 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
8708
8709 emit_label (label);
8710 LABEL_NUSES (label) = 1;
8711
8712 DONE;
886c62d1 8713}")
886c62d1 8714
e075ae69
RH
8715(define_insn "ashrsi3_31"
8716 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
8717 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
8718 (match_operand:SI 2 "const_int_operand" "i,i")))
8719 (clobber (reg:CC 17))]
d525dfdf
JH
8720 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
8721 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
8722 "@
8723 {cltd|cdq}
8724 sar{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
8725 [(set_attr "type" "imovx,ishift")
8726 (set_attr "prefix_0f" "0,*")
8727 (set_attr "length_immediate" "0,*")
8728 (set_attr "modrm" "0,1")
8729 (set_attr "mode" "SI")])
e075ae69 8730
d525dfdf
JH
8731(define_expand "ashrsi3"
8732 [(set (match_operand:SI 0 "nonimmediate_operand" "")
155d8a47 8733 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
d525dfdf
JH
8734 (match_operand:QI 2 "nonmemory_operand" "")))
8735 (clobber (reg:CC 17))]
8736 ""
8737 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
8738
8bad7136
JL
8739(define_insn "*ashrsi3_1_one_bit"
8740 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8741 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8742 (match_operand:QI 2 "const_int_1_operand" "")))
8743 (clobber (reg:CC 17))]
8744 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
8745 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8746 "sar{l}\\t%0"
8747 [(set_attr "type" "ishift")
8748 (set (attr "length")
8749 (if_then_else (match_operand:SI 0 "register_operand" "")
8750 (const_string "2")
8751 (const_string "*")))])
8752
d525dfdf 8753(define_insn "*ashrsi3_1"
e075ae69
RH
8754 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8755 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8756 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8757 (clobber (reg:CC 17))]
d525dfdf 8758 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
e075ae69
RH
8759 "@
8760 sar{l}\\t{%2, %0|%0, %2}
8761 sar{l}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
8762 [(set_attr "type" "ishift")
8763 (set_attr "mode" "SI")])
886c62d1 8764
8bad7136
JL
8765;; This pattern can't accept a variable shift count, since shifts by
8766;; zero don't affect the flags. We assume that shifts by constant
8767;; zero are optimized away.
2c873473 8768(define_insn "*ashrsi3_one_bit_cmp"
8bad7136
JL
8769 [(set (reg 17)
8770 (compare
8771 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8772 (match_operand:QI 2 "const_int_1_operand" ""))
8773 (const_int 0)))
8774 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8775 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 8776 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
8777 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8778 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8779 "sar{l}\\t%0"
8780 [(set_attr "type" "ishift")
8781 (set (attr "length")
8782 (if_then_else (match_operand:SI 0 "register_operand" "")
8783 (const_string "2")
8784 (const_string "*")))])
8785
28cefcd2
BS
8786;; This pattern can't accept a variable shift count, since shifts by
8787;; zero don't affect the flags. We assume that shifts by constant
8788;; zero are optimized away.
2c873473 8789(define_insn "*ashrsi3_cmp"
16189740
RH
8790 [(set (reg 17)
8791 (compare
28cefcd2
BS
8792 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8793 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 8794 (const_int 0)))
28cefcd2 8795 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 8796 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
2c873473 8797 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8798 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
2bed3391 8799 "sar{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
8800 [(set_attr "type" "ishift")
8801 (set_attr "mode" "SI")])
886c62d1 8802
d525dfdf
JH
8803(define_expand "ashrhi3"
8804 [(set (match_operand:HI 0 "nonimmediate_operand" "")
155d8a47 8805 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
d525dfdf
JH
8806 (match_operand:QI 2 "nonmemory_operand" "")))
8807 (clobber (reg:CC 17))]
d9f32422 8808 "TARGET_HIMODE_MATH"
d525dfdf
JH
8809 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
8810
8bad7136
JL
8811(define_insn "*ashrhi3_1_one_bit"
8812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8813 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8814 (match_operand:QI 2 "const_int_1_operand" "")))
8815 (clobber (reg:CC 17))]
8816 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
8817 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8818 "sar{w}\\t%0"
8819 [(set_attr "type" "ishift")
8820 (set (attr "length")
3d117b30 8821 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
8822 (const_string "2")
8823 (const_string "*")))])
8824
d525dfdf 8825(define_insn "*ashrhi3_1"
e075ae69
RH
8826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8827 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8828 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8829 (clobber (reg:CC 17))]
d525dfdf 8830 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
e075ae69
RH
8831 "@
8832 sar{w}\\t{%2, %0|%0, %2}
8833 sar{w}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
8834 [(set_attr "type" "ishift")
8835 (set_attr "mode" "HI")])
886c62d1 8836
8bad7136
JL
8837;; This pattern can't accept a variable shift count, since shifts by
8838;; zero don't affect the flags. We assume that shifts by constant
8839;; zero are optimized away.
2c873473 8840(define_insn "*ashrhi3_one_bit_cmp"
8bad7136
JL
8841 [(set (reg 17)
8842 (compare
8843 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8844 (match_operand:QI 2 "const_int_1_operand" ""))
8845 (const_int 0)))
8846 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8847 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 8848 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
8849 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8850 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8851 "sar{w}\\t%0"
8852 [(set_attr "type" "ishift")
8853 (set (attr "length")
3d117b30 8854 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
8855 (const_string "2")
8856 (const_string "*")))])
8857
28cefcd2
BS
8858;; This pattern can't accept a variable shift count, since shifts by
8859;; zero don't affect the flags. We assume that shifts by constant
8860;; zero are optimized away.
2c873473 8861(define_insn "*ashrhi3_cmp"
16189740
RH
8862 [(set (reg 17)
8863 (compare
28cefcd2
BS
8864 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8865 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 8866 (const_int 0)))
28cefcd2 8867 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 8868 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
2c873473 8869 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8870 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
2bed3391 8871 "sar{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
8872 [(set_attr "type" "ishift")
8873 (set_attr "mode" "HI")])
886c62d1 8874
d525dfdf
JH
8875(define_expand "ashrqi3"
8876 [(set (match_operand:QI 0 "nonimmediate_operand" "")
155d8a47 8877 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
d525dfdf
JH
8878 (match_operand:QI 2 "nonmemory_operand" "")))
8879 (clobber (reg:CC 17))]
d9f32422 8880 "TARGET_QIMODE_MATH"
d525dfdf
JH
8881 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
8882
8bad7136
JL
8883(define_insn "*ashrqi3_1_one_bit"
8884 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8885 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8886 (match_operand:QI 2 "const_int_1_operand" "")))
8887 (clobber (reg:CC 17))]
8888 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
8889 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8890 "sar{b}\\t%0"
8891 [(set_attr "type" "ishift")
8892 (set (attr "length")
3d117b30 8893 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
8894 (const_string "2")
8895 (const_string "*")))])
8896
d525dfdf 8897(define_insn "*ashrqi3_1"
e075ae69
RH
8898 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8899 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8900 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8901 (clobber (reg:CC 17))]
d525dfdf 8902 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
e075ae69
RH
8903 "@
8904 sar{b}\\t{%2, %0|%0, %2}
8905 sar{b}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
8906 [(set_attr "type" "ishift")
8907 (set_attr "mode" "QI")])
886c62d1 8908
8bad7136
JL
8909;; This pattern can't accept a variable shift count, since shifts by
8910;; zero don't affect the flags. We assume that shifts by constant
8911;; zero are optimized away.
2c873473 8912(define_insn "*ashrqi3_one_bit_cmp"
8bad7136
JL
8913 [(set (reg 17)
8914 (compare
8915 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8916 (match_operand:QI 2 "const_int_1_operand" "I"))
8917 (const_int 0)))
8918 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8919 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 8920 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
8921 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8922 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8923 "sar{b}\\t%0"
8924 [(set_attr "type" "ishift")
8925 (set (attr "length")
3d117b30 8926 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
8927 (const_string "2")
8928 (const_string "*")))])
8929
28cefcd2
BS
8930;; This pattern can't accept a variable shift count, since shifts by
8931;; zero don't affect the flags. We assume that shifts by constant
8932;; zero are optimized away.
2c873473 8933(define_insn "*ashrqi3_cmp"
16189740
RH
8934 [(set (reg 17)
8935 (compare
28cefcd2
BS
8936 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8937 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 8938 (const_int 0)))
28cefcd2 8939 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
e075ae69 8940 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
2c873473 8941 "ix86_match_ccmode (insn, CCGOCmode)
16189740 8942 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
2bed3391 8943 "sar{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
8944 [(set_attr "type" "ishift")
8945 (set_attr "mode" "QI")])
886c62d1 8946\f
e075ae69
RH
8947;; Logical shift instructions
8948
8949;; See comment above `ashldi3' about how this works.
8950
8951(define_expand "lshrdi3"
8952 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8954 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8955 (clobber (reg:CC 17))])]
886c62d1 8956 ""
e075ae69 8957 "
886c62d1 8958{
e075ae69 8959 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
886c62d1 8960 {
e075ae69
RH
8961 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
8962 DONE;
886c62d1 8963 }
886c62d1 8964}")
886c62d1 8965
e075ae69
RH
8966(define_insn "lshrdi3_1"
8967 [(set (match_operand:DI 0 "register_operand" "=r")
8968 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8969 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8970 (clobber (match_scratch:SI 3 "=&r"))
8971 (clobber (reg:CC 17))]
1e07edd3 8972 "!TARGET_64BIT && TARGET_CMOVE"
e075ae69
RH
8973 "#"
8974 [(set_attr "type" "multi")])
886c62d1 8975
e075ae69
RH
8976(define_insn "*lshrdi3_2"
8977 [(set (match_operand:DI 0 "register_operand" "=r")
8978 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8979 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8980 (clobber (reg:CC 17))]
1e07edd3 8981 "!TARGET_64BIT"
e075ae69
RH
8982 "#"
8983 [(set_attr "type" "multi")])
886c62d1 8984
e075ae69
RH
8985(define_split
8986 [(set (match_operand:DI 0 "register_operand" "")
8987 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8988 (match_operand:QI 2 "nonmemory_operand" "")))
8989 (clobber (match_scratch:SI 3 ""))
8990 (clobber (reg:CC 17))]
1e07edd3 8991 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
e075ae69
RH
8992 [(const_int 0)]
8993 "ix86_split_lshrdi (operands, operands[3]); DONE;")
886c62d1 8994
e075ae69
RH
8995(define_split
8996 [(set (match_operand:DI 0 "register_operand" "")
8997 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8998 (match_operand:QI 2 "nonmemory_operand" "")))
8999 (clobber (reg:CC 17))]
1e07edd3 9000 "!TARGET_64BIT && reload_completed"
e075ae69
RH
9001 [(const_int 0)]
9002 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
886c62d1 9003
d525dfdf
JH
9004(define_expand "lshrsi3"
9005 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9006 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9007 (match_operand:QI 2 "nonmemory_operand" "")))
9008 (clobber (reg:CC 17))]
9009 ""
9010 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
9011
8bad7136
JL
9012(define_insn "*lshrsi3_1_one_bit"
9013 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9014 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9015 (match_operand:QI 2 "const_int_1_operand" "")))
9016 (clobber (reg:CC 17))]
9017 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
9018 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9019 "shr{l}\\t%0"
9020 [(set_attr "type" "ishift")
9021 (set (attr "length")
9022 (if_then_else (match_operand:SI 0 "register_operand" "")
9023 (const_string "2")
9024 (const_string "*")))])
9025
d525dfdf 9026(define_insn "*lshrsi3_1"
e075ae69
RH
9027 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
9028 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9029 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9030 (clobber (reg:CC 17))]
d525dfdf 9031 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69
RH
9032 "@
9033 shr{l}\\t{%2, %0|%0, %2}
9034 shr{l}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9035 [(set_attr "type" "ishift")
9036 (set_attr "mode" "SI")])
886c62d1 9037
8bad7136
JL
9038;; This pattern can't accept a variable shift count, since shifts by
9039;; zero don't affect the flags. We assume that shifts by constant
9040;; zero are optimized away.
2c873473 9041(define_insn "*lshrsi3_one_bit_cmp"
8bad7136
JL
9042 [(set (reg 17)
9043 (compare
9044 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9045 (match_operand:QI 2 "const_int_1_operand" ""))
9046 (const_int 0)))
9047 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9048 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 9049 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
9050 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
9051 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
9052 "shr{l}\\t%0"
9053 [(set_attr "type" "ishift")
9054 (set (attr "length")
9055 (if_then_else (match_operand:SI 0 "register_operand" "")
9056 (const_string "2")
9057 (const_string "*")))])
9058
28cefcd2
BS
9059;; This pattern can't accept a variable shift count, since shifts by
9060;; zero don't affect the flags. We assume that shifts by constant
9061;; zero are optimized away.
2c873473 9062(define_insn "*lshrsi3_cmp"
16189740
RH
9063 [(set (reg 17)
9064 (compare
28cefcd2
BS
9065 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9066 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 9067 (const_int 0)))
28cefcd2 9068 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
e075ae69 9069 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
9076b9c1 9070 "ix86_match_ccmode (insn, CCGOCmode)
16189740 9071 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
2bed3391 9072 "shr{l}\\t{%2, %0|%0, %2}"
6ef67412
JH
9073 [(set_attr "type" "ishift")
9074 (set_attr "mode" "SI")])
886c62d1 9075
d525dfdf
JH
9076(define_expand "lshrhi3"
9077 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9078 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
9079 (match_operand:QI 2 "nonmemory_operand" "")))
9080 (clobber (reg:CC 17))]
d9f32422 9081 "TARGET_HIMODE_MATH"
d525dfdf
JH
9082 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
9083
8bad7136
JL
9084(define_insn "*lshrhi3_1_one_bit"
9085 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9086 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9087 (match_operand:QI 2 "const_int_1_operand" "")))
9088 (clobber (reg:CC 17))]
9089 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
9090 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9091 "shr{w}\\t%0"
9092 [(set_attr "type" "ishift")
9093 (set (attr "length")
3d117b30 9094 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9095 (const_string "2")
9096 (const_string "*")))])
9097
d525dfdf 9098(define_insn "*lshrhi3_1"
e075ae69
RH
9099 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
9100 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
9101 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9102 (clobber (reg:CC 17))]
d525dfdf 9103 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
e075ae69
RH
9104 "@
9105 shr{w}\\t{%2, %0|%0, %2}
9106 shr{w}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9107 [(set_attr "type" "ishift")
9108 (set_attr "mode" "HI")])
886c62d1 9109
8bad7136
JL
9110;; This pattern can't accept a variable shift count, since shifts by
9111;; zero don't affect the flags. We assume that shifts by constant
9112;; zero are optimized away.
2c873473 9113(define_insn "*lshrhi3_one_bit_cmp"
8bad7136
JL
9114 [(set (reg 17)
9115 (compare
9116 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9117 (match_operand:QI 2 "const_int_1_operand" ""))
9118 (const_int 0)))
9119 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9120 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 9121 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
9122 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
9123 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
9124 "shr{w}\\t%0"
9125 [(set_attr "type" "ishift")
9126 (set (attr "length")
9127 (if_then_else (match_operand:SI 0 "register_operand" "")
9128 (const_string "2")
9129 (const_string "*")))])
9130
28cefcd2
BS
9131;; This pattern can't accept a variable shift count, since shifts by
9132;; zero don't affect the flags. We assume that shifts by constant
9133;; zero are optimized away.
2c873473 9134(define_insn "*lshrhi3_cmp"
16189740
RH
9135 [(set (reg 17)
9136 (compare
28cefcd2
BS
9137 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9138 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 9139 (const_int 0)))
28cefcd2 9140 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
e075ae69 9141 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
9076b9c1 9142 "ix86_match_ccmode (insn, CCGOCmode)
16189740 9143 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
2bed3391 9144 "shr{w}\\t{%2, %0|%0, %2}"
6ef67412
JH
9145 [(set_attr "type" "ishift")
9146 (set_attr "mode" "HI")])
886c62d1 9147
d525dfdf
JH
9148(define_expand "lshrqi3"
9149 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9150 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
9151 (match_operand:QI 2 "nonmemory_operand" "")))
9152 (clobber (reg:CC 17))]
d9f32422 9153 "TARGET_QIMODE_MATH"
d525dfdf
JH
9154 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
9155
8bad7136
JL
9156(define_insn "*lshrqi3_1_one_bit"
9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9158 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9159 (match_operand:QI 2 "const_int_1_operand" "")))
9160 (clobber (reg:CC 17))]
9161 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
9162 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9163 "shr{b}\\t%0"
9164 [(set_attr "type" "ishift")
9165 (set (attr "length")
3d117b30 9166 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9167 (const_string "2")
9168 (const_string "*")))])
9169
d525dfdf 9170(define_insn "*lshrqi3_1"
e075ae69
RH
9171 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9172 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9174 (clobber (reg:CC 17))]
d525dfdf 9175 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
e075ae69
RH
9176 "@
9177 shr{b}\\t{%2, %0|%0, %2}
9178 shr{b}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9179 [(set_attr "type" "ishift")
9180 (set_attr "mode" "QI")])
886c62d1 9181
8bad7136
JL
9182;; This pattern can't accept a variable shift count, since shifts by
9183;; zero don't affect the flags. We assume that shifts by constant
9184;; zero are optimized away.
2c873473 9185(define_insn "*lshrqi2_one_bit_cmp"
8bad7136
JL
9186 [(set (reg 17)
9187 (compare
9188 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9189 (match_operand:QI 2 "const_int_1_operand" ""))
9190 (const_int 0)))
9191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9192 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 9193 "ix86_match_ccmode (insn, CCGOCmode)
8bad7136
JL
9194 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
9195 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
9196 "shr{b}\\t%0"
9197 [(set_attr "type" "ishift")
9198 (set (attr "length")
9199 (if_then_else (match_operand:SI 0 "register_operand" "")
9200 (const_string "2")
9201 (const_string "*")))])
9202
28cefcd2
BS
9203;; This pattern can't accept a variable shift count, since shifts by
9204;; zero don't affect the flags. We assume that shifts by constant
9205;; zero are optimized away.
2c873473 9206(define_insn "*lshrqi2_cmp"
16189740
RH
9207 [(set (reg 17)
9208 (compare
28cefcd2
BS
9209 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9210 (match_operand:QI 2 "immediate_operand" "I"))
e075ae69 9211 (const_int 0)))
122ddbf9 9212 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
e075ae69 9213 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
9076b9c1 9214 "ix86_match_ccmode (insn, CCGOCmode)
16189740
RH
9215 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
9216 "shr{b}\\t{%2, %0|%0, %2}"
6ef67412
JH
9217 [(set_attr "type" "ishift")
9218 (set_attr "mode" "QI")])
886c62d1 9219\f
e075ae69 9220;; Rotate instructions
886c62d1 9221
d525dfdf
JH
9222(define_expand "rotlsi3"
9223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9224 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
9225 (match_operand:QI 2 "nonmemory_operand" "")))
9226 (clobber (reg:CC 17))]
9227 ""
9228 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
9229
8bad7136
JL
9230(define_insn "*rotlsi3_1_one_bit"
9231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9232 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9233 (match_operand:QI 2 "const_int_1_operand" "")))
9234 (clobber (reg:CC 17))]
9235 "ix86_binary_operator_ok (ROTATE, SImode, operands)
9236 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9237 "rol{l}\\t%0"
9238 [(set_attr "type" "ishift")
9239 (set (attr "length")
9240 (if_then_else (match_operand:SI 0 "register_operand" "")
9241 (const_string "2")
9242 (const_string "*")))])
9243
d525dfdf 9244(define_insn "*rotlsi3_1"
e075ae69
RH
9245 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
9246 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9247 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9248 (clobber (reg:CC 17))]
d525dfdf 9249 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
e075ae69
RH
9250 "@
9251 rol{l}\\t{%2, %0|%0, %2}
9252 rol{l}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9253 [(set_attr "type" "ishift")
9254 (set_attr "mode" "SI")])
b4ac57ab 9255
d525dfdf
JH
9256(define_expand "rotlhi3"
9257 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9258 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
9259 (match_operand:QI 2 "nonmemory_operand" "")))
9260 (clobber (reg:CC 17))]
d9f32422 9261 "TARGET_HIMODE_MATH"
d525dfdf
JH
9262 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
9263
8bad7136
JL
9264(define_insn "*rotlhi3_1_one_bit"
9265 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9266 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9267 (match_operand:QI 2 "const_int_1_operand" "")))
9268 (clobber (reg:CC 17))]
9269 "ix86_binary_operator_ok (ROTATE, HImode, operands)
9270 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9271 "rol{w}\\t%0"
9272 [(set_attr "type" "ishift")
9273 (set (attr "length")
3d117b30 9274 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9275 (const_string "2")
9276 (const_string "*")))])
9277
d525dfdf 9278(define_insn "*rotlhi3_1"
e075ae69
RH
9279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
9280 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
9281 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9282 (clobber (reg:CC 17))]
d525dfdf 9283 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
e075ae69
RH
9284 "@
9285 rol{w}\\t{%2, %0|%0, %2}
9286 rol{w}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9287 [(set_attr "type" "ishift")
9288 (set_attr "mode" "HI")])
47af5d50 9289
d525dfdf
JH
9290(define_expand "rotlqi3"
9291 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9292 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
9293 (match_operand:QI 2 "nonmemory_operand" "")))
9294 (clobber (reg:CC 17))]
d9f32422 9295 "TARGET_QIMODE_MATH"
d525dfdf
JH
9296 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
9297
8bad7136
JL
9298(define_insn "*rotlqi3_1_one_bit"
9299 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9300 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9301 (match_operand:QI 2 "const_int_1_operand" "")))
9302 (clobber (reg:CC 17))]
9303 "ix86_binary_operator_ok (ROTATE, QImode, operands)
9304 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9305 "rol{b}\\t%0"
9306 [(set_attr "type" "ishift")
9307 (set (attr "length")
3d117b30 9308 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9309 (const_string "2")
9310 (const_string "*")))])
9311
d525dfdf 9312(define_insn "*rotlqi3_1"
e075ae69
RH
9313 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9314 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9315 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9316 (clobber (reg:CC 17))]
d525dfdf 9317 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
e075ae69
RH
9318 "@
9319 rol{b}\\t{%2, %0|%0, %2}
9320 rol{b}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9321 [(set_attr "type" "ishift")
9322 (set_attr "mode" "QI")])
47af5d50 9323
d525dfdf
JH
9324(define_expand "rotrsi3"
9325 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9326 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
9327 (match_operand:QI 2 "nonmemory_operand" "")))
9328 (clobber (reg:CC 17))]
9329 ""
9330 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
9331
8bad7136
JL
9332(define_insn "*rotrsi3_1_one_bit"
9333 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9334 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9335 (match_operand:QI 2 "const_int_1_operand" "")))
9336 (clobber (reg:CC 17))]
9337 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
9338 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9339 "ror{l}\\t%0"
9340 [(set_attr "type" "ishift")
9341 (set (attr "length")
9342 (if_then_else (match_operand:SI 0 "register_operand" "")
9343 (const_string "2")
9344 (const_string "*")))])
9345
d525dfdf 9346(define_insn "*rotrsi3_1"
e075ae69
RH
9347 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
9348 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9349 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9350 (clobber (reg:CC 17))]
d525dfdf 9351 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
e075ae69
RH
9352 "@
9353 ror{l}\\t{%2, %0|%0, %2}
9354 ror{l}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9355 [(set_attr "type" "ishift")
9356 (set_attr "mode" "SI")])
47af5d50 9357
d525dfdf
JH
9358(define_expand "rotrhi3"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9360 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
9361 (match_operand:QI 2 "nonmemory_operand" "")))
9362 (clobber (reg:CC 17))]
d9f32422 9363 "TARGET_HIMODE_MATH"
d525dfdf
JH
9364 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
9365
8bad7136
JL
9366(define_insn "*rotrhi3_one_bit"
9367 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9368 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9369 (match_operand:QI 2 "const_int_1_operand" "")))
9370 (clobber (reg:CC 17))]
9371 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
9372 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9373 "ror{w}\\t%0"
9374 [(set_attr "type" "ishift")
9375 (set (attr "length")
3d117b30 9376 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9377 (const_string "2")
9378 (const_string "*")))])
9379
d525dfdf 9380(define_insn "*rotrhi3"
e075ae69
RH
9381 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
9382 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
9383 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9384 (clobber (reg:CC 17))]
d525dfdf 9385 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
e075ae69
RH
9386 "@
9387 ror{w}\\t{%2, %0|%0, %2}
9388 ror{w}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9389 [(set_attr "type" "ishift")
9390 (set_attr "mode" "HI")])
a199fdd6 9391
d525dfdf
JH
9392(define_expand "rotrqi3"
9393 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9394 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
9395 (match_operand:QI 2 "nonmemory_operand" "")))
9396 (clobber (reg:CC 17))]
d9f32422 9397 "TARGET_QIMODE_MATH"
d525dfdf
JH
9398 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
9399
8bad7136
JL
9400(define_insn "*rotrqi3_1_one_bit"
9401 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9402 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9403 (match_operand:QI 2 "const_int_1_operand" "")))
9404 (clobber (reg:CC 17))]
9405 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
9406 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9407 "ror{b}\\t%0"
9408 [(set_attr "type" "ishift")
9409 (set (attr "length")
3d117b30 9410 (if_then_else (match_operand 0 "register_operand" "")
8bad7136
JL
9411 (const_string "2")
9412 (const_string "*")))])
9413
d525dfdf 9414(define_insn "*rotrqi3_1"
e075ae69
RH
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9416 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9417 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9418 (clobber (reg:CC 17))]
d525dfdf 9419 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
e075ae69
RH
9420 "@
9421 ror{b}\\t{%2, %0|%0, %2}
9422 ror{b}\\t{%b2, %0|%0, %b2}"
6ef67412
JH
9423 [(set_attr "type" "ishift")
9424 (set_attr "mode" "QI")])
e075ae69
RH
9425\f
9426;; Bit set / bit test instructions
a199fdd6 9427
e075ae69
RH
9428(define_expand "extv"
9429 [(set (match_operand:SI 0 "register_operand" "")
9430 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9431 (match_operand:SI 2 "immediate_operand" "")
9432 (match_operand:SI 3 "immediate_operand" "")))]
9433 ""
9434 "
9435{
9436 /* Handle extractions from %ah et al. */
9437 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9438 FAIL;
a199fdd6 9439
e075ae69
RH
9440 /* From mips.md: extract_bit_field doesn't verify that our source
9441 matches the predicate, so check it again here. */
9442 if (! register_operand (operands[1], VOIDmode))
9443 FAIL;
9444}")
a199fdd6 9445
e075ae69
RH
9446(define_expand "extzv"
9447 [(set (match_operand:SI 0 "register_operand" "")
9448 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
9449 (match_operand:SI 2 "immediate_operand" "")
9450 (match_operand:SI 3 "immediate_operand" "")))]
9451 ""
9452 "
9453{
9454 /* Handle extractions from %ah et al. */
9455 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9456 FAIL;
a199fdd6 9457
e075ae69
RH
9458 /* From mips.md: extract_bit_field doesn't verify that our source
9459 matches the predicate, so check it again here. */
9460 if (! register_operand (operands[1], VOIDmode))
9461 FAIL;
9462}")
a199fdd6 9463
e075ae69
RH
9464(define_expand "insv"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9466 (match_operand:SI 1 "immediate_operand" "")
9467 (match_operand:SI 2 "immediate_operand" ""))
9468 (match_operand:SI 3 "register_operand" ""))]
9469 ""
9470 "
9471{
9472 /* Handle extractions from %ah et al. */
9473 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
9474 FAIL;
a199fdd6 9475
e075ae69
RH
9476 /* From mips.md: insert_bit_field doesn't verify that our source
9477 matches the predicate, so check it again here. */
9478 if (! register_operand (operands[0], VOIDmode))
9479 FAIL;
a199fdd6 9480}")
e075ae69
RH
9481
9482;; %%% bts, btr, btc, bt.
886c62d1
JVA
9483\f
9484;; Store-flag instructions.
9485
c572e5ba
JVA
9486;; For all sCOND expanders, also expand the compare or test insn that
9487;; generates cc0. Generate an equality comparison if `seq' or `sne'.
9488
e075ae69
RH
9489;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
9490;; to avoid partial register stalls. Otherwise do things the setcc+movzx
9491;; way, which can later delete the movzx if only QImode is needed.
9492
c572e5ba 9493(define_expand "seq"
e075ae69
RH
9494 [(set (match_operand:SI 0 "register_operand" "")
9495 (eq:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9496 ""
3a3677ff 9497 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
c572e5ba 9498
c572e5ba 9499(define_expand "sne"
e075ae69
RH
9500 [(set (match_operand:SI 0 "register_operand" "")
9501 (ne:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9502 ""
3a3677ff 9503 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
c572e5ba 9504
c572e5ba 9505(define_expand "sgt"
e075ae69
RH
9506 [(set (match_operand:SI 0 "register_operand" "")
9507 (gt:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9508 ""
3a3677ff 9509 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
c572e5ba 9510
c572e5ba 9511(define_expand "sgtu"
e075ae69
RH
9512 [(set (match_operand:SI 0 "register_operand" "")
9513 (gtu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9514 ""
3a3677ff 9515 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
c572e5ba 9516
c572e5ba 9517(define_expand "slt"
e075ae69
RH
9518 [(set (match_operand:SI 0 "register_operand" "")
9519 (lt:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9520 ""
3a3677ff 9521 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
c572e5ba 9522
c572e5ba 9523(define_expand "sltu"
e075ae69
RH
9524 [(set (match_operand:SI 0 "register_operand" "")
9525 (ltu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9526 ""
3a3677ff 9527 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
c572e5ba 9528
c572e5ba 9529(define_expand "sge"
e075ae69
RH
9530 [(set (match_operand:SI 0 "register_operand" "")
9531 (ge:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9532 ""
3a3677ff 9533 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
c572e5ba 9534
c572e5ba 9535(define_expand "sgeu"
e075ae69
RH
9536 [(set (match_operand:SI 0 "register_operand" "")
9537 (geu:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9538 ""
3a3677ff 9539 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
c572e5ba 9540
c572e5ba 9541(define_expand "sle"
e075ae69
RH
9542 [(set (match_operand:SI 0 "register_operand" "")
9543 (le:SI (reg:CC 17) (const_int 0)))]
c572e5ba 9544 ""
3a3677ff 9545 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
c572e5ba 9546
c785c660 9547(define_expand "sleu"
e075ae69
RH
9548 [(set (match_operand:SI 0 "register_operand" "")
9549 (leu:SI (reg:CC 17) (const_int 0)))]
c785c660 9550 ""
3a3677ff
RH
9551 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
9552
9553(define_expand "sunordered"
9554 [(set (match_operand:SI 0 "register_operand" "")
9555 (unordered:SI (reg:CC 17) (const_int 0)))]
0644b628 9556 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9557 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
9558
9559(define_expand "sordered"
9560 [(set (match_operand:SI 0 "register_operand" "")
9561 (ordered:SI (reg:CC 17) (const_int 0)))]
9562 "TARGET_80387"
9563 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
9564
9565(define_expand "suneq"
9566 [(set (match_operand:SI 0 "register_operand" "")
9567 (uneq:SI (reg:CC 17) (const_int 0)))]
0644b628 9568 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9569 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
9570
9571(define_expand "sunge"
9572 [(set (match_operand:SI 0 "register_operand" "")
9573 (unge:SI (reg:CC 17) (const_int 0)))]
0644b628 9574 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9575 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
9576
9577(define_expand "sungt"
9578 [(set (match_operand:SI 0 "register_operand" "")
9579 (ungt:SI (reg:CC 17) (const_int 0)))]
0644b628 9580 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9581 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
9582
9583(define_expand "sunle"
9584 [(set (match_operand:SI 0 "register_operand" "")
9585 (unle:SI (reg:CC 17) (const_int 0)))]
0644b628 9586 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9587 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
9588
9589(define_expand "sunlt"
9590 [(set (match_operand:SI 0 "register_operand" "")
9591 (unlt:SI (reg:CC 17) (const_int 0)))]
0644b628 9592 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9593 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
9594
9595(define_expand "sltgt"
9596 [(set (match_operand:SI 0 "register_operand" "")
9597 (ltgt:SI (reg:CC 17) (const_int 0)))]
0644b628 9598 "TARGET_80387 || TARGET_SSE"
3a3677ff 9599 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
c785c660 9600
e075ae69 9601(define_insn "*setcc_1"
a269a03c 9602 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9076b9c1 9603 (match_operator:QI 1 "ix86_comparison_operator"
e075ae69
RH
9604 [(reg 17) (const_int 0)]))]
9605 ""
9606 "set%C1\\t%0"
6ef67412
JH
9607 [(set_attr "type" "setcc")
9608 (set_attr "mode" "QI")])
a269a03c 9609
bd793c65 9610(define_insn "setcc_2"
e075ae69 9611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9076b9c1 9612 (match_operator:QI 1 "ix86_comparison_operator"
e075ae69
RH
9613 [(reg 17) (const_int 0)]))]
9614 ""
9615 "set%C1\\t%0"
6ef67412
JH
9616 [(set_attr "type" "setcc")
9617 (set_attr "mode" "QI")])
e075ae69 9618
a46d1d38
JH
9619;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
9620;; subsequent logical operations are used to imitate conditional moves.
9621;; 0xffffffff is NaN, but not in normalized form, so we can't represent
9622;; it directly. Futher holding this value in pseudo register might bring
9623;; problem in implicit normalization in spill code.
9624;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
9625;; instructions after reload by splitting the conditional move patterns.
9626
9627(define_insn "*sse_setccsf"
9628 [(set (match_operand:SF 0 "register_operand" "=x")
9629 (match_operator:SF 1 "sse_comparison_operator"
9630 [(match_operand:SF 2 "register_operand" "0")
9631 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
9632 "TARGET_SSE && reload_completed"
9633 "cmp%D1ss\\t{%3, %0|%0, %3}"
9634 [(set_attr "type" "sse")
9635 (set_attr "mode" "SF")])
9636
9637(define_insn "*sse_setccdf"
9638 [(set (match_operand:DF 0 "register_operand" "=Y")
9639 (match_operator:DF 1 "sse_comparison_operator"
9640 [(match_operand:DF 2 "register_operand" "0")
9641 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
9642 "TARGET_SSE2 && reload_completed"
9643 "cmp%D1sd\\t{%3, %0|%0, %3}"
9644 [(set_attr "type" "sse")
9645 (set_attr "mode" "DF")])
886c62d1
JVA
9646\f
9647;; Basic conditional jump instructions.
9648;; We ignore the overflow flag for signed branch instructions.
9649
c572e5ba 9650;; For all bCOND expanders, also expand the compare or test insn that
e075ae69 9651;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
c572e5ba
JVA
9652
9653(define_expand "beq"
e075ae69
RH
9654 [(set (pc)
9655 (if_then_else (match_dup 1)
c572e5ba
JVA
9656 (label_ref (match_operand 0 "" ""))
9657 (pc)))]
9658 ""
3a3677ff 9659 "ix86_expand_branch (EQ, operands[0]); DONE;")
c572e5ba 9660
c572e5ba 9661(define_expand "bne"
e075ae69
RH
9662 [(set (pc)
9663 (if_then_else (match_dup 1)
c572e5ba
JVA
9664 (label_ref (match_operand 0 "" ""))
9665 (pc)))]
9666 ""
3a3677ff 9667 "ix86_expand_branch (NE, operands[0]); DONE;")
886c62d1 9668
c572e5ba 9669(define_expand "bgt"
e075ae69
RH
9670 [(set (pc)
9671 (if_then_else (match_dup 1)
c572e5ba
JVA
9672 (label_ref (match_operand 0 "" ""))
9673 (pc)))]
9674 ""
3a3677ff 9675 "ix86_expand_branch (GT, operands[0]); DONE;")
c572e5ba 9676
c572e5ba 9677(define_expand "bgtu"
e075ae69
RH
9678 [(set (pc)
9679 (if_then_else (match_dup 1)
c572e5ba
JVA
9680 (label_ref (match_operand 0 "" ""))
9681 (pc)))]
9682 ""
3a3677ff 9683 "ix86_expand_branch (GTU, operands[0]); DONE;")
886c62d1 9684
886c62d1 9685(define_expand "blt"
e075ae69
RH
9686 [(set (pc)
9687 (if_then_else (match_dup 1)
886c62d1
JVA
9688 (label_ref (match_operand 0 "" ""))
9689 (pc)))]
9690 ""
3a3677ff 9691 "ix86_expand_branch (LT, operands[0]); DONE;")
886c62d1 9692
c572e5ba 9693(define_expand "bltu"
e075ae69
RH
9694 [(set (pc)
9695 (if_then_else (match_dup 1)
c572e5ba
JVA
9696 (label_ref (match_operand 0 "" ""))
9697 (pc)))]
9698 ""
3a3677ff 9699 "ix86_expand_branch (LTU, operands[0]); DONE;")
c572e5ba 9700
c572e5ba 9701(define_expand "bge"
e075ae69
RH
9702 [(set (pc)
9703 (if_then_else (match_dup 1)
c572e5ba
JVA
9704 (label_ref (match_operand 0 "" ""))
9705 (pc)))]
9706 ""
3a3677ff 9707 "ix86_expand_branch (GE, operands[0]); DONE;")
c572e5ba 9708
c572e5ba 9709(define_expand "bgeu"
e075ae69
RH
9710 [(set (pc)
9711 (if_then_else (match_dup 1)
c572e5ba
JVA
9712 (label_ref (match_operand 0 "" ""))
9713 (pc)))]
9714 ""
3a3677ff 9715 "ix86_expand_branch (GEU, operands[0]); DONE;")
886c62d1 9716
886c62d1 9717(define_expand "ble"
e075ae69
RH
9718 [(set (pc)
9719 (if_then_else (match_dup 1)
886c62d1
JVA
9720 (label_ref (match_operand 0 "" ""))
9721 (pc)))]
9722 ""
3a3677ff 9723 "ix86_expand_branch (LE, operands[0]); DONE;")
886c62d1 9724
c572e5ba 9725(define_expand "bleu"
e075ae69
RH
9726 [(set (pc)
9727 (if_then_else (match_dup 1)
c572e5ba
JVA
9728 (label_ref (match_operand 0 "" ""))
9729 (pc)))]
9730 ""
3a3677ff
RH
9731 "ix86_expand_branch (LEU, operands[0]); DONE;")
9732
9733(define_expand "bunordered"
9734 [(set (pc)
9735 (if_then_else (match_dup 1)
9736 (label_ref (match_operand 0 "" ""))
9737 (pc)))]
0644b628 9738 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9739 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
9740
9741(define_expand "bordered"
9742 [(set (pc)
9743 (if_then_else (match_dup 1)
9744 (label_ref (match_operand 0 "" ""))
9745 (pc)))]
0644b628 9746 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9747 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
9748
9749(define_expand "buneq"
9750 [(set (pc)
9751 (if_then_else (match_dup 1)
9752 (label_ref (match_operand 0 "" ""))
9753 (pc)))]
0644b628 9754 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9755 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
9756
9757(define_expand "bunge"
9758 [(set (pc)
9759 (if_then_else (match_dup 1)
9760 (label_ref (match_operand 0 "" ""))
9761 (pc)))]
0644b628 9762 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9763 "ix86_expand_branch (UNGE, operands[0]); DONE;")
9764
9765(define_expand "bungt"
9766 [(set (pc)
9767 (if_then_else (match_dup 1)
9768 (label_ref (match_operand 0 "" ""))
9769 (pc)))]
0644b628 9770 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9771 "ix86_expand_branch (UNGT, operands[0]); DONE;")
9772
9773(define_expand "bunle"
9774 [(set (pc)
9775 (if_then_else (match_dup 1)
9776 (label_ref (match_operand 0 "" ""))
9777 (pc)))]
0644b628 9778 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9779 "ix86_expand_branch (UNLE, operands[0]); DONE;")
9780
9781(define_expand "bunlt"
9782 [(set (pc)
9783 (if_then_else (match_dup 1)
9784 (label_ref (match_operand 0 "" ""))
9785 (pc)))]
0644b628 9786 "TARGET_80387 || TARGET_SSE"
3a3677ff
RH
9787 "ix86_expand_branch (UNLT, operands[0]); DONE;")
9788
9789(define_expand "bltgt"
9790 [(set (pc)
9791 (if_then_else (match_dup 1)
9792 (label_ref (match_operand 0 "" ""))
9793 (pc)))]
0644b628 9794 "TARGET_80387 || TARGET_SSE"
3a3677ff 9795 "ix86_expand_branch (LTGT, operands[0]); DONE;")
886c62d1 9796
e075ae69
RH
9797(define_insn "*jcc_1"
9798 [(set (pc)
9076b9c1 9799 (if_then_else (match_operator 1 "ix86_comparison_operator"
e075ae69 9800 [(reg 17) (const_int 0)])
6ef67412 9801 (label_ref (match_operand 0 "" ""))
e075ae69
RH
9802 (pc)))]
9803 ""
6ef67412 9804 "j%C1\\t%l0"
e075ae69 9805 [(set_attr "type" "ibr")
6ef67412
JH
9806 (set (attr "prefix_0f")
9807 (if_then_else (and (ge (minus (match_dup 0) (pc))
9808 (const_int -128))
9809 (lt (minus (match_dup 0) (pc))
9810 (const_int 124)))
9811 (const_int 0)
9812 (const_int 1)))])
e075ae69
RH
9813
9814(define_insn "*jcc_2"
9815 [(set (pc)
9076b9c1 9816 (if_then_else (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
9817 [(reg 17) (const_int 0)])
9818 (pc)
6ef67412 9819 (label_ref (match_operand 0 "" ""))))]
e075ae69 9820 ""
6ef67412 9821 "j%c1\\t%l0"
e075ae69 9822 [(set_attr "type" "ibr")
6ef67412
JH
9823 (set (attr "prefix_0f")
9824 (if_then_else (and (ge (minus (match_dup 0) (pc))
9825 (const_int -128))
9826 (lt (minus (match_dup 0) (pc))
9827 (const_int 124)))
9828 (const_int 0)
9829 (const_int 1)))])
e075ae69 9830
3a3677ff
RH
9831;; Define combination compare-and-branch fp compare instructions to use
9832;; during early optimization. Splitting the operation apart early makes
9833;; for bad code when we want to reverse the operation.
9834
9835(define_insn "*fp_jcc_1"
9836 [(set (pc)
9837 (if_then_else (match_operator 0 "comparison_operator"
9838 [(match_operand 1 "register_operand" "f")
9839 (match_operand 2 "register_operand" "f")])
9840 (label_ref (match_operand 3 "" ""))
9841 (pc)))
9842 (clobber (reg:CCFP 18))
9843 (clobber (reg:CCFP 17))]
9844 "TARGET_CMOVE && TARGET_80387
0644b628 9845 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff
RH
9846 && FLOAT_MODE_P (GET_MODE (operands[1]))
9847 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9848 "#")
9849
0644b628
JH
9850(define_insn "*fp_jcc_1_sse"
9851 [(set (pc)
9852 (if_then_else (match_operator 0 "comparison_operator"
9853 [(match_operand 1 "register_operand" "f#x,x#f")
9854 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9855 (label_ref (match_operand 3 "" ""))
9856 (pc)))
9857 (clobber (reg:CCFP 18))
9858 (clobber (reg:CCFP 17))]
9859 "TARGET_80387
9860 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9861 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9862 "#")
9863
9864(define_insn "*fp_jcc_1_sse_only"
9865 [(set (pc)
9866 (if_then_else (match_operator 0 "comparison_operator"
9867 [(match_operand 1 "register_operand" "x")
9868 (match_operand 2 "nonimmediate_operand" "xm")])
9869 (label_ref (match_operand 3 "" ""))
9870 (pc)))
9871 (clobber (reg:CCFP 18))
9872 (clobber (reg:CCFP 17))]
9873 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9874 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9875 "#")
9876
3a3677ff
RH
9877(define_insn "*fp_jcc_2"
9878 [(set (pc)
9879 (if_then_else (match_operator 0 "comparison_operator"
9880 [(match_operand 1 "register_operand" "f")
9881 (match_operand 2 "register_operand" "f")])
9882 (pc)
9883 (label_ref (match_operand 3 "" ""))))
9884 (clobber (reg:CCFP 18))
9885 (clobber (reg:CCFP 17))]
9886 "TARGET_CMOVE && TARGET_80387
0644b628 9887 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
3a3677ff
RH
9888 && FLOAT_MODE_P (GET_MODE (operands[1]))
9889 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9890 "#")
9891
0644b628
JH
9892(define_insn "*fp_jcc_2_sse"
9893 [(set (pc)
9894 (if_then_else (match_operator 0 "comparison_operator"
9895 [(match_operand 1 "register_operand" "f#x,x#f")
9896 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9897 (pc)
9898 (label_ref (match_operand 3 "" ""))))
9899 (clobber (reg:CCFP 18))
9900 (clobber (reg:CCFP 17))]
9901 "TARGET_80387
9902 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9903 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9904 "#")
9905
9906(define_insn "*fp_jcc_2_sse_only"
9907 [(set (pc)
9908 (if_then_else (match_operator 0 "comparison_operator"
9909 [(match_operand 1 "register_operand" "x")
9910 (match_operand 2 "nonimmediate_operand" "xm")])
9911 (pc)
9912 (label_ref (match_operand 3 "" ""))))
9913 (clobber (reg:CCFP 18))
9914 (clobber (reg:CCFP 17))]
9915 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9916 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9917 "#")
9918
3a3677ff
RH
9919(define_insn "*fp_jcc_3"
9920 [(set (pc)
b1cdafbb 9921 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
9922 [(match_operand 1 "register_operand" "f")
9923 (match_operand 2 "nonimmediate_operand" "fm")])
9924 (label_ref (match_operand 3 "" ""))
9925 (pc)))
9926 (clobber (reg:CCFP 18))
9927 (clobber (reg:CCFP 17))
9928 (clobber (match_scratch:HI 4 "=a"))]
9929 "TARGET_80387
9930 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 9931 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
9932 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9933 && SELECT_CC_MODE (GET_CODE (operands[0]),
9934 operands[1], operands[2]) == CCFPmode"
3a3677ff
RH
9935 "#")
9936
9937(define_insn "*fp_jcc_4"
9938 [(set (pc)
b1cdafbb 9939 (if_then_else (match_operator 0 "comparison_operator"
3a3677ff
RH
9940 [(match_operand 1 "register_operand" "f")
9941 (match_operand 2 "nonimmediate_operand" "fm")])
9942 (pc)
9943 (label_ref (match_operand 3 "" ""))))
9944 (clobber (reg:CCFP 18))
9945 (clobber (reg:CCFP 17))
9946 (clobber (match_scratch:HI 4 "=a"))]
9947 "TARGET_80387
9948 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
a940d8bd 9949 && GET_MODE (operands[1]) == GET_MODE (operands[2])
b1cdafbb
JH
9950 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9951 && SELECT_CC_MODE (GET_CODE (operands[0]),
9952 operands[1], operands[2]) == CCFPmode"
3a3677ff
RH
9953 "#")
9954
9955(define_insn "*fp_jcc_5"
9956 [(set (pc)
9957 (if_then_else (match_operator 0 "comparison_operator"
9958 [(match_operand 1 "register_operand" "f")
9959 (match_operand 2 "register_operand" "f")])
9960 (label_ref (match_operand 3 "" ""))
9961 (pc)))
9962 (clobber (reg:CCFP 18))
9963 (clobber (reg:CCFP 17))
9964 (clobber (match_scratch:HI 4 "=a"))]
9965 "TARGET_80387
9966 && FLOAT_MODE_P (GET_MODE (operands[1]))
9967 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9968 "#")
9969
9970(define_insn "*fp_jcc_6"
9971 [(set (pc)
9972 (if_then_else (match_operator 0 "comparison_operator"
9973 [(match_operand 1 "register_operand" "f")
9974 (match_operand 2 "register_operand" "f")])
9975 (pc)
9976 (label_ref (match_operand 3 "" ""))))
9977 (clobber (reg:CCFP 18))
9978 (clobber (reg:CCFP 17))
9979 (clobber (match_scratch:HI 4 "=a"))]
9980 "TARGET_80387
9981 && FLOAT_MODE_P (GET_MODE (operands[1]))
9982 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9983 "#")
9984
9985(define_split
9986 [(set (pc)
9987 (if_then_else (match_operator 0 "comparison_operator"
9988 [(match_operand 1 "register_operand" "")
9989 (match_operand 2 "nonimmediate_operand" "")])
9990 (match_operand 3 "" "")
9991 (match_operand 4 "" "")))
9992 (clobber (reg:CCFP 18))
9993 (clobber (reg:CCFP 17))]
9994 "reload_completed"
9e7adcb3 9995 [(const_int 0)]
3a3677ff
RH
9996 "
9997{
9e7adcb3
JH
9998 ix86_split_fp_branch (operands[0], operands[1], operands[2],
9999 operands[3], operands[4], NULL_RTX);
10000 DONE;
3a3677ff
RH
10001}")
10002
10003(define_split
10004 [(set (pc)
10005 (if_then_else (match_operator 0 "comparison_operator"
10006 [(match_operand 1 "register_operand" "")
10007 (match_operand 2 "nonimmediate_operand" "")])
10008 (match_operand 3 "" "")
10009 (match_operand 4 "" "")))
10010 (clobber (reg:CCFP 18))
10011 (clobber (reg:CCFP 17))
10012 (clobber (match_scratch:HI 5 "=a"))]
10013 "reload_completed"
10014 [(set (pc)
10015 (if_then_else (match_dup 6)
10016 (match_dup 3)
10017 (match_dup 4)))]
10018 "
10019{
9e7adcb3
JH
10020 ix86_split_fp_branch (operands[0], operands[1], operands[2],
10021 operands[3], operands[4], operands[5]);
10022 DONE;
3a3677ff 10023}")
886c62d1
JVA
10024\f
10025;; Unconditional and other jump instructions
10026
10027(define_insn "jump"
10028 [(set (pc)
10029 (label_ref (match_operand 0 "" "")))]
10030 ""
e075ae69 10031 "jmp\\t%l0"
6ef67412 10032 [(set_attr "type" "ibr")])
886c62d1
JVA
10033
10034(define_insn "indirect_jump"
2ae0f82c 10035 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
886c62d1 10036 ""
fb204271 10037 "jmp\\t%A0"
6ef67412
JH
10038 [(set_attr "type" "ibr")
10039 (set_attr "length_immediate" "0")])
4801403e 10040
e075ae69
RH
10041(define_insn "tablejump"
10042 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
10043 (use (label_ref (match_operand 1 "" "")))]
10044 "! flag_pic"
fb204271 10045 "jmp\\t%A0"
6ef67412
JH
10046 [(set_attr "type" "ibr")
10047 (set_attr "length_immediate" "0")])
4801403e 10048
2bb7a0f5
RS
10049;; Implement switch statements when generating PIC code. Switches are
10050;; implemented by `tablejump' when not using -fpic.
e075ae69 10051;;
2bb7a0f5 10052;; Emit code here to do the range checking and make the index zero based.
e075ae69 10053;;
2bb7a0f5
RS
10054;; Each entry in the "addr_diff_vec" looks like this as the result of the
10055;; two rules below:
10056;;
10057;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
10058;;
10059;; 1. An expression involving an external reference may only use the
10060;; addition operator, and only with an assembly-time constant.
10061;; The example above satisfies this because ".-.L2" is a constant.
10062;;
10063;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
10064;; given the value of "GOT - .", where GOT is the actual address of
10065;; the Global Offset Table. Therefore, the .long above actually
10066;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
10067;; expression "GOT - .L2" by itself would generate an error from as(1).
10068;;
10069;; The pattern below emits code that looks like this:
10070;;
10071;; movl %ebx,reg
10072;; subl TABLE@GOTOFF(%ebx,index,4),reg
10073;; jmp reg
10074;;
10075;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
10076;; the addr_diff_vec is known to be part of this module.
10077;;
10078;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
10079;; evaluates to just ".L2".
10080
e075ae69
RH
10081(define_expand "casesi"
10082 [(set (match_dup 5)
10083 (match_operand:SI 0 "general_operand" ""))
10084 (parallel [(set (match_dup 6)
10085 (minus:SI (match_dup 5)
10086 (match_operand:SI 1 "general_operand" "")))
10087 (clobber (reg:CC 17))])
10088 (set (reg:CC 17)
10089 (compare:CC (match_dup 6)
10090 (match_operand:SI 2 "general_operand" "")))
10091 (set (pc)
10092 (if_then_else (gtu (reg:CC 17)
10093 (const_int 0))
10094 (label_ref (match_operand 4 "" ""))
10095 (pc)))
10096 (parallel
10097 [(set (match_dup 7)
10098 (minus:SI (match_dup 8)
10099 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
10100 (match_dup 8))
10101 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
10102 (clobber (reg:CC 17))])
10103 (parallel [(set (pc) (match_dup 7))
10104 (use (label_ref (match_dup 3)))])]
10105 "flag_pic"
10106 "
2bb7a0f5 10107{
e075ae69
RH
10108 operands[5] = gen_reg_rtx (SImode);
10109 operands[6] = gen_reg_rtx (SImode);
10110 operands[7] = gen_reg_rtx (SImode);
10111 operands[8] = pic_offset_table_rtx;
10112 current_function_uses_pic_offset_table = 1;
2bb7a0f5
RS
10113}")
10114
6343a50e 10115(define_insn "*tablejump_pic"
2ae0f82c 10116 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
886c62d1
JVA
10117 (use (label_ref (match_operand 1 "" "")))]
10118 ""
fb204271 10119 "jmp\\t%A0"
6ef67412
JH
10120 [(set_attr "type" "ibr")
10121 (set_attr "length_immediate" "0")])
e075ae69
RH
10122\f
10123;; Loop instruction
10124;;
10125;; This is all complicated by the fact that since this is a jump insn
10126;; we must handle our own reloads.
10127
5527bf14
RH
10128(define_expand "doloop_end"
10129 [(use (match_operand 0 "" "")) ; loop pseudo
10130 (use (match_operand 1 "" "")) ; iterations; zero if unknown
10131 (use (match_operand 2 "" "")) ; max iterations
10132 (use (match_operand 3 "" "")) ; loop level
10133 (use (match_operand 4 "" ""))] ; label
1e07edd3 10134 "TARGET_USE_LOOP && !TARGET_64BIT"
5527bf14
RH
10135 "
10136{
10137 /* Only use cloop on innermost loops. */
10138 if (INTVAL (operands[3]) > 1)
10139 FAIL;
10140 if (GET_MODE (operands[0]) != SImode)
10141 FAIL;
10142 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
10143 operands[0]));
10144 DONE;
10145}")
e075ae69 10146
5527bf14 10147(define_insn "doloop_end_internal"
e075ae69 10148 [(set (pc)
5527bf14 10149 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
e075ae69
RH
10150 (const_int 1))
10151 (label_ref (match_operand 0 "" ""))
10152 (pc)))
5527bf14 10153 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
e075ae69
RH
10154 (plus:SI (match_dup 1)
10155 (const_int -1)))
10156 (clobber (match_scratch:SI 3 "=X,X,r"))
10157 (clobber (reg:CC 17))]
1e07edd3 10158 "TARGET_USE_LOOP && !TARGET_64BIT"
e075ae69
RH
10159 "*
10160{
10161 if (which_alternative != 0)
10162 return \"#\";
10163 if (get_attr_length (insn) == 2)
10164 return \"loop\\t%l0\";
10165 else
10166 return \"dec{l}\\t%1\;jne\\t%l0\";
10167}"
6ef67412
JH
10168 [(set_attr "ppro_uops" "many")
10169 (set (attr "type")
e075ae69
RH
10170 (if_then_else (and (eq_attr "alternative" "0")
10171 (and (ge (minus (match_dup 0) (pc))
10172 (const_int -128))
10173 (lt (minus (match_dup 0) (pc))
10174 (const_int 124))))
6ef67412
JH
10175 (const_string "ibr")
10176 (const_string "multi")))])
e075ae69 10177
e075ae69
RH
10178(define_split
10179 [(set (pc)
10180 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
10181 (const_int 1))
10182 (match_operand 0 "" "")
10183 (pc)))
5527bf14 10184 (set (match_dup 1)
e075ae69
RH
10185 (plus:SI (match_dup 1)
10186 (const_int -1)))
5527bf14 10187 (clobber (match_scratch:SI 2 ""))
e075ae69 10188 (clobber (reg:CC 17))]
1e07edd3 10189 "TARGET_USE_LOOP && !TARGET_64BIT
5527bf14
RH
10190 && reload_completed
10191 && REGNO (operands[1]) != 2"
10192 [(parallel [(set (reg:CCZ 17)
10193 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
e075ae69 10194 (const_int 0)))
5527bf14 10195 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
16189740 10196 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
10197 (match_dup 0)
10198 (pc)))]
10199 "")
10200
10201(define_split
10202 [(set (pc)
10203 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
10204 (const_int 1))
10205 (match_operand 0 "" "")
10206 (pc)))
5527bf14 10207 (set (match_operand:SI 2 "nonimmediate_operand" "")
e075ae69
RH
10208 (plus:SI (match_dup 1)
10209 (const_int -1)))
10210 (clobber (match_scratch:SI 3 ""))
10211 (clobber (reg:CC 17))]
1e07edd3 10212 "TARGET_USE_LOOP && !TARGET_64BIT
5527bf14
RH
10213 && reload_completed
10214 && (! REG_P (operands[2])
10215 || ! rtx_equal_p (operands[1], operands[2]))"
e075ae69 10216 [(set (match_dup 3) (match_dup 1))
16189740
RH
10217 (parallel [(set (reg:CCZ 17)
10218 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
10219 (const_int 0)))
e075ae69
RH
10220 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
10221 (set (match_dup 2) (match_dup 3))
16189740 10222 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
e075ae69
RH
10223 (match_dup 0)
10224 (pc)))]
10225 "")
e075ae69
RH
10226\f
10227;; Call instructions.
2bb7a0f5 10228
cbbf65e0
RH
10229;; The predicates normally associated with named expanders are not properly
10230;; checked for calls. This is a bug in the generic code, but it isn't that
10231;; easy to fix. Ignore it for now and be prepared to fix things up.
2bb7a0f5 10232
886c62d1
JVA
10233;; Call subroutine returning no value.
10234
2bb7a0f5 10235(define_expand "call_pop"
cbbf65e0
RH
10236 [(parallel [(call (match_operand:QI 0 "" "")
10237 (match_operand:SI 1 "" ""))
2bb7a0f5
RS
10238 (set (reg:SI 7)
10239 (plus:SI (reg:SI 7)
cbbf65e0 10240 (match_operand:SI 3 "" "")))])]
1e07edd3 10241 "!TARGET_64BIT"
2bb7a0f5
RS
10242 "
10243{
35e2d030
RH
10244 if (operands[3] == const0_rtx)
10245 {
10246 emit_insn (gen_call (operands[0], operands[1]));
10247 DONE;
10248 }
b848ded1
JH
10249 /* Static functions and indirect calls don't need
10250 current_function_uses_pic_offset_table. */
10251 if (flag_pic
2a4bbffa
RH
10252 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
10253 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2bb7a0f5 10254 current_function_uses_pic_offset_table = 1;
e1ff012c 10255 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
cbbf65e0 10256 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1e07edd3
JH
10257 if (TARGET_64BIT)
10258 abort();
2bb7a0f5
RS
10259}")
10260
94bb5d0c 10261(define_insn "*call_pop_0"
e1ff012c 10262 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c
RH
10263 (match_operand:SI 1 "" ""))
10264 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 10265 (match_operand:SI 2 "immediate_operand" "")))]
1e07edd3 10266 "!TARGET_64BIT"
94bb5d0c
RH
10267 "*
10268{
10269 if (SIBLING_CALL_P (insn))
10270 return \"jmp\\t%P0\";
10271 else
10272 return \"call\\t%P0\";
10273}"
10274 [(set_attr "type" "call")])
10275
cbbf65e0 10276(define_insn "*call_pop_1"
e1ff012c 10277 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 10278 (match_operand:SI 1 "" ""))
886c62d1 10279 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 10280 (match_operand:SI 2 "immediate_operand" "i")))]
1e07edd3 10281 "!TARGET_64BIT"
886c62d1
JVA
10282 "*
10283{
e1ff012c 10284 if (constant_call_address_operand (operands[0], Pmode))
94bb5d0c
RH
10285 {
10286 if (SIBLING_CALL_P (insn))
10287 return \"jmp\\t%P0\";
10288 else
10289 return \"call\\t%P0\";
10290 }
94bb5d0c 10291 if (SIBLING_CALL_P (insn))
fb204271 10292 return \"jmp\\t%A0\";
94bb5d0c 10293 else
fb204271 10294 return \"call\\t%A0\";
e075ae69
RH
10295}"
10296 [(set_attr "type" "call")])
886c62d1 10297
2bb7a0f5 10298(define_expand "call"
cbbf65e0
RH
10299 [(call (match_operand:QI 0 "" "")
10300 (match_operand:SI 1 "" ""))]
2bb7a0f5
RS
10301 ;; Operand 1 not used on the i386.
10302 ""
10303 "
10304{
b848ded1
JH
10305 /* Static functions and indirect calls don't need
10306 current_function_uses_pic_offset_table. */
10307 if (flag_pic
2a4bbffa
RH
10308 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
10309 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2bb7a0f5 10310 current_function_uses_pic_offset_table = 1;
e1ff012c 10311 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
cbbf65e0 10312 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2bb7a0f5
RS
10313}")
10314
94bb5d0c 10315(define_insn "*call_0"
e1ff012c 10316 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
94bb5d0c
RH
10317 (match_operand:SI 1 "" ""))]
10318 ""
10319 "*
10320{
10321 if (SIBLING_CALL_P (insn))
10322 return \"jmp\\t%P0\";
10323 else
10324 return \"call\\t%P0\";
10325}"
10326 [(set_attr "type" "call")])
10327
cbbf65e0 10328(define_insn "*call_1"
e1ff012c 10329 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
94bb5d0c 10330 (match_operand:SI 1 "" ""))]
886c62d1
JVA
10331 ""
10332 "*
10333{
94bb5d0c 10334 if (constant_call_address_operand (operands[0], QImode))
cbbf65e0
RH
10335 {
10336 if (SIBLING_CALL_P (insn))
10337 return \"jmp\\t%P0\";
10338 else
10339 return \"call\\t%P0\";
10340 }
cbbf65e0 10341 if (SIBLING_CALL_P (insn))
fb204271 10342 return \"jmp\\t%A0\";
cbbf65e0 10343 else
fb204271 10344 return \"call\\t%A0\";
e075ae69
RH
10345}"
10346 [(set_attr "type" "call")])
886c62d1
JVA
10347
10348;; Call subroutine, returning value in operand 0
10349;; (which must be a hard register).
10350
2bb7a0f5
RS
10351(define_expand "call_value_pop"
10352 [(parallel [(set (match_operand 0 "" "")
cbbf65e0
RH
10353 (call (match_operand:QI 1 "" "")
10354 (match_operand:SI 2 "" "")))
2bb7a0f5
RS
10355 (set (reg:SI 7)
10356 (plus:SI (reg:SI 7)
cbbf65e0 10357 (match_operand:SI 4 "" "")))])]
1e07edd3 10358 "!TARGET_64BIT"
2bb7a0f5
RS
10359 "
10360{
35e2d030
RH
10361 if (operands[4] == const0_rtx)
10362 {
10363 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
10364 DONE;
10365 }
b848ded1
JH
10366 /* Static functions and indirect calls don't need
10367 current_function_uses_pic_offset_table. */
10368 if (flag_pic
2a4bbffa
RH
10369 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10370 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2bb7a0f5 10371 current_function_uses_pic_offset_table = 1;
e1ff012c 10372 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
cbbf65e0 10373 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2bb7a0f5
RS
10374}")
10375
2bb7a0f5
RS
10376(define_expand "call_value"
10377 [(set (match_operand 0 "" "")
cbbf65e0
RH
10378 (call (match_operand:QI 1 "" "")
10379 (match_operand:SI 2 "" "")))]
2bb7a0f5
RS
10380 ;; Operand 2 not used on the i386.
10381 ""
10382 "
10383{
b848ded1
JH
10384 /* Static functions and indirect calls don't need
10385 current_function_uses_pic_offset_table. */
10386 if (flag_pic
2a4bbffa
RH
10387 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10388 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2bb7a0f5 10389 current_function_uses_pic_offset_table = 1;
e1ff012c 10390 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
cbbf65e0 10391 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2bb7a0f5
RS
10392}")
10393
b840bfb0
MM
10394;; Call subroutine returning any type.
10395
576182a3 10396(define_expand "untyped_call"
b840bfb0 10397 [(parallel [(call (match_operand 0 "" "")
576182a3 10398 (const_int 0))
b840bfb0 10399 (match_operand 1 "" "")
576182a3
TW
10400 (match_operand 2 "" "")])]
10401 ""
10402 "
10403{
b840bfb0 10404 int i;
576182a3 10405
d8b679b9
RK
10406 /* In order to give reg-stack an easier job in validating two
10407 coprocessor registers as containing a possible return value,
10408 simply pretend the untyped call returns a complex long double
10409 value. */
74775c7a 10410
d8b679b9 10411 emit_call_insn (TARGET_80387
f64cecad
JC
10412 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
10413 operands[0], const0_rtx)
d8b679b9 10414 : gen_call (operands[0], const0_rtx));
576182a3 10415
b840bfb0 10416 for (i = 0; i < XVECLEN (operands[2], 0); i++)
576182a3 10417 {
b840bfb0
MM
10418 rtx set = XVECEXP (operands[2], 0, i);
10419 emit_move_insn (SET_DEST (set), SET_SRC (set));
576182a3 10420 }
576182a3 10421
b840bfb0
MM
10422 /* The optimizer does not know that the call sets the function value
10423 registers we stored in the result block. We avoid problems by
10424 claiming that all hard registers are used and clobbered at this
10425 point. */
10426 emit_insn (gen_blockage ());
576182a3
TW
10427
10428 DONE;
10429}")
e075ae69
RH
10430\f
10431;; Prologue and epilogue instructions
576182a3 10432
b840bfb0
MM
10433;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10434;; all of memory. This blocks insns from being moved across this point.
10435
10436(define_insn "blockage"
10437 [(unspec_volatile [(const_int 0)] 0)]
576182a3 10438 ""
90aec2cf 10439 ""
e075ae69 10440 [(set_attr "length" "0")])
576182a3 10441
886c62d1
JVA
10442;; Insn emitted into the body of a function to return from a function.
10443;; This is only done if the function's epilogue is known to be simple.
182a4620 10444;; See comments for ix86_can_use_return_insn_p in i386.c.
886c62d1 10445
5f3d14e3 10446(define_expand "return"
886c62d1 10447 [(return)]
5f3d14e3 10448 "ix86_can_use_return_insn_p ()"
9a7372d6
RH
10449 "
10450{
10451 if (current_function_pops_args)
10452 {
10453 rtx popc = GEN_INT (current_function_pops_args);
10454 emit_jump_insn (gen_return_pop_internal (popc));
10455 DONE;
10456 }
10457}")
5f3d14e3
SC
10458
10459(define_insn "return_internal"
10460 [(return)]
10461 "reload_completed"
90aec2cf 10462 "ret"
6ef67412
JH
10463 [(set_attr "length" "1")
10464 (set_attr "length_immediate" "0")
10465 (set_attr "modrm" "0")])
5f3d14e3 10466
6cd96118
SC
10467(define_insn "return_pop_internal"
10468 [(return)
10469 (use (match_operand:SI 0 "const_int_operand" ""))]
10470 "reload_completed"
e075ae69 10471 "ret\\t%0"
6ef67412
JH
10472 [(set_attr "length" "3")
10473 (set_attr "length_immediate" "2")
10474 (set_attr "modrm" "0")])
6cd96118 10475
11837777
RH
10476(define_insn "return_indirect_internal"
10477 [(return)
10478 (use (match_operand:SI 0 "register_operand" "r"))]
10479 "reload_completed"
fb204271 10480 "jmp\\t%A0"
11837777
RH
10481 [(set_attr "type" "ibr")
10482 (set_attr "length_immediate" "0")])
10483
5f3d14e3
SC
10484(define_insn "nop"
10485 [(const_int 0)]
10486 ""
90aec2cf 10487 "nop"
e075ae69 10488 [(set_attr "length" "1")
6ef67412
JH
10489 (set_attr "length_immediate" "0")
10490 (set_attr "modrm" "0")
e075ae69 10491 (set_attr "ppro_uops" "one")])
5f3d14e3
SC
10492
10493(define_expand "prologue"
10494 [(const_int 1)]
10495 ""
e075ae69 10496 "ix86_expand_prologue (); DONE;")
5f3d14e3 10497
e075ae69 10498(define_insn "prologue_set_got"
69404d6f 10499 [(set (match_operand:SI 0 "register_operand" "=r")
c76aab11 10500 (unspec_volatile:SI
e075ae69
RH
10501 [(plus:SI (match_dup 0)
10502 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
10503 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
10504 (clobber (reg:CC 17))]
47d36400
BS
10505 ""
10506 "*
10507{
e075ae69
RH
10508 if (GET_CODE (operands[2]) == LABEL_REF)
10509 operands[2] = XEXP (operands[2], 0);
10510 if (TARGET_DEEP_BRANCH_PREDICTION)
10511 return \"add{l}\\t{%1, %0|%0, %1}\";
10512 else
10513 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
90aec2cf 10514}"
6ef67412 10515 [(set_attr "type" "alu")
d731a1da
JH
10516 ; Since this insn may have two constant operands, we must set the
10517 ; length manually.
10518 (set_attr "length_immediate" "4")
6ef67412 10519 (set_attr "mode" "SI")])
47d36400 10520
e075ae69 10521(define_insn "prologue_get_pc"
69404d6f 10522 [(set (match_operand:SI 0 "register_operand" "=r")
c76aab11 10523 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
1e07edd3 10524 "!TARGET_64BIT"
886c62d1
JVA
10525 "*
10526{
e075ae69
RH
10527 if (GET_CODE (operands[1]) == LABEL_REF)
10528 operands[1] = XEXP (operands[1], 0);
10529 output_asm_insn (\"call\\t%X1\", operands);
10530 if (! TARGET_DEEP_BRANCH_PREDICTION)
10531 {
10532 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
10533 CODE_LABEL_NUMBER (operands[1]));
10534 }
10535 RET;
10536}"
10537 [(set_attr "type" "multi")])
5f3d14e3 10538
e075ae69
RH
10539(define_expand "epilogue"
10540 [(const_int 1)]
10541 ""
cbbf65e0
RH
10542 "ix86_expand_epilogue (1); DONE;")
10543
10544(define_expand "sibcall_epilogue"
10545 [(const_int 1)]
10546 ""
10547 "ix86_expand_epilogue (0); DONE;")
e075ae69
RH
10548
10549(define_insn "leave"
10550 [(set (reg:SI 7) (reg:SI 6))
10551 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
1e07edd3 10552 "!TARGET_64BIT"
e075ae69 10553 "leave"
6ef67412
JH
10554 [(set_attr "length_immediate" "0")
10555 (set_attr "length" "1")
10556 (set_attr "modrm" "0")
10557 (set_attr "modrm" "0")
0b5107cf 10558 (set_attr "athlon_decode" "vector")
e075ae69
RH
10559 (set_attr "ppro_uops" "few")])
10560\f
10561(define_expand "ffssi2"
4cbfbb1b 10562 [(set (match_operand:SI 0 "nonimmediate_operand" "")
e075ae69
RH
10563 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
10564 ""
10565 "
10566{
10567 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
10568 rtx in = operands[1];
10569
10570 if (TARGET_CMOVE)
5f3d14e3 10571 {
e075ae69
RH
10572 emit_move_insn (tmp, constm1_rtx);
10573 emit_insn (gen_ffssi_1 (out, in));
10574 emit_insn (gen_rtx_SET (VOIDmode, out,
10575 gen_rtx_IF_THEN_ELSE (SImode,
16189740 10576 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
e075ae69
RH
10577 const0_rtx),
10578 tmp,
10579 out)));
e0dc26ff
JH
10580 emit_insn (gen_addsi3 (out, out, const1_rtx));
10581 emit_move_insn (operands[0], out);
10582 }
10583
16189740
RH
10584 /* Pentium bsf instruction is extremly slow. The following code is
10585 recommended by the Intel Optimizing Manual as a reasonable replacement:
e0dc26ff
JH
10586 TEST EAX,EAX
10587 JZ SHORT BS2
10588 XOR ECX,ECX
10589 MOV DWORD PTR [TEMP+4],ECX
10590 SUB ECX,EAX
10591 AND EAX,ECX
10592 MOV DWORD PTR [TEMP],EAX
10593 FILD QWORD PTR [TEMP]
10594 FSTP QWORD PTR [TEMP]
10595 WAIT ; WAIT only needed for compatibility with
10596 ; earlier processors
10597 MOV ECX, DWORD PTR [TEMP+4]
10598 SHR ECX,20
10599 SUB ECX,3FFH
10600 TEST EAX,EAX ; clear zero flag
10601 BS2:
10602 Following piece of code expand ffs to similar beast.
10603 */
10604
10605 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
10606 {
10607 rtx label = gen_label_rtx ();
10608 rtx lo, hi;
10609 rtx mem = assign_386_stack_local (DImode, 0);
10610 rtx fptmp = gen_reg_rtx (DFmode);
10611 split_di (&mem, 1, &lo, &hi);
10612
10613 emit_move_insn (out, const0_rtx);
10614
10615 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
10616
10617 emit_move_insn (hi, out);
10618 emit_insn (gen_subsi3 (out, out, in));
10619 emit_insn (gen_andsi3 (out, out, in));
10620 emit_move_insn (lo, out);
10621 emit_insn (gen_floatdidf2 (fptmp,mem));
10622 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
10623 emit_move_insn (out, hi);
10624 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
16189740 10625 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
e0dc26ff
JH
10626
10627 emit_label (label);
10628 LABEL_NUSES (label) = 1;
10629
10630 emit_move_insn (operands[0], out);
5f3d14e3 10631 }
e075ae69 10632 else
5f3d14e3 10633 {
e075ae69
RH
10634 emit_move_insn (tmp, const0_rtx);
10635 emit_insn (gen_ffssi_1 (out, in));
10636 emit_insn (gen_rtx_SET (VOIDmode,
10637 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
16189740 10638 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
e075ae69
RH
10639 const0_rtx)));
10640 emit_insn (gen_negsi2 (tmp, tmp));
10641 emit_insn (gen_iorsi3 (out, out, tmp));
e0dc26ff
JH
10642 emit_insn (gen_addsi3 (out, out, const1_rtx));
10643 emit_move_insn (operands[0], out);
e075ae69 10644 }
e075ae69 10645 DONE;
886c62d1
JVA
10646}")
10647
e075ae69 10648(define_insn "ffssi_1"
16189740
RH
10649 [(set (reg:CCZ 17)
10650 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
10651 (const_int 0)))
e075ae69
RH
10652 (set (match_operand:SI 0 "register_operand" "=r")
10653 (unspec:SI [(match_dup 1)] 5))]
10654 ""
10655 "bsf{l}\\t{%1, %0|%0, %1}"
6ef67412 10656 [(set_attr "prefix_0f" "1")
e075ae69
RH
10657 (set_attr "ppro_uops" "few")])
10658
10659;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
10660;; and slower than the two-byte movzx insn needed to do the work in SImode.
10661\f
10662;; These patterns match the binary 387 instructions for addM3, subM3,
10663;; mulM3 and divM3. There are three patterns for each of DFmode and
10664;; SFmode. The first is the normal insn, the second the same insn but
10665;; with one operand a conversion, and the third the same insn but with
10666;; the other operand a conversion. The conversion may be SFmode or
10667;; SImode if the target mode DFmode, but only SImode if the target mode
10668;; is SFmode.
10669
caa6ec8d
JH
10670;; Gcc is slightly more smart about handling normal two address instructions
10671;; so use special patterns for add and mull.
10672(define_insn "*fop_sf_comm"
1deaa899 10673 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
caa6ec8d 10674 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
10675 [(match_operand:SF 1 "register_operand" "%0,0")
10676 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
10677 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
10678 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
10679 "* return output_387_binary_op (insn, operands);"
10680 [(set (attr "type")
1deaa899
JH
10681 (if_then_else (eq_attr "alternative" "1")
10682 (const_string "sse")
10683 (if_then_else (match_operand:SF 3 "mult_operator" "")
10684 (const_string "fmul")
10685 (const_string "fop"))))
10686 (set_attr "mode" "SF")])
10687
10688(define_insn "*fop_sf_comm_sse"
10689 [(set (match_operand:SF 0 "register_operand" "=x")
10690 (match_operator:SF 3 "binary_fp_operator"
10691 [(match_operand:SF 1 "register_operand" "%0")
10692 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10693 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10694 "* return output_387_binary_op (insn, operands);"
10695 [(set_attr "type" "sse")
6ef67412 10696 (set_attr "mode" "SF")])
caa6ec8d
JH
10697
10698(define_insn "*fop_df_comm"
1deaa899 10699 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
caa6ec8d 10700 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
10701 [(match_operand:DF 1 "register_operand" "%0,0")
10702 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
10703 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
10704 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
10705 "* return output_387_binary_op (insn, operands);"
10706 [(set (attr "type")
1deaa899
JH
10707 (if_then_else (eq_attr "alternative" "1")
10708 (const_string "sse")
10709 (if_then_else (match_operand:SF 3 "mult_operator" "")
10710 (const_string "fmul")
10711 (const_string "fop"))))
10712 (set_attr "mode" "DF")])
10713
10714(define_insn "*fop_df_comm_sse"
10715 [(set (match_operand:DF 0 "register_operand" "=Y")
10716 (match_operator:DF 3 "binary_fp_operator"
10717 [(match_operand:DF 1 "register_operand" "%0")
10718 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10719 "TARGET_SSE2
10720 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10721 "* return output_387_binary_op (insn, operands);"
10722 [(set_attr "type" "sse")
6ef67412 10723 (set_attr "mode" "DF")])
caa6ec8d
JH
10724
10725(define_insn "*fop_xf_comm"
10726 [(set (match_operand:XF 0 "register_operand" "=f")
10727 (match_operator:XF 3 "binary_fp_operator"
10728 [(match_operand:XF 1 "register_operand" "%0")
10729 (match_operand:XF 2 "register_operand" "f")]))]
1e07edd3
JH
10730 "TARGET_80387 && !TARGET_64BIT
10731 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
caa6ec8d
JH
10732 "* return output_387_binary_op (insn, operands);"
10733 [(set (attr "type")
10734 (if_then_else (match_operand:XF 3 "mult_operator" "")
10735 (const_string "fmul")
6ef67412
JH
10736 (const_string "fop")))
10737 (set_attr "mode" "XF")])
caa6ec8d 10738
2b589241
JH
10739(define_insn "*fop_tf_comm"
10740 [(set (match_operand:TF 0 "register_operand" "=f")
10741 (match_operator:TF 3 "binary_fp_operator"
10742 [(match_operand:TF 1 "register_operand" "%0")
10743 (match_operand:TF 2 "register_operand" "f")]))]
10744 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10745 "* return output_387_binary_op (insn, operands);"
10746 [(set (attr "type")
10747 (if_then_else (match_operand:TF 3 "mult_operator" "")
10748 (const_string "fmul")
10749 (const_string "fop")))
10750 (set_attr "mode" "XF")])
10751
e075ae69 10752(define_insn "*fop_sf_1"
1deaa899 10753 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
e075ae69 10754 (match_operator:SF 3 "binary_fp_operator"
1deaa899
JH
10755 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
10756 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
10757 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
caa6ec8d 10758 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
f97d9ec3 10759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
10760 "* return output_387_binary_op (insn, operands);"
10761 [(set (attr "type")
1deaa899
JH
10762 (cond [(eq_attr "alternative" "2")
10763 (const_string "sse")
10764 (match_operand:SF 3 "mult_operator" "")
e075ae69
RH
10765 (const_string "fmul")
10766 (match_operand:SF 3 "div_operator" "")
10767 (const_string "fdiv")
10768 ]
6ef67412
JH
10769 (const_string "fop")))
10770 (set_attr "mode" "SF")])
e075ae69 10771
1deaa899
JH
10772(define_insn "*fop_sf_1_sse"
10773 [(set (match_operand:SF 0 "register_operand" "=x")
10774 (match_operator:SF 3 "binary_fp_operator"
10775 [(match_operand:SF 1 "register_operand" "0")
10776 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10777 "TARGET_SSE
10778 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10779 "* return output_387_binary_op (insn, operands);"
10780 [(set_attr "type" "sse")
10781 (set_attr "mode" "SF")])
10782
10783;; ??? Add SSE splitters for these!
e075ae69
RH
10784(define_insn "*fop_sf_2"
10785 [(set (match_operand:SF 0 "register_operand" "=f,f")
10786 (match_operator:SF 3 "binary_fp_operator"
10787 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10788 (match_operand:SF 2 "register_operand" "0,0")]))]
1deaa899 10789 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
e075ae69
RH
10790 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10791 [(set (attr "type")
10792 (cond [(match_operand:SF 3 "mult_operator" "")
10793 (const_string "fmul")
10794 (match_operand:SF 3 "div_operator" "")
10795 (const_string "fdiv")
10796 ]
10797 (const_string "fop")))
10798 (set_attr "fp_int_src" "true")
6ef67412
JH
10799 (set_attr "ppro_uops" "many")
10800 (set_attr "mode" "SI")])
e075ae69
RH
10801
10802(define_insn "*fop_sf_3"
10803 [(set (match_operand:SF 0 "register_operand" "=f,f")
10804 (match_operator:SF 3 "binary_fp_operator"
10805 [(match_operand:SF 1 "register_operand" "0,0")
10806 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1deaa899 10807 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
e075ae69
RH
10808 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10809 [(set (attr "type")
10810 (cond [(match_operand:SF 3 "mult_operator" "")
10811 (const_string "fmul")
10812 (match_operand:SF 3 "div_operator" "")
10813 (const_string "fdiv")
10814 ]
10815 (const_string "fop")))
10816 (set_attr "fp_int_src" "true")
6ef67412
JH
10817 (set_attr "ppro_uops" "many")
10818 (set_attr "mode" "SI")])
e075ae69
RH
10819
10820(define_insn "*fop_df_1"
1deaa899 10821 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
e075ae69 10822 (match_operator:DF 3 "binary_fp_operator"
1deaa899
JH
10823 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
10824 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
10825 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
caa6ec8d 10826 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
f97d9ec3 10827 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
10828 "* return output_387_binary_op (insn, operands);"
10829 [(set (attr "type")
1deaa899
JH
10830 (cond [(eq_attr "alternative" "2")
10831 (const_string "sse")
10832 (match_operand:DF 3 "mult_operator" "")
e075ae69
RH
10833 (const_string "fmul")
10834 (match_operand:DF 3 "div_operator" "")
10835 (const_string "fdiv")
10836 ]
6ef67412
JH
10837 (const_string "fop")))
10838 (set_attr "mode" "DF")])
e075ae69 10839
1deaa899
JH
10840(define_insn "*fop_df_1_sse"
10841 [(set (match_operand:DF 0 "register_operand" "=Y")
10842 (match_operator:DF 3 "binary_fp_operator"
10843 [(match_operand:DF 1 "register_operand" "0")
10844 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10845 "TARGET_SSE
10846 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10847 "* return output_387_binary_op (insn, operands);"
10848 [(set_attr "type" "sse")])
10849
10850;; ??? Add SSE splitters for these!
e075ae69
RH
10851(define_insn "*fop_df_2"
10852 [(set (match_operand:DF 0 "register_operand" "=f,f")
10853 (match_operator:DF 3 "binary_fp_operator"
10854 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10855 (match_operand:DF 2 "register_operand" "0,0")]))]
1deaa899 10856 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
e075ae69
RH
10857 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10858 [(set (attr "type")
10859 (cond [(match_operand:DF 3 "mult_operator" "")
10860 (const_string "fmul")
10861 (match_operand:DF 3 "div_operator" "")
10862 (const_string "fdiv")
10863 ]
10864 (const_string "fop")))
10865 (set_attr "fp_int_src" "true")
6ef67412
JH
10866 (set_attr "ppro_uops" "many")
10867 (set_attr "mode" "SI")])
e075ae69
RH
10868
10869(define_insn "*fop_df_3"
10870 [(set (match_operand:DF 0 "register_operand" "=f,f")
10871 (match_operator:DF 3 "binary_fp_operator"
10872 [(match_operand:DF 1 "register_operand" "0,0")
10873 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1deaa899 10874 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
e075ae69
RH
10875 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10876 [(set (attr "type")
10877 (cond [(match_operand:DF 3 "mult_operator" "")
10878 (const_string "fmul")
10879 (match_operand:DF 3 "div_operator" "")
10880 (const_string "fdiv")
10881 ]
10882 (const_string "fop")))
10883 (set_attr "fp_int_src" "true")
6ef67412
JH
10884 (set_attr "ppro_uops" "many")
10885 (set_attr "mode" "SI")])
e075ae69
RH
10886
10887(define_insn "*fop_df_4"
10888 [(set (match_operand:DF 0 "register_operand" "=f,f")
10889 (match_operator:DF 3 "binary_fp_operator"
10890 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10891 (match_operand:DF 2 "register_operand" "0,f")]))]
f97d9ec3
JH
10892 "TARGET_80387
10893 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
e075ae69
RH
10894 "* return output_387_binary_op (insn, operands);"
10895 [(set (attr "type")
10896 (cond [(match_operand:DF 3 "mult_operator" "")
10897 (const_string "fmul")
10898 (match_operand:DF 3 "div_operator" "")
10899 (const_string "fdiv")
10900 ]
6ef67412
JH
10901 (const_string "fop")))
10902 (set_attr "mode" "SF")])
e075ae69
RH
10903
10904(define_insn "*fop_df_5"
10905 [(set (match_operand:DF 0 "register_operand" "=f,f")
10906 (match_operator:DF 3 "binary_fp_operator"
10907 [(match_operand:DF 1 "register_operand" "0,f")
10908 (float_extend:DF
10909 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1deaa899 10910 "TARGET_80387 && !TARGET_SSE2"
e075ae69
RH
10911 "* return output_387_binary_op (insn, operands);"
10912 [(set (attr "type")
10913 (cond [(match_operand:DF 3 "mult_operator" "")
10914 (const_string "fmul")
10915 (match_operand:DF 3 "div_operator" "")
10916 (const_string "fdiv")
10917 ]
6ef67412
JH
10918 (const_string "fop")))
10919 (set_attr "mode" "SF")])
e075ae69
RH
10920
10921(define_insn "*fop_xf_1"
10922 [(set (match_operand:XF 0 "register_operand" "=f,f")
10923 (match_operator:XF 3 "binary_fp_operator"
10924 [(match_operand:XF 1 "register_operand" "0,f")
10925 (match_operand:XF 2 "register_operand" "f,0")]))]
1e07edd3 10926 "TARGET_80387 && !TARGET_64BIT
caa6ec8d 10927 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
e075ae69
RH
10928 "* return output_387_binary_op (insn, operands);"
10929 [(set (attr "type")
ca285e07 10930 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 10931 (const_string "fmul")
ca285e07 10932 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
10933 (const_string "fdiv")
10934 ]
6ef67412
JH
10935 (const_string "fop")))
10936 (set_attr "mode" "XF")])
e075ae69 10937
2b589241
JH
10938(define_insn "*fop_tf_1"
10939 [(set (match_operand:TF 0 "register_operand" "=f,f")
10940 (match_operator:TF 3 "binary_fp_operator"
10941 [(match_operand:TF 1 "register_operand" "0,f")
10942 (match_operand:TF 2 "register_operand" "f,0")]))]
10943 "TARGET_80387
10944 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10945 "* return output_387_binary_op (insn, operands);"
10946 [(set (attr "type")
10947 (cond [(match_operand:TF 3 "mult_operator" "")
10948 (const_string "fmul")
10949 (match_operand:TF 3 "div_operator" "")
10950 (const_string "fdiv")
10951 ]
10952 (const_string "fop")))
10953 (set_attr "mode" "XF")])
10954
e075ae69
RH
10955(define_insn "*fop_xf_2"
10956 [(set (match_operand:XF 0 "register_operand" "=f,f")
10957 (match_operator:XF 3 "binary_fp_operator"
10958 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10959 (match_operand:XF 2 "register_operand" "0,0")]))]
1e07edd3 10960 "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP"
e075ae69
RH
10961 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10962 [(set (attr "type")
ca285e07 10963 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 10964 (const_string "fmul")
ca285e07 10965 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
10966 (const_string "fdiv")
10967 ]
10968 (const_string "fop")))
10969 (set_attr "fp_int_src" "true")
6ef67412 10970 (set_attr "mode" "SI")
e075ae69
RH
10971 (set_attr "ppro_uops" "many")])
10972
2b589241
JH
10973(define_insn "*fop_tf_2"
10974 [(set (match_operand:TF 0 "register_operand" "=f,f")
10975 (match_operator:TF 3 "binary_fp_operator"
10976 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10977 (match_operand:TF 2 "register_operand" "0,0")]))]
10978 "TARGET_80387 && TARGET_USE_FIOP"
10979 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10980 [(set (attr "type")
10981 (cond [(match_operand:TF 3 "mult_operator" "")
10982 (const_string "fmul")
10983 (match_operand:TF 3 "div_operator" "")
10984 (const_string "fdiv")
10985 ]
10986 (const_string "fop")))
10987 (set_attr "fp_int_src" "true")
10988 (set_attr "mode" "SI")
10989 (set_attr "ppro_uops" "many")])
10990
e075ae69
RH
10991(define_insn "*fop_xf_3"
10992 [(set (match_operand:XF 0 "register_operand" "=f,f")
10993 (match_operator:XF 3 "binary_fp_operator"
10994 [(match_operand:XF 1 "register_operand" "0,0")
10995 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1e07edd3 10996 "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP"
e075ae69
RH
10997 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10998 [(set (attr "type")
ca285e07 10999 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 11000 (const_string "fmul")
ca285e07 11001 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
11002 (const_string "fdiv")
11003 ]
11004 (const_string "fop")))
11005 (set_attr "fp_int_src" "true")
6ef67412 11006 (set_attr "mode" "SI")
e075ae69
RH
11007 (set_attr "ppro_uops" "many")])
11008
2b589241
JH
11009(define_insn "*fop_tf_3"
11010 [(set (match_operand:TF 0 "register_operand" "=f,f")
11011 (match_operator:TF 3 "binary_fp_operator"
11012 [(match_operand:TF 1 "register_operand" "0,0")
11013 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
11014 "TARGET_80387 && TARGET_USE_FIOP"
11015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
11016 [(set (attr "type")
11017 (cond [(match_operand:TF 3 "mult_operator" "")
11018 (const_string "fmul")
11019 (match_operand:TF 3 "div_operator" "")
11020 (const_string "fdiv")
11021 ]
11022 (const_string "fop")))
11023 (set_attr "fp_int_src" "true")
11024 (set_attr "mode" "SI")
11025 (set_attr "ppro_uops" "many")])
11026
e075ae69
RH
11027(define_insn "*fop_xf_4"
11028 [(set (match_operand:XF 0 "register_operand" "=f,f")
11029 (match_operator:XF 3 "binary_fp_operator"
11030 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
11031 (match_operand:XF 2 "register_operand" "0,f")]))]
1e07edd3 11032 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
11033 "* return output_387_binary_op (insn, operands);"
11034 [(set (attr "type")
ca285e07 11035 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 11036 (const_string "fmul")
ca285e07 11037 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
11038 (const_string "fdiv")
11039 ]
6ef67412
JH
11040 (const_string "fop")))
11041 (set_attr "mode" "SF")])
e075ae69 11042
2b589241
JH
11043(define_insn "*fop_tf_4"
11044 [(set (match_operand:TF 0 "register_operand" "=f,f")
11045 (match_operator:TF 3 "binary_fp_operator"
11046 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
11047 (match_operand:TF 2 "register_operand" "0,f")]))]
11048 "TARGET_80387"
11049 "* return output_387_binary_op (insn, operands);"
11050 [(set (attr "type")
11051 (cond [(match_operand:TF 3 "mult_operator" "")
11052 (const_string "fmul")
11053 (match_operand:TF 3 "div_operator" "")
11054 (const_string "fdiv")
11055 ]
11056 (const_string "fop")))
11057 (set_attr "mode" "SF")])
11058
e075ae69
RH
11059(define_insn "*fop_xf_5"
11060 [(set (match_operand:XF 0 "register_operand" "=f,f")
11061 (match_operator:XF 3 "binary_fp_operator"
11062 [(match_operand:XF 1 "register_operand" "0,f")
11063 (float_extend:XF
11064 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1e07edd3 11065 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
11066 "* return output_387_binary_op (insn, operands);"
11067 [(set (attr "type")
ca285e07 11068 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 11069 (const_string "fmul")
ca285e07 11070 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
11071 (const_string "fdiv")
11072 ]
6ef67412
JH
11073 (const_string "fop")))
11074 (set_attr "mode" "SF")])
e075ae69 11075
2b589241
JH
11076(define_insn "*fop_tf_5"
11077 [(set (match_operand:TF 0 "register_operand" "=f,f")
11078 (match_operator:TF 3 "binary_fp_operator"
11079 [(match_operand:TF 1 "register_operand" "0,f")
11080 (float_extend:TF
11081 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
11082 "TARGET_80387"
11083 "* return output_387_binary_op (insn, operands);"
11084 [(set (attr "type")
11085 (cond [(match_operand:TF 3 "mult_operator" "")
11086 (const_string "fmul")
11087 (match_operand:TF 3 "div_operator" "")
11088 (const_string "fdiv")
11089 ]
11090 (const_string "fop")))
11091 (set_attr "mode" "SF")])
11092
e075ae69
RH
11093(define_insn "*fop_xf_6"
11094 [(set (match_operand:XF 0 "register_operand" "=f,f")
11095 (match_operator:XF 3 "binary_fp_operator"
11096 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
11097 (match_operand:XF 2 "register_operand" "0,f")]))]
1e07edd3 11098 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
11099 "* return output_387_binary_op (insn, operands);"
11100 [(set (attr "type")
ca285e07 11101 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 11102 (const_string "fmul")
ca285e07 11103 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
11104 (const_string "fdiv")
11105 ]
6ef67412
JH
11106 (const_string "fop")))
11107 (set_attr "mode" "DF")])
e075ae69 11108
2b589241
JH
11109(define_insn "*fop_tf_6"
11110 [(set (match_operand:TF 0 "register_operand" "=f,f")
11111 (match_operator:TF 3 "binary_fp_operator"
11112 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
11113 (match_operand:TF 2 "register_operand" "0,f")]))]
11114 "TARGET_80387"
11115 "* return output_387_binary_op (insn, operands);"
11116 [(set (attr "type")
11117 (cond [(match_operand:TF 3 "mult_operator" "")
11118 (const_string "fmul")
11119 (match_operand:TF 3 "div_operator" "")
11120 (const_string "fdiv")
11121 ]
11122 (const_string "fop")))
11123 (set_attr "mode" "DF")])
11124
e075ae69
RH
11125(define_insn "*fop_xf_7"
11126 [(set (match_operand:XF 0 "register_operand" "=f,f")
11127 (match_operator:XF 3 "binary_fp_operator"
11128 [(match_operand:XF 1 "register_operand" "0,f")
11129 (float_extend:XF
11130 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1e07edd3 11131 "TARGET_80387 && !TARGET_64BIT"
e075ae69
RH
11132 "* return output_387_binary_op (insn, operands);"
11133 [(set (attr "type")
ca285e07 11134 (cond [(match_operand:XF 3 "mult_operator" "")
e075ae69 11135 (const_string "fmul")
ca285e07 11136 (match_operand:XF 3 "div_operator" "")
e075ae69
RH
11137 (const_string "fdiv")
11138 ]
6ef67412
JH
11139 (const_string "fop")))
11140 (set_attr "mode" "DF")])
e075ae69 11141
2b589241
JH
11142(define_insn "*fop_tf_7"
11143 [(set (match_operand:TF 0 "register_operand" "=f,f")
11144 (match_operator:TF 3 "binary_fp_operator"
11145 [(match_operand:TF 1 "register_operand" "0,f")
11146 (float_extend:TF
11147 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
11148 "TARGET_80387"
11149 "* return output_387_binary_op (insn, operands);"
11150 [(set (attr "type")
11151 (cond [(match_operand:TF 3 "mult_operator" "")
11152 (const_string "fmul")
11153 (match_operand:TF 3 "div_operator" "")
11154 (const_string "fdiv")
11155 ]
11156 (const_string "fop")))
11157 (set_attr "mode" "DF")])
11158
e075ae69
RH
11159(define_split
11160 [(set (match_operand 0 "register_operand" "")
11161 (match_operator 3 "binary_fp_operator"
11162 [(float (match_operand:SI 1 "register_operand" ""))
11163 (match_operand 2 "register_operand" "")]))]
11164 "TARGET_80387 && reload_completed
11165 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb
JH
11166 [(const_int 0)]
11167 "
11168{
11169 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
11170 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
11171 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
11172 gen_rtx_fmt_ee (GET_CODE (operands[3]),
11173 GET_MODE (operands[3]),
11174 operands[4],
11175 operands[2])));
11176 ix86_free_from_memory (GET_MODE (operands[1]));
11177 DONE;
11178}")
e075ae69
RH
11179
11180(define_split
11181 [(set (match_operand 0 "register_operand" "")
11182 (match_operator 3 "binary_fp_operator"
11183 [(match_operand 1 "register_operand" "")
11184 (float (match_operand:SI 2 "register_operand" ""))]))]
11185 "TARGET_80387 && reload_completed
11186 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4211a8fb
JH
11187 [(const_int 0)]
11188 "
11189{
11190 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11191 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
11192 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2b66da3c 11193 gen_rtx_fmt_ee (GET_CODE (operands[3]),
4211a8fb
JH
11194 GET_MODE (operands[3]),
11195 operands[1],
11196 operands[4])));
11197 ix86_free_from_memory (GET_MODE (operands[2]));
11198 DONE;
11199}")
e075ae69
RH
11200\f
11201;; FPU special functions.
11202
a8083431
JH
11203(define_expand "sqrtsf2"
11204 [(set (match_operand:SF 0 "register_operand" "")
11205 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
ca9a9b12 11206 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE"
a8083431
JH
11207 "
11208{
11209 if (!TARGET_SSE)
11210 operands[1] = force_reg (SFmode, operands[1]);
11211}")
11212
11213(define_insn "sqrtsf2_1"
ca9a9b12
JH
11214 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
11215 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
a8083431
JH
11216 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11217 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
11218 "@
11219 fsqrt
11220 sqrtss\\t{%1, %0|%0, %1}"
11221 [(set_attr "type" "fpspc,sse")
11222 (set_attr "mode" "SF,SF")
11223 (set_attr "athlon_decode" "direct,*")])
11224
11225(define_insn "sqrtsf2_1_sse_only"
ca9a9b12
JH
11226 [(set (match_operand:SF 0 "register_operand" "=x")
11227 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
a8083431
JH
11228 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
11229 "sqrtss\\t{%1, %0|%0, %1}"
11230 [(set_attr "type" "sse")
11231 (set_attr "mode" "SF")
11232 (set_attr "athlon_decode" "*")])
11233
11234(define_insn "sqrtsf2_i387"
e075ae69
RH
11235 [(set (match_operand:SF 0 "register_operand" "=f")
11236 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
a8083431
JH
11237 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11238 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
e075ae69 11239 "fsqrt"
0b5107cf 11240 [(set_attr "type" "fpspc")
6ef67412 11241 (set_attr "mode" "SF")
0b5107cf 11242 (set_attr "athlon_decode" "direct")])
e075ae69 11243
a8083431
JH
11244(define_expand "sqrtdf2"
11245 [(set (match_operand:DF 0 "register_operand" "")
11246 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
11247 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
11248 "
11249{
11250 if (!TARGET_SSE2)
11251 operands[1] = force_reg (SFmode, operands[1]);
11252}")
11253
11254(define_insn "sqrtdf2_1"
11255 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
11256 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
11257 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11258 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
11259 "@
11260 fsqrt
11261 sqrtsd\\t{%1, %0|%0, %1}"
11262 [(set_attr "type" "fpspc,sse")
11263 (set_attr "mode" "DF,DF")
11264 (set_attr "athlon_decode" "direct,*")])
11265
11266(define_insn "sqrtdf2_1_sse_only"
11267 [(set (match_operand:DF 0 "register_operand" "=Y")
11268 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
11269 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
11270 "sqrtsd\\t{%1, %0|%0, %1}"
11271 [(set_attr "type" "sse")
11272 (set_attr "mode" "DF")
11273 (set_attr "athlon_decode" "*")])
11274
11275(define_insn "sqrtdf2_i387"
e075ae69
RH
11276 [(set (match_operand:DF 0 "register_operand" "=f")
11277 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
11278 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
a8083431 11279 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
e075ae69 11280 "fsqrt"
0b5107cf 11281 [(set_attr "type" "fpspc")
6ef67412 11282 (set_attr "mode" "DF")
0b5107cf 11283 (set_attr "athlon_decode" "direct")])
e075ae69 11284
6343a50e 11285(define_insn "*sqrtextendsfdf2"
e075ae69
RH
11286 [(set (match_operand:DF 0 "register_operand" "=f")
11287 (sqrt:DF (float_extend:DF
11288 (match_operand:SF 1 "register_operand" "0"))))]
ca9a9b12 11289 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2"
e075ae69 11290 "fsqrt"
0b5107cf 11291 [(set_attr "type" "fpspc")
6ef67412 11292 (set_attr "mode" "DF")
0b5107cf 11293 (set_attr "athlon_decode" "direct")])
e075ae69
RH
11294
11295(define_insn "sqrtxf2"
11296 [(set (match_operand:XF 0 "register_operand" "=f")
11297 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1e07edd3 11298 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT
de6c5979 11299 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
e075ae69 11300 "fsqrt"
0b5107cf 11301 [(set_attr "type" "fpspc")
6ef67412 11302 (set_attr "mode" "XF")
0b5107cf 11303 (set_attr "athlon_decode" "direct")])
e075ae69 11304
2b589241
JH
11305(define_insn "sqrttf2"
11306 [(set (match_operand:TF 0 "register_operand" "=f")
11307 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
11308 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
de6c5979 11309 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
2b589241
JH
11310 "fsqrt"
11311 [(set_attr "type" "fpspc")
11312 (set_attr "mode" "XF")
11313 (set_attr "athlon_decode" "direct")])
11314
6343a50e 11315(define_insn "*sqrtextenddfxf2"
e075ae69
RH
11316 [(set (match_operand:XF 0 "register_operand" "=f")
11317 (sqrt:XF (float_extend:XF
11318 (match_operand:DF 1 "register_operand" "0"))))]
1e07edd3 11319 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT"
e075ae69 11320 "fsqrt"
0b5107cf 11321 [(set_attr "type" "fpspc")
6ef67412 11322 (set_attr "mode" "XF")
0b5107cf 11323 (set_attr "athlon_decode" "direct")])
e075ae69 11324
2b589241
JH
11325(define_insn "*sqrtextenddftf2"
11326 [(set (match_operand:TF 0 "register_operand" "=f")
11327 (sqrt:TF (float_extend:TF
11328 (match_operand:DF 1 "register_operand" "0"))))]
11329 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11330 "fsqrt"
11331 [(set_attr "type" "fpspc")
11332 (set_attr "mode" "XF")
11333 (set_attr "athlon_decode" "direct")])
11334
6343a50e 11335(define_insn "*sqrtextendsfxf2"
e075ae69
RH
11336 [(set (match_operand:XF 0 "register_operand" "=f")
11337 (sqrt:XF (float_extend:XF
11338 (match_operand:SF 1 "register_operand" "0"))))]
1e07edd3 11339 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT"
e075ae69 11340 "fsqrt"
0b5107cf 11341 [(set_attr "type" "fpspc")
6ef67412 11342 (set_attr "mode" "XF")
0b5107cf 11343 (set_attr "athlon_decode" "direct")])
e075ae69 11344
2b589241
JH
11345(define_insn "*sqrtextendsftf2"
11346 [(set (match_operand:TF 0 "register_operand" "=f")
11347 (sqrt:TF (float_extend:TF
11348 (match_operand:SF 1 "register_operand" "0"))))]
11349 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11350 "fsqrt"
11351 [(set_attr "type" "fpspc")
11352 (set_attr "mode" "XF")
11353 (set_attr "athlon_decode" "direct")])
11354
e075ae69
RH
11355(define_insn "sindf2"
11356 [(set (match_operand:DF 0 "register_operand" "=f")
11357 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
de6c5979
BL
11358 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11359 && flag_unsafe_math_optimizations"
e075ae69 11360 "fsin"
6ef67412
JH
11361 [(set_attr "type" "fpspc")
11362 (set_attr "mode" "DF")])
e075ae69
RH
11363
11364(define_insn "sinsf2"
11365 [(set (match_operand:SF 0 "register_operand" "=f")
11366 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
de6c5979
BL
11367 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11368 && flag_unsafe_math_optimizations"
e075ae69 11369 "fsin"
6ef67412
JH
11370 [(set_attr "type" "fpspc")
11371 (set_attr "mode" "SF")])
5f3d14e3 11372
6343a50e 11373(define_insn "*sinextendsfdf2"
e075ae69
RH
11374 [(set (match_operand:DF 0 "register_operand" "=f")
11375 (unspec:DF [(float_extend:DF
11376 (match_operand:SF 1 "register_operand" "0"))] 1))]
de6c5979
BL
11377 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11378 && flag_unsafe_math_optimizations"
e075ae69 11379 "fsin"
6ef67412
JH
11380 [(set_attr "type" "fpspc")
11381 (set_attr "mode" "DF")])
4f9ca067 11382
e075ae69
RH
11383(define_insn "sinxf2"
11384 [(set (match_operand:XF 0 "register_operand" "=f")
11385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
1e07edd3 11386 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT
de6c5979 11387 && flag_unsafe_math_optimizations"
e075ae69 11388 "fsin"
6ef67412
JH
11389 [(set_attr "type" "fpspc")
11390 (set_attr "mode" "XF")])
5f3d14e3 11391
2b589241
JH
11392(define_insn "sintf2"
11393 [(set (match_operand:TF 0 "register_operand" "=f")
11394 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
de6c5979
BL
11395 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11396 && flag_unsafe_math_optimizations"
2b589241
JH
11397 "fsin"
11398 [(set_attr "type" "fpspc")
11399 (set_attr "mode" "XF")])
11400
e075ae69
RH
11401(define_insn "cosdf2"
11402 [(set (match_operand:DF 0 "register_operand" "=f")
11403 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
de6c5979
BL
11404 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11405 && flag_unsafe_math_optimizations"
e075ae69 11406 "fcos"
6ef67412
JH
11407 [(set_attr "type" "fpspc")
11408 (set_attr "mode" "DF")])
bca7cce2 11409
e075ae69
RH
11410(define_insn "cossf2"
11411 [(set (match_operand:SF 0 "register_operand" "=f")
11412 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
de6c5979
BL
11413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11414 && flag_unsafe_math_optimizations"
e075ae69 11415 "fcos"
6ef67412
JH
11416 [(set_attr "type" "fpspc")
11417 (set_attr "mode" "SF")])
bca7cce2 11418
6343a50e 11419(define_insn "*cosextendsfdf2"
e075ae69
RH
11420 [(set (match_operand:DF 0 "register_operand" "=f")
11421 (unspec:DF [(float_extend:DF
11422 (match_operand:SF 1 "register_operand" "0"))] 2))]
de6c5979
BL
11423 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11424 && flag_unsafe_math_optimizations"
e075ae69 11425 "fcos"
6ef67412
JH
11426 [(set_attr "type" "fpspc")
11427 (set_attr "mode" "DF")])
5f3d14e3 11428
e075ae69
RH
11429(define_insn "cosxf2"
11430 [(set (match_operand:XF 0 "register_operand" "=f")
11431 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
1e07edd3 11432 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
de6c5979 11433 && flag_unsafe_math_optimizations"
e075ae69 11434 "fcos"
6ef67412
JH
11435 [(set_attr "type" "fpspc")
11436 (set_attr "mode" "XF")])
2b589241
JH
11437
11438(define_insn "costf2"
11439 [(set (match_operand:TF 0 "register_operand" "=f")
11440 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
de6c5979
BL
11441 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
11442 && flag_unsafe_math_optimizations"
2b589241
JH
11443 "fcos"
11444 [(set_attr "type" "fpspc")
11445 (set_attr "mode" "XF")])
e075ae69
RH
11446\f
11447;; Block operation instructions
886c62d1 11448
7c7ef435
JH
11449(define_insn "cld"
11450 [(set (reg:SI 19) (const_int 0))]
11451 ""
11452 "cld"
11453 [(set_attr "type" "cld")])
11454
886c62d1 11455(define_expand "movstrsi"
f90800f8
JH
11456 [(use (match_operand:BLK 0 "memory_operand" ""))
11457 (use (match_operand:BLK 1 "memory_operand" ""))
79f05c19 11458 (use (match_operand:SI 2 "nonmemory_operand" ""))
f90800f8 11459 (use (match_operand:SI 3 "const_int_operand" ""))]
886c62d1
JVA
11460 ""
11461 "
11462{
f90800f8 11463 rtx srcreg, destreg, countreg;
79f05c19
JH
11464 int align = 0;
11465 int count = -1;
0e4970d7
RK
11466 rtx insns;
11467
11468 start_sequence ();
664921b4 11469
79f05c19
JH
11470 if (GET_CODE (operands[3]) == CONST_INT)
11471 align = INTVAL (operands[3]);
11472
11473 /* This simple hack avoids all inlining code and simplifies code bellow. */
11474 if (!TARGET_ALIGN_STRINGOPS)
11475 align = 32;
11476
11477 if (GET_CODE (operands[2]) == CONST_INT)
11478 count = INTVAL (operands[2]);
664921b4 11479
f90800f8
JH
11480 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11481 srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
664921b4 11482
0e4970d7 11483 emit_insn (gen_cld ());
79f05c19 11484
e2e52e1b
JH
11485 /* When optimizing for size emit simple rep ; movsb instruction for
11486 counts not divisible by 4. */
79f05c19
JH
11487
11488 if ((!optimize || optimize_size)
11489 && (count < 0 || (count & 0x03)))
f90800f8
JH
11490 {
11491 countreg = copy_to_mode_reg (SImode, operands[2]);
11492 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
11493 destreg, srcreg, countreg));
11494 }
79f05c19
JH
11495
11496 /* For constant aligned (or small unaligned) copies use rep movsl
11497 followed by code copying the rest. For PentiumPro ensure 8 byte
11498 alignment to allow rep movsl acceleration. */
11499
11500 else if (count >= 0
11501 && (align >= 8
11502 || (!TARGET_PENTIUMPRO && align >= 4)
11503 || optimize_size || count < 64))
f90800f8 11504 {
79f05c19 11505 if (count & ~0x03)
f90800f8
JH
11506 {
11507 countreg = copy_to_mode_reg (SImode,
79f05c19 11508 GEN_INT ((count >> 2)
f90800f8
JH
11509 & 0x3fffffff));
11510 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
11511 destreg, srcreg, countreg));
11512 }
79f05c19 11513 if (count & 0x02)
f90800f8 11514 emit_insn (gen_strmovhi (destreg, srcreg));
79f05c19 11515 if (count & 0x01)
f90800f8
JH
11516 emit_insn (gen_strmovqi (destreg, srcreg));
11517 }
79f05c19
JH
11518 /* The generic code based on the glibc implementation:
11519 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
11520 allowing accelerated copying there)
11521 - copy the data using rep movsl
11522 - copy the rest. */
11523 else
11524 {
11525 rtx countreg2;
11526 rtx label = NULL;
11527
11528 /* In case we don't know anything about the alignment, default to
11529 library version, since it is usually equally fast and result in
11530 shorter code. */
11531 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
4ddb47b3
RK
11532 {
11533 end_sequence ();
11534 FAIL;
11535 }
79f05c19
JH
11536
11537 if (TARGET_SINGLE_STRINGOP)
4ddb47b3 11538 emit_insn (gen_cld ());
79f05c19
JH
11539
11540 countreg2 = gen_reg_rtx (SImode);
11541 countreg = copy_to_mode_reg (SImode, operands[2]);
11542
11543 /* We don't use loops to align destination and to copy parts smaller
11544 than 4 bytes, because gcc is able to optimize such code better (in
11545 the case the destination or the count really is aligned, gcc is often
11546 able to predict the branches) and also it is friendlier to the
11547 hardware branch prediction.
11548
11549 Using loops is benefical for generic case, because we can
11550 handle small counts using the loops. Many CPUs (such as Athlon)
11551 have large REP prefix setup costs.
11552
11553 This is quite costy. Maybe we can revisit this decision later or
11554 add some customizability to this code. */
11555
11556 if (count < 0
11557 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11558 {
11559 label = gen_label_rtx ();
11560 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11561 LEU, 0, SImode, 1, 0, label);
11562 }
11563 if (align <= 1)
11564 {
11565 rtx label = gen_label_rtx ();
11566 rtx tmpcount = gen_reg_rtx (SImode);
11567 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11568 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11569 SImode, 1, 0, label);
11570 emit_insn (gen_strmovqi (destreg, srcreg));
11571 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11572 emit_label (label);
11573 LABEL_NUSES (label) = 1;
11574 }
11575 if (align <= 2)
11576 {
11577 rtx label = gen_label_rtx ();
11578 rtx tmpcount = gen_reg_rtx (SImode);
11579 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11580 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11581 SImode, 1, 0, label);
11582 emit_insn (gen_strmovhi (destreg, srcreg));
11583 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11584 emit_label (label);
11585 LABEL_NUSES (label) = 1;
11586 }
11587 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11588 {
11589 rtx label = gen_label_rtx ();
11590 rtx tmpcount = gen_reg_rtx (SImode);
11591 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11592 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11593 SImode, 1, 0, label);
11594 emit_insn (gen_strmovsi (destreg, srcreg));
11595 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11596 emit_label (label);
11597 LABEL_NUSES (label) = 1;
11598 }
11599
11600 if (!TARGET_SINGLE_STRINGOP)
11601 emit_insn (gen_cld());
11602 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11603 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
11604 destreg, srcreg, countreg2));
11605
11606 if (label)
11607 {
11608 emit_label (label);
11609 LABEL_NUSES (label) = 1;
11610 }
11611 if (align > 2 && count > 0 && (count & 2))
11612 emit_insn (gen_strmovhi (destreg, srcreg));
11613 if (align <= 2 || count < 0)
11614 {
11615 rtx label = gen_label_rtx ();
11616 rtx tmpcount = gen_reg_rtx (SImode);
11617 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11618 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11619 SImode, 1, 0, label);
11620 emit_insn (gen_strmovhi (destreg, srcreg));
11621 emit_label (label);
11622 LABEL_NUSES (label) = 1;
11623 }
11624 if (align > 1 && count > 0 && (count & 1))
11625 emit_insn (gen_strmovsi (destreg, srcreg));
11626 if (align <= 1 || count < 0)
11627 {
11628 rtx label = gen_label_rtx ();
11629 rtx tmpcount = gen_reg_rtx (SImode);
11630 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11631 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11632 SImode, 1, 0, label);
11633 emit_insn (gen_strmovqi (destreg, srcreg));
11634 emit_label (label);
11635 LABEL_NUSES (label) = 1;
11636 }
11637 }
0e4970d7
RK
11638
11639 insns = get_insns ();
11640 end_sequence ();
11641
11642 ix86_set_move_mem_attrs (insns, operands[0], operands[1], destreg, srcreg);
11643 emit_insns (insns);
f90800f8 11644 DONE;
886c62d1
JVA
11645}")
11646
f90800f8
JH
11647;; Most CPUs don't like single string operations
11648;; Handle this case here to simplify previous expander.
56c0e8fa 11649
79f05c19
JH
11650(define_expand "strmovsi"
11651 [(set (match_dup 2)
11652 (mem:SI (match_operand:SI 1 "register_operand" "")))
11653 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
11654 (match_dup 2))
11655 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11656 (clobber (reg:CC 17))])
11657 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
11658 (clobber (reg:CC 17))])]
11659 ""
11660 "
11661{
11662 if (TARGET_SINGLE_STRINGOP || optimize_size)
11663 {
11664 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
11665 operands[1]));
11666 DONE;
11667 }
11668 else
11669 operands[2] = gen_reg_rtx (SImode);
11670}")
11671
f90800f8
JH
11672(define_expand "strmovhi"
11673 [(set (match_dup 2)
11674 (mem:HI (match_operand:SI 1 "register_operand" "")))
11675 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
11676 (match_dup 2))
11677 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11678 (clobber (reg:CC 17))])
11679 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
11680 (clobber (reg:CC 17))])]
886c62d1 11681 ""
f90800f8 11682 "
886c62d1 11683{
f90800f8 11684 if (TARGET_SINGLE_STRINGOP || optimize_size)
886c62d1 11685 {
f90800f8
JH
11686 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
11687 operands[1]));
11688 DONE;
11689 }
11690 else
11691 operands[2] = gen_reg_rtx (HImode);
11692}")
886c62d1 11693
f90800f8
JH
11694(define_expand "strmovqi"
11695 [(set (match_dup 2)
11696 (mem:QI (match_operand:SI 1 "register_operand" "")))
11697 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
11698 (match_dup 2))
11699 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11700 (clobber (reg:CC 17))])
11701 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
11702 (clobber (reg:CC 17))])]
11703 ""
11704 "
11705{
11706 if (TARGET_SINGLE_STRINGOP || optimize_size)
11707 {
11708 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
11709 operands[1]));
11710 DONE;
886c62d1 11711 }
f90800f8
JH
11712 else
11713 operands[2] = gen_reg_rtx (QImode);
11714}")
11715
79f05c19
JH
11716(define_insn "strmovsi_1"
11717 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
11718 (mem:SI (match_operand:SI 3 "register_operand" "1")))
11719 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 11720 (plus:SI (match_dup 2)
79f05c19
JH
11721 (const_int 4)))
11722 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 11723 (plus:SI (match_dup 3)
79f05c19
JH
11724 (const_int 4)))
11725 (use (reg:SI 19))]
11726 "TARGET_SINGLE_STRINGOP || optimize_size"
11727 "movsl"
11728 [(set_attr "type" "str")
6ef67412 11729 (set_attr "mode" "SI")
79f05c19
JH
11730 (set_attr "memory" "both")])
11731
f90800f8
JH
11732(define_insn "strmovhi_1"
11733 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
11734 (mem:HI (match_operand:SI 3 "register_operand" "1")))
11735 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 11736 (plus:SI (match_dup 2)
f90800f8
JH
11737 (const_int 2)))
11738 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 11739 (plus:SI (match_dup 3)
f90800f8
JH
11740 (const_int 2)))
11741 (use (reg:SI 19))]
11742 "TARGET_SINGLE_STRINGOP || optimize_size"
11743 "movsw"
11744 [(set_attr "type" "str")
11745 (set_attr "memory" "both")
6ef67412 11746 (set_attr "mode" "HI")])
f90800f8
JH
11747
11748(define_insn "strmovqi_1"
11749 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
11750 (mem:QI (match_operand:SI 3 "register_operand" "1")))
11751 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 11752 (plus:SI (match_dup 2)
f90800f8
JH
11753 (const_int 1)))
11754 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 11755 (plus:SI (match_dup 3)
f90800f8
JH
11756 (const_int 1)))
11757 (use (reg:SI 19))]
11758 "TARGET_SINGLE_STRINGOP || optimize_size"
11759 "movsb"
11760 [(set_attr "type" "str")
6ef67412
JH
11761 (set_attr "memory" "both")
11762 (set_attr "mode" "QI")])
f90800f8 11763
f90800f8
JH
11764(define_insn "rep_movsi"
11765 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 11766 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
11767 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
11768 (const_int 2))
11769 (match_operand:SI 3 "register_operand" "0")))
f90800f8 11770 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb
JH
11771 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
11772 (match_operand:SI 4 "register_operand" "1")))
f90800f8
JH
11773 (set (mem:BLK (match_dup 3))
11774 (mem:BLK (match_dup 4)))
b1cdafbb 11775 (use (match_dup 5))
f90800f8
JH
11776 (use (reg:SI 19))]
11777 ""
11778 "rep\;movsl|rep movsd"
11779 [(set_attr "type" "str")
6ef67412
JH
11780 (set_attr "prefix_rep" "1")
11781 (set_attr "memory" "both")
11782 (set_attr "mode" "SI")])
f90800f8
JH
11783
11784(define_insn "rep_movqi"
11785 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
f90800f8 11786 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
11787 (plus:SI (match_operand:SI 3 "register_operand" "0")
11788 (match_operand:SI 5 "register_operand" "2")))
f90800f8 11789 (set (match_operand:SI 1 "register_operand" "=S")
b1cdafbb 11790 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
f90800f8
JH
11791 (set (mem:BLK (match_dup 3))
11792 (mem:BLK (match_dup 4)))
b1cdafbb 11793 (use (match_dup 5))
f90800f8
JH
11794 (use (reg:SI 19))]
11795 ""
11796 "rep\;movsb|rep movsb"
11797 [(set_attr "type" "str")
6ef67412
JH
11798 (set_attr "prefix_rep" "1")
11799 (set_attr "memory" "both")
11800 (set_attr "mode" "SI")])
886c62d1 11801
0ae40045 11802(define_expand "clrstrsi"
e2e52e1b 11803 [(use (match_operand:BLK 0 "memory_operand" ""))
79f05c19 11804 (use (match_operand:SI 1 "nonmemory_operand" ""))
e2e52e1b 11805 (use (match_operand:SI 2 "const_int_operand" ""))]
0ae40045
RK
11806 ""
11807 "
11808{
79f05c19
JH
11809 /* See comments in movstr expanders. The code is mostly identical. */
11810
e2e52e1b 11811 rtx destreg, zeroreg, countreg;
79f05c19
JH
11812 int align = 0;
11813 int count = -1;
4082ab0f
RK
11814 rtx insns;
11815
11816 start_sequence ();
0ae40045 11817
79f05c19
JH
11818 if (GET_CODE (operands[2]) == CONST_INT)
11819 align = INTVAL (operands[2]);
11820
11821 /* This simple hack avoids all inlining code and simplifies code bellow. */
11822 if (!TARGET_ALIGN_STRINGOPS)
11823 align = 32;
11824
11825 if (GET_CODE (operands[1]) == CONST_INT)
11826 count = INTVAL (operands[1]);
0ae40045 11827
e2e52e1b
JH
11828 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11829
4082ab0f 11830 emit_insn (gen_cld ());
e2e52e1b
JH
11831
11832 /* When optimizing for size emit simple rep ; movsb instruction for
11833 counts not divisible by 4. */
79f05c19
JH
11834
11835 if ((!optimize || optimize_size)
11836 && (count < 0 || (count & 0x03)))
e2e52e1b
JH
11837 {
11838 countreg = copy_to_mode_reg (SImode, operands[1]);
11839 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
11840 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
11841 destreg, countreg));
11842 }
79f05c19
JH
11843 else if (count >= 0
11844 && (align >= 8
11845 || (!TARGET_PENTIUMPRO && align >= 4)
11846 || optimize_size || count < 64))
e2e52e1b
JH
11847 {
11848 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11849 if (INTVAL (operands[1]) & ~0x03)
11850 {
11851 countreg = copy_to_mode_reg (SImode,
11852 GEN_INT ((INTVAL (operands[1]) >> 2)
11853 & 0x3fffffff));
11854 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
11855 destreg, countreg));
11856 }
11857 if (INTVAL (operands[1]) & 0x02)
11858 emit_insn (gen_strsethi (destreg,
11859 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11860 if (INTVAL (operands[1]) & 0x01)
11861 emit_insn (gen_strsetqi (destreg,
11862 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11863 }
79f05c19
JH
11864 else
11865 {
11866 rtx countreg2;
11867 rtx label = NULL;
11868
11869 /* In case we don't know anything about the alignment, default to
11870 library version, since it is usually equally fast and result in
11871 shorter code. */
11872 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
4082ab0f
RK
11873 {
11874 end_sequence ();
11875 FAIL;
11876 }
79f05c19
JH
11877
11878 if (TARGET_SINGLE_STRINGOP)
4082ab0f 11879 emit_insn (gen_cld ());
79f05c19
JH
11880
11881 countreg2 = gen_reg_rtx (SImode);
11882 countreg = copy_to_mode_reg (SImode, operands[1]);
11883 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11884
11885 if (count < 0
11886 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11887 {
11888 label = gen_label_rtx ();
11889 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11890 LEU, 0, SImode, 1, 0, label);
11891 }
11892 if (align <= 1)
11893 {
11894 rtx label = gen_label_rtx ();
11895 rtx tmpcount = gen_reg_rtx (SImode);
11896 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11897 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11898 SImode, 1, 0, label);
11899 emit_insn (gen_strsetqi (destreg,
11900 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11901 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11902 emit_label (label);
11903 LABEL_NUSES (label) = 1;
11904 }
11905 if (align <= 2)
11906 {
11907 rtx label = gen_label_rtx ();
11908 rtx tmpcount = gen_reg_rtx (SImode);
11909 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11910 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11911 SImode, 1, 0, label);
11912 emit_insn (gen_strsethi (destreg,
11913 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11914 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11915 emit_label (label);
11916 LABEL_NUSES (label) = 1;
11917 }
11918 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11919 {
11920 rtx label = gen_label_rtx ();
11921 rtx tmpcount = gen_reg_rtx (SImode);
11922 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11923 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11924 SImode, 1, 0, label);
4a92092a 11925 emit_insn (gen_strsetsi (destreg, zeroreg));
79f05c19
JH
11926 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11927 emit_label (label);
11928 LABEL_NUSES (label) = 1;
11929 }
11930
11931 if (!TARGET_SINGLE_STRINGOP)
11932 emit_insn (gen_cld());
11933 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11934 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
11935 destreg, countreg2));
11936
11937 if (label)
11938 {
11939 emit_label (label);
11940 LABEL_NUSES (label) = 1;
11941 }
11942 if (align > 2 && count > 0 && (count & 2))
11943 emit_insn (gen_strsethi (destreg,
11944 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11945 if (align <= 2 || count < 0)
11946 {
11947 rtx label = gen_label_rtx ();
11948 rtx tmpcount = gen_reg_rtx (SImode);
11949 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11950 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11951 SImode, 1, 0, label);
11952 emit_insn (gen_strsethi (destreg,
11953 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11954 emit_label (label);
11955 LABEL_NUSES (label) = 1;
11956 }
11957 if (align > 1 && count > 0 && (count & 1))
11958 emit_insn (gen_strsetqi (destreg,
11959 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11960 if (align <= 1 || count < 0)
11961 {
11962 rtx label = gen_label_rtx ();
11963 rtx tmpcount = gen_reg_rtx (SImode);
11964 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11965 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11966 SImode, 1, 0, label);
11967 emit_insn (gen_strsetqi (destreg,
11968 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11969 emit_label (label);
11970 LABEL_NUSES (label) = 1;
11971 }
11972 }
4082ab0f
RK
11973
11974 insns = get_insns ();
11975 end_sequence ();
11976
11977 ix86_set_move_mem_attrs (insns, operands[0], operands[0], destreg, destreg);
11978 emit_insns (insns);
11979
e2e52e1b
JH
11980 DONE;
11981}")
11982
11983;; Most CPUs don't like single string operations
11984;; Handle this case here to simplify previous expander.
0ae40045 11985
79f05c19
JH
11986(define_expand "strsetsi"
11987 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
11988 (match_operand:SI 1 "register_operand" ""))
11989 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11990 (clobber (reg:CC 17))])]
11991 ""
11992 "
11993{
11994 if (TARGET_SINGLE_STRINGOP || optimize_size)
11995 {
11996 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
11997 DONE;
11998 }
11999}")
12000
e2e52e1b
JH
12001(define_expand "strsethi"
12002 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
12003 (match_operand:HI 1 "register_operand" ""))
12004 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
12005 (clobber (reg:CC 17))])]
12006 ""
12007 "
12008{
12009 if (TARGET_SINGLE_STRINGOP || optimize_size)
12010 {
12011 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
12012 DONE;
12013 }
12014}")
0ae40045 12015
e2e52e1b
JH
12016(define_expand "strsetqi"
12017 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
12018 (match_operand:QI 1 "register_operand" ""))
12019 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12020 (clobber (reg:CC 17))])]
12021 ""
12022 "
12023{
12024 if (TARGET_SINGLE_STRINGOP || optimize_size)
12025 {
12026 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
12027 DONE;
12028 }
0ae40045
RK
12029}")
12030
79f05c19
JH
12031(define_insn "strsetsi_1"
12032 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
12033 (match_operand:SI 2 "register_operand" "a"))
12034 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 12035 (plus:SI (match_dup 1)
79f05c19
JH
12036 (const_int 4)))
12037 (use (reg:SI 19))]
12038 "TARGET_SINGLE_STRINGOP || optimize_size"
12039 "stosl"
12040 [(set_attr "type" "str")
6ef67412
JH
12041 (set_attr "memory" "store")
12042 (set_attr "mode" "SI")])
79f05c19 12043
e2e52e1b
JH
12044(define_insn "strsethi_1"
12045 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
12046 (match_operand:HI 2 "register_operand" "a"))
12047 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 12048 (plus:SI (match_dup 1)
e2e52e1b
JH
12049 (const_int 2)))
12050 (use (reg:SI 19))]
12051 "TARGET_SINGLE_STRINGOP || optimize_size"
12052 "stosw"
12053 [(set_attr "type" "str")
12054 (set_attr "memory" "store")
6ef67412 12055 (set_attr "mode" "HI")])
e2e52e1b
JH
12056
12057(define_insn "strsetqi_1"
12058 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
12059 (match_operand:QI 2 "register_operand" "a"))
12060 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb 12061 (plus:SI (match_dup 1)
e2e52e1b
JH
12062 (const_int 1)))
12063 (use (reg:SI 19))]
12064 "TARGET_SINGLE_STRINGOP || optimize_size"
12065 "stosb"
12066 [(set_attr "type" "str")
6ef67412
JH
12067 (set_attr "memory" "store")
12068 (set_attr "mode" "QI")])
e2e52e1b 12069
e2e52e1b
JH
12070(define_insn "rep_stossi"
12071 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 12072 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
12073 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
12074 (const_int 2))
12075 (match_operand:SI 3 "register_operand" "0")))
e2e52e1b 12076 (set (mem:BLK (match_dup 3))
0ae40045 12077 (const_int 0))
b1cdafbb
JH
12078 (use (match_operand:SI 2 "register_operand" "a"))
12079 (use (match_dup 4))
e2e52e1b 12080 (use (reg:SI 19))]
0ae40045 12081 ""
e2e52e1b
JH
12082 "rep\;stosl|rep stosd"
12083 [(set_attr "type" "str")
6ef67412
JH
12084 (set_attr "prefix_rep" "1")
12085 (set_attr "memory" "store")
12086 (set_attr "mode" "SI")])
0ae40045 12087
e2e52e1b
JH
12088(define_insn "rep_stosqi"
12089 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
e2e52e1b 12090 (set (match_operand:SI 0 "register_operand" "=D")
b1cdafbb
JH
12091 (plus:SI (match_operand:SI 3 "register_operand" "0")
12092 (match_operand:SI 4 "register_operand" "1")))
e2e52e1b
JH
12093 (set (mem:BLK (match_dup 3))
12094 (const_int 0))
b1cdafbb
JH
12095 (use (match_operand:QI 2 "register_operand" "a"))
12096 (use (match_dup 4))
e2e52e1b
JH
12097 (use (reg:SI 19))]
12098 ""
12099 "rep\;stosb|rep stosb"
12100 [(set_attr "type" "str")
6ef67412
JH
12101 (set_attr "prefix_rep" "1")
12102 (set_attr "memory" "store")
12103 (set_attr "mode" "QI")])
0ae40045 12104
886c62d1 12105(define_expand "cmpstrsi"
e075ae69
RH
12106 [(set (match_operand:SI 0 "register_operand" "")
12107 (compare:SI (match_operand:BLK 1 "general_operand" "")
12108 (match_operand:BLK 2 "general_operand" "")))
12109 (use (match_operand:SI 3 "general_operand" ""))
12110 (use (match_operand:SI 4 "immediate_operand" ""))]
886c62d1
JVA
12111 ""
12112 "
12113{
e075ae69
RH
12114 rtx addr1, addr2, out, outlow, count, countreg, align;
12115
12116 out = operands[0];
12117 if (GET_CODE (out) != REG)
12118 out = gen_reg_rtx (SImode);
783cdf65
JVA
12119
12120 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
12121 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
e075ae69
RH
12122
12123 count = operands[3];
12124 countreg = copy_to_mode_reg (SImode, count);
12125
12126 /* %%% Iff we are testing strict equality, we can use known alignment
12127 to good advantage. This may be possible with combine, particularly
12128 once cc0 is dead. */
12129 align = operands[4];
783cdf65 12130
7c7ef435 12131 emit_insn (gen_cld ());
e075ae69
RH
12132 if (GET_CODE (count) == CONST_INT)
12133 {
12134 if (INTVAL (count) == 0)
12135 {
12136 emit_move_insn (operands[0], const0_rtx);
12137 DONE;
12138 }
b1cdafbb
JH
12139 emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align,
12140 addr1, addr2, countreg));
e075ae69
RH
12141 }
12142 else
e2e52e1b
JH
12143 {
12144 emit_insn (gen_cmpsi_1 (countreg, countreg));
b1cdafbb
JH
12145 emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align,
12146 addr1, addr2, countreg));
e2e52e1b 12147 }
e075ae69
RH
12148
12149 outlow = gen_lowpart (QImode, out);
12150 emit_insn (gen_cmpintqi (outlow));
12151 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
783cdf65 12152
e075ae69
RH
12153 if (operands[0] != out)
12154 emit_move_insn (operands[0], out);
783cdf65 12155
e075ae69 12156 DONE;
886c62d1
JVA
12157}")
12158
e075ae69
RH
12159;; Produce a tri-state integer (-1, 0, 1) from condition codes.
12160
12161(define_expand "cmpintqi"
12162 [(set (match_dup 1)
12163 (gtu:QI (reg:CC 17) (const_int 0)))
12164 (set (match_dup 2)
12165 (ltu:QI (reg:CC 17) (const_int 0)))
12166 (parallel [(set (match_operand:QI 0 "register_operand" "")
12167 (minus:QI (match_dup 1)
12168 (match_dup 2)))
12169 (clobber (reg:CC 17))])]
12170 ""
12171 "operands[1] = gen_reg_rtx (QImode);
12172 operands[2] = gen_reg_rtx (QImode);")
12173
f76e3b05
JVA
12174;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
12175;; zero. Emit extra code to make sure that a zero-length compare is EQ.
56c0e8fa 12176
e075ae69
RH
12177(define_insn "cmpstrsi_nz_1"
12178 [(set (reg:CC 17)
b1cdafbb
JH
12179 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
12180 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
12181 (use (match_operand:SI 6 "register_operand" "2"))
886c62d1 12182 (use (match_operand:SI 3 "immediate_operand" "i"))
7c7ef435 12183 (use (reg:SI 19))
b1cdafbb
JH
12184 (clobber (match_operand:SI 0 "register_operand" "=S"))
12185 (clobber (match_operand:SI 1 "register_operand" "=D"))
12186 (clobber (match_operand:SI 2 "register_operand" "=c"))]
886c62d1 12187 ""
7c7ef435 12188 "repz{\;| }cmpsb"
e2e52e1b 12189 [(set_attr "type" "str")
6ef67412
JH
12190 (set_attr "mode" "QI")
12191 (set_attr "prefix_rep" "1")])
886c62d1 12192
e075ae69 12193;; The same, but the count is not known to not be zero.
886c62d1 12194
e075ae69
RH
12195(define_insn "cmpstrsi_1"
12196 [(set (reg:CC 17)
b1cdafbb 12197 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
e075ae69 12198 (const_int 0))
2bed3391 12199 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
b1cdafbb 12200 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
e075ae69
RH
12201 (const_int 0)))
12202 (use (match_operand:SI 3 "immediate_operand" "i"))
e2e52e1b 12203 (use (reg:CC 17))
7c7ef435 12204 (use (reg:SI 19))
b1cdafbb
JH
12205 (clobber (match_operand:SI 0 "register_operand" "=S"))
12206 (clobber (match_operand:SI 1 "register_operand" "=D"))
12207 (clobber (match_operand:SI 2 "register_operand" "=c"))]
886c62d1 12208 ""
e2e52e1b
JH
12209 "repz{\;| }cmpsb"
12210 [(set_attr "type" "str")
6ef67412
JH
12211 (set_attr "mode" "QI")
12212 (set_attr "prefix_rep" "1")])
886c62d1 12213
e075ae69
RH
12214(define_expand "strlensi"
12215 [(set (match_operand:SI 0 "register_operand" "")
12216 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
12217 (match_operand:QI 2 "immediate_operand" "")
12218 (match_operand:SI 3 "immediate_operand" "")] 0))]
886c62d1 12219 ""
ce193852 12220 "
886c62d1 12221{
c5aa680d
RH
12222 rtx out, addr, scratch1, scratch2, scratch3;
12223 rtx eoschar = operands[2];
12224 rtx align = operands[3];
886c62d1 12225
79f05c19
JH
12226 /* The generic case of strlen expander is long. Avoid it's
12227 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
12228
12229 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
d9f32422 12230 && !TARGET_INLINE_ALL_STRINGOPS
79f05c19
JH
12231 && !optimize_size
12232 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
12233 FAIL;
12234
e075ae69
RH
12235 out = operands[0];
12236 addr = force_reg (Pmode, XEXP (operands[1], 0));
e075ae69 12237 scratch1 = gen_reg_rtx (SImode);
886c62d1 12238
e2e52e1b
JH
12239 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
12240 && !optimize_size)
628448b3 12241 {
e075ae69 12242 /* Well it seems that some optimizer does not combine a call like
628448b3 12243 foo(strlen(bar), strlen(bar));
e075ae69
RH
12244 when the move and the subtraction is done here. It does calculate
12245 the length just once when these instructions are done inside of
12246 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
12247 often used and I use one fewer register for the lifetime of
12248 output_strlen_unroll() this is better. */
12249
12250 if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
12251 emit_move_insn (scratch1, addr);
79f05c19 12252
e075ae69
RH
12253 emit_move_insn (out, addr);
12254
12255 ix86_expand_strlensi_unroll_1 (out, align, scratch1);
12256
12257 /* strlensi_unroll_1 returns the address of the zero at the end of
12258 the string, like memchr(), so compute the length by subtracting
12259 the start address. */
12260 emit_insn (gen_subsi3 (out, out, addr));
628448b3 12261 }
e075ae69
RH
12262 else
12263 {
12264 scratch2 = gen_reg_rtx (SImode);
12265 scratch3 = gen_reg_rtx (SImode);
628448b3 12266
e075ae69
RH
12267 emit_move_insn (scratch3, addr);
12268
7c7ef435 12269 emit_insn (gen_cld ());
e075ae69 12270 emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
b1cdafbb 12271 align, constm1_rtx, scratch3));
e075ae69
RH
12272 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
12273 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
12274 }
12275 DONE;
19c3fc24
RS
12276}")
12277
e075ae69
RH
12278(define_insn "strlensi_1"
12279 [(set (match_operand:SI 0 "register_operand" "=&c")
b1cdafbb 12280 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
e075ae69
RH
12281 (match_operand:QI 2 "general_operand" "a")
12282 (match_operand:SI 3 "immediate_operand" "i")
12283 (match_operand:SI 4 "immediate_operand" "0")] 0))
7c7ef435 12284 (use (reg:SI 19))
b1cdafbb 12285 (clobber (match_operand:SI 1 "register_operand" "=D"))
e075ae69
RH
12286 (clobber (reg:CC 17))]
12287 ""
7c7ef435 12288 "repnz{\;| }scasb"
e2e52e1b 12289 [(set_attr "type" "str")
6ef67412
JH
12290 (set_attr "mode" "QI")
12291 (set_attr "prefix_rep" "1")])
e075ae69
RH
12292\f
12293;; Conditional move instructions.
726e2d54 12294
e075ae69 12295(define_expand "movsicc"
6a4a5d95 12296 [(set (match_operand:SI 0 "register_operand" "")
e075ae69
RH
12297 (if_then_else:SI (match_operand 1 "comparison_operator" "")
12298 (match_operand:SI 2 "general_operand" "")
12299 (match_operand:SI 3 "general_operand" "")))]
12300 ""
12301 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 12302
e075ae69
RH
12303;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
12304;; the register first winds up with `sbbl $0,reg', which is also weird.
12305;; So just document what we're doing explicitly.
12306
12307(define_insn "x86_movsicc_0_m1"
12308 [(set (match_operand:SI 0 "register_operand" "=r")
12309 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
12310 (const_int -1)
12311 (const_int 0)))
12312 (clobber (reg:CC 17))]
12313 ""
12314 "sbb{l}\\t%0, %0"
12315 ; Since we don't have the proper number of operands for an alu insn,
12316 ; fill in all the blanks.
12317 [(set_attr "type" "alu")
12318 (set_attr "memory" "none")
12319 (set_attr "imm_disp" "false")
6ef67412
JH
12320 (set_attr "mode" "SI")
12321 (set_attr "length_immediate" "0")])
e075ae69 12322
6343a50e 12323(define_insn "*movsicc_noc"
e075ae69 12324 [(set (match_operand:SI 0 "register_operand" "=r,r")
9076b9c1 12325 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
12326 [(reg 17) (const_int 0)])
12327 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
12328 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
12329 "TARGET_CMOVE
12330 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69
RH
12331 "@
12332 cmov%C1\\t{%2, %0|%0, %2}
12333 cmov%c1\\t{%3, %0|%0, %3}"
6ef67412
JH
12334 [(set_attr "type" "icmov")
12335 (set_attr "mode" "SI")])
726e2d54 12336
726e2d54
JW
12337(define_expand "movhicc"
12338 [(set (match_operand:HI 0 "register_operand" "")
12339 (if_then_else:HI (match_operand 1 "comparison_operator" "")
12340 (match_operand:HI 2 "nonimmediate_operand" "")
12341 (match_operand:HI 3 "nonimmediate_operand" "")))]
d9f32422 12342 "TARGET_CMOVE && TARGET_HIMODE_MATH"
e075ae69 12343 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
726e2d54 12344
6343a50e 12345(define_insn "*movhicc_noc"
e075ae69 12346 [(set (match_operand:HI 0 "register_operand" "=r,r")
9076b9c1 12347 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
e075ae69
RH
12348 [(reg 17) (const_int 0)])
12349 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
12350 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
d525dfdf
JH
12351 "TARGET_CMOVE
12352 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69
RH
12353 "@
12354 cmov%C1\\t{%2, %0|%0, %2}
12355 cmov%c1\\t{%3, %0|%0, %3}"
6ef67412
JH
12356 [(set_attr "type" "icmov")
12357 (set_attr "mode" "HI")])
726e2d54 12358
56710e42 12359(define_expand "movsfcc"
726e2d54 12360 [(set (match_operand:SF 0 "register_operand" "")
56710e42 12361 (if_then_else:SF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
12362 (match_operand:SF 2 "register_operand" "")
12363 (match_operand:SF 3 "register_operand" "")))]
726e2d54 12364 "TARGET_CMOVE"
e075ae69 12365 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 12366
6343a50e 12367(define_insn "*movsfcc_1"
7093c9ea 12368 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
e075ae69
RH
12369 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
12370 [(reg 17) (const_int 0)])
7093c9ea
JH
12371 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
12372 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
12373 "TARGET_CMOVE
12374 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69
RH
12375 "@
12376 fcmov%F1\\t{%2, %0|%0, %2}
7093c9ea
JH
12377 fcmov%f1\\t{%3, %0|%0, %3}
12378 cmov%C1\\t{%2, %0|%0, %2}
12379 cmov%c1\\t{%3, %0|%0, %3}"
12380 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
12381 (set_attr "mode" "SF,SF,SI,SI")])
56710e42
SC
12382
12383(define_expand "movdfcc"
726e2d54 12384 [(set (match_operand:DF 0 "register_operand" "")
56710e42 12385 (if_then_else:DF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
12386 (match_operand:DF 2 "register_operand" "")
12387 (match_operand:DF 3 "register_operand" "")))]
726e2d54 12388 "TARGET_CMOVE"
e075ae69 12389 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 12390
6343a50e 12391(define_insn "*movdfcc_1"
7093c9ea 12392 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
e075ae69
RH
12393 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12394 [(reg 17) (const_int 0)])
7093c9ea
JH
12395 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
12396 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1e07edd3 12397 "TARGET_CMOVE && !TARGET_64BIT
7093c9ea 12398 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
e075ae69
RH
12399 "@
12400 fcmov%F1\\t{%2, %0|%0, %2}
7093c9ea
JH
12401 fcmov%f1\\t{%3, %0|%0, %3}
12402 #
12403 #"
12404 [(set_attr "type" "fcmov,fcmov,multi,multi")
6ef67412 12405 (set_attr "mode" "DF")])
56710e42 12406
1e07edd3
JH
12407(define_insn "*movdfcc_1_rex64"
12408 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
12409 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12410 [(reg 17) (const_int 0)])
12411 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
12412 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
12413 "TARGET_CMOVE && TARGET_64BIT
12414 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12415 "@
12416 fcmov%F1\\t{%2, %0|%0, %2}
12417 fcmov%f1\\t{%3, %0|%0, %3}
12418 cmov%C1\\t{%2, %0|%0, %2}
12419 cmov%c1\\t{%3, %0|%0, %3}"
12420 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
12421 (set_attr "mode" "DF")])
12422
7093c9ea
JH
12423(define_split
12424 [(set (match_operand:DF 0 "register_operand" "")
12425 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12426 [(match_operand 4 "" "") (const_int 0)])
12427 (match_operand:DF 2 "nonimmediate_operand" "")
12428 (match_operand:DF 3 "nonimmediate_operand" "")))]
1e07edd3 12429 "!ANY_FP_REG_P (operands[0]) && reload_completed && !TARGET_64BIT"
7093c9ea
JH
12430 [(set (match_dup 2)
12431 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12432 (match_dup 5)
12433 (match_dup 7)))
12434 (set (match_dup 3)
12435 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12436 (match_dup 6)
12437 (match_dup 8)))]
12438 "split_di (operands+2, 1, operands+5, operands+6);
12439 split_di (operands+3, 1, operands+7, operands+8);
12440 split_di (operands, 1, operands+2, operands+3);")
12441
56710e42 12442(define_expand "movxfcc"
726e2d54 12443 [(set (match_operand:XF 0 "register_operand" "")
56710e42 12444 (if_then_else:XF (match_operand 1 "comparison_operator" "")
e5e809f4
JL
12445 (match_operand:XF 2 "register_operand" "")
12446 (match_operand:XF 3 "register_operand" "")))]
1e07edd3 12447 "TARGET_CMOVE && !TARGET_64BIT"
e075ae69 12448 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
726e2d54 12449
2b589241
JH
12450(define_expand "movtfcc"
12451 [(set (match_operand:TF 0 "register_operand" "")
12452 (if_then_else:TF (match_operand 1 "comparison_operator" "")
12453 (match_operand:TF 2 "register_operand" "")
12454 (match_operand:TF 3 "register_operand" "")))]
12455 "TARGET_CMOVE"
12456 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12457
6343a50e 12458(define_insn "*movxfcc_1"
3aeae608 12459 [(set (match_operand:XF 0 "register_operand" "=f,f")
e075ae69
RH
12460 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
12461 [(reg 17) (const_int 0)])
3aeae608
JW
12462 (match_operand:XF 2 "register_operand" "f,0")
12463 (match_operand:XF 3 "register_operand" "0,f")))]
1e07edd3 12464 "TARGET_CMOVE && !TARGET_64BIT"
e075ae69
RH
12465 "@
12466 fcmov%F1\\t{%2, %0|%0, %2}
12467 fcmov%f1\\t{%3, %0|%0, %3}"
6ef67412
JH
12468 [(set_attr "type" "fcmov")
12469 (set_attr "mode" "XF")])
2b589241
JH
12470
12471(define_insn "*movtfcc_1"
12472 [(set (match_operand:TF 0 "register_operand" "=f,f")
12473 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
12474 [(reg 17) (const_int 0)])
12475 (match_operand:TF 2 "register_operand" "f,0")
12476 (match_operand:TF 3 "register_operand" "0,f")))]
12477 "TARGET_CMOVE"
12478 "@
12479 fcmov%F1\\t{%2, %0|%0, %2}
12480 fcmov%f1\\t{%3, %0|%0, %3}"
12481 [(set_attr "type" "fcmov")
12482 (set_attr "mode" "XF")])
7ada6625
JH
12483
12484(define_expand "minsf3"
12485 [(parallel [
12486 (set (match_operand:SF 0 "register_operand" "")
12487 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
12488 (match_operand:SF 2 "nonimmediate_operand" ""))
12489 (match_dup 1)
12490 (match_dup 2)))
12491 (clobber (reg:CC 17))])]
12492 "TARGET_SSE"
12493 "")
12494
12495(define_insn "*minsf"
12496 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
12497 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
12498 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
12499 (match_dup 1)
12500 (match_dup 2)))
12501 (clobber (reg:CC 17))]
12502 "TARGET_SSE && TARGET_IEEE_FP"
12503 "#")
12504
12505(define_insn "*minsf_nonieee"
12506 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
12507 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
12508 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
12509 (match_dup 1)
12510 (match_dup 2)))
12511 (clobber (reg:CC 17))]
12512 "TARGET_SSE && !TARGET_IEEE_FP"
12513 "#")
12514
12515(define_split
12516 [(set (match_operand:SF 0 "register_operand" "")
12517 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
12518 (match_operand:SF 2 "nonimmediate_operand" ""))
12519 (match_dup 1)
12520 (match_dup 2)))
12521 (clobber (reg:CC 17))]
12522 "SSE_REG_P (operands[0]) && reload_completed"
12523 [(set (match_dup 0)
12524 (if_then_else:SF (lt (match_dup 1)
12525 (match_dup 2))
12526 (match_dup 1)
12527 (match_dup 2)))])
12528
12529;; We can't represent the LT test directly. Do this by swapping the operands.
12530(define_split
12531 [(set (match_operand:SF 0 "register_operand" "")
12532 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
12533 (match_operand:SF 2 "register_operand" ""))
12534 (match_dup 1)
12535 (match_dup 2)))
12536 (clobber (reg:CC 17))]
12537 "FP_REG_P (operands[0]) && reload_completed"
12538 [(set (reg:CCFP 17)
12539 (compare:CCFP (match_dup 2)
12540 (match_dup 1)))
12541 (set (match_dup 0)
12542 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
12543 (match_dup 1)
12544 (match_dup 2)))])
12545
12546(define_insn "*minsf_sse"
12547 [(set (match_operand:SF 0 "register_operand" "=x")
12548 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
12549 (match_operand:SF 2 "nonimmediate_operand" "xm"))
12550 (match_dup 1)
12551 (match_dup 2)))]
12552 "TARGET_SSE && reload_completed"
12553 "minss\\t{%2, %0|%0, %2}"
12554 [(set_attr "type" "sse")
12555 (set_attr "mode" "SF")])
12556
12557(define_expand "mindf3"
12558 [(parallel [
12559 (set (match_operand:DF 0 "register_operand" "")
12560 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
12561 (match_operand:DF 2 "nonimmediate_operand" ""))
12562 (match_dup 1)
12563 (match_dup 2)))
12564 (clobber (reg:CC 17))])]
12565 "TARGET_SSE2"
12566 "#")
12567
12568(define_insn "*mindf"
12569 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
12570 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
12571 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
12572 (match_dup 1)
12573 (match_dup 2)))
12574 (clobber (reg:CC 17))]
12575 "TARGET_SSE2 && TARGET_IEEE_FP"
12576 "#")
12577
12578(define_insn "*mindf_nonieee"
12579 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
12580 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
12581 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
12582 (match_dup 1)
12583 (match_dup 2)))
12584 (clobber (reg:CC 17))]
12585 "TARGET_SSE2 && !TARGET_IEEE_FP"
12586 "#")
12587
12588(define_split
12589 [(set (match_operand:DF 0 "register_operand" "")
12590 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
12591 (match_operand:DF 2 "nonimmediate_operand" ""))
12592 (match_dup 1)
12593 (match_dup 2)))
12594 (clobber (reg:CC 17))]
12595 "SSE_REG_P (operands[0]) && reload_completed"
12596 [(set (match_dup 0)
12597 (if_then_else:DF (lt (match_dup 1)
12598 (match_dup 2))
12599 (match_dup 1)
12600 (match_dup 2)))])
12601
12602;; We can't represent the LT test directly. Do this by swapping the operands.
12603(define_split
12604 [(set (match_operand:DF 0 "register_operand" "")
12605 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
12606 (match_operand:DF 2 "register_operand" ""))
12607 (match_dup 1)
12608 (match_dup 2)))
12609 (clobber (reg:CC 17))]
12610 "FP_REG_P (operands[0]) && reload_completed"
12611 [(set (reg:CCFP 17)
12612 (compare:CCFP (match_dup 2)
12613 (match_dup 2)))
12614 (set (match_dup 0)
12615 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
12616 (match_dup 1)
12617 (match_dup 2)))])
12618
12619(define_insn "*mindf_sse"
12620 [(set (match_operand:DF 0 "register_operand" "=Y")
12621 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
12622 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
12623 (match_dup 1)
12624 (match_dup 2)))]
12625 "TARGET_SSE2 && reload_completed"
12626 "minsd\\t{%2, %0|%0, %2}"
12627 [(set_attr "type" "sse")
12628 (set_attr "mode" "DF")])
12629
12630(define_expand "maxsf3"
12631 [(parallel [
12632 (set (match_operand:SF 0 "register_operand" "")
12633 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
12634 (match_operand:SF 2 "nonimmediate_operand" ""))
12635 (match_dup 1)
12636 (match_dup 2)))
12637 (clobber (reg:CC 17))])]
12638 "TARGET_SSE"
12639 "#")
12640
12641(define_insn "*maxsf"
12642 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
12643 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
12644 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
12645 (match_dup 1)
12646 (match_dup 2)))
12647 (clobber (reg:CC 17))]
12648 "TARGET_SSE && TARGET_IEEE_FP"
12649 "#")
12650
12651(define_insn "*maxsf_nonieee"
12652 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
12653 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
12654 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
12655 (match_dup 1)
12656 (match_dup 2)))
12657 (clobber (reg:CC 17))]
12658 "TARGET_SSE && !TARGET_IEEE_FP"
12659 "#")
12660
12661(define_split
12662 [(set (match_operand:SF 0 "register_operand" "")
12663 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
12664 (match_operand:SF 2 "nonimmediate_operand" ""))
12665 (match_dup 1)
12666 (match_dup 2)))
12667 (clobber (reg:CC 17))]
12668 "SSE_REG_P (operands[0]) && reload_completed"
12669 [(set (match_dup 0)
12670 (if_then_else:SF (gt (match_dup 1)
12671 (match_dup 2))
12672 (match_dup 1)
12673 (match_dup 2)))])
12674
12675(define_split
12676 [(set (match_operand:SF 0 "register_operand" "")
12677 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
12678 (match_operand:SF 2 "register_operand" ""))
12679 (match_dup 1)
12680 (match_dup 2)))
12681 (clobber (reg:CC 17))]
12682 "FP_REG_P (operands[0]) && reload_completed"
12683 [(set (reg:CCFP 17)
12684 (compare:CCFP (match_dup 1)
12685 (match_dup 2)))
12686 (set (match_dup 0)
12687 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
12688 (match_dup 1)
12689 (match_dup 2)))])
12690
12691(define_insn "*maxsf_sse"
12692 [(set (match_operand:SF 0 "register_operand" "=x")
12693 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
12694 (match_operand:SF 2 "nonimmediate_operand" "xm"))
12695 (match_dup 1)
12696 (match_dup 2)))]
12697 "TARGET_SSE && reload_completed"
12698 "maxss\\t{%2, %0|%0, %2}"
12699 [(set_attr "type" "sse")
12700 (set_attr "mode" "SF")])
12701
12702(define_expand "maxdf3"
12703 [(parallel [
12704 (set (match_operand:DF 0 "register_operand" "")
12705 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
12706 (match_operand:DF 2 "nonimmediate_operand" ""))
12707 (match_dup 1)
12708 (match_dup 2)))
12709 (clobber (reg:CC 17))])]
12710 "TARGET_SSE2"
12711 "#")
12712
12713(define_insn "*maxdf"
12714 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
12715 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
12716 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
12717 (match_dup 1)
12718 (match_dup 2)))
12719 (clobber (reg:CC 17))]
12720 "TARGET_SSE2 && TARGET_IEEE_FP"
12721 "#")
12722
12723(define_insn "*maxdf_nonieee"
12724 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
12725 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
12726 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
12727 (match_dup 1)
12728 (match_dup 2)))
12729 (clobber (reg:CC 17))]
12730 "TARGET_SSE2 && !TARGET_IEEE_FP"
12731 "#")
12732
12733(define_split
12734 [(set (match_operand:DF 0 "register_operand" "")
12735 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
12736 (match_operand:DF 2 "nonimmediate_operand" ""))
12737 (match_dup 1)
12738 (match_dup 2)))
12739 (clobber (reg:CC 17))]
12740 "SSE_REG_P (operands[0]) && reload_completed"
12741 [(set (match_dup 0)
12742 (if_then_else:DF (gt (match_dup 1)
12743 (match_dup 2))
12744 (match_dup 1)
12745 (match_dup 2)))])
12746
12747(define_split
12748 [(set (match_operand:DF 0 "register_operand" "")
12749 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
12750 (match_operand:DF 2 "register_operand" ""))
12751 (match_dup 1)
12752 (match_dup 2)))
12753 (clobber (reg:CC 17))]
12754 "FP_REG_P (operands[0]) && reload_completed"
12755 [(set (reg:CCFP 17)
12756 (compare:CCFP (match_dup 1)
12757 (match_dup 2)))
12758 (set (match_dup 0)
12759 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
12760 (match_dup 1)
12761 (match_dup 2)))])
12762
12763(define_insn "*maxdf_sse"
12764 [(set (match_operand:DF 0 "register_operand" "=Y")
12765 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
12766 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
12767 (match_dup 1)
12768 (match_dup 2)))]
12769 "TARGET_SSE2 && reload_completed"
12770 "maxsd\\t{%2, %0|%0, %2}"
12771 [(set_attr "type" "sse")
12772 (set_attr "mode" "DF")])
e075ae69
RH
12773\f
12774;; Misc patterns (?)
726e2d54 12775
e075ae69
RH
12776;; This pattern exists to put a dependancy on all ebp-based memory accesses.
12777;; Otherwise there will be nothing to keep
12778;;
12779;; [(set (reg ebp) (reg esp))]
12780;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
12781;; (clobber (eflags)]
12782;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
12783;;
12784;; in proper program order.
726e2d54 12785
1c71e60e
JH
12786(define_insn "pro_epilogue_adjust_stack"
12787 [(set (match_operand:SI 0 "register_operand" "=r,r")
12788 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
12789 (match_operand:SI 2 "immediate_operand" "i,i")))
12790 (set (match_operand:SI 3 "register_operand" "+r,r")
e075ae69
RH
12791 (match_dup 3))
12792 (clobber (reg:CC 17))]
12793 ""
12794 "*
12795{
1c71e60e 12796 switch (get_attr_type (insn))
e075ae69 12797 {
1c71e60e
JH
12798 case TYPE_IMOV:
12799 return \"mov{l}\\t{%1, %0|%0, %1}\";
12800
12801 case TYPE_ALU:
12802 if (GET_CODE (operands[2]) == CONST_INT
12803 && (INTVAL (operands[2]) == 128
12804 || (INTVAL (operands[2]) < 0
12805 && INTVAL (operands[2]) != -128)))
12806 {
12807 operands[2] = GEN_INT (-INTVAL (operands[2]));
12808 return \"sub{l}\\t{%2, %0|%0, %2}\";
12809 }
12810 return \"add{l}\\t{%2, %0|%0, %2}\";
12811
12812 case TYPE_LEA:
12813 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
12814 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
12815
12816 default:
12817 abort ();
e075ae69 12818 }
e075ae69 12819}"
1c71e60e
JH
12820 [(set (attr "type")
12821 (cond [(eq_attr "alternative" "0")
12822 (const_string "alu")
12823 (match_operand:SI 2 "const0_operand" "")
12824 (const_string "imov")
12825 ]
6ef67412
JH
12826 (const_string "lea")))
12827 (set_attr "mode" "SI")])
578b58f5 12828
0073023d
JH
12829;; Placeholder for the conditional moves. This one is split eighter to SSE
12830;; based moves emulation or to usual cmove sequence. Little bit unfortunate
12831;; fact is that compares supported by the cmp??ss instructions are exactly
12832;; swapped of those supported by cmove sequence.
fa9f36a1
JH
12833;; The EQ/NE comparisons also needs bit care, since they are not directly
12834;; supported by i387 comparisons and we do need to emit two conditional moves
12835;; in tandem.
0073023d
JH
12836
12837(define_insn "sse_movsfcc"
12838 [(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")
12839 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
12840 [(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")
12841 (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")])
12842 (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")
12843 (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 12844 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
0073023d 12845 (clobber (reg:CC 17))]
fa9f36a1
JH
12846 "TARGET_SSE
12847 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
12848 && (!TARGET_IEEE_FP
12849 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
12850 "#")
12851
12852(define_insn "sse_movsfcc_eq"
12853 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
12854 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
12855 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
12856 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
12857 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
12858 (clobber (match_scratch:SF 5 "=1,&4,X,X,X,X"))
12859 (clobber (reg:CC 17))]
0073023d
JH
12860 "TARGET_SSE
12861 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12862 "#")
12863
12864(define_insn "sse_movdfcc"
12865 [(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")
12866 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
12867 [(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")
12868 (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")])
12869 (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")
12870 (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 12871 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
0073023d
JH
12872 (clobber (reg:CC 17))]
12873 "TARGET_SSE2
fa9f36a1
JH
12874 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
12875 && (!TARGET_IEEE_FP
12876 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
12877 "#")
12878
12879(define_insn "sse_movdfcc_eq"
12880 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
12881 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
12882 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
12883 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
12884 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
12885 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
12886 (clobber (reg:CC 17))]
12887 "TARGET_SSE
0073023d
JH
12888 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12889 "#")
12890
12891;; For non-sse moves just expand the usual cmove sequence.
12892(define_split
12893 [(set (match_operand 0 "register_operand" "")
12894 (if_then_else (match_operator 1 "comparison_operator"
12895 [(match_operand 4 "nonimmediate_operand" "")
12896 (match_operand 5 "register_operand" "")])
12897 (match_operand 2 "nonimmediate_operand" "")
12898 (match_operand 3 "nonimmediate_operand" "")))
12899 (clobber (match_operand 6 "" ""))
12900 (clobber (reg:CC 17))]
12901 "!SSE_REG_P (operands[0]) && reload_completed
12902 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
12903 [(const_int 0)]
12904 "
12905{
12906 ix86_compare_op0 = operands[5];
12907 ix86_compare_op1 = operands[4];
12908 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
12909 VOIDmode, operands[5], operands[4]);
12910 ix86_expand_fp_movcc (operands);
12911 DONE;
12912}")
12913
12914;; Split SSE based conditional move into seqence:
12915;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
12916;; and op2, op0 - zero op2 if comparison was false
12917;; nand op0, op3 - load op3 to op0 if comparison was false
12918;; or op2, op0 - get the non-zero one into the result.
12919(define_split
12920 [(set (match_operand 0 "register_operand" "")
12921 (if_then_else (match_operator 1 "sse_comparison_operator"
12922 [(match_operand 4 "register_operand" "")
12923 (match_operand 5 "nonimmediate_operand" "")])
12924 (match_operand 2 "register_operand" "")
12925 (match_operand 3 "register_operand" "")))
bf71a4f8 12926 (clobber (match_operand 6 "" ""))
0073023d
JH
12927 (clobber (reg:CC 17))]
12928 "SSE_REG_P (operands[0]) && reload_completed"
12929 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
12930 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
12931 (subreg:TI (match_dup 0) 0)))
12932 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 0) 0))
12933 (subreg:TI (match_dup 3) 0)))
12934 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
12935 (subreg:TI (match_dup 7) 0)))]
12936 "
12937{
12938 PUT_MODE (operands[1], GET_MODE (operands[0]));
12939 if (rtx_equal_p (operands[0], operands[4]))
12940 operands[6] = operands[4], operands[7] = operands[2];
12941 else
12942 operands[6] = operands[2], operands[7] = operands[0];
12943}")
12944
12945;; Special case of conditional move we can handle effectivly.
12946;; Do not brother with the integer/floating point case, since these are
12947;; bot considerably slower, unlike in the generic case.
12948(define_insn "*sse_movsfcc_const0_1"
12949 [(set (match_operand:SF 0 "register_operand" "=x")
12950 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
12951 [(match_operand:SF 4 "register_operand" "0")
12952 (match_operand:SF 5 "nonimmediate_operand" "xm")])
12953 (match_operand:SF 2 "register_operand" "x")
12954 (match_operand:SF 3 "const0_operand" "X")))]
12955 "TARGET_SSE"
12956 "#")
12957
12958(define_insn "*sse_movsfcc_const0_2"
12959 [(set (match_operand:SF 0 "register_operand" "=x")
12960 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
12961 [(match_operand:SF 4 "register_operand" "0")
12962 (match_operand:SF 5 "nonimmediate_operand" "xm")])
12963 (match_operand:SF 2 "const0_operand" "x")
12964 (match_operand:SF 3 "register_operand" "X")))]
12965 "TARGET_SSE"
12966 "#")
12967
12968(define_insn "*sse_movsfcc_const0_3"
12969 [(set (match_operand:SF 0 "register_operand" "=x")
12970 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
12971 [(match_operand:SF 4 "nonimmediate_operand" "xm")
12972 (match_operand:SF 5 "register_operand" "0")])
12973 (match_operand:SF 2 "register_operand" "x")
12974 (match_operand:SF 3 "const0_operand" "X")))]
12975 "TARGET_SSE"
12976 "#")
12977
12978(define_insn "*sse_movsfcc_const0_4"
12979 [(set (match_operand:SF 0 "register_operand" "=x")
12980 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
12981 [(match_operand:SF 4 "nonimmediate_operand" "xm")
12982 (match_operand:SF 5 "register_operand" "0")])
12983 (match_operand:SF 2 "const0_operand" "x")
12984 (match_operand:SF 3 "register_operand" "X")))]
12985 "TARGET_SSE"
12986 "#")
12987
12988(define_insn "*sse_movdfcc_const0_1"
12989 [(set (match_operand:SF 0 "register_operand" "=x")
12990 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
12991 [(match_operand:SF 4 "register_operand" "0")
12992 (match_operand:SF 5 "nonimmediate_operand" "xm")])
12993 (match_operand:SF 2 "register_operand" "x")
12994 (match_operand:SF 3 "const0_operand" "X")))]
12995 "TARGET_SSE2"
12996 "#")
12997
12998(define_insn "*sse_movdfcc_const0_2"
12999 [(set (match_operand:SF 0 "register_operand" "=x")
13000 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
13001 [(match_operand:SF 4 "register_operand" "0")
13002 (match_operand:SF 5 "nonimmediate_operand" "xm")])
13003 (match_operand:SF 2 "const0_operand" "x")
13004 (match_operand:SF 3 "register_operand" "X")))]
13005 "TARGET_SSE2"
13006 "#")
13007
13008(define_insn "*sse_movdfcc_const0_3"
13009 [(set (match_operand:SF 0 "register_operand" "=x")
13010 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
13011 [(match_operand:SF 4 "nonimmediate_operand" "xm")
13012 (match_operand:SF 5 "register_operand" "0")])
13013 (match_operand:SF 2 "register_operand" "x")
13014 (match_operand:SF 3 "const0_operand" "X")))]
13015 "TARGET_SSE2"
13016 "#")
13017
13018(define_insn "*sse_movdfcc_const0_4"
13019 [(set (match_operand:SF 0 "register_operand" "=x")
13020 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
13021 [(match_operand:SF 4 "nonimmediate_operand" "xm")
13022 (match_operand:SF 5 "register_operand" "0")])
13023 (match_operand:SF 2 "const0_operand" "x")
13024 (match_operand:SF 3 "register_operand" "X")))]
13025 "TARGET_SSE2"
13026 "#")
13027
13028(define_split
13029 [(set (match_operand 0 "register_operand" "")
13030 (if_then_else (match_operator 1 "comparison_operator"
13031 [(match_operand 4 "register_operand" "")
13032 (match_operand 5 "nonimmediate_operand" "")])
13033 (match_operand 2 "nonmemory_operand" "")
13034 (match_operand 3 "nonmemory_operand" "")))]
13035 "SSE_REG_P (operands[0]) && reload_completed
13036 && (const0_operand (operands[2], GET_MODE (operands[0]))
13037 || const0_operand (operands[3], GET_MODE (operands[0])))"
13038 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
13039 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
13040 (subreg:TI (match_dup 7) 0)))]
13041 "
13042{
13043 PUT_MODE (operands[1], GET_MODE (operands[0]));
13044 if (!sse_comparison_operator (operands[1], VOIDmode))
13045 {
13046 rtx tmp = operands[5];
13047 operands[5] = operands[4];
13048 operands[4] = tmp;
13049 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
13050 }
13051 if (const0_operand (operands[2], GET_MODE (operands[0])))
13052 {
13053 operands[7] = operands[3];
13054 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
13055 0));
13056 }
13057 else
13058 {
13059 operands[7] = operands[2];
13060 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
13061 }
13062}")
13063
578b58f5
RK
13064(define_insn "allocate_stack_worker"
13065 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
13066 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
e075ae69
RH
13067 (clobber (match_dup 0))
13068 (clobber (reg:CC 17))]
578b58f5 13069 "TARGET_STACK_PROBE"
e075ae69
RH
13070 "call\\t__alloca"
13071 [(set_attr "type" "multi")
13072 (set_attr "length" "5")])
578b58f5
RK
13073
13074(define_expand "allocate_stack"
e075ae69
RH
13075 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
13076 (minus:SI (reg:SI 7)
13077 (match_operand:SI 1 "general_operand" "")))
13078 (clobber (reg:CC 17))])
13079 (parallel [(set (reg:SI 7)
13080 (minus:SI (reg:SI 7) (match_dup 1)))
13081 (clobber (reg:CC 17))])]
13082 "TARGET_STACK_PROBE"
578b58f5
RK
13083 "
13084{
13085#ifdef CHECK_STACK_LIMIT
e9a25f70
JL
13086 if (GET_CODE (operands[1]) == CONST_INT
13087 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
578b58f5 13088 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
e9a25f70 13089 operands[1]));
578b58f5
RK
13090 else
13091#endif
13092 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
e9a25f70 13093 operands[1])));
578b58f5 13094
e9a25f70
JL
13095 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
13096 DONE;
13097}")
e31ca113
JW
13098
13099(define_expand "exception_receiver"
13100 [(const_int 0)]
13101 "flag_pic"
13102 "
13103{
6baf1cc8 13104 load_pic_register ();
e31ca113
JW
13105 DONE;
13106}")
fb754025
AG
13107
13108(define_expand "builtin_setjmp_receiver"
13109 [(label_ref (match_operand 0 "" ""))]
13110 "flag_pic"
13111 "
13112{
13113 load_pic_register ();
13114 DONE;
13115}")
e9e80858
JH
13116\f
13117;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
13118
13119(define_split
13120 [(set (match_operand 0 "register_operand" "")
13121 (match_operator 3 "promotable_binary_operator"
13122 [(match_operand 1 "register_operand" "")
2247f6ed 13123 (match_operand 2 "aligned_operand" "")]))
e9e80858
JH
13124 (clobber (reg:CC 17))]
13125 "! TARGET_PARTIAL_REG_STALL && reload_completed
13126 && ((GET_MODE (operands[0]) == HImode
13127 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
13128 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
13129 || (GET_MODE (operands[0]) == QImode
13130 && (TARGET_PROMOTE_QImode || optimize_size)))"
13131 [(parallel [(set (match_dup 0)
13132 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
13133 (clobber (reg:CC 17))])]
13134 "operands[0] = gen_lowpart (SImode, operands[0]);
13135 operands[1] = gen_lowpart (SImode, operands[1]);
13136 if (GET_CODE (operands[3]) != ASHIFT)
13137 operands[2] = gen_lowpart (SImode, operands[2]);
dbbbbf3b 13138 PUT_MODE (operands[3], SImode);")
e9e80858
JH
13139
13140(define_split
16189740
RH
13141 [(set (reg 17)
13142 (compare (and (match_operand 1 "aligned_operand" "")
13143 (match_operand 2 "const_int_operand" ""))
13144 (const_int 0)))
e9e80858
JH
13145 (set (match_operand 0 "register_operand" "")
13146 (and (match_dup 1) (match_dup 2)))]
13147 "! TARGET_PARTIAL_REG_STALL && reload_completed
16189740 13148 && ix86_match_ccmode (insn, CCNOmode)
e9e80858
JH
13149 && (GET_MODE (operands[0]) == HImode
13150 || (GET_MODE (operands[0]) == QImode
13151 && (TARGET_PROMOTE_QImode || optimize_size)))"
13152 [(parallel [(set (reg:CCNO 17)
13153 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
13154 (const_int 0)))
13155 (set (match_dup 0)
13156 (and:SI (match_dup 1) (match_dup 2)))])]
d9f0b960
RH
13157 "operands[2]
13158 = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
13159 operands[0] = gen_lowpart (SImode, operands[0]);
13160 operands[1] = gen_lowpart (SImode, operands[1]);")
e9e80858
JH
13161
13162(define_split
16189740
RH
13163 [(set (reg 17)
13164 (compare (and (match_operand 0 "aligned_operand" "")
13165 (match_operand 1 "const_int_operand" ""))
13166 (const_int 0)))]
e9e80858 13167 "! TARGET_PARTIAL_REG_STALL && reload_completed
16189740 13168 && ix86_match_ccmode (insn, CCNOmode)
e9e80858
JH
13169 && (GET_MODE (operands[0]) == HImode
13170 || (GET_MODE (operands[0]) == QImode
13171 && (TARGET_PROMOTE_QImode || optimize_size)))"
13172 [(set (reg:CCNO 17)
13173 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
13174 (const_int 0)))]
d9f0b960
RH
13175 "operands[1]
13176 = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
13177 operands[0] = gen_lowpart (SImode, operands[0]);")
e9e80858
JH
13178
13179(define_split
13180 [(set (match_operand 0 "register_operand" "")
13181 (neg (match_operand 1 "register_operand" "")))
13182 (clobber (reg:CC 17))]
13183 "! TARGET_PARTIAL_REG_STALL && reload_completed
13184 && (GET_MODE (operands[0]) == HImode
13185 || (GET_MODE (operands[0]) == QImode
13186 && (TARGET_PROMOTE_QImode || optimize_size)))"
13187 [(parallel [(set (match_dup 0)
13188 (neg:SI (match_dup 1)))
13189 (clobber (reg:CC 17))])]
13190 "operands[0] = gen_lowpart (SImode, operands[0]);
13191 operands[1] = gen_lowpart (SImode, operands[1]);")
13192
13193(define_split
13194 [(set (match_operand 0 "register_operand" "")
13195 (not (match_operand 1 "register_operand" "")))]
13196 "! TARGET_PARTIAL_REG_STALL && reload_completed
13197 && (GET_MODE (operands[0]) == HImode
13198 || (GET_MODE (operands[0]) == QImode
13199 && (TARGET_PROMOTE_QImode || optimize_size)))"
13200 [(set (match_dup 0)
13201 (not:SI (match_dup 1)))]
13202 "operands[0] = gen_lowpart (SImode, operands[0]);
13203 operands[1] = gen_lowpart (SImode, operands[1]);")
13204
13205(define_split
13206 [(set (match_operand 0 "register_operand" "")
13207 (if_then_else (match_operator 1 "comparison_operator"
13208 [(reg 17) (const_int 0)])
13209 (match_operand 2 "register_operand" "")
13210 (match_operand 3 "register_operand" "")))]
13211 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
13212 && (GET_MODE (operands[0]) == HImode
13213 || (GET_MODE (operands[0]) == QImode
13214 && (TARGET_PROMOTE_QImode || optimize_size)))"
13215 [(set (match_dup 0)
13216 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
13217 "operands[0] = gen_lowpart (SImode, operands[0]);
13218 operands[2] = gen_lowpart (SImode, operands[2]);
13219 operands[3] = gen_lowpart (SImode, operands[3]);")
13220
e075ae69
RH
13221\f
13222;; RTL Peephole optimizations, run before sched2. These primarily look to
13223;; transform a complex memory operation into two memory to register operations.
13224
13225;; Don't push memory operands
13226(define_peephole2
3071fab5
RH
13227 [(set (match_operand:SI 0 "push_operand" "")
13228 (match_operand:SI 1 "memory_operand" ""))
13229 (match_scratch:SI 2 "r")]
e075ae69
RH
13230 "! optimize_size && ! TARGET_PUSH_MEMORY"
13231 [(set (match_dup 2) (match_dup 1))
13232 (set (match_dup 0) (match_dup 2))]
13233 "")
13234
e9e80858
JH
13235;; We need to handle SFmode only, because DFmode and XFmode is split to
13236;; SImode pushes.
13237(define_peephole2
13238 [(set (match_operand:SF 0 "push_operand" "")
13239 (match_operand:SF 1 "memory_operand" ""))
13240 (match_scratch:SF 2 "r")]
13241 "! optimize_size && ! TARGET_PUSH_MEMORY"
13242 [(set (match_dup 2) (match_dup 1))
13243 (set (match_dup 0) (match_dup 2))]
13244 "")
13245
e075ae69 13246(define_peephole2
3071fab5
RH
13247 [(set (match_operand:HI 0 "push_operand" "")
13248 (match_operand:HI 1 "memory_operand" ""))
13249 (match_scratch:HI 2 "r")]
e075ae69
RH
13250 "! optimize_size && ! TARGET_PUSH_MEMORY"
13251 [(set (match_dup 2) (match_dup 1))
13252 (set (match_dup 0) (match_dup 2))]
13253 "")
13254
13255(define_peephole2
3071fab5
RH
13256 [(set (match_operand:QI 0 "push_operand" "")
13257 (match_operand:QI 1 "memory_operand" ""))
13258 (match_scratch:QI 2 "q")]
e075ae69
RH
13259 "! optimize_size && ! TARGET_PUSH_MEMORY"
13260 [(set (match_dup 2) (match_dup 1))
13261 (set (match_dup 0) (match_dup 2))]
13262 "")
13263
13264;; Don't move an immediate directly to memory when the instruction
13265;; gets too big.
13266(define_peephole2
13267 [(match_scratch:SI 1 "r")
13268 (set (match_operand:SI 0 "memory_operand" "")
13269 (const_int 0))]
23280139 13270 "! optimize_size
591702de 13271 && ! TARGET_USE_MOV0
23280139
RH
13272 && TARGET_SPLIT_LONG_MOVES
13273 && get_attr_length (insn) >= ix86_cost->large_insn
13274 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
13275 [(parallel [(set (match_dup 1) (const_int 0))
13276 (clobber (reg:CC 17))])
13277 (set (match_dup 0) (match_dup 1))]
13278 "")
13279
13280(define_peephole2
13281 [(match_scratch:HI 1 "r")
13282 (set (match_operand:HI 0 "memory_operand" "")
13283 (const_int 0))]
23280139 13284 "! optimize_size
591702de 13285 && ! TARGET_USE_MOV0
23280139
RH
13286 && TARGET_SPLIT_LONG_MOVES
13287 && get_attr_length (insn) >= ix86_cost->large_insn
13288 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 13289 [(parallel [(set (match_dup 2) (const_int 0))
e075ae69
RH
13290 (clobber (reg:CC 17))])
13291 (set (match_dup 0) (match_dup 1))]
591702de 13292 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
e075ae69
RH
13293
13294(define_peephole2
13295 [(match_scratch:QI 1 "q")
13296 (set (match_operand:QI 0 "memory_operand" "")
13297 (const_int 0))]
23280139 13298 "! optimize_size
591702de 13299 && ! TARGET_USE_MOV0
23280139
RH
13300 && TARGET_SPLIT_LONG_MOVES
13301 && get_attr_length (insn) >= ix86_cost->large_insn
13302 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 13303 [(parallel [(set (match_dup 2) (const_int 0))
e075ae69
RH
13304 (clobber (reg:CC 17))])
13305 (set (match_dup 0) (match_dup 1))]
591702de 13306 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
e075ae69
RH
13307
13308(define_peephole2
13309 [(match_scratch:SI 2 "r")
13310 (set (match_operand:SI 0 "memory_operand" "")
13311 (match_operand:SI 1 "immediate_operand" ""))]
23280139
RH
13312 "! optimize_size
13313 && get_attr_length (insn) >= ix86_cost->large_insn
13314 && TARGET_SPLIT_LONG_MOVES"
e075ae69
RH
13315 [(set (match_dup 2) (match_dup 1))
13316 (set (match_dup 0) (match_dup 2))]
13317 "")
13318
13319(define_peephole2
13320 [(match_scratch:HI 2 "r")
13321 (set (match_operand:HI 0 "memory_operand" "")
13322 (match_operand:HI 1 "immediate_operand" ""))]
13323 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
13324 && TARGET_SPLIT_LONG_MOVES"
13325 [(set (match_dup 2) (match_dup 1))
13326 (set (match_dup 0) (match_dup 2))]
13327 "")
13328
13329(define_peephole2
13330 [(match_scratch:QI 2 "q")
13331 (set (match_operand:QI 0 "memory_operand" "")
13332 (match_operand:QI 1 "immediate_operand" ""))]
13333 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
13334 && TARGET_SPLIT_LONG_MOVES"
13335 [(set (match_dup 2) (match_dup 1))
13336 (set (match_dup 0) (match_dup 2))]
13337 "")
13338
13339;; Don't compare memory with zero, load and use a test instead.
13340(define_peephole2
16189740
RH
13341 [(set (reg 17)
13342 (compare (match_operand:SI 0 "memory_operand" "")
13343 (const_int 0)))
3071fab5 13344 (match_scratch:SI 3 "r")]
16189740
RH
13345 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
13346 [(set (match_dup 3) (match_dup 0))
13347 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
e075ae69
RH
13348 "")
13349
13350;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
13351;; Don't split NOTs with a displacement operand, because resulting XOR
13352;; will not be pariable anyway.
13353;;
13354;; On AMD K6, NOT is vector decoded with memory operand that can not be
13355;; represented using a modRM byte. The XOR replacement is long decoded,
13356;; so this split helps here as well.
13357;;
23280139
RH
13358;; Note: Can't do this as a regular split because we can't get proper
13359;; lifetime information then.
e075ae69
RH
13360
13361(define_peephole2
13362 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13363 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
13364 "!optimize_size
23280139 13365 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
13366 && ((TARGET_PENTIUM
13367 && (GET_CODE (operands[0]) != MEM
13368 || !memory_displacement_operand (operands[0], SImode)))
13369 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
13370 [(parallel [(set (match_dup 0)
13371 (xor:SI (match_dup 1) (const_int -1)))
13372 (clobber (reg:CC 17))])]
13373 "")
13374
13375(define_peephole2
13376 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13377 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
13378 "!optimize_size
23280139 13379 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
13380 && ((TARGET_PENTIUM
13381 && (GET_CODE (operands[0]) != MEM
13382 || !memory_displacement_operand (operands[0], HImode)))
13383 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
13384 [(parallel [(set (match_dup 0)
13385 (xor:HI (match_dup 1) (const_int -1)))
13386 (clobber (reg:CC 17))])]
13387 "")
13388
13389(define_peephole2
13390 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
13391 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
13392 "!optimize_size
23280139 13393 && peep2_regno_dead_p (0, FLAGS_REG)
e075ae69
RH
13394 && ((TARGET_PENTIUM
13395 && (GET_CODE (operands[0]) != MEM
13396 || !memory_displacement_operand (operands[0], QImode)))
13397 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
13398 [(parallel [(set (match_dup 0)
13399 (xor:QI (match_dup 1) (const_int -1)))
13400 (clobber (reg:CC 17))])]
13401 "")
13402
13403;; Non pairable "test imm, reg" instructions can be translated to
13404;; "and imm, reg" if reg dies. The "and" form is also shorter (one
13405;; byte opcode instead of two, have a short form for byte operands),
13406;; so do it for other CPUs as well. Given that the value was dead,
13407;; this should not create any new dependancies. Pass on the sub-word
13408;; versions if we're concerned about partial register stalls.
13409
13410(define_peephole2
16189740
RH
13411 [(set (reg 17)
13412 (compare (and:SI (match_operand:SI 0 "register_operand" "")
13413 (match_operand:SI 1 "immediate_operand" ""))
13414 (const_int 0)))]
13415 "ix86_match_ccmode (insn, CCNOmode)
13416 && (true_regnum (operands[0]) != 0
13417 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
e075ae69
RH
13418 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13419 [(parallel
13420 [(set (reg:CCNO 17)
13421 (compare:CCNO (and:SI (match_dup 0)
13422 (match_dup 1))
13423 (const_int 0)))
13424 (set (match_dup 0)
13425 (and:SI (match_dup 0) (match_dup 1)))])]
13426 "")
13427
e9e80858
JH
13428;; We don't need to handle HImode case, because it will be promoted to SImode
13429;; on ! TARGET_PARTIAL_REG_STALL
e075ae69
RH
13430
13431(define_peephole2
16189740
RH
13432 [(set (reg 17)
13433 (compare (and:QI (match_operand:QI 0 "register_operand" "")
13434 (match_operand:QI 1 "immediate_operand" ""))
13435 (const_int 0)))]
e075ae69 13436 "! TARGET_PARTIAL_REG_STALL
16189740 13437 && ix86_match_ccmode (insn, CCNOmode)
e075ae69
RH
13438 && true_regnum (operands[0]) != 0
13439 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13440 [(parallel
13441 [(set (reg:CCNO 17)
13442 (compare:CCNO (and:QI (match_dup 0)
13443 (match_dup 1))
13444 (const_int 0)))
13445 (set (match_dup 0)
13446 (and:QI (match_dup 0) (match_dup 1)))])]
13447 "")
13448
13449(define_peephole2
16189740
RH
13450 [(set (reg 17)
13451 (compare
e075ae69
RH
13452 (and:SI
13453 (zero_extract:SI
13454 (match_operand 0 "ext_register_operand" "q")
13455 (const_int 8)
13456 (const_int 8))
13457 (match_operand 1 "const_int_operand" "n"))
13458 (const_int 0)))]
13459 "! TARGET_PARTIAL_REG_STALL
16189740 13460 && ix86_match_ccmode (insn, CCNOmode)
e075ae69
RH
13461 && true_regnum (operands[0]) != 0
13462 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13463 [(parallel [(set (reg:CCNO 17)
13464 (compare:CCNO
13465 (and:SI
13466 (zero_extract:SI
13467 (match_dup 0)
13468 (const_int 8)
13469 (const_int 8))
13470 (match_dup 1))
13471 (const_int 0)))
13472 (set (zero_extract:SI (match_dup 0)
13473 (const_int 8)
13474 (const_int 8))
13475 (and:SI
13476 (zero_extract:SI
13477 (match_dup 0)
13478 (const_int 8)
13479 (const_int 8))
13480 (match_dup 1)))])]
13481 "")
13482
13483;; Don't do logical operations with memory inputs.
13484(define_peephole2
13485 [(match_scratch:SI 2 "r")
13486 (parallel [(set (match_operand:SI 0 "register_operand" "")
13487 (match_operator:SI 3 "arith_or_logical_operator"
13488 [(match_dup 0)
13489 (match_operand:SI 1 "memory_operand" "")]))
13490 (clobber (reg:CC 17))])]
13491 "! optimize_size && ! TARGET_READ_MODIFY"
13492 [(set (match_dup 2) (match_dup 1))
13493 (parallel [(set (match_dup 0)
13494 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
13495 (clobber (reg:CC 17))])]
13496 "")
13497
13498(define_peephole2
13499 [(match_scratch:SI 2 "r")
13500 (parallel [(set (match_operand:SI 0 "register_operand" "")
13501 (match_operator:SI 3 "arith_or_logical_operator"
13502 [(match_operand:SI 1 "memory_operand" "")
13503 (match_dup 0)]))
13504 (clobber (reg:CC 17))])]
13505 "! optimize_size && ! TARGET_READ_MODIFY"
13506 [(set (match_dup 2) (match_dup 1))
13507 (parallel [(set (match_dup 0)
13508 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
13509 (clobber (reg:CC 17))])]
13510 "")
13511
13512; Don't do logical operations with memory outputs
13513;
13514; These two don't make sense for PPro/PII -- we're expanding a 4-uop
13515; instruction into two 1-uop insns plus a 2-uop insn. That last has
13516; the same decoder scheduling characteristics as the original.
13517
13518(define_peephole2
13519 [(match_scratch:SI 2 "r")
13520 (parallel [(set (match_operand:SI 0 "memory_operand" "")
13521 (match_operator:SI 3 "arith_or_logical_operator"
13522 [(match_dup 0)
13523 (match_operand:SI 1 "nonmemory_operand" "")]))
13524 (clobber (reg:CC 17))])]
13525 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
13526 [(set (match_dup 2) (match_dup 0))
13527 (parallel [(set (match_dup 2)
13528 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
13529 (clobber (reg:CC 17))])
13530 (set (match_dup 0) (match_dup 2))]
13531 "")
13532
13533(define_peephole2
13534 [(match_scratch:SI 2 "r")
13535 (parallel [(set (match_operand:SI 0 "memory_operand" "")
13536 (match_operator:SI 3 "arith_or_logical_operator"
13537 [(match_operand:SI 1 "nonmemory_operand" "")
13538 (match_dup 0)]))
13539 (clobber (reg:CC 17))])]
13540 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
13541 [(set (match_dup 2) (match_dup 0))
13542 (parallel [(set (match_dup 2)
13543 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
13544 (clobber (reg:CC 17))])
13545 (set (match_dup 0) (match_dup 2))]
13546 "")
13547
13548;; Attempt to always use XOR for zeroing registers.
13549(define_peephole2
13550 [(set (match_operand 0 "register_operand" "")
13551 (const_int 0))]
13552 "(GET_MODE (operands[0]) == QImode
13553 || GET_MODE (operands[0]) == HImode
13554 || GET_MODE (operands[0]) == SImode)
13555 && (! TARGET_USE_MOV0 || optimize_size)
23280139 13556 && peep2_regno_dead_p (0, FLAGS_REG)"
e075ae69
RH
13557 [(parallel [(set (match_dup 0) (const_int 0))
13558 (clobber (reg:CC 17))])]
591702de 13559 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
d3a923ee 13560
6ef67412
JH
13561(define_peephole2
13562 [(set (strict_low_part (match_operand 0 "register_operand" ""))
13563 (const_int 0))]
13564 "(GET_MODE (operands[0]) == QImode
13565 || GET_MODE (operands[0]) == HImode)
13566 && (! TARGET_USE_MOV0 || optimize_size)
13567 && peep2_regno_dead_p (0, FLAGS_REG)"
13568 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
13569 (clobber (reg:CC 17))])])
13570
e075ae69
RH
13571;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
13572(define_peephole2
591702de 13573 [(set (match_operand 0 "register_operand" "")
e075ae69 13574 (const_int -1))]
591702de
JH
13575 "(GET_MODE (operands[0]) == HImode
13576 || GET_MODE (operands[0]) == SImode)
13577 && (optimize_size || TARGET_PENTIUM)
23280139 13578 && peep2_regno_dead_p (0, FLAGS_REG)"
591702de 13579 [(parallel [(set (match_dup 0) (const_int -1))
e075ae69 13580 (clobber (reg:CC 17))])]
591702de 13581 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
1c27d4b2
JH
13582
13583;; Attempt to convert simple leas to adds. These can be created by
13584;; move expanders.
13585(define_peephole2
13586 [(set (match_operand:SI 0 "register_operand" "")
13587 (plus:SI (match_dup 0)
13588 (match_operand:SI 1 "nonmemory_operand" "")))]
23280139 13589 "peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2
JH
13590 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
13591 (clobber (reg:CC 17))])]
13592 "")
13593
13594(define_peephole2
13595 [(set (match_operand:SI 0 "register_operand" "")
13596 (mult:SI (match_dup 0)
13597 (match_operand:SI 1 "immediate_operand" "")))]
23280139
RH
13598 "exact_log2 (INTVAL (operands[1])) >= 0
13599 && peep2_regno_dead_p (0, FLAGS_REG)"
1c27d4b2
JH
13600 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
13601 (clobber (reg:CC 17))])]
13602 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
bdeb029c
JH
13603
13604;; The ESP adjustments can be done by the push and pop instructions. Resulting
13605;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
13606;; many CPUs it is also faster, since special hardware to avoid esp
13607;; dependancies is present.
13608
13609;; While some of these converisons may be done using splitters, we use peepholes
13610;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
13611
13612;; Convert prologue esp substractions to push.
13613;; We need register to push. In order to keep verify_flow_info happy we have
13614;; two choices
13615;; - use scratch and clobber it in order to avoid dependencies
13616;; - use already live register
13617;; We can't use the second way right now, since there is no reliable way how to
13618;; verify that given register is live. First choice will also most likely in
13619;; fewer dependencies. On the place of esp adjustments it is very likely that
13620;; call clobbered registers are dead. We may want to use base pointer as an
13621;; alternative when no register is available later.
13622
13623(define_peephole2
13624 [(match_scratch:SI 0 "r")
13625 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
13626 (set (reg:SI 6) (reg:SI 6))
13627 (clobber (reg:CC 17))])]
13628 "optimize_size || !TARGET_SUB_ESP_4"
13629 [(clobber (match_dup 0))
13630 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
13631 (set (reg:SI 6) (reg:SI 6))])])
13632
13633(define_peephole2
13634 [(match_scratch:SI 0 "r")
13635 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13636 (set (reg:SI 6) (reg:SI 6))
13637 (clobber (reg:CC 17))])]
13638 "optimize_size || !TARGET_SUB_ESP_8"
13639 [(clobber (match_dup 0))
13640 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
13641 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
13642 (set (reg:SI 6) (reg:SI 6))])])
13643
13644;; Convert esp substractions to push.
13645(define_peephole2
13646 [(match_scratch:SI 0 "r")
13647 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
13648 (clobber (reg:CC 17))])]
13649 "optimize_size || !TARGET_SUB_ESP_4"
13650 [(clobber (match_dup 0))
13651 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
13652
13653(define_peephole2
13654 [(match_scratch:SI 0 "r")
13655 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13656 (clobber (reg:CC 17))])]
13657 "optimize_size || !TARGET_SUB_ESP_8"
13658 [(clobber (match_dup 0))
13659 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
13660 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
13661
13662;; Convert epilogue deallocator to pop.
13663(define_peephole2
13664 [(match_scratch:SI 0 "r")
13665 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
13666 (set (reg:SI 6) (reg:SI 6))
13667 (clobber (reg:CC 17))])]
13668 "optimize_size || !TARGET_ADD_ESP_4"
13669 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13670 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
13671 (set (reg:SI 6) (reg:SI 6))])]
13672 "")
13673
13674;; Two pops case is tricky, since pop causes dependency on destination register.
13675;; We use two registers if available.
13676(define_peephole2
13677 [(match_scratch:SI 0 "r")
13678 (match_scratch:SI 1 "r")
13679 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
13680 (set (reg:SI 6) (reg:SI 6))
13681 (clobber (reg:CC 17))])]
13682 "optimize_size || !TARGET_ADD_ESP_8"
13683 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13684 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
13685 (set (reg:SI 6) (reg:SI 6))])
13686 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
13687 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
13688 "")
13689
13690(define_peephole2
13691 [(match_scratch:SI 0 "r")
13692 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
13693 (set (reg:SI 6) (reg:SI 6))
13694 (clobber (reg:CC 17))])]
13695 "optimize_size"
13696 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13697 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
13698 (set (reg:SI 6) (reg:SI 6))])
13699 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13700 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
13701 "")
13702
13703;; Convert esp additions to pop.
13704(define_peephole2
13705 [(match_scratch:SI 0 "r")
13706 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
13707 (clobber (reg:CC 17))])]
13708 ""
13709 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13710 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
13711 "")
13712
13713;; Two pops case is tricky, since pop causes dependency on destination register.
13714;; We use two registers if available.
13715(define_peephole2
13716 [(match_scratch:SI 0 "r")
13717 (match_scratch:SI 1 "r")
13718 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
13719 (clobber (reg:CC 17))])]
13720 ""
13721 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13722 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
13723 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
13724 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
13725 "")
13726
13727(define_peephole2
13728 [(match_scratch:SI 0 "r")
13729 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
13730 (clobber (reg:CC 17))])]
13731 "optimize_size"
13732 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13733 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
13734 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
13735 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
13736 "")
69404d6f 13737\f
9dcbdc7e
JH
13738;; Convert compares with 1 to shorter inc/dec operations when CF is not
13739;; required and register dies.
13740(define_peephole2
13741 [(set (reg 17)
13742 (compare (match_operand:SI 0 "register_operand" "")
13743 (match_operand:SI 1 "incdec_operand" "")))]
13744 "ix86_match_ccmode (insn, CCGCmode)
13745 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13746 [(parallel [(set (reg:CCGC 17)
265dab10 13747 (compare:CCGC (match_dup 0)
7e08e190 13748 (match_dup 1)))
9dcbdc7e 13749 (clobber (match_dup 0))])]
7e08e190 13750 "")
9dcbdc7e
JH
13751
13752(define_peephole2
13753 [(set (reg 17)
13754 (compare (match_operand:HI 0 "register_operand" "")
13755 (match_operand:HI 1 "incdec_operand" "")))]
13756 "ix86_match_ccmode (insn, CCGCmode)
13757 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13758 [(parallel [(set (reg:CCGC 17)
265dab10 13759 (compare:CCGC (match_dup 0)
7e08e190 13760 (match_dup 1)))
9dcbdc7e 13761 (clobber (match_dup 0))])]
7e08e190 13762 "")
9dcbdc7e
JH
13763
13764(define_peephole2
13765 [(set (reg 17)
13766 (compare (match_operand:QI 0 "register_operand" "")
13767 (match_operand:QI 1 "incdec_operand" "")))]
13768 "ix86_match_ccmode (insn, CCGCmode)
13769 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
13770 [(parallel [(set (reg:CCGC 17)
265dab10 13771 (compare:CCGC (match_dup 0)
7e08e190 13772 (match_dup 1)))
9dcbdc7e 13773 (clobber (match_dup 0))])]
7e08e190 13774 "")
9dcbdc7e
JH
13775
13776;; Convert compares with 128 to shorter add -128
13777(define_peephole2
13778 [(set (reg 17)
13779 (compare (match_operand:SI 0 "register_operand" "")
13780 (const_int 128)))]
7e08e190 13781 "ix86_match_ccmode (insn, CCGCmode)
9dcbdc7e 13782 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7e08e190
JH
13783 [(parallel [(set (reg:CCGC 17)
13784 (compare:CCGC (match_dup 0)
13785 (const_int 128)))
9dcbdc7e
JH
13786 (clobber (match_dup 0))])]
13787 "")
13788
13789(define_peephole2
13790 [(set (reg 17)
13791 (compare (match_operand:HI 0 "register_operand" "")
13792 (const_int 128)))]
7e08e190 13793 "ix86_match_ccmode (insn, CCGCmode)
9dcbdc7e 13794 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7e08e190
JH
13795 [(parallel [(set (reg:CCGC 17)
13796 (compare:CCGC (match_dup 0)
13797 (const_int 128)))
9dcbdc7e
JH
13798 (clobber (match_dup 0))])]
13799 "")
13800\f
69404d6f
RH
13801;; Call-value patterns last so that the wildcard operand does not
13802;; disrupt insn-recog's switch tables.
13803
94bb5d0c
RH
13804(define_insn "*call_value_pop_0"
13805 [(set (match_operand 0 "" "")
e1ff012c 13806 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c
RH
13807 (match_operand:SI 2 "" "")))
13808 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 13809 (match_operand:SI 3 "immediate_operand" "")))]
1e07edd3 13810 "!TARGET_64BIT"
94bb5d0c
RH
13811 "*
13812{
13813 if (SIBLING_CALL_P (insn))
13814 return \"jmp\\t%P1\";
13815 else
13816 return \"call\\t%P1\";
13817}"
13818 [(set_attr "type" "callv")])
13819
69404d6f
RH
13820(define_insn "*call_value_pop_1"
13821 [(set (match_operand 0 "" "")
e1ff012c 13822 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 13823 (match_operand:SI 2 "" "")))
69404d6f 13824 (set (reg:SI 7) (plus:SI (reg:SI 7)
90d10fb9 13825 (match_operand:SI 3 "immediate_operand" "i")))]
1e07edd3 13826 "!TARGET_64BIT"
69404d6f
RH
13827 "*
13828{
94bb5d0c
RH
13829 if (constant_call_address_operand (operands[1], QImode))
13830 {
13831 if (SIBLING_CALL_P (insn))
13832 return \"jmp\\t%P1\";
13833 else
13834 return \"call\\t%P1\";
13835 }
94bb5d0c 13836 if (SIBLING_CALL_P (insn))
fb204271 13837 return \"jmp\\t%A1\";
94bb5d0c 13838 else
fb204271 13839 return \"call\\t%A1\";
94bb5d0c
RH
13840}"
13841 [(set_attr "type" "callv")])
13842
13843(define_insn "*call_value_0"
13844 [(set (match_operand 0 "" "")
e1ff012c 13845 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
94bb5d0c
RH
13846 (match_operand:SI 2 "" "")))]
13847 ""
13848 "*
13849{
13850 if (SIBLING_CALL_P (insn))
13851 return \"jmp\\t%P1\";
13852 else
13853 return \"call\\t%P1\";
69404d6f
RH
13854}"
13855 [(set_attr "type" "callv")])
13856
69404d6f
RH
13857(define_insn "*call_value_1"
13858 [(set (match_operand 0 "" "")
e1ff012c 13859 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
94bb5d0c 13860 (match_operand:SI 2 "" "")))]
69404d6f
RH
13861 ""
13862 "*
13863{
94bb5d0c 13864 if (constant_call_address_operand (operands[1], QImode))
cbbf65e0
RH
13865 {
13866 if (SIBLING_CALL_P (insn))
13867 return \"jmp\\t%P1\";
13868 else
13869 return \"call\\t%P1\";
13870 }
cbbf65e0 13871 if (SIBLING_CALL_P (insn))
fb204271 13872 return \"jmp\\t%A1\";
cbbf65e0 13873 else
fb204271 13874 return \"call\\t%A1\";
69404d6f
RH
13875}"
13876 [(set_attr "type" "callv")])
9e3e266c
GM
13877\f
13878(define_insn "trap"
13879 [(trap_if (const_int 1) (const_int 5))]
13880 ""
13881 "int\\t$5")
13882
13883;;; ix86 doesn't have conditional trap instructions, but we fake them
13884;;; for the sake of bounds checking. By emitting bounds checks as
13885;;; conditional traps rather than as conditional jumps around
13886;;; unconditional traps we avoid introducing spurious basic-block
13887;;; boundaries and facilitate elimination of redundant checks. In
13888;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
13889;;; interrupt 5.
13890;;;
13891;;; FIXME: Static branch prediction rules for ix86 are such that
13892;;; forward conditional branches predict as untaken. As implemented
13893;;; below, pseudo conditional traps violate that rule. We should use
13894;;; .pushsection/.popsection to place all of the `int 5's in a special
13895;;; section loaded at the end of the text segment and branch forward
13896;;; there on bounds-failure, and then jump back immediately (in case
13897;;; the system chooses to ignore bounds violations, or to report
13898;;; violations and continue execution).
13899
13900(define_expand "conditional_trap"
13901 [(trap_if (match_operator 0 "comparison_operator"
13902 [(match_dup 2) (const_int 0)])
13903 (match_operand 1 "const_int_operand" ""))]
13904 ""
13905 "
13906{
13907 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
a1b8572c
JH
13908 ix86_expand_compare (GET_CODE (operands[0]),
13909 NULL_RTX, NULL_RTX),
9e3e266c
GM
13910 operands[1]));
13911 DONE;
13912}")
13913
13914(define_insn ""
13915 [(trap_if (match_operator 0 "comparison_operator"
13916 [(reg 17) (const_int 0)])
13917 (match_operand 1 "const_int_operand" ""))]
13918 ""
13919 "*
13920{
13921 operands[2] = gen_label_rtx ();
13922 output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands);
13923 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
13924 CODE_LABEL_NUMBER (operands[2]));
13925 RET;
13926}")
915119a5
BS
13927
13928 ;; Pentium III SIMD instructions.
13929
13930;; Moves for SSE/MMX regs.
13931
13932(define_insn "movv4sf_internal"
13933 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13934 (match_operand:V4SF 1 "general_operand" "xm,x"))]
13935 "TARGET_SSE"
13936 ;; @@@ let's try to use movaps here.
13937 "movaps\\t{%1, %0|%0, %1}"
13938 [(set_attr "type" "sse")])
13939
13940(define_insn "movv4si_internal"
13941 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
13942 (match_operand:V4SI 1 "general_operand" "xm,x"))]
13943 "TARGET_SSE"
13944 ;; @@@ let's try to use movaps here.
13945 "movaps\\t{%1, %0|%0, %1}"
13946 [(set_attr "type" "sse")])
13947
13948(define_insn "movv8qi_internal"
13949 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
13950 (match_operand:V8QI 1 "general_operand" "ym,y"))]
13951 "TARGET_MMX"
13952 "movq\\t{%1, %0|%0, %1}"
13953 [(set_attr "type" "mmx")])
13954
13955(define_insn "movv4hi_internal"
13956 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
13957 (match_operand:V4HI 1 "general_operand" "ym,y"))]
13958 "TARGET_MMX"
13959 "movq\\t{%1, %0|%0, %1}"
13960 [(set_attr "type" "mmx")])
13961
13962(define_insn "movv2si_internal"
13963 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
13964 (match_operand:V2SI 1 "general_operand" "ym,y"))]
13965 "TARGET_MMX"
13966 "movq\\t{%1, %0|%0, %1}"
13967 [(set_attr "type" "mmx")])
13968
13969(define_expand "movti"
13970 [(set (match_operand:TI 0 "general_operand" "")
13971 (match_operand:TI 1 "general_operand" ""))]
13972 "TARGET_SSE"
13973 "
13974{
13975 /* For constants other than zero into memory. We do not know how the
13976 instructions used to build constants modify the upper 64 bits
13977 of the register, once we have that information we may be able
13978 to handle some of them more efficiently. */
13979 if ((reload_in_progress | reload_completed) == 0
13980 && register_operand (operands[0], TImode)
13981 && CONSTANT_P (operands[1]))
13982 {
13983 rtx addr = gen_reg_rtx (Pmode);
13984
13985 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
13986 operands[1] = gen_rtx_MEM (TImode, addr);
13987 }
13988
13989 /* Make operand1 a register if it isn't already. */
13990 if ((reload_in_progress | reload_completed) == 0
13991 && !register_operand (operands[0], TImode)
13992 && !register_operand (operands[1], TImode)
13993 && operands[1] != CONST0_RTX (TImode))
13994 {
13995 rtx temp = force_reg (TImode, operands[1]);
13996 emit_move_insn (operands[0], temp);
13997 DONE;
13998 }
13999}")
14000
14001(define_expand "movv4sf"
14002 [(set (match_operand:V4SF 0 "general_operand" "")
14003 (match_operand:V4SF 1 "general_operand" ""))]
14004 "TARGET_SSE"
14005 "
14006{
14007 /* For constants other than zero into memory. We do not know how the
14008 instructions used to build constants modify the upper 64 bits
14009 of the register, once we have that information we may be able
14010 to handle some of them more efficiently. */
14011 if ((reload_in_progress | reload_completed) == 0
14012 && register_operand (operands[0], V4SFmode)
14013 && CONSTANT_P (operands[1]))
14014 {
14015 rtx addr = gen_reg_rtx (Pmode);
14016
14017 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
14018 operands[1] = gen_rtx_MEM (V4SFmode, addr);
14019 }
14020
14021 /* Make operand1 a register if it isn't already. */
14022 if ((reload_in_progress | reload_completed) == 0
14023 && !register_operand (operands[0], V4SFmode)
14024 && !register_operand (operands[1], V4SFmode)
14025 && operands[1] != CONST0_RTX (V4SFmode))
14026 {
14027 rtx temp = force_reg (V4SFmode, operands[1]);
14028 emit_move_insn (operands[0], temp);
14029 DONE;
14030 }
14031}")
14032
14033(define_expand "movv4si"
14034 [(set (match_operand:V4SI 0 "general_operand" "")
14035 (match_operand:V4SI 1 "general_operand" ""))]
14036 "TARGET_MMX"
14037 "
14038{
14039 /* For constants other than zero into memory. We do not know how the
14040 instructions used to build constants modify the upper 64 bits
14041 of the register, once we have that information we may be able
14042 to handle some of them more efficiently. */
14043 if ((reload_in_progress | reload_completed) == 0
14044 && register_operand (operands[0], V4SImode)
14045 && CONSTANT_P (operands[1]))
14046 {
14047 rtx addr = gen_reg_rtx (Pmode);
14048
14049 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
14050 operands[1] = gen_rtx_MEM (V4SImode, addr);
14051 }
14052
14053 /* Make operand1 a register if it isn't already. */
14054 if ((reload_in_progress | reload_completed) == 0
14055 && !register_operand (operands[0], V4SImode)
14056 && !register_operand (operands[1], V4SImode)
14057 && operands[1] != CONST0_RTX (V4SImode))
14058 {
14059 rtx temp = force_reg (V4SImode, operands[1]);
14060 emit_move_insn (operands[0], temp);
14061 DONE;
14062 }
14063}")
14064
14065(define_expand "movv2si"
14066 [(set (match_operand:V2SI 0 "general_operand" "")
14067 (match_operand:V2SI 1 "general_operand" ""))]
14068 "TARGET_MMX"
14069 "
14070{
14071 /* For constants other than zero into memory. We do not know how the
14072 instructions used to build constants modify the upper 64 bits
14073 of the register, once we have that information we may be able
14074 to handle some of them more efficiently. */
14075 if ((reload_in_progress | reload_completed) == 0
14076 && register_operand (operands[0], V2SImode)
14077 && CONSTANT_P (operands[1]))
14078 {
14079 rtx addr = gen_reg_rtx (Pmode);
14080
14081 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
14082 operands[1] = gen_rtx_MEM (V2SImode, addr);
14083 }
14084
14085 /* Make operand1 a register if it isn't already. */
14086 if ((reload_in_progress | reload_completed) == 0
14087 && !register_operand (operands[0], V2SImode)
14088 && !register_operand (operands[1], V2SImode)
14089 && operands[1] != CONST0_RTX (V2SImode))
14090 {
14091 rtx temp = force_reg (V2SImode, operands[1]);
14092 emit_move_insn (operands[0], temp);
14093 DONE;
14094 }
14095}")
14096
14097(define_expand "movv4hi"
14098 [(set (match_operand:V4HI 0 "general_operand" "")
14099 (match_operand:V4HI 1 "general_operand" ""))]
14100 "TARGET_MMX"
14101 "
14102{
14103 /* For constants other than zero into memory. We do not know how the
14104 instructions used to build constants modify the upper 64 bits
14105 of the register, once we have that information we may be able
14106 to handle some of them more efficiently. */
14107 if ((reload_in_progress | reload_completed) == 0
14108 && register_operand (operands[0], V4HImode)
14109 && CONSTANT_P (operands[1]))
14110 {
14111 rtx addr = gen_reg_rtx (Pmode);
14112
14113 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
14114 operands[1] = gen_rtx_MEM (V4HImode, addr);
14115 }
14116
14117 /* Make operand1 a register if it isn't already. */
14118 if ((reload_in_progress | reload_completed) == 0
14119 && !register_operand (operands[0], V4HImode)
14120 && !register_operand (operands[1], V4HImode)
14121 && operands[1] != CONST0_RTX (V4HImode))
14122 {
14123 rtx temp = force_reg (V4HImode, operands[1]);
14124 emit_move_insn (operands[0], temp);
14125 DONE;
14126 }
14127}")
14128
14129(define_expand "movv8qi"
14130 [(set (match_operand:V8QI 0 "general_operand" "")
14131 (match_operand:V8QI 1 "general_operand" ""))]
14132 "TARGET_MMX"
14133 "
14134{
14135 /* For constants other than zero into memory. We do not know how the
14136 instructions used to build constants modify the upper 64 bits
14137 of the register, once we have that information we may be able
14138 to handle some of them more efficiently. */
14139 if ((reload_in_progress | reload_completed) == 0
14140 && register_operand (operands[0], V8QImode)
14141 && CONSTANT_P (operands[1]))
14142 {
14143 rtx addr = gen_reg_rtx (Pmode);
14144
14145 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
14146 operands[1] = gen_rtx_MEM (V8QImode, addr);
14147 }
14148
14149 /* Make operand1 a register if it isn't already. */
14150 if ((reload_in_progress | reload_completed) == 0
14151 && !register_operand (operands[0], V8QImode)
14152 && !register_operand (operands[1], V8QImode)
14153 && operands[1] != CONST0_RTX (V8QImode))
14154 {
14155 rtx temp = force_reg (V8QImode, operands[1]);
14156 emit_move_insn (operands[0], temp);
14157 DONE;
14158 }
14159}")
14160
14161(define_insn_and_split "*pushti"
14162 [(set (match_operand:TI 0 "push_operand" "=<")
14163 (match_operand:TI 1 "nonmemory_operand" "x"))]
14164 "TARGET_SSE"
14165 "#"
14166 ""
14167 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
14168 (set (mem:TI (reg:SI 7)) (match_dup 1))]
14169 ""
14170 [(set_attr "type" "sse")])
14171
14172(define_insn_and_split "*pushv4sf"
14173 [(set (match_operand:V4SF 0 "push_operand" "=<")
14174 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
14175 "TARGET_SSE"
14176 "#"
14177 ""
14178 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
14179 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
14180 ""
14181 [(set_attr "type" "sse")])
14182
14183(define_insn_and_split "*pushv4si"
14184 [(set (match_operand:V4SI 0 "push_operand" "=<")
14185 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
14186 "TARGET_SSE"
14187 "#"
14188 ""
14189 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
14190 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
14191 ""
14192 [(set_attr "type" "sse")])
14193
14194(define_insn_and_split "*pushv2si"
14195 [(set (match_operand:V2SI 0 "push_operand" "=<")
14196 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
14197 "TARGET_MMX"
14198 "#"
14199 ""
14200 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
14201 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
14202 ""
14203 [(set_attr "type" "mmx")])
14204
14205(define_insn_and_split "*pushv4hi"
14206 [(set (match_operand:V4HI 0 "push_operand" "=<")
14207 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
14208 "TARGET_MMX"
14209 "#"
14210 ""
14211 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
14212 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
14213 ""
14214 [(set_attr "type" "mmx")])
14215
14216(define_insn_and_split "*pushv8qi"
14217 [(set (match_operand:V8QI 0 "push_operand" "=<")
14218 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
14219 "TARGET_MMX"
14220 "#"
14221 ""
14222 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
14223 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
14224 ""
14225 [(set_attr "type" "mmx")])
14226
14227(define_insn "movti_internal"
14228 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
14229 (match_operand:TI 1 "general_operand" "xm,x"))]
14230 "TARGET_SSE"
14231 "@
14232 movaps\\t{%1, %0|%0, %1}
14233 movaps\\t{%1, %0|%0, %1}"
14234 [(set_attr "type" "sse")])
14235
14236;; These two patterns are useful for specifying exactly whether to use
14237;; movaps or movups
14238(define_insn "sse_movaps"
14239 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
14240 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
14241 "TARGET_SSE"
14242 "@
14243 movaps\\t{%1, %0|%0, %1}
14244 movaps\\t{%1, %0|%0, %1}"
14245 [(set_attr "type" "sse")])
14246
14247(define_insn "sse_movups"
14248 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
14249 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
14250 "TARGET_SSE"
14251 "@
14252 movups\\t{%1, %0|%0, %1}
14253 movups\\t{%1, %0|%0, %1}"
14254 [(set_attr "type" "sse")])
14255
14256
14257;; SSE Strange Moves.
14258
14259(define_insn "sse_movmskps"
14260 [(set (match_operand:SI 0 "register_operand" "=r")
14261 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
14262 "TARGET_SSE"
14263 "movmskps\\t{%1, %0|%0, %1}"
14264 [(set_attr "type" "sse")])
14265
14266(define_insn "mmx_pmovmskb"
14267 [(set (match_operand:SI 0 "register_operand" "=r")
14268 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
14269 "TARGET_SSE"
14270 "pmovmskb\\t{%1, %0|%0, %1}"
14271 [(set_attr "type" "sse")])
14272
14273(define_insn "mmx_maskmovq"
14274 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
14275 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
14276 (match_operand:V8QI 2 "register_operand" "y")] 32))]
14277 "TARGET_SSE"
14278 ;; @@@ check ordering of operands in intel/nonintel syntax
14279 "maskmovq\\t{%2, %1|%1, %2}"
14280 [(set_attr "type" "sse")])
14281
14282(define_insn "sse_movntv4sf"
14283 [(set (match_operand:V4SF 0 "memory_operand" "=m")
14284 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
14285 "TARGET_SSE"
14286 "movntps\\t{%1, %0|%0, %1}"
14287 [(set_attr "type" "sse")])
14288
14289(define_insn "sse_movntdi"
14290 [(set (match_operand:DI 0 "memory_operand" "=m")
332316cd 14291 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
915119a5
BS
14292 "TARGET_SSE"
14293 "movntq\\t{%1, %0|%0, %1}"
14294 [(set_attr "type" "sse")])
14295
14296(define_insn "sse_movhlps"
14297 [(set (match_operand:V4SF 0 "register_operand" "=x")
14298 (vec_merge:V4SF
14299 (match_operand:V4SF 1 "register_operand" "0")
14300 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
14301 (parallel [(const_int 2)
14302 (const_int 3)
14303 (const_int 0)
14304 (const_int 1)]))
14305 (const_int 3)))]
14306 "TARGET_SSE"
14307 "movhlps\\t{%2, %0|%0, %2}"
14308 [(set_attr "type" "sse")])
14309
14310(define_insn "sse_movlhps"
14311 [(set (match_operand:V4SF 0 "register_operand" "=x")
14312 (vec_merge:V4SF
14313 (match_operand:V4SF 1 "register_operand" "0")
14314 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
14315 (parallel [(const_int 2)
14316 (const_int 3)
14317 (const_int 0)
14318 (const_int 1)]))
14319 (const_int 12)))]
14320 "TARGET_SSE"
14321 "movlhps\\t{%2, %0|%0, %2}"
14322 [(set_attr "type" "sse")])
14323
14324(define_insn "sse_movhps"
14325 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
14326 (vec_merge:V4SF
14327 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
14328 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
14329 (const_int 12)))]
14330 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
14331 "movhps\\t{%2, %0|%0, %2}"
14332 [(set_attr "type" "sse")])
14333
14334(define_insn "sse_movlps"
14335 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
14336 (vec_merge:V4SF
14337 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
14338 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
14339 (const_int 3)))]
14340 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
14341 "movlps\\t{%2, %0|%0, %2}"
14342 [(set_attr "type" "sse")])
14343
14344(define_insn "sse_loadss"
14345 [(set (match_operand:V4SF 0 "register_operand" "=x")
14346 (vec_merge:V4SF
14347 (match_operand:V4SF 1 "memory_operand" "m")
14348 (vec_duplicate:V4SF (float:SF (const_int 0)))
14349 (const_int 1)))]
14350 "TARGET_SSE"
14351 "movss\\t{%1, %0|%0, %1}"
14352 [(set_attr "type" "sse")])
14353
14354(define_insn "sse_movss"
14355 [(set (match_operand:V4SF 0 "register_operand" "=x")
14356 (vec_merge:V4SF
14357 (match_operand:V4SF 1 "register_operand" "0")
14358 (match_operand:V4SF 2 "register_operand" "x")
14359 (const_int 1)))]
14360 "TARGET_SSE"
14361 "movss\\t{%2, %0|%0, %2}"
14362 [(set_attr "type" "sse")])
14363
14364(define_insn "sse_storess"
14365 [(set (match_operand:SF 0 "memory_operand" "=m")
14366 (vec_select:SF
14367 (match_operand:V4SF 1 "register_operand" "x")
14368 (parallel [(const_int 0)])))]
14369 "TARGET_SSE"
14370 "movss\\t{%1, %0|%0, %1}"
14371 [(set_attr "type" "sse")])
14372
14373(define_insn "sse_shufps"
14374 [(set (match_operand:V4SF 0 "register_operand" "=x")
14375 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
14376 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
14377 (match_operand:SI 3 "immediate_operand" "i")] 41))]
14378 "TARGET_SSE"
14379 ;; @@@ check operand order for intel/nonintel syntax
14380 "shufps\\t{%3, %2, %0|%0, %2, %3}"
14381 [(set_attr "type" "sse")])
14382
14383
14384;; SSE arithmetic
14385
14386(define_insn "addv4sf3"
14387 [(set (match_operand:V4SF 0 "register_operand" "=x")
14388 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
14389 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14390 "TARGET_SSE"
14391 "addps\\t{%2, %0|%0, %2}"
14392 [(set_attr "type" "sse")])
14393
14394(define_insn "vmaddv4sf3"
14395 [(set (match_operand:V4SF 0 "register_operand" "=x")
14396 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
14397 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14398 (match_dup 1)
14399 (const_int 1)))]
14400 "TARGET_SSE"
14401 "addss\\t{%2, %0|%0, %2}"
14402 [(set_attr "type" "sse")])
14403
14404(define_insn "subv4sf3"
14405 [(set (match_operand:V4SF 0 "register_operand" "=x")
14406 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
14407 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14408 "TARGET_SSE"
14409 "subps\\t{%2, %0|%0, %2}"
14410 [(set_attr "type" "sse")])
14411
14412(define_insn "vmsubv4sf3"
14413 [(set (match_operand:V4SF 0 "register_operand" "=x")
14414 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
14415 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14416 (match_dup 1)
14417 (const_int 1)))]
14418 "TARGET_SSE"
14419 "subss\\t{%2, %0|%0, %2}"
14420 [(set_attr "type" "sse")])
14421
14422(define_insn "mulv4sf3"
14423 [(set (match_operand:V4SF 0 "register_operand" "=x")
14424 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
14425 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14426 "TARGET_SSE"
14427 "mulps\\t{%2, %0|%0, %2}"
14428 [(set_attr "type" "sse")])
14429
14430(define_insn "vmmulv4sf3"
14431 [(set (match_operand:V4SF 0 "register_operand" "=x")
14432 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
14433 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14434 (match_dup 1)
14435 (const_int 1)))]
14436 "TARGET_SSE"
14437 "mulss\\t{%2, %0|%0, %2}"
14438 [(set_attr "type" "sse")])
14439
14440(define_insn "divv4sf3"
14441 [(set (match_operand:V4SF 0 "register_operand" "=x")
14442 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
14443 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14444 "TARGET_SSE"
14445 "divps\\t{%2, %0|%0, %2}"
14446 [(set_attr "type" "sse")])
14447
14448(define_insn "vmdivv4sf3"
14449 [(set (match_operand:V4SF 0 "register_operand" "=x")
14450 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
14451 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14452 (match_dup 1)
14453 (const_int 1)))]
14454 "TARGET_SSE"
14455 "divss\\t{%2, %0|%0, %2}"
14456 [(set_attr "type" "sse")])
14457
14458
14459;; SSE square root/reciprocal
14460
14461(define_insn "rcpv4sf2"
14462 [(set (match_operand:V4SF 0 "register_operand" "=x")
14463 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
14464 "TARGET_SSE"
14465 "rcpps\\t{%1, %0|%0, %1}"
14466 [(set_attr "type" "sse")])
14467
14468(define_insn "vmrcpv4sf2"
14469 [(set (match_operand:V4SF 0 "register_operand" "=x")
14470 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
14471 (match_operand:V4SF 2 "register_operand" "0")
14472 (const_int 1)))]
14473 "TARGET_SSE"
14474 "rcpss\\t{%1, %0|%0, %1}"
14475 [(set_attr "type" "sse")])
14476
14477(define_insn "rsqrtv4sf2"
14478 [(set (match_operand:V4SF 0 "register_operand" "=x")
14479 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
14480 "TARGET_SSE"
14481 "rsqrtps\\t{%1, %0|%0, %1}"
14482 [(set_attr "type" "sse")])
14483
14484(define_insn "vmrsqrtv4sf2"
14485 [(set (match_operand:V4SF 0 "register_operand" "=x")
14486 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
14487 (match_operand:V4SF 2 "register_operand" "0")
14488 (const_int 1)))]
14489 "TARGET_SSE"
14490 "rsqrtss\\t{%1, %0|%0, %1}"
14491 [(set_attr "type" "sse")])
14492
14493(define_insn "sqrtv4sf2"
14494 [(set (match_operand:V4SF 0 "register_operand" "=x")
14495 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
14496 "TARGET_SSE"
14497 "sqrtps\\t{%1, %0|%0, %1}"
14498 [(set_attr "type" "sse")])
14499
14500(define_insn "vmsqrtv4sf2"
14501 [(set (match_operand:V4SF 0 "register_operand" "=x")
14502 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
14503 (match_operand:V4SF 2 "register_operand" "0")
14504 (const_int 1)))]
14505 "TARGET_SSE"
14506 "sqrtss\\t{%1, %0|%0, %1}"
14507 [(set_attr "type" "sse")])
14508
14509
14510;; SSE logical operations.
14511
14512;; These are not called andti3 etc. because we really really don't want
14513;; the compiler to widen DImode ands to TImode ands and then try to move
14514;; into DImode subregs of SSE registers, and them together, and move out
14515;; of DImode subregs again!
14516
c679d048
JH
14517(define_insn "*sse_andti3_df_1"
14518 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14519 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
14520 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
14521 "TARGET_SSE2"
14522 "andpd\\t{%2, %0|%0, %2}"
14523 [(set_attr "type" "sse")])
14524
14525(define_insn "*sse_andti3_df_2"
14526 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14527 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
14528 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
14529 "TARGET_SSE2"
14530 "andpd\\t{%2, %0|%0, %2}"
14531 [(set_attr "type" "sse")])
14532
14533(define_insn "*sse_andti3_sf_1"
14534 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14535 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
14536 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
14537 "TARGET_SSE"
14538 "andps\\t{%2, %0|%0, %2}"
14539 [(set_attr "type" "sse")])
14540
14541(define_insn "*sse_andti3_sf_2"
14542 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14543 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
14544 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14545 "TARGET_SSE"
14546 "andps\\t{%2, %0|%0, %2}"
14547 [(set_attr "type" "sse")])
14548
915119a5
BS
14549(define_insn "sse_andti3"
14550 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048 14551 (and:TI (match_operand:TI 1 "register_operand" "%0")
915119a5 14552 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 14553 "TARGET_SSE && !TARGET_SSE2"
915119a5
BS
14554 "andps\\t{%2, %0|%0, %2}"
14555 [(set_attr "type" "sse")])
14556
c679d048
JH
14557(define_insn "*sse_andti3_sse2"
14558 [(set (match_operand:TI 0 "register_operand" "=x")
14559 (and:TI (match_operand:TI 1 "register_operand" "%0")
14560 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14561 "TARGET_SSE2"
14562 "pand\\t{%2, %0|%0, %2}"
14563 [(set_attr "type" "sse")])
14564
14565(define_insn "*sse_nandti3_df"
14566 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14567 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
14568 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
14569 "TARGET_SSE2"
14570 "andnpd\\t{%2, %0|%0, %2}"
14571 [(set_attr "type" "sse")])
14572
14573(define_insn "*sse_nandti3_sf"
14574 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14575 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
14576 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14577 "TARGET_SSE"
14578 "andnps\\t{%2, %0|%0, %2}"
14579 [(set_attr "type" "sse")])
14580
915119a5
BS
14581(define_insn "sse_nandti3"
14582 [(set (match_operand:TI 0 "register_operand" "=x")
14583 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
14584 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 14585 "TARGET_SSE && !TARGET_SSE2"
915119a5
BS
14586 "andnps\\t{%2, %0|%0, %2}"
14587 [(set_attr "type" "sse")])
14588
c679d048
JH
14589(define_insn "*sse_nandti3_sse2"
14590 [(set (match_operand:TI 0 "register_operand" "=x")
14591 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
14592 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14593 "TARGET_SSE2"
14594 "pnand\\t{%2, %0|%0, %2}"
14595 [(set_attr "type" "sse")])
14596
14597(define_insn "*sse_iorti3_df_1"
14598 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14599 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
14600 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
14601 "TARGET_SSE2"
14602 "orpd\\t{%2, %0|%0, %2}"
14603 [(set_attr "type" "sse")])
14604
14605(define_insn "*sse_iorti3_df_2"
14606 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14607 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
14608 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
14609 "TARGET_SSE2"
14610 "orpd\\t{%2, %0|%0, %2}"
14611 [(set_attr "type" "sse")])
14612
14613(define_insn "*sse_iorti3_sf_1"
14614 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14615 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
14616 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
14617 "TARGET_SSE"
14618 "orps\\t{%2, %0|%0, %2}"
14619 [(set_attr "type" "sse")])
14620
14621(define_insn "*sse_iorti3_sf_2"
14622 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14623 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
14624 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14625 "TARGET_SSE"
14626 "orps\\t{%2, %0|%0, %2}"
14627 [(set_attr "type" "sse")])
14628
915119a5
BS
14629(define_insn "sse_iorti3"
14630 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048
JH
14631 (ior:TI (match_operand:TI 1 "register_operand" "%0")
14632 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14633 "TARGET_SSE && !TARGET_SSE2"
14634 "orps\\t{%2, %0|%0, %2}"
14635 [(set_attr "type" "sse")])
14636
14637(define_insn "*sse_iorti3_sse2"
14638 [(set (match_operand:TI 0 "register_operand" "=x")
14639 (ior:TI (match_operand:TI 1 "register_operand" "%0")
14640 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14641 "TARGET_SSE2"
14642 "por\\t{%2, %0|%0, %2}"
14643 [(set_attr "type" "sse")])
14644
14645(define_insn "*sse_xorti3_df_1"
14646 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14647 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
14648 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
14649 "TARGET_SSE2"
14650 "xorpd\\t{%2, %0|%0, %2}"
14651 [(set_attr "type" "sse")])
14652
14653(define_insn "*sse_xorti3_df_2"
14654 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
14655 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
14656 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
14657 "TARGET_SSE2"
14658 "xorpd\\t{%2, %0|%0, %2}"
14659 [(set_attr "type" "sse")])
14660
14661(define_insn "*sse_xorti3_sf_1"
14662 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14663 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
14664 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
14665 "TARGET_SSE"
14666 "xorps\\t{%2, %0|%0, %2}"
14667 [(set_attr "type" "sse")])
14668
14669(define_insn "*sse_xorti3_sf_2"
14670 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
14671 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
915119a5
BS
14672 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14673 "TARGET_SSE"
c679d048 14674 "xorps\\t{%2, %0|%0, %2}"
915119a5
BS
14675 [(set_attr "type" "sse")])
14676
14677(define_insn "sse_xorti3"
14678 [(set (match_operand:TI 0 "register_operand" "=x")
c679d048 14679 (xor:TI (match_operand:TI 1 "register_operand" "%0")
915119a5 14680 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
c679d048 14681 "TARGET_SSE && !TARGET_SSE2"
915119a5
BS
14682 "xorps\\t{%2, %0|%0, %2}"
14683 [(set_attr "type" "sse")])
14684
c679d048
JH
14685(define_insn "*sse_xorti3_sse2"
14686 [(set (match_operand:TI 0 "register_operand" "=x")
14687 (xor:TI (match_operand:TI 1 "register_operand" "%0")
14688 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
14689 "TARGET_SSE2"
14690 "pxor\\t{%2, %0|%0, %2}"
14691 [(set_attr "type" "sse")])
14692
915119a5
BS
14693;; Use xor, but don't show input operands so they aren't live before
14694;; this insn.
14695(define_insn "sse_clrti"
14696 [(set (match_operand:TI 0 "register_operand" "=x")
14697 (unspec:TI [(const_int 0)] 45))]
14698 "TARGET_SSE"
14699 "xorps\\t{%0, %0|%0, %0}"
14700 [(set_attr "type" "sse")])
14701
14702
14703;; SSE mask-generating compares
14704
14705(define_insn "maskcmpv4sf3"
14706 [(set (match_operand:V4SI 0 "register_operand" "=x")
14707 (match_operator:V4SI 3 "sse_comparison_operator"
14708 [(match_operand:V4SF 1 "register_operand" "0")
14709 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
14710 "TARGET_SSE"
a46d1d38 14711 "cmp%D3ps\\t{%2, %0|%0, %2}"
915119a5
BS
14712 [(set_attr "type" "sse")])
14713
14714(define_insn "maskncmpv4sf3"
14715 [(set (match_operand:V4SI 0 "register_operand" "=x")
14716 (not:V4SI
14717 (match_operator:V4SI 3 "sse_comparison_operator"
14718 [(match_operand:V4SF 1 "register_operand" "0")
14719 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
14720 "TARGET_SSE"
a46d1d38 14721 "cmpn%D3ps\\t{%2, %0|%0, %2}"
915119a5
BS
14722 [(set_attr "type" "sse")])
14723
14724(define_insn "vmmaskcmpv4sf3"
14725 [(set (match_operand:V4SI 0 "register_operand" "=x")
14726 (vec_merge:V4SI
14727 (match_operator:V4SI 3 "sse_comparison_operator"
14728 [(match_operand:V4SF 1 "register_operand" "0")
14729 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
14730 (match_dup 1)
14731 (const_int 1)))]
14732 "TARGET_SSE"
a46d1d38 14733 "cmp%D3ss\\t{%2, %0|%0, %2}"
915119a5
BS
14734 [(set_attr "type" "sse")])
14735
14736(define_insn "vmmaskncmpv4sf3"
14737 [(set (match_operand:V4SI 0 "register_operand" "=x")
14738 (vec_merge:V4SI
14739 (not:V4SI
14740 (match_operator:V4SI 3 "sse_comparison_operator"
14741 [(match_operand:V4SF 1 "register_operand" "0")
14742 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
14743 (subreg:V4SI (match_dup 1) 0)
14744 (const_int 1)))]
14745 "TARGET_SSE"
a46d1d38 14746 "cmp%D3ss\\t{%2, %0|%0, %2}"
915119a5
BS
14747 [(set_attr "type" "sse")])
14748
14749(define_insn "sse_comi"
14750 [(set (reg:CCFP 17)
14751 (match_operator:CCFP 2 "sse_comparison_operator"
14752 [(vec_select:SF
14753 (match_operand:V4SF 0 "register_operand" "x")
14754 (parallel [(const_int 0)]))
14755 (vec_select:SF
14756 (match_operand:V4SF 1 "register_operand" "x")
14757 (parallel [(const_int 0)]))]))]
14758 "TARGET_SSE"
14759 "comiss\\t{%2, %0|%0, %2}"
14760 [(set_attr "type" "sse")])
14761
14762(define_insn "sse_ucomi"
14763 [(set (reg:CCFPU 17)
14764 (match_operator:CCFPU 2 "sse_comparison_operator"
14765 [(vec_select:SF
14766 (match_operand:V4SF 0 "register_operand" "x")
14767 (parallel [(const_int 0)]))
14768 (vec_select:SF
14769 (match_operand:V4SF 1 "register_operand" "x")
14770 (parallel [(const_int 0)]))]))]
14771 "TARGET_SSE"
14772 "ucomiss\\t{%2, %0|%0, %2}"
14773 [(set_attr "type" "sse")])
14774
14775
14776;; SSE unpack
14777
14778(define_insn "sse_unpckhps"
14779 [(set (match_operand:V4SF 0 "register_operand" "=x")
14780 (vec_merge:V4SF
14781 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
14782 (parallel [(const_int 2)
14783 (const_int 0)
14784 (const_int 3)
14785 (const_int 1)]))
14786 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
14787 (parallel [(const_int 0)
14788 (const_int 2)
14789 (const_int 1)
14790 (const_int 3)]))
14791 (const_int 5)))]
14792 "TARGET_SSE"
14793 "unpckhps\\t{%2, %0|%0, %2}"
14794 [(set_attr "type" "sse")])
14795
14796(define_insn "sse_unpcklps"
14797 [(set (match_operand:V4SF 0 "register_operand" "=x")
14798 (vec_merge:V4SF
14799 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
14800 (parallel [(const_int 0)
14801 (const_int 2)
14802 (const_int 1)
14803 (const_int 3)]))
14804 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
14805 (parallel [(const_int 2)
14806 (const_int 0)
14807 (const_int 3)
14808 (const_int 1)]))
14809 (const_int 5)))]
14810 "TARGET_SSE"
14811 "unpcklps\\t{%2, %0|%0, %2}"
14812 [(set_attr "type" "sse")])
14813
14814
14815;; SSE min/max
14816
14817(define_insn "smaxv4sf3"
14818 [(set (match_operand:V4SF 0 "register_operand" "=x")
14819 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
14820 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14821 "TARGET_SSE"
14822 "maxps\\t{%2, %0|%0, %2}"
14823 [(set_attr "type" "sse")])
14824
14825(define_insn "vmsmaxv4sf3"
14826 [(set (match_operand:V4SF 0 "register_operand" "=x")
14827 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
14828 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14829 (match_dup 1)
14830 (const_int 1)))]
14831 "TARGET_SSE"
14832 "maxss\\t{%2, %0|%0, %2}"
14833 [(set_attr "type" "sse")])
14834
14835(define_insn "sminv4sf3"
14836 [(set (match_operand:V4SF 0 "register_operand" "=x")
14837 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
14838 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
14839 "TARGET_SSE"
14840 "minps\\t{%2, %0|%0, %2}"
14841 [(set_attr "type" "sse")])
14842
14843(define_insn "vmsminv4sf3"
14844 [(set (match_operand:V4SF 0 "register_operand" "=x")
14845 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
14846 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
14847 (match_dup 1)
14848 (const_int 1)))]
14849 "TARGET_SSE"
14850 "minss\\t{%2, %0|%0, %2}"
14851 [(set_attr "type" "sse")])
14852
14853
14854;; SSE <-> integer/MMX conversions
14855
14856(define_insn "cvtpi2ps"
14857 [(set (match_operand:V4SF 0 "register_operand" "=x")
14858 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
14859 (vec_duplicate:V4SF
14860 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
14861 (const_int 12)))]
14862 "TARGET_SSE"
14863 "cvtpi2ps\\t{%2, %0|%0, %2}"
14864 [(set_attr "type" "sse")])
14865
14866(define_insn "cvtps2pi"
14867 [(set (match_operand:V2SI 0 "register_operand" "=y")
14868 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
14869 (parallel
14870 [(const_int 0)
14871 (const_int 1)])))]
14872 "TARGET_SSE"
14873 "cvtps2pi\\t{%1, %0|%0, %1}"
14874 [(set_attr "type" "sse")])
14875
14876(define_insn "cvttps2pi"
14877 [(set (match_operand:V2SI 0 "register_operand" "=y")
14878 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
14879 (parallel
14880 [(const_int 0)
14881 (const_int 1)])))]
14882 "TARGET_SSE"
14883 "cvttps2pi\\t{%1, %0|%0, %1}"
14884 [(set_attr "type" "sse")])
14885
14886(define_insn "cvtsi2ss"
14887 [(set (match_operand:V4SF 0 "register_operand" "=x")
14888 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
14889 (vec_duplicate:V4SF
14890 (float:SF (match_operand:SI 2 "register_operand" "rm")))
14891 (const_int 15)))]
14892 "TARGET_SSE"
14893 "cvtsi2ss\\t{%2, %0|%0, %2}"
14894 [(set_attr "type" "sse")])
14895
14896(define_insn "cvtss2si"
14897 [(set (match_operand:SI 0 "register_operand" "=y")
14898 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
14899 (parallel [(const_int 0)])))]
14900 "TARGET_SSE"
14901 "cvtss2si\\t{%1, %0|%0, %1}"
14902 [(set_attr "type" "sse")])
14903
14904(define_insn "cvttss2si"
14905 [(set (match_operand:SI 0 "register_operand" "=y")
14906 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
14907 (parallel [(const_int 0)])))]
14908 "TARGET_SSE"
14909 "cvttss2si\\t{%1, %0|%0, %1}"
14910 [(set_attr "type" "sse")])
14911
14912
14913;; MMX insns
14914
14915;; MMX arithmetic
14916
14917(define_insn "addv8qi3"
14918 [(set (match_operand:V8QI 0 "register_operand" "=y")
14919 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14920 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14921 "TARGET_MMX"
14922 "paddb\\t{%2, %0|%0, %2}"
14923 [(set_attr "type" "mmx")])
14924
14925(define_insn "addv4hi3"
14926 [(set (match_operand:V4HI 0 "register_operand" "=y")
14927 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14928 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14929 "TARGET_MMX"
14930 "paddw\\t{%2, %0|%0, %2}"
14931 [(set_attr "type" "mmx")])
14932
14933(define_insn "addv2si3"
14934 [(set (match_operand:V2SI 0 "register_operand" "=y")
14935 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
14936 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14937 "TARGET_MMX"
14938 "paddd\\t{%2, %0|%0, %2}"
14939 [(set_attr "type" "mmx")])
14940
14941(define_insn "ssaddv8qi3"
14942 [(set (match_operand:V8QI 0 "register_operand" "=y")
14943 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14944 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14945 "TARGET_MMX"
14946 "paddsb\\t{%2, %0|%0, %2}"
14947 [(set_attr "type" "mmx")])
14948
14949(define_insn "ssaddv4hi3"
14950 [(set (match_operand:V4HI 0 "register_operand" "=y")
14951 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14952 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14953 "TARGET_MMX"
14954 "paddsw\\t{%2, %0|%0, %2}"
14955 [(set_attr "type" "mmx")])
14956
14957(define_insn "usaddv8qi3"
14958 [(set (match_operand:V8QI 0 "register_operand" "=y")
14959 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14960 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14961 "TARGET_MMX"
14962 "paddusb\\t{%2, %0|%0, %2}"
14963 [(set_attr "type" "mmx")])
14964
14965(define_insn "usaddv4hi3"
14966 [(set (match_operand:V4HI 0 "register_operand" "=y")
14967 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14968 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14969 "TARGET_MMX"
14970 "paddusw\\t{%2, %0|%0, %2}"
14971 [(set_attr "type" "mmx")])
14972
14973(define_insn "subv8qi3"
14974 [(set (match_operand:V8QI 0 "register_operand" "=y")
14975 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14976 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14977 "TARGET_MMX"
14978 "psubb\\t{%2, %0|%0, %2}"
14979 [(set_attr "type" "mmx")])
14980
14981(define_insn "subv4hi3"
14982 [(set (match_operand:V4HI 0 "register_operand" "=y")
14983 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14984 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14985 "TARGET_MMX"
14986 "psubw\\t{%2, %0|%0, %2}"
14987 [(set_attr "type" "mmx")])
14988
14989(define_insn "subv2si3"
14990 [(set (match_operand:V2SI 0 "register_operand" "=y")
14991 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
14992 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14993 "TARGET_MMX"
14994 "psubd\\t{%2, %0|%0, %2}"
14995 [(set_attr "type" "mmx")])
14996
14997(define_insn "sssubv8qi3"
14998 [(set (match_operand:V8QI 0 "register_operand" "=y")
14999 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
15000 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15001 "TARGET_MMX"
15002 "psubsb\\t{%2, %0|%0, %2}"
15003 [(set_attr "type" "mmx")])
15004
15005(define_insn "sssubv4hi3"
15006 [(set (match_operand:V4HI 0 "register_operand" "=y")
15007 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
15008 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15009 "TARGET_MMX"
15010 "psubsw\\t{%2, %0|%0, %2}"
15011 [(set_attr "type" "mmx")])
15012
15013(define_insn "ussubv8qi3"
15014 [(set (match_operand:V8QI 0 "register_operand" "=y")
15015 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
15016 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15017 "TARGET_MMX"
15018 "psubusb\\t{%2, %0|%0, %2}"
15019 [(set_attr "type" "mmx")])
15020
15021(define_insn "ussubv4hi3"
15022 [(set (match_operand:V4HI 0 "register_operand" "=y")
15023 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
15024 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15025 "TARGET_MMX"
15026 "psubusw\\t{%2, %0|%0, %2}"
15027 [(set_attr "type" "mmx")])
15028
15029(define_insn "mulv4hi3"
15030 [(set (match_operand:V4HI 0 "register_operand" "=y")
15031 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
15032 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15033 "TARGET_MMX"
15034 "pmullw\\t{%2, %0|%0, %2}"
15035 [(set_attr "type" "mmx")])
15036
15037(define_insn "smulv4hi3_highpart"
15038 [(set (match_operand:V4HI 0 "register_operand" "=y")
15039 (truncate:V4HI
15040 (lshiftrt:V4SI
15041 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
15042 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
15043 (const_int 16))))]
15044 "TARGET_MMX"
15045 "pmulhw\\t{%2, %0|%0, %2}"
15046 [(set_attr "type" "mmx")])
15047
15048(define_insn "umulv4hi3_highpart"
15049 [(set (match_operand:V4HI 0 "register_operand" "=y")
15050 (truncate:V4HI
15051 (lshiftrt:V4SI
15052 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
15053 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
15054 (const_int 16))))]
15055 "TARGET_MMX"
15056 "pmulhuw\\t{%2, %0|%0, %2}"
15057 [(set_attr "type" "mmx")])
15058
15059(define_insn "mmx_pmaddwd"
15060 [(set (match_operand:V2SI 0 "register_operand" "=y")
15061 (plus:V2SI
15062 (mult:V2SI
15063 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
15064 (parallel [(const_int 0)
15065 (const_int 2)])))
15066 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
15067 (parallel [(const_int 0)
15068 (const_int 2)]))))
15069 (mult:V2SI
15070 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
15071 (parallel [(const_int 1)
15072 (const_int 3)])))
15073 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
15074 (parallel [(const_int 1)
15075 (const_int 3)]))))))]
15076 "TARGET_MMX"
15077 "pmaddwd\\t{%2, %0|%0, %2}"
15078 [(set_attr "type" "mmx")])
15079
15080
15081;; MMX logical operations
15082;; Note we don't want to declare these as regular iordi3 insns to prevent
15083;; normal code that also wants to use the FPU from getting broken.
15084;; The UNSPECs are there to prevent the combiner from getting overly clever.
15085(define_insn "mmx_iordi3"
15086 [(set (match_operand:DI 0 "register_operand" "=y")
15087 (unspec:DI
15088 [(ior:DI (match_operand:DI 1 "register_operand" "0")
15089 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
15090 "TARGET_MMX"
15091 "por\\t{%2, %0|%0, %2}"
15092 [(set_attr "type" "mmx")])
15093
15094(define_insn "mmx_xordi3"
15095 [(set (match_operand:DI 0 "register_operand" "=y")
15096 (unspec:DI
15097 [(xor:DI (match_operand:DI 1 "register_operand" "0")
15098 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
15099 "TARGET_MMX"
15100 "pxor\\t{%2, %0|%0, %2}"
15101 [(set_attr "type" "mmx")])
15102
15103;; Same as pxor, but don't show input operands so that we don't think
15104;; they are live.
15105(define_insn "mmx_clrdi"
15106 [(set (match_operand:DI 0 "register_operand" "=y")
15107 (unspec:DI [(const_int 0)] 45))]
15108 "TARGET_MMX"
15109 "pxor\\t{%0, %0|%0, %0}"
15110 [(set_attr "type" "mmx")])
15111
15112(define_insn "mmx_anddi3"
15113 [(set (match_operand:DI 0 "register_operand" "=y")
15114 (unspec:DI
15115 [(and:DI (match_operand:DI 1 "register_operand" "0")
15116 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
15117 "TARGET_MMX"
15118 "pand\\t{%2, %0|%0, %2}"
15119 [(set_attr "type" "mmx")])
15120
15121(define_insn "mmx_nanddi3"
15122 [(set (match_operand:DI 0 "register_operand" "=y")
15123 (unspec:DI
15124 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
15125 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
15126 "TARGET_MMX"
15127 "pandn\\t{%2, %0|%0, %2}"
15128 [(set_attr "type" "mmx")])
15129
15130
15131;; MMX unsigned averages/sum of absolute differences
15132
15133(define_insn "mmx_uavgv8qi3"
15134 [(set (match_operand:V8QI 0 "register_operand" "=y")
15135 (ashiftrt:V8QI
15136 (plus:V8QI (plus:V8QI
15137 (match_operand:V8QI 1 "register_operand" "0")
15138 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
15139 (vec_const:V8QI (parallel [(const_int 1)
15140 (const_int 1)
15141 (const_int 1)
15142 (const_int 1)
15143 (const_int 1)
15144 (const_int 1)
15145 (const_int 1)
15146 (const_int 1)])))
15147 (const_int 1)))]
15148 "TARGET_SSE"
332316cd 15149 "pavgb\\t{%2, %0|%0, %2}"
915119a5
BS
15150 [(set_attr "type" "sse")])
15151
15152(define_insn "mmx_uavgv4hi3"
15153 [(set (match_operand:V4HI 0 "register_operand" "=y")
15154 (ashiftrt:V4HI
15155 (plus:V4HI (plus:V4HI
15156 (match_operand:V4HI 1 "register_operand" "0")
15157 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
15158 (vec_const:V4HI (parallel [(const_int 1)
15159 (const_int 1)
15160 (const_int 1)
15161 (const_int 1)])))
15162 (const_int 1)))]
15163 "TARGET_SSE"
332316cd 15164 "pavgw\\t{%2, %0|%0, %2}"
915119a5
BS
15165 [(set_attr "type" "sse")])
15166
15167(define_insn "mmx_psadbw"
15168 [(set (match_operand:V8QI 0 "register_operand" "=y")
332316cd
BS
15169 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
15170 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
915119a5 15171 "TARGET_SSE"
332316cd 15172 "psadbw\\t{%2, %0|%0, %2}"
915119a5
BS
15173 [(set_attr "type" "sse")])
15174
15175
15176;; MMX insert/extract/shuffle
15177
15178(define_insn "mmx_pinsrw"
15179 [(set (match_operand:V4HI 0 "register_operand" "=y")
15180 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
15181 (vec_duplicate:V4HI
15182 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
15183 (match_operand:SI 3 "immediate_operand" "i")))]
15184 "TARGET_SSE"
6a4afa6c 15185 "pinsrw\\t{%3, %2, %0|%0, %2, %3}"
915119a5
BS
15186 [(set_attr "type" "sse")])
15187
15188(define_insn "mmx_pextrw"
15189 [(set (match_operand:SI 0 "register_operand" "=r")
15190 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
15191 (parallel
15192 [(match_operand:SI 2 "immediate_operand" "i")]))))]
15193 "TARGET_SSE"
6a4afa6c 15194 "pextrw\\t{%2, %1, %0|%0, %1, %2}"
915119a5
BS
15195 [(set_attr "type" "sse")])
15196
15197(define_insn "mmx_pshufw"
15198 [(set (match_operand:V4HI 0 "register_operand" "=y")
15199 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
15200 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
15201 (match_operand:SI 3 "immediate_operand" "i")] 41))]
15202 "TARGET_SSE"
6a4afa6c 15203 "pshufw\\t{%3, %2, %0|%0, %2, %3}"
915119a5
BS
15204 [(set_attr "type" "sse")])
15205
15206
15207;; MMX mask-generating comparisons
15208
15209(define_insn "eqv8qi3"
15210 [(set (match_operand:V8QI 0 "register_operand" "=y")
15211 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
15212 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15213 "TARGET_MMX"
15214 "pcmpeqb\\t{%2, %0|%0, %2}"
15215 [(set_attr "type" "mmx")])
15216
15217(define_insn "eqv4hi3"
15218 [(set (match_operand:V4HI 0 "register_operand" "=y")
15219 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
15220 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15221 "TARGET_MMX"
15222 "pcmpeqw\\t{%2, %0|%0, %2}"
15223 [(set_attr "type" "mmx")])
15224
15225(define_insn "eqv2si3"
15226 [(set (match_operand:V2SI 0 "register_operand" "=y")
15227 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
15228 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
15229 "TARGET_MMX"
15230 "pcmpeqd\\t{%2, %0|%0, %2}"
15231 [(set_attr "type" "mmx")])
15232
15233(define_insn "gtv8qi3"
15234 [(set (match_operand:V8QI 0 "register_operand" "=y")
15235 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
15236 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15237 "TARGET_MMX"
15238 "pcmpgtb\\t{%2, %0|%0, %2}"
15239 [(set_attr "type" "mmx")])
15240
15241(define_insn "gtv4hi3"
15242 [(set (match_operand:V4HI 0 "register_operand" "=y")
15243 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
15244 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15245 "TARGET_MMX"
15246 "pcmpgtw\\t{%2, %0|%0, %2}"
15247 [(set_attr "type" "mmx")])
15248
15249(define_insn "gtv2si3"
15250 [(set (match_operand:V2SI 0 "register_operand" "=y")
15251 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
15252 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
15253 "TARGET_MMX"
15254 "pcmpgtd\\t{%2, %0|%0, %2}"
15255 [(set_attr "type" "mmx")])
15256
15257
15258;; MMX max/min insns
15259
15260(define_insn "umaxv8qi3"
15261 [(set (match_operand:V8QI 0 "register_operand" "=y")
15262 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
15263 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15264 "TARGET_SSE"
15265 "pmaxub\\t{%2, %0|%0, %2}"
15266 [(set_attr "type" "sse")])
15267
15268(define_insn "smaxv4hi3"
15269 [(set (match_operand:V4HI 0 "register_operand" "=y")
15270 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
15271 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15272 "TARGET_SSE"
15273 "pmaxsw\\t{%2, %0|%0, %2}"
15274 [(set_attr "type" "sse")])
15275
15276(define_insn "uminv8qi3"
15277 [(set (match_operand:V8QI 0 "register_operand" "=y")
15278 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
15279 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
15280 "TARGET_SSE"
15281 "pminub\\t{%2, %0|%0, %2}"
15282 [(set_attr "type" "sse")])
15283
15284(define_insn "sminv4hi3"
15285 [(set (match_operand:V4HI 0 "register_operand" "=y")
15286 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
15287 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
15288 "TARGET_SSE"
15289 "pminsw\\t{%2, %0|%0, %2}"
15290 [(set_attr "type" "sse")])
15291
15292
15293;; MMX shifts
15294
15295(define_insn "ashrv4hi3"
15296 [(set (match_operand:V4HI 0 "register_operand" "=y")
15297 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
15298 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15299 "TARGET_MMX"
15300 "psraw\\t{%2, %0|%0, %2}"
15301 [(set_attr "type" "mmx")])
15302
15303(define_insn "ashrv2si3"
15304 [(set (match_operand:V2SI 0 "register_operand" "=y")
15305 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
15306 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15307 "TARGET_MMX"
15308 "psrad\\t{%2, %0|%0, %2}"
15309 [(set_attr "type" "mmx")])
15310
15311(define_insn "lshrv4hi3"
15312 [(set (match_operand:V4HI 0 "register_operand" "=y")
15313 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
15314 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15315 "TARGET_MMX"
15316 "psrlw\\t{%2, %0|%0, %2}"
15317 [(set_attr "type" "mmx")])
15318
15319(define_insn "lshrv2si3"
15320 [(set (match_operand:V2SI 0 "register_operand" "=y")
15321 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
15322 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15323 "TARGET_MMX"
15324 "psrld\\t{%2, %0|%0, %2}"
15325 [(set_attr "type" "mmx")])
15326
15327;; See logical MMX insns.
15328(define_insn "mmx_lshrdi3"
15329 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
15330 (unspec:DI
15331 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
15332 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
915119a5
BS
15333 "TARGET_MMX"
15334 "psrlq\\t{%2, %0|%0, %2}"
15335 [(set_attr "type" "mmx")])
15336
15337(define_insn "ashlv4hi3"
15338 [(set (match_operand:V4HI 0 "register_operand" "=y")
15339 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
15340 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15341 "TARGET_MMX"
15342 "psllw\\t{%2, %0|%0, %2}"
15343 [(set_attr "type" "mmx")])
15344
15345(define_insn "ashlv2si3"
15346 [(set (match_operand:V2SI 0 "register_operand" "=y")
15347 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
15348 (match_operand:DI 2 "nonmemory_operand" "yi")))]
15349 "TARGET_MMX"
15350 "pslld\\t{%2, %0|%0, %2}"
15351 [(set_attr "type" "mmx")])
15352
15353;; See logical MMX insns.
15354(define_insn "mmx_ashldi3"
15355 [(set (match_operand:DI 0 "register_operand" "=y")
2b71bf37
JH
15356 (unspec:DI
15357 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
15358 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
915119a5
BS
15359 "TARGET_MMX"
15360 "psllq\\t{%2, %0|%0, %2}"
15361 [(set_attr "type" "mmx")])
15362
15363
15364;; MMX pack/unpack insns.
15365
15366(define_insn "mmx_packsswb"
15367 [(set (match_operand:V8QI 0 "register_operand" "=y")
15368 (vec_concat:V8QI
15369 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
15370 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
15371 "TARGET_MMX"
15372 "packsswb\\t{%2, %0|%0, %2}"
15373 [(set_attr "type" "mmx")])
15374
15375(define_insn "mmx_packssdw"
15376 [(set (match_operand:V4HI 0 "register_operand" "=y")
15377 (vec_concat:V4HI
15378 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
15379 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
15380 "TARGET_MMX"
15381 "packssdw\\t{%2, %0|%0, %2}"
15382 [(set_attr "type" "mmx")])
15383
15384(define_insn "mmx_packuswb"
15385 [(set (match_operand:V8QI 0 "register_operand" "=y")
15386 (vec_concat:V8QI
15387 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
15388 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
15389 "TARGET_MMX"
15390 "packuswb\\t{%2, %0|%0, %2}"
15391 [(set_attr "type" "mmx")])
15392
15393(define_insn "mmx_punpckhbw"
15394 [(set (match_operand:V8QI 0 "register_operand" "=y")
15395 (vec_merge:V8QI
15396 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
15397 (parallel [(const_int 4)
15398 (const_int 0)
15399 (const_int 5)
15400 (const_int 1)
15401 (const_int 6)
15402 (const_int 2)
15403 (const_int 7)
15404 (const_int 3)]))
15405 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
15406 (parallel [(const_int 0)
15407 (const_int 4)
15408 (const_int 1)
15409 (const_int 5)
15410 (const_int 2)
15411 (const_int 6)
15412 (const_int 3)
15413 (const_int 7)]))
15414 (const_int 85)))]
15415 "TARGET_MMX"
15416 "punpckhbw\\t{%2, %0|%0, %2}"
15417 [(set_attr "type" "mmx")])
15418
15419(define_insn "mmx_punpckhwd"
15420 [(set (match_operand:V4HI 0 "register_operand" "=y")
15421 (vec_merge:V4HI
15422 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
15423 (parallel [(const_int 0)
15424 (const_int 2)
15425 (const_int 1)
15426 (const_int 3)]))
15427 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
15428 (parallel [(const_int 2)
15429 (const_int 0)
15430 (const_int 3)
15431 (const_int 1)]))
15432 (const_int 5)))]
15433 "TARGET_MMX"
332316cd 15434 "punpckhwd\\t{%2, %0|%0, %2}"
915119a5
BS
15435 [(set_attr "type" "mmx")])
15436
15437(define_insn "mmx_punpckhdq"
15438 [(set (match_operand:V2SI 0 "register_operand" "=y")
15439 (vec_merge:V2SI
15440 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
15441 (parallel [(const_int 0)
15442 (const_int 1)]))
15443 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
15444 (parallel [(const_int 1)
15445 (const_int 0)]))
15446 (const_int 1)))]
15447 "TARGET_MMX"
332316cd 15448 "punpckhdq\\t{%2, %0|%0, %2}"
915119a5
BS
15449 [(set_attr "type" "mmx")])
15450
15451(define_insn "mmx_punpcklbw"
15452 [(set (match_operand:V8QI 0 "register_operand" "=y")
15453 (vec_merge:V8QI
15454 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
15455 (parallel [(const_int 0)
15456 (const_int 4)
15457 (const_int 1)
15458 (const_int 5)
15459 (const_int 2)
15460 (const_int 6)
15461 (const_int 3)
15462 (const_int 7)]))
15463 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
15464 (parallel [(const_int 4)
15465 (const_int 0)
15466 (const_int 5)
15467 (const_int 1)
15468 (const_int 6)
15469 (const_int 2)
15470 (const_int 7)
15471 (const_int 3)]))
15472 (const_int 85)))]
15473 "TARGET_MMX"
15474 "punpcklbw\\t{%2, %0|%0, %2}"
15475 [(set_attr "type" "mmx")])
15476
15477(define_insn "mmx_punpcklwd"
15478 [(set (match_operand:V4HI 0 "register_operand" "=y")
15479 (vec_merge:V4HI
15480 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
15481 (parallel [(const_int 2)
15482 (const_int 0)
15483 (const_int 3)
15484 (const_int 1)]))
15485 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
15486 (parallel [(const_int 0)
15487 (const_int 2)
15488 (const_int 1)
15489 (const_int 3)]))
15490 (const_int 5)))]
15491 "TARGET_MMX"
332316cd 15492 "punpcklwd\\t{%2, %0|%0, %2}"
915119a5
BS
15493 [(set_attr "type" "mmx")])
15494
15495(define_insn "mmx_punpckldq"
15496 [(set (match_operand:V2SI 0 "register_operand" "=y")
15497 (vec_merge:V2SI
15498 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
15499 (parallel [(const_int 1)
15500 (const_int 0)]))
15501 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
15502 (parallel [(const_int 0)
15503 (const_int 1)]))
15504 (const_int 1)))]
15505 "TARGET_MMX"
332316cd 15506 "punpckldq\\t{%2, %0|%0, %2}"
915119a5
BS
15507 [(set_attr "type" "mmx")])
15508
15509
15510;; Miscellaneous stuff
15511
15512(define_insn "emms"
15513 [(unspec_volatile [(const_int 0)] 31)
15514 (clobber (reg:XF 8))
15515 (clobber (reg:XF 9))
15516 (clobber (reg:XF 10))
15517 (clobber (reg:XF 11))
15518 (clobber (reg:XF 12))
15519 (clobber (reg:XF 13))
15520 (clobber (reg:XF 14))
15521 (clobber (reg:XF 15))
915119a5
BS
15522 (clobber (reg:DI 29))
15523 (clobber (reg:DI 30))
15524 (clobber (reg:DI 31))
15525 (clobber (reg:DI 32))
15526 (clobber (reg:DI 33))
bd793c65
BS
15527 (clobber (reg:DI 34))
15528 (clobber (reg:DI 35))
15529 (clobber (reg:DI 36))]
915119a5
BS
15530 "TARGET_MMX"
15531 "emms"
bd793c65
BS
15532 [(set_attr "type" "mmx")
15533 (set_attr "memory" "unknown")])
915119a5
BS
15534
15535(define_insn "ldmxcsr"
15536 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
15537 "TARGET_MMX"
15538 "ldmxcsr\\t%0"
15539 [(set_attr "type" "mmx")])
15540
15541(define_insn "stmxcsr"
15542 [(set (match_operand:SI 0 "memory_operand" "=m")
15543 (unspec_volatile:SI [(const_int 0)] 40))]
15544 "TARGET_MMX"
15545 "stmxcsr\\t%0"
15546 [(set_attr "type" "mmx")])
15547
15548(define_expand "sfence"
15549 [(set (match_dup 0)
15550 (unspec:BLK [(match_dup 0)] 44))]
15551 "TARGET_SSE"
15552 "
15553{
15554 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15555 MEM_VOLATILE_P (operands[0]) = 1;
15556}")
15557
15558(define_insn "*sfence_insn"
15559 [(set (match_operand:BLK 0 "" "")
15560 (unspec:BLK [(match_dup 0)] 44))]
15561 "TARGET_SSE"
15562 "sfence"
bd793c65
BS
15563 [(set_attr "type" "sse")
15564 (set_attr "memory" "unknown")])
915119a5
BS
15565
15566(define_insn "prefetch"
15567 [(unspec [(match_operand:SI 0 "address_operand" "p")
332316cd 15568 (match_operand:SI 1 "immediate_operand" "n")] 35)]
915119a5
BS
15569 "TARGET_SSE"
15570 "*
15571{
15572 switch (INTVAL (operands[1]))
15573 {
15574 case 0:
332316cd 15575 return \"prefetchnta\\t%a0\";
915119a5 15576 case 1:
332316cd 15577 return \"prefetcht0\\t%a0\";
915119a5 15578 case 2:
332316cd 15579 return \"prefetcht1\\t%a0\";
915119a5 15580 case 3:
332316cd 15581 return \"prefetcht2\\t%a0\";
915119a5
BS
15582 default:
15583 abort ();
15584 }
15585}"
15586 [(set_attr "type" "sse")])
15587
This page took 3.091721 seconds and 5 git commands to generate.