avr.c: Fix comment typos.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;; x86_64 support added by Jan Hubicka
6 ;;
7 ;; This file is part of GNU CC.
8 ;;
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.
13 ;;
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.
18 ;;
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
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
30 ;; updates for most instructions.
31 ;;
32 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
33 ;; constraint letters.
34 ;;
35 ;; The special asm out single letter directives following a '%' are:
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.
41 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
42 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
43 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
44 ;; 'J' Print the appropriate jump operand.
45 ;;
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.
52 ;;
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.
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'.
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.
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.
68 ;; 5 This is a `bsf' operation.
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.
72 ;; 9 This is an `fnstsw' operation.
73 ;; 10 This is a `sahf' operation.
74 ;; 11 This is a `fstcw' operation
75 ;; 12 This is behaviour of add when setting carry flag.
76 ;; 13 This is a `eh_return' placeholder.
77
78 ;; For SSE/MMX support:
79 ;; 30 This is `fix', guaranteed to be truncating.
80 ;; 31 This is a `emms' operation.
81 ;; 32 This is a `maskmov' operation.
82 ;; 33 This is a `movmsk' operation.
83 ;; 34 This is a `non-temporal' move.
84 ;; 35 This is a `prefetch' (SSE) operation.
85 ;; 36 This is used to distinguish COMISS from UCOMISS.
86 ;; 37 This is a `ldmxcsr' operation.
87 ;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
88 ;; 39 This is a forced `movups' instruction (rather than whatever movti does)
89 ;; 40 This is a `stmxcsr' operation.
90 ;; 41 This is a `shuffle' operation.
91 ;; 42 This is a `rcp' operation.
92 ;; 43 This is a `rsqsrt' operation.
93 ;; 44 This is a `sfence' operation.
94 ;; 45 This is a noop to prevent excessive combiner cleverness.
95 ;; 46 This is a `femms' operation.
96 ;; 49 This is a 'pavgusb' operation.
97 ;; 50 This is a `pfrcp' operation.
98 ;; 51 This is a `pfrcpit1' operation.
99 ;; 52 This is a `pfrcpit2' operation.
100 ;; 53 This is a `pfrsqrt' operation.
101 ;; 54 This is a `pfrsqrit1' operation.
102
103 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
104 ;; from i386.c.
105
106 ;; In C guard expressions, put expressions which may be compile-time
107 ;; constants first. This allows for better optimization. For
108 ;; example, write "TARGET_64BIT && reload_completed", not
109 ;; "reload_completed && TARGET_64BIT".
110
111 \f
112 ;; Processor type. This attribute must exactly match the processor_type
113 ;; enumeration in i386.h.
114 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
115 (const (symbol_ref "ix86_cpu")))
116
117 ;; A basic instruction type. Refinements due to arguments to be
118 ;; provided in other attributes.
119 (define_attr "type"
120 "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
121 (const_string "other"))
122
123 ;; Main data type used by the insn
124 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
125 (const_string "unknown"))
126
127 ;; Set for i387 operations.
128 (define_attr "i387" ""
129 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
130 (const_int 1)
131 (const_int 0)))
132
133 ;; The (bounding maximum) length of an instruction immediate.
134 (define_attr "length_immediate" ""
135 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
136 (const_int 0)
137 (eq_attr "i387" "1")
138 (const_int 0)
139 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
140 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
141 (eq_attr "type" "imov,test")
142 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
143 (eq_attr "type" "call")
144 (if_then_else (match_operand 0 "constant_call_address_operand" "")
145 (const_int 4)
146 (const_int 0))
147 (eq_attr "type" "callv")
148 (if_then_else (match_operand 1 "constant_call_address_operand" "")
149 (const_int 4)
150 (const_int 0))
151 (eq_attr "type" "ibr")
152 (if_then_else (and (ge (minus (match_dup 0) (pc))
153 (const_int -128))
154 (lt (minus (match_dup 0) (pc))
155 (const_int 124)))
156 (const_int 1)
157 (const_int 4))
158 ]
159 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
160
161 ;; The (bounding maximum) length of an instruction address.
162 (define_attr "length_address" ""
163 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
164 (const_int 0)
165 (and (eq_attr "type" "call")
166 (match_operand 1 "constant_call_address_operand" ""))
167 (const_int 0)
168 (and (eq_attr "type" "callv")
169 (match_operand 1 "constant_call_address_operand" ""))
170 (const_int 0)
171 ]
172 (symbol_ref "ix86_attr_length_address_default (insn)")))
173
174 ;; Set when length prefix is used.
175 (define_attr "prefix_data16" ""
176 (if_then_else (eq_attr "mode" "HI")
177 (const_int 1)
178 (const_int 0)))
179
180 ;; Set when string REP prefix is used.
181 (define_attr "prefix_rep" "" (const_int 0))
182
183 ;; Set when 0f opcode prefix is used.
184 (define_attr "prefix_0f" ""
185 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
186 (const_int 1)
187 (const_int 0)))
188
189 ;; Set when modrm byte is used.
190 (define_attr "modrm" ""
191 (cond [(eq_attr "type" "str,cld")
192 (const_int 0)
193 (eq_attr "i387" "1")
194 (const_int 0)
195 (and (eq_attr "type" "incdec")
196 (ior (match_operand:SI 1 "register_operand" "")
197 (match_operand:HI 1 "register_operand" "")))
198 (const_int 0)
199 (and (eq_attr "type" "push")
200 (not (match_operand 1 "memory_operand" "")))
201 (const_int 0)
202 (and (eq_attr "type" "pop")
203 (not (match_operand 0 "memory_operand" "")))
204 (const_int 0)
205 (and (eq_attr "type" "imov")
206 (and (match_operand 0 "register_operand" "")
207 (match_operand 1 "immediate_operand" "")))
208 (const_int 0)
209 ]
210 (const_int 1)))
211
212 ;; The (bounding maximum) length of an instruction in bytes.
213 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
214 ;; to split it and compute proper length as for other insns.
215 (define_attr "length" ""
216 (cond [(eq_attr "type" "other,multi,fistp")
217 (const_int 16)
218 ]
219 (plus (plus (attr "modrm")
220 (plus (attr "prefix_0f")
221 (plus (attr "i387")
222 (const_int 1))))
223 (plus (attr "prefix_rep")
224 (plus (attr "prefix_data16")
225 (plus (attr "length_immediate")
226 (attr "length_address")))))))
227
228 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
229 ;; `store' if there is a simple memory reference therein, or `unknown'
230 ;; if the instruction is complex.
231
232 (define_attr "memory" "none,load,store,both,unknown"
233 (cond [(eq_attr "type" "other,multi,str")
234 (const_string "unknown")
235 (eq_attr "type" "lea,fcmov,fpspc,cld")
236 (const_string "none")
237 (eq_attr "type" "fistp")
238 (const_string "both")
239 (eq_attr "type" "push")
240 (if_then_else (match_operand 1 "memory_operand" "")
241 (const_string "both")
242 (const_string "store"))
243 (eq_attr "type" "pop,setcc")
244 (if_then_else (match_operand 0 "memory_operand" "")
245 (const_string "both")
246 (const_string "load"))
247 (eq_attr "type" "icmp,test")
248 (if_then_else (ior (match_operand 0 "memory_operand" "")
249 (match_operand 1 "memory_operand" ""))
250 (const_string "load")
251 (const_string "none"))
252 (eq_attr "type" "ibr")
253 (if_then_else (match_operand 0 "memory_operand" "")
254 (const_string "load")
255 (const_string "none"))
256 (eq_attr "type" "call")
257 (if_then_else (match_operand 0 "constant_call_address_operand" "")
258 (const_string "none")
259 (const_string "load"))
260 (eq_attr "type" "callv")
261 (if_then_else (match_operand 1 "constant_call_address_operand" "")
262 (const_string "none")
263 (const_string "load"))
264 (and (eq_attr "type" "alu1,negnot")
265 (match_operand 1 "memory_operand" ""))
266 (const_string "both")
267 (and (match_operand 0 "memory_operand" "")
268 (match_operand 1 "memory_operand" ""))
269 (const_string "both")
270 (match_operand 0 "memory_operand" "")
271 (const_string "store")
272 (match_operand 1 "memory_operand" "")
273 (const_string "load")
274 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
275 (match_operand 2 "memory_operand" ""))
276 (const_string "load")
277 (and (eq_attr "type" "icmov")
278 (match_operand 3 "memory_operand" ""))
279 (const_string "load")
280 ]
281 (const_string "none")))
282
283 ;; Indicates if an instruction has both an immediate and a displacement.
284
285 (define_attr "imm_disp" "false,true,unknown"
286 (cond [(eq_attr "type" "other,multi")
287 (const_string "unknown")
288 (and (eq_attr "type" "icmp,test,imov")
289 (and (match_operand 0 "memory_displacement_operand" "")
290 (match_operand 1 "immediate_operand" "")))
291 (const_string "true")
292 (and (eq_attr "type" "alu,ishift,imul,idiv")
293 (and (match_operand 0 "memory_displacement_operand" "")
294 (match_operand 2 "immediate_operand" "")))
295 (const_string "true")
296 ]
297 (const_string "false")))
298
299 ;; Indicates if an FP operation has an integer source.
300
301 (define_attr "fp_int_src" "false,true"
302 (const_string "false"))
303
304 ;; Describe a user's asm statement.
305 (define_asm_attributes
306 [(set_attr "length" "128")
307 (set_attr "type" "multi")])
308 \f
309 ;; Pentium Scheduling
310 ;;
311 ;; The Pentium is an in-order core with two integer pipelines.
312
313 ;; True for insns that behave like prefixed insns on the Pentium.
314 (define_attr "pent_prefix" "false,true"
315 (if_then_else (ior (eq_attr "prefix_0f" "1")
316 (ior (eq_attr "prefix_data16" "1")
317 (eq_attr "prefix_rep" "1")))
318 (const_string "true")
319 (const_string "false")))
320
321 ;; Categorize how an instruction slots.
322
323 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
324 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
325 ;; rules, because it results in noticeably better code on non-MMX Pentium
326 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
327 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
328
329 (define_attr "pent_pair" "uv,pu,pv,np"
330 (cond [(eq_attr "imm_disp" "true")
331 (const_string "np")
332 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
333 (and (eq_attr "type" "pop,push")
334 (eq_attr "memory" "!both")))
335 (if_then_else (eq_attr "pent_prefix" "true")
336 (const_string "pu")
337 (const_string "uv"))
338 (eq_attr "type" "ibr")
339 (const_string "pv")
340 (and (eq_attr "type" "ishift")
341 (match_operand 2 "const_int_operand" ""))
342 (const_string "pu")
343 (and (eq_attr "type" "call")
344 (match_operand 0 "constant_call_address_operand" ""))
345 (const_string "pv")
346 (and (eq_attr "type" "callv")
347 (match_operand 1 "constant_call_address_operand" ""))
348 (const_string "pv")
349 ]
350 (const_string "np")))
351
352 ;; Rough readiness numbers. Fine tuning happens in i386.c.
353 ;;
354 ;; u describes pipe U
355 ;; v describes pipe V
356 ;; uv describes either pipe U or V for those that can issue to either
357 ;; np describes not paring
358 ;; fpu describes fpu
359 ;; fpm describes fp insns of different types are not pipelined.
360 ;;
361 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
362
363 (define_function_unit "pent_np" 1 0
364 (and (eq_attr "cpu" "pentium")
365 (eq_attr "type" "imul"))
366 11 11)
367
368 (define_function_unit "pent_mul" 1 1
369 (and (eq_attr "cpu" "pentium")
370 (eq_attr "type" "imul"))
371 11 11)
372
373 ;; Rep movs takes minimally 12 cycles.
374 (define_function_unit "pent_np" 1 0
375 (and (eq_attr "cpu" "pentium")
376 (eq_attr "type" "str"))
377 12 12)
378
379 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
380 (define_function_unit "pent_np" 1 0
381 (and (eq_attr "cpu" "pentium")
382 (eq_attr "type" "idiv"))
383 46 46)
384
385 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
386 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
387 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
388 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
389 ; like normal fp operation and fist takes 6 cycles.
390
391 (define_function_unit "fpu" 1 0
392 (and (eq_attr "cpu" "pentium")
393 (and (eq_attr "type" "fmov")
394 (and (eq_attr "memory" "load,store")
395 (eq_attr "mode" "XF"))))
396 3 3)
397
398 (define_function_unit "pent_np" 1 0
399 (and (eq_attr "cpu" "pentium")
400 (and (eq_attr "type" "fmov")
401 (and (eq_attr "memory" "load,store")
402 (eq_attr "mode" "XF"))))
403 3 3)
404
405 (define_function_unit "fpu" 1 0
406 (and (eq_attr "cpu" "pentium")
407 (and (eq_attr "type" "fmov")
408 (ior (match_operand 1 "immediate_operand" "")
409 (eq_attr "memory" "store"))))
410 2 2)
411
412 (define_function_unit "pent_np" 1 0
413 (and (eq_attr "cpu" "pentium")
414 (and (eq_attr "type" "fmov")
415 (ior (match_operand 1 "immediate_operand" "")
416 (eq_attr "memory" "store"))))
417 2 2)
418
419 (define_function_unit "pent_np" 1 0
420 (and (eq_attr "cpu" "pentium")
421 (eq_attr "type" "cld"))
422 2 2)
423
424 (define_function_unit "fpu" 1 0
425 (and (eq_attr "cpu" "pentium")
426 (and (eq_attr "type" "fmov")
427 (eq_attr "memory" "none,load")))
428 1 1)
429
430 ; Read/Modify/Write instructions usually take 3 cycles.
431 (define_function_unit "pent_u" 1 0
432 (and (eq_attr "cpu" "pentium")
433 (and (eq_attr "type" "alu,alu1,ishift")
434 (and (eq_attr "pent_pair" "pu")
435 (eq_attr "memory" "both"))))
436 3 3)
437
438 (define_function_unit "pent_uv" 2 0
439 (and (eq_attr "cpu" "pentium")
440 (and (eq_attr "type" "alu,alu1,ishift")
441 (and (eq_attr "pent_pair" "!np")
442 (eq_attr "memory" "both"))))
443 3 3)
444
445 (define_function_unit "pent_np" 1 0
446 (and (eq_attr "cpu" "pentium")
447 (and (eq_attr "type" "alu,alu1,negnot,ishift")
448 (and (eq_attr "pent_pair" "np")
449 (eq_attr "memory" "both"))))
450 3 3)
451
452 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
453 (define_function_unit "pent_u" 1 0
454 (and (eq_attr "cpu" "pentium")
455 (and (eq_attr "type" "alu,ishift")
456 (and (eq_attr "pent_pair" "pu")
457 (eq_attr "memory" "load,store"))))
458 2 2)
459
460 (define_function_unit "pent_uv" 2 0
461 (and (eq_attr "cpu" "pentium")
462 (and (eq_attr "type" "alu,ishift")
463 (and (eq_attr "pent_pair" "!np")
464 (eq_attr "memory" "load,store"))))
465 2 2)
466
467 (define_function_unit "pent_np" 1 0
468 (and (eq_attr "cpu" "pentium")
469 (and (eq_attr "type" "alu,ishift")
470 (and (eq_attr "pent_pair" "np")
471 (eq_attr "memory" "load,store"))))
472 2 2)
473
474 ; Insns w/o memory operands and move instructions usually take one cycle.
475 (define_function_unit "pent_u" 1 0
476 (and (eq_attr "cpu" "pentium")
477 (eq_attr "pent_pair" "pu"))
478 1 1)
479
480 (define_function_unit "pent_v" 1 0
481 (and (eq_attr "cpu" "pentium")
482 (eq_attr "pent_pair" "pv"))
483 1 1)
484
485 (define_function_unit "pent_uv" 2 0
486 (and (eq_attr "cpu" "pentium")
487 (eq_attr "pent_pair" "!np"))
488 1 1)
489
490 (define_function_unit "pent_np" 1 0
491 (and (eq_attr "cpu" "pentium")
492 (eq_attr "pent_pair" "np"))
493 1 1)
494
495 ; Pairable insns only conflict with other non-pairable insns.
496 (define_function_unit "pent_np" 1 0
497 (and (eq_attr "cpu" "pentium")
498 (and (eq_attr "type" "alu,alu1,ishift")
499 (and (eq_attr "pent_pair" "!np")
500 (eq_attr "memory" "both"))))
501 3 3
502 [(eq_attr "pent_pair" "np")])
503
504 (define_function_unit "pent_np" 1 0
505 (and (eq_attr "cpu" "pentium")
506 (and (eq_attr "type" "alu,alu1,ishift")
507 (and (eq_attr "pent_pair" "!np")
508 (eq_attr "memory" "load,store"))))
509 2 2
510 [(eq_attr "pent_pair" "np")])
511
512 (define_function_unit "pent_np" 1 0
513 (and (eq_attr "cpu" "pentium")
514 (eq_attr "pent_pair" "!np"))
515 1 1
516 [(eq_attr "pent_pair" "np")])
517
518 ; Floating point instructions usually blocks cycle longer when combined with
519 ; integer instructions, because of the inpaired fxch instruction.
520 (define_function_unit "pent_np" 1 0
521 (and (eq_attr "cpu" "pentium")
522 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
523 2 2
524 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
525
526 (define_function_unit "fpu" 1 0
527 (and (eq_attr "cpu" "pentium")
528 (eq_attr "type" "fcmp,fxch,fsgn"))
529 1 1)
530
531 ; Addition takes 3 cycles; assume other random cruft does as well.
532 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
533 (define_function_unit "fpu" 1 0
534 (and (eq_attr "cpu" "pentium")
535 (eq_attr "type" "fop,fop1,fistp"))
536 3 1)
537
538 ; Multiplication takes 3 cycles and is only half pipelined.
539 (define_function_unit "fpu" 1 0
540 (and (eq_attr "cpu" "pentium")
541 (eq_attr "type" "fmul"))
542 3 1)
543
544 (define_function_unit "pent_mul" 1 1
545 (and (eq_attr "cpu" "pentium")
546 (eq_attr "type" "fmul"))
547 2 2)
548
549 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
550 ; They can overlap with integer insns. Only the last two cycles can overlap
551 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
552 ; Only last two cycles of fsin/fcos can overlap with other instructions.
553 (define_function_unit "fpu" 1 0
554 (and (eq_attr "cpu" "pentium")
555 (eq_attr "type" "fdiv"))
556 39 37)
557
558 (define_function_unit "pent_mul" 1 1
559 (and (eq_attr "cpu" "pentium")
560 (eq_attr "type" "fdiv"))
561 39 39)
562
563 (define_function_unit "fpu" 1 0
564 (and (eq_attr "cpu" "pentium")
565 (eq_attr "type" "fpspc"))
566 70 68)
567
568 (define_function_unit "pent_mul" 1 1
569 (and (eq_attr "cpu" "pentium")
570 (eq_attr "type" "fpspc"))
571 70 70)
572 \f
573 ;; Pentium Pro/PII Scheduling
574 ;;
575 ;; The PPro has an out-of-order core, but the instruction decoders are
576 ;; naturally in-order and asymmetric. We get best performance by scheduling
577 ;; for the decoders, for in doing so we give the oo execution unit the
578 ;; most choices.
579
580 ;; Categorize how many uops an ia32 instruction evaluates to:
581 ;; one -- an instruction with 1 uop can be decoded by any of the
582 ;; three decoders.
583 ;; few -- an instruction with 1 to 4 uops can be decoded only by
584 ;; decoder 0.
585 ;; many -- a complex instruction may take an unspecified number of
586 ;; cycles to decode in decoder 0.
587
588 (define_attr "ppro_uops" "one,few,many"
589 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
590 (const_string "many")
591 (eq_attr "type" "icmov,fcmov,str,cld")
592 (const_string "few")
593 (eq_attr "type" "imov")
594 (if_then_else (eq_attr "memory" "store,both")
595 (const_string "few")
596 (const_string "one"))
597 (eq_attr "memory" "!none")
598 (const_string "few")
599 ]
600 (const_string "one")))
601
602 ;; Rough readiness numbers. Fine tuning happens in i386.c.
603 ;;
604 ;; p0 describes port 0.
605 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
606 ;; p2 describes port 2 for loads.
607 ;; p34 describes ports 3 and 4 for stores.
608 ;; fpu describes the fpu accessed via port 0.
609 ;; ??? It is less than clear if there are separate fadd and fmul units
610 ;; that could operate in parallel.
611 ;;
612 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
613
614 (define_function_unit "ppro_p0" 1 0
615 (and (eq_attr "cpu" "pentiumpro")
616 (eq_attr "type" "ishift,lea,ibr,cld"))
617 1 1)
618
619 (define_function_unit "ppro_p0" 1 0
620 (and (eq_attr "cpu" "pentiumpro")
621 (eq_attr "type" "imul"))
622 4 1)
623
624 ;; ??? Does the divider lock out the pipe while it works,
625 ;; or is there a disconnected unit?
626 (define_function_unit "ppro_p0" 1 0
627 (and (eq_attr "cpu" "pentiumpro")
628 (eq_attr "type" "idiv"))
629 17 17)
630
631 (define_function_unit "ppro_p0" 1 0
632 (and (eq_attr "cpu" "pentiumpro")
633 (eq_attr "type" "fop,fop1,fsgn,fistp"))
634 3 1)
635
636 (define_function_unit "ppro_p0" 1 0
637 (and (eq_attr "cpu" "pentiumpro")
638 (eq_attr "type" "fcmov"))
639 2 1)
640
641 (define_function_unit "ppro_p0" 1 0
642 (and (eq_attr "cpu" "pentiumpro")
643 (eq_attr "type" "fcmp"))
644 1 1)
645
646 (define_function_unit "ppro_p0" 1 0
647 (and (eq_attr "cpu" "pentiumpro")
648 (eq_attr "type" "fmov"))
649 1 1)
650
651 (define_function_unit "ppro_p0" 1 0
652 (and (eq_attr "cpu" "pentiumpro")
653 (eq_attr "type" "fmul"))
654 5 1)
655
656 (define_function_unit "ppro_p0" 1 0
657 (and (eq_attr "cpu" "pentiumpro")
658 (eq_attr "type" "fdiv,fpspc"))
659 56 1)
660
661 (define_function_unit "ppro_p01" 2 0
662 (and (eq_attr "cpu" "pentiumpro")
663 (eq_attr "type" "!imov,fmov"))
664 1 1)
665
666 (define_function_unit "ppro_p01" 2 0
667 (and (and (eq_attr "cpu" "pentiumpro")
668 (eq_attr "type" "imov,fmov"))
669 (eq_attr "memory" "none"))
670 1 1)
671
672 (define_function_unit "ppro_p2" 1 0
673 (and (eq_attr "cpu" "pentiumpro")
674 (ior (eq_attr "type" "pop")
675 (eq_attr "memory" "load,both")))
676 3 1)
677
678 (define_function_unit "ppro_p34" 1 0
679 (and (eq_attr "cpu" "pentiumpro")
680 (ior (eq_attr "type" "push")
681 (eq_attr "memory" "store,both")))
682 1 1)
683
684 (define_function_unit "fpu" 1 0
685 (and (eq_attr "cpu" "pentiumpro")
686 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
687 1 1)
688
689 (define_function_unit "fpu" 1 0
690 (and (eq_attr "cpu" "pentiumpro")
691 (eq_attr "type" "fmul"))
692 5 2)
693
694 (define_function_unit "fpu" 1 0
695 (and (eq_attr "cpu" "pentiumpro")
696 (eq_attr "type" "fdiv,fpspc"))
697 56 56)
698
699 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
700 (define_function_unit "fpu" 1 0
701 (and (eq_attr "cpu" "pentiumpro")
702 (eq_attr "type" "imul"))
703 4 1)
704 \f
705 ;; AMD K6/K6-2 Scheduling
706 ;;
707 ;; The K6 has similar architecture to PPro. Important difference is, that
708 ;; there are only two decoders and they seems to be much slower than execution
709 ;; units. So we have to pay much more attention to proper decoding for
710 ;; schedulers. We share most of scheduler code for PPro in i386.c
711 ;;
712 ;; The fp unit is not pipelined and do one operation per two cycles including
713 ;; the FXCH.
714 ;;
715 ;; alu describes both ALU units (ALU-X and ALU-Y).
716 ;; alux describes X alu unit
717 ;; fpu describes FPU unit
718 ;; load describes load unit.
719 ;; branch describes branch unit.
720 ;; store decsribes store unit. This unit is not modelled completely and only
721 ;; used to model lea operation. Otherwise it lie outside of the critical
722 ;; path.
723 ;;
724 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
725
726 ;; The decoder specification is in the PPro section above!
727
728 ;; Shift instructions and certain arithmetic are issued only to X pipe.
729 (define_function_unit "k6_alux" 1 0
730 (and (eq_attr "cpu" "k6")
731 (eq_attr "type" "ishift,alu1,negnot,cld"))
732 1 1)
733
734 ;; The QI mode arithmetic is issued to X pipe only.
735 (define_function_unit "k6_alux" 1 0
736 (and (eq_attr "cpu" "k6")
737 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
738 (match_operand:QI 0 "general_operand" "")))
739 1 1)
740
741 (define_function_unit "k6_alu" 2 0
742 (and (eq_attr "cpu" "k6")
743 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
744 1 1)
745
746 (define_function_unit "k6_alu" 2 0
747 (and (eq_attr "cpu" "k6")
748 (and (eq_attr "type" "imov")
749 (eq_attr "memory" "none")))
750 1 1)
751
752 (define_function_unit "k6_branch" 1 0
753 (and (eq_attr "cpu" "k6")
754 (eq_attr "type" "call,callv,ibr"))
755 1 1)
756
757 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
758 (define_function_unit "k6_load" 1 0
759 (and (eq_attr "cpu" "k6")
760 (ior (eq_attr "type" "pop")
761 (eq_attr "memory" "load,both")))
762 1 1)
763
764 (define_function_unit "k6_load" 1 0
765 (and (eq_attr "cpu" "k6")
766 (and (eq_attr "type" "str")
767 (eq_attr "memory" "load,both")))
768 10 10)
769
770 ;; Lea have two instructions, so latency is probably 2
771 (define_function_unit "k6_store" 1 0
772 (and (eq_attr "cpu" "k6")
773 (eq_attr "type" "lea"))
774 2 1)
775
776 (define_function_unit "k6_store" 1 0
777 (and (eq_attr "cpu" "k6")
778 (eq_attr "type" "str"))
779 10 10)
780
781 (define_function_unit "k6_store" 1 0
782 (and (eq_attr "cpu" "k6")
783 (ior (eq_attr "type" "push")
784 (eq_attr "memory" "store,both")))
785 1 1)
786
787 (define_function_unit "k6_fpu" 1 1
788 (and (eq_attr "cpu" "k6")
789 (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
790 2 2)
791
792 (define_function_unit "k6_fpu" 1 1
793 (and (eq_attr "cpu" "k6")
794 (eq_attr "type" "fmul"))
795 2 2)
796
797 ;; ??? Guess
798 (define_function_unit "k6_fpu" 1 1
799 (and (eq_attr "cpu" "k6")
800 (eq_attr "type" "fdiv,fpspc"))
801 56 56)
802
803 (define_function_unit "k6_alu" 2 0
804 (and (eq_attr "cpu" "k6")
805 (eq_attr "type" "imul"))
806 2 2)
807
808 (define_function_unit "k6_alux" 1 0
809 (and (eq_attr "cpu" "k6")
810 (eq_attr "type" "imul"))
811 2 2)
812
813 ;; ??? Guess
814 (define_function_unit "k6_alu" 2 0
815 (and (eq_attr "cpu" "k6")
816 (eq_attr "type" "idiv"))
817 17 17)
818
819 (define_function_unit "k6_alux" 1 0
820 (and (eq_attr "cpu" "k6")
821 (eq_attr "type" "idiv"))
822 17 17)
823 \f
824 ;; AMD Athlon Scheduling
825 ;;
826 ;; The Athlon does contain three pipelined FP units, three integer units and
827 ;; three address generation units.
828 ;;
829 ;; The predecode logic is determining boundaries of instructions in the 64
830 ;; byte cache line. So the cache line straddling problem of K6 might be issue
831 ;; here as well, but it is not noted in the documentation.
832 ;;
833 ;; Three DirectPath instructions decoders and only one VectorPath decoder
834 ;; is available. They can decode three DirectPath instructions or one VectorPath
835 ;; instruction per cycle.
836 ;; Decoded macro instructions are then passed to 72 entry instruction control
837 ;; unit, that passes
838 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
839 ;;
840 ;; The load/store queue unit is not attached to the schedulers but
841 ;; communicates with all the execution units separately instead.
842
843 (define_attr "athlon_decode" "direct,vector"
844 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
845 (const_string "vector")
846 (and (eq_attr "type" "push")
847 (match_operand 1 "memory_operand" ""))
848 (const_string "vector")
849 (and (eq_attr "type" "fmov")
850 (and (eq_attr "memory" "load,store")
851 (eq_attr "mode" "XF")))
852 (const_string "vector")]
853 (const_string "direct")))
854
855 (define_function_unit "athlon_vectordec" 1 0
856 (and (eq_attr "cpu" "athlon")
857 (eq_attr "athlon_decode" "vector"))
858 1 1)
859
860 (define_function_unit "athlon_directdec" 3 0
861 (and (eq_attr "cpu" "athlon")
862 (eq_attr "athlon_decode" "direct"))
863 1 1)
864
865 (define_function_unit "athlon_vectordec" 1 0
866 (and (eq_attr "cpu" "athlon")
867 (eq_attr "athlon_decode" "direct"))
868 1 1 [(eq_attr "athlon_decode" "vector")])
869
870 (define_function_unit "athlon_ieu" 3 0
871 (and (eq_attr "cpu" "athlon")
872 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
873 1 1)
874
875 (define_function_unit "athlon_ieu" 3 0
876 (and (eq_attr "cpu" "athlon")
877 (eq_attr "type" "str"))
878 15 15)
879
880 (define_function_unit "athlon_ieu" 3 0
881 (and (eq_attr "cpu" "athlon")
882 (eq_attr "type" "imul"))
883 5 0)
884
885 (define_function_unit "athlon_ieu" 3 0
886 (and (eq_attr "cpu" "athlon")
887 (eq_attr "type" "idiv"))
888 42 0)
889
890 (define_function_unit "athlon_muldiv" 1 0
891 (and (eq_attr "cpu" "athlon")
892 (eq_attr "type" "imul"))
893 5 0)
894
895 (define_function_unit "athlon_muldiv" 1 0
896 (and (eq_attr "cpu" "athlon")
897 (eq_attr "type" "idiv"))
898 42 42)
899
900 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
901 (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
902 (const_string "add")
903 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
904 (const_string "mul")
905 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
906 (const_string "store")
907 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
908 (const_string "any")
909 (and (eq_attr "type" "fmov")
910 (ior (match_operand:SI 1 "register_operand" "")
911 (match_operand 1 "immediate_operand" "")))
912 (const_string "store")
913 (eq_attr "type" "fmov")
914 (const_string "muladd")]
915 (const_string "none")))
916
917 ;; We use latencies 1 for definitions. This is OK to model colisions
918 ;; in execution units. The real latencies are modeled in the "fp" pipeline.
919
920 ;; fsin, fcos: 96-192
921 ;; fsincos: 107-211
922 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
923 (define_function_unit "athlon_fp" 3 0
924 (and (eq_attr "cpu" "athlon")
925 (eq_attr "type" "fpspc"))
926 100 1)
927
928 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
929 (define_function_unit "athlon_fp" 3 0
930 (and (eq_attr "cpu" "athlon")
931 (eq_attr "type" "fdiv"))
932 24 1)
933
934 (define_function_unit "athlon_fp" 3 0
935 (and (eq_attr "cpu" "athlon")
936 (eq_attr "type" "fop,fop1,fmul,fistp"))
937 4 1)
938
939 ;; XFmode loads are slow.
940 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
941 ;; there are no dependent instructions.
942
943 (define_function_unit "athlon_fp" 3 0
944 (and (eq_attr "cpu" "athlon")
945 (and (eq_attr "type" "fmov")
946 (and (eq_attr "memory" "load")
947 (eq_attr "mode" "XF"))))
948 10 1)
949
950 (define_function_unit "athlon_fp" 3 0
951 (and (eq_attr "cpu" "athlon")
952 (eq_attr "type" "fmov,fsgn"))
953 2 1)
954
955 ;; fcmp and ftst instructions
956 (define_function_unit "athlon_fp" 3 0
957 (and (eq_attr "cpu" "athlon")
958 (and (eq_attr "type" "fcmp")
959 (eq_attr "athlon_decode" "direct")))
960 3 1)
961
962 ;; fcmpi instructions.
963 (define_function_unit "athlon_fp" 3 0
964 (and (eq_attr "cpu" "athlon")
965 (and (eq_attr "type" "fcmp")
966 (eq_attr "athlon_decode" "vector")))
967 3 1)
968
969 (define_function_unit "athlon_fp" 3 0
970 (and (eq_attr "cpu" "athlon")
971 (eq_attr "type" "fcmov"))
972 7 1)
973
974 (define_function_unit "athlon_fp_mul" 1 0
975 (and (eq_attr "cpu" "athlon")
976 (eq_attr "athlon_fpunits" "mul"))
977 1 1)
978
979 (define_function_unit "athlon_fp_add" 1 0
980 (and (eq_attr "cpu" "athlon")
981 (eq_attr "athlon_fpunits" "add"))
982 1 1)
983
984 (define_function_unit "athlon_fp_muladd" 2 0
985 (and (eq_attr "cpu" "athlon")
986 (eq_attr "athlon_fpunits" "muladd,mul,add"))
987 1 1)
988
989 (define_function_unit "athlon_fp_store" 1 0
990 (and (eq_attr "cpu" "athlon")
991 (eq_attr "athlon_fpunits" "store"))
992 1 1)
993
994 ;; We don't need to model the Address Generation Unit, since we don't model
995 ;; the re-order buffer yet and thus we never schedule more than three operations
996 ;; at time. Later we may want to experiment with MD_SCHED macros modeling the
997 ;; decoders independently on the functional units.
998
999 ;(define_function_unit "athlon_agu" 3 0
1000 ; (and (eq_attr "cpu" "athlon")
1001 ; (and (eq_attr "memory" "!none")
1002 ; (eq_attr "athlon_fpunits" "none")))
1003 ; 1 1)
1004
1005 ;; Model load unit to avoid too long sequences of loads. We don't need to
1006 ;; model store queue, since it is hardly going to be bottleneck.
1007
1008 (define_function_unit "athlon_load" 2 0
1009 (and (eq_attr "cpu" "athlon")
1010 (eq_attr "memory" "load,both"))
1011 1 1)
1012
1013 \f
1014 ;; Compare instructions.
1015
1016 ;; All compare insns have expanders that save the operands away without
1017 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
1018 ;; after the cmp) will actually emit the cmpM.
1019
1020 (define_expand "cmpdi"
1021 [(set (reg:CC 17)
1022 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1023 (match_operand:DI 1 "x86_64_general_operand" "")))]
1024 ""
1025 {
1026 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1027 operands[0] = force_reg (DImode, operands[0]);
1028 ix86_compare_op0 = operands[0];
1029 ix86_compare_op1 = operands[1];
1030 DONE;
1031 })
1032
1033 (define_expand "cmpsi"
1034 [(set (reg:CC 17)
1035 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1036 (match_operand:SI 1 "general_operand" "")))]
1037 ""
1038 {
1039 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1040 operands[0] = force_reg (SImode, operands[0]);
1041 ix86_compare_op0 = operands[0];
1042 ix86_compare_op1 = operands[1];
1043 DONE;
1044 })
1045
1046 (define_expand "cmphi"
1047 [(set (reg:CC 17)
1048 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
1049 (match_operand:HI 1 "general_operand" "")))]
1050 ""
1051 {
1052 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1053 operands[0] = force_reg (HImode, operands[0]);
1054 ix86_compare_op0 = operands[0];
1055 ix86_compare_op1 = operands[1];
1056 DONE;
1057 })
1058
1059 (define_expand "cmpqi"
1060 [(set (reg:CC 17)
1061 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
1062 (match_operand:QI 1 "general_operand" "")))]
1063 "TARGET_QIMODE_MATH"
1064 {
1065 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1066 operands[0] = force_reg (QImode, operands[0]);
1067 ix86_compare_op0 = operands[0];
1068 ix86_compare_op1 = operands[1];
1069 DONE;
1070 })
1071
1072 (define_insn "cmpdi_ccno_1_rex64"
1073 [(set (reg 17)
1074 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1075 (match_operand:DI 1 "const0_operand" "n,n")))]
1076 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1077 "@
1078 test{q}\t{%0, %0|%0, %0}
1079 cmp{q}\t{%1, %0|%0, %1}"
1080 [(set_attr "type" "test,icmp")
1081 (set_attr "length_immediate" "0,1")
1082 (set_attr "mode" "DI")])
1083
1084 (define_insn "*cmpdi_minus_1_rex64"
1085 [(set (reg 17)
1086 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1087 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1088 (const_int 0)))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1090 "cmp{q}\t{%1, %0|%0, %1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "mode" "DI")])
1093
1094 (define_expand "cmpdi_1_rex64"
1095 [(set (reg:CC 17)
1096 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1097 (match_operand:DI 1 "general_operand" "")))]
1098 "TARGET_64BIT"
1099 "")
1100
1101 (define_insn "cmpdi_1_insn_rex64"
1102 [(set (reg 17)
1103 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1104 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1105 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1106 "cmp{q}\t{%1, %0|%0, %1}"
1107 [(set_attr "type" "icmp")
1108 (set_attr "mode" "DI")])
1109
1110
1111 (define_insn "*cmpsi_ccno_1"
1112 [(set (reg 17)
1113 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1114 (match_operand:SI 1 "const0_operand" "n,n")))]
1115 "ix86_match_ccmode (insn, CCNOmode)"
1116 "@
1117 test{l}\t{%0, %0|%0, %0}
1118 cmp{l}\t{%1, %0|%0, %1}"
1119 [(set_attr "type" "test,icmp")
1120 (set_attr "length_immediate" "0,1")
1121 (set_attr "mode" "SI")])
1122
1123 (define_insn "*cmpsi_minus_1"
1124 [(set (reg 17)
1125 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1126 (match_operand:SI 1 "general_operand" "ri,mr"))
1127 (const_int 0)))]
1128 "ix86_match_ccmode (insn, CCGOCmode)"
1129 "cmp{l}\t{%1, %0|%0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "mode" "SI")])
1132
1133 (define_expand "cmpsi_1"
1134 [(set (reg:CC 17)
1135 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1136 (match_operand:SI 1 "general_operand" "ri,mr")))]
1137 ""
1138 "")
1139
1140 (define_insn "*cmpsi_1_insn"
1141 [(set (reg 17)
1142 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1143 (match_operand:SI 1 "general_operand" "ri,mr")))]
1144 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1145 && ix86_match_ccmode (insn, CCmode)"
1146 "cmp{l}\t{%1, %0|%0, %1}"
1147 [(set_attr "type" "icmp")
1148 (set_attr "mode" "SI")])
1149
1150 (define_insn "*cmphi_ccno_1"
1151 [(set (reg 17)
1152 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1153 (match_operand:HI 1 "const0_operand" "n,n")))]
1154 "ix86_match_ccmode (insn, CCNOmode)"
1155 "@
1156 test{w}\t{%0, %0|%0, %0}
1157 cmp{w}\t{%1, %0|%0, %1}"
1158 [(set_attr "type" "test,icmp")
1159 (set_attr "length_immediate" "0,1")
1160 (set_attr "mode" "HI")])
1161
1162 (define_insn "*cmphi_minus_1"
1163 [(set (reg 17)
1164 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1165 (match_operand:HI 1 "general_operand" "ri,mr"))
1166 (const_int 0)))]
1167 "ix86_match_ccmode (insn, CCGOCmode)"
1168 "cmp{w}\t{%1, %0|%0, %1}"
1169 [(set_attr "type" "icmp")
1170 (set_attr "mode" "HI")])
1171
1172 (define_insn "*cmphi_1"
1173 [(set (reg 17)
1174 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1175 (match_operand:HI 1 "general_operand" "ri,mr")))]
1176 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1177 && ix86_match_ccmode (insn, CCmode)"
1178 "cmp{w}\t{%1, %0|%0, %1}"
1179 [(set_attr "type" "icmp")
1180 (set_attr "mode" "HI")])
1181
1182 (define_insn "*cmpqi_ccno_1"
1183 [(set (reg 17)
1184 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1185 (match_operand:QI 1 "const0_operand" "n,n")))]
1186 "ix86_match_ccmode (insn, CCNOmode)"
1187 "@
1188 test{b}\t{%0, %0|%0, %0}
1189 cmp{b}\t{$0, %0|%0, 0}"
1190 [(set_attr "type" "test,icmp")
1191 (set_attr "length_immediate" "0,1")
1192 (set_attr "mode" "QI")])
1193
1194 (define_insn "*cmpqi_1"
1195 [(set (reg 17)
1196 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1197 (match_operand:QI 1 "general_operand" "qi,mq")))]
1198 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1199 && ix86_match_ccmode (insn, CCmode)"
1200 "cmp{b}\t{%1, %0|%0, %1}"
1201 [(set_attr "type" "icmp")
1202 (set_attr "mode" "QI")])
1203
1204 (define_insn "*cmpqi_minus_1"
1205 [(set (reg 17)
1206 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1207 (match_operand:QI 1 "general_operand" "qi,mq"))
1208 (const_int 0)))]
1209 "ix86_match_ccmode (insn, CCGOCmode)"
1210 "cmp{b}\t{%1, %0|%0, %1}"
1211 [(set_attr "type" "icmp")
1212 (set_attr "mode" "QI")])
1213
1214 (define_insn "*cmpqi_ext_1"
1215 [(set (reg 17)
1216 (compare
1217 (match_operand:QI 0 "general_operand" "Qm")
1218 (subreg:QI
1219 (zero_extract:SI
1220 (match_operand 1 "ext_register_operand" "Q")
1221 (const_int 8)
1222 (const_int 8)) 0)))]
1223 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1224 "cmp{b}\t{%h1, %0|%0, %h1}"
1225 [(set_attr "type" "icmp")
1226 (set_attr "mode" "QI")])
1227
1228 (define_insn "*cmpqi_ext_1_rex64"
1229 [(set (reg 17)
1230 (compare
1231 (match_operand:QI 0 "register_operand" "Q")
1232 (subreg:QI
1233 (zero_extract:SI
1234 (match_operand 1 "ext_register_operand" "Q")
1235 (const_int 8)
1236 (const_int 8)) 0)))]
1237 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1238 "cmp{b}\t{%h1, %0|%0, %h1}"
1239 [(set_attr "type" "icmp")
1240 (set_attr "mode" "QI")])
1241
1242 (define_insn "*cmpqi_ext_2"
1243 [(set (reg 17)
1244 (compare
1245 (subreg:QI
1246 (zero_extract:SI
1247 (match_operand 0 "ext_register_operand" "Q")
1248 (const_int 8)
1249 (const_int 8)) 0)
1250 (match_operand:QI 1 "const0_operand" "n")))]
1251 "ix86_match_ccmode (insn, CCNOmode)"
1252 "test{b}\t%h0, %h0"
1253 [(set_attr "type" "test")
1254 (set_attr "length_immediate" "0")
1255 (set_attr "mode" "QI")])
1256
1257 (define_expand "cmpqi_ext_3"
1258 [(set (reg:CC 17)
1259 (compare:CC
1260 (subreg:QI
1261 (zero_extract:SI
1262 (match_operand 0 "ext_register_operand" "")
1263 (const_int 8)
1264 (const_int 8)) 0)
1265 (match_operand:QI 1 "general_operand" "")))]
1266 ""
1267 "")
1268
1269 (define_insn "cmpqi_ext_3_insn"
1270 [(set (reg 17)
1271 (compare
1272 (subreg:QI
1273 (zero_extract:SI
1274 (match_operand 0 "ext_register_operand" "Q")
1275 (const_int 8)
1276 (const_int 8)) 0)
1277 (match_operand:QI 1 "general_operand" "Qmn")))]
1278 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1279 "cmp{b}\t{%1, %h0|%h0, %1}"
1280 [(set_attr "type" "icmp")
1281 (set_attr "mode" "QI")])
1282
1283 (define_insn "cmpqi_ext_3_insn_rex64"
1284 [(set (reg 17)
1285 (compare
1286 (subreg:QI
1287 (zero_extract:SI
1288 (match_operand 0 "ext_register_operand" "Q")
1289 (const_int 8)
1290 (const_int 8)) 0)
1291 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1292 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1293 "cmp{b}\t{%1, %h0|%h0, %1}"
1294 [(set_attr "type" "icmp")
1295 (set_attr "mode" "QI")])
1296
1297 (define_insn "*cmpqi_ext_4"
1298 [(set (reg 17)
1299 (compare
1300 (subreg:QI
1301 (zero_extract:SI
1302 (match_operand 0 "ext_register_operand" "Q")
1303 (const_int 8)
1304 (const_int 8)) 0)
1305 (subreg:QI
1306 (zero_extract:SI
1307 (match_operand 1 "ext_register_operand" "Q")
1308 (const_int 8)
1309 (const_int 8)) 0)))]
1310 "ix86_match_ccmode (insn, CCmode)"
1311 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1312 [(set_attr "type" "icmp")
1313 (set_attr "mode" "QI")])
1314
1315 ;; These implement float point compares.
1316 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1317 ;; which would allow mix and match FP modes on the compares. Which is what
1318 ;; the old patterns did, but with many more of them.
1319
1320 (define_expand "cmpxf"
1321 [(set (reg:CC 17)
1322 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1323 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1324 "!TARGET_64BIT && TARGET_80387"
1325 {
1326 ix86_compare_op0 = operands[0];
1327 ix86_compare_op1 = operands[1];
1328 DONE;
1329 })
1330
1331 (define_expand "cmptf"
1332 [(set (reg:CC 17)
1333 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1334 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1335 "TARGET_80387"
1336 {
1337 ix86_compare_op0 = operands[0];
1338 ix86_compare_op1 = operands[1];
1339 DONE;
1340 })
1341
1342 (define_expand "cmpdf"
1343 [(set (reg:CC 17)
1344 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1345 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1346 "TARGET_80387 || TARGET_SSE2"
1347 {
1348 ix86_compare_op0 = operands[0];
1349 ix86_compare_op1 = operands[1];
1350 DONE;
1351 })
1352
1353 (define_expand "cmpsf"
1354 [(set (reg:CC 17)
1355 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1356 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1357 "TARGET_80387 || TARGET_SSE"
1358 {
1359 ix86_compare_op0 = operands[0];
1360 ix86_compare_op1 = operands[1];
1361 DONE;
1362 })
1363
1364 ;; FP compares, step 1:
1365 ;; Set the FP condition codes.
1366 ;;
1367 ;; CCFPmode compare with exceptions
1368 ;; CCFPUmode compare with no exceptions
1369
1370 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1371 ;; and that fp moves clobber the condition codes, and that there is
1372 ;; currently no way to describe this fact to reg-stack. So there are
1373 ;; no splitters yet for this.
1374
1375 ;; %%% YIKES! This scheme does not retain a strong connection between
1376 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1377 ;; work! Only allow tos/mem with tos in op 0.
1378 ;;
1379 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1380 ;; things aren't as bad as they sound...
1381
1382 (define_insn "*cmpfp_0"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1384 (unspec:HI
1385 [(compare:CCFP (match_operand 1 "register_operand" "f")
1386 (match_operand 2 "const0_operand" "X"))] 9))]
1387 "TARGET_80387
1388 && FLOAT_MODE_P (GET_MODE (operands[1]))
1389 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1390 {
1391 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1392 return "ftst\;fnstsw\t%0\;fstp\t%y0";
1393 else
1394 return "ftst\;fnstsw\t%0";
1395 }
1396 [(set_attr "type" "multi")
1397 (set_attr "mode" "unknownfp")])
1398
1399 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1400 ;; used to manage the reg stack popping would not be preserved.
1401
1402 (define_insn "*cmpfp_2_sf"
1403 [(set (reg:CCFP 18)
1404 (compare:CCFP
1405 (match_operand:SF 0 "register_operand" "f")
1406 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1407 "TARGET_80387"
1408 "* return output_fp_compare (insn, operands, 0, 0);"
1409 [(set_attr "type" "fcmp")
1410 (set_attr "mode" "SF")])
1411
1412 (define_insn "*cmpfp_2_sf_1"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1414 (unspec:HI
1415 [(compare:CCFP
1416 (match_operand:SF 1 "register_operand" "f")
1417 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1418 "TARGET_80387"
1419 "* return output_fp_compare (insn, operands, 2, 0);"
1420 [(set_attr "type" "fcmp")
1421 (set_attr "mode" "SF")])
1422
1423 (define_insn "*cmpfp_2_df"
1424 [(set (reg:CCFP 18)
1425 (compare:CCFP
1426 (match_operand:DF 0 "register_operand" "f")
1427 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1428 "TARGET_80387"
1429 "* return output_fp_compare (insn, operands, 0, 0);"
1430 [(set_attr "type" "fcmp")
1431 (set_attr "mode" "DF")])
1432
1433 (define_insn "*cmpfp_2_df_1"
1434 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (unspec:HI
1436 [(compare:CCFP
1437 (match_operand:DF 1 "register_operand" "f")
1438 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1439 "TARGET_80387"
1440 "* return output_fp_compare (insn, operands, 2, 0);"
1441 [(set_attr "type" "multi")
1442 (set_attr "mode" "DF")])
1443
1444 (define_insn "*cmpfp_2_xf"
1445 [(set (reg:CCFP 18)
1446 (compare:CCFP
1447 (match_operand:XF 0 "register_operand" "f")
1448 (match_operand:XF 1 "register_operand" "f")))]
1449 "!TARGET_64BIT && TARGET_80387"
1450 "* return output_fp_compare (insn, operands, 0, 0);"
1451 [(set_attr "type" "fcmp")
1452 (set_attr "mode" "XF")])
1453
1454 (define_insn "*cmpfp_2_tf"
1455 [(set (reg:CCFP 18)
1456 (compare:CCFP
1457 (match_operand:TF 0 "register_operand" "f")
1458 (match_operand:TF 1 "register_operand" "f")))]
1459 "TARGET_80387"
1460 "* return output_fp_compare (insn, operands, 0, 0);"
1461 [(set_attr "type" "fcmp")
1462 (set_attr "mode" "XF")])
1463
1464 (define_insn "*cmpfp_2_xf_1"
1465 [(set (match_operand:HI 0 "register_operand" "=a")
1466 (unspec:HI
1467 [(compare:CCFP
1468 (match_operand:XF 1 "register_operand" "f")
1469 (match_operand:XF 2 "register_operand" "f"))] 9))]
1470 "!TARGET_64BIT && TARGET_80387"
1471 "* return output_fp_compare (insn, operands, 2, 0);"
1472 [(set_attr "type" "multi")
1473 (set_attr "mode" "XF")])
1474
1475 (define_insn "*cmpfp_2_tf_1"
1476 [(set (match_operand:HI 0 "register_operand" "=a")
1477 (unspec:HI
1478 [(compare:CCFP
1479 (match_operand:TF 1 "register_operand" "f")
1480 (match_operand:TF 2 "register_operand" "f"))] 9))]
1481 "TARGET_80387"
1482 "* return output_fp_compare (insn, operands, 2, 0);"
1483 [(set_attr "type" "multi")
1484 (set_attr "mode" "XF")])
1485
1486 (define_insn "*cmpfp_2u"
1487 [(set (reg:CCFPU 18)
1488 (compare:CCFPU
1489 (match_operand 0 "register_operand" "f")
1490 (match_operand 1 "register_operand" "f")))]
1491 "TARGET_80387
1492 && FLOAT_MODE_P (GET_MODE (operands[0]))
1493 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1494 "* return output_fp_compare (insn, operands, 0, 1);"
1495 [(set_attr "type" "fcmp")
1496 (set_attr "mode" "unknownfp")])
1497
1498 (define_insn "*cmpfp_2u_1"
1499 [(set (match_operand:HI 0 "register_operand" "=a")
1500 (unspec:HI
1501 [(compare:CCFPU
1502 (match_operand 1 "register_operand" "f")
1503 (match_operand 2 "register_operand" "f"))] 9))]
1504 "TARGET_80387
1505 && FLOAT_MODE_P (GET_MODE (operands[1]))
1506 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1507 "* return output_fp_compare (insn, operands, 2, 1);"
1508 [(set_attr "type" "multi")
1509 (set_attr "mode" "unknownfp")])
1510
1511 ;; Patterns to match the SImode-in-memory ficom instructions.
1512 ;;
1513 ;; %%% Play games with accepting gp registers, as otherwise we have to
1514 ;; force them to memory during rtl generation, which is no good. We
1515 ;; can get rid of this once we teach reload to do memory input reloads
1516 ;; via pushes.
1517
1518 (define_insn "*ficom_1"
1519 [(set (reg:CCFP 18)
1520 (compare:CCFP
1521 (match_operand 0 "register_operand" "f,f")
1522 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1523 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1525 "#")
1526
1527 ;; Split the not-really-implemented gp register case into a
1528 ;; push-op-pop sequence.
1529 ;;
1530 ;; %%% This is most efficient, but am I gonna get in trouble
1531 ;; for separating cc0_setter and cc0_user?
1532
1533 (define_split
1534 [(set (reg:CCFP 18)
1535 (compare:CCFP
1536 (match_operand:SF 0 "register_operand" "")
1537 (float (match_operand:SI 1 "register_operand" ""))))]
1538 "0 && TARGET_80387 && reload_completed"
1539 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1540 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1541 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1542 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1543 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1544 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1545
1546 ;; FP compares, step 2
1547 ;; Move the fpsw to ax.
1548
1549 (define_insn "x86_fnstsw_1"
1550 [(set (match_operand:HI 0 "register_operand" "=a")
1551 (unspec:HI [(reg 18)] 9))]
1552 "TARGET_80387"
1553 "fnstsw\t%0"
1554 [(set_attr "length" "2")
1555 (set_attr "mode" "SI")
1556 (set_attr "i387" "1")
1557 (set_attr "ppro_uops" "few")])
1558
1559 ;; FP compares, step 3
1560 ;; Get ax into flags, general case.
1561
1562 (define_insn "x86_sahf_1"
1563 [(set (reg:CC 17)
1564 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1565 "!TARGET_64BIT"
1566 "sahf"
1567 [(set_attr "length" "1")
1568 (set_attr "athlon_decode" "vector")
1569 (set_attr "mode" "SI")
1570 (set_attr "ppro_uops" "one")])
1571
1572 ;; Pentium Pro can do steps 1 through 3 in one go.
1573
1574 (define_insn "*cmpfp_i"
1575 [(set (reg:CCFP 17)
1576 (compare:CCFP (match_operand 0 "register_operand" "f")
1577 (match_operand 1 "register_operand" "f")))]
1578 "TARGET_80387 && TARGET_CMOVE
1579 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1580 && FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1582 "* return output_fp_compare (insn, operands, 1, 0);"
1583 [(set_attr "type" "fcmp")
1584 (set_attr "mode" "unknownfp")
1585 (set_attr "athlon_decode" "vector")])
1586
1587 (define_insn "*cmpfp_i_sse"
1588 [(set (reg:CCFP 17)
1589 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1590 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1591 "TARGET_80387
1592 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1593 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1594 "* return output_fp_compare (insn, operands, 1, 0);"
1595 [(set_attr "type" "fcmp,sse")
1596 (set_attr "mode" "unknownfp")
1597 (set_attr "athlon_decode" "vector")])
1598
1599 (define_insn "*cmpfp_i_sse_only"
1600 [(set (reg:CCFP 17)
1601 (compare:CCFP (match_operand 0 "register_operand" "x")
1602 (match_operand 1 "nonimmediate_operand" "xm")))]
1603 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1604 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1605 "* return output_fp_compare (insn, operands, 1, 0);"
1606 [(set_attr "type" "sse")
1607 (set_attr "mode" "unknownfp")
1608 (set_attr "athlon_decode" "vector")])
1609
1610 (define_insn "*cmpfp_iu"
1611 [(set (reg:CCFPU 17)
1612 (compare:CCFPU (match_operand 0 "register_operand" "f")
1613 (match_operand 1 "register_operand" "f")))]
1614 "TARGET_80387 && TARGET_CMOVE
1615 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1616 && FLOAT_MODE_P (GET_MODE (operands[0]))
1617 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1618 "* return output_fp_compare (insn, operands, 1, 1);"
1619 [(set_attr "type" "fcmp")
1620 (set_attr "mode" "unknownfp")
1621 (set_attr "athlon_decode" "vector")])
1622
1623 (define_insn "*cmpfp_iu_sse"
1624 [(set (reg:CCFPU 17)
1625 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1626 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1627 "TARGET_80387
1628 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1629 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1630 "* return output_fp_compare (insn, operands, 1, 1);"
1631 [(set_attr "type" "fcmp,sse")
1632 (set_attr "mode" "unknownfp")
1633 (set_attr "athlon_decode" "vector")])
1634
1635 (define_insn "*cmpfp_iu_sse_only"
1636 [(set (reg:CCFPU 17)
1637 (compare:CCFPU (match_operand 0 "register_operand" "x")
1638 (match_operand 1 "nonimmediate_operand" "xm")))]
1639 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1640 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1641 "* return output_fp_compare (insn, operands, 1, 1);"
1642 [(set_attr "type" "sse")
1643 (set_attr "mode" "unknownfp")
1644 (set_attr "athlon_decode" "vector")])
1645 \f
1646 ;; Move instructions.
1647
1648 ;; General case of fullword move.
1649
1650 (define_expand "movsi"
1651 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1652 (match_operand:SI 1 "general_operand" ""))]
1653 ""
1654 "ix86_expand_move (SImode, operands); DONE;")
1655
1656 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1657 ;; general_operand.
1658 ;;
1659 ;; %%% We don't use a post-inc memory reference because x86 is not a
1660 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1661 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1662 ;; targets without our curiosities, and it is just as easy to represent
1663 ;; this differently.
1664
1665 (define_insn "*pushsi2"
1666 [(set (match_operand:SI 0 "push_operand" "=<")
1667 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1668 "!TARGET_64BIT"
1669 "push{l}\t%1"
1670 [(set_attr "type" "push")
1671 (set_attr "mode" "SI")])
1672
1673 ;; For 64BIT abi we always round up to 8 bytes.
1674 (define_insn "*pushsi2_rex64"
1675 [(set (match_operand:SI 0 "push_operand" "=X")
1676 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1677 "TARGET_64BIT"
1678 "push{q}\t%q1"
1679 [(set_attr "type" "push")
1680 (set_attr "mode" "SI")])
1681
1682 (define_insn "*pushsi2_prologue"
1683 [(set (match_operand:SI 0 "push_operand" "=<")
1684 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1685 (clobber (mem:BLK (scratch)))]
1686 "!TARGET_64BIT"
1687 "push{l}\t%1"
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "SI")])
1690
1691 (define_insn "*popsi1_epilogue"
1692 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1693 (mem:SI (reg:SI 7)))
1694 (set (reg:SI 7)
1695 (plus:SI (reg:SI 7) (const_int 4)))
1696 (clobber (mem:BLK (scratch)))]
1697 "!TARGET_64BIT"
1698 "pop{l}\t%0"
1699 [(set_attr "type" "pop")
1700 (set_attr "mode" "SI")])
1701
1702 (define_insn "popsi1"
1703 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1704 (mem:SI (reg:SI 7)))
1705 (set (reg:SI 7)
1706 (plus:SI (reg:SI 7) (const_int 4)))]
1707 "!TARGET_64BIT"
1708 "pop{l}\t%0"
1709 [(set_attr "type" "pop")
1710 (set_attr "mode" "SI")])
1711
1712 (define_insn "*movsi_xor"
1713 [(set (match_operand:SI 0 "register_operand" "=r")
1714 (match_operand:SI 1 "const0_operand" "i"))
1715 (clobber (reg:CC 17))]
1716 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1717 "xor{l}\t{%0, %0|%0, %0}"
1718 [(set_attr "type" "alu1")
1719 (set_attr "mode" "SI")
1720 (set_attr "length_immediate" "0")])
1721
1722 (define_insn "*movsi_or"
1723 [(set (match_operand:SI 0 "register_operand" "=r")
1724 (match_operand:SI 1 "immediate_operand" "i"))
1725 (clobber (reg:CC 17))]
1726 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1727 && INTVAL (operands[1]) == -1
1728 && (TARGET_PENTIUM || optimize_size)"
1729 {
1730 operands[1] = constm1_rtx;
1731 return "or{l}\t{%1, %0|%0, %1}";
1732 }
1733 [(set_attr "type" "alu1")
1734 (set_attr "mode" "SI")
1735 (set_attr "length_immediate" "1")])
1736
1737 (define_insn "*movsi_1"
1738 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
1739 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
1740 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1741 {
1742 switch (get_attr_type (insn))
1743 {
1744 case TYPE_SSE:
1745 if (get_attr_mode (insn) == TImode)
1746 return "movdqa\t{%1, %0|%0, %1}";
1747 return "movd\t{%1, %0|%0, %1}";
1748
1749 case TYPE_MMX:
1750 return "movd\t{%1, %0|%0, %1}";
1751
1752 case TYPE_LEA:
1753 return "lea{l}\t{%1, %0|%0, %1}";
1754
1755 default:
1756 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1757 abort();
1758 return "mov{l}\t{%1, %0|%0, %1}";
1759 }
1760 }
1761 [(set (attr "type")
1762 (cond [(eq_attr "alternative" "4,5")
1763 (const_string "mmx")
1764 (eq_attr "alternative" "6,7,8")
1765 (const_string "sse")
1766 (and (ne (symbol_ref "flag_pic") (const_int 0))
1767 (match_operand:SI 1 "symbolic_operand" ""))
1768 (const_string "lea")
1769 ]
1770 (const_string "imov")))
1771 (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
1772 (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
1773
1774 ;; Stores and loads of ax to arbitary constant address.
1775 ;; We fake an second form of instruction to force reload to load address
1776 ;; into register when rax is not available
1777 (define_insn "*movabssi_1_rex64"
1778 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1779 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1780 "TARGET_64BIT"
1781 "@
1782 movabs{l}\t{%1, %P0|%P0, %1}
1783 mov{l}\t{%1, %a0|%a0, %1}
1784 movabs{l}\t{%1, %a0|%a0, %1}"
1785 [(set_attr "type" "imov")
1786 (set_attr "modrm" "0,*,*")
1787 (set_attr "length_address" "8,0,0")
1788 (set_attr "length_immediate" "0,*,*")
1789 (set_attr "memory" "store")
1790 (set_attr "mode" "SI")])
1791
1792 (define_insn "*movabssi_2_rex64"
1793 [(set (match_operand:SI 0 "register_operand" "=a,r")
1794 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1795 "TARGET_64BIT"
1796 "@
1797 movabs{l}\t{%P1, %0|%0, %P1}
1798 mov{l}\t{%a1, %0|%0, %a1}"
1799 [(set_attr "type" "imov")
1800 (set_attr "modrm" "0,*")
1801 (set_attr "length_address" "8,0")
1802 (set_attr "length_immediate" "0")
1803 (set_attr "memory" "load")
1804 (set_attr "mode" "SI")])
1805
1806 (define_insn "*swapsi"
1807 [(set (match_operand:SI 0 "register_operand" "+r")
1808 (match_operand:SI 1 "register_operand" "+r"))
1809 (set (match_dup 1)
1810 (match_dup 0))]
1811 ""
1812 "xchg{l}\t%1, %0"
1813 [(set_attr "type" "imov")
1814 (set_attr "pent_pair" "np")
1815 (set_attr "athlon_decode" "vector")
1816 (set_attr "mode" "SI")
1817 (set_attr "modrm" "0")
1818 (set_attr "ppro_uops" "few")])
1819
1820 (define_expand "movhi"
1821 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1822 (match_operand:HI 1 "general_operand" ""))]
1823 ""
1824 "ix86_expand_move (HImode, operands); DONE;")
1825
1826 (define_insn "*pushhi2"
1827 [(set (match_operand:HI 0 "push_operand" "=<,<")
1828 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1829 "!TARGET_64BIT"
1830 "@
1831 push{w}\t{|WORD PTR }%1
1832 push{w}\t%1"
1833 [(set_attr "type" "push")
1834 (set_attr "mode" "HI")])
1835
1836 ;; For 64BIT abi we always round up to 8 bytes.
1837 (define_insn "*pushhi2_rex64"
1838 [(set (match_operand:HI 0 "push_operand" "=X")
1839 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1840 "TARGET_64BIT"
1841 "push{q}\t%q1"
1842 [(set_attr "type" "push")
1843 (set_attr "mode" "QI")])
1844
1845 (define_insn "*movhi_1"
1846 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1847 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1848 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1849 {
1850 switch (get_attr_type (insn))
1851 {
1852 case TYPE_IMOVX:
1853 /* movzwl is faster than movw on p2 due to partial word stalls,
1854 though not as fast as an aligned movl. */
1855 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1856 default:
1857 if (get_attr_mode (insn) == MODE_SI)
1858 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1859 else
1860 return "mov{w}\t{%1, %0|%0, %1}";
1861 }
1862 }
1863 [(set (attr "type")
1864 (cond [(and (eq_attr "alternative" "0,1")
1865 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1866 (const_int 0))
1867 (eq (symbol_ref "TARGET_HIMODE_MATH")
1868 (const_int 0))))
1869 (const_string "imov")
1870 (and (eq_attr "alternative" "2,3,4")
1871 (match_operand:HI 1 "aligned_operand" ""))
1872 (const_string "imov")
1873 (and (ne (symbol_ref "TARGET_MOVX")
1874 (const_int 0))
1875 (eq_attr "alternative" "0,1,3,4"))
1876 (const_string "imovx")
1877 ]
1878 (const_string "imov")))
1879 (set (attr "mode")
1880 (cond [(eq_attr "type" "imovx")
1881 (const_string "SI")
1882 (and (eq_attr "alternative" "2,3,4")
1883 (match_operand:HI 1 "aligned_operand" ""))
1884 (const_string "SI")
1885 (and (eq_attr "alternative" "0,1")
1886 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1887 (const_int 0))
1888 (eq (symbol_ref "TARGET_HIMODE_MATH")
1889 (const_int 0))))
1890 (const_string "SI")
1891 ]
1892 (const_string "HI")))
1893 (set_attr "modrm" "0,*,*,0,*,*")])
1894
1895 ;; Stores and loads of ax to arbitary constant address.
1896 ;; We fake an second form of instruction to force reload to load address
1897 ;; into register when rax is not available
1898 (define_insn "*movabshi_1_rex64"
1899 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1900 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1901 "TARGET_64BIT"
1902 "@
1903 movabs{w}\t{%1, %P0|%P0, %1}
1904 mov{w}\t{%1, %a0|%a0, %1}
1905 movabs{w}\t{%1, %a0|%a0, %1}"
1906 [(set_attr "type" "imov")
1907 (set_attr "modrm" "0,*,*")
1908 (set_attr "length_address" "8,0,0")
1909 (set_attr "length_immediate" "0,*,*")
1910 (set_attr "memory" "store")
1911 (set_attr "mode" "HI")])
1912
1913 (define_insn "*movabshi_2_rex64"
1914 [(set (match_operand:HI 0 "register_operand" "=a,r")
1915 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916 "TARGET_64BIT"
1917 "@
1918 movabs{w}\t{%P1, %0|%0, %P1}
1919 mov{w}\t{%a1, %0|%0, %a1}"
1920 [(set_attr "type" "imov")
1921 (set_attr "modrm" "0,*")
1922 (set_attr "length_address" "8,0")
1923 (set_attr "length_immediate" "0")
1924 (set_attr "memory" "load")
1925 (set_attr "mode" "HI")])
1926
1927 (define_insn "*swaphi_1"
1928 [(set (match_operand:HI 0 "register_operand" "+r")
1929 (match_operand:HI 1 "register_operand" "+r"))
1930 (set (match_dup 1)
1931 (match_dup 0))]
1932 "TARGET_PARTIAL_REG_STALL"
1933 "xchg{w}\t%1, %0"
1934 [(set_attr "type" "imov")
1935 (set_attr "pent_pair" "np")
1936 (set_attr "mode" "HI")
1937 (set_attr "modrm" "0")
1938 (set_attr "ppro_uops" "few")])
1939
1940 (define_insn "*swaphi_2"
1941 [(set (match_operand:HI 0 "register_operand" "+r")
1942 (match_operand:HI 1 "register_operand" "+r"))
1943 (set (match_dup 1)
1944 (match_dup 0))]
1945 "! TARGET_PARTIAL_REG_STALL"
1946 "xchg{l}\t%k1, %k0"
1947 [(set_attr "type" "imov")
1948 (set_attr "pent_pair" "np")
1949 (set_attr "mode" "SI")
1950 (set_attr "modrm" "0")
1951 (set_attr "ppro_uops" "few")])
1952
1953 (define_expand "movstricthi"
1954 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1955 (match_operand:HI 1 "general_operand" ""))]
1956 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1957 {
1958 /* Don't generate memory->memory moves, go through a register */
1959 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1960 operands[1] = force_reg (HImode, operands[1]);
1961 })
1962
1963 (define_insn "*movstricthi_1"
1964 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1965 (match_operand:HI 1 "general_operand" "rn,m"))]
1966 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1967 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1968 "mov{w}\t{%1, %0|%0, %1}"
1969 [(set_attr "type" "imov")
1970 (set_attr "mode" "HI")])
1971
1972 (define_insn "*movstricthi_xor"
1973 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1974 (match_operand:HI 1 "const0_operand" "i"))
1975 (clobber (reg:CC 17))]
1976 "reload_completed
1977 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1978 "xor{w}\t{%0, %0|%0, %0}"
1979 [(set_attr "type" "alu1")
1980 (set_attr "mode" "HI")
1981 (set_attr "length_immediate" "0")])
1982
1983 (define_expand "movqi"
1984 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1985 (match_operand:QI 1 "general_operand" ""))]
1986 ""
1987 "ix86_expand_move (QImode, operands); DONE;")
1988
1989 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1990 ;; "push a byte". But actually we use pushw, which has the effect
1991 ;; of rounding the amount pushed up to a halfword.
1992
1993 (define_insn "*pushqi2"
1994 [(set (match_operand:QI 0 "push_operand" "=X,X")
1995 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1996 "!TARGET_64BIT"
1997 "@
1998 push{w}\t{|word ptr }%1
1999 push{w}\t%w1"
2000 [(set_attr "type" "push")
2001 (set_attr "mode" "HI")])
2002
2003 ;; For 64BIT abi we always round up to 8 bytes.
2004 (define_insn "*pushqi2_rex64"
2005 [(set (match_operand:QI 0 "push_operand" "=X")
2006 (match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
2007 "TARGET_64BIT"
2008 "push{q}\t%q1"
2009 [(set_attr "type" "push")
2010 (set_attr "mode" "QI")])
2011
2012 ;; Situation is quite tricky about when to choose full sized (SImode) move
2013 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2014 ;; partial register dependency machines (such as AMD Athlon), where QImode
2015 ;; moves issue extra dependency and for partial register stalls machines
2016 ;; that don't use QImode patterns (and QImode move cause stall on the next
2017 ;; instruction).
2018 ;;
2019 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2020 ;; register stall machines with, where we use QImode instructions, since
2021 ;; partial register stall can be caused there. Then we use movzx.
2022 (define_insn "*movqi_1"
2023 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2024 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2025 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2026 {
2027 switch (get_attr_type (insn))
2028 {
2029 case TYPE_IMOVX:
2030 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2031 abort ();
2032 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2033 default:
2034 if (get_attr_mode (insn) == MODE_SI)
2035 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2036 else
2037 return "mov{b}\t{%1, %0|%0, %1}";
2038 }
2039 }
2040 [(set (attr "type")
2041 (cond [(and (eq_attr "alternative" "3")
2042 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2043 (const_int 0))
2044 (eq (symbol_ref "TARGET_QIMODE_MATH")
2045 (const_int 0))))
2046 (const_string "imov")
2047 (eq_attr "alternative" "3,5")
2048 (const_string "imovx")
2049 (and (ne (symbol_ref "TARGET_MOVX")
2050 (const_int 0))
2051 (eq_attr "alternative" "2"))
2052 (const_string "imovx")
2053 ]
2054 (const_string "imov")))
2055 (set (attr "mode")
2056 (cond [(eq_attr "alternative" "3,4,5")
2057 (const_string "SI")
2058 (eq_attr "alternative" "6")
2059 (const_string "QI")
2060 (eq_attr "type" "imovx")
2061 (const_string "SI")
2062 (and (eq_attr "type" "imov")
2063 (and (eq_attr "alternative" "0,1,2")
2064 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2065 (const_int 0))))
2066 (const_string "SI")
2067 ;; Avoid partial register stalls when not using QImode arithmetic
2068 (and (eq_attr "type" "imov")
2069 (and (eq_attr "alternative" "0,1,2")
2070 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2071 (const_int 0))
2072 (eq (symbol_ref "TARGET_QIMODE_MATH")
2073 (const_int 0)))))
2074 (const_string "SI")
2075 ]
2076 (const_string "QI")))])
2077
2078 (define_expand "reload_outqi"
2079 [(parallel [(match_operand:QI 0 "" "=m")
2080 (match_operand:QI 1 "register_operand" "r")
2081 (match_operand:QI 2 "register_operand" "=&q")])]
2082 ""
2083 {
2084 rtx op0, op1, op2;
2085 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2086
2087 if (reg_overlap_mentioned_p (op2, op0))
2088 abort ();
2089 if (! q_regs_operand (op1, QImode))
2090 {
2091 emit_insn (gen_movqi (op2, op1));
2092 op1 = op2;
2093 }
2094 emit_insn (gen_movqi (op0, op1));
2095 DONE;
2096 })
2097
2098 (define_insn "*swapqi"
2099 [(set (match_operand:QI 0 "register_operand" "+r")
2100 (match_operand:QI 1 "register_operand" "+r"))
2101 (set (match_dup 1)
2102 (match_dup 0))]
2103 ""
2104 "xchg{b}\t%1, %0"
2105 [(set_attr "type" "imov")
2106 (set_attr "pent_pair" "np")
2107 (set_attr "mode" "QI")
2108 (set_attr "modrm" "0")
2109 (set_attr "ppro_uops" "few")])
2110
2111 (define_expand "movstrictqi"
2112 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2113 (match_operand:QI 1 "general_operand" ""))]
2114 "! TARGET_PARTIAL_REG_STALL"
2115 {
2116 /* Don't generate memory->memory moves, go through a register. */
2117 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2118 operands[1] = force_reg (QImode, operands[1]);
2119 })
2120
2121 (define_insn "*movstrictqi_1"
2122 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2123 (match_operand:QI 1 "general_operand" "*qn,m"))]
2124 "! TARGET_PARTIAL_REG_STALL
2125 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2126 "mov{b}\t{%1, %0|%0, %1}"
2127 [(set_attr "type" "imov")
2128 (set_attr "mode" "QI")])
2129
2130 (define_insn "*movstrictqi_xor"
2131 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2132 (match_operand:QI 1 "const0_operand" "i"))
2133 (clobber (reg:CC 17))]
2134 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2135 "xor{b}\t{%0, %0|%0, %0}"
2136 [(set_attr "type" "alu1")
2137 (set_attr "mode" "QI")
2138 (set_attr "length_immediate" "0")])
2139
2140 (define_insn "*movsi_extv_1"
2141 [(set (match_operand:SI 0 "register_operand" "=R")
2142 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2143 (const_int 8)
2144 (const_int 8)))]
2145 ""
2146 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2147 [(set_attr "type" "imovx")
2148 (set_attr "mode" "SI")])
2149
2150 (define_insn "*movhi_extv_1"
2151 [(set (match_operand:HI 0 "register_operand" "=R")
2152 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2153 (const_int 8)
2154 (const_int 8)))]
2155 ""
2156 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2157 [(set_attr "type" "imovx")
2158 (set_attr "mode" "SI")])
2159
2160 (define_insn "*movqi_extv_1"
2161 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2162 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2163 (const_int 8)
2164 (const_int 8)))]
2165 "!TARGET_64BIT"
2166 {
2167 switch (get_attr_type (insn))
2168 {
2169 case TYPE_IMOVX:
2170 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2171 default:
2172 return "mov{b}\t{%h1, %0|%0, %h1}";
2173 }
2174 }
2175 [(set (attr "type")
2176 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2177 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2178 (ne (symbol_ref "TARGET_MOVX")
2179 (const_int 0))))
2180 (const_string "imovx")
2181 (const_string "imov")))
2182 (set (attr "mode")
2183 (if_then_else (eq_attr "type" "imovx")
2184 (const_string "SI")
2185 (const_string "QI")))])
2186
2187 (define_insn "*movqi_extv_1_rex64"
2188 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2189 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2190 (const_int 8)
2191 (const_int 8)))]
2192 "TARGET_64BIT"
2193 {
2194 switch (get_attr_type (insn))
2195 {
2196 case TYPE_IMOVX:
2197 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2198 default:
2199 return "mov{b}\t{%h1, %0|%0, %h1}";
2200 }
2201 }
2202 [(set (attr "type")
2203 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2204 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2205 (ne (symbol_ref "TARGET_MOVX")
2206 (const_int 0))))
2207 (const_string "imovx")
2208 (const_string "imov")))
2209 (set (attr "mode")
2210 (if_then_else (eq_attr "type" "imovx")
2211 (const_string "SI")
2212 (const_string "QI")))])
2213
2214 ;; Stores and loads of ax to arbitary constant address.
2215 ;; We fake an second form of instruction to force reload to load address
2216 ;; into register when rax is not available
2217 (define_insn "*movabsqi_1_rex64"
2218 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2219 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2220 "TARGET_64BIT"
2221 "@
2222 movabs{b}\t{%1, %P0|%P0, %1}
2223 mov{b}\t{%1, %a0|%a0, %1}
2224 movabs{b}\t{%1, %a0|%a0, %1}"
2225 [(set_attr "type" "imov")
2226 (set_attr "modrm" "0,*,*")
2227 (set_attr "length_address" "8,0,0")
2228 (set_attr "length_immediate" "0,*,*")
2229 (set_attr "memory" "store")
2230 (set_attr "mode" "QI")])
2231
2232 (define_insn "*movabsqi_2_rex64"
2233 [(set (match_operand:QI 0 "register_operand" "=a,r")
2234 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2235 "TARGET_64BIT"
2236 "@
2237 movabs{b}\t{%P1, %0|%0, %P1}
2238 mov{b}\t{%a1, %0|%0, %a1}"
2239 [(set_attr "type" "imov")
2240 (set_attr "modrm" "0,*")
2241 (set_attr "length_address" "8,0")
2242 (set_attr "length_immediate" "0")
2243 (set_attr "memory" "load")
2244 (set_attr "mode" "QI")])
2245
2246 (define_insn "*movsi_extzv_1"
2247 [(set (match_operand:SI 0 "register_operand" "=R")
2248 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2249 (const_int 8)
2250 (const_int 8)))]
2251 ""
2252 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2253 [(set_attr "type" "imovx")
2254 (set_attr "mode" "SI")])
2255
2256 (define_insn "*movqi_extzv_2"
2257 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2258 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2259 (const_int 8)
2260 (const_int 8)) 0))]
2261 "!TARGET_64BIT"
2262 {
2263 switch (get_attr_type (insn))
2264 {
2265 case TYPE_IMOVX:
2266 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2267 default:
2268 return "mov{b}\t{%h1, %0|%0, %h1}";
2269 }
2270 }
2271 [(set (attr "type")
2272 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2273 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2274 (ne (symbol_ref "TARGET_MOVX")
2275 (const_int 0))))
2276 (const_string "imovx")
2277 (const_string "imov")))
2278 (set (attr "mode")
2279 (if_then_else (eq_attr "type" "imovx")
2280 (const_string "SI")
2281 (const_string "QI")))])
2282
2283 (define_insn "*movqi_extzv_2_rex64"
2284 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2285 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2286 (const_int 8)
2287 (const_int 8)) 0))]
2288 "TARGET_64BIT"
2289 {
2290 switch (get_attr_type (insn))
2291 {
2292 case TYPE_IMOVX:
2293 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2294 default:
2295 return "mov{b}\t{%h1, %0|%0, %h1}";
2296 }
2297 }
2298 [(set (attr "type")
2299 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2300 (ne (symbol_ref "TARGET_MOVX")
2301 (const_int 0)))
2302 (const_string "imovx")
2303 (const_string "imov")))
2304 (set (attr "mode")
2305 (if_then_else (eq_attr "type" "imovx")
2306 (const_string "SI")
2307 (const_string "QI")))])
2308
2309 (define_insn "movsi_insv_1"
2310 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2311 (const_int 8)
2312 (const_int 8))
2313 (match_operand:SI 1 "general_operand" "Qmn"))]
2314 "!TARGET_64BIT"
2315 "mov{b}\t{%b1, %h0|%h0, %b1}"
2316 [(set_attr "type" "imov")
2317 (set_attr "mode" "QI")])
2318
2319 (define_insn "*movsi_insv_1_rex64"
2320 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2321 (const_int 8)
2322 (const_int 8))
2323 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2324 "TARGET_64BIT"
2325 "mov{b}\t{%b1, %h0|%h0, %b1}"
2326 [(set_attr "type" "imov")
2327 (set_attr "mode" "QI")])
2328
2329 (define_insn "*movqi_insv_2"
2330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2331 (const_int 8)
2332 (const_int 8))
2333 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2334 (const_int 8))
2335 (const_int 255)))]
2336 ""
2337 "mov{b}\t{%h1, %h0|%h0, %h1}"
2338 [(set_attr "type" "imov")
2339 (set_attr "mode" "QI")])
2340
2341 (define_expand "movdi"
2342 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2343 (match_operand:DI 1 "general_operand" ""))]
2344 ""
2345 "ix86_expand_move (DImode, operands); DONE;")
2346
2347 (define_insn "*pushdi"
2348 [(set (match_operand:DI 0 "push_operand" "=<")
2349 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2350 "!TARGET_64BIT"
2351 "#")
2352
2353 (define_insn "pushdi2_rex64"
2354 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2355 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2356 "TARGET_64BIT"
2357 "@
2358 push{q}\t%1
2359 #"
2360 [(set_attr "type" "push,multi")
2361 (set_attr "mode" "DI")])
2362
2363 ;; Convert impossible pushes of immediate to existing instructions.
2364 ;; First try to get scratch register and go through it. In case this
2365 ;; fails, push sign extended lower part first and then overwrite
2366 ;; upper part by 32bit move.
2367 (define_peephole2
2368 [(match_scratch:DI 2 "r")
2369 (set (match_operand:DI 0 "push_operand" "")
2370 (match_operand:DI 1 "immediate_operand" ""))]
2371 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2372 && !x86_64_immediate_operand (operands[1], DImode)"
2373 [(set (match_dup 2) (match_dup 1))
2374 (set (match_dup 0) (match_dup 2))]
2375 "")
2376
2377 ;; We need to define this as both peepholer and splitter for case
2378 ;; peephole2 pass is not run.
2379 (define_peephole2
2380 [(set (match_operand:DI 0 "push_operand" "")
2381 (match_operand:DI 1 "immediate_operand" ""))]
2382 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2383 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2384 [(set (match_dup 0) (match_dup 1))
2385 (set (match_dup 2) (match_dup 3))]
2386 "split_di (operands + 1, 1, operands + 2, operands + 3);
2387 operands[1] = gen_lowpart (DImode, operands[2]);
2388 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2389 GEN_INT (4)));
2390 ")
2391
2392 (define_split
2393 [(set (match_operand:DI 0 "push_operand" "")
2394 (match_operand:DI 1 "immediate_operand" ""))]
2395 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2396 && !symbolic_operand (operands[1], DImode)
2397 && !x86_64_immediate_operand (operands[1], DImode)"
2398 [(set (match_dup 0) (match_dup 1))
2399 (set (match_dup 2) (match_dup 3))]
2400 "split_di (operands + 1, 1, operands + 2, operands + 3);
2401 operands[1] = gen_lowpart (DImode, operands[2]);
2402 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2403 GEN_INT (4)));
2404 ")
2405
2406 (define_insn "*pushdi2_prologue_rex64"
2407 [(set (match_operand:DI 0 "push_operand" "=<")
2408 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2409 (clobber (mem:BLK (scratch)))]
2410 "TARGET_64BIT"
2411 "push{q}\t%1"
2412 [(set_attr "type" "push")
2413 (set_attr "mode" "DI")])
2414
2415 (define_insn "*popdi1_epilogue_rex64"
2416 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2417 (mem:DI (reg:DI 7)))
2418 (set (reg:DI 7)
2419 (plus:DI (reg:DI 7) (const_int 8)))
2420 (clobber (mem:BLK (scratch)))]
2421 "TARGET_64BIT"
2422 "pop{q}\t%0"
2423 [(set_attr "type" "pop")
2424 (set_attr "mode" "DI")])
2425
2426 (define_insn "popdi1"
2427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2428 (mem:DI (reg:DI 7)))
2429 (set (reg:DI 7)
2430 (plus:DI (reg:DI 7) (const_int 8)))]
2431 "TARGET_64BIT"
2432 "pop{q}\t%0"
2433 [(set_attr "type" "pop")
2434 (set_attr "mode" "DI")])
2435
2436 (define_insn "*movdi_xor_rex64"
2437 [(set (match_operand:DI 0 "register_operand" "=r")
2438 (match_operand:DI 1 "const0_operand" "i"))
2439 (clobber (reg:CC 17))]
2440 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2441 && reload_completed"
2442 "xor{l}\t{%k0, %k0|%k0, %k0}"
2443 [(set_attr "type" "alu1")
2444 (set_attr "mode" "SI")
2445 (set_attr "length_immediate" "0")])
2446
2447 (define_insn "*movdi_or_rex64"
2448 [(set (match_operand:DI 0 "register_operand" "=r")
2449 (match_operand:DI 1 "const_int_operand" "i"))
2450 (clobber (reg:CC 17))]
2451 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2452 && reload_completed
2453 && GET_CODE (operands[1]) == CONST_INT
2454 && INTVAL (operands[1]) == -1"
2455 {
2456 operands[1] = constm1_rtx;
2457 return "or{q}\t{%1, %0|%0, %1}";
2458 }
2459 [(set_attr "type" "alu1")
2460 (set_attr "mode" "DI")
2461 (set_attr "length_immediate" "1")])
2462
2463 (define_insn "*movdi_2"
2464 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
2465 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
2466 "!TARGET_64BIT
2467 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2468 "@
2469 #
2470 #
2471 movq\t{%1, %0|%0, %1}
2472 movq\t{%1, %0|%0, %1}
2473 movq\t{%1, %0|%0, %1}
2474 movdqa\t{%1, %0|%0, %1}
2475 movq\t{%1, %0|%0, %1}"
2476 [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2477 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
2478
2479 (define_split
2480 [(set (match_operand:DI 0 "push_operand" "")
2481 (match_operand:DI 1 "general_operand" ""))]
2482 "!TARGET_64BIT && reload_completed
2483 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2484 [(const_int 0)]
2485 "ix86_split_long_move (operands); DONE;")
2486
2487 ;; %%% This multiword shite has got to go.
2488 (define_split
2489 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2490 (match_operand:DI 1 "general_operand" ""))]
2491 "!TARGET_64BIT && reload_completed
2492 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2493 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2494 [(const_int 0)]
2495 "ix86_split_long_move (operands); DONE;")
2496
2497 (define_insn "*movdi_1_rex64"
2498 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2499 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
2500 "TARGET_64BIT
2501 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2502 {
2503 switch (get_attr_type (insn))
2504 {
2505 case TYPE_SSE:
2506 if (register_operand (operands[0], DImode)
2507 && register_operand (operands[1], DImode))
2508 return "movdqa\t{%1, %0|%0, %1}";
2509 /* FALLTHRU */
2510 case TYPE_MMX:
2511 return "movq\t{%1, %0|%0, %1}";
2512 case TYPE_MULTI:
2513 return "#";
2514 case TYPE_LEA:
2515 return "lea{q}\t{%a1, %0|%0, %a1}";
2516 default:
2517 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2518 abort ();
2519 if (get_attr_mode (insn) == MODE_SI)
2520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2521 else if (which_alternative == 2)
2522 return "movabs{q}\t{%1, %0|%0, %1}";
2523 else
2524 return "mov{q}\t{%1, %0|%0, %1}";
2525 }
2526 }
2527 [(set (attr "type")
2528 (cond [(eq_attr "alternative" "5,6")
2529 (const_string "mmx")
2530 (eq_attr "alternative" "7,8")
2531 (const_string "sse")
2532 (eq_attr "alternative" "4")
2533 (const_string "multi")
2534 (and (ne (symbol_ref "flag_pic") (const_int 0))
2535 (match_operand:DI 1 "symbolic_operand" ""))
2536 (const_string "lea")
2537 ]
2538 (const_string "imov")))
2539 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2540 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2541 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
2542
2543 ;; Stores and loads of ax to arbitary constant address.
2544 ;; We fake an second form of instruction to force reload to load address
2545 ;; into register when rax is not available
2546 (define_insn "*movabsdi_1_rex64"
2547 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2548 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2549 "TARGET_64BIT"
2550 "@
2551 movabs{q}\t{%1, %P0|%P0, %1}
2552 mov{q}\t{%1, %a0|%a0, %1}
2553 movabs{q}\t{%1, %a0|%a0, %1}"
2554 [(set_attr "type" "imov")
2555 (set_attr "modrm" "0,*,*")
2556 (set_attr "length_address" "8,0,0")
2557 (set_attr "length_immediate" "0,*,*")
2558 (set_attr "memory" "store")
2559 (set_attr "mode" "DI")])
2560
2561 (define_insn "*movabsdi_2_rex64"
2562 [(set (match_operand:DI 0 "register_operand" "=a,r")
2563 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2564 "TARGET_64BIT"
2565 "@
2566 movabs{q}\t{%P1, %0|%0, %P1}
2567 mov{q}\t{%a1, %0|%0, %a1}"
2568 [(set_attr "type" "imov")
2569 (set_attr "modrm" "0,*")
2570 (set_attr "length_address" "8,0")
2571 (set_attr "length_immediate" "0")
2572 (set_attr "memory" "load")
2573 (set_attr "mode" "DI")])
2574
2575 ;; Convert impossible stores of immediate to existing instructions.
2576 ;; First try to get scratch register and go through it. In case this
2577 ;; fails, move by 32bit parts.
2578 (define_peephole2
2579 [(match_scratch:DI 2 "r")
2580 (set (match_operand:DI 0 "memory_operand" "")
2581 (match_operand:DI 1 "immediate_operand" ""))]
2582 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583 && !x86_64_immediate_operand (operands[1], DImode)"
2584 [(set (match_dup 2) (match_dup 1))
2585 (set (match_dup 0) (match_dup 2))]
2586 "")
2587
2588 ;; We need to define this as both peepholer and splitter for case
2589 ;; peephole2 pass is not run.
2590 (define_peephole2
2591 [(set (match_operand:DI 0 "memory_operand" "")
2592 (match_operand:DI 1 "immediate_operand" ""))]
2593 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2594 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2595 [(set (match_dup 2) (match_dup 3))
2596 (set (match_dup 4) (match_dup 5))]
2597 "split_di (operands, 2, operands + 2, operands + 4);")
2598
2599 (define_split
2600 [(set (match_operand:DI 0 "memory_operand" "")
2601 (match_operand:DI 1 "immediate_operand" ""))]
2602 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2603 && !symbolic_operand (operands[1], DImode)
2604 && !x86_64_immediate_operand (operands[1], DImode)"
2605 [(set (match_dup 2) (match_dup 3))
2606 (set (match_dup 4) (match_dup 5))]
2607 "split_di (operands, 2, operands + 2, operands + 4);")
2608
2609 (define_insn "*swapdi_rex64"
2610 [(set (match_operand:DI 0 "register_operand" "+r")
2611 (match_operand:DI 1 "register_operand" "+r"))
2612 (set (match_dup 1)
2613 (match_dup 0))]
2614 "TARGET_64BIT"
2615 "xchg{q}\t%1, %0"
2616 [(set_attr "type" "imov")
2617 (set_attr "pent_pair" "np")
2618 (set_attr "athlon_decode" "vector")
2619 (set_attr "mode" "DI")
2620 (set_attr "modrm" "0")
2621 (set_attr "ppro_uops" "few")])
2622
2623
2624 (define_expand "movsf"
2625 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2626 (match_operand:SF 1 "general_operand" ""))]
2627 ""
2628 "ix86_expand_move (SFmode, operands); DONE;")
2629
2630 (define_insn "*pushsf"
2631 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2632 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2633 "!TARGET_64BIT"
2634 {
2635 switch (which_alternative)
2636 {
2637 case 0:
2638 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2639 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2640 operands[2] = stack_pointer_rtx;
2641 operands[3] = GEN_INT (4);
2642 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2643 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2644 else
2645 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2646
2647 case 1:
2648 return "push{l}\t%1";
2649 case 2:
2650 return "#";
2651
2652 default:
2653 abort ();
2654 }
2655 }
2656 [(set_attr "type" "multi,push,multi")
2657 (set_attr "mode" "SF,SI,SF")])
2658
2659 (define_insn "*pushsf_rex64"
2660 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2661 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2662 "TARGET_64BIT"
2663 {
2664 switch (which_alternative)
2665 {
2666 case 0:
2667 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2668 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2669 operands[2] = stack_pointer_rtx;
2670 operands[3] = GEN_INT (8);
2671 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2672 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2673 else
2674 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2675
2676 case 1:
2677 return "push{q}\t%q1";
2678
2679 case 2:
2680 return "#";
2681
2682 default:
2683 abort ();
2684 }
2685 }
2686 [(set_attr "type" "multi,push,multi")
2687 (set_attr "mode" "SF,DI,SF")])
2688
2689 (define_split
2690 [(set (match_operand:SF 0 "push_operand" "")
2691 (match_operand:SF 1 "memory_operand" ""))]
2692 "reload_completed
2693 && GET_CODE (operands[1]) == MEM
2694 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2695 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2696 [(set (match_dup 0)
2697 (match_dup 1))]
2698 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2699
2700
2701 ;; %%% Kill this when call knows how to work this out.
2702 (define_split
2703 [(set (match_operand:SF 0 "push_operand" "")
2704 (match_operand:SF 1 "register_operand" ""))]
2705 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2706 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2707 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2708
2709 (define_split
2710 [(set (match_operand:SF 0 "push_operand" "")
2711 (match_operand:SF 1 "register_operand" ""))]
2712 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2713 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2714 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2715
2716 (define_insn "*movsf_1"
2717 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2718 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
2719 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2720 && (reload_in_progress || reload_completed
2721 || GET_CODE (operands[1]) != CONST_DOUBLE
2722 || memory_operand (operands[0], SFmode))"
2723 {
2724 switch (which_alternative)
2725 {
2726 case 0:
2727 if (REG_P (operands[1])
2728 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2729 return "fstp\t%y0";
2730 else if (STACK_TOP_P (operands[0]))
2731 return "fld%z1\t%y1";
2732 else
2733 return "fst\t%y0";
2734
2735 case 1:
2736 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2737 return "fstp%z0\t%y0";
2738 else
2739 return "fst%z0\t%y0";
2740
2741 case 2:
2742 switch (standard_80387_constant_p (operands[1]))
2743 {
2744 case 1:
2745 return "fldz";
2746 case 2:
2747 return "fld1";
2748 }
2749 abort();
2750
2751 case 3:
2752 case 4:
2753 return "mov{l}\t{%1, %0|%0, %1}";
2754 case 5:
2755 return "pxor\t%0, %0";
2756 case 6:
2757 if (TARGET_PARTIAL_REG_DEPENDENCY)
2758 return "movaps\t{%1, %0|%0, %1}";
2759 else
2760 return "movss\t{%1, %0|%0, %1}";
2761 case 7:
2762 case 8:
2763 return "movss\t{%1, %0|%0, %1}";
2764
2765 default:
2766 abort();
2767 }
2768 }
2769 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2770 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
2771
2772 (define_insn "*swapsf"
2773 [(set (match_operand:SF 0 "register_operand" "+f")
2774 (match_operand:SF 1 "register_operand" "+f"))
2775 (set (match_dup 1)
2776 (match_dup 0))]
2777 "reload_completed || !TARGET_SSE"
2778 {
2779 if (STACK_TOP_P (operands[0]))
2780 return "fxch\t%1";
2781 else
2782 return "fxch\t%0";
2783 }
2784 [(set_attr "type" "fxch")
2785 (set_attr "mode" "SF")])
2786
2787 (define_expand "movdf"
2788 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2789 (match_operand:DF 1 "general_operand" ""))]
2790 ""
2791 "ix86_expand_move (DFmode, operands); DONE;")
2792
2793 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2794 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2795 ;; On the average, pushdf using integers can be still shorter. Allow this
2796 ;; pattern for optimize_size too.
2797
2798 (define_insn "*pushdf_nointeger"
2799 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2800 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2801 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2802 {
2803 switch (which_alternative)
2804 {
2805 case 0:
2806 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2807 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2808 operands[2] = stack_pointer_rtx;
2809 operands[3] = GEN_INT (8);
2810 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2812 else
2813 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2814
2815 case 1:
2816 case 2:
2817 case 3:
2818 return "#";
2819
2820 default:
2821 abort ();
2822 }
2823 }
2824 [(set_attr "type" "multi")
2825 (set_attr "mode" "DF,SI,SI,DF")])
2826
2827 (define_insn "*pushdf_integer"
2828 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2829 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2830 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2831 {
2832 switch (which_alternative)
2833 {
2834 case 0:
2835 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2836 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2837 operands[2] = stack_pointer_rtx;
2838 operands[3] = GEN_INT (8);
2839 if (TARGET_64BIT)
2840 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2841 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2842 else
2843 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2844 else
2845 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2846 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2847 else
2848 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2849
2850
2851 case 1:
2852 case 2:
2853 return "#";
2854
2855 default:
2856 abort ();
2857 }
2858 }
2859 [(set_attr "type" "multi")
2860 (set_attr "mode" "DF,SI,DF")])
2861
2862 ;; %%% Kill this when call knows how to work this out.
2863 (define_split
2864 [(set (match_operand:DF 0 "push_operand" "")
2865 (match_operand:DF 1 "register_operand" ""))]
2866 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2867 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2868 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2869 "")
2870
2871 (define_split
2872 [(set (match_operand:DF 0 "push_operand" "")
2873 (match_operand:DF 1 "register_operand" ""))]
2874 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2875 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2876 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2877 "")
2878
2879 (define_split
2880 [(set (match_operand:DF 0 "push_operand" "")
2881 (match_operand:DF 1 "general_operand" ""))]
2882 "reload_completed"
2883 [(const_int 0)]
2884 "ix86_split_long_move (operands); DONE;")
2885
2886 ;; Moving is usually shorter when only FP registers are used. This separate
2887 ;; movdf pattern avoids the use of integer registers for FP operations
2888 ;; when optimizing for size.
2889
2890 (define_insn "*movdf_nointeger"
2891 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2892 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2893 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2894 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2895 && (reload_in_progress || reload_completed
2896 || GET_CODE (operands[1]) != CONST_DOUBLE
2897 || memory_operand (operands[0], DFmode))"
2898 {
2899 switch (which_alternative)
2900 {
2901 case 0:
2902 if (REG_P (operands[1])
2903 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2904 return "fstp\t%y0";
2905 else if (STACK_TOP_P (operands[0]))
2906 return "fld%z1\t%y1";
2907 else
2908 return "fst\t%y0";
2909
2910 case 1:
2911 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2912 return "fstp%z0\t%y0";
2913 else
2914 return "fst%z0\t%y0";
2915
2916 case 2:
2917 switch (standard_80387_constant_p (operands[1]))
2918 {
2919 case 1:
2920 return "fldz";
2921 case 2:
2922 return "fld1";
2923 }
2924 abort();
2925
2926 case 3:
2927 case 4:
2928 return "#";
2929 case 5:
2930 return "pxor\t%0, %0";
2931 case 6:
2932 if (TARGET_PARTIAL_REG_DEPENDENCY)
2933 return "movapd\t{%1, %0|%0, %1}";
2934 else
2935 return "movsd\t{%1, %0|%0, %1}";
2936 case 7:
2937 case 8:
2938 return "movsd\t{%1, %0|%0, %1}";
2939
2940 default:
2941 abort();
2942 }
2943 }
2944 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2945 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2946
2947 (define_insn "*movdf_integer"
2948 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2949 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2950 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2951 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2952 && (reload_in_progress || reload_completed
2953 || GET_CODE (operands[1]) != CONST_DOUBLE
2954 || memory_operand (operands[0], DFmode))"
2955 {
2956 switch (which_alternative)
2957 {
2958 case 0:
2959 if (REG_P (operands[1])
2960 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2961 return "fstp\t%y0";
2962 else if (STACK_TOP_P (operands[0]))
2963 return "fld%z1\t%y1";
2964 else
2965 return "fst\t%y0";
2966
2967 case 1:
2968 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2969 return "fstp%z0\t%y0";
2970 else
2971 return "fst%z0\t%y0";
2972
2973 case 2:
2974 switch (standard_80387_constant_p (operands[1]))
2975 {
2976 case 1:
2977 return "fldz";
2978 case 2:
2979 return "fld1";
2980 }
2981 abort();
2982
2983 case 3:
2984 case 4:
2985 return "#";
2986
2987 case 5:
2988 return "pxor\t%0, %0";
2989 case 6:
2990 if (TARGET_PARTIAL_REG_DEPENDENCY)
2991 return "movapd\t{%1, %0|%0, %1}";
2992 else
2993 return "movsd\t{%1, %0|%0, %1}";
2994 case 7:
2995 case 8:
2996 return "movsd\t{%1, %0|%0, %1}";
2997
2998 default:
2999 abort();
3000 }
3001 }
3002 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3003 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
3004
3005 (define_split
3006 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3007 (match_operand:DF 1 "general_operand" ""))]
3008 "reload_completed
3009 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3010 && ! (ANY_FP_REG_P (operands[0]) ||
3011 (GET_CODE (operands[0]) == SUBREG
3012 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3013 && ! (ANY_FP_REG_P (operands[1]) ||
3014 (GET_CODE (operands[1]) == SUBREG
3015 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3016 [(const_int 0)]
3017 "ix86_split_long_move (operands); DONE;")
3018
3019 (define_insn "*swapdf"
3020 [(set (match_operand:DF 0 "register_operand" "+f")
3021 (match_operand:DF 1 "register_operand" "+f"))
3022 (set (match_dup 1)
3023 (match_dup 0))]
3024 "reload_completed || !TARGET_SSE2"
3025 {
3026 if (STACK_TOP_P (operands[0]))
3027 return "fxch\t%1";
3028 else
3029 return "fxch\t%0";
3030 }
3031 [(set_attr "type" "fxch")
3032 (set_attr "mode" "DF")])
3033
3034 (define_expand "movxf"
3035 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3036 (match_operand:XF 1 "general_operand" ""))]
3037 "!TARGET_64BIT"
3038 "ix86_expand_move (XFmode, operands); DONE;")
3039
3040 (define_expand "movtf"
3041 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3042 (match_operand:TF 1 "general_operand" ""))]
3043 ""
3044 "ix86_expand_move (TFmode, operands); DONE;")
3045
3046 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3047 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
3048 ;; Pushing using integer instructions is longer except for constants
3049 ;; and direct memory references.
3050 ;; (assuming that any given constant is pushed only once, but this ought to be
3051 ;; handled elsewhere).
3052
3053 (define_insn "*pushxf_nointeger"
3054 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3055 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3056 "!TARGET_64BIT && optimize_size"
3057 {
3058 switch (which_alternative)
3059 {
3060 case 0:
3061 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3062 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3063 operands[2] = stack_pointer_rtx;
3064 operands[3] = GEN_INT (12);
3065 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3066 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3067 else
3068 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3069
3070 case 1:
3071 case 2:
3072 return "#";
3073
3074 default:
3075 abort ();
3076 }
3077 }
3078 [(set_attr "type" "multi")
3079 (set_attr "mode" "XF,SI,SI")])
3080
3081 (define_insn "*pushtf_nointeger"
3082 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3083 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3084 "optimize_size"
3085 {
3086 switch (which_alternative)
3087 {
3088 case 0:
3089 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3090 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3091 operands[2] = stack_pointer_rtx;
3092 operands[3] = GEN_INT (16);
3093 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3094 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3095 else
3096 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3097
3098 case 1:
3099 case 2:
3100 return "#";
3101
3102 default:
3103 abort ();
3104 }
3105 }
3106 [(set_attr "type" "multi")
3107 (set_attr "mode" "XF,SI,SI")])
3108
3109 (define_insn "*pushxf_integer"
3110 [(set (match_operand:XF 0 "push_operand" "=<,<")
3111 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3112 "!TARGET_64BIT && !optimize_size"
3113 {
3114 switch (which_alternative)
3115 {
3116 case 0:
3117 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3118 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3119 operands[2] = stack_pointer_rtx;
3120 operands[3] = GEN_INT (12);
3121 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3122 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3123 else
3124 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3125
3126 case 1:
3127 return "#";
3128
3129 default:
3130 abort ();
3131 }
3132 }
3133 [(set_attr "type" "multi")
3134 (set_attr "mode" "XF,SI")])
3135
3136 (define_insn "*pushtf_integer"
3137 [(set (match_operand:TF 0 "push_operand" "=<,<")
3138 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3139 "!optimize_size"
3140 {
3141 switch (which_alternative)
3142 {
3143 case 0:
3144 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3145 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3146 operands[2] = stack_pointer_rtx;
3147 operands[3] = GEN_INT (16);
3148 if (TARGET_64BIT)
3149 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3150 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3151 else
3152 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3153 else
3154 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3155 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3156 else
3157 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3158
3159 case 1:
3160 return "#";
3161
3162 default:
3163 abort ();
3164 }
3165 }
3166 [(set_attr "type" "multi")
3167 (set_attr "mode" "XF,SI")])
3168
3169 (define_split
3170 [(set (match_operand 0 "push_operand" "")
3171 (match_operand 1 "general_operand" ""))]
3172 "reload_completed
3173 && (GET_MODE (operands[0]) == XFmode
3174 || GET_MODE (operands[0]) == TFmode
3175 || GET_MODE (operands[0]) == DFmode)
3176 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3177 [(const_int 0)]
3178 "ix86_split_long_move (operands); DONE;")
3179
3180 (define_split
3181 [(set (match_operand:XF 0 "push_operand" "")
3182 (match_operand:XF 1 "register_operand" ""))]
3183 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3184 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3185 (set (mem:XF (reg:SI 7)) (match_dup 1))])
3186
3187 (define_split
3188 [(set (match_operand:TF 0 "push_operand" "")
3189 (match_operand:TF 1 "register_operand" ""))]
3190 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3191 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3192 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3193
3194 (define_split
3195 [(set (match_operand:TF 0 "push_operand" "")
3196 (match_operand:TF 1 "register_operand" ""))]
3197 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3198 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3199 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3200
3201 ;; Do not use integer registers when optimizing for size
3202 (define_insn "*movxf_nointeger"
3203 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3204 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3205 "!TARGET_64BIT
3206 && optimize_size
3207 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3208 && (reload_in_progress || reload_completed
3209 || GET_CODE (operands[1]) != CONST_DOUBLE
3210 || memory_operand (operands[0], XFmode))"
3211 {
3212 switch (which_alternative)
3213 {
3214 case 0:
3215 if (REG_P (operands[1])
3216 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3217 return "fstp\t%y0";
3218 else if (STACK_TOP_P (operands[0]))
3219 return "fld%z1\t%y1";
3220 else
3221 return "fst\t%y0";
3222
3223 case 1:
3224 /* There is no non-popping store to memory for XFmode. So if
3225 we need one, follow the store with a load. */
3226 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3227 return "fstp%z0\t%y0\;fld%z0\t%y0";
3228 else
3229 return "fstp%z0\t%y0";
3230
3231 case 2:
3232 switch (standard_80387_constant_p (operands[1]))
3233 {
3234 case 1:
3235 return "fldz";
3236 case 2:
3237 return "fld1";
3238 }
3239 break;
3240
3241 case 3: case 4:
3242 return "#";
3243 }
3244 abort();
3245 }
3246 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3247 (set_attr "mode" "XF,XF,XF,SI,SI")])
3248
3249 (define_insn "*movtf_nointeger"
3250 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3251 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3252 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3253 && optimize_size
3254 && (reload_in_progress || reload_completed
3255 || GET_CODE (operands[1]) != CONST_DOUBLE
3256 || memory_operand (operands[0], TFmode))"
3257 {
3258 switch (which_alternative)
3259 {
3260 case 0:
3261 if (REG_P (operands[1])
3262 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3263 return "fstp\t%y0";
3264 else if (STACK_TOP_P (operands[0]))
3265 return "fld%z1\t%y1";
3266 else
3267 return "fst\t%y0";
3268
3269 case 1:
3270 /* There is no non-popping store to memory for XFmode. So if
3271 we need one, follow the store with a load. */
3272 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3273 return "fstp%z0\t%y0\;fld%z0\t%y0";
3274 else
3275 return "fstp%z0\t%y0";
3276
3277 case 2:
3278 switch (standard_80387_constant_p (operands[1]))
3279 {
3280 case 1:
3281 return "fldz";
3282 case 2:
3283 return "fld1";
3284 }
3285 break;
3286
3287 case 3: case 4:
3288 return "#";
3289 }
3290 abort();
3291 }
3292 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3293 (set_attr "mode" "XF,XF,XF,SI,SI")])
3294
3295 (define_insn "*movxf_integer"
3296 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3297 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3298 "!TARGET_64BIT
3299 && !optimize_size
3300 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3301 && (reload_in_progress || reload_completed
3302 || GET_CODE (operands[1]) != CONST_DOUBLE
3303 || memory_operand (operands[0], XFmode))"
3304 {
3305 switch (which_alternative)
3306 {
3307 case 0:
3308 if (REG_P (operands[1])
3309 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3310 return "fstp\t%y0";
3311 else if (STACK_TOP_P (operands[0]))
3312 return "fld%z1\t%y1";
3313 else
3314 return "fst\t%y0";
3315
3316 case 1:
3317 /* There is no non-popping store to memory for XFmode. So if
3318 we need one, follow the store with a load. */
3319 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3320 return "fstp%z0\t%y0\;fld%z0\t%y0";
3321 else
3322 return "fstp%z0\t%y0";
3323
3324 case 2:
3325 switch (standard_80387_constant_p (operands[1]))
3326 {
3327 case 1:
3328 return "fldz";
3329 case 2:
3330 return "fld1";
3331 }
3332 break;
3333
3334 case 3: case 4:
3335 return "#";
3336 }
3337 abort();
3338 }
3339 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3340 (set_attr "mode" "XF,XF,XF,SI,SI")])
3341
3342 (define_insn "*movtf_integer"
3343 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3344 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3345 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3346 && !optimize_size
3347 && (reload_in_progress || reload_completed
3348 || GET_CODE (operands[1]) != CONST_DOUBLE
3349 || memory_operand (operands[0], TFmode))"
3350 {
3351 switch (which_alternative)
3352 {
3353 case 0:
3354 if (REG_P (operands[1])
3355 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3356 return "fstp\t%y0";
3357 else if (STACK_TOP_P (operands[0]))
3358 return "fld%z1\t%y1";
3359 else
3360 return "fst\t%y0";
3361
3362 case 1:
3363 /* There is no non-popping store to memory for XFmode. So if
3364 we need one, follow the store with a load. */
3365 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3366 return "fstp%z0\t%y0\;fld%z0\t%y0";
3367 else
3368 return "fstp%z0\t%y0";
3369
3370 case 2:
3371 switch (standard_80387_constant_p (operands[1]))
3372 {
3373 case 1:
3374 return "fldz";
3375 case 2:
3376 return "fld1";
3377 }
3378 break;
3379
3380 case 3: case 4:
3381 return "#";
3382 }
3383 abort();
3384 }
3385 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3386 (set_attr "mode" "XF,XF,XF,SI,SI")])
3387
3388 (define_split
3389 [(set (match_operand 0 "nonimmediate_operand" "")
3390 (match_operand 1 "general_operand" ""))]
3391 "reload_completed
3392 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3393 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3394 && ! (ANY_FP_REG_P (operands[0]) ||
3395 (GET_CODE (operands[0]) == SUBREG
3396 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3397 && ! (ANY_FP_REG_P (operands[1]) ||
3398 (GET_CODE (operands[1]) == SUBREG
3399 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3400 [(const_int 0)]
3401 "ix86_split_long_move (operands); DONE;")
3402
3403 (define_split
3404 [(set (match_operand 0 "register_operand" "")
3405 (match_operand 1 "memory_operand" ""))]
3406 "reload_completed
3407 && GET_CODE (operands[1]) == MEM
3408 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3409 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3410 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3411 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3412 && (!(SSE_REG_P (operands[0]) ||
3413 (GET_CODE (operands[0]) == SUBREG
3414 && SSE_REG_P (SUBREG_REG (operands[0]))))
3415 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3416 && (!(FP_REG_P (operands[0]) ||
3417 (GET_CODE (operands[0]) == SUBREG
3418 && FP_REG_P (SUBREG_REG (operands[0]))))
3419 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3420 [(set (match_dup 0)
3421 (match_dup 1))]
3422 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3423
3424 (define_insn "swapxf"
3425 [(set (match_operand:XF 0 "register_operand" "+f")
3426 (match_operand:XF 1 "register_operand" "+f"))
3427 (set (match_dup 1)
3428 (match_dup 0))]
3429 ""
3430 {
3431 if (STACK_TOP_P (operands[0]))
3432 return "fxch\t%1";
3433 else
3434 return "fxch\t%0";
3435 }
3436 [(set_attr "type" "fxch")
3437 (set_attr "mode" "XF")])
3438
3439 (define_insn "swaptf"
3440 [(set (match_operand:TF 0 "register_operand" "+f")
3441 (match_operand:TF 1 "register_operand" "+f"))
3442 (set (match_dup 1)
3443 (match_dup 0))]
3444 ""
3445 {
3446 if (STACK_TOP_P (operands[0]))
3447 return "fxch\t%1";
3448 else
3449 return "fxch\t%0";
3450 }
3451 [(set_attr "type" "fxch")
3452 (set_attr "mode" "XF")])
3453 \f
3454 ;; Zero extension instructions
3455
3456 (define_expand "zero_extendhisi2"
3457 [(set (match_operand:SI 0 "register_operand" "")
3458 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3459 ""
3460 {
3461 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3462 {
3463 operands[1] = force_reg (HImode, operands[1]);
3464 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3465 DONE;
3466 }
3467 })
3468
3469 (define_insn "zero_extendhisi2_and"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472 (clobber (reg:CC 17))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3474 "#"
3475 [(set_attr "type" "alu1")
3476 (set_attr "mode" "SI")])
3477
3478 (define_split
3479 [(set (match_operand:SI 0 "register_operand" "")
3480 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3481 (clobber (reg:CC 17))]
3482 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3483 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3484 (clobber (reg:CC 17))])]
3485 "")
3486
3487 (define_insn "*zero_extendhisi2_movzwl"
3488 [(set (match_operand:SI 0 "register_operand" "=r")
3489 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3490 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3491 "movz{wl|x}\t{%1, %0|%0, %1}"
3492 [(set_attr "type" "imovx")
3493 (set_attr "mode" "SI")])
3494
3495 (define_expand "zero_extendqihi2"
3496 [(parallel
3497 [(set (match_operand:HI 0 "register_operand" "")
3498 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3499 (clobber (reg:CC 17))])]
3500 ""
3501 "")
3502
3503 (define_insn "*zero_extendqihi2_and"
3504 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3505 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3506 (clobber (reg:CC 17))]
3507 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3508 "#"
3509 [(set_attr "type" "alu1")
3510 (set_attr "mode" "HI")])
3511
3512 (define_insn "*zero_extendqihi2_movzbw_and"
3513 [(set (match_operand:HI 0 "register_operand" "=r,r")
3514 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3515 (clobber (reg:CC 17))]
3516 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3517 "#"
3518 [(set_attr "type" "imovx,alu1")
3519 (set_attr "mode" "HI")])
3520
3521 (define_insn "*zero_extendqihi2_movzbw"
3522 [(set (match_operand:HI 0 "register_operand" "=r")
3523 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3525 "movz{bw|x}\t{%1, %0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "HI")])
3528
3529 ;; For the movzbw case strip only the clobber
3530 (define_split
3531 [(set (match_operand:HI 0 "register_operand" "")
3532 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3533 (clobber (reg:CC 17))]
3534 "reload_completed
3535 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3536 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3537 [(set (match_operand:HI 0 "register_operand" "")
3538 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3539
3540 ;; When source and destination does not overlap, clear destination
3541 ;; first and then do the movb
3542 (define_split
3543 [(set (match_operand:HI 0 "register_operand" "")
3544 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3545 (clobber (reg:CC 17))]
3546 "reload_completed
3547 && ANY_QI_REG_P (operands[0])
3548 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3549 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3550 [(set (match_dup 0) (const_int 0))
3551 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3552 "operands[2] = gen_lowpart (QImode, operands[0]);")
3553
3554 ;; Rest is handled by single and.
3555 (define_split
3556 [(set (match_operand:HI 0 "register_operand" "")
3557 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3558 (clobber (reg:CC 17))]
3559 "reload_completed
3560 && true_regnum (operands[0]) == true_regnum (operands[1])"
3561 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3562 (clobber (reg:CC 17))])]
3563 "")
3564
3565 (define_expand "zero_extendqisi2"
3566 [(parallel
3567 [(set (match_operand:SI 0 "register_operand" "")
3568 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3569 (clobber (reg:CC 17))])]
3570 ""
3571 "")
3572
3573 (define_insn "*zero_extendqisi2_and"
3574 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3575 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3576 (clobber (reg:CC 17))]
3577 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3578 "#"
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "SI")])
3581
3582 (define_insn "*zero_extendqisi2_movzbw_and"
3583 [(set (match_operand:SI 0 "register_operand" "=r,r")
3584 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3585 (clobber (reg:CC 17))]
3586 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3587 "#"
3588 [(set_attr "type" "imovx,alu1")
3589 (set_attr "mode" "SI")])
3590
3591 (define_insn "*zero_extendqisi2_movzbw"
3592 [(set (match_operand:SI 0 "register_operand" "=r")
3593 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3594 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3595 "movz{bl|x}\t{%1, %0|%0, %1}"
3596 [(set_attr "type" "imovx")
3597 (set_attr "mode" "SI")])
3598
3599 ;; For the movzbl case strip only the clobber
3600 (define_split
3601 [(set (match_operand:SI 0 "register_operand" "")
3602 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3603 (clobber (reg:CC 17))]
3604 "reload_completed
3605 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3606 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3607 [(set (match_dup 0)
3608 (zero_extend:SI (match_dup 1)))])
3609
3610 ;; When source and destination does not overlap, clear destination
3611 ;; first and then do the movb
3612 (define_split
3613 [(set (match_operand:SI 0 "register_operand" "")
3614 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3615 (clobber (reg:CC 17))]
3616 "reload_completed
3617 && ANY_QI_REG_P (operands[0])
3618 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3619 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3620 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3621 [(set (match_dup 0) (const_int 0))
3622 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3623 "operands[2] = gen_lowpart (QImode, operands[0]);")
3624
3625 ;; Rest is handled by single and.
3626 (define_split
3627 [(set (match_operand:SI 0 "register_operand" "")
3628 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3629 (clobber (reg:CC 17))]
3630 "reload_completed
3631 && true_regnum (operands[0]) == true_regnum (operands[1])"
3632 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3633 (clobber (reg:CC 17))])]
3634 "")
3635
3636 ;; %%% Kill me once multi-word ops are sane.
3637 (define_expand "zero_extendsidi2"
3638 [(set (match_operand:DI 0 "register_operand" "=r")
3639 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3640 ""
3641 "if (!TARGET_64BIT)
3642 {
3643 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3644 DONE;
3645 }
3646 ")
3647
3648 (define_insn "zero_extendsidi2_32"
3649 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3650 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3651 (clobber (reg:CC 17))]
3652 "!TARGET_64BIT"
3653 "#"
3654 [(set_attr "mode" "SI")])
3655
3656 (define_insn "zero_extendsidi2_rex64"
3657 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3658 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3659 "TARGET_64BIT"
3660 "@
3661 mov\t{%k1, %k0|%k0, %k1}
3662 #"
3663 [(set_attr "type" "imovx,imov")
3664 (set_attr "mode" "SI,DI")])
3665
3666 (define_split
3667 [(set (match_operand:DI 0 "memory_operand" "")
3668 (zero_extend:DI (match_dup 0)))]
3669 "TARGET_64BIT"
3670 [(set (match_dup 4) (const_int 0))]
3671 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3672
3673 (define_split
3674 [(set (match_operand:DI 0 "register_operand" "")
3675 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3676 (clobber (reg:CC 17))]
3677 "!TARGET_64BIT && reload_completed
3678 && true_regnum (operands[0]) == true_regnum (operands[1])"
3679 [(set (match_dup 4) (const_int 0))]
3680 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3681
3682 (define_split
3683 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3684 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3685 (clobber (reg:CC 17))]
3686 "!TARGET_64BIT && reload_completed"
3687 [(set (match_dup 3) (match_dup 1))
3688 (set (match_dup 4) (const_int 0))]
3689 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3690
3691 (define_insn "zero_extendhidi2"
3692 [(set (match_operand:DI 0 "register_operand" "=r,r")
3693 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3694 "TARGET_64BIT"
3695 "@
3696 movz{wl|x}\t{%1, %k0|%k0, %1}
3697 movz{wq|x}\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "imovx")
3699 (set_attr "mode" "SI,DI")])
3700
3701 (define_insn "zero_extendqidi2"
3702 [(set (match_operand:DI 0 "register_operand" "=r,r")
3703 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3704 "TARGET_64BIT"
3705 "@
3706 movz{bl|x}\t{%1, %k0|%k0, %1}
3707 movz{bq|x}\t{%1, %0|%0, %1}"
3708 [(set_attr "type" "imovx")
3709 (set_attr "mode" "SI,DI")])
3710 \f
3711 ;; Sign extension instructions
3712
3713 (define_expand "extendsidi2"
3714 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3716 (clobber (reg:CC 17))
3717 (clobber (match_scratch:SI 2 ""))])]
3718 ""
3719 {
3720 if (TARGET_64BIT)
3721 {
3722 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3723 DONE;
3724 }
3725 })
3726
3727 (define_insn "*extendsidi2_1"
3728 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3729 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3730 (clobber (reg:CC 17))
3731 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3732 "!TARGET_64BIT"
3733 "#")
3734
3735 (define_insn "extendsidi2_rex64"
3736 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3737 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3738 "TARGET_64BIT"
3739 "@
3740 {cltq|cdqe}
3741 movs{lq|x}\t{%1,%0|%0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "DI")
3744 (set_attr "prefix_0f" "0")
3745 (set_attr "modrm" "0,1")])
3746
3747 (define_insn "extendhidi2"
3748 [(set (match_operand:DI 0 "register_operand" "=r")
3749 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3750 "TARGET_64BIT"
3751 "movs{wq|x}\t{%1,%0|%0, %1}"
3752 [(set_attr "type" "imovx")
3753 (set_attr "mode" "DI")])
3754
3755 (define_insn "extendqidi2"
3756 [(set (match_operand:DI 0 "register_operand" "=r")
3757 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3758 "TARGET_64BIT"
3759 "movs{bq|x}\t{%1,%0|%0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "DI")])
3762
3763 ;; Extend to memory case when source register does die.
3764 (define_split
3765 [(set (match_operand:DI 0 "memory_operand" "")
3766 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3767 (clobber (reg:CC 17))
3768 (clobber (match_operand:SI 2 "register_operand" ""))]
3769 "(reload_completed
3770 && dead_or_set_p (insn, operands[1])
3771 && !reg_mentioned_p (operands[1], operands[0]))"
3772 [(set (match_dup 3) (match_dup 1))
3773 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3774 (clobber (reg:CC 17))])
3775 (set (match_dup 4) (match_dup 1))]
3776 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3777
3778 ;; Extend to memory case when source register does not die.
3779 (define_split
3780 [(set (match_operand:DI 0 "memory_operand" "")
3781 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3782 (clobber (reg:CC 17))
3783 (clobber (match_operand:SI 2 "register_operand" ""))]
3784 "reload_completed"
3785 [(const_int 0)]
3786 {
3787 split_di (&operands[0], 1, &operands[3], &operands[4]);
3788
3789 emit_move_insn (operands[3], operands[1]);
3790
3791 /* Generate a cltd if possible and doing so it profitable. */
3792 if (true_regnum (operands[1]) == 0
3793 && true_regnum (operands[2]) == 1
3794 && (optimize_size || TARGET_USE_CLTD))
3795 {
3796 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3797 }
3798 else
3799 {
3800 emit_move_insn (operands[2], operands[1]);
3801 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3802 }
3803 emit_move_insn (operands[4], operands[2]);
3804 DONE;
3805 })
3806
3807 ;; Extend to register case. Optimize case where source and destination
3808 ;; registers match and cases where we can use cltd.
3809 (define_split
3810 [(set (match_operand:DI 0 "register_operand" "")
3811 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3812 (clobber (reg:CC 17))
3813 (clobber (match_scratch:SI 2 ""))]
3814 "reload_completed"
3815 [(const_int 0)]
3816 {
3817 split_di (&operands[0], 1, &operands[3], &operands[4]);
3818
3819 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3820 emit_move_insn (operands[3], operands[1]);
3821
3822 /* Generate a cltd if possible and doing so it profitable. */
3823 if (true_regnum (operands[3]) == 0
3824 && (optimize_size || TARGET_USE_CLTD))
3825 {
3826 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3827 DONE;
3828 }
3829
3830 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3831 emit_move_insn (operands[4], operands[1]);
3832
3833 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3834 DONE;
3835 })
3836
3837 (define_insn "extendhisi2"
3838 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3839 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3840 ""
3841 {
3842 switch (get_attr_prefix_0f (insn))
3843 {
3844 case 0:
3845 return "{cwtl|cwde}";
3846 default:
3847 return "movs{wl|x}\t{%1,%0|%0, %1}";
3848 }
3849 }
3850 [(set_attr "type" "imovx")
3851 (set_attr "mode" "SI")
3852 (set (attr "prefix_0f")
3853 ;; movsx is short decodable while cwtl is vector decoded.
3854 (if_then_else (and (eq_attr "cpu" "!k6")
3855 (eq_attr "alternative" "0"))
3856 (const_string "0")
3857 (const_string "1")))
3858 (set (attr "modrm")
3859 (if_then_else (eq_attr "prefix_0f" "0")
3860 (const_string "0")
3861 (const_string "1")))])
3862
3863 (define_insn "*extendhisi2_zext"
3864 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3865 (zero_extend:DI
3866 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3867 "TARGET_64BIT"
3868 {
3869 switch (get_attr_prefix_0f (insn))
3870 {
3871 case 0:
3872 return "{cwtl|cwde}";
3873 default:
3874 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3875 }
3876 }
3877 [(set_attr "type" "imovx")
3878 (set_attr "mode" "SI")
3879 (set (attr "prefix_0f")
3880 ;; movsx is short decodable while cwtl is vector decoded.
3881 (if_then_else (and (eq_attr "cpu" "!k6")
3882 (eq_attr "alternative" "0"))
3883 (const_string "0")
3884 (const_string "1")))
3885 (set (attr "modrm")
3886 (if_then_else (eq_attr "prefix_0f" "0")
3887 (const_string "0")
3888 (const_string "1")))])
3889
3890 (define_insn "extendqihi2"
3891 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3892 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3893 ""
3894 {
3895 switch (get_attr_prefix_0f (insn))
3896 {
3897 case 0:
3898 return "{cbtw|cbw}";
3899 default:
3900 return "movs{bw|x}\t{%1,%0|%0, %1}";
3901 }
3902 }
3903 [(set_attr "type" "imovx")
3904 (set_attr "mode" "HI")
3905 (set (attr "prefix_0f")
3906 ;; movsx is short decodable while cwtl is vector decoded.
3907 (if_then_else (and (eq_attr "cpu" "!k6")
3908 (eq_attr "alternative" "0"))
3909 (const_string "0")
3910 (const_string "1")))
3911 (set (attr "modrm")
3912 (if_then_else (eq_attr "prefix_0f" "0")
3913 (const_string "0")
3914 (const_string "1")))])
3915
3916 (define_insn "extendqisi2"
3917 [(set (match_operand:SI 0 "register_operand" "=r")
3918 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3919 ""
3920 "movs{bl|x}\t{%1,%0|%0, %1}"
3921 [(set_attr "type" "imovx")
3922 (set_attr "mode" "SI")])
3923
3924 (define_insn "*extendqisi2_zext"
3925 [(set (match_operand:DI 0 "register_operand" "=r")
3926 (zero_extend:DI
3927 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3928 "TARGET_64BIT"
3929 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3930 [(set_attr "type" "imovx")
3931 (set_attr "mode" "SI")])
3932 \f
3933 ;; Conversions between float and double.
3934
3935 ;; These are all no-ops in the model used for the 80387. So just
3936 ;; emit moves.
3937
3938 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3939 (define_insn "*dummy_extendsfdf2"
3940 [(set (match_operand:DF 0 "push_operand" "=<")
3941 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3942 "0"
3943 "#")
3944
3945 (define_split
3946 [(set (match_operand:DF 0 "push_operand" "")
3947 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3948 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3949 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3950 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3951
3952 (define_split
3953 [(set (match_operand:DF 0 "push_operand" "")
3954 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3955 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3956 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3957 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3958
3959 (define_insn "*dummy_extendsfxf2"
3960 [(set (match_operand:XF 0 "push_operand" "=<")
3961 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3962 "0"
3963 "#")
3964
3965 (define_split
3966 [(set (match_operand:XF 0 "push_operand" "")
3967 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3968 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3969 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3970 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3971
3972 (define_insn "*dummy_extendsftf2"
3973 [(set (match_operand:TF 0 "push_operand" "=<")
3974 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3975 "0"
3976 "#")
3977
3978 (define_split
3979 [(set (match_operand:TF 0 "push_operand" "")
3980 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3981 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3982 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3983 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3984
3985 (define_split
3986 [(set (match_operand:TF 0 "push_operand" "")
3987 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3988 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3989 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3990 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3991
3992 (define_insn "*dummy_extenddfxf2"
3993 [(set (match_operand:XF 0 "push_operand" "=<")
3994 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3995 "0"
3996 "#")
3997
3998 (define_split
3999 [(set (match_operand:XF 0 "push_operand" "")
4000 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4001 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4002 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4003 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4004
4005 (define_insn "*dummy_extenddftf2"
4006 [(set (match_operand:TF 0 "push_operand" "=<")
4007 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4008 "0"
4009 "#")
4010
4011 (define_split
4012 [(set (match_operand:TF 0 "push_operand" "")
4013 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4014 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4015 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4016 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4017
4018 (define_split
4019 [(set (match_operand:TF 0 "push_operand" "")
4020 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4021 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4022 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4023 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4024
4025 (define_expand "extendsfdf2"
4026 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4027 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4028 "TARGET_80387 || TARGET_SSE2"
4029 {
4030 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4031 operands[1] = force_reg (SFmode, operands[1]);
4032 })
4033
4034 (define_insn "*extendsfdf2_1"
4035 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4036 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
4037 "(TARGET_80387 || TARGET_SSE2)
4038 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4039 {
4040 switch (which_alternative)
4041 {
4042 case 0:
4043 if (REG_P (operands[1])
4044 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp\t%y0";
4046 else if (STACK_TOP_P (operands[0]))
4047 return "fld%z1\t%y1";
4048 else
4049 return "fst\t%y0";
4050
4051 case 1:
4052 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4053 return "fstp%z0\t%y0";
4054
4055 else
4056 return "fst%z0\t%y0";
4057 case 2:
4058 return "cvtss2sd\t{%1, %0|%0, %1}";
4059
4060 default:
4061 abort ();
4062 }
4063 }
4064 [(set_attr "type" "fmov,fmov,sse")
4065 (set_attr "mode" "SF,XF,DF")])
4066
4067 (define_insn "*extendsfdf2_1_sse_only"
4068 [(set (match_operand:DF 0 "register_operand" "=Y")
4069 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4070 "!TARGET_80387 && TARGET_SSE2
4071 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4072 "cvtss2sd\t{%1, %0|%0, %1}"
4073 [(set_attr "type" "sse")
4074 (set_attr "mode" "DF")])
4075
4076 (define_expand "extendsfxf2"
4077 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4078 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4079 "!TARGET_64BIT && TARGET_80387"
4080 {
4081 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4082 operands[1] = force_reg (SFmode, operands[1]);
4083 })
4084
4085 (define_insn "*extendsfxf2_1"
4086 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4087 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4088 "!TARGET_64BIT && TARGET_80387
4089 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4090 {
4091 switch (which_alternative)
4092 {
4093 case 0:
4094 if (REG_P (operands[1])
4095 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4096 return "fstp\t%y0";
4097 else if (STACK_TOP_P (operands[0]))
4098 return "fld%z1\t%y1";
4099 else
4100 return "fst\t%y0";
4101
4102 case 1:
4103 /* There is no non-popping store to memory for XFmode. So if
4104 we need one, follow the store with a load. */
4105 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4106 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4107 else
4108 return "fstp%z0\t%y0";
4109
4110 default:
4111 abort ();
4112 }
4113 }
4114 [(set_attr "type" "fmov")
4115 (set_attr "mode" "SF,XF")])
4116
4117 (define_expand "extendsftf2"
4118 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4119 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4120 "TARGET_80387"
4121 {
4122 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4123 operands[1] = force_reg (SFmode, operands[1]);
4124 })
4125
4126 (define_insn "*extendsftf2_1"
4127 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4128 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4129 "TARGET_80387
4130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4131 {
4132 switch (which_alternative)
4133 {
4134 case 0:
4135 if (REG_P (operands[1])
4136 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4137 return "fstp\t%y0";
4138 else if (STACK_TOP_P (operands[0]))
4139 return "fld%z1\t%y1";
4140 else
4141 return "fst\t%y0";
4142
4143 case 1:
4144 /* There is no non-popping store to memory for XFmode. So if
4145 we need one, follow the store with a load. */
4146 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4147 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4148 else
4149 return "fstp%z0\t%y0";
4150
4151 default:
4152 abort ();
4153 }
4154 }
4155 [(set_attr "type" "fmov")
4156 (set_attr "mode" "SF,XF")])
4157
4158 (define_expand "extenddfxf2"
4159 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4160 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4161 "!TARGET_64BIT && TARGET_80387"
4162 {
4163 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4164 operands[1] = force_reg (DFmode, operands[1]);
4165 })
4166
4167 (define_insn "*extenddfxf2_1"
4168 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4169 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4170 "!TARGET_64BIT && TARGET_80387
4171 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4172 {
4173 switch (which_alternative)
4174 {
4175 case 0:
4176 if (REG_P (operands[1])
4177 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4178 return "fstp\t%y0";
4179 else if (STACK_TOP_P (operands[0]))
4180 return "fld%z1\t%y1";
4181 else
4182 return "fst\t%y0";
4183
4184 case 1:
4185 /* There is no non-popping store to memory for XFmode. So if
4186 we need one, follow the store with a load. */
4187 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4188 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4189 else
4190 return "fstp%z0\t%y0";
4191
4192 default:
4193 abort ();
4194 }
4195 }
4196 [(set_attr "type" "fmov")
4197 (set_attr "mode" "DF,XF")])
4198
4199 (define_expand "extenddftf2"
4200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4201 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4202 "TARGET_80387"
4203 {
4204 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4205 operands[1] = force_reg (DFmode, operands[1]);
4206 })
4207
4208 (define_insn "*extenddftf2_1"
4209 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4210 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4211 "TARGET_80387
4212 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4213 {
4214 switch (which_alternative)
4215 {
4216 case 0:
4217 if (REG_P (operands[1])
4218 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4219 return "fstp\t%y0";
4220 else if (STACK_TOP_P (operands[0]))
4221 return "fld%z1\t%y1";
4222 else
4223 return "fst\t%y0";
4224
4225 case 1:
4226 /* There is no non-popping store to memory for XFmode. So if
4227 we need one, follow the store with a load. */
4228 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4229 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4230 else
4231 return "fstp%z0\t%y0";
4232
4233 default:
4234 abort ();
4235 }
4236 }
4237 [(set_attr "type" "fmov")
4238 (set_attr "mode" "DF,XF")])
4239
4240 ;; %%% This seems bad bad news.
4241 ;; This cannot output into an f-reg because there is no way to be sure
4242 ;; of truncating in that case. Otherwise this is just like a simple move
4243 ;; insn. So we pretend we can output to a reg in order to get better
4244 ;; register preferencing, but we really use a stack slot.
4245
4246 (define_expand "truncdfsf2"
4247 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4248 (float_truncate:SF
4249 (match_operand:DF 1 "register_operand" "")))
4250 (clobber (match_dup 2))])]
4251 "TARGET_80387 || TARGET_SSE2"
4252 "
4253 if (TARGET_80387)
4254 operands[2] = assign_386_stack_local (SFmode, 0);
4255 else
4256 {
4257 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4258 DONE;
4259 }
4260 ")
4261
4262 (define_insn "*truncdfsf2_1"
4263 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4264 (float_truncate:SF
4265 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4266 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4267 "TARGET_80387 && !TARGET_SSE2"
4268 {
4269 switch (which_alternative)
4270 {
4271 case 0:
4272 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4273 return "fstp%z0\t%y0";
4274 else
4275 return "fst%z0\t%y0";
4276 default:
4277 abort ();
4278 }
4279 }
4280 [(set_attr "type" "fmov,multi,multi,multi")
4281 (set_attr "mode" "SF,SF,SF,SF")])
4282
4283 (define_insn "*truncdfsf2_1_sse"
4284 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4285 (float_truncate:SF
4286 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4287 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4288 "TARGET_80387 && TARGET_SSE2"
4289 {
4290 switch (which_alternative)
4291 {
4292 case 0:
4293 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4294 return "fstp%z0\t%y0";
4295 else
4296 return "fst%z0\t%y0";
4297 case 4:
4298 return "cvtsd2ss\t{%1, %0|%0, %1}";
4299 default:
4300 abort ();
4301 }
4302 }
4303 [(set_attr "type" "fmov,multi,multi,multi,sse")
4304 (set_attr "mode" "SF,SF,SF,SF,DF")])
4305
4306 (define_insn "*truncdfsf2_2"
4307 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4308 (float_truncate:SF
4309 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4310 "TARGET_80387 && TARGET_SSE2
4311 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4312 {
4313 switch (which_alternative)
4314 {
4315 case 0:
4316 return "cvtsd2ss\t{%1, %0|%0, %1}";
4317 case 1:
4318 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4319 return "fstp%z0\t%y0";
4320 else
4321 return "fst%z0\t%y0";
4322 default:
4323 abort ();
4324 }
4325 }
4326 [(set_attr "type" "sse,fmov")
4327 (set_attr "mode" "DF,SF")])
4328
4329 (define_insn "truncdfsf2_3"
4330 [(set (match_operand:SF 0 "memory_operand" "=m")
4331 (float_truncate:SF
4332 (match_operand:DF 1 "register_operand" "f")))]
4333 "TARGET_80387"
4334 {
4335 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4336 return "fstp%z0\t%y0";
4337 else
4338 return "fst%z0\t%y0";
4339 }
4340 [(set_attr "type" "fmov")
4341 (set_attr "mode" "SF")])
4342
4343 (define_insn "truncdfsf2_sse_only"
4344 [(set (match_operand:SF 0 "register_operand" "=Y")
4345 (float_truncate:SF
4346 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4347 "!TARGET_80387 && TARGET_SSE2"
4348 "cvtsd2ss\t{%1, %0|%0, %1}"
4349 [(set_attr "type" "sse")
4350 (set_attr "mode" "DF")])
4351
4352 (define_split
4353 [(set (match_operand:SF 0 "memory_operand" "")
4354 (float_truncate:SF
4355 (match_operand:DF 1 "register_operand" "")))
4356 (clobber (match_operand:SF 2 "memory_operand" ""))]
4357 "TARGET_80387"
4358 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4359 "")
4360
4361 (define_split
4362 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4363 (float_truncate:SF
4364 (match_operand:DF 1 "nonimmediate_operand" "")))
4365 (clobber (match_operand 2 "" ""))]
4366 "TARGET_80387 && reload_completed
4367 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4368 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4369 "")
4370
4371 (define_split
4372 [(set (match_operand:SF 0 "register_operand" "")
4373 (float_truncate:SF
4374 (match_operand:DF 1 "register_operand" "")))
4375 (clobber (match_operand:SF 2 "memory_operand" ""))]
4376 "TARGET_80387 && reload_completed
4377 && FP_REG_P (operands[1])"
4378 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4379 (set (match_dup 0) (match_dup 2))]
4380 "")
4381
4382 (define_expand "truncxfsf2"
4383 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4384 (float_truncate:SF
4385 (match_operand:XF 1 "register_operand" "")))
4386 (clobber (match_dup 2))])]
4387 "!TARGET_64BIT && TARGET_80387"
4388 "operands[2] = assign_386_stack_local (SFmode, 0);")
4389
4390 (define_insn "*truncxfsf2_1"
4391 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4392 (float_truncate:SF
4393 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4394 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4395 "!TARGET_64BIT && TARGET_80387"
4396 {
4397 switch (which_alternative)
4398 {
4399 case 0:
4400 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4401 return "fstp%z0\t%y0";
4402 else
4403 return "fst%z0\t%y0";
4404 default:
4405 abort();
4406 }
4407 }
4408 [(set_attr "type" "fmov,multi,multi,multi")
4409 (set_attr "mode" "SF")])
4410
4411 (define_insn "*truncxfsf2_2"
4412 [(set (match_operand:SF 0 "memory_operand" "=m")
4413 (float_truncate:SF
4414 (match_operand:XF 1 "register_operand" "f")))]
4415 "!TARGET_64BIT && TARGET_80387"
4416 {
4417 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4418 return "fstp%z0\t%y0";
4419 else
4420 return "fst%z0\t%y0";
4421 }
4422 [(set_attr "type" "fmov")
4423 (set_attr "mode" "SF")])
4424
4425 (define_split
4426 [(set (match_operand:SF 0 "memory_operand" "")
4427 (float_truncate:SF
4428 (match_operand:XF 1 "register_operand" "")))
4429 (clobber (match_operand:SF 2 "memory_operand" ""))]
4430 "TARGET_80387"
4431 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4432 "")
4433
4434 (define_split
4435 [(set (match_operand:SF 0 "register_operand" "")
4436 (float_truncate:SF
4437 (match_operand:XF 1 "register_operand" "")))
4438 (clobber (match_operand:SF 2 "memory_operand" ""))]
4439 "TARGET_80387 && reload_completed"
4440 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4441 (set (match_dup 0) (match_dup 2))]
4442 "")
4443
4444 (define_expand "trunctfsf2"
4445 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4446 (float_truncate:SF
4447 (match_operand:TF 1 "register_operand" "")))
4448 (clobber (match_dup 2))])]
4449 "TARGET_80387"
4450 "operands[2] = assign_386_stack_local (SFmode, 0);")
4451
4452 (define_insn "*trunctfsf2_1"
4453 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4454 (float_truncate:SF
4455 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4456 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4457 "TARGET_80387"
4458 {
4459 switch (which_alternative)
4460 {
4461 case 0:
4462 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4463 return "fstp%z0\t%y0";
4464 else
4465 return "fst%z0\t%y0";
4466 default:
4467 abort();
4468 }
4469 }
4470 [(set_attr "type" "fmov,multi,multi,multi")
4471 (set_attr "mode" "SF")])
4472
4473 (define_insn "*trunctfsf2_2"
4474 [(set (match_operand:SF 0 "memory_operand" "=m")
4475 (float_truncate:SF
4476 (match_operand:TF 1 "register_operand" "f")))]
4477 "TARGET_80387"
4478 {
4479 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4480 return "fstp%z0\t%y0";
4481 else
4482 return "fst%z0\t%y0";
4483 }
4484 [(set_attr "type" "fmov")
4485 (set_attr "mode" "SF")])
4486
4487 (define_split
4488 [(set (match_operand:SF 0 "memory_operand" "")
4489 (float_truncate:SF
4490 (match_operand:TF 1 "register_operand" "")))
4491 (clobber (match_operand:SF 2 "memory_operand" ""))]
4492 "TARGET_80387"
4493 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4494 "")
4495
4496 (define_split
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float_truncate:SF
4499 (match_operand:TF 1 "register_operand" "")))
4500 (clobber (match_operand:SF 2 "memory_operand" ""))]
4501 "TARGET_80387 && reload_completed"
4502 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4503 (set (match_dup 0) (match_dup 2))]
4504 "")
4505
4506
4507 (define_expand "truncxfdf2"
4508 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4509 (float_truncate:DF
4510 (match_operand:XF 1 "register_operand" "")))
4511 (clobber (match_dup 2))])]
4512 "!TARGET_64BIT && TARGET_80387"
4513 "operands[2] = assign_386_stack_local (DFmode, 0);")
4514
4515 (define_insn "*truncxfdf2_1"
4516 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4517 (float_truncate:DF
4518 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4519 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4520 "!TARGET_64BIT && TARGET_80387"
4521 {
4522 switch (which_alternative)
4523 {
4524 case 0:
4525 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4526 return "fstp%z0\t%y0";
4527 else
4528 return "fst%z0\t%y0";
4529 default:
4530 abort();
4531 }
4532 abort ();
4533 }
4534 [(set_attr "type" "fmov,multi,multi,multi")
4535 (set_attr "mode" "DF")])
4536
4537 (define_insn "*truncxfdf2_2"
4538 [(set (match_operand:DF 0 "memory_operand" "=m")
4539 (float_truncate:DF
4540 (match_operand:XF 1 "register_operand" "f")))]
4541 "!TARGET_64BIT && TARGET_80387"
4542 {
4543 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4544 return "fstp%z0\t%y0";
4545 else
4546 return "fst%z0\t%y0";
4547 }
4548 [(set_attr "type" "fmov")
4549 (set_attr "mode" "DF")])
4550
4551 (define_split
4552 [(set (match_operand:DF 0 "memory_operand" "")
4553 (float_truncate:DF
4554 (match_operand:XF 1 "register_operand" "")))
4555 (clobber (match_operand:DF 2 "memory_operand" ""))]
4556 "TARGET_80387"
4557 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4558 "")
4559
4560 (define_split
4561 [(set (match_operand:DF 0 "register_operand" "")
4562 (float_truncate:DF
4563 (match_operand:XF 1 "register_operand" "")))
4564 (clobber (match_operand:DF 2 "memory_operand" ""))]
4565 "TARGET_80387 && reload_completed"
4566 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4567 (set (match_dup 0) (match_dup 2))]
4568 "")
4569
4570 (define_expand "trunctfdf2"
4571 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4572 (float_truncate:DF
4573 (match_operand:TF 1 "register_operand" "")))
4574 (clobber (match_dup 2))])]
4575 "TARGET_80387"
4576 "operands[2] = assign_386_stack_local (DFmode, 0);")
4577
4578 (define_insn "*trunctfdf2_1"
4579 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4580 (float_truncate:DF
4581 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4582 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4583 "TARGET_80387"
4584 {
4585 switch (which_alternative)
4586 {
4587 case 0:
4588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4589 return "fstp%z0\t%y0";
4590 else
4591 return "fst%z0\t%y0";
4592 default:
4593 abort();
4594 }
4595 abort ();
4596 }
4597 [(set_attr "type" "fmov,multi,multi,multi")
4598 (set_attr "mode" "DF")])
4599
4600 (define_insn "*trunctfdf2_2"
4601 [(set (match_operand:DF 0 "memory_operand" "=m")
4602 (float_truncate:DF
4603 (match_operand:TF 1 "register_operand" "f")))]
4604 "TARGET_80387"
4605 {
4606 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4607 return "fstp%z0\t%y0";
4608 else
4609 return "fst%z0\t%y0";
4610 }
4611 [(set_attr "type" "fmov")
4612 (set_attr "mode" "DF")])
4613
4614 (define_split
4615 [(set (match_operand:DF 0 "memory_operand" "")
4616 (float_truncate:DF
4617 (match_operand:TF 1 "register_operand" "")))
4618 (clobber (match_operand:DF 2 "memory_operand" ""))]
4619 "TARGET_80387"
4620 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4621 "")
4622
4623 (define_split
4624 [(set (match_operand:DF 0 "register_operand" "")
4625 (float_truncate:DF
4626 (match_operand:TF 1 "register_operand" "")))
4627 (clobber (match_operand:DF 2 "memory_operand" ""))]
4628 "TARGET_80387 && reload_completed"
4629 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4630 (set (match_dup 0) (match_dup 2))]
4631 "")
4632
4633 \f
4634 ;; %%% Break up all these bad boys.
4635
4636 ;; Signed conversion to DImode.
4637
4638 (define_expand "fix_truncxfdi2"
4639 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4640 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4641 "!TARGET_64BIT && TARGET_80387"
4642 "")
4643
4644 (define_expand "fix_trunctfdi2"
4645 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4646 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4647 "TARGET_80387"
4648 "")
4649
4650 (define_expand "fix_truncdfdi2"
4651 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4652 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4653 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4654 {
4655 if (TARGET_64BIT && TARGET_SSE2)
4656 {
4657 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4658 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4659 if (out != operands[0])
4660 emit_move_insn (operands[0], out);
4661 DONE;
4662 }
4663 })
4664
4665 (define_expand "fix_truncsfdi2"
4666 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4667 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4668 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4669 {
4670 if (TARGET_SSE && TARGET_64BIT)
4671 {
4672 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4673 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4674 if (out != operands[0])
4675 emit_move_insn (operands[0], out);
4676 DONE;
4677 }
4678 })
4679
4680 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4681 ;; of the machinery.
4682 (define_insn_and_split "*fix_truncdi_1"
4683 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4684 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4685 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && !reload_completed && !reload_in_progress
4687 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4688 "#"
4689 "&& 1"
4690 [(const_int 0)]
4691 {
4692 operands[2] = assign_386_stack_local (HImode, 1);
4693 operands[3] = assign_386_stack_local (HImode, 2);
4694 if (memory_operand (operands[0], VOIDmode))
4695 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4696 operands[2], operands[3]));
4697 else
4698 {
4699 operands[4] = assign_386_stack_local (DImode, 0);
4700 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4701 operands[2], operands[3],
4702 operands[4]));
4703 }
4704 DONE;
4705 }
4706 [(set_attr "type" "fistp")])
4707
4708 (define_insn "fix_truncdi_nomemory"
4709 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4710 (fix:DI (match_operand 1 "register_operand" "f,f")))
4711 (use (match_operand:HI 2 "memory_operand" "m,m"))
4712 (use (match_operand:HI 3 "memory_operand" "m,m"))
4713 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4714 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4715 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4716 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4717 "#"
4718 [(set_attr "type" "fistp")])
4719
4720 (define_insn "fix_truncdi_memory"
4721 [(set (match_operand:DI 0 "memory_operand" "=m")
4722 (fix:DI (match_operand 1 "register_operand" "f")))
4723 (use (match_operand:HI 2 "memory_operand" "m"))
4724 (use (match_operand:HI 3 "memory_operand" "m"))
4725 (clobber (match_scratch:DF 4 "=&1f"))]
4726 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4727 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4728 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4729 [(set_attr "type" "fistp")])
4730
4731 (define_split
4732 [(set (match_operand:DI 0 "register_operand" "")
4733 (fix:DI (match_operand 1 "register_operand" "")))
4734 (use (match_operand:HI 2 "memory_operand" ""))
4735 (use (match_operand:HI 3 "memory_operand" ""))
4736 (clobber (match_operand:DI 4 "memory_operand" ""))
4737 (clobber (match_scratch 5 ""))]
4738 "reload_completed"
4739 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4740 (use (match_dup 2))
4741 (use (match_dup 3))
4742 (clobber (match_dup 5))])
4743 (set (match_dup 0) (match_dup 4))]
4744 "")
4745
4746 (define_split
4747 [(set (match_operand:DI 0 "memory_operand" "")
4748 (fix:DI (match_operand 1 "register_operand" "")))
4749 (use (match_operand:HI 2 "memory_operand" ""))
4750 (use (match_operand:HI 3 "memory_operand" ""))
4751 (clobber (match_operand:DI 4 "memory_operand" ""))
4752 (clobber (match_scratch 5 ""))]
4753 "reload_completed"
4754 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4755 (use (match_dup 2))
4756 (use (match_dup 3))
4757 (clobber (match_dup 5))])]
4758 "")
4759
4760 ;; When SSE available, it is always faster to use it!
4761 (define_insn "fix_truncsfdi_sse"
4762 [(set (match_operand:DI 0 "register_operand" "=r")
4763 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4764 "TARGET_64BIT && TARGET_SSE"
4765 "cvttss2si{q}\t{%1, %0|%0, %1}"
4766 [(set_attr "type" "sse")])
4767
4768 (define_insn "fix_truncdfdi_sse"
4769 [(set (match_operand:DI 0 "register_operand" "=r")
4770 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4771 "TARGET_64BIT && TARGET_SSE2"
4772 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4773 [(set_attr "type" "sse")])
4774
4775 ;; Signed conversion to SImode.
4776
4777 (define_expand "fix_truncxfsi2"
4778 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4779 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4780 "!TARGET_64BIT && TARGET_80387"
4781 "")
4782
4783 (define_expand "fix_trunctfsi2"
4784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4785 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4786 "TARGET_80387"
4787 "")
4788
4789 (define_expand "fix_truncdfsi2"
4790 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4791 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4792 "TARGET_80387 || TARGET_SSE2"
4793 {
4794 if (TARGET_SSE2)
4795 {
4796 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4797 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4798 if (out != operands[0])
4799 emit_move_insn (operands[0], out);
4800 DONE;
4801 }
4802 })
4803
4804 (define_expand "fix_truncsfsi2"
4805 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4806 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4807 "TARGET_80387 || TARGET_SSE"
4808 {
4809 if (TARGET_SSE)
4810 {
4811 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4812 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4813 if (out != operands[0])
4814 emit_move_insn (operands[0], out);
4815 DONE;
4816 }
4817 })
4818
4819 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4820 ;; of the machinery.
4821 (define_insn_and_split "*fix_truncsi_1"
4822 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4823 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4824 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4825 && !reload_completed && !reload_in_progress
4826 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4827 "#"
4828 "&& 1"
4829 [(const_int 0)]
4830 {
4831 operands[2] = assign_386_stack_local (HImode, 1);
4832 operands[3] = assign_386_stack_local (HImode, 2);
4833 if (memory_operand (operands[0], VOIDmode))
4834 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4835 operands[2], operands[3]));
4836 else
4837 {
4838 operands[4] = assign_386_stack_local (SImode, 0);
4839 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4840 operands[2], operands[3],
4841 operands[4]));
4842 }
4843 DONE;
4844 }
4845 [(set_attr "type" "fistp")])
4846
4847 (define_insn "fix_truncsi_nomemory"
4848 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4849 (fix:SI (match_operand 1 "register_operand" "f,f")))
4850 (use (match_operand:HI 2 "memory_operand" "m,m"))
4851 (use (match_operand:HI 3 "memory_operand" "m,m"))
4852 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4853 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4854 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4855 "#"
4856 [(set_attr "type" "fistp")])
4857
4858 (define_insn "fix_truncsi_memory"
4859 [(set (match_operand:SI 0 "memory_operand" "=m")
4860 (fix:SI (match_operand 1 "register_operand" "f")))
4861 (use (match_operand:HI 2 "memory_operand" "m"))
4862 (use (match_operand:HI 3 "memory_operand" "m"))]
4863 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4864 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4865 "* return output_fix_trunc (insn, operands);"
4866 [(set_attr "type" "fistp")])
4867
4868 ;; When SSE available, it is always faster to use it!
4869 (define_insn "fix_truncsfsi_sse"
4870 [(set (match_operand:SI 0 "register_operand" "=r")
4871 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4872 "TARGET_SSE"
4873 "cvttss2si\t{%1, %0|%0, %1}"
4874 [(set_attr "type" "sse")])
4875
4876 (define_insn "fix_truncdfsi_sse"
4877 [(set (match_operand:SI 0 "register_operand" "=r")
4878 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4879 "TARGET_SSE2"
4880 "cvttsd2si\t{%1, %0|%0, %1}"
4881 [(set_attr "type" "sse")])
4882
4883 (define_split
4884 [(set (match_operand:SI 0 "register_operand" "")
4885 (fix:SI (match_operand 1 "register_operand" "")))
4886 (use (match_operand:HI 2 "memory_operand" ""))
4887 (use (match_operand:HI 3 "memory_operand" ""))
4888 (clobber (match_operand:SI 4 "memory_operand" ""))]
4889 "reload_completed"
4890 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4891 (use (match_dup 2))
4892 (use (match_dup 3))])
4893 (set (match_dup 0) (match_dup 4))]
4894 "")
4895
4896 (define_split
4897 [(set (match_operand:SI 0 "memory_operand" "")
4898 (fix:SI (match_operand 1 "register_operand" "")))
4899 (use (match_operand:HI 2 "memory_operand" ""))
4900 (use (match_operand:HI 3 "memory_operand" ""))
4901 (clobber (match_operand:SI 4 "memory_operand" ""))]
4902 "reload_completed"
4903 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4904 (use (match_dup 2))
4905 (use (match_dup 3))])]
4906 "")
4907
4908 ;; Signed conversion to HImode.
4909
4910 (define_expand "fix_truncxfhi2"
4911 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4912 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4913 "!TARGET_64BIT && TARGET_80387"
4914 "")
4915
4916 (define_expand "fix_trunctfhi2"
4917 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4918 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4919 "TARGET_80387"
4920 "")
4921
4922 (define_expand "fix_truncdfhi2"
4923 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4924 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4925 "TARGET_80387 && !TARGET_SSE2"
4926 "")
4927
4928 (define_expand "fix_truncsfhi2"
4929 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4930 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4931 "TARGET_80387 && !TARGET_SSE"
4932 "")
4933
4934 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4935 ;; of the machinery.
4936 (define_insn_and_split "*fix_trunchi_1"
4937 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4938 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4939 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4940 && !reload_completed && !reload_in_progress
4941 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4942 "#"
4943 ""
4944 [(const_int 0)]
4945 {
4946 operands[2] = assign_386_stack_local (HImode, 1);
4947 operands[3] = assign_386_stack_local (HImode, 2);
4948 if (memory_operand (operands[0], VOIDmode))
4949 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4950 operands[2], operands[3]));
4951 else
4952 {
4953 operands[4] = assign_386_stack_local (HImode, 0);
4954 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4955 operands[2], operands[3],
4956 operands[4]));
4957 }
4958 DONE;
4959 }
4960 [(set_attr "type" "fistp")])
4961
4962 (define_insn "fix_trunchi_nomemory"
4963 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4964 (fix:HI (match_operand 1 "register_operand" "f,f")))
4965 (use (match_operand:HI 2 "memory_operand" "m,m"))
4966 (use (match_operand:HI 3 "memory_operand" "m,m"))
4967 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4968 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4969 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4970 "#"
4971 [(set_attr "type" "fistp")])
4972
4973 (define_insn "fix_trunchi_memory"
4974 [(set (match_operand:HI 0 "memory_operand" "=m")
4975 (fix:HI (match_operand 1 "register_operand" "f")))
4976 (use (match_operand:HI 2 "memory_operand" "m"))
4977 (use (match_operand:HI 3 "memory_operand" "m"))]
4978 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4979 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4980 "* return output_fix_trunc (insn, operands);"
4981 [(set_attr "type" "fistp")])
4982
4983 (define_split
4984 [(set (match_operand:HI 0 "memory_operand" "")
4985 (fix:HI (match_operand 1 "register_operand" "")))
4986 (use (match_operand:HI 2 "memory_operand" ""))
4987 (use (match_operand:HI 3 "memory_operand" ""))
4988 (clobber (match_operand:HI 4 "memory_operand" ""))]
4989 "reload_completed"
4990 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4991 (use (match_dup 2))
4992 (use (match_dup 3))])]
4993 "")
4994
4995 (define_split
4996 [(set (match_operand:HI 0 "register_operand" "")
4997 (fix:HI (match_operand 1 "register_operand" "")))
4998 (use (match_operand:HI 2 "memory_operand" ""))
4999 (use (match_operand:HI 3 "memory_operand" ""))
5000 (clobber (match_operand:HI 4 "memory_operand" ""))]
5001 "reload_completed"
5002 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5003 (use (match_dup 2))
5004 (use (match_dup 3))
5005 (clobber (match_dup 4))])
5006 (set (match_dup 0) (match_dup 4))]
5007 "")
5008
5009 ;; %% Not used yet.
5010 (define_insn "x86_fnstcw_1"
5011 [(set (match_operand:HI 0 "memory_operand" "=m")
5012 (unspec:HI [(reg:HI 18)] 11))]
5013 "TARGET_80387"
5014 "fnstcw\t%0"
5015 [(set_attr "length" "2")
5016 (set_attr "mode" "HI")
5017 (set_attr "i387" "1")
5018 (set_attr "ppro_uops" "few")])
5019
5020 (define_insn "x86_fldcw_1"
5021 [(set (reg:HI 18)
5022 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
5023 "TARGET_80387"
5024 "fldcw\t%0"
5025 [(set_attr "length" "2")
5026 (set_attr "mode" "HI")
5027 (set_attr "i387" "1")
5028 (set_attr "athlon_decode" "vector")
5029 (set_attr "ppro_uops" "few")])
5030 \f
5031 ;; Conversion between fixed point and floating point.
5032
5033 ;; Even though we only accept memory inputs, the backend _really_
5034 ;; wants to be able to do this between registers.
5035
5036 (define_insn "floathisf2"
5037 [(set (match_operand:SF 0 "register_operand" "=f,f")
5038 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5039 "TARGET_80387 && !TARGET_SSE"
5040 "@
5041 fild%z1\t%1
5042 #"
5043 [(set_attr "type" "fmov,multi")
5044 (set_attr "mode" "SF")
5045 (set_attr "fp_int_src" "true")])
5046
5047 (define_expand "floatsisf2"
5048 [(set (match_operand:SF 0 "register_operand" "")
5049 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5050 "TARGET_SSE || TARGET_80387"
5051 "")
5052
5053 (define_insn "*floatsisf2_i387"
5054 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5055 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5056 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5057 "@
5058 fild%z1\t%1
5059 #
5060 cvtsi2ss\t{%1, %0|%0, %1}"
5061 [(set_attr "type" "fmov,multi,sse")
5062 (set_attr "mode" "SF")
5063 (set_attr "fp_int_src" "true")])
5064
5065 (define_insn "*floatsisf2_sse"
5066 [(set (match_operand:SF 0 "register_operand" "=x")
5067 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5068 "TARGET_SSE"
5069 "cvtsi2ss\t{%1, %0|%0, %1}"
5070 [(set_attr "type" "sse")
5071 (set_attr "mode" "SF")
5072 (set_attr "fp_int_src" "true")])
5073
5074 (define_expand "floatdisf2"
5075 [(set (match_operand:SF 0 "register_operand" "")
5076 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5077 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
5078 "")
5079
5080 (define_insn "*floatdisf2_i387_only"
5081 [(set (match_operand:SF 0 "register_operand" "=f,?f")
5082 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5083 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5084 "@
5085 fild%z1\t%1
5086 #"
5087 [(set_attr "type" "fmov,multi")
5088 (set_attr "mode" "SF")
5089 (set_attr "fp_int_src" "true")])
5090
5091 (define_insn "*floatdisf2_i387"
5092 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5093 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5094 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5095 "@
5096 fild%z1\t%1
5097 #
5098 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5099 [(set_attr "type" "fmov,multi,sse")
5100 (set_attr "mode" "SF")
5101 (set_attr "fp_int_src" "true")])
5102
5103 (define_insn "*floatdisf2_sse"
5104 [(set (match_operand:SF 0 "register_operand" "=x")
5105 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5106 "TARGET_64BIT && TARGET_SSE"
5107 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5108 [(set_attr "type" "sse")
5109 (set_attr "mode" "SF")
5110 (set_attr "fp_int_src" "true")])
5111
5112 (define_insn "floathidf2"
5113 [(set (match_operand:DF 0 "register_operand" "=f,f")
5114 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5115 "TARGET_80387 && !TARGET_SSE2"
5116 "@
5117 fild%z1\t%1
5118 #"
5119 [(set_attr "type" "fmov,multi")
5120 (set_attr "mode" "DF")
5121 (set_attr "fp_int_src" "true")])
5122
5123 (define_expand "floatsidf2"
5124 [(set (match_operand:DF 0 "register_operand" "")
5125 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5126 ""
5127 "")
5128
5129 (define_insn "*floatsidf2_i387"
5130 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5131 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5132 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5133 "@
5134 fild%z1\t%1
5135 #
5136 cvtsi2sd\t{%1, %0|%0, %1}"
5137 [(set_attr "type" "fmov,multi,sse")
5138 (set_attr "mode" "DF")
5139 (set_attr "fp_int_src" "true")])
5140
5141 (define_insn "*floatsidf2_sse"
5142 [(set (match_operand:DF 0 "register_operand" "=Y")
5143 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5144 "TARGET_SSE2"
5145 "cvtsi2sd\t{%1, %0|%0, %1}"
5146 [(set_attr "type" "sse")
5147 (set_attr "mode" "DF")
5148 (set_attr "fp_int_src" "true")])
5149
5150 (define_expand "floatdidf2"
5151 [(set (match_operand:DF 0 "register_operand" "")
5152 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5153 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5154 "")
5155
5156 (define_insn "*floatdidf2_i387_only"
5157 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5158 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5159 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5160 "@
5161 fild%z1\t%1
5162 #"
5163 [(set_attr "type" "fmov,multi")
5164 (set_attr "mode" "DF")
5165 (set_attr "fp_int_src" "true")])
5166
5167 (define_insn "*floatdidf2_i387"
5168 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5169 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5170 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5171 "@
5172 fild%z1\t%1
5173 #
5174 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5175 [(set_attr "type" "fmov,multi,sse")
5176 (set_attr "mode" "DF")
5177 (set_attr "fp_int_src" "true")])
5178
5179 (define_insn "*floatdidf2_sse"
5180 [(set (match_operand:DF 0 "register_operand" "=Y")
5181 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5182 "TARGET_SSE2"
5183 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5184 [(set_attr "type" "sse")
5185 (set_attr "mode" "DF")
5186 (set_attr "fp_int_src" "true")])
5187
5188 (define_insn "floathixf2"
5189 [(set (match_operand:XF 0 "register_operand" "=f,f")
5190 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5191 "!TARGET_64BIT && TARGET_80387"
5192 "@
5193 fild%z1\t%1
5194 #"
5195 [(set_attr "type" "fmov,multi")
5196 (set_attr "mode" "XF")
5197 (set_attr "fp_int_src" "true")])
5198
5199 (define_insn "floathitf2"
5200 [(set (match_operand:TF 0 "register_operand" "=f,f")
5201 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5202 "TARGET_80387"
5203 "@
5204 fild%z1\t%1
5205 #"
5206 [(set_attr "type" "fmov,multi")
5207 (set_attr "mode" "XF")
5208 (set_attr "fp_int_src" "true")])
5209
5210 (define_insn "floatsixf2"
5211 [(set (match_operand:XF 0 "register_operand" "=f,f")
5212 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5213 "!TARGET_64BIT && TARGET_80387"
5214 "@
5215 fild%z1\t%1
5216 #"
5217 [(set_attr "type" "fmov,multi")
5218 (set_attr "mode" "XF")
5219 (set_attr "fp_int_src" "true")])
5220
5221 (define_insn "floatsitf2"
5222 [(set (match_operand:TF 0 "register_operand" "=f,f")
5223 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5224 "TARGET_80387"
5225 "@
5226 fild%z1\t%1
5227 #"
5228 [(set_attr "type" "fmov,multi")
5229 (set_attr "mode" "XF")
5230 (set_attr "fp_int_src" "true")])
5231
5232 (define_insn "floatdixf2"
5233 [(set (match_operand:XF 0 "register_operand" "=f,f")
5234 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5235 "!TARGET_64BIT && TARGET_80387"
5236 "@
5237 fild%z1\t%1
5238 #"
5239 [(set_attr "type" "fmov,multi")
5240 (set_attr "mode" "XF")
5241 (set_attr "fp_int_src" "true")])
5242
5243 (define_insn "floatditf2"
5244 [(set (match_operand:TF 0 "register_operand" "=f,f")
5245 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5246 "TARGET_80387"
5247 "@
5248 fild%z1\t%1
5249 #"
5250 [(set_attr "type" "fmov,multi")
5251 (set_attr "mode" "XF")
5252 (set_attr "fp_int_src" "true")])
5253
5254 ;; %%% Kill these when reload knows how to do it.
5255 (define_split
5256 [(set (match_operand 0 "register_operand" "")
5257 (float (match_operand 1 "register_operand" "")))]
5258 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5259 && FP_REG_P (operands[0])"
5260 [(const_int 0)]
5261 {
5262 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5263 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5265 ix86_free_from_memory (GET_MODE (operands[1]));
5266 DONE;
5267 })
5268 \f
5269 ;; Add instructions
5270
5271 ;; %%% splits for addsidi3
5272 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5273 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5274 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5275
5276 (define_expand "adddi3"
5277 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5278 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5279 (match_operand:DI 2 "x86_64_general_operand" "")))
5280 (clobber (reg:CC 17))]
5281 ""
5282 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5283
5284 (define_insn "*adddi3_1"
5285 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5286 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5287 (match_operand:DI 2 "general_operand" "roiF,riF")))
5288 (clobber (reg:CC 17))]
5289 "!TARGET_64BIT"
5290 "#")
5291
5292 (define_split
5293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5294 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5295 (match_operand:DI 2 "general_operand" "")))
5296 (clobber (reg:CC 17))]
5297 "!TARGET_64BIT && reload_completed"
5298 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5299 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5300 (parallel [(set (match_dup 3)
5301 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5302 (match_dup 4))
5303 (match_dup 5)))
5304 (clobber (reg:CC 17))])]
5305 "split_di (operands+0, 1, operands+0, operands+3);
5306 split_di (operands+1, 1, operands+1, operands+4);
5307 split_di (operands+2, 1, operands+2, operands+5);")
5308
5309 (define_insn "*adddi3_carry_rex64"
5310 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5311 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5312 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5313 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5314 (clobber (reg:CC 17))]
5315 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5316 "adc{q}\t{%2, %0|%0, %2}"
5317 [(set_attr "type" "alu")
5318 (set_attr "pent_pair" "pu")
5319 (set_attr "mode" "DI")
5320 (set_attr "ppro_uops" "few")])
5321
5322 (define_insn "*adddi3_cc_rex64"
5323 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5324 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5325 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5326 (plus:DI (match_dup 1) (match_dup 2)))]
5327 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5328 "add{q}\t{%2, %0|%0, %2}"
5329 [(set_attr "type" "alu")
5330 (set_attr "mode" "DI")])
5331
5332 (define_insn "*addsi3_carry"
5333 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5334 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5335 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5336 (match_operand:SI 2 "general_operand" "ri,rm")))
5337 (clobber (reg:CC 17))]
5338 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5339 "adc{l}\t{%2, %0|%0, %2}"
5340 [(set_attr "type" "alu")
5341 (set_attr "pent_pair" "pu")
5342 (set_attr "mode" "SI")
5343 (set_attr "ppro_uops" "few")])
5344
5345 (define_insn "*addsi3_carry_zext"
5346 [(set (match_operand:DI 0 "register_operand" "=r")
5347 (zero_extend:DI
5348 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5349 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5350 (match_operand:SI 2 "general_operand" "rim"))))
5351 (clobber (reg:CC 17))]
5352 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5353 "adc{l}\t{%2, %k0|%k0, %2}"
5354 [(set_attr "type" "alu")
5355 (set_attr "pent_pair" "pu")
5356 (set_attr "mode" "SI")
5357 (set_attr "ppro_uops" "few")])
5358
5359 (define_insn "*addsi3_cc"
5360 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5361 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5362 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5363 (plus:SI (match_dup 1) (match_dup 2)))]
5364 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5365 "add{l}\t{%2, %0|%0, %2}"
5366 [(set_attr "type" "alu")
5367 (set_attr "mode" "SI")])
5368
5369 (define_insn "addqi3_cc"
5370 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5371 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5372 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5373 (plus:QI (match_dup 1) (match_dup 2)))]
5374 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5375 "add{b}\t{%2, %0|%0, %2}"
5376 [(set_attr "type" "alu")
5377 (set_attr "mode" "QI")])
5378
5379 (define_expand "addsi3"
5380 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5381 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5382 (match_operand:SI 2 "general_operand" "")))
5383 (clobber (reg:CC 17))])]
5384 ""
5385 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5386
5387 (define_insn "*lea_1"
5388 [(set (match_operand:SI 0 "register_operand" "=r")
5389 (match_operand:SI 1 "address_operand" "p"))]
5390 "!TARGET_64BIT"
5391 "lea{l}\t{%a1, %0|%0, %a1}"
5392 [(set_attr "type" "lea")
5393 (set_attr "mode" "SI")])
5394
5395 (define_insn "*lea_1_rex64"
5396 [(set (match_operand:SI 0 "register_operand" "=r")
5397 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5398 "TARGET_64BIT"
5399 "lea{l}\t{%a1, %0|%0, %a1}"
5400 [(set_attr "type" "lea")
5401 (set_attr "mode" "SI")])
5402
5403 (define_insn "*lea_1_zext"
5404 [(set (match_operand:DI 0 "register_operand" "=r")
5405 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5406 "TARGET_64BIT"
5407 "lea{l}\t{%a1, %k0|%k0, %a1}"
5408 [(set_attr "type" "lea")
5409 (set_attr "mode" "SI")])
5410
5411 (define_insn "*lea_2_rex64"
5412 [(set (match_operand:DI 0 "register_operand" "=r")
5413 (match_operand:DI 1 "address_operand" "p"))]
5414 "TARGET_64BIT"
5415 "lea{q}\t{%a1, %0|%0, %a1}"
5416 [(set_attr "type" "lea")
5417 (set_attr "mode" "DI")])
5418
5419 ;; The lea patterns for non-Pmodes needs to be matched by several
5420 ;; insns converted to real lea by splitters.
5421
5422 (define_insn_and_split "*lea_general_1"
5423 [(set (match_operand 0 "register_operand" "=r")
5424 (plus (plus (match_operand 1 "register_operand" "r")
5425 (match_operand 2 "register_operand" "r"))
5426 (match_operand 3 "immediate_operand" "i")))]
5427 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5428 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5429 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5430 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5431 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5432 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5433 || GET_MODE (operands[3]) == VOIDmode)"
5434 "#"
5435 "&& reload_completed"
5436 [(const_int 0)]
5437 {
5438 rtx pat;
5439 operands[0] = gen_lowpart (SImode, operands[0]);
5440 operands[1] = gen_lowpart (Pmode, operands[1]);
5441 operands[2] = gen_lowpart (Pmode, operands[2]);
5442 operands[3] = gen_lowpart (Pmode, operands[3]);
5443 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5444 operands[3]);
5445 if (Pmode != SImode)
5446 pat = gen_rtx_SUBREG (SImode, pat, 0);
5447 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5448 DONE;
5449 }
5450 [(set_attr "type" "lea")
5451 (set_attr "mode" "SI")])
5452
5453 (define_insn_and_split "*lea_general_1_zext"
5454 [(set (match_operand:DI 0 "register_operand" "=r")
5455 (zero_extend:DI
5456 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5457 (match_operand:SI 2 "register_operand" "r"))
5458 (match_operand:SI 3 "immediate_operand" "i"))))]
5459 "TARGET_64BIT"
5460 "#"
5461 "&& reload_completed"
5462 [(set (match_dup 0)
5463 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5464 (match_dup 2))
5465 (match_dup 3)) 0)))]
5466 {
5467 operands[1] = gen_lowpart (Pmode, operands[1]);
5468 operands[2] = gen_lowpart (Pmode, operands[2]);
5469 operands[3] = gen_lowpart (Pmode, operands[3]);
5470 }
5471 [(set_attr "type" "lea")
5472 (set_attr "mode" "SI")])
5473
5474 (define_insn_and_split "*lea_general_2"
5475 [(set (match_operand 0 "register_operand" "=r")
5476 (plus (mult (match_operand 1 "register_operand" "r")
5477 (match_operand 2 "const248_operand" "i"))
5478 (match_operand 3 "nonmemory_operand" "ri")))]
5479 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5480 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5481 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5482 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5483 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5484 || GET_MODE (operands[3]) == VOIDmode)"
5485 "#"
5486 "&& reload_completed"
5487 [(const_int 0)]
5488 {
5489 rtx pat;
5490 operands[0] = gen_lowpart (SImode, operands[0]);
5491 operands[1] = gen_lowpart (Pmode, operands[1]);
5492 operands[3] = gen_lowpart (Pmode, operands[3]);
5493 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5494 operands[3]);
5495 if (Pmode != SImode)
5496 pat = gen_rtx_SUBREG (SImode, pat, 0);
5497 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5498 DONE;
5499 }
5500 [(set_attr "type" "lea")
5501 (set_attr "mode" "SI")])
5502
5503 (define_insn_and_split "*lea_general_2_zext"
5504 [(set (match_operand:DI 0 "register_operand" "=r")
5505 (zero_extend:DI
5506 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5507 (match_operand:SI 2 "const248_operand" "n"))
5508 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5509 "TARGET_64BIT"
5510 "#"
5511 "&& reload_completed"
5512 [(set (match_dup 0)
5513 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5514 (match_dup 2))
5515 (match_dup 3)) 0)))]
5516 {
5517 operands[1] = gen_lowpart (Pmode, operands[1]);
5518 operands[3] = gen_lowpart (Pmode, operands[3]);
5519 }
5520 [(set_attr "type" "lea")
5521 (set_attr "mode" "SI")])
5522
5523 (define_insn_and_split "*lea_general_3"
5524 [(set (match_operand 0 "register_operand" "=r")
5525 (plus (plus (mult (match_operand 1 "register_operand" "r")
5526 (match_operand 2 "const248_operand" "i"))
5527 (match_operand 3 "register_operand" "r"))
5528 (match_operand 4 "immediate_operand" "i")))]
5529 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5530 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5531 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5532 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5533 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5534 "#"
5535 "&& reload_completed"
5536 [(const_int 0)]
5537 {
5538 rtx pat;
5539 operands[0] = gen_lowpart (SImode, operands[0]);
5540 operands[1] = gen_lowpart (Pmode, operands[1]);
5541 operands[3] = gen_lowpart (Pmode, operands[3]);
5542 operands[4] = gen_lowpart (Pmode, operands[4]);
5543 pat = gen_rtx_PLUS (Pmode,
5544 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5545 operands[2]),
5546 operands[3]),
5547 operands[4]);
5548 if (Pmode != SImode)
5549 pat = gen_rtx_SUBREG (SImode, pat, 0);
5550 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5551 DONE;
5552 }
5553 [(set_attr "type" "lea")
5554 (set_attr "mode" "SI")])
5555
5556 (define_insn_and_split "*lea_general_3_zext"
5557 [(set (match_operand:DI 0 "register_operand" "=r")
5558 (zero_extend:DI
5559 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5560 (match_operand:SI 2 "const248_operand" "n"))
5561 (match_operand:SI 3 "register_operand" "r"))
5562 (match_operand:SI 4 "immediate_operand" "i"))))]
5563 "TARGET_64BIT"
5564 "#"
5565 "&& reload_completed"
5566 [(set (match_dup 0)
5567 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5568 (match_dup 2))
5569 (match_dup 3))
5570 (match_dup 4)) 0)))]
5571 {
5572 operands[1] = gen_lowpart (Pmode, operands[1]);
5573 operands[3] = gen_lowpart (Pmode, operands[3]);
5574 operands[4] = gen_lowpart (Pmode, operands[4]);
5575 }
5576 [(set_attr "type" "lea")
5577 (set_attr "mode" "SI")])
5578
5579 (define_insn "*adddi_1_rex64"
5580 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5581 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5582 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5583 (clobber (reg:CC 17))]
5584 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5585 {
5586 switch (get_attr_type (insn))
5587 {
5588 case TYPE_LEA:
5589 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5590 return "lea{q}\t{%a2, %0|%0, %a2}";
5591
5592 case TYPE_INCDEC:
5593 if (! rtx_equal_p (operands[0], operands[1]))
5594 abort ();
5595 if (operands[2] == const1_rtx)
5596 return "inc{q}\t%0";
5597 else if (operands[2] == constm1_rtx)
5598 return "dec{q}\t%0";
5599 else
5600 abort ();
5601
5602 default:
5603 if (! rtx_equal_p (operands[0], operands[1]))
5604 abort ();
5605
5606 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5607 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5608 if (GET_CODE (operands[2]) == CONST_INT
5609 /* Avoid overflows. */
5610 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5611 && (INTVAL (operands[2]) == 128
5612 || (INTVAL (operands[2]) < 0
5613 && INTVAL (operands[2]) != -128)))
5614 {
5615 operands[2] = GEN_INT (-INTVAL (operands[2]));
5616 return "sub{q}\t{%2, %0|%0, %2}";
5617 }
5618 return "add{q}\t{%2, %0|%0, %2}";
5619 }
5620 }
5621 [(set (attr "type")
5622 (cond [(eq_attr "alternative" "2")
5623 (const_string "lea")
5624 ; Current assemblers are broken and do not allow @GOTOFF in
5625 ; ought but a memory context.
5626 (match_operand:DI 2 "pic_symbolic_operand" "")
5627 (const_string "lea")
5628 (match_operand:DI 2 "incdec_operand" "")
5629 (const_string "incdec")
5630 ]
5631 (const_string "alu")))
5632 (set_attr "mode" "DI")])
5633
5634 ;; Convert lea to the lea pattern to avoid flags dependency.
5635 (define_split
5636 [(set (match_operand:DI 0 "register_operand" "")
5637 (plus:DI (match_operand:DI 1 "register_operand" "")
5638 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5639 (clobber (reg:CC 17))]
5640 "TARGET_64BIT && reload_completed
5641 && true_regnum (operands[0]) != true_regnum (operands[1])"
5642 [(set (match_dup 0)
5643 (plus:DI (match_dup 1)
5644 (match_dup 2)))]
5645 "")
5646
5647 (define_insn "*adddi_2_rex64"
5648 [(set (reg 17)
5649 (compare
5650 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5651 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5652 (const_int 0)))
5653 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5654 (plus:DI (match_dup 1) (match_dup 2)))]
5655 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5656 && ix86_binary_operator_ok (PLUS, DImode, operands)
5657 /* Current assemblers are broken and do not allow @GOTOFF in
5658 ought but a memory context. */
5659 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5660 {
5661 switch (get_attr_type (insn))
5662 {
5663 case TYPE_INCDEC:
5664 if (! rtx_equal_p (operands[0], operands[1]))
5665 abort ();
5666 if (operands[2] == const1_rtx)
5667 return "inc{q}\t%0";
5668 else if (operands[2] == constm1_rtx)
5669 return "dec{q}\t%0";
5670 else
5671 abort ();
5672
5673 default:
5674 if (! rtx_equal_p (operands[0], operands[1]))
5675 abort ();
5676 /* ???? We ought to handle there the 32bit case too
5677 - do we need new constrant? */
5678 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5679 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5680 if (GET_CODE (operands[2]) == CONST_INT
5681 /* Avoid overflows. */
5682 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5683 && (INTVAL (operands[2]) == 128
5684 || (INTVAL (operands[2]) < 0
5685 && INTVAL (operands[2]) != -128)))
5686 {
5687 operands[2] = GEN_INT (-INTVAL (operands[2]));
5688 return "sub{q}\t{%2, %0|%0, %2}";
5689 }
5690 return "add{q}\t{%2, %0|%0, %2}";
5691 }
5692 }
5693 [(set (attr "type")
5694 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5695 (const_string "incdec")
5696 (const_string "alu")))
5697 (set_attr "mode" "DI")])
5698
5699 (define_insn "*adddi_3_rex64"
5700 [(set (reg 17)
5701 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5702 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5703 (clobber (match_scratch:DI 0 "=r"))]
5704 "TARGET_64BIT
5705 && ix86_match_ccmode (insn, CCZmode)
5706 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5707 /* Current assemblers are broken and do not allow @GOTOFF in
5708 ought but a memory context. */
5709 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5710 {
5711 switch (get_attr_type (insn))
5712 {
5713 case TYPE_INCDEC:
5714 if (! rtx_equal_p (operands[0], operands[1]))
5715 abort ();
5716 if (operands[2] == const1_rtx)
5717 return "inc{q}\t%0";
5718 else if (operands[2] == constm1_rtx)
5719 return "dec{q}\t%0";
5720 else
5721 abort ();
5722
5723 default:
5724 if (! rtx_equal_p (operands[0], operands[1]))
5725 abort ();
5726 /* ???? We ought to handle there the 32bit case too
5727 - do we need new constrant? */
5728 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5730 if (GET_CODE (operands[2]) == CONST_INT
5731 /* Avoid overflows. */
5732 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5733 && (INTVAL (operands[2]) == 128
5734 || (INTVAL (operands[2]) < 0
5735 && INTVAL (operands[2]) != -128)))
5736 {
5737 operands[2] = GEN_INT (-INTVAL (operands[2]));
5738 return "sub{q}\t{%2, %0|%0, %2}";
5739 }
5740 return "add{q}\t{%2, %0|%0, %2}";
5741 }
5742 }
5743 [(set (attr "type")
5744 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5745 (const_string "incdec")
5746 (const_string "alu")))
5747 (set_attr "mode" "DI")])
5748
5749 ; For comparisons against 1, -1 and 128, we may generate better code
5750 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5751 ; is matched then. We can't accept general immediate, because for
5752 ; case of overflows, the result is messed up.
5753 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5754 ; when negated.
5755 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5756 ; only for comparisons not depending on it.
5757 (define_insn "*adddi_4_rex64"
5758 [(set (reg 17)
5759 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5760 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5761 (clobber (match_scratch:DI 0 "=rm"))]
5762 "TARGET_64BIT
5763 && ix86_match_ccmode (insn, CCGCmode)"
5764 {
5765 switch (get_attr_type (insn))
5766 {
5767 case TYPE_INCDEC:
5768 if (operands[2] == constm1_rtx)
5769 return "inc{q}\t%0";
5770 else if (operands[2] == const1_rtx)
5771 return "dec{q}\t%0";
5772 else
5773 abort();
5774
5775 default:
5776 if (! rtx_equal_p (operands[0], operands[1]))
5777 abort ();
5778 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5780 if ((INTVAL (operands[2]) == -128
5781 || (INTVAL (operands[2]) > 0
5782 && INTVAL (operands[2]) != 128))
5783 /* Avoid overflows. */
5784 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5785 return "sub{q}\t{%2, %0|%0, %2}";
5786 operands[2] = GEN_INT (-INTVAL (operands[2]));
5787 return "add{q}\t{%2, %0|%0, %2}";
5788 }
5789 }
5790 [(set (attr "type")
5791 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5792 (const_string "incdec")
5793 (const_string "alu")))
5794 (set_attr "mode" "DI")])
5795
5796 (define_insn "*adddi_5_rex64"
5797 [(set (reg 17)
5798 (compare
5799 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5800 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5801 (const_int 0)))
5802 (clobber (match_scratch:DI 0 "=r"))]
5803 "TARGET_64BIT
5804 && ix86_match_ccmode (insn, CCGOCmode)
5805 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5806 /* Current assemblers are broken and do not allow @GOTOFF in
5807 ought but a memory context. */
5808 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5809 {
5810 switch (get_attr_type (insn))
5811 {
5812 case TYPE_INCDEC:
5813 if (! rtx_equal_p (operands[0], operands[1]))
5814 abort ();
5815 if (operands[2] == const1_rtx)
5816 return "inc{q}\t%0";
5817 else if (operands[2] == constm1_rtx)
5818 return "dec{q}\t%0";
5819 else
5820 abort();
5821
5822 default:
5823 if (! rtx_equal_p (operands[0], operands[1]))
5824 abort ();
5825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5827 if (GET_CODE (operands[2]) == CONST_INT
5828 /* Avoid overflows. */
5829 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5830 && (INTVAL (operands[2]) == 128
5831 || (INTVAL (operands[2]) < 0
5832 && INTVAL (operands[2]) != -128)))
5833 {
5834 operands[2] = GEN_INT (-INTVAL (operands[2]));
5835 return "sub{q}\t{%2, %0|%0, %2}";
5836 }
5837 return "add{q}\t{%2, %0|%0, %2}";
5838 }
5839 }
5840 [(set (attr "type")
5841 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5842 (const_string "incdec")
5843 (const_string "alu")))
5844 (set_attr "mode" "DI")])
5845
5846
5847 (define_insn "*addsi_1"
5848 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5849 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5850 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5851 (clobber (reg:CC 17))]
5852 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5853 {
5854 switch (get_attr_type (insn))
5855 {
5856 case TYPE_LEA:
5857 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5858 return "lea{l}\t{%a2, %0|%0, %a2}";
5859
5860 case TYPE_INCDEC:
5861 if (! rtx_equal_p (operands[0], operands[1]))
5862 abort ();
5863 if (operands[2] == const1_rtx)
5864 return "inc{l}\t%0";
5865 else if (operands[2] == constm1_rtx)
5866 return "dec{l}\t%0";
5867 else
5868 abort();
5869
5870 default:
5871 if (! rtx_equal_p (operands[0], operands[1]))
5872 abort ();
5873
5874 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5875 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5876 if (GET_CODE (operands[2]) == CONST_INT
5877 && (INTVAL (operands[2]) == 128
5878 || (INTVAL (operands[2]) < 0
5879 && INTVAL (operands[2]) != -128)))
5880 {
5881 operands[2] = GEN_INT (-INTVAL (operands[2]));
5882 return "sub{l}\t{%2, %0|%0, %2}";
5883 }
5884 return "add{l}\t{%2, %0|%0, %2}";
5885 }
5886 }
5887 [(set (attr "type")
5888 (cond [(eq_attr "alternative" "2")
5889 (const_string "lea")
5890 ; Current assemblers are broken and do not allow @GOTOFF in
5891 ; ought but a memory context.
5892 (match_operand:SI 2 "pic_symbolic_operand" "")
5893 (const_string "lea")
5894 (match_operand:SI 2 "incdec_operand" "")
5895 (const_string "incdec")
5896 ]
5897 (const_string "alu")))
5898 (set_attr "mode" "SI")])
5899
5900 ;; Convert lea to the lea pattern to avoid flags dependency.
5901 (define_split
5902 [(set (match_operand 0 "register_operand" "")
5903 (plus (match_operand 1 "register_operand" "")
5904 (match_operand 2 "nonmemory_operand" "")))
5905 (clobber (reg:CC 17))]
5906 "reload_completed
5907 && true_regnum (operands[0]) != true_regnum (operands[1])"
5908 [(const_int 0)]
5909 {
5910 rtx pat;
5911 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5912 may confuse gen_lowpart. */
5913 if (GET_MODE (operands[0]) != Pmode)
5914 {
5915 operands[1] = gen_lowpart (Pmode, operands[1]);
5916 operands[2] = gen_lowpart (Pmode, operands[2]);
5917 }
5918 operands[0] = gen_lowpart (SImode, operands[0]);
5919 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5920 if (Pmode != SImode)
5921 pat = gen_rtx_SUBREG (SImode, pat, 0);
5922 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5923 DONE;
5924 })
5925
5926 ;; It may seem that nonimmediate operand is proper one for operand 1.
5927 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5928 ;; we take care in ix86_binary_operator_ok to not allow two memory
5929 ;; operands so proper swapping will be done in reload. This allow
5930 ;; patterns constructed from addsi_1 to match.
5931 (define_insn "addsi_1_zext"
5932 [(set (match_operand:DI 0 "register_operand" "=r,r")
5933 (zero_extend:DI
5934 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5935 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5936 (clobber (reg:CC 17))]
5937 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5938 {
5939 switch (get_attr_type (insn))
5940 {
5941 case TYPE_LEA:
5942 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5943 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5944
5945 case TYPE_INCDEC:
5946 if (operands[2] == const1_rtx)
5947 return "inc{l}\t%k0";
5948 else if (operands[2] == constm1_rtx)
5949 return "dec{l}\t%k0";
5950 else
5951 abort();
5952
5953 default:
5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5956 if (GET_CODE (operands[2]) == CONST_INT
5957 && (INTVAL (operands[2]) == 128
5958 || (INTVAL (operands[2]) < 0
5959 && INTVAL (operands[2]) != -128)))
5960 {
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "sub{l}\t{%2, %k0|%k0, %2}";
5963 }
5964 return "add{l}\t{%2, %k0|%k0, %2}";
5965 }
5966 }
5967 [(set (attr "type")
5968 (cond [(eq_attr "alternative" "1")
5969 (const_string "lea")
5970 ; Current assemblers are broken and do not allow @GOTOFF in
5971 ; ought but a memory context.
5972 (match_operand:SI 2 "pic_symbolic_operand" "")
5973 (const_string "lea")
5974 (match_operand:SI 2 "incdec_operand" "")
5975 (const_string "incdec")
5976 ]
5977 (const_string "alu")))
5978 (set_attr "mode" "SI")])
5979
5980 ;; Convert lea to the lea pattern to avoid flags dependency.
5981 (define_split
5982 [(set (match_operand:DI 0 "register_operand" "")
5983 (zero_extend:DI
5984 (plus:SI (match_operand:SI 1 "register_operand" "")
5985 (match_operand:SI 2 "nonmemory_operand" ""))))
5986 (clobber (reg:CC 17))]
5987 "reload_completed
5988 && true_regnum (operands[0]) != true_regnum (operands[1])"
5989 [(set (match_dup 0)
5990 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5991 {
5992 operands[1] = gen_lowpart (Pmode, operands[1]);
5993 operands[2] = gen_lowpart (Pmode, operands[2]);
5994 })
5995
5996 (define_insn "*addsi_2"
5997 [(set (reg 17)
5998 (compare
5999 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6000 (match_operand:SI 2 "general_operand" "rmni,rni"))
6001 (const_int 0)))
6002 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6003 (plus:SI (match_dup 1) (match_dup 2)))]
6004 "ix86_match_ccmode (insn, CCGOCmode)
6005 && ix86_binary_operator_ok (PLUS, SImode, operands)
6006 /* Current assemblers are broken and do not allow @GOTOFF in
6007 ought but a memory context. */
6008 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6009 {
6010 switch (get_attr_type (insn))
6011 {
6012 case TYPE_INCDEC:
6013 if (! rtx_equal_p (operands[0], operands[1]))
6014 abort ();
6015 if (operands[2] == const1_rtx)
6016 return "inc{l}\t%0";
6017 else if (operands[2] == constm1_rtx)
6018 return "dec{l}\t%0";
6019 else
6020 abort();
6021
6022 default:
6023 if (! rtx_equal_p (operands[0], operands[1]))
6024 abort ();
6025 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6026 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6027 if (GET_CODE (operands[2]) == CONST_INT
6028 && (INTVAL (operands[2]) == 128
6029 || (INTVAL (operands[2]) < 0
6030 && INTVAL (operands[2]) != -128)))
6031 {
6032 operands[2] = GEN_INT (-INTVAL (operands[2]));
6033 return "sub{l}\t{%2, %0|%0, %2}";
6034 }
6035 return "add{l}\t{%2, %0|%0, %2}";
6036 }
6037 }
6038 [(set (attr "type")
6039 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6040 (const_string "incdec")
6041 (const_string "alu")))
6042 (set_attr "mode" "SI")])
6043
6044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6045 (define_insn "*addsi_2_zext"
6046 [(set (reg 17)
6047 (compare
6048 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6049 (match_operand:SI 2 "general_operand" "rmni"))
6050 (const_int 0)))
6051 (set (match_operand:DI 0 "register_operand" "=r")
6052 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6054 && ix86_binary_operator_ok (PLUS, SImode, operands)
6055 /* Current assemblers are broken and do not allow @GOTOFF in
6056 ought but a memory context. */
6057 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6058 {
6059 switch (get_attr_type (insn))
6060 {
6061 case TYPE_INCDEC:
6062 if (operands[2] == const1_rtx)
6063 return "inc{l}\t%k0";
6064 else if (operands[2] == constm1_rtx)
6065 return "dec{l}\t%k0";
6066 else
6067 abort();
6068
6069 default:
6070 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6071 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6072 if (GET_CODE (operands[2]) == CONST_INT
6073 && (INTVAL (operands[2]) == 128
6074 || (INTVAL (operands[2]) < 0
6075 && INTVAL (operands[2]) != -128)))
6076 {
6077 operands[2] = GEN_INT (-INTVAL (operands[2]));
6078 return "sub{l}\t{%2, %k0|%k0, %2}";
6079 }
6080 return "add{l}\t{%2, %k0|%k0, %2}";
6081 }
6082 }
6083 [(set (attr "type")
6084 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6085 (const_string "incdec")
6086 (const_string "alu")))
6087 (set_attr "mode" "SI")])
6088
6089 (define_insn "*addsi_3"
6090 [(set (reg 17)
6091 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6092 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6093 (clobber (match_scratch:SI 0 "=r"))]
6094 "ix86_match_ccmode (insn, CCZmode)
6095 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6096 /* Current assemblers are broken and do not allow @GOTOFF in
6097 ought but a memory context. */
6098 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6099 {
6100 switch (get_attr_type (insn))
6101 {
6102 case TYPE_INCDEC:
6103 if (! rtx_equal_p (operands[0], operands[1]))
6104 abort ();
6105 if (operands[2] == const1_rtx)
6106 return "inc{l}\t%0";
6107 else if (operands[2] == constm1_rtx)
6108 return "dec{l}\t%0";
6109 else
6110 abort();
6111
6112 default:
6113 if (! rtx_equal_p (operands[0], operands[1]))
6114 abort ();
6115 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6116 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6117 if (GET_CODE (operands[2]) == CONST_INT
6118 && (INTVAL (operands[2]) == 128
6119 || (INTVAL (operands[2]) < 0
6120 && INTVAL (operands[2]) != -128)))
6121 {
6122 operands[2] = GEN_INT (-INTVAL (operands[2]));
6123 return "sub{l}\t{%2, %0|%0, %2}";
6124 }
6125 return "add{l}\t{%2, %0|%0, %2}";
6126 }
6127 }
6128 [(set (attr "type")
6129 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6130 (const_string "incdec")
6131 (const_string "alu")))
6132 (set_attr "mode" "SI")])
6133
6134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6135 (define_insn "*addsi_3_zext"
6136 [(set (reg 17)
6137 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6138 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6139 (set (match_operand:DI 0 "register_operand" "=r")
6140 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6141 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6142 && ix86_binary_operator_ok (PLUS, SImode, operands)
6143 /* Current assemblers are broken and do not allow @GOTOFF in
6144 ought but a memory context. */
6145 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6146 {
6147 switch (get_attr_type (insn))
6148 {
6149 case TYPE_INCDEC:
6150 if (operands[2] == const1_rtx)
6151 return "inc{l}\t%k0";
6152 else if (operands[2] == constm1_rtx)
6153 return "dec{l}\t%k0";
6154 else
6155 abort();
6156
6157 default:
6158 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6159 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6160 if (GET_CODE (operands[2]) == CONST_INT
6161 && (INTVAL (operands[2]) == 128
6162 || (INTVAL (operands[2]) < 0
6163 && INTVAL (operands[2]) != -128)))
6164 {
6165 operands[2] = GEN_INT (-INTVAL (operands[2]));
6166 return "sub{l}\t{%2, %k0|%k0, %2}";
6167 }
6168 return "add{l}\t{%2, %k0|%k0, %2}";
6169 }
6170 }
6171 [(set (attr "type")
6172 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "mode" "SI")])
6176
6177 ; For comparisons agains 1, -1 and 128, we may generate better code
6178 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6179 ; is matched then. We can't accept general immediate, because for
6180 ; case of overflows, the result is messed up.
6181 ; This pattern also don't hold of 0x80000000, since the value overflows
6182 ; when negated.
6183 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6184 ; only for comparisons not depending on it.
6185 (define_insn "*addsi_4"
6186 [(set (reg 17)
6187 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6188 (match_operand:SI 2 "const_int_operand" "n")))
6189 (clobber (match_scratch:SI 0 "=rm"))]
6190 "ix86_match_ccmode (insn, CCGCmode)
6191 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6192 {
6193 switch (get_attr_type (insn))
6194 {
6195 case TYPE_INCDEC:
6196 if (operands[2] == constm1_rtx)
6197 return "inc{l}\t%0";
6198 else if (operands[2] == const1_rtx)
6199 return "dec{l}\t%0";
6200 else
6201 abort();
6202
6203 default:
6204 if (! rtx_equal_p (operands[0], operands[1]))
6205 abort ();
6206 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6207 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6208 if ((INTVAL (operands[2]) == -128
6209 || (INTVAL (operands[2]) > 0
6210 && INTVAL (operands[2]) != 128)))
6211 return "sub{l}\t{%2, %0|%0, %2}";
6212 operands[2] = GEN_INT (-INTVAL (operands[2]));
6213 return "add{l}\t{%2, %0|%0, %2}";
6214 }
6215 }
6216 [(set (attr "type")
6217 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6218 (const_string "incdec")
6219 (const_string "alu")))
6220 (set_attr "mode" "SI")])
6221
6222 (define_insn "*addsi_5"
6223 [(set (reg 17)
6224 (compare
6225 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6226 (match_operand:SI 2 "general_operand" "rmni"))
6227 (const_int 0)))
6228 (clobber (match_scratch:SI 0 "=r"))]
6229 "ix86_match_ccmode (insn, CCGOCmode)
6230 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6231 /* Current assemblers are broken and do not allow @GOTOFF in
6232 ought but a memory context. */
6233 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6234 {
6235 switch (get_attr_type (insn))
6236 {
6237 case TYPE_INCDEC:
6238 if (! rtx_equal_p (operands[0], operands[1]))
6239 abort ();
6240 if (operands[2] == const1_rtx)
6241 return "inc{l}\t%0";
6242 else if (operands[2] == constm1_rtx)
6243 return "dec{l}\t%0";
6244 else
6245 abort();
6246
6247 default:
6248 if (! rtx_equal_p (operands[0], operands[1]))
6249 abort ();
6250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6252 if (GET_CODE (operands[2]) == CONST_INT
6253 && (INTVAL (operands[2]) == 128
6254 || (INTVAL (operands[2]) < 0
6255 && INTVAL (operands[2]) != -128)))
6256 {
6257 operands[2] = GEN_INT (-INTVAL (operands[2]));
6258 return "sub{l}\t{%2, %0|%0, %2}";
6259 }
6260 return "add{l}\t{%2, %0|%0, %2}";
6261 }
6262 }
6263 [(set (attr "type")
6264 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set_attr "mode" "SI")])
6268
6269 (define_expand "addhi3"
6270 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6271 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6272 (match_operand:HI 2 "general_operand" "")))
6273 (clobber (reg:CC 17))])]
6274 "TARGET_HIMODE_MATH"
6275 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6276
6277 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6278 ;; type optimizations enabled by define-splits. This is not important
6279 ;; for PII, and in fact harmful because of partial register stalls.
6280
6281 (define_insn "*addhi_1_lea"
6282 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6283 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6284 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6285 (clobber (reg:CC 17))]
6286 "!TARGET_PARTIAL_REG_STALL
6287 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6288 {
6289 switch (get_attr_type (insn))
6290 {
6291 case TYPE_LEA:
6292 return "#";
6293 case TYPE_INCDEC:
6294 if (operands[2] == const1_rtx)
6295 return "inc{w}\t%0";
6296 else if (operands[2] == constm1_rtx
6297 || (GET_CODE (operands[2]) == CONST_INT
6298 && INTVAL (operands[2]) == 65535))
6299 return "dec{w}\t%0";
6300 abort();
6301
6302 default:
6303 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6304 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6305 if (GET_CODE (operands[2]) == CONST_INT
6306 && (INTVAL (operands[2]) == 128
6307 || (INTVAL (operands[2]) < 0
6308 && INTVAL (operands[2]) != -128)))
6309 {
6310 operands[2] = GEN_INT (-INTVAL (operands[2]));
6311 return "sub{w}\t{%2, %0|%0, %2}";
6312 }
6313 return "add{w}\t{%2, %0|%0, %2}";
6314 }
6315 }
6316 [(set (attr "type")
6317 (if_then_else (eq_attr "alternative" "2")
6318 (const_string "lea")
6319 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320 (const_string "incdec")
6321 (const_string "alu"))))
6322 (set_attr "mode" "HI,HI,SI")])
6323
6324 (define_insn "*addhi_1"
6325 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6326 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6327 (match_operand:HI 2 "general_operand" "ri,rm")))
6328 (clobber (reg:CC 17))]
6329 "TARGET_PARTIAL_REG_STALL
6330 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6331 {
6332 switch (get_attr_type (insn))
6333 {
6334 case TYPE_INCDEC:
6335 if (operands[2] == const1_rtx)
6336 return "inc{w}\t%0";
6337 else if (operands[2] == constm1_rtx
6338 || (GET_CODE (operands[2]) == CONST_INT
6339 && INTVAL (operands[2]) == 65535))
6340 return "dec{w}\t%0";
6341 abort();
6342
6343 default:
6344 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6346 if (GET_CODE (operands[2]) == CONST_INT
6347 && (INTVAL (operands[2]) == 128
6348 || (INTVAL (operands[2]) < 0
6349 && INTVAL (operands[2]) != -128)))
6350 {
6351 operands[2] = GEN_INT (-INTVAL (operands[2]));
6352 return "sub{w}\t{%2, %0|%0, %2}";
6353 }
6354 return "add{w}\t{%2, %0|%0, %2}";
6355 }
6356 }
6357 [(set (attr "type")
6358 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "HI")])
6362
6363 (define_insn "*addhi_2"
6364 [(set (reg 17)
6365 (compare
6366 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6367 (match_operand:HI 2 "general_operand" "rmni,rni"))
6368 (const_int 0)))
6369 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6370 (plus:HI (match_dup 1) (match_dup 2)))]
6371 "ix86_match_ccmode (insn, CCGOCmode)
6372 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6373 {
6374 switch (get_attr_type (insn))
6375 {
6376 case TYPE_INCDEC:
6377 if (operands[2] == const1_rtx)
6378 return "inc{w}\t%0";
6379 else if (operands[2] == constm1_rtx
6380 || (GET_CODE (operands[2]) == CONST_INT
6381 && INTVAL (operands[2]) == 65535))
6382 return "dec{w}\t%0";
6383 abort();
6384
6385 default:
6386 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6388 if (GET_CODE (operands[2]) == CONST_INT
6389 && (INTVAL (operands[2]) == 128
6390 || (INTVAL (operands[2]) < 0
6391 && INTVAL (operands[2]) != -128)))
6392 {
6393 operands[2] = GEN_INT (-INTVAL (operands[2]));
6394 return "sub{w}\t{%2, %0|%0, %2}";
6395 }
6396 return "add{w}\t{%2, %0|%0, %2}";
6397 }
6398 }
6399 [(set (attr "type")
6400 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6401 (const_string "incdec")
6402 (const_string "alu")))
6403 (set_attr "mode" "HI")])
6404
6405 (define_insn "*addhi_3"
6406 [(set (reg 17)
6407 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6408 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6409 (clobber (match_scratch:HI 0 "=r"))]
6410 "ix86_match_ccmode (insn, CCZmode)
6411 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6412 {
6413 switch (get_attr_type (insn))
6414 {
6415 case TYPE_INCDEC:
6416 if (operands[2] == const1_rtx)
6417 return "inc{w}\t%0";
6418 else if (operands[2] == constm1_rtx
6419 || (GET_CODE (operands[2]) == CONST_INT
6420 && INTVAL (operands[2]) == 65535))
6421 return "dec{w}\t%0";
6422 abort();
6423
6424 default:
6425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6427 if (GET_CODE (operands[2]) == CONST_INT
6428 && (INTVAL (operands[2]) == 128
6429 || (INTVAL (operands[2]) < 0
6430 && INTVAL (operands[2]) != -128)))
6431 {
6432 operands[2] = GEN_INT (-INTVAL (operands[2]));
6433 return "sub{w}\t{%2, %0|%0, %2}";
6434 }
6435 return "add{w}\t{%2, %0|%0, %2}";
6436 }
6437 }
6438 [(set (attr "type")
6439 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "HI")])
6443
6444 ; See comments above addsi_3_imm for details.
6445 (define_insn "*addhi_4"
6446 [(set (reg 17)
6447 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6448 (match_operand:HI 2 "const_int_operand" "n")))
6449 (clobber (match_scratch:HI 0 "=rm"))]
6450 "ix86_match_ccmode (insn, CCGCmode)
6451 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6452 {
6453 switch (get_attr_type (insn))
6454 {
6455 case TYPE_INCDEC:
6456 if (operands[2] == constm1_rtx
6457 || (GET_CODE (operands[2]) == CONST_INT
6458 && INTVAL (operands[2]) == 65535))
6459 return "inc{w}\t%0";
6460 else if (operands[2] == const1_rtx)
6461 return "dec{w}\t%0";
6462 else
6463 abort();
6464
6465 default:
6466 if (! rtx_equal_p (operands[0], operands[1]))
6467 abort ();
6468 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6469 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6470 if ((INTVAL (operands[2]) == -128
6471 || (INTVAL (operands[2]) > 0
6472 && INTVAL (operands[2]) != 128)))
6473 return "sub{w}\t{%2, %0|%0, %2}";
6474 operands[2] = GEN_INT (-INTVAL (operands[2]));
6475 return "add{w}\t{%2, %0|%0, %2}";
6476 }
6477 }
6478 [(set (attr "type")
6479 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6480 (const_string "incdec")
6481 (const_string "alu")))
6482 (set_attr "mode" "SI")])
6483
6484
6485 (define_insn "*addhi_5"
6486 [(set (reg 17)
6487 (compare
6488 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6489 (match_operand:HI 2 "general_operand" "rmni"))
6490 (const_int 0)))
6491 (clobber (match_scratch:HI 0 "=r"))]
6492 "ix86_match_ccmode (insn, CCGOCmode)
6493 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6494 {
6495 switch (get_attr_type (insn))
6496 {
6497 case TYPE_INCDEC:
6498 if (operands[2] == const1_rtx)
6499 return "inc{w}\t%0";
6500 else if (operands[2] == constm1_rtx
6501 || (GET_CODE (operands[2]) == CONST_INT
6502 && INTVAL (operands[2]) == 65535))
6503 return "dec{w}\t%0";
6504 abort();
6505
6506 default:
6507 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6508 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6509 if (GET_CODE (operands[2]) == CONST_INT
6510 && (INTVAL (operands[2]) == 128
6511 || (INTVAL (operands[2]) < 0
6512 && INTVAL (operands[2]) != -128)))
6513 {
6514 operands[2] = GEN_INT (-INTVAL (operands[2]));
6515 return "sub{w}\t{%2, %0|%0, %2}";
6516 }
6517 return "add{w}\t{%2, %0|%0, %2}";
6518 }
6519 }
6520 [(set (attr "type")
6521 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6522 (const_string "incdec")
6523 (const_string "alu")))
6524 (set_attr "mode" "HI")])
6525
6526 (define_expand "addqi3"
6527 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6528 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6529 (match_operand:QI 2 "general_operand" "")))
6530 (clobber (reg:CC 17))])]
6531 "TARGET_QIMODE_MATH"
6532 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6533
6534 ;; %%% Potential partial reg stall on alternative 2. What to do?
6535 (define_insn "*addqi_1_lea"
6536 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6537 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6538 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6539 (clobber (reg:CC 17))]
6540 "!TARGET_PARTIAL_REG_STALL
6541 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6542 {
6543 int widen = (which_alternative == 2);
6544 switch (get_attr_type (insn))
6545 {
6546 case TYPE_LEA:
6547 return "#";
6548 case TYPE_INCDEC:
6549 if (operands[2] == const1_rtx)
6550 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6551 else if (operands[2] == constm1_rtx
6552 || (GET_CODE (operands[2]) == CONST_INT
6553 && INTVAL (operands[2]) == 255))
6554 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6555 abort();
6556
6557 default:
6558 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6559 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6560 if (GET_CODE (operands[2]) == CONST_INT
6561 && (INTVAL (operands[2]) == 128
6562 || (INTVAL (operands[2]) < 0
6563 && INTVAL (operands[2]) != -128)))
6564 {
6565 operands[2] = GEN_INT (-INTVAL (operands[2]));
6566 if (widen)
6567 return "sub{l}\t{%2, %k0|%k0, %2}";
6568 else
6569 return "sub{b}\t{%2, %0|%0, %2}";
6570 }
6571 if (widen)
6572 return "add{l}\t{%k2, %k0|%k0, %k2}";
6573 else
6574 return "add{b}\t{%2, %0|%0, %2}";
6575 }
6576 }
6577 [(set (attr "type")
6578 (if_then_else (eq_attr "alternative" "3")
6579 (const_string "lea")
6580 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6581 (const_string "incdec")
6582 (const_string "alu"))))
6583 (set_attr "mode" "QI,QI,SI,SI")])
6584
6585 (define_insn "*addqi_1"
6586 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6587 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6588 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6589 (clobber (reg:CC 17))]
6590 "TARGET_PARTIAL_REG_STALL
6591 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6592 {
6593 int widen = (which_alternative == 2);
6594 switch (get_attr_type (insn))
6595 {
6596 case TYPE_INCDEC:
6597 if (operands[2] == const1_rtx)
6598 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6599 else if (operands[2] == constm1_rtx
6600 || (GET_CODE (operands[2]) == CONST_INT
6601 && INTVAL (operands[2]) == 255))
6602 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6603 abort();
6604
6605 default:
6606 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6607 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6608 if (GET_CODE (operands[2]) == CONST_INT
6609 && (INTVAL (operands[2]) == 128
6610 || (INTVAL (operands[2]) < 0
6611 && INTVAL (operands[2]) != -128)))
6612 {
6613 operands[2] = GEN_INT (-INTVAL (operands[2]));
6614 if (widen)
6615 return "sub{l}\t{%2, %k0|%k0, %2}";
6616 else
6617 return "sub{b}\t{%2, %0|%0, %2}";
6618 }
6619 if (widen)
6620 return "add{l}\t{%k2, %k0|%k0, %k2}";
6621 else
6622 return "add{b}\t{%2, %0|%0, %2}";
6623 }
6624 }
6625 [(set (attr "type")
6626 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6627 (const_string "incdec")
6628 (const_string "alu")))
6629 (set_attr "mode" "QI,QI,SI")])
6630
6631 (define_insn "*addqi_2"
6632 [(set (reg 17)
6633 (compare
6634 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6635 (match_operand:QI 2 "general_operand" "qmni,qni"))
6636 (const_int 0)))
6637 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6638 (plus:QI (match_dup 1) (match_dup 2)))]
6639 "ix86_match_ccmode (insn, CCGOCmode)
6640 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6641 {
6642 switch (get_attr_type (insn))
6643 {
6644 case TYPE_INCDEC:
6645 if (operands[2] == const1_rtx)
6646 return "inc{b}\t%0";
6647 else if (operands[2] == constm1_rtx
6648 || (GET_CODE (operands[2]) == CONST_INT
6649 && INTVAL (operands[2]) == 255))
6650 return "dec{b}\t%0";
6651 abort();
6652
6653 default:
6654 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6655 if (GET_CODE (operands[2]) == CONST_INT
6656 && INTVAL (operands[2]) < 0)
6657 {
6658 operands[2] = GEN_INT (-INTVAL (operands[2]));
6659 return "sub{b}\t{%2, %0|%0, %2}";
6660 }
6661 return "add{b}\t{%2, %0|%0, %2}";
6662 }
6663 }
6664 [(set (attr "type")
6665 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6666 (const_string "incdec")
6667 (const_string "alu")))
6668 (set_attr "mode" "QI")])
6669
6670 (define_insn "*addqi_3"
6671 [(set (reg 17)
6672 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6673 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6674 (clobber (match_scratch:QI 0 "=q"))]
6675 "ix86_match_ccmode (insn, CCZmode)
6676 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6677 {
6678 switch (get_attr_type (insn))
6679 {
6680 case TYPE_INCDEC:
6681 if (operands[2] == const1_rtx)
6682 return "inc{b}\t%0";
6683 else if (operands[2] == constm1_rtx
6684 || (GET_CODE (operands[2]) == CONST_INT
6685 && INTVAL (operands[2]) == 255))
6686 return "dec{b}\t%0";
6687 abort();
6688
6689 default:
6690 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6691 if (GET_CODE (operands[2]) == CONST_INT
6692 && INTVAL (operands[2]) < 0)
6693 {
6694 operands[2] = GEN_INT (-INTVAL (operands[2]));
6695 return "sub{b}\t{%2, %0|%0, %2}";
6696 }
6697 return "add{b}\t{%2, %0|%0, %2}";
6698 }
6699 }
6700 [(set (attr "type")
6701 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6702 (const_string "incdec")
6703 (const_string "alu")))
6704 (set_attr "mode" "QI")])
6705
6706 ; See comments above addsi_3_imm for details.
6707 (define_insn "*addqi_4"
6708 [(set (reg 17)
6709 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6710 (match_operand:QI 2 "const_int_operand" "n")))
6711 (clobber (match_scratch:QI 0 "=qm"))]
6712 "ix86_match_ccmode (insn, CCGCmode)
6713 && (INTVAL (operands[2]) & 0xff) != 0x80"
6714 {
6715 switch (get_attr_type (insn))
6716 {
6717 case TYPE_INCDEC:
6718 if (operands[2] == constm1_rtx
6719 || (GET_CODE (operands[2]) == CONST_INT
6720 && INTVAL (operands[2]) == 255))
6721 return "inc{b}\t%0";
6722 else if (operands[2] == const1_rtx)
6723 return "dec{b}\t%0";
6724 else
6725 abort();
6726
6727 default:
6728 if (! rtx_equal_p (operands[0], operands[1]))
6729 abort ();
6730 if (INTVAL (operands[2]) < 0)
6731 {
6732 operands[2] = GEN_INT (-INTVAL (operands[2]));
6733 return "add{b}\t{%2, %0|%0, %2}";
6734 }
6735 return "sub{b}\t{%2, %0|%0, %2}";
6736 }
6737 }
6738 [(set (attr "type")
6739 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6740 (const_string "incdec")
6741 (const_string "alu")))
6742 (set_attr "mode" "QI")])
6743
6744
6745 (define_insn "*addqi_5"
6746 [(set (reg 17)
6747 (compare
6748 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6749 (match_operand:QI 2 "general_operand" "qmni"))
6750 (const_int 0)))
6751 (clobber (match_scratch:QI 0 "=q"))]
6752 "ix86_match_ccmode (insn, CCGOCmode)
6753 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6754 {
6755 switch (get_attr_type (insn))
6756 {
6757 case TYPE_INCDEC:
6758 if (operands[2] == const1_rtx)
6759 return "inc{b}\t%0";
6760 else if (operands[2] == constm1_rtx
6761 || (GET_CODE (operands[2]) == CONST_INT
6762 && INTVAL (operands[2]) == 255))
6763 return "dec{b}\t%0";
6764 abort();
6765
6766 default:
6767 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6768 if (GET_CODE (operands[2]) == CONST_INT
6769 && INTVAL (operands[2]) < 0)
6770 {
6771 operands[2] = GEN_INT (-INTVAL (operands[2]));
6772 return "sub{b}\t{%2, %0|%0, %2}";
6773 }
6774 return "add{b}\t{%2, %0|%0, %2}";
6775 }
6776 }
6777 [(set (attr "type")
6778 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6779 (const_string "incdec")
6780 (const_string "alu")))
6781 (set_attr "mode" "QI")])
6782
6783
6784 (define_insn "addqi_ext_1"
6785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6786 (const_int 8)
6787 (const_int 8))
6788 (plus:SI
6789 (zero_extract:SI
6790 (match_operand 1 "ext_register_operand" "0")
6791 (const_int 8)
6792 (const_int 8))
6793 (match_operand:QI 2 "general_operand" "Qmn")))
6794 (clobber (reg:CC 17))]
6795 "!TARGET_64BIT"
6796 {
6797 switch (get_attr_type (insn))
6798 {
6799 case TYPE_INCDEC:
6800 if (operands[2] == const1_rtx)
6801 return "inc{b}\t%h0";
6802 else if (operands[2] == constm1_rtx
6803 || (GET_CODE (operands[2]) == CONST_INT
6804 && INTVAL (operands[2]) == 255))
6805 return "dec{b}\t%h0";
6806 abort();
6807
6808 default:
6809 return "add{b}\t{%2, %h0|%h0, %2}";
6810 }
6811 }
6812 [(set (attr "type")
6813 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6814 (const_string "incdec")
6815 (const_string "alu")))
6816 (set_attr "mode" "QI")])
6817
6818 (define_insn "*addqi_ext_1_rex64"
6819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6820 (const_int 8)
6821 (const_int 8))
6822 (plus:SI
6823 (zero_extract:SI
6824 (match_operand 1 "ext_register_operand" "0")
6825 (const_int 8)
6826 (const_int 8))
6827 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6828 (clobber (reg:CC 17))]
6829 "TARGET_64BIT"
6830 {
6831 switch (get_attr_type (insn))
6832 {
6833 case TYPE_INCDEC:
6834 if (operands[2] == const1_rtx)
6835 return "inc{b}\t%h0";
6836 else if (operands[2] == constm1_rtx
6837 || (GET_CODE (operands[2]) == CONST_INT
6838 && INTVAL (operands[2]) == 255))
6839 return "dec{b}\t%h0";
6840 abort();
6841
6842 default:
6843 return "add{b}\t{%2, %h0|%h0, %2}";
6844 }
6845 }
6846 [(set (attr "type")
6847 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6848 (const_string "incdec")
6849 (const_string "alu")))
6850 (set_attr "mode" "QI")])
6851
6852 (define_insn "*addqi_ext_2"
6853 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6854 (const_int 8)
6855 (const_int 8))
6856 (plus:SI
6857 (zero_extract:SI
6858 (match_operand 1 "ext_register_operand" "%0")
6859 (const_int 8)
6860 (const_int 8))
6861 (zero_extract:SI
6862 (match_operand 2 "ext_register_operand" "Q")
6863 (const_int 8)
6864 (const_int 8))))
6865 (clobber (reg:CC 17))]
6866 ""
6867 "add{b}\t{%h2, %h0|%h0, %h2}"
6868 [(set_attr "type" "alu")
6869 (set_attr "mode" "QI")])
6870
6871 ;; The patterns that match these are at the end of this file.
6872
6873 (define_expand "addxf3"
6874 [(set (match_operand:XF 0 "register_operand" "")
6875 (plus:XF (match_operand:XF 1 "register_operand" "")
6876 (match_operand:XF 2 "register_operand" "")))]
6877 "!TARGET_64BIT && TARGET_80387"
6878 "")
6879
6880 (define_expand "addtf3"
6881 [(set (match_operand:TF 0 "register_operand" "")
6882 (plus:TF (match_operand:TF 1 "register_operand" "")
6883 (match_operand:TF 2 "register_operand" "")))]
6884 "TARGET_80387"
6885 "")
6886
6887 (define_expand "adddf3"
6888 [(set (match_operand:DF 0 "register_operand" "")
6889 (plus:DF (match_operand:DF 1 "register_operand" "")
6890 (match_operand:DF 2 "nonimmediate_operand" "")))]
6891 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6892 "")
6893
6894 (define_expand "addsf3"
6895 [(set (match_operand:SF 0 "register_operand" "")
6896 (plus:SF (match_operand:SF 1 "register_operand" "")
6897 (match_operand:SF 2 "nonimmediate_operand" "")))]
6898 "TARGET_80387 || TARGET_SSE_MATH"
6899 "")
6900 \f
6901 ;; Subtract instructions
6902
6903 ;; %%% splits for subsidi3
6904
6905 (define_expand "subdi3"
6906 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6907 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6908 (match_operand:DI 2 "x86_64_general_operand" "")))
6909 (clobber (reg:CC 17))])]
6910 ""
6911 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6912
6913 (define_insn "*subdi3_1"
6914 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6915 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6916 (match_operand:DI 2 "general_operand" "roiF,riF")))
6917 (clobber (reg:CC 17))]
6918 "!TARGET_64BIT"
6919 "#")
6920
6921 (define_split
6922 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6923 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6924 (match_operand:DI 2 "general_operand" "")))
6925 (clobber (reg:CC 17))]
6926 "!TARGET_64BIT && reload_completed"
6927 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6928 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6929 (parallel [(set (match_dup 3)
6930 (minus:SI (match_dup 4)
6931 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6932 (match_dup 5))))
6933 (clobber (reg:CC 17))])]
6934 "split_di (operands+0, 1, operands+0, operands+3);
6935 split_di (operands+1, 1, operands+1, operands+4);
6936 split_di (operands+2, 1, operands+2, operands+5);")
6937
6938 (define_insn "subdi3_carry_rex64"
6939 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6940 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6941 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6942 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6943 (clobber (reg:CC 17))]
6944 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6945 "sbb{q}\t{%2, %0|%0, %2}"
6946 [(set_attr "type" "alu")
6947 (set_attr "pent_pair" "pu")
6948 (set_attr "ppro_uops" "few")
6949 (set_attr "mode" "DI")])
6950
6951 (define_insn "*subdi_1_rex64"
6952 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6953 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6954 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6955 (clobber (reg:CC 17))]
6956 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6957 "sub{q}\t{%2, %0|%0, %2}"
6958 [(set_attr "type" "alu")
6959 (set_attr "mode" "DI")])
6960
6961 (define_insn "*subdi_2_rex64"
6962 [(set (reg 17)
6963 (compare
6964 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6965 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6966 (const_int 0)))
6967 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6968 (minus:DI (match_dup 1) (match_dup 2)))]
6969 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6970 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6971 "sub{q}\t{%2, %0|%0, %2}"
6972 [(set_attr "type" "alu")
6973 (set_attr "mode" "DI")])
6974
6975 (define_insn "*subdi_3_rex63"
6976 [(set (reg 17)
6977 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6978 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6979 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6980 (minus:DI (match_dup 1) (match_dup 2)))]
6981 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6982 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6983 "sub{q}\t{%2, %0|%0, %2}"
6984 [(set_attr "type" "alu")
6985 (set_attr "mode" "DI")])
6986
6987
6988 (define_insn "subsi3_carry"
6989 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6991 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6992 (match_operand:SI 2 "general_operand" "ri,rm"))))
6993 (clobber (reg:CC 17))]
6994 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6995 "sbb{l}\t{%2, %0|%0, %2}"
6996 [(set_attr "type" "alu")
6997 (set_attr "pent_pair" "pu")
6998 (set_attr "ppro_uops" "few")
6999 (set_attr "mode" "SI")])
7000
7001 (define_insn "subsi3_carry_zext"
7002 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7003 (zero_extend:DI
7004 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7005 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7006 (match_operand:SI 2 "general_operand" "ri,rm")))))
7007 (clobber (reg:CC 17))]
7008 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7009 "sbb{l}\t{%2, %k0|%k0, %2}"
7010 [(set_attr "type" "alu")
7011 (set_attr "pent_pair" "pu")
7012 (set_attr "ppro_uops" "few")
7013 (set_attr "mode" "SI")])
7014
7015 (define_expand "subsi3"
7016 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7017 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7018 (match_operand:SI 2 "general_operand" "")))
7019 (clobber (reg:CC 17))])]
7020 ""
7021 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7022
7023 (define_insn "*subsi_1"
7024 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7025 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7026 (match_operand:SI 2 "general_operand" "ri,rm")))
7027 (clobber (reg:CC 17))]
7028 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7029 "sub{l}\t{%2, %0|%0, %2}"
7030 [(set_attr "type" "alu")
7031 (set_attr "mode" "SI")])
7032
7033 (define_insn "*subsi_1_zext"
7034 [(set (match_operand:DI 0 "register_operand" "=r")
7035 (zero_extend:DI
7036 (minus:SI (match_operand:SI 1 "register_operand" "0")
7037 (match_operand:SI 2 "general_operand" "rim"))))
7038 (clobber (reg:CC 17))]
7039 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7040 "sub{l}\t{%2, %k0|%k0, %2}"
7041 [(set_attr "type" "alu")
7042 (set_attr "mode" "SI")])
7043
7044 (define_insn "*subsi_2"
7045 [(set (reg 17)
7046 (compare
7047 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7048 (match_operand:SI 2 "general_operand" "ri,rm"))
7049 (const_int 0)))
7050 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7051 (minus:SI (match_dup 1) (match_dup 2)))]
7052 "ix86_match_ccmode (insn, CCGOCmode)
7053 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7054 "sub{l}\t{%2, %0|%0, %2}"
7055 [(set_attr "type" "alu")
7056 (set_attr "mode" "SI")])
7057
7058 (define_insn "*subsi_2_zext"
7059 [(set (reg 17)
7060 (compare
7061 (minus:SI (match_operand:SI 1 "register_operand" "0")
7062 (match_operand:SI 2 "general_operand" "rim"))
7063 (const_int 0)))
7064 (set (match_operand:DI 0 "register_operand" "=r")
7065 (zero_extend:DI
7066 (minus:SI (match_dup 1)
7067 (match_dup 2))))]
7068 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7069 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7070 "sub{l}\t{%2, %k0|%k0, %2}"
7071 [(set_attr "type" "alu")
7072 (set_attr "mode" "SI")])
7073
7074 (define_insn "*subsi_3"
7075 [(set (reg 17)
7076 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7077 (match_operand:SI 2 "general_operand" "ri,rm")))
7078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7079 (minus:SI (match_dup 1) (match_dup 2)))]
7080 "ix86_match_ccmode (insn, CCmode)
7081 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7082 "sub{l}\t{%2, %0|%0, %2}"
7083 [(set_attr "type" "alu")
7084 (set_attr "mode" "SI")])
7085
7086 (define_insn "*subsi_3_zext"
7087 [(set (reg 17)
7088 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7089 (match_operand:SI 2 "general_operand" "rim")))
7090 (set (match_operand:DI 0 "register_operand" "=r")
7091 (zero_extend:DI
7092 (minus:SI (match_dup 1)
7093 (match_dup 2))))]
7094 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7095 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7096 "sub{q}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "DI")])
7099
7100 (define_expand "subhi3"
7101 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7102 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7103 (match_operand:HI 2 "general_operand" "")))
7104 (clobber (reg:CC 17))])]
7105 "TARGET_HIMODE_MATH"
7106 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7107
7108 (define_insn "*subhi_1"
7109 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7110 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7111 (match_operand:HI 2 "general_operand" "ri,rm")))
7112 (clobber (reg:CC 17))]
7113 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7114 "sub{w}\t{%2, %0|%0, %2}"
7115 [(set_attr "type" "alu")
7116 (set_attr "mode" "HI")])
7117
7118 (define_insn "*subhi_2"
7119 [(set (reg 17)
7120 (compare
7121 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7122 (match_operand:HI 2 "general_operand" "ri,rm"))
7123 (const_int 0)))
7124 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7125 (minus:HI (match_dup 1) (match_dup 2)))]
7126 "ix86_match_ccmode (insn, CCGOCmode)
7127 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7128 "sub{w}\t{%2, %0|%0, %2}"
7129 [(set_attr "type" "alu")
7130 (set_attr "mode" "HI")])
7131
7132 (define_insn "*subhi_3"
7133 [(set (reg 17)
7134 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7135 (match_operand:HI 2 "general_operand" "ri,rm")))
7136 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7137 (minus:HI (match_dup 1) (match_dup 2)))]
7138 "ix86_match_ccmode (insn, CCmode)
7139 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7140 "sub{w}\t{%2, %0|%0, %2}"
7141 [(set_attr "type" "alu")
7142 (set_attr "mode" "HI")])
7143
7144 (define_expand "subqi3"
7145 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7146 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7147 (match_operand:QI 2 "general_operand" "")))
7148 (clobber (reg:CC 17))])]
7149 "TARGET_QIMODE_MATH"
7150 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7151
7152 (define_insn "*subqi_1"
7153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7154 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7155 (match_operand:QI 2 "general_operand" "qn,qmn")))
7156 (clobber (reg:CC 17))]
7157 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7158 "sub{b}\t{%2, %0|%0, %2}"
7159 [(set_attr "type" "alu")
7160 (set_attr "mode" "QI")])
7161
7162 (define_insn "*subqi_2"
7163 [(set (reg 17)
7164 (compare
7165 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7166 (match_operand:QI 2 "general_operand" "qi,qm"))
7167 (const_int 0)))
7168 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7169 (minus:HI (match_dup 1) (match_dup 2)))]
7170 "ix86_match_ccmode (insn, CCGOCmode)
7171 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7172 "sub{b}\t{%2, %0|%0, %2}"
7173 [(set_attr "type" "alu")
7174 (set_attr "mode" "QI")])
7175
7176 (define_insn "*subqi_3"
7177 [(set (reg 17)
7178 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7179 (match_operand:QI 2 "general_operand" "qi,qm")))
7180 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7181 (minus:HI (match_dup 1) (match_dup 2)))]
7182 "ix86_match_ccmode (insn, CCmode)
7183 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7184 "sub{b}\t{%2, %0|%0, %2}"
7185 [(set_attr "type" "alu")
7186 (set_attr "mode" "QI")])
7187
7188 ;; The patterns that match these are at the end of this file.
7189
7190 (define_expand "subxf3"
7191 [(set (match_operand:XF 0 "register_operand" "")
7192 (minus:XF (match_operand:XF 1 "register_operand" "")
7193 (match_operand:XF 2 "register_operand" "")))]
7194 "!TARGET_64BIT && TARGET_80387"
7195 "")
7196
7197 (define_expand "subtf3"
7198 [(set (match_operand:TF 0 "register_operand" "")
7199 (minus:TF (match_operand:TF 1 "register_operand" "")
7200 (match_operand:TF 2 "register_operand" "")))]
7201 "TARGET_80387"
7202 "")
7203
7204 (define_expand "subdf3"
7205 [(set (match_operand:DF 0 "register_operand" "")
7206 (minus:DF (match_operand:DF 1 "register_operand" "")
7207 (match_operand:DF 2 "nonimmediate_operand" "")))]
7208 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7209 "")
7210
7211 (define_expand "subsf3"
7212 [(set (match_operand:SF 0 "register_operand" "")
7213 (minus:SF (match_operand:SF 1 "register_operand" "")
7214 (match_operand:SF 2 "nonimmediate_operand" "")))]
7215 "TARGET_80387 || TARGET_SSE_MATH"
7216 "")
7217 \f
7218 ;; Multiply instructions
7219
7220 (define_expand "muldi3"
7221 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7222 (mult:DI (match_operand:DI 1 "register_operand" "")
7223 (match_operand:DI 2 "x86_64_general_operand" "")))
7224 (clobber (reg:CC 17))])]
7225 "TARGET_64BIT"
7226 "")
7227
7228 (define_insn "*muldi3_1_rex64"
7229 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7230 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7231 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7232 (clobber (reg:CC 17))]
7233 "TARGET_64BIT
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 "@
7236 imul{q}\t{%2, %1, %0|%0, %1, %2}
7237 imul{q}\t{%2, %1, %0|%0, %1, %2}
7238 imul{q}\t{%2, %0|%0, %2}"
7239 [(set_attr "type" "imul")
7240 (set_attr "prefix_0f" "0,0,1")
7241 (set_attr "mode" "DI")])
7242
7243 (define_expand "mulsi3"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7245 (mult:SI (match_operand:SI 1 "register_operand" "")
7246 (match_operand:SI 2 "general_operand" "")))
7247 (clobber (reg:CC 17))])]
7248 ""
7249 "")
7250
7251 (define_insn "*mulsi3_1"
7252 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7253 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7254 (match_operand:SI 2 "general_operand" "K,i,mr")))
7255 (clobber (reg:CC 17))]
7256 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7257 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7258 ; there are two ways of writing the exact same machine instruction
7259 ; in assembly language. One, for example, is:
7260 ;
7261 ; imul $12, %eax
7262 ;
7263 ; while the other is:
7264 ;
7265 ; imul $12, %eax, %eax
7266 ;
7267 ; The first is simply short-hand for the latter. But, some assemblers,
7268 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7269 "@
7270 imul{l}\t{%2, %1, %0|%0, %1, %2}
7271 imul{l}\t{%2, %1, %0|%0, %1, %2}
7272 imul{l}\t{%2, %0|%0, %2}"
7273 [(set_attr "type" "imul")
7274 (set_attr "prefix_0f" "0,0,1")
7275 (set_attr "mode" "SI")])
7276
7277 (define_insn "*mulsi3_1_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7279 (zero_extend:DI
7280 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7281 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7282 (clobber (reg:CC 17))]
7283 "TARGET_64BIT
7284 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7285 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7286 ; there are two ways of writing the exact same machine instruction
7287 ; in assembly language. One, for example, is:
7288 ;
7289 ; imul $12, %eax
7290 ;
7291 ; while the other is:
7292 ;
7293 ; imul $12, %eax, %eax
7294 ;
7295 ; The first is simply short-hand for the latter. But, some assemblers,
7296 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7297 "@
7298 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7299 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7300 imul{l}\t{%2, %k0|%k0, %2}"
7301 [(set_attr "type" "imul")
7302 (set_attr "prefix_0f" "0,0,1")
7303 (set_attr "mode" "SI")])
7304
7305 (define_expand "mulhi3"
7306 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7307 (mult:HI (match_operand:HI 1 "register_operand" "")
7308 (match_operand:HI 2 "general_operand" "")))
7309 (clobber (reg:CC 17))])]
7310 "TARGET_HIMODE_MATH"
7311 "")
7312
7313 (define_insn "*mulhi3_1"
7314 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7315 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7316 (match_operand:HI 2 "general_operand" "K,i,mr")))
7317 (clobber (reg:CC 17))]
7318 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7319 ; %%% There was a note about "Assembler has weird restrictions",
7320 ; concerning alternative 1 when op1 == op0. True?
7321 "@
7322 imul{w}\t{%2, %1, %0|%0, %1, %2}
7323 imul{w}\t{%2, %1, %0|%0, %1, %2}
7324 imul{w}\t{%2, %0|%0, %2}"
7325 [(set_attr "type" "imul")
7326 (set_attr "prefix_0f" "0,0,1")
7327 (set_attr "mode" "HI")])
7328
7329 (define_insn "mulqi3"
7330 [(set (match_operand:QI 0 "register_operand" "=a")
7331 (mult:QI (match_operand:QI 1 "register_operand" "%0")
7332 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333 (clobber (reg:CC 17))]
7334 "TARGET_QIMODE_MATH"
7335 "mul{b}\t%2"
7336 [(set_attr "type" "imul")
7337 (set_attr "length_immediate" "0")
7338 (set_attr "mode" "QI")])
7339
7340 (define_insn "umulqihi3"
7341 [(set (match_operand:HI 0 "register_operand" "=a")
7342 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7343 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7344 (clobber (reg:CC 17))]
7345 "TARGET_QIMODE_MATH"
7346 "mul{b}\t%2"
7347 [(set_attr "type" "imul")
7348 (set_attr "length_immediate" "0")
7349 (set_attr "mode" "QI")])
7350
7351 (define_insn "mulqihi3"
7352 [(set (match_operand:HI 0 "register_operand" "=a")
7353 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7354 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7355 (clobber (reg:CC 17))]
7356 "TARGET_QIMODE_MATH"
7357 "imul{b}\t%2"
7358 [(set_attr "type" "imul")
7359 (set_attr "length_immediate" "0")
7360 (set_attr "mode" "QI")])
7361
7362 (define_insn "umulditi3"
7363 [(set (match_operand:TI 0 "register_operand" "=A")
7364 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7365 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7366 (clobber (reg:CC 17))]
7367 "TARGET_64BIT"
7368 "mul{q}\t%2"
7369 [(set_attr "type" "imul")
7370 (set_attr "ppro_uops" "few")
7371 (set_attr "length_immediate" "0")
7372 (set_attr "mode" "DI")])
7373
7374 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7375 (define_insn "umulsidi3"
7376 [(set (match_operand:DI 0 "register_operand" "=A")
7377 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7378 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7379 (clobber (reg:CC 17))]
7380 "!TARGET_64BIT"
7381 "mul{l}\t%2"
7382 [(set_attr "type" "imul")
7383 (set_attr "ppro_uops" "few")
7384 (set_attr "length_immediate" "0")
7385 (set_attr "mode" "SI")])
7386
7387 (define_insn "mulditi3"
7388 [(set (match_operand:TI 0 "register_operand" "=A")
7389 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7390 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7391 (clobber (reg:CC 17))]
7392 "TARGET_64BIT"
7393 "imul{q}\t%2"
7394 [(set_attr "type" "imul")
7395 (set_attr "length_immediate" "0")
7396 (set_attr "mode" "DI")])
7397
7398 (define_insn "mulsidi3"
7399 [(set (match_operand:DI 0 "register_operand" "=A")
7400 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7401 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7402 (clobber (reg:CC 17))]
7403 "!TARGET_64BIT"
7404 "imul{l}\t%2"
7405 [(set_attr "type" "imul")
7406 (set_attr "length_immediate" "0")
7407 (set_attr "mode" "SI")])
7408
7409 (define_insn "*umuldi3_highpart_rex64"
7410 [(set (match_operand:DI 0 "register_operand" "=d")
7411 (truncate:DI
7412 (lshiftrt:TI
7413 (mult:TI (zero_extend:TI
7414 (match_operand:DI 1 "register_operand" "%a"))
7415 (zero_extend:TI
7416 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7417 (const_int 64))))
7418 (clobber (match_scratch:DI 3 "=a"))
7419 (clobber (reg:CC 17))]
7420 "TARGET_64BIT"
7421 "mul{q}\t%2"
7422 [(set_attr "type" "imul")
7423 (set_attr "ppro_uops" "few")
7424 (set_attr "length_immediate" "0")
7425 (set_attr "mode" "DI")])
7426
7427 (define_insn "umulsi3_highpart"
7428 [(set (match_operand:SI 0 "register_operand" "=d")
7429 (truncate:SI
7430 (lshiftrt:DI
7431 (mult:DI (zero_extend:DI
7432 (match_operand:SI 1 "register_operand" "%a"))
7433 (zero_extend:DI
7434 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7435 (const_int 32))))
7436 (clobber (match_scratch:SI 3 "=a"))
7437 (clobber (reg:CC 17))]
7438 ""
7439 "mul{l}\t%2"
7440 [(set_attr "type" "imul")
7441 (set_attr "ppro_uops" "few")
7442 (set_attr "length_immediate" "0")
7443 (set_attr "mode" "SI")])
7444
7445 (define_insn "*umulsi3_highpart_zext"
7446 [(set (match_operand:DI 0 "register_operand" "=d")
7447 (zero_extend:DI (truncate:SI
7448 (lshiftrt:DI
7449 (mult:DI (zero_extend:DI
7450 (match_operand:SI 1 "register_operand" "%a"))
7451 (zero_extend:DI
7452 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7453 (const_int 32)))))
7454 (clobber (match_scratch:SI 3 "=a"))
7455 (clobber (reg:CC 17))]
7456 "TARGET_64BIT"
7457 "mul{l}\t%2"
7458 [(set_attr "type" "imul")
7459 (set_attr "ppro_uops" "few")
7460 (set_attr "length_immediate" "0")
7461 (set_attr "mode" "SI")])
7462
7463 (define_insn "*smuldi3_highpart_rex64"
7464 [(set (match_operand:DI 0 "register_operand" "=d")
7465 (truncate:DI
7466 (lshiftrt:TI
7467 (mult:TI (sign_extend:TI
7468 (match_operand:DI 1 "register_operand" "%a"))
7469 (sign_extend:TI
7470 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7471 (const_int 64))))
7472 (clobber (match_scratch:DI 3 "=a"))
7473 (clobber (reg:CC 17))]
7474 "TARGET_64BIT"
7475 "imul{q}\t%2"
7476 [(set_attr "type" "imul")
7477 (set_attr "ppro_uops" "few")
7478 (set_attr "mode" "DI")])
7479
7480 (define_insn "smulsi3_highpart"
7481 [(set (match_operand:SI 0 "register_operand" "=d")
7482 (truncate:SI
7483 (lshiftrt:DI
7484 (mult:DI (sign_extend:DI
7485 (match_operand:SI 1 "register_operand" "%a"))
7486 (sign_extend:DI
7487 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7488 (const_int 32))))
7489 (clobber (match_scratch:SI 3 "=a"))
7490 (clobber (reg:CC 17))]
7491 ""
7492 "imul{l}\t%2"
7493 [(set_attr "type" "imul")
7494 (set_attr "ppro_uops" "few")
7495 (set_attr "mode" "SI")])
7496
7497 (define_insn "*smulsi3_highpart_zext"
7498 [(set (match_operand:DI 0 "register_operand" "=d")
7499 (zero_extend:DI (truncate:SI
7500 (lshiftrt:DI
7501 (mult:DI (sign_extend:DI
7502 (match_operand:SI 1 "register_operand" "%a"))
7503 (sign_extend:DI
7504 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7505 (const_int 32)))))
7506 (clobber (match_scratch:SI 3 "=a"))
7507 (clobber (reg:CC 17))]
7508 "TARGET_64BIT"
7509 "imul{l}\t%2"
7510 [(set_attr "type" "imul")
7511 (set_attr "ppro_uops" "few")
7512 (set_attr "mode" "SI")])
7513
7514 ;; The patterns that match these are at the end of this file.
7515
7516 (define_expand "mulxf3"
7517 [(set (match_operand:XF 0 "register_operand" "")
7518 (mult:XF (match_operand:XF 1 "register_operand" "")
7519 (match_operand:XF 2 "register_operand" "")))]
7520 "!TARGET_64BIT && TARGET_80387"
7521 "")
7522
7523 (define_expand "multf3"
7524 [(set (match_operand:TF 0 "register_operand" "")
7525 (mult:TF (match_operand:TF 1 "register_operand" "")
7526 (match_operand:TF 2 "register_operand" "")))]
7527 "TARGET_80387"
7528 "")
7529
7530 (define_expand "muldf3"
7531 [(set (match_operand:DF 0 "register_operand" "")
7532 (mult:DF (match_operand:DF 1 "register_operand" "")
7533 (match_operand:DF 2 "nonimmediate_operand" "")))]
7534 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7535 "")
7536
7537 (define_expand "mulsf3"
7538 [(set (match_operand:SF 0 "register_operand" "")
7539 (mult:SF (match_operand:SF 1 "register_operand" "")
7540 (match_operand:SF 2 "nonimmediate_operand" "")))]
7541 "TARGET_80387 || TARGET_SSE_MATH"
7542 "")
7543 \f
7544 ;; Divide instructions
7545
7546 (define_insn "divqi3"
7547 [(set (match_operand:QI 0 "register_operand" "=a")
7548 (div:QI (match_operand:HI 1 "register_operand" "0")
7549 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7550 (clobber (reg:CC 17))]
7551 "TARGET_QIMODE_MATH"
7552 "idiv{b}\t%2"
7553 [(set_attr "type" "idiv")
7554 (set_attr "mode" "QI")
7555 (set_attr "ppro_uops" "few")])
7556
7557 (define_insn "udivqi3"
7558 [(set (match_operand:QI 0 "register_operand" "=a")
7559 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7560 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7561 (clobber (reg:CC 17))]
7562 "TARGET_QIMODE_MATH"
7563 "div{b}\t%2"
7564 [(set_attr "type" "idiv")
7565 (set_attr "mode" "QI")
7566 (set_attr "ppro_uops" "few")])
7567
7568 ;; The patterns that match these are at the end of this file.
7569
7570 (define_expand "divxf3"
7571 [(set (match_operand:XF 0 "register_operand" "")
7572 (div:XF (match_operand:XF 1 "register_operand" "")
7573 (match_operand:XF 2 "register_operand" "")))]
7574 "!TARGET_64BIT && TARGET_80387"
7575 "")
7576
7577 (define_expand "divtf3"
7578 [(set (match_operand:TF 0 "register_operand" "")
7579 (div:TF (match_operand:TF 1 "register_operand" "")
7580 (match_operand:TF 2 "register_operand" "")))]
7581 "TARGET_80387"
7582 "")
7583
7584 (define_expand "divdf3"
7585 [(set (match_operand:DF 0 "register_operand" "")
7586 (div:DF (match_operand:DF 1 "register_operand" "")
7587 (match_operand:DF 2 "nonimmediate_operand" "")))]
7588 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7589 "")
7590
7591 (define_expand "divsf3"
7592 [(set (match_operand:SF 0 "register_operand" "")
7593 (div:SF (match_operand:SF 1 "register_operand" "")
7594 (match_operand:SF 2 "nonimmediate_operand" "")))]
7595 "TARGET_80387 || TARGET_SSE_MATH"
7596 "")
7597 \f
7598 ;; Remainder instructions.
7599
7600 (define_expand "divmoddi4"
7601 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7602 (div:DI (match_operand:DI 1 "register_operand" "")
7603 (match_operand:DI 2 "nonimmediate_operand" "")))
7604 (set (match_operand:DI 3 "register_operand" "")
7605 (mod:DI (match_dup 1) (match_dup 2)))
7606 (clobber (reg:CC 17))])]
7607 "TARGET_64BIT"
7608 "")
7609
7610 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7611 ;; Penalize eax case sligthly because it results in worse scheduling
7612 ;; of code.
7613 (define_insn "*divmoddi4_nocltd_rex64"
7614 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7615 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7616 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7617 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7618 (mod:DI (match_dup 2) (match_dup 3)))
7619 (clobber (reg:CC 17))]
7620 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7621 "#"
7622 [(set_attr "type" "multi")])
7623
7624 (define_insn "*divmoddi4_cltd_rex64"
7625 [(set (match_operand:DI 0 "register_operand" "=a")
7626 (div:DI (match_operand:DI 2 "register_operand" "a")
7627 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7628 (set (match_operand:DI 1 "register_operand" "=&d")
7629 (mod:DI (match_dup 2) (match_dup 3)))
7630 (clobber (reg:CC 17))]
7631 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7632 "#"
7633 [(set_attr "type" "multi")])
7634
7635 (define_insn "*divmoddi_noext_rex64"
7636 [(set (match_operand:DI 0 "register_operand" "=a")
7637 (div:DI (match_operand:DI 1 "register_operand" "0")
7638 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7639 (set (match_operand:DI 3 "register_operand" "=d")
7640 (mod:DI (match_dup 1) (match_dup 2)))
7641 (use (match_operand:DI 4 "register_operand" "3"))
7642 (clobber (reg:CC 17))]
7643 "TARGET_64BIT"
7644 "idiv{q}\t%2"
7645 [(set_attr "type" "idiv")
7646 (set_attr "mode" "DI")
7647 (set_attr "ppro_uops" "few")])
7648
7649 (define_split
7650 [(set (match_operand:DI 0 "register_operand" "")
7651 (div:DI (match_operand:DI 1 "register_operand" "")
7652 (match_operand:DI 2 "nonimmediate_operand" "")))
7653 (set (match_operand:DI 3 "register_operand" "")
7654 (mod:DI (match_dup 1) (match_dup 2)))
7655 (clobber (reg:CC 17))]
7656 "TARGET_64BIT && reload_completed"
7657 [(parallel [(set (match_dup 3)
7658 (ashiftrt:DI (match_dup 4) (const_int 63)))
7659 (clobber (reg:CC 17))])
7660 (parallel [(set (match_dup 0)
7661 (div:DI (reg:DI 0) (match_dup 2)))
7662 (set (match_dup 3)
7663 (mod:DI (reg:DI 0) (match_dup 2)))
7664 (use (match_dup 3))
7665 (clobber (reg:CC 17))])]
7666 {
7667 /* Avoid use of cltd in favour of a mov+shift. */
7668 if (!TARGET_USE_CLTD && !optimize_size)
7669 {
7670 if (true_regnum (operands[1]))
7671 emit_move_insn (operands[0], operands[1]);
7672 else
7673 emit_move_insn (operands[3], operands[1]);
7674 operands[4] = operands[3];
7675 }
7676 else
7677 {
7678 if (true_regnum (operands[1]))
7679 abort();
7680 operands[4] = operands[1];
7681 }
7682 })
7683
7684
7685 (define_expand "divmodsi4"
7686 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7687 (div:SI (match_operand:SI 1 "register_operand" "")
7688 (match_operand:SI 2 "nonimmediate_operand" "")))
7689 (set (match_operand:SI 3 "register_operand" "")
7690 (mod:SI (match_dup 1) (match_dup 2)))
7691 (clobber (reg:CC 17))])]
7692 ""
7693 "")
7694
7695 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7696 ;; Penalize eax case sligthly because it results in worse scheduling
7697 ;; of code.
7698 (define_insn "*divmodsi4_nocltd"
7699 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7700 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7701 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7702 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7703 (mod:SI (match_dup 2) (match_dup 3)))
7704 (clobber (reg:CC 17))]
7705 "!optimize_size && !TARGET_USE_CLTD"
7706 "#"
7707 [(set_attr "type" "multi")])
7708
7709 (define_insn "*divmodsi4_cltd"
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (div:SI (match_operand:SI 2 "register_operand" "a")
7712 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7713 (set (match_operand:SI 1 "register_operand" "=&d")
7714 (mod:SI (match_dup 2) (match_dup 3)))
7715 (clobber (reg:CC 17))]
7716 "optimize_size || TARGET_USE_CLTD"
7717 "#"
7718 [(set_attr "type" "multi")])
7719
7720 (define_insn "*divmodsi_noext"
7721 [(set (match_operand:SI 0 "register_operand" "=a")
7722 (div:SI (match_operand:SI 1 "register_operand" "0")
7723 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7724 (set (match_operand:SI 3 "register_operand" "=d")
7725 (mod:SI (match_dup 1) (match_dup 2)))
7726 (use (match_operand:SI 4 "register_operand" "3"))
7727 (clobber (reg:CC 17))]
7728 ""
7729 "idiv{l}\t%2"
7730 [(set_attr "type" "idiv")
7731 (set_attr "mode" "SI")
7732 (set_attr "ppro_uops" "few")])
7733
7734 (define_split
7735 [(set (match_operand:SI 0 "register_operand" "")
7736 (div:SI (match_operand:SI 1 "register_operand" "")
7737 (match_operand:SI 2 "nonimmediate_operand" "")))
7738 (set (match_operand:SI 3 "register_operand" "")
7739 (mod:SI (match_dup 1) (match_dup 2)))
7740 (clobber (reg:CC 17))]
7741 "reload_completed"
7742 [(parallel [(set (match_dup 3)
7743 (ashiftrt:SI (match_dup 4) (const_int 31)))
7744 (clobber (reg:CC 17))])
7745 (parallel [(set (match_dup 0)
7746 (div:SI (reg:SI 0) (match_dup 2)))
7747 (set (match_dup 3)
7748 (mod:SI (reg:SI 0) (match_dup 2)))
7749 (use (match_dup 3))
7750 (clobber (reg:CC 17))])]
7751 {
7752 /* Avoid use of cltd in favour of a mov+shift. */
7753 if (!TARGET_USE_CLTD && !optimize_size)
7754 {
7755 if (true_regnum (operands[1]))
7756 emit_move_insn (operands[0], operands[1]);
7757 else
7758 emit_move_insn (operands[3], operands[1]);
7759 operands[4] = operands[3];
7760 }
7761 else
7762 {
7763 if (true_regnum (operands[1]))
7764 abort();
7765 operands[4] = operands[1];
7766 }
7767 })
7768 ;; %%% Split me.
7769 (define_insn "divmodhi4"
7770 [(set (match_operand:HI 0 "register_operand" "=a")
7771 (div:HI (match_operand:HI 1 "register_operand" "0")
7772 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7773 (set (match_operand:HI 3 "register_operand" "=&d")
7774 (mod:HI (match_dup 1) (match_dup 2)))
7775 (clobber (reg:CC 17))]
7776 "TARGET_HIMODE_MATH"
7777 "cwtd\;idiv{w}\t%2"
7778 [(set_attr "type" "multi")
7779 (set_attr "length_immediate" "0")
7780 (set_attr "mode" "SI")])
7781
7782 (define_insn "udivmoddi4"
7783 [(set (match_operand:DI 0 "register_operand" "=a")
7784 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7785 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7786 (set (match_operand:DI 3 "register_operand" "=&d")
7787 (umod:DI (match_dup 1) (match_dup 2)))
7788 (clobber (reg:CC 17))]
7789 "TARGET_64BIT"
7790 "xor{q}\t%3, %3\;div{q}\t%2"
7791 [(set_attr "type" "multi")
7792 (set_attr "length_immediate" "0")
7793 (set_attr "mode" "DI")])
7794
7795 (define_insn "*udivmoddi4_noext"
7796 [(set (match_operand:DI 0 "register_operand" "=a")
7797 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7798 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7799 (set (match_operand:DI 3 "register_operand" "=d")
7800 (umod:DI (match_dup 1) (match_dup 2)))
7801 (use (match_dup 3))
7802 (clobber (reg:CC 17))]
7803 "TARGET_64BIT"
7804 "div{q}\t%2"
7805 [(set_attr "type" "idiv")
7806 (set_attr "ppro_uops" "few")
7807 (set_attr "mode" "DI")])
7808
7809 (define_split
7810 [(set (match_operand:DI 0 "register_operand" "")
7811 (udiv:DI (match_operand:DI 1 "register_operand" "")
7812 (match_operand:DI 2 "nonimmediate_operand" "")))
7813 (set (match_operand:DI 3 "register_operand" "")
7814 (umod:DI (match_dup 1) (match_dup 2)))
7815 (clobber (reg:CC 17))]
7816 "TARGET_64BIT && reload_completed"
7817 [(set (match_dup 3) (const_int 0))
7818 (parallel [(set (match_dup 0)
7819 (udiv:DI (match_dup 1) (match_dup 2)))
7820 (set (match_dup 3)
7821 (umod:DI (match_dup 1) (match_dup 2)))
7822 (use (match_dup 3))
7823 (clobber (reg:CC 17))])]
7824 "")
7825
7826 (define_insn "udivmodsi4"
7827 [(set (match_operand:SI 0 "register_operand" "=a")
7828 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7829 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7830 (set (match_operand:SI 3 "register_operand" "=&d")
7831 (umod:SI (match_dup 1) (match_dup 2)))
7832 (clobber (reg:CC 17))]
7833 ""
7834 "xor{l}\t%3, %3\;div{l}\t%2"
7835 [(set_attr "type" "multi")
7836 (set_attr "length_immediate" "0")
7837 (set_attr "mode" "SI")])
7838
7839 (define_insn "*udivmodsi4_noext"
7840 [(set (match_operand:SI 0 "register_operand" "=a")
7841 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7842 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7843 (set (match_operand:SI 3 "register_operand" "=d")
7844 (umod:SI (match_dup 1) (match_dup 2)))
7845 (use (match_dup 3))
7846 (clobber (reg:CC 17))]
7847 ""
7848 "div{l}\t%2"
7849 [(set_attr "type" "idiv")
7850 (set_attr "ppro_uops" "few")
7851 (set_attr "mode" "SI")])
7852
7853 (define_split
7854 [(set (match_operand:SI 0 "register_operand" "")
7855 (udiv:SI (match_operand:SI 1 "register_operand" "")
7856 (match_operand:SI 2 "nonimmediate_operand" "")))
7857 (set (match_operand:SI 3 "register_operand" "")
7858 (umod:SI (match_dup 1) (match_dup 2)))
7859 (clobber (reg:CC 17))]
7860 "reload_completed"
7861 [(set (match_dup 3) (const_int 0))
7862 (parallel [(set (match_dup 0)
7863 (udiv:SI (match_dup 1) (match_dup 2)))
7864 (set (match_dup 3)
7865 (umod:SI (match_dup 1) (match_dup 2)))
7866 (use (match_dup 3))
7867 (clobber (reg:CC 17))])]
7868 "")
7869
7870 (define_expand "udivmodhi4"
7871 [(set (match_dup 4) (const_int 0))
7872 (parallel [(set (match_operand:HI 0 "register_operand" "")
7873 (udiv:HI (match_operand:HI 1 "register_operand" "")
7874 (match_operand:HI 2 "nonimmediate_operand" "")))
7875 (set (match_operand:HI 3 "register_operand" "")
7876 (umod:HI (match_dup 1) (match_dup 2)))
7877 (use (match_dup 4))
7878 (clobber (reg:CC 17))])]
7879 "TARGET_HIMODE_MATH"
7880 "operands[4] = gen_reg_rtx (HImode);")
7881
7882 (define_insn "*udivmodhi_noext"
7883 [(set (match_operand:HI 0 "register_operand" "=a")
7884 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7885 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7886 (set (match_operand:HI 3 "register_operand" "=d")
7887 (umod:HI (match_dup 1) (match_dup 2)))
7888 (use (match_operand:HI 4 "register_operand" "3"))
7889 (clobber (reg:CC 17))]
7890 ""
7891 "div{w}\t%2"
7892 [(set_attr "type" "idiv")
7893 (set_attr "mode" "HI")
7894 (set_attr "ppro_uops" "few")])
7895
7896 ;; We can not use div/idiv for double division, because it causes
7897 ;; "division by zero" on the overflow and that's not what we expect
7898 ;; from truncate. Because true (non truncating) double division is
7899 ;; never generated, we can't create this insn anyway.
7900 ;
7901 ;(define_insn ""
7902 ; [(set (match_operand:SI 0 "register_operand" "=a")
7903 ; (truncate:SI
7904 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7905 ; (zero_extend:DI
7906 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7907 ; (set (match_operand:SI 3 "register_operand" "=d")
7908 ; (truncate:SI
7909 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7910 ; (clobber (reg:CC 17))]
7911 ; ""
7912 ; "div{l}\t{%2, %0|%0, %2}"
7913 ; [(set_attr "type" "idiv")
7914 ; (set_attr "ppro_uops" "few")])
7915 \f
7916 ;;- Logical AND instructions
7917
7918 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7919 ;; Note that this excludes ah.
7920
7921 (define_insn "*testdi_1_rex64"
7922 [(set (reg 17)
7923 (compare
7924 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7925 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7926 (const_int 0)))]
7927 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7928 "@
7929 test{l}\t{%k1, %k0|%k0, %k1}
7930 test{l}\t{%k1, %k0|%k0, %k1}
7931 test{q}\t{%1, %0|%0, %1}
7932 test{q}\t{%1, %0|%0, %1}
7933 test{q}\t{%1, %0|%0, %1}"
7934 [(set_attr "type" "test")
7935 (set_attr "modrm" "0,1,0,1,1")
7936 (set_attr "mode" "SI,SI,DI,DI,DI")
7937 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7938
7939 (define_insn "testsi_1"
7940 [(set (reg 17)
7941 (compare
7942 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7943 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7944 (const_int 0)))]
7945 "ix86_match_ccmode (insn, CCNOmode)"
7946 "test{l}\t{%1, %0|%0, %1}"
7947 [(set_attr "type" "test")
7948 (set_attr "modrm" "0,1,1")
7949 (set_attr "mode" "SI")
7950 (set_attr "pent_pair" "uv,np,uv")])
7951
7952 (define_expand "testsi_ccno_1"
7953 [(set (reg:CCNO 17)
7954 (compare:CCNO
7955 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7956 (match_operand:SI 1 "nonmemory_operand" ""))
7957 (const_int 0)))]
7958 ""
7959 "")
7960
7961 (define_insn "*testhi_1"
7962 [(set (reg 17)
7963 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7964 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7965 (const_int 0)))]
7966 "ix86_match_ccmode (insn, CCNOmode)"
7967 "test{w}\t{%1, %0|%0, %1}"
7968 [(set_attr "type" "test")
7969 (set_attr "modrm" "0,1,1")
7970 (set_attr "mode" "HI")
7971 (set_attr "pent_pair" "uv,np,uv")])
7972
7973 (define_expand "testqi_ccz_1"
7974 [(set (reg:CCZ 17)
7975 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7976 (match_operand:QI 1 "nonmemory_operand" ""))
7977 (const_int 0)))]
7978 ""
7979 "")
7980
7981 (define_insn "*testqi_1"
7982 [(set (reg 17)
7983 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7984 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7985 (const_int 0)))]
7986 "ix86_match_ccmode (insn, CCNOmode)"
7987 {
7988 if (which_alternative == 3)
7989 {
7990 if (GET_CODE (operands[1]) == CONST_INT
7991 && (INTVAL (operands[1]) & 0xffffff00))
7992 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7993 return "test{l}\t{%1, %k0|%k0, %1}";
7994 }
7995 return "test{b}\t{%1, %0|%0, %1}";
7996 }
7997 [(set_attr "type" "test")
7998 (set_attr "modrm" "0,1,1,1")
7999 (set_attr "mode" "QI,QI,QI,SI")
8000 (set_attr "pent_pair" "uv,np,uv,np")])
8001
8002 (define_expand "testqi_ext_ccno_0"
8003 [(set (reg:CCNO 17)
8004 (compare:CCNO
8005 (and:SI
8006 (zero_extract:SI
8007 (match_operand 0 "ext_register_operand" "")
8008 (const_int 8)
8009 (const_int 8))
8010 (match_operand 1 "const_int_operand" ""))
8011 (const_int 0)))]
8012 ""
8013 "")
8014
8015 (define_insn "*testqi_ext_0"
8016 [(set (reg 17)
8017 (compare
8018 (and:SI
8019 (zero_extract:SI
8020 (match_operand 0 "ext_register_operand" "Q")
8021 (const_int 8)
8022 (const_int 8))
8023 (match_operand 1 "const_int_operand" "n"))
8024 (const_int 0)))]
8025 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8026 && ix86_match_ccmode (insn, CCNOmode)"
8027 "test{b}\t{%1, %h0|%h0, %1}"
8028 [(set_attr "type" "test")
8029 (set_attr "mode" "QI")
8030 (set_attr "length_immediate" "1")
8031 (set_attr "pent_pair" "np")])
8032
8033 (define_insn "*testqi_ext_1"
8034 [(set (reg 17)
8035 (compare
8036 (and:SI
8037 (zero_extract:SI
8038 (match_operand 0 "ext_register_operand" "Q")
8039 (const_int 8)
8040 (const_int 8))
8041 (zero_extend:SI
8042 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8043 (const_int 0)))]
8044 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8045 "test{b}\t{%1, %h0|%h0, %1}"
8046 [(set_attr "type" "test")
8047 (set_attr "mode" "QI")])
8048
8049 (define_insn "*testqi_ext_1_rex64"
8050 [(set (reg 17)
8051 (compare
8052 (and:SI
8053 (zero_extract:SI
8054 (match_operand 0 "ext_register_operand" "Q")
8055 (const_int 8)
8056 (const_int 8))
8057 (zero_extend:SI
8058 (match_operand:QI 1 "register_operand" "Q")))
8059 (const_int 0)))]
8060 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8061 "test{b}\t{%1, %h0|%h0, %1}"
8062 [(set_attr "type" "test")
8063 (set_attr "mode" "QI")])
8064
8065 (define_insn "*testqi_ext_2"
8066 [(set (reg 17)
8067 (compare
8068 (and:SI
8069 (zero_extract:SI
8070 (match_operand 0 "ext_register_operand" "Q")
8071 (const_int 8)
8072 (const_int 8))
8073 (zero_extract:SI
8074 (match_operand 1 "ext_register_operand" "Q")
8075 (const_int 8)
8076 (const_int 8)))
8077 (const_int 0)))]
8078 "ix86_match_ccmode (insn, CCNOmode)"
8079 "test{b}\t{%h1, %h0|%h0, %h1}"
8080 [(set_attr "type" "test")
8081 (set_attr "mode" "QI")])
8082
8083 ;; Combine likes to form bit extractions for some tests. Humor it.
8084 (define_insn "*testqi_ext_3"
8085 [(set (reg 17)
8086 (compare (zero_extract:SI
8087 (match_operand 0 "nonimmediate_operand" "rm")
8088 (match_operand:SI 1 "const_int_operand" "")
8089 (match_operand:SI 2 "const_int_operand" ""))
8090 (const_int 0)))]
8091 "ix86_match_ccmode (insn, CCNOmode)
8092 && (GET_MODE (operands[0]) == SImode
8093 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8094 || GET_MODE (operands[0]) == HImode
8095 || GET_MODE (operands[0]) == QImode)"
8096 "#")
8097
8098 (define_insn "*testqi_ext_3_rex64"
8099 [(set (reg 17)
8100 (compare (zero_extract:DI
8101 (match_operand 0 "nonimmediate_operand" "rm")
8102 (match_operand:DI 1 "const_int_operand" "")
8103 (match_operand:DI 2 "const_int_operand" ""))
8104 (const_int 0)))]
8105 "TARGET_64BIT
8106 && ix86_match_ccmode (insn, CCNOmode)
8107 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8108 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8109 /* Ensure that resulting mask is zero or sign extended operand. */
8110 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8111 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8112 && INTVAL (operands[1]) > 32))
8113 && (GET_MODE (operands[0]) == SImode
8114 || GET_MODE (operands[0]) == DImode
8115 || GET_MODE (operands[0]) == HImode
8116 || GET_MODE (operands[0]) == QImode)"
8117 "#")
8118
8119 (define_split
8120 [(set (reg 17)
8121 (compare (zero_extract
8122 (match_operand 0 "nonimmediate_operand" "")
8123 (match_operand 1 "const_int_operand" "")
8124 (match_operand 2 "const_int_operand" ""))
8125 (const_int 0)))]
8126 "ix86_match_ccmode (insn, CCNOmode)"
8127 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8128 {
8129 HOST_WIDE_INT len = INTVAL (operands[1]);
8130 HOST_WIDE_INT pos = INTVAL (operands[2]);
8131 HOST_WIDE_INT mask;
8132 enum machine_mode mode, submode;
8133
8134 mode = GET_MODE (operands[0]);
8135 if (GET_CODE (operands[0]) == MEM)
8136 {
8137 /* ??? Combine likes to put non-volatile mem extractions in QImode
8138 no matter the size of the test. So find a mode that works. */
8139 if (! MEM_VOLATILE_P (operands[0]))
8140 {
8141 mode = smallest_mode_for_size (pos + len, MODE_INT);
8142 operands[0] = adjust_address (operands[0], mode, 0);
8143 }
8144 }
8145 else if (GET_CODE (operands[0]) == SUBREG
8146 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8147 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8148 && pos + len <= GET_MODE_BITSIZE (submode))
8149 {
8150 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8151 mode = submode;
8152 operands[0] = SUBREG_REG (operands[0]);
8153 }
8154 else if (mode == HImode && pos + len <= 8)
8155 {
8156 /* Small HImode tests can be converted to QImode. */
8157 mode = QImode;
8158 operands[0] = gen_lowpart (QImode, operands[0]);
8159 }
8160
8161 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8162 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8163
8164 operands[3] = gen_rtx_AND (mode, operands[0],
8165 GEN_INT (trunc_int_for_mode (mask, mode)));
8166 })
8167
8168 ;; %%% This used to optimize known byte-wide and operations to memory,
8169 ;; and sometimes to QImode registers. If this is considered useful,
8170 ;; it should be done with splitters.
8171
8172 (define_expand "anddi3"
8173 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8174 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8175 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8176 (clobber (reg:CC 17))]
8177 "TARGET_64BIT"
8178 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8179
8180 (define_insn "*anddi_1_rex64"
8181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8182 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8183 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8184 (clobber (reg:CC 17))]
8185 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8186 {
8187 switch (get_attr_type (insn))
8188 {
8189 case TYPE_IMOVX:
8190 {
8191 enum machine_mode mode;
8192
8193 if (GET_CODE (operands[2]) != CONST_INT)
8194 abort ();
8195 if (INTVAL (operands[2]) == 0xff)
8196 mode = QImode;
8197 else if (INTVAL (operands[2]) == 0xffff)
8198 mode = HImode;
8199 else
8200 abort ();
8201
8202 operands[1] = gen_lowpart (mode, operands[1]);
8203 if (mode == QImode)
8204 return "movz{bq|x}\t{%1,%0|%0, %1}";
8205 else
8206 return "movz{wq|x}\t{%1,%0|%0, %1}";
8207 }
8208
8209 default:
8210 if (! rtx_equal_p (operands[0], operands[1]))
8211 abort ();
8212 if (get_attr_mode (insn) == MODE_SI)
8213 return "and{l}\t{%k2, %k0|%k0, %k2}";
8214 else
8215 return "and{q}\t{%2, %0|%0, %2}";
8216 }
8217 }
8218 [(set_attr "type" "alu,alu,alu,imovx")
8219 (set_attr "length_immediate" "*,*,*,0")
8220 (set_attr "mode" "SI,DI,DI,DI")])
8221
8222 (define_insn "*anddi_2"
8223 [(set (reg 17)
8224 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8225 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8226 (const_int 0)))
8227 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8228 (and:DI (match_dup 1) (match_dup 2)))]
8229 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8230 && ix86_binary_operator_ok (AND, DImode, operands)"
8231 "@
8232 and{l}\t{%k2, %k0|%k0, %k2}
8233 and{q}\t{%2, %0|%0, %2}
8234 and{q}\t{%2, %0|%0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "SI,DI,DI")])
8237
8238 (define_expand "andsi3"
8239 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8240 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8241 (match_operand:SI 2 "general_operand" "")))
8242 (clobber (reg:CC 17))]
8243 ""
8244 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8245
8246 (define_insn "*andsi_1"
8247 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8248 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8249 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8250 (clobber (reg:CC 17))]
8251 "ix86_binary_operator_ok (AND, SImode, operands)"
8252 {
8253 switch (get_attr_type (insn))
8254 {
8255 case TYPE_IMOVX:
8256 {
8257 enum machine_mode mode;
8258
8259 if (GET_CODE (operands[2]) != CONST_INT)
8260 abort ();
8261 if (INTVAL (operands[2]) == 0xff)
8262 mode = QImode;
8263 else if (INTVAL (operands[2]) == 0xffff)
8264 mode = HImode;
8265 else
8266 abort ();
8267
8268 operands[1] = gen_lowpart (mode, operands[1]);
8269 if (mode == QImode)
8270 return "movz{bl|x}\t{%1,%0|%0, %1}";
8271 else
8272 return "movz{wl|x}\t{%1,%0|%0, %1}";
8273 }
8274
8275 default:
8276 if (! rtx_equal_p (operands[0], operands[1]))
8277 abort ();
8278 return "and{l}\t{%2, %0|%0, %2}";
8279 }
8280 }
8281 [(set_attr "type" "alu,alu,imovx")
8282 (set_attr "length_immediate" "*,*,0")
8283 (set_attr "mode" "SI")])
8284
8285 (define_split
8286 [(set (match_operand 0 "register_operand" "")
8287 (and (match_dup 0)
8288 (const_int -65536)))
8289 (clobber (reg:CC 17))]
8290 "optimize_size"
8291 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8292 "operands[1] = gen_lowpart (HImode, operands[0]);")
8293
8294 (define_split
8295 [(set (match_operand 0 "ext_register_operand" "")
8296 (and (match_dup 0)
8297 (const_int -256)))
8298 (clobber (reg:CC 17))]
8299 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8300 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8301 "operands[1] = gen_lowpart (QImode, operands[0]);")
8302
8303 (define_split
8304 [(set (match_operand 0 "ext_register_operand" "")
8305 (and (match_dup 0)
8306 (const_int -65281)))
8307 (clobber (reg:CC 17))]
8308 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8309 [(parallel [(set (zero_extract:SI (match_dup 0)
8310 (const_int 8)
8311 (const_int 8))
8312 (xor:SI
8313 (zero_extract:SI (match_dup 0)
8314 (const_int 8)
8315 (const_int 8))
8316 (zero_extract:SI (match_dup 0)
8317 (const_int 8)
8318 (const_int 8))))
8319 (clobber (reg:CC 17))])]
8320 "operands[0] = gen_lowpart (SImode, operands[0]);")
8321
8322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8323 (define_insn "*andsi_1_zext"
8324 [(set (match_operand:DI 0 "register_operand" "=r")
8325 (zero_extend:DI
8326 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8327 (match_operand:SI 2 "general_operand" "rim"))))
8328 (clobber (reg:CC 17))]
8329 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8330 "and{l}\t{%2, %k0|%k0, %2}"
8331 [(set_attr "type" "alu")
8332 (set_attr "mode" "SI")])
8333
8334 (define_insn "*andsi_2"
8335 [(set (reg 17)
8336 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8337 (match_operand:SI 2 "general_operand" "rim,ri"))
8338 (const_int 0)))
8339 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8340 (and:SI (match_dup 1) (match_dup 2)))]
8341 "ix86_match_ccmode (insn, CCNOmode)
8342 && ix86_binary_operator_ok (AND, SImode, operands)"
8343 "and{l}\t{%2, %0|%0, %2}"
8344 [(set_attr "type" "alu")
8345 (set_attr "mode" "SI")])
8346
8347 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8348 (define_insn "*andsi_2_zext"
8349 [(set (reg 17)
8350 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8351 (match_operand:SI 2 "general_operand" "rim"))
8352 (const_int 0)))
8353 (set (match_operand:DI 0 "register_operand" "=r")
8354 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8355 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8356 && ix86_binary_operator_ok (AND, SImode, operands)"
8357 "and{l}\t{%2, %k0|%k0, %2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "mode" "SI")])
8360
8361 (define_expand "andhi3"
8362 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8363 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8364 (match_operand:HI 2 "general_operand" "")))
8365 (clobber (reg:CC 17))]
8366 "TARGET_HIMODE_MATH"
8367 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8368
8369 (define_insn "*andhi_1"
8370 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8371 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8372 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8373 (clobber (reg:CC 17))]
8374 "ix86_binary_operator_ok (AND, HImode, operands)"
8375 {
8376 switch (get_attr_type (insn))
8377 {
8378 case TYPE_IMOVX:
8379 if (GET_CODE (operands[2]) != CONST_INT)
8380 abort ();
8381 if (INTVAL (operands[2]) == 0xff)
8382 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8383 abort ();
8384
8385 default:
8386 if (! rtx_equal_p (operands[0], operands[1]))
8387 abort ();
8388
8389 return "and{w}\t{%2, %0|%0, %2}";
8390 }
8391 }
8392 [(set_attr "type" "alu,alu,imovx")
8393 (set_attr "length_immediate" "*,*,0")
8394 (set_attr "mode" "HI,HI,SI")])
8395
8396 (define_insn "*andhi_2"
8397 [(set (reg 17)
8398 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8399 (match_operand:HI 2 "general_operand" "rim,ri"))
8400 (const_int 0)))
8401 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8402 (and:HI (match_dup 1) (match_dup 2)))]
8403 "ix86_match_ccmode (insn, CCNOmode)
8404 && ix86_binary_operator_ok (AND, HImode, operands)"
8405 "and{w}\t{%2, %0|%0, %2}"
8406 [(set_attr "type" "alu")
8407 (set_attr "mode" "HI")])
8408
8409 (define_expand "andqi3"
8410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8411 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8412 (match_operand:QI 2 "general_operand" "")))
8413 (clobber (reg:CC 17))]
8414 "TARGET_QIMODE_MATH"
8415 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8416
8417 ;; %%% Potential partial reg stall on alternative 2. What to do?
8418 (define_insn "*andqi_1"
8419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8420 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8421 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8422 (clobber (reg:CC 17))]
8423 "ix86_binary_operator_ok (AND, QImode, operands)"
8424 "@
8425 and{b}\t{%2, %0|%0, %2}
8426 and{b}\t{%2, %0|%0, %2}
8427 and{l}\t{%k2, %k0|%k0, %k2}"
8428 [(set_attr "type" "alu")
8429 (set_attr "mode" "QI,QI,SI")])
8430
8431 (define_insn "*andqi_1_slp"
8432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8433 (and:QI (match_dup 0)
8434 (match_operand:QI 1 "general_operand" "qi,qmi")))
8435 (clobber (reg:CC 17))]
8436 ""
8437 "and{b}\t{%1, %0|%0, %1}"
8438 [(set_attr "type" "alu1")
8439 (set_attr "mode" "QI")])
8440
8441 (define_insn "*andqi_2"
8442 [(set (reg 17)
8443 (compare (and:QI
8444 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8445 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8446 (const_int 0)))
8447 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8448 (and:QI (match_dup 1) (match_dup 2)))]
8449 "ix86_match_ccmode (insn, CCNOmode)
8450 && ix86_binary_operator_ok (AND, QImode, operands)"
8451 {
8452 if (which_alternative == 2)
8453 {
8454 if (GET_CODE (operands[2]) == CONST_INT
8455 && (INTVAL (operands[2]) & 0xffffff00))
8456 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8457 return "and{l}\t{%2, %k0|%k0, %2}";
8458 }
8459 return "and{b}\t{%2, %0|%0, %2}";
8460 }
8461 [(set_attr "type" "alu")
8462 (set_attr "mode" "QI,QI,SI")])
8463
8464 (define_insn "*andqi_2_slp"
8465 [(set (reg 17)
8466 (compare (and:QI
8467 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8468 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8469 (const_int 0)))
8470 (set (strict_low_part (match_dup 0))
8471 (and:QI (match_dup 0) (match_dup 1)))]
8472 "ix86_match_ccmode (insn, CCNOmode)"
8473 "and{b}\t{%1, %0|%0, %1}"
8474 [(set_attr "type" "alu1")
8475 (set_attr "mode" "QI")])
8476
8477 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8478 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8479 ;; for a QImode operand, which of course failed.
8480
8481 (define_insn "andqi_ext_0"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (const_int 8)
8484 (const_int 8))
8485 (and:SI
8486 (zero_extract:SI
8487 (match_operand 1 "ext_register_operand" "0")
8488 (const_int 8)
8489 (const_int 8))
8490 (match_operand 2 "const_int_operand" "n")))
8491 (clobber (reg:CC 17))]
8492 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8493 "and{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "length_immediate" "1")
8496 (set_attr "mode" "QI")])
8497
8498 ;; Generated by peephole translating test to and. This shows up
8499 ;; often in fp comparisons.
8500
8501 (define_insn "*andqi_ext_0_cc"
8502 [(set (reg 17)
8503 (compare
8504 (and:SI
8505 (zero_extract:SI
8506 (match_operand 1 "ext_register_operand" "0")
8507 (const_int 8)
8508 (const_int 8))
8509 (match_operand 2 "const_int_operand" "n"))
8510 (const_int 0)))
8511 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8512 (const_int 8)
8513 (const_int 8))
8514 (and:SI
8515 (zero_extract:SI
8516 (match_dup 1)
8517 (const_int 8)
8518 (const_int 8))
8519 (match_dup 2)))]
8520 "ix86_match_ccmode (insn, CCNOmode)
8521 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8522 "and{b}\t{%2, %h0|%h0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "length_immediate" "1")
8525 (set_attr "mode" "QI")])
8526
8527 (define_insn "*andqi_ext_1"
8528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8529 (const_int 8)
8530 (const_int 8))
8531 (and:SI
8532 (zero_extract:SI
8533 (match_operand 1 "ext_register_operand" "0")
8534 (const_int 8)
8535 (const_int 8))
8536 (zero_extend:SI
8537 (match_operand:QI 2 "general_operand" "Qm"))))
8538 (clobber (reg:CC 17))]
8539 "!TARGET_64BIT"
8540 "and{b}\t{%2, %h0|%h0, %2}"
8541 [(set_attr "type" "alu")
8542 (set_attr "length_immediate" "0")
8543 (set_attr "mode" "QI")])
8544
8545 (define_insn "*andqi_ext_1_rex64"
8546 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8547 (const_int 8)
8548 (const_int 8))
8549 (and:SI
8550 (zero_extract:SI
8551 (match_operand 1 "ext_register_operand" "0")
8552 (const_int 8)
8553 (const_int 8))
8554 (zero_extend:SI
8555 (match_operand 2 "ext_register_operand" "Q"))))
8556 (clobber (reg:CC 17))]
8557 "TARGET_64BIT"
8558 "and{b}\t{%2, %h0|%h0, %2}"
8559 [(set_attr "type" "alu")
8560 (set_attr "length_immediate" "0")
8561 (set_attr "mode" "QI")])
8562
8563 (define_insn "*andqi_ext_2"
8564 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8565 (const_int 8)
8566 (const_int 8))
8567 (and:SI
8568 (zero_extract:SI
8569 (match_operand 1 "ext_register_operand" "%0")
8570 (const_int 8)
8571 (const_int 8))
8572 (zero_extract:SI
8573 (match_operand 2 "ext_register_operand" "Q")
8574 (const_int 8)
8575 (const_int 8))))
8576 (clobber (reg:CC 17))]
8577 ""
8578 "and{b}\t{%h2, %h0|%h0, %h2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "length_immediate" "0")
8581 (set_attr "mode" "QI")])
8582 \f
8583 ;; Logical inclusive OR instructions
8584
8585 ;; %%% This used to optimize known byte-wide and operations to memory.
8586 ;; If this is considered useful, it should be done with splitters.
8587
8588 (define_expand "iordi3"
8589 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8590 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8591 (match_operand:DI 2 "x86_64_general_operand" "")))
8592 (clobber (reg:CC 17))]
8593 "TARGET_64BIT"
8594 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8595
8596 (define_insn "*iordi_1_rex64"
8597 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8598 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8599 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8600 (clobber (reg:CC 17))]
8601 "TARGET_64BIT
8602 && ix86_binary_operator_ok (IOR, DImode, operands)"
8603 "or{q}\t{%2, %0|%0, %2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "mode" "DI")])
8606
8607 (define_insn "*iordi_2_rex64"
8608 [(set (reg 17)
8609 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8610 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8611 (const_int 0)))
8612 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8613 (ior:DI (match_dup 1) (match_dup 2)))]
8614 "TARGET_64BIT
8615 && ix86_match_ccmode (insn, CCNOmode)
8616 && ix86_binary_operator_ok (IOR, DImode, operands)"
8617 "or{q}\t{%2, %0|%0, %2}"
8618 [(set_attr "type" "alu")
8619 (set_attr "mode" "DI")])
8620
8621 (define_insn "*iordi_3_rex64"
8622 [(set (reg 17)
8623 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8624 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8625 (const_int 0)))
8626 (clobber (match_scratch:DI 0 "=r"))]
8627 "TARGET_64BIT
8628 && ix86_match_ccmode (insn, CCNOmode)
8629 && ix86_binary_operator_ok (IOR, DImode, operands)"
8630 "or{q}\t{%2, %0|%0, %2}"
8631 [(set_attr "type" "alu")
8632 (set_attr "mode" "DI")])
8633
8634
8635 (define_expand "iorsi3"
8636 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8637 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8638 (match_operand:SI 2 "general_operand" "")))
8639 (clobber (reg:CC 17))]
8640 ""
8641 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8642
8643 (define_insn "*iorsi_1"
8644 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8645 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8646 (match_operand:SI 2 "general_operand" "ri,rmi")))
8647 (clobber (reg:CC 17))]
8648 "ix86_binary_operator_ok (IOR, SImode, operands)"
8649 "or{l}\t{%2, %0|%0, %2}"
8650 [(set_attr "type" "alu")
8651 (set_attr "mode" "SI")])
8652
8653 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8654 (define_insn "*iorsi_1_zext"
8655 [(set (match_operand:DI 0 "register_operand" "=rm")
8656 (zero_extend:DI
8657 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8658 (match_operand:SI 2 "general_operand" "rim"))))
8659 (clobber (reg:CC 17))]
8660 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8661 "or{l}\t{%2, %k0|%k0, %2}"
8662 [(set_attr "type" "alu")
8663 (set_attr "mode" "SI")])
8664
8665 (define_insn "*iorsi_1_zext_imm"
8666 [(set (match_operand:DI 0 "register_operand" "=rm")
8667 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8668 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8669 (clobber (reg:CC 17))]
8670 "TARGET_64BIT"
8671 "or{l}\t{%2, %k0|%k0, %2}"
8672 [(set_attr "type" "alu")
8673 (set_attr "mode" "SI")])
8674
8675 (define_insn "*iorsi_2"
8676 [(set (reg 17)
8677 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8678 (match_operand:SI 2 "general_operand" "rim,ri"))
8679 (const_int 0)))
8680 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8681 (ior:SI (match_dup 1) (match_dup 2)))]
8682 "ix86_match_ccmode (insn, CCNOmode)
8683 && ix86_binary_operator_ok (IOR, SImode, operands)"
8684 "or{l}\t{%2, %0|%0, %2}"
8685 [(set_attr "type" "alu")
8686 (set_attr "mode" "SI")])
8687
8688 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8689 ;; ??? Special case for immediate operand is missing - it is tricky.
8690 (define_insn "*iorsi_2_zext"
8691 [(set (reg 17)
8692 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693 (match_operand:SI 2 "general_operand" "rim"))
8694 (const_int 0)))
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8697 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, SImode, operands)"
8699 "or{l}\t{%2, %k0|%k0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "SI")])
8702
8703 (define_insn "*iorsi_2_zext_imm"
8704 [(set (reg 17)
8705 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8707 (const_int 0)))
8708 (set (match_operand:DI 0 "register_operand" "=r")
8709 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8710 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8711 && ix86_binary_operator_ok (IOR, SImode, operands)"
8712 "or{l}\t{%2, %k0|%k0, %2}"
8713 [(set_attr "type" "alu")
8714 (set_attr "mode" "SI")])
8715
8716 (define_insn "*iorsi_3"
8717 [(set (reg 17)
8718 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8719 (match_operand:SI 2 "general_operand" "rim"))
8720 (const_int 0)))
8721 (clobber (match_scratch:SI 0 "=r"))]
8722 "ix86_match_ccmode (insn, CCNOmode)
8723 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8724 "or{l}\t{%2, %0|%0, %2}"
8725 [(set_attr "type" "alu")
8726 (set_attr "mode" "SI")])
8727
8728 (define_expand "iorhi3"
8729 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8730 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8731 (match_operand:HI 2 "general_operand" "")))
8732 (clobber (reg:CC 17))]
8733 "TARGET_HIMODE_MATH"
8734 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8735
8736 (define_insn "*iorhi_1"
8737 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8738 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8739 (match_operand:HI 2 "general_operand" "rmi,ri")))
8740 (clobber (reg:CC 17))]
8741 "ix86_binary_operator_ok (IOR, HImode, operands)"
8742 "or{w}\t{%2, %0|%0, %2}"
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "HI")])
8745
8746 (define_insn "*iorhi_2"
8747 [(set (reg 17)
8748 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8749 (match_operand:HI 2 "general_operand" "rim,ri"))
8750 (const_int 0)))
8751 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8752 (ior:HI (match_dup 1) (match_dup 2)))]
8753 "ix86_match_ccmode (insn, CCNOmode)
8754 && ix86_binary_operator_ok (IOR, HImode, operands)"
8755 "or{w}\t{%2, %0|%0, %2}"
8756 [(set_attr "type" "alu")
8757 (set_attr "mode" "HI")])
8758
8759 (define_insn "*iorhi_3"
8760 [(set (reg 17)
8761 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8762 (match_operand:HI 2 "general_operand" "rim"))
8763 (const_int 0)))
8764 (clobber (match_scratch:HI 0 "=r"))]
8765 "ix86_match_ccmode (insn, CCNOmode)
8766 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8767 "or{w}\t{%2, %0|%0, %2}"
8768 [(set_attr "type" "alu")
8769 (set_attr "mode" "HI")])
8770
8771 (define_expand "iorqi3"
8772 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8773 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8774 (match_operand:QI 2 "general_operand" "")))
8775 (clobber (reg:CC 17))]
8776 "TARGET_QIMODE_MATH"
8777 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8778
8779 ;; %%% Potential partial reg stall on alternative 2. What to do?
8780 (define_insn "*iorqi_1"
8781 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8782 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8783 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8784 (clobber (reg:CC 17))]
8785 "ix86_binary_operator_ok (IOR, QImode, operands)"
8786 "@
8787 or{b}\t{%2, %0|%0, %2}
8788 or{b}\t{%2, %0|%0, %2}
8789 or{l}\t{%k2, %k0|%k0, %k2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "QI,QI,SI")])
8792
8793 (define_insn "*iorqi_1_slp"
8794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8795 (ior:QI (match_dup 0)
8796 (match_operand:QI 1 "general_operand" "qmi,qi")))
8797 (clobber (reg:CC 17))]
8798 ""
8799 "or{b}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "*iorqi_2"
8804 [(set (reg 17)
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8807 (const_int 0)))
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
8812 "or{b}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_2_slp"
8817 [(set (reg 17)
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8820 (const_int 0)))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
8823 "ix86_match_ccmode (insn, CCNOmode)"
8824 "or{b}\t{%1, %0|%0, %1}"
8825 [(set_attr "type" "alu1")
8826 (set_attr "mode" "QI")])
8827
8828 (define_insn "*iorqi_3"
8829 [(set (reg 17)
8830 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8831 (match_operand:QI 2 "general_operand" "qim"))
8832 (const_int 0)))
8833 (clobber (match_scratch:QI 0 "=q"))]
8834 "ix86_match_ccmode (insn, CCNOmode)
8835 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8836 "or{b}\t{%2, %0|%0, %2}"
8837 [(set_attr "type" "alu")
8838 (set_attr "mode" "QI")])
8839
8840 \f
8841 ;; Logical XOR instructions
8842
8843 ;; %%% This used to optimize known byte-wide and operations to memory.
8844 ;; If this is considered useful, it should be done with splitters.
8845
8846 (define_expand "xordi3"
8847 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8848 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8849 (match_operand:DI 2 "x86_64_general_operand" "")))
8850 (clobber (reg:CC 17))]
8851 "TARGET_64BIT"
8852 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8853
8854 (define_insn "*xordi_1_rex64"
8855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8856 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8857 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8858 (clobber (reg:CC 17))]
8859 "TARGET_64BIT
8860 && ix86_binary_operator_ok (XOR, DImode, operands)"
8861 "@
8862 xor{q}\t{%2, %0|%0, %2}
8863 xor{q}\t{%2, %0|%0, %2}"
8864 [(set_attr "type" "alu")
8865 (set_attr "mode" "DI,DI")])
8866
8867 (define_insn "*xordi_2_rex64"
8868 [(set (reg 17)
8869 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8870 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8871 (const_int 0)))
8872 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8873 (xor:DI (match_dup 1) (match_dup 2)))]
8874 "TARGET_64BIT
8875 && ix86_match_ccmode (insn, CCNOmode)
8876 && ix86_binary_operator_ok (XOR, DImode, operands)"
8877 "@
8878 xor{q}\t{%2, %0|%0, %2}
8879 xor{q}\t{%2, %0|%0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "DI,DI")])
8882
8883 (define_insn "*xordi_3_rex64"
8884 [(set (reg 17)
8885 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8886 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8887 (const_int 0)))
8888 (clobber (match_scratch:DI 0 "=r"))]
8889 "TARGET_64BIT
8890 && ix86_match_ccmode (insn, CCNOmode)
8891 && ix86_binary_operator_ok (XOR, DImode, operands)"
8892 "xor{q}\t{%2, %0|%0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "mode" "DI")])
8895
8896 (define_expand "xorsi3"
8897 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8898 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8899 (match_operand:SI 2 "general_operand" "")))
8900 (clobber (reg:CC 17))]
8901 ""
8902 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8903
8904 (define_insn "*xorsi_1"
8905 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8906 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8907 (match_operand:SI 2 "general_operand" "ri,rm")))
8908 (clobber (reg:CC 17))]
8909 "ix86_binary_operator_ok (XOR, SImode, operands)"
8910 "xor{l}\t{%2, %0|%0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI")])
8913
8914 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8915 ;; Add speccase for immediates
8916 (define_insn "*xorsi_1_zext"
8917 [(set (match_operand:DI 0 "register_operand" "=r")
8918 (zero_extend:DI
8919 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8920 (match_operand:SI 2 "general_operand" "rim"))))
8921 (clobber (reg:CC 17))]
8922 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8923 "xor{l}\t{%2, %k0|%k0, %2}"
8924 [(set_attr "type" "alu")
8925 (set_attr "mode" "SI")])
8926
8927 (define_insn "*xorsi_1_zext_imm"
8928 [(set (match_operand:DI 0 "register_operand" "=r")
8929 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8930 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8931 (clobber (reg:CC 17))]
8932 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8933 "xor{l}\t{%2, %k0|%k0, %2}"
8934 [(set_attr "type" "alu")
8935 (set_attr "mode" "SI")])
8936
8937 (define_insn "*xorsi_2"
8938 [(set (reg 17)
8939 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8940 (match_operand:SI 2 "general_operand" "rim,ri"))
8941 (const_int 0)))
8942 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8943 (xor:SI (match_dup 1) (match_dup 2)))]
8944 "ix86_match_ccmode (insn, CCNOmode)
8945 && ix86_binary_operator_ok (XOR, SImode, operands)"
8946 "xor{l}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "SI")])
8949
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; ??? Special case for immediate operand is missing - it is tricky.
8952 (define_insn "*xorsi_2_zext"
8953 [(set (reg 17)
8954 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955 (match_operand:SI 2 "general_operand" "rim"))
8956 (const_int 0)))
8957 (set (match_operand:DI 0 "register_operand" "=r")
8958 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8960 && ix86_binary_operator_ok (XOR, SImode, operands)"
8961 "xor{l}\t{%2, %k0|%k0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "mode" "SI")])
8964
8965 (define_insn "*xorsi_2_zext_imm"
8966 [(set (reg 17)
8967 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8969 (const_int 0)))
8970 (set (match_operand:DI 0 "register_operand" "=r")
8971 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8972 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8973 && ix86_binary_operator_ok (XOR, SImode, operands)"
8974 "xor{l}\t{%2, %k0|%k0, %2}"
8975 [(set_attr "type" "alu")
8976 (set_attr "mode" "SI")])
8977
8978 (define_insn "*xorsi_3"
8979 [(set (reg 17)
8980 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8981 (match_operand:SI 2 "general_operand" "rim"))
8982 (const_int 0)))
8983 (clobber (match_scratch:SI 0 "=r"))]
8984 "ix86_match_ccmode (insn, CCNOmode)
8985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8986 "xor{l}\t{%2, %0|%0, %2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "SI")])
8989
8990 (define_expand "xorhi3"
8991 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8992 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8993 (match_operand:HI 2 "general_operand" "")))
8994 (clobber (reg:CC 17))]
8995 "TARGET_HIMODE_MATH"
8996 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8997
8998 (define_insn "*xorhi_1"
8999 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9000 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9001 (match_operand:HI 2 "general_operand" "rmi,ri")))
9002 (clobber (reg:CC 17))]
9003 "ix86_binary_operator_ok (XOR, HImode, operands)"
9004 "xor{w}\t{%2, %0|%0, %2}"
9005 [(set_attr "type" "alu")
9006 (set_attr "mode" "HI")])
9007
9008 (define_insn "*xorhi_2"
9009 [(set (reg 17)
9010 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9011 (match_operand:HI 2 "general_operand" "rim,ri"))
9012 (const_int 0)))
9013 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9014 (xor:HI (match_dup 1) (match_dup 2)))]
9015 "ix86_match_ccmode (insn, CCNOmode)
9016 && ix86_binary_operator_ok (XOR, HImode, operands)"
9017 "xor{w}\t{%2, %0|%0, %2}"
9018 [(set_attr "type" "alu")
9019 (set_attr "mode" "HI")])
9020
9021 (define_insn "*xorhi_3"
9022 [(set (reg 17)
9023 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9024 (match_operand:HI 2 "general_operand" "rim"))
9025 (const_int 0)))
9026 (clobber (match_scratch:HI 0 "=r"))]
9027 "ix86_match_ccmode (insn, CCNOmode)
9028 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9029 "xor{w}\t{%2, %0|%0, %2}"
9030 [(set_attr "type" "alu")
9031 (set_attr "mode" "HI")])
9032
9033 (define_expand "xorqi3"
9034 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9035 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9036 (match_operand:QI 2 "general_operand" "")))
9037 (clobber (reg:CC 17))]
9038 "TARGET_QIMODE_MATH"
9039 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9040
9041 ;; %%% Potential partial reg stall on alternative 2. What to do?
9042 (define_insn "*xorqi_1"
9043 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9044 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9045 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9046 (clobber (reg:CC 17))]
9047 "ix86_binary_operator_ok (XOR, QImode, operands)"
9048 "@
9049 xor{b}\t{%2, %0|%0, %2}
9050 xor{b}\t{%2, %0|%0, %2}
9051 xor{l}\t{%k2, %k0|%k0, %k2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "mode" "QI,QI,SI")])
9054
9055 (define_insn "*xorqi_ext_1"
9056 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9057 (const_int 8)
9058 (const_int 8))
9059 (xor:SI
9060 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9061 (const_int 8)
9062 (const_int 8))
9063 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9064 (const_int 8)
9065 (const_int 8))))
9066 (clobber (reg:CC 17))]
9067 ""
9068 "xor{b}\t{%h2, %h0|%h0, %h2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "length_immediate" "0")
9071 (set_attr "mode" "QI")])
9072
9073 (define_insn "*xorqi_cc_1"
9074 [(set (reg 17)
9075 (compare
9076 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:QI 2 "general_operand" "qim,qi"))
9078 (const_int 0)))
9079 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9080 (xor:QI (match_dup 1) (match_dup 2)))]
9081 "ix86_match_ccmode (insn, CCNOmode)
9082 && ix86_binary_operator_ok (XOR, QImode, operands)"
9083 "xor{b}\t{%2, %0|%0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*xorqi_cc_2"
9088 [(set (reg 17)
9089 (compare
9090 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9091 (match_operand:QI 2 "general_operand" "qim"))
9092 (const_int 0)))
9093 (clobber (match_scratch:QI 0 "=q"))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9096 "xor{b}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI")])
9099
9100 (define_insn "*xorqi_cc_ext_1"
9101 [(set (reg 17)
9102 (compare
9103 (xor:SI
9104 (zero_extract:SI
9105 (match_operand 1 "ext_register_operand" "0")
9106 (const_int 8)
9107 (const_int 8))
9108 (match_operand:QI 2 "general_operand" "qmn"))
9109 (const_int 0)))
9110 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9111 (const_int 8)
9112 (const_int 8))
9113 (xor:SI
9114 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9115 (match_dup 2)))]
9116 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9117 "xor{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "mode" "QI")])
9120
9121 (define_insn "*xorqi_cc_ext_1_rex64"
9122 [(set (reg 17)
9123 (compare
9124 (xor:SI
9125 (zero_extract:SI
9126 (match_operand 1 "ext_register_operand" "0")
9127 (const_int 8)
9128 (const_int 8))
9129 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9130 (const_int 0)))
9131 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9132 (const_int 8)
9133 (const_int 8))
9134 (xor:SI
9135 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9136 (match_dup 2)))]
9137 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9138 "xor{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "mode" "QI")])
9141
9142 (define_expand "xorqi_cc_ext_1"
9143 [(parallel [
9144 (set (reg:CCNO 17)
9145 (compare:CCNO
9146 (xor:SI
9147 (zero_extract:SI
9148 (match_operand 1 "ext_register_operand" "")
9149 (const_int 8)
9150 (const_int 8))
9151 (match_operand:QI 2 "general_operand" ""))
9152 (const_int 0)))
9153 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9154 (const_int 8)
9155 (const_int 8))
9156 (xor:SI
9157 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9158 (match_dup 2)))])]
9159 ""
9160 "")
9161 \f
9162 ;; Negation instructions
9163
9164 (define_expand "negdi2"
9165 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9166 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9167 (clobber (reg:CC 17))])]
9168 ""
9169 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9170
9171 (define_insn "*negdi2_1"
9172 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9173 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9174 (clobber (reg:CC 17))]
9175 "!TARGET_64BIT
9176 && ix86_unary_operator_ok (NEG, DImode, operands)"
9177 "#")
9178
9179 (define_split
9180 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9181 (neg:DI (match_operand:DI 1 "general_operand" "")))
9182 (clobber (reg:CC 17))]
9183 "!TARGET_64BIT && reload_completed"
9184 [(parallel
9185 [(set (reg:CCZ 17)
9186 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9187 (set (match_dup 0) (neg:SI (match_dup 2)))])
9188 (parallel
9189 [(set (match_dup 1)
9190 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9191 (match_dup 3))
9192 (const_int 0)))
9193 (clobber (reg:CC 17))])
9194 (parallel
9195 [(set (match_dup 1)
9196 (neg:SI (match_dup 1)))
9197 (clobber (reg:CC 17))])]
9198 "split_di (operands+1, 1, operands+2, operands+3);
9199 split_di (operands+0, 1, operands+0, operands+1);")
9200
9201 (define_insn "*negdi2_1_rex64"
9202 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9203 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9204 (clobber (reg:CC 17))]
9205 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9206 "neg{q}\t%0"
9207 [(set_attr "type" "negnot")
9208 (set_attr "mode" "DI")])
9209
9210 ;; The problem with neg is that it does not perform (compare x 0),
9211 ;; it really performs (compare 0 x), which leaves us with the zero
9212 ;; flag being the only useful item.
9213
9214 (define_insn "*negdi2_cmpz_rex64"
9215 [(set (reg:CCZ 17)
9216 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9217 (const_int 0)))
9218 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9219 (neg:DI (match_dup 1)))]
9220 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9221 "neg{q}\t%0"
9222 [(set_attr "type" "negnot")
9223 (set_attr "mode" "DI")])
9224
9225
9226 (define_expand "negsi2"
9227 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9228 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9229 (clobber (reg:CC 17))])]
9230 ""
9231 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9232
9233 (define_insn "*negsi2_1"
9234 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9235 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9236 (clobber (reg:CC 17))]
9237 "ix86_unary_operator_ok (NEG, SImode, operands)"
9238 "neg{l}\t%0"
9239 [(set_attr "type" "negnot")
9240 (set_attr "mode" "SI")])
9241
9242 ;; Combine is quite creative about this pattern.
9243 (define_insn "*negsi2_1_zext"
9244 [(set (match_operand:DI 0 "register_operand" "=r")
9245 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9246 (const_int 32)))
9247 (const_int 32)))
9248 (clobber (reg:CC 17))]
9249 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9250 "neg{l}\t%k0"
9251 [(set_attr "type" "negnot")
9252 (set_attr "mode" "SI")])
9253
9254 ;; The problem with neg is that it does not perform (compare x 0),
9255 ;; it really performs (compare 0 x), which leaves us with the zero
9256 ;; flag being the only useful item.
9257
9258 (define_insn "*negsi2_cmpz"
9259 [(set (reg:CCZ 17)
9260 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9261 (const_int 0)))
9262 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9263 (neg:SI (match_dup 1)))]
9264 "ix86_unary_operator_ok (NEG, SImode, operands)"
9265 "neg{l}\t%0"
9266 [(set_attr "type" "negnot")
9267 (set_attr "mode" "SI")])
9268
9269 (define_insn "*negsi2_cmpz_zext"
9270 [(set (reg:CCZ 17)
9271 (compare:CCZ (lshiftrt:DI
9272 (neg:DI (ashift:DI
9273 (match_operand:DI 1 "register_operand" "0")
9274 (const_int 32)))
9275 (const_int 32))
9276 (const_int 0)))
9277 (set (match_operand:DI 0 "register_operand" "=r")
9278 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9279 (const_int 32)))
9280 (const_int 32)))]
9281 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9282 "neg{l}\t%k0"
9283 [(set_attr "type" "negnot")
9284 (set_attr "mode" "SI")])
9285
9286 (define_expand "neghi2"
9287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9288 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9289 (clobber (reg:CC 17))])]
9290 "TARGET_HIMODE_MATH"
9291 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9292
9293 (define_insn "*neghi2_1"
9294 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9295 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9296 (clobber (reg:CC 17))]
9297 "ix86_unary_operator_ok (NEG, HImode, operands)"
9298 "neg{w}\t%0"
9299 [(set_attr "type" "negnot")
9300 (set_attr "mode" "HI")])
9301
9302 (define_insn "*neghi2_cmpz"
9303 [(set (reg:CCZ 17)
9304 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9305 (const_int 0)))
9306 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9307 (neg:HI (match_dup 1)))]
9308 "ix86_unary_operator_ok (NEG, HImode, operands)"
9309 "neg{w}\t%0"
9310 [(set_attr "type" "negnot")
9311 (set_attr "mode" "HI")])
9312
9313 (define_expand "negqi2"
9314 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9315 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9316 (clobber (reg:CC 17))])]
9317 "TARGET_QIMODE_MATH"
9318 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9319
9320 (define_insn "*negqi2_1"
9321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9322 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9323 (clobber (reg:CC 17))]
9324 "ix86_unary_operator_ok (NEG, QImode, operands)"
9325 "neg{b}\t%0"
9326 [(set_attr "type" "negnot")
9327 (set_attr "mode" "QI")])
9328
9329 (define_insn "*negqi2_cmpz"
9330 [(set (reg:CCZ 17)
9331 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9332 (const_int 0)))
9333 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9334 (neg:QI (match_dup 1)))]
9335 "ix86_unary_operator_ok (NEG, QImode, operands)"
9336 "neg{b}\t%0"
9337 [(set_attr "type" "negnot")
9338 (set_attr "mode" "QI")])
9339
9340 ;; Changing of sign for FP values is doable using integer unit too.
9341
9342 (define_expand "negsf2"
9343 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9344 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9345 (clobber (reg:CC 17))])]
9346 "TARGET_80387"
9347 "if (TARGET_SSE)
9348 {
9349 /* In case operand is in memory, we will not use SSE. */
9350 if (memory_operand (operands[0], VOIDmode)
9351 && rtx_equal_p (operands[0], operands[1]))
9352 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9353 else
9354 {
9355 /* Using SSE is tricky, since we need bitwise negation of -0
9356 in register. */
9357 rtx reg = gen_reg_rtx (SFmode);
9358 rtx dest = operands[0];
9359
9360 operands[1] = force_reg (SFmode, operands[1]);
9361 operands[0] = force_reg (SFmode, operands[0]);
9362 emit_move_insn (reg,
9363 gen_lowpart (SFmode,
9364 GEN_INT (trunc_int_for_mode (0x80000000,
9365 SImode))));
9366 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9367 if (dest != operands[0])
9368 emit_move_insn (dest, operands[0]);
9369 }
9370 DONE;
9371 }
9372 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9373
9374 (define_insn "negsf2_memory"
9375 [(set (match_operand:SF 0 "memory_operand" "=m")
9376 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9377 (clobber (reg:CC 17))]
9378 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9379 "#")
9380
9381 (define_insn "negsf2_ifs"
9382 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9383 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9384 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
9385 (clobber (reg:CC 17))]
9386 "TARGET_SSE
9387 && (reload_in_progress || reload_completed
9388 || (register_operand (operands[0], VOIDmode)
9389 && register_operand (operands[1], VOIDmode)))"
9390 "#")
9391
9392 (define_split
9393 [(set (match_operand:SF 0 "memory_operand" "")
9394 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9395 (use (match_operand:SF 2 "" ""))
9396 (clobber (reg:CC 17))]
9397 ""
9398 [(parallel [(set (match_dup 0)
9399 (neg:SF (match_dup 1)))
9400 (clobber (reg:CC 17))])])
9401
9402 (define_split
9403 [(set (match_operand:SF 0 "register_operand" "")
9404 (neg:SF (match_operand:SF 1 "register_operand" "")))
9405 (use (match_operand:SF 2 "" ""))
9406 (clobber (reg:CC 17))]
9407 "reload_completed && !SSE_REG_P (operands[0])"
9408 [(parallel [(set (match_dup 0)
9409 (neg:SF (match_dup 1)))
9410 (clobber (reg:CC 17))])])
9411
9412 (define_split
9413 [(set (match_operand:SF 0 "register_operand" "")
9414 (neg:SF (match_operand:SF 1 "register_operand" "")))
9415 (use (match_operand:SF 2 "register_operand" ""))
9416 (clobber (reg:CC 17))]
9417 "reload_completed && SSE_REG_P (operands[0])"
9418 [(set (subreg:TI (match_dup 0) 0)
9419 (xor:TI (subreg:TI (match_dup 1) 0)
9420 (subreg:TI (match_dup 2) 0)))]
9421 {
9422 if (operands_match_p (operands[0], operands[2]))
9423 {
9424 rtx tmp;
9425 tmp = operands[1];
9426 operands[1] = operands[2];
9427 operands[2] = tmp;
9428 }
9429 })
9430
9431
9432 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9433 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9434 ;; to itself.
9435 (define_insn "*negsf2_if"
9436 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9437 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9438 (clobber (reg:CC 17))]
9439 "TARGET_80387 && !TARGET_SSE
9440 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9441 "#")
9442
9443 (define_split
9444 [(set (match_operand:SF 0 "register_operand" "")
9445 (neg:SF (match_operand:SF 1 "register_operand" "")))
9446 (clobber (reg:CC 17))]
9447 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9448 [(set (match_dup 0)
9449 (neg:SF (match_dup 1)))]
9450 "")
9451
9452 (define_split
9453 [(set (match_operand:SF 0 "register_operand" "")
9454 (neg:SF (match_operand:SF 1 "register_operand" "")))
9455 (clobber (reg:CC 17))]
9456 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9457 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9458 (clobber (reg:CC 17))])]
9459 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9460 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9461
9462 (define_split
9463 [(set (match_operand 0 "memory_operand" "")
9464 (neg (match_operand 1 "memory_operand" "")))
9465 (clobber (reg:CC 17))]
9466 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9467 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9468 (clobber (reg:CC 17))])]
9469 {
9470 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9471
9472 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9473 if (size >= 12)
9474 size = 10;
9475 operands[0] = adjust_address (operands[0], QImode, size - 1);
9476 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9477 })
9478
9479 (define_expand "negdf2"
9480 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9481 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9482 (clobber (reg:CC 17))])]
9483 "TARGET_80387"
9484 "if (TARGET_SSE2)
9485 {
9486 /* In case operand is in memory, we will not use SSE. */
9487 if (memory_operand (operands[0], VOIDmode)
9488 && rtx_equal_p (operands[0], operands[1]))
9489 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9490 else
9491 {
9492 /* Using SSE is tricky, since we need bitwise negation of -0
9493 in register. */
9494 rtx reg = gen_reg_rtx (DFmode);
9495 #if HOST_BITS_PER_WIDE_INT >= 64
9496 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9497 DImode));
9498 #else
9499 rtx imm = immed_double_const (0, 0x80000000, DImode);
9500 #endif
9501 rtx dest = operands[0];
9502
9503 operands[1] = force_reg (DFmode, operands[1]);
9504 operands[0] = force_reg (DFmode, operands[0]);
9505 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9506 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9507 if (dest != operands[0])
9508 emit_move_insn (dest, operands[0]);
9509 }
9510 DONE;
9511 }
9512 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9513
9514 (define_insn "negdf2_memory"
9515 [(set (match_operand:DF 0 "memory_operand" "=m")
9516 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9517 (clobber (reg:CC 17))]
9518 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9519 "#")
9520
9521 (define_insn "negdf2_ifs"
9522 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9523 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9524 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9525 (clobber (reg:CC 17))]
9526 "!TARGET_64BIT && TARGET_SSE2
9527 && (reload_in_progress || reload_completed
9528 || (register_operand (operands[0], VOIDmode)
9529 && register_operand (operands[1], VOIDmode)))"
9530 "#")
9531
9532 (define_insn "*negdf2_ifs_rex64"
9533 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9534 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9535 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9536 (clobber (reg:CC 17))]
9537 "TARGET_64BIT && TARGET_SSE2
9538 && (reload_in_progress || reload_completed
9539 || (register_operand (operands[0], VOIDmode)
9540 && register_operand (operands[1], VOIDmode)))"
9541 "#")
9542
9543 (define_split
9544 [(set (match_operand:DF 0 "memory_operand" "")
9545 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9546 (use (match_operand:DF 2 "" ""))
9547 (clobber (reg:CC 17))]
9548 ""
9549 [(parallel [(set (match_dup 0)
9550 (neg:DF (match_dup 1)))
9551 (clobber (reg:CC 17))])])
9552
9553 (define_split
9554 [(set (match_operand:DF 0 "register_operand" "")
9555 (neg:DF (match_operand:DF 1 "register_operand" "")))
9556 (use (match_operand:DF 2 "" ""))
9557 (clobber (reg:CC 17))]
9558 "reload_completed && !SSE_REG_P (operands[0])
9559 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9560 [(parallel [(set (match_dup 0)
9561 (neg:DF (match_dup 1)))
9562 (clobber (reg:CC 17))])])
9563
9564 (define_split
9565 [(set (match_operand:DF 0 "register_operand" "")
9566 (neg:DF (match_operand:DF 1 "register_operand" "")))
9567 (use (match_operand:DF 2 "" ""))
9568 (clobber (reg:CC 17))]
9569 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9570 [(parallel [(set (match_dup 0)
9571 (xor:DI (match_dup 1) (match_dup 2)))
9572 (clobber (reg:CC 17))])]
9573 "operands[0] = gen_lowpart (DImode, operands[0]);
9574 operands[1] = gen_lowpart (DImode, operands[1]);
9575 operands[2] = gen_lowpart (DImode, operands[2]);")
9576
9577 (define_split
9578 [(set (match_operand:DF 0 "register_operand" "")
9579 (neg:DF (match_operand:DF 1 "register_operand" "")))
9580 (use (match_operand:DF 2 "register_operand" ""))
9581 (clobber (reg:CC 17))]
9582 "reload_completed && SSE_REG_P (operands[0])"
9583 [(set (subreg:TI (match_dup 0) 0)
9584 (xor:TI (subreg:TI (match_dup 1) 0)
9585 (subreg:TI (match_dup 2) 0)))]
9586 {
9587 if (operands_match_p (operands[0], operands[2]))
9588 {
9589 rtx tmp;
9590 tmp = operands[1];
9591 operands[1] = operands[2];
9592 operands[2] = tmp;
9593 }
9594 })
9595
9596 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9597 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9598 ;; to itself.
9599 (define_insn "*negdf2_if"
9600 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9601 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9602 (clobber (reg:CC 17))]
9603 "!TARGET_64BIT && TARGET_80387
9604 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9605 "#")
9606
9607 ;; FIXME: We should to allow integer registers here. Problem is that
9608 ;; we need another scratch register to get constant from.
9609 ;; Forcing constant to mem if no register available in peep2 should be
9610 ;; safe even for PIC mode, because of RIP relative addressing.
9611 (define_insn "*negdf2_if_rex64"
9612 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9613 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9614 (clobber (reg:CC 17))]
9615 "TARGET_64BIT && TARGET_80387
9616 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9617 "#")
9618
9619 (define_split
9620 [(set (match_operand:DF 0 "register_operand" "")
9621 (neg:DF (match_operand:DF 1 "register_operand" "")))
9622 (clobber (reg:CC 17))]
9623 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9624 [(set (match_dup 0)
9625 (neg:DF (match_dup 1)))]
9626 "")
9627
9628 (define_split
9629 [(set (match_operand:DF 0 "register_operand" "")
9630 (neg:DF (match_operand:DF 1 "register_operand" "")))
9631 (clobber (reg:CC 17))]
9632 "!TARGET_64BIT && TARGET_80387 && reload_completed
9633 && !FP_REGNO_P (REGNO (operands[0]))"
9634 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9635 (clobber (reg:CC 17))])]
9636 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9637 split_di (operands+0, 1, operands+2, operands+3);")
9638
9639 (define_expand "negxf2"
9640 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9641 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9642 (clobber (reg:CC 17))])]
9643 "!TARGET_64BIT && TARGET_80387"
9644 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9645
9646 (define_expand "negtf2"
9647 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9648 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9649 (clobber (reg:CC 17))])]
9650 "TARGET_80387"
9651 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9652
9653 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9654 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9655 ;; to itself.
9656 (define_insn "*negxf2_if"
9657 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9658 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9659 (clobber (reg:CC 17))]
9660 "!TARGET_64BIT && TARGET_80387
9661 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9662 "#")
9663
9664 (define_split
9665 [(set (match_operand:XF 0 "register_operand" "")
9666 (neg:XF (match_operand:XF 1 "register_operand" "")))
9667 (clobber (reg:CC 17))]
9668 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9669 [(set (match_dup 0)
9670 (neg:XF (match_dup 1)))]
9671 "")
9672
9673 (define_split
9674 [(set (match_operand:XF 0 "register_operand" "")
9675 (neg:XF (match_operand:XF 1 "register_operand" "")))
9676 (clobber (reg:CC 17))]
9677 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9678 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9679 (clobber (reg:CC 17))])]
9680 "operands[1] = GEN_INT (0x8000);
9681 operands[0] = gen_rtx_REG (SImode,
9682 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9683
9684 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9685 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9686 ;; to itself.
9687 (define_insn "*negtf2_if"
9688 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9689 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9690 (clobber (reg:CC 17))]
9691 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9692 "#")
9693
9694 (define_split
9695 [(set (match_operand:TF 0 "register_operand" "")
9696 (neg:TF (match_operand:TF 1 "register_operand" "")))
9697 (clobber (reg:CC 17))]
9698 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9699 [(set (match_dup 0)
9700 (neg:TF (match_dup 1)))]
9701 "")
9702
9703 (define_split
9704 [(set (match_operand:TF 0 "register_operand" "")
9705 (neg:TF (match_operand:TF 1 "register_operand" "")))
9706 (clobber (reg:CC 17))]
9707 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9708 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9709 (clobber (reg:CC 17))])]
9710 "operands[1] = GEN_INT (0x8000);
9711 operands[0] = gen_rtx_REG (SImode,
9712 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9713
9714 ;; Conditionize these after reload. If they matches before reload, we
9715 ;; lose the clobber and ability to use integer instructions.
9716
9717 (define_insn "*negsf2_1"
9718 [(set (match_operand:SF 0 "register_operand" "=f")
9719 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9720 "TARGET_80387 && reload_completed"
9721 "fchs"
9722 [(set_attr "type" "fsgn")
9723 (set_attr "mode" "SF")
9724 (set_attr "ppro_uops" "few")])
9725
9726 (define_insn "*negdf2_1"
9727 [(set (match_operand:DF 0 "register_operand" "=f")
9728 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9729 "TARGET_80387 && reload_completed"
9730 "fchs"
9731 [(set_attr "type" "fsgn")
9732 (set_attr "mode" "DF")
9733 (set_attr "ppro_uops" "few")])
9734
9735 (define_insn "*negextendsfdf2"
9736 [(set (match_operand:DF 0 "register_operand" "=f")
9737 (neg:DF (float_extend:DF
9738 (match_operand:SF 1 "register_operand" "0"))))]
9739 "TARGET_80387"
9740 "fchs"
9741 [(set_attr "type" "fsgn")
9742 (set_attr "mode" "DF")
9743 (set_attr "ppro_uops" "few")])
9744
9745 (define_insn "*negxf2_1"
9746 [(set (match_operand:XF 0 "register_operand" "=f")
9747 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9748 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9749 "fchs"
9750 [(set_attr "type" "fsgn")
9751 (set_attr "mode" "XF")
9752 (set_attr "ppro_uops" "few")])
9753
9754 (define_insn "*negextenddfxf2"
9755 [(set (match_operand:XF 0 "register_operand" "=f")
9756 (neg:XF (float_extend:XF
9757 (match_operand:DF 1 "register_operand" "0"))))]
9758 "!TARGET_64BIT && TARGET_80387"
9759 "fchs"
9760 [(set_attr "type" "fsgn")
9761 (set_attr "mode" "XF")
9762 (set_attr "ppro_uops" "few")])
9763
9764 (define_insn "*negextendsfxf2"
9765 [(set (match_operand:XF 0 "register_operand" "=f")
9766 (neg:XF (float_extend:XF
9767 (match_operand:SF 1 "register_operand" "0"))))]
9768 "!TARGET_64BIT && TARGET_80387"
9769 "fchs"
9770 [(set_attr "type" "fsgn")
9771 (set_attr "mode" "XF")
9772 (set_attr "ppro_uops" "few")])
9773
9774 (define_insn "*negtf2_1"
9775 [(set (match_operand:TF 0 "register_operand" "=f")
9776 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9777 "TARGET_80387 && reload_completed"
9778 "fchs"
9779 [(set_attr "type" "fsgn")
9780 (set_attr "mode" "XF")
9781 (set_attr "ppro_uops" "few")])
9782
9783 (define_insn "*negextenddftf2"
9784 [(set (match_operand:TF 0 "register_operand" "=f")
9785 (neg:TF (float_extend:TF
9786 (match_operand:DF 1 "register_operand" "0"))))]
9787 "TARGET_80387"
9788 "fchs"
9789 [(set_attr "type" "fsgn")
9790 (set_attr "mode" "XF")
9791 (set_attr "ppro_uops" "few")])
9792
9793 (define_insn "*negextendsftf2"
9794 [(set (match_operand:TF 0 "register_operand" "=f")
9795 (neg:TF (float_extend:TF
9796 (match_operand:SF 1 "register_operand" "0"))))]
9797 "TARGET_80387"
9798 "fchs"
9799 [(set_attr "type" "fsgn")
9800 (set_attr "mode" "XF")
9801 (set_attr "ppro_uops" "few")])
9802 \f
9803 ;; Absolute value instructions
9804
9805 (define_expand "abssf2"
9806 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9807 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9808 (clobber (reg:CC 17))])]
9809 "TARGET_80387"
9810 "if (TARGET_SSE)
9811 {
9812 /* In case operand is in memory, we will not use SSE. */
9813 if (memory_operand (operands[0], VOIDmode)
9814 && rtx_equal_p (operands[0], operands[1]))
9815 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9816 else
9817 {
9818 /* Using SSE is tricky, since we need bitwise negation of -0
9819 in register. */
9820 rtx reg = gen_reg_rtx (SFmode);
9821 rtx dest = operands[0];
9822
9823 operands[1] = force_reg (SFmode, operands[1]);
9824 operands[0] = force_reg (SFmode, operands[0]);
9825 emit_move_insn (reg,
9826 gen_lowpart (SFmode,
9827 GEN_INT (trunc_int_for_mode (0x80000000,
9828 SImode))));
9829 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9830 if (dest != operands[0])
9831 emit_move_insn (dest, operands[0]);
9832 }
9833 DONE;
9834 }
9835 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9836
9837 (define_insn "abssf2_memory"
9838 [(set (match_operand:SF 0 "memory_operand" "=m")
9839 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9840 (clobber (reg:CC 17))]
9841 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9842 "#")
9843
9844 (define_insn "abssf2_ifs"
9845 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
9846 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9847 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
9848 (clobber (reg:CC 17))]
9849 "TARGET_SSE
9850 && (reload_in_progress || reload_completed
9851 || (register_operand (operands[0], VOIDmode)
9852 && register_operand (operands[1], VOIDmode)))"
9853 "#")
9854
9855 (define_split
9856 [(set (match_operand:SF 0 "memory_operand" "")
9857 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9858 (use (match_operand:SF 2 "" ""))
9859 (clobber (reg:CC 17))]
9860 ""
9861 [(parallel [(set (match_dup 0)
9862 (abs:SF (match_dup 1)))
9863 (clobber (reg:CC 17))])])
9864
9865 (define_split
9866 [(set (match_operand:SF 0 "register_operand" "")
9867 (abs:SF (match_operand:SF 1 "register_operand" "")))
9868 (use (match_operand:SF 2 "" ""))
9869 (clobber (reg:CC 17))]
9870 "reload_completed && !SSE_REG_P (operands[0])"
9871 [(parallel [(set (match_dup 0)
9872 (abs:SF (match_dup 1)))
9873 (clobber (reg:CC 17))])])
9874
9875 (define_split
9876 [(set (match_operand:SF 0 "register_operand" "")
9877 (abs:SF (match_operand:SF 1 "register_operand" "")))
9878 (use (match_operand:SF 2 "register_operand" ""))
9879 (clobber (reg:CC 17))]
9880 "reload_completed && SSE_REG_P (operands[0])"
9881 [(set (subreg:TI (match_dup 0) 0)
9882 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9883 (subreg:TI (match_dup 1) 0)))])
9884
9885 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9886 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9887 ;; to itself.
9888 (define_insn "*abssf2_if"
9889 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9890 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9891 (clobber (reg:CC 17))]
9892 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9893 "#")
9894
9895 (define_split
9896 [(set (match_operand:SF 0 "register_operand" "")
9897 (abs:SF (match_operand:SF 1 "register_operand" "")))
9898 (clobber (reg:CC 17))]
9899 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9900 [(set (match_dup 0)
9901 (abs:SF (match_dup 1)))]
9902 "")
9903
9904 (define_split
9905 [(set (match_operand:SF 0 "register_operand" "")
9906 (abs:SF (match_operand:SF 1 "register_operand" "")))
9907 (clobber (reg:CC 17))]
9908 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9909 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9910 (clobber (reg:CC 17))])]
9911 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
9912 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9913
9914 (define_split
9915 [(set (match_operand 0 "memory_operand" "")
9916 (abs (match_operand 1 "memory_operand" "")))
9917 (clobber (reg:CC 17))]
9918 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9919 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9920 (clobber (reg:CC 17))])]
9921 {
9922 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9923
9924 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9925 if (size >= 12)
9926 size = 10;
9927 operands[0] = adjust_address (operands[0], QImode, size - 1);
9928 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
9929 })
9930
9931 (define_expand "absdf2"
9932 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9933 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9934 (clobber (reg:CC 17))])]
9935 "TARGET_80387"
9936 "if (TARGET_SSE2)
9937 {
9938 /* In case operand is in memory, we will not use SSE. */
9939 if (memory_operand (operands[0], VOIDmode)
9940 && rtx_equal_p (operands[0], operands[1]))
9941 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9942 else
9943 {
9944 /* Using SSE is tricky, since we need bitwise negation of -0
9945 in register. */
9946 rtx reg = gen_reg_rtx (DFmode);
9947 #if HOST_BITS_PER_WIDE_INT >= 64
9948 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9949 DImode));
9950 #else
9951 rtx imm = immed_double_const (0, 0x80000000, DImode);
9952 #endif
9953 rtx dest = operands[0];
9954
9955 operands[1] = force_reg (DFmode, operands[1]);
9956 operands[0] = force_reg (DFmode, operands[0]);
9957 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9958 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9959 if (dest != operands[0])
9960 emit_move_insn (dest, operands[0]);
9961 }
9962 DONE;
9963 }
9964 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9965
9966 (define_insn "absdf2_memory"
9967 [(set (match_operand:DF 0 "memory_operand" "=m")
9968 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9969 (clobber (reg:CC 17))]
9970 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9971 "#")
9972
9973 (define_insn "absdf2_ifs"
9974 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
9975 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9976 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
9977 (clobber (reg:CC 17))]
9978 "!TARGET_64BIT && TARGET_SSE2
9979 && (reload_in_progress || reload_completed
9980 || (register_operand (operands[0], VOIDmode)
9981 && register_operand (operands[1], VOIDmode)))"
9982 "#")
9983
9984 (define_insn "*absdf2_ifs_rex64"
9985 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9986 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9987 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9988 (clobber (reg:CC 17))]
9989 "TARGET_64BIT && TARGET_SSE2
9990 && (reload_in_progress || reload_completed
9991 || (register_operand (operands[0], VOIDmode)
9992 && register_operand (operands[1], VOIDmode)))"
9993 "#")
9994
9995 (define_split
9996 [(set (match_operand:DF 0 "memory_operand" "")
9997 (abs:DF (match_operand:DF 1 "memory_operand" "")))
9998 (use (match_operand:DF 2 "" ""))
9999 (clobber (reg:CC 17))]
10000 ""
10001 [(parallel [(set (match_dup 0)
10002 (abs:DF (match_dup 1)))
10003 (clobber (reg:CC 17))])])
10004
10005 (define_split
10006 [(set (match_operand:DF 0 "register_operand" "")
10007 (abs:DF (match_operand:DF 1 "register_operand" "")))
10008 (use (match_operand:DF 2 "" ""))
10009 (clobber (reg:CC 17))]
10010 "reload_completed && !SSE_REG_P (operands[0])"
10011 [(parallel [(set (match_dup 0)
10012 (abs:DF (match_dup 1)))
10013 (clobber (reg:CC 17))])])
10014
10015 (define_split
10016 [(set (match_operand:DF 0 "register_operand" "")
10017 (abs:DF (match_operand:DF 1 "register_operand" "")))
10018 (use (match_operand:DF 2 "register_operand" ""))
10019 (clobber (reg:CC 17))]
10020 "reload_completed && SSE_REG_P (operands[0])"
10021 [(set (subreg:TI (match_dup 0) 0)
10022 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10023 (subreg:TI (match_dup 1) 0)))])
10024
10025
10026 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10027 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10028 ;; to itself.
10029 (define_insn "*absdf2_if"
10030 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10031 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10032 (clobber (reg:CC 17))]
10033 "!TARGET_64BIT && TARGET_80387
10034 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10035 "#")
10036
10037 ;; FIXME: We should to allow integer registers here. Problem is that
10038 ;; we need another scratch register to get constant from.
10039 ;; Forcing constant to mem if no register available in peep2 should be
10040 ;; safe even for PIC mode, because of RIP relative addressing.
10041 (define_insn "*absdf2_if_rex64"
10042 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10043 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10044 (clobber (reg:CC 17))]
10045 "TARGET_64BIT && TARGET_80387
10046 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10047 "#")
10048
10049 (define_split
10050 [(set (match_operand:DF 0 "register_operand" "")
10051 (abs:DF (match_operand:DF 1 "register_operand" "")))
10052 (clobber (reg:CC 17))]
10053 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10054 [(set (match_dup 0)
10055 (abs:DF (match_dup 1)))]
10056 "")
10057
10058 (define_split
10059 [(set (match_operand:DF 0 "register_operand" "")
10060 (abs:DF (match_operand:DF 1 "register_operand" "")))
10061 (clobber (reg:CC 17))]
10062 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10063 !FP_REGNO_P (REGNO (operands[0]))"
10064 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10065 (clobber (reg:CC 17))])]
10066 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10067 split_di (operands+0, 1, operands+2, operands+3);")
10068
10069 (define_expand "absxf2"
10070 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10071 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10072 (clobber (reg:CC 17))])]
10073 "!TARGET_64BIT && TARGET_80387"
10074 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10075
10076 (define_expand "abstf2"
10077 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10078 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10079 (clobber (reg:CC 17))])]
10080 "TARGET_80387"
10081 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10082
10083 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10084 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10085 ;; to itself.
10086 (define_insn "*absxf2_if"
10087 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10088 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10089 (clobber (reg:CC 17))]
10090 "!TARGET_64BIT && TARGET_80387
10091 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10092 "#")
10093
10094 (define_split
10095 [(set (match_operand:XF 0 "register_operand" "")
10096 (abs:XF (match_operand:XF 1 "register_operand" "")))
10097 (clobber (reg:CC 17))]
10098 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10099 [(set (match_dup 0)
10100 (abs:XF (match_dup 1)))]
10101 "")
10102
10103 (define_split
10104 [(set (match_operand:XF 0 "register_operand" "")
10105 (abs:XF (match_operand:XF 1 "register_operand" "")))
10106 (clobber (reg:CC 17))]
10107 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10108 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10109 (clobber (reg:CC 17))])]
10110 "operands[1] = GEN_INT (~0x8000);
10111 operands[0] = gen_rtx_REG (SImode,
10112 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10113
10114 (define_insn "*abstf2_if"
10115 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10116 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10117 (clobber (reg:CC 17))]
10118 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10119 "#")
10120
10121 (define_split
10122 [(set (match_operand:TF 0 "register_operand" "")
10123 (abs:TF (match_operand:TF 1 "register_operand" "")))
10124 (clobber (reg:CC 17))]
10125 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10126 [(set (match_dup 0)
10127 (abs:TF (match_dup 1)))]
10128 "")
10129
10130 (define_split
10131 [(set (match_operand:TF 0 "register_operand" "")
10132 (abs:TF (match_operand:TF 1 "register_operand" "")))
10133 (clobber (reg:CC 17))]
10134 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10135 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10136 (clobber (reg:CC 17))])]
10137 "operands[1] = GEN_INT (~0x8000);
10138 operands[0] = gen_rtx_REG (SImode,
10139 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10140
10141 (define_insn "*abssf2_1"
10142 [(set (match_operand:SF 0 "register_operand" "=f")
10143 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10144 "TARGET_80387 && reload_completed"
10145 "fabs"
10146 [(set_attr "type" "fsgn")
10147 (set_attr "mode" "SF")])
10148
10149 (define_insn "*absdf2_1"
10150 [(set (match_operand:DF 0 "register_operand" "=f")
10151 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10152 "TARGET_80387 && reload_completed"
10153 "fabs"
10154 [(set_attr "type" "fsgn")
10155 (set_attr "mode" "DF")])
10156
10157 (define_insn "*absextendsfdf2"
10158 [(set (match_operand:DF 0 "register_operand" "=f")
10159 (abs:DF (float_extend:DF
10160 (match_operand:SF 1 "register_operand" "0"))))]
10161 "TARGET_80387"
10162 "fabs"
10163 [(set_attr "type" "fsgn")
10164 (set_attr "mode" "DF")])
10165
10166 (define_insn "*absxf2_1"
10167 [(set (match_operand:XF 0 "register_operand" "=f")
10168 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10169 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10170 "fabs"
10171 [(set_attr "type" "fsgn")
10172 (set_attr "mode" "DF")])
10173
10174 (define_insn "*absextenddfxf2"
10175 [(set (match_operand:XF 0 "register_operand" "=f")
10176 (abs:XF (float_extend:XF
10177 (match_operand:DF 1 "register_operand" "0"))))]
10178 "!TARGET_64BIT && TARGET_80387"
10179 "fabs"
10180 [(set_attr "type" "fsgn")
10181 (set_attr "mode" "XF")])
10182
10183 (define_insn "*absextendsfxf2"
10184 [(set (match_operand:XF 0 "register_operand" "=f")
10185 (abs:XF (float_extend:XF
10186 (match_operand:SF 1 "register_operand" "0"))))]
10187 "!TARGET_64BIT && TARGET_80387"
10188 "fabs"
10189 [(set_attr "type" "fsgn")
10190 (set_attr "mode" "XF")])
10191
10192 (define_insn "*abstf2_1"
10193 [(set (match_operand:TF 0 "register_operand" "=f")
10194 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10195 "TARGET_80387 && reload_completed"
10196 "fabs"
10197 [(set_attr "type" "fsgn")
10198 (set_attr "mode" "DF")])
10199
10200 (define_insn "*absextenddftf2"
10201 [(set (match_operand:TF 0 "register_operand" "=f")
10202 (abs:TF (float_extend:TF
10203 (match_operand:DF 1 "register_operand" "0"))))]
10204 "TARGET_80387"
10205 "fabs"
10206 [(set_attr "type" "fsgn")
10207 (set_attr "mode" "XF")])
10208
10209 (define_insn "*absextendsftf2"
10210 [(set (match_operand:TF 0 "register_operand" "=f")
10211 (abs:TF (float_extend:TF
10212 (match_operand:SF 1 "register_operand" "0"))))]
10213 "TARGET_80387"
10214 "fabs"
10215 [(set_attr "type" "fsgn")
10216 (set_attr "mode" "XF")])
10217 \f
10218 ;; One complement instructions
10219
10220 (define_expand "one_cmpldi2"
10221 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10222 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10223 "TARGET_64BIT"
10224 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10225
10226 (define_insn "*one_cmpldi2_1_rex64"
10227 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10228 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10229 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10230 "not{q}\t%0"
10231 [(set_attr "type" "negnot")
10232 (set_attr "mode" "DI")])
10233
10234 (define_insn "*one_cmpldi2_2_rex64"
10235 [(set (reg 17)
10236 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10237 (const_int 0)))
10238 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10239 (not:DI (match_dup 1)))]
10240 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10241 && ix86_unary_operator_ok (NOT, DImode, operands)"
10242 "#"
10243 [(set_attr "type" "alu1")
10244 (set_attr "mode" "DI")])
10245
10246 (define_split
10247 [(set (reg 17)
10248 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10249 (const_int 0)))
10250 (set (match_operand:DI 0 "nonimmediate_operand" "")
10251 (not:DI (match_dup 1)))]
10252 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10253 [(parallel [(set (reg:CCNO 17)
10254 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10255 (const_int 0)))
10256 (set (match_dup 0)
10257 (xor:DI (match_dup 1) (const_int -1)))])]
10258 "")
10259
10260 (define_expand "one_cmplsi2"
10261 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10262 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10263 ""
10264 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10265
10266 (define_insn "*one_cmplsi2_1"
10267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10268 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10269 "ix86_unary_operator_ok (NOT, SImode, operands)"
10270 "not{l}\t%0"
10271 [(set_attr "type" "negnot")
10272 (set_attr "mode" "SI")])
10273
10274 ;; ??? Currently never generated - xor is used instead.
10275 (define_insn "*one_cmplsi2_1_zext"
10276 [(set (match_operand:DI 0 "register_operand" "=r")
10277 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10278 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10279 "not{l}\t%k0"
10280 [(set_attr "type" "negnot")
10281 (set_attr "mode" "SI")])
10282
10283 (define_insn "*one_cmplsi2_2"
10284 [(set (reg 17)
10285 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10286 (const_int 0)))
10287 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10288 (not:SI (match_dup 1)))]
10289 "ix86_match_ccmode (insn, CCNOmode)
10290 && ix86_unary_operator_ok (NOT, SImode, operands)"
10291 "#"
10292 [(set_attr "type" "alu1")
10293 (set_attr "mode" "SI")])
10294
10295 (define_split
10296 [(set (reg 17)
10297 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10298 (const_int 0)))
10299 (set (match_operand:SI 0 "nonimmediate_operand" "")
10300 (not:SI (match_dup 1)))]
10301 "ix86_match_ccmode (insn, CCNOmode)"
10302 [(parallel [(set (reg:CCNO 17)
10303 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10304 (const_int 0)))
10305 (set (match_dup 0)
10306 (xor:SI (match_dup 1) (const_int -1)))])]
10307 "")
10308
10309 ;; ??? Currently never generated - xor is used instead.
10310 (define_insn "*one_cmplsi2_2_zext"
10311 [(set (reg 17)
10312 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10313 (const_int 0)))
10314 (set (match_operand:DI 0 "register_operand" "=r")
10315 (zero_extend:DI (not:SI (match_dup 1))))]
10316 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10317 && ix86_unary_operator_ok (NOT, SImode, operands)"
10318 "#"
10319 [(set_attr "type" "alu1")
10320 (set_attr "mode" "SI")])
10321
10322 (define_split
10323 [(set (reg 17)
10324 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10325 (const_int 0)))
10326 (set (match_operand:DI 0 "register_operand" "")
10327 (zero_extend:DI (not:SI (match_dup 1))))]
10328 "ix86_match_ccmode (insn, CCNOmode)"
10329 [(parallel [(set (reg:CCNO 17)
10330 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10331 (const_int 0)))
10332 (set (match_dup 0)
10333 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10334 "")
10335
10336 (define_expand "one_cmplhi2"
10337 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10338 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10339 "TARGET_HIMODE_MATH"
10340 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10341
10342 (define_insn "*one_cmplhi2_1"
10343 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10344 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10345 "ix86_unary_operator_ok (NOT, HImode, operands)"
10346 "not{w}\t%0"
10347 [(set_attr "type" "negnot")
10348 (set_attr "mode" "HI")])
10349
10350 (define_insn "*one_cmplhi2_2"
10351 [(set (reg 17)
10352 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10353 (const_int 0)))
10354 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10355 (not:HI (match_dup 1)))]
10356 "ix86_match_ccmode (insn, CCNOmode)
10357 && ix86_unary_operator_ok (NEG, HImode, operands)"
10358 "#"
10359 [(set_attr "type" "alu1")
10360 (set_attr "mode" "HI")])
10361
10362 (define_split
10363 [(set (reg 17)
10364 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10365 (const_int 0)))
10366 (set (match_operand:HI 0 "nonimmediate_operand" "")
10367 (not:HI (match_dup 1)))]
10368 "ix86_match_ccmode (insn, CCNOmode)"
10369 [(parallel [(set (reg:CCNO 17)
10370 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10371 (const_int 0)))
10372 (set (match_dup 0)
10373 (xor:HI (match_dup 1) (const_int -1)))])]
10374 "")
10375
10376 ;; %%% Potential partial reg stall on alternative 1. What to do?
10377 (define_expand "one_cmplqi2"
10378 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10379 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10380 "TARGET_QIMODE_MATH"
10381 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10382
10383 (define_insn "*one_cmplqi2_1"
10384 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10385 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10386 "ix86_unary_operator_ok (NOT, QImode, operands)"
10387 "@
10388 not{b}\t%0
10389 not{l}\t%k0"
10390 [(set_attr "type" "negnot")
10391 (set_attr "mode" "QI,SI")])
10392
10393 (define_insn "*one_cmplqi2_2"
10394 [(set (reg 17)
10395 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10396 (const_int 0)))
10397 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10398 (not:QI (match_dup 1)))]
10399 "ix86_match_ccmode (insn, CCNOmode)
10400 && ix86_unary_operator_ok (NOT, QImode, operands)"
10401 "#"
10402 [(set_attr "type" "alu1")
10403 (set_attr "mode" "QI")])
10404
10405 (define_split
10406 [(set (reg 17)
10407 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10408 (const_int 0)))
10409 (set (match_operand:QI 0 "nonimmediate_operand" "")
10410 (not:QI (match_dup 1)))]
10411 "ix86_match_ccmode (insn, CCNOmode)"
10412 [(parallel [(set (reg:CCNO 17)
10413 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10414 (const_int 0)))
10415 (set (match_dup 0)
10416 (xor:QI (match_dup 1) (const_int -1)))])]
10417 "")
10418 \f
10419 ;; Arithmetic shift instructions
10420
10421 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10422 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10423 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10424 ;; from the assembler input.
10425 ;;
10426 ;; This instruction shifts the target reg/mem as usual, but instead of
10427 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10428 ;; is a left shift double, bits are taken from the high order bits of
10429 ;; reg, else if the insn is a shift right double, bits are taken from the
10430 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10431 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10432 ;;
10433 ;; Since sh[lr]d does not change the `reg' operand, that is done
10434 ;; separately, making all shifts emit pairs of shift double and normal
10435 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10436 ;; support a 63 bit shift, each shift where the count is in a reg expands
10437 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10438 ;;
10439 ;; If the shift count is a constant, we need never emit more than one
10440 ;; shift pair, instead using moves and sign extension for counts greater
10441 ;; than 31.
10442
10443 (define_expand "ashldi3"
10444 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10445 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10446 (match_operand:QI 2 "nonmemory_operand" "")))
10447 (clobber (reg:CC 17))])]
10448 ""
10449 {
10450 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10451 {
10452 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10453 DONE;
10454 }
10455 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10456 DONE;
10457 })
10458
10459 (define_insn "*ashldi3_1_rex64"
10460 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10461 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10462 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10463 (clobber (reg:CC 17))]
10464 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10465 {
10466 switch (get_attr_type (insn))
10467 {
10468 case TYPE_ALU:
10469 if (operands[2] != const1_rtx)
10470 abort ();
10471 if (!rtx_equal_p (operands[0], operands[1]))
10472 abort ();
10473 return "add{q}\t{%0, %0|%0, %0}";
10474
10475 case TYPE_LEA:
10476 if (GET_CODE (operands[2]) != CONST_INT
10477 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10478 abort ();
10479 operands[1] = gen_rtx_MULT (DImode, operands[1],
10480 GEN_INT (1 << INTVAL (operands[2])));
10481 return "lea{q}\t{%a1, %0|%0, %a1}";
10482
10483 default:
10484 if (REG_P (operands[2]))
10485 return "sal{q}\t{%b2, %0|%0, %b2}";
10486 else if (GET_CODE (operands[2]) == CONST_INT
10487 && INTVAL (operands[2]) == 1
10488 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10489 return "sal{q}\t%0";
10490 else
10491 return "sal{q}\t{%2, %0|%0, %2}";
10492 }
10493 }
10494 [(set (attr "type")
10495 (cond [(eq_attr "alternative" "1")
10496 (const_string "lea")
10497 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498 (const_int 0))
10499 (match_operand 0 "register_operand" ""))
10500 (match_operand 2 "const1_operand" ""))
10501 (const_string "alu")
10502 ]
10503 (const_string "ishift")))
10504 (set_attr "mode" "DI")])
10505
10506 ;; Convert lea to the lea pattern to avoid flags dependency.
10507 (define_split
10508 [(set (match_operand:DI 0 "register_operand" "")
10509 (ashift:DI (match_operand:DI 1 "register_operand" "")
10510 (match_operand:QI 2 "immediate_operand" "")))
10511 (clobber (reg:CC 17))]
10512 "TARGET_64BIT && reload_completed
10513 && true_regnum (operands[0]) != true_regnum (operands[1])"
10514 [(set (match_dup 0)
10515 (mult:DI (match_dup 1)
10516 (match_dup 2)))]
10517 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10518 DImode));")
10519
10520 ;; This pattern can't accept a variable shift count, since shifts by
10521 ;; zero don't affect the flags. We assume that shifts by constant
10522 ;; zero are optimized away.
10523 (define_insn "*ashldi3_cmp_rex64"
10524 [(set (reg 17)
10525 (compare
10526 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10527 (match_operand:QI 2 "immediate_operand" "e"))
10528 (const_int 0)))
10529 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10530 (ashift:DI (match_dup 1) (match_dup 2)))]
10531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10532 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10533 {
10534 switch (get_attr_type (insn))
10535 {
10536 case TYPE_ALU:
10537 if (operands[2] != const1_rtx)
10538 abort ();
10539 return "add{q}\t{%0, %0|%0, %0}";
10540
10541 default:
10542 if (REG_P (operands[2]))
10543 return "sal{q}\t{%b2, %0|%0, %b2}";
10544 else if (GET_CODE (operands[2]) == CONST_INT
10545 && INTVAL (operands[2]) == 1
10546 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10547 return "sal{q}\t%0";
10548 else
10549 return "sal{q}\t{%2, %0|%0, %2}";
10550 }
10551 }
10552 [(set (attr "type")
10553 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10554 (const_int 0))
10555 (match_operand 0 "register_operand" ""))
10556 (match_operand 2 "const1_operand" ""))
10557 (const_string "alu")
10558 ]
10559 (const_string "ishift")))
10560 (set_attr "mode" "DI")])
10561
10562 (define_insn "ashldi3_1"
10563 [(set (match_operand:DI 0 "register_operand" "=r")
10564 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10565 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10566 (clobber (match_scratch:SI 3 "=&r"))
10567 (clobber (reg:CC 17))]
10568 "!TARGET_64BIT && TARGET_CMOVE"
10569 "#"
10570 [(set_attr "type" "multi")])
10571
10572 (define_insn "*ashldi3_2"
10573 [(set (match_operand:DI 0 "register_operand" "=r")
10574 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10575 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10576 (clobber (reg:CC 17))]
10577 "!TARGET_64BIT"
10578 "#"
10579 [(set_attr "type" "multi")])
10580
10581 (define_split
10582 [(set (match_operand:DI 0 "register_operand" "")
10583 (ashift:DI (match_operand:DI 1 "register_operand" "")
10584 (match_operand:QI 2 "nonmemory_operand" "")))
10585 (clobber (match_scratch:SI 3 ""))
10586 (clobber (reg:CC 17))]
10587 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10588 [(const_int 0)]
10589 "ix86_split_ashldi (operands, operands[3]); DONE;")
10590
10591 (define_split
10592 [(set (match_operand:DI 0 "register_operand" "")
10593 (ashift:DI (match_operand:DI 1 "register_operand" "")
10594 (match_operand:QI 2 "nonmemory_operand" "")))
10595 (clobber (reg:CC 17))]
10596 "!TARGET_64BIT && reload_completed"
10597 [(const_int 0)]
10598 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10599
10600 (define_insn "x86_shld_1"
10601 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10602 (ior:SI (ashift:SI (match_dup 0)
10603 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10604 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10605 (minus:QI (const_int 32) (match_dup 2)))))
10606 (clobber (reg:CC 17))]
10607 ""
10608 "@
10609 shld{l}\t{%2, %1, %0|%0, %1, %2}
10610 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10611 [(set_attr "type" "ishift")
10612 (set_attr "prefix_0f" "1")
10613 (set_attr "mode" "SI")
10614 (set_attr "pent_pair" "np")
10615 (set_attr "athlon_decode" "vector")
10616 (set_attr "ppro_uops" "few")])
10617
10618 (define_expand "x86_shift_adj_1"
10619 [(set (reg:CCZ 17)
10620 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10621 (const_int 32))
10622 (const_int 0)))
10623 (set (match_operand:SI 0 "register_operand" "")
10624 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10625 (match_operand:SI 1 "register_operand" "")
10626 (match_dup 0)))
10627 (set (match_dup 1)
10628 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10629 (match_operand:SI 3 "register_operand" "r")
10630 (match_dup 1)))]
10631 "TARGET_CMOVE"
10632 "")
10633
10634 (define_expand "x86_shift_adj_2"
10635 [(use (match_operand:SI 0 "register_operand" ""))
10636 (use (match_operand:SI 1 "register_operand" ""))
10637 (use (match_operand:QI 2 "register_operand" ""))]
10638 ""
10639 {
10640 rtx label = gen_label_rtx ();
10641 rtx tmp;
10642
10643 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10644
10645 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10646 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10647 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10648 gen_rtx_LABEL_REF (VOIDmode, label),
10649 pc_rtx);
10650 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10651 JUMP_LABEL (tmp) = label;
10652
10653 emit_move_insn (operands[0], operands[1]);
10654 emit_move_insn (operands[1], const0_rtx);
10655
10656 emit_label (label);
10657 LABEL_NUSES (label) = 1;
10658
10659 DONE;
10660 })
10661
10662 (define_expand "ashlsi3"
10663 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10664 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10665 (match_operand:QI 2 "nonmemory_operand" "")))
10666 (clobber (reg:CC 17))]
10667 ""
10668 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10669
10670 (define_insn "*ashlsi3_1"
10671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10672 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10673 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10674 (clobber (reg:CC 17))]
10675 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10676 {
10677 switch (get_attr_type (insn))
10678 {
10679 case TYPE_ALU:
10680 if (operands[2] != const1_rtx)
10681 abort ();
10682 if (!rtx_equal_p (operands[0], operands[1]))
10683 abort ();
10684 return "add{l}\t{%0, %0|%0, %0}";
10685
10686 case TYPE_LEA:
10687 return "#";
10688
10689 default:
10690 if (REG_P (operands[2]))
10691 return "sal{l}\t{%b2, %0|%0, %b2}";
10692 else if (GET_CODE (operands[2]) == CONST_INT
10693 && INTVAL (operands[2]) == 1
10694 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10695 return "sal{l}\t%0";
10696 else
10697 return "sal{l}\t{%2, %0|%0, %2}";
10698 }
10699 }
10700 [(set (attr "type")
10701 (cond [(eq_attr "alternative" "1")
10702 (const_string "lea")
10703 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10704 (const_int 0))
10705 (match_operand 0 "register_operand" ""))
10706 (match_operand 2 "const1_operand" ""))
10707 (const_string "alu")
10708 ]
10709 (const_string "ishift")))
10710 (set_attr "mode" "SI")])
10711
10712 ;; Convert lea to the lea pattern to avoid flags dependency.
10713 (define_split
10714 [(set (match_operand 0 "register_operand" "")
10715 (ashift (match_operand 1 "register_operand" "")
10716 (match_operand:QI 2 "const_int_operand" "")))
10717 (clobber (reg:CC 17))]
10718 "reload_completed
10719 && true_regnum (operands[0]) != true_regnum (operands[1])"
10720 [(const_int 0)]
10721 {
10722 rtx pat;
10723 operands[0] = gen_lowpart (SImode, operands[0]);
10724 operands[1] = gen_lowpart (Pmode, operands[1]);
10725 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10726 Pmode));
10727 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10728 if (Pmode != SImode)
10729 pat = gen_rtx_SUBREG (SImode, pat, 0);
10730 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10731 DONE;
10732 })
10733
10734 (define_insn "*ashlsi3_1_zext"
10735 [(set (match_operand:DI 0 "register_operand" "=r,r")
10736 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10737 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10738 (clobber (reg:CC 17))]
10739 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10740 {
10741 switch (get_attr_type (insn))
10742 {
10743 case TYPE_ALU:
10744 if (operands[2] != const1_rtx)
10745 abort ();
10746 return "add{l}\t{%k0, %k0|%k0, %k0}";
10747
10748 case TYPE_LEA:
10749 return "#";
10750
10751 default:
10752 if (REG_P (operands[2]))
10753 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10754 else if (GET_CODE (operands[2]) == CONST_INT
10755 && INTVAL (operands[2]) == 1
10756 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10757 return "sal{l}\t%k0";
10758 else
10759 return "sal{l}\t{%2, %k0|%k0, %2}";
10760 }
10761 }
10762 [(set (attr "type")
10763 (cond [(eq_attr "alternative" "1")
10764 (const_string "lea")
10765 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766 (const_int 0))
10767 (match_operand 2 "const1_operand" ""))
10768 (const_string "alu")
10769 ]
10770 (const_string "ishift")))
10771 (set_attr "mode" "SI")])
10772
10773 ;; Convert lea to the lea pattern to avoid flags dependency.
10774 (define_split
10775 [(set (match_operand:DI 0 "register_operand" "")
10776 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10777 (match_operand:QI 2 "const_int_operand" ""))))
10778 (clobber (reg:CC 17))]
10779 "reload_completed
10780 && true_regnum (operands[0]) != true_regnum (operands[1])"
10781 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10782 {
10783 operands[1] = gen_lowpart (Pmode, operands[1]);
10784 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10785 Pmode));
10786 })
10787
10788 ;; This pattern can't accept a variable shift count, since shifts by
10789 ;; zero don't affect the flags. We assume that shifts by constant
10790 ;; zero are optimized away.
10791 (define_insn "*ashlsi3_cmp"
10792 [(set (reg 17)
10793 (compare
10794 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10795 (match_operand:QI 2 "immediate_operand" "I"))
10796 (const_int 0)))
10797 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10798 (ashift:SI (match_dup 1) (match_dup 2)))]
10799 "ix86_match_ccmode (insn, CCGOCmode)
10800 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10801 {
10802 switch (get_attr_type (insn))
10803 {
10804 case TYPE_ALU:
10805 if (operands[2] != const1_rtx)
10806 abort ();
10807 return "add{l}\t{%0, %0|%0, %0}";
10808
10809 default:
10810 if (REG_P (operands[2]))
10811 return "sal{l}\t{%b2, %0|%0, %b2}";
10812 else if (GET_CODE (operands[2]) == CONST_INT
10813 && INTVAL (operands[2]) == 1
10814 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10815 return "sal{l}\t%0";
10816 else
10817 return "sal{l}\t{%2, %0|%0, %2}";
10818 }
10819 }
10820 [(set (attr "type")
10821 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822 (const_int 0))
10823 (match_operand 0 "register_operand" ""))
10824 (match_operand 2 "const1_operand" ""))
10825 (const_string "alu")
10826 ]
10827 (const_string "ishift")))
10828 (set_attr "mode" "SI")])
10829
10830 (define_insn "*ashlsi3_cmp_zext"
10831 [(set (reg 17)
10832 (compare
10833 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10834 (match_operand:QI 2 "immediate_operand" "I"))
10835 (const_int 0)))
10836 (set (match_operand:DI 0 "register_operand" "=r")
10837 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10839 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10840 {
10841 switch (get_attr_type (insn))
10842 {
10843 case TYPE_ALU:
10844 if (operands[2] != const1_rtx)
10845 abort ();
10846 return "add{l}\t{%k0, %k0|%k0, %k0}";
10847
10848 default:
10849 if (REG_P (operands[2]))
10850 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10851 else if (GET_CODE (operands[2]) == CONST_INT
10852 && INTVAL (operands[2]) == 1
10853 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10854 return "sal{l}\t%k0";
10855 else
10856 return "sal{l}\t{%2, %k0|%k0, %2}";
10857 }
10858 }
10859 [(set (attr "type")
10860 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10861 (const_int 0))
10862 (match_operand 2 "const1_operand" ""))
10863 (const_string "alu")
10864 ]
10865 (const_string "ishift")))
10866 (set_attr "mode" "SI")])
10867
10868 (define_expand "ashlhi3"
10869 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10870 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10871 (match_operand:QI 2 "nonmemory_operand" "")))
10872 (clobber (reg:CC 17))]
10873 "TARGET_HIMODE_MATH"
10874 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10875
10876 (define_insn "*ashlhi3_1_lea"
10877 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10878 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10879 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10880 (clobber (reg:CC 17))]
10881 "!TARGET_PARTIAL_REG_STALL
10882 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10883 {
10884 switch (get_attr_type (insn))
10885 {
10886 case TYPE_LEA:
10887 return "#";
10888 case TYPE_ALU:
10889 if (operands[2] != const1_rtx)
10890 abort ();
10891 return "add{w}\t{%0, %0|%0, %0}";
10892
10893 default:
10894 if (REG_P (operands[2]))
10895 return "sal{w}\t{%b2, %0|%0, %b2}";
10896 else if (GET_CODE (operands[2]) == CONST_INT
10897 && INTVAL (operands[2]) == 1
10898 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10899 return "sal{w}\t%0";
10900 else
10901 return "sal{w}\t{%2, %0|%0, %2}";
10902 }
10903 }
10904 [(set (attr "type")
10905 (cond [(eq_attr "alternative" "1")
10906 (const_string "lea")
10907 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10908 (const_int 0))
10909 (match_operand 0 "register_operand" ""))
10910 (match_operand 2 "const1_operand" ""))
10911 (const_string "alu")
10912 ]
10913 (const_string "ishift")))
10914 (set_attr "mode" "HI,SI")])
10915
10916 (define_insn "*ashlhi3_1"
10917 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10918 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10919 (match_operand:QI 2 "nonmemory_operand" "cI")))
10920 (clobber (reg:CC 17))]
10921 "TARGET_PARTIAL_REG_STALL
10922 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10923 {
10924 switch (get_attr_type (insn))
10925 {
10926 case TYPE_ALU:
10927 if (operands[2] != const1_rtx)
10928 abort ();
10929 return "add{w}\t{%0, %0|%0, %0}";
10930
10931 default:
10932 if (REG_P (operands[2]))
10933 return "sal{w}\t{%b2, %0|%0, %b2}";
10934 else if (GET_CODE (operands[2]) == CONST_INT
10935 && INTVAL (operands[2]) == 1
10936 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10937 return "sal{w}\t%0";
10938 else
10939 return "sal{w}\t{%2, %0|%0, %2}";
10940 }
10941 }
10942 [(set (attr "type")
10943 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944 (const_int 0))
10945 (match_operand 0 "register_operand" ""))
10946 (match_operand 2 "const1_operand" ""))
10947 (const_string "alu")
10948 ]
10949 (const_string "ishift")))
10950 (set_attr "mode" "HI")])
10951
10952 ;; This pattern can't accept a variable shift count, since shifts by
10953 ;; zero don't affect the flags. We assume that shifts by constant
10954 ;; zero are optimized away.
10955 (define_insn "*ashlhi3_cmp"
10956 [(set (reg 17)
10957 (compare
10958 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10959 (match_operand:QI 2 "immediate_operand" "I"))
10960 (const_int 0)))
10961 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10962 (ashift:HI (match_dup 1) (match_dup 2)))]
10963 "ix86_match_ccmode (insn, CCGOCmode)
10964 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10965 {
10966 switch (get_attr_type (insn))
10967 {
10968 case TYPE_ALU:
10969 if (operands[2] != const1_rtx)
10970 abort ();
10971 return "add{w}\t{%0, %0|%0, %0}";
10972
10973 default:
10974 if (REG_P (operands[2]))
10975 return "sal{w}\t{%b2, %0|%0, %b2}";
10976 else if (GET_CODE (operands[2]) == CONST_INT
10977 && INTVAL (operands[2]) == 1
10978 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10979 return "sal{w}\t%0";
10980 else
10981 return "sal{w}\t{%2, %0|%0, %2}";
10982 }
10983 }
10984 [(set (attr "type")
10985 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10986 (const_int 0))
10987 (match_operand 0 "register_operand" ""))
10988 (match_operand 2 "const1_operand" ""))
10989 (const_string "alu")
10990 ]
10991 (const_string "ishift")))
10992 (set_attr "mode" "HI")])
10993
10994 (define_expand "ashlqi3"
10995 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10996 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10997 (match_operand:QI 2 "nonmemory_operand" "")))
10998 (clobber (reg:CC 17))]
10999 "TARGET_QIMODE_MATH"
11000 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11001
11002 ;; %%% Potential partial reg stall on alternative 2. What to do?
11003
11004 (define_insn "*ashlqi3_1_lea"
11005 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11006 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11007 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11008 (clobber (reg:CC 17))]
11009 "!TARGET_PARTIAL_REG_STALL
11010 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11011 {
11012 switch (get_attr_type (insn))
11013 {
11014 case TYPE_LEA:
11015 return "#";
11016 case TYPE_ALU:
11017 if (operands[2] != const1_rtx)
11018 abort ();
11019 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11020 return "add{l}\t{%k0, %k0|%k0, %k0}";
11021 else
11022 return "add{b}\t{%0, %0|%0, %0}";
11023
11024 default:
11025 if (REG_P (operands[2]))
11026 {
11027 if (get_attr_mode (insn) == MODE_SI)
11028 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11029 else
11030 return "sal{b}\t{%b2, %0|%0, %b2}";
11031 }
11032 else if (GET_CODE (operands[2]) == CONST_INT
11033 && INTVAL (operands[2]) == 1
11034 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11035 {
11036 if (get_attr_mode (insn) == MODE_SI)
11037 return "sal{l}\t%0";
11038 else
11039 return "sal{b}\t%0";
11040 }
11041 else
11042 {
11043 if (get_attr_mode (insn) == MODE_SI)
11044 return "sal{l}\t{%2, %k0|%k0, %2}";
11045 else
11046 return "sal{b}\t{%2, %0|%0, %2}";
11047 }
11048 }
11049 }
11050 [(set (attr "type")
11051 (cond [(eq_attr "alternative" "2")
11052 (const_string "lea")
11053 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054 (const_int 0))
11055 (match_operand 0 "register_operand" ""))
11056 (match_operand 2 "const1_operand" ""))
11057 (const_string "alu")
11058 ]
11059 (const_string "ishift")))
11060 (set_attr "mode" "QI,SI,SI")])
11061
11062 (define_insn "*ashlqi3_1"
11063 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11064 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11065 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11066 (clobber (reg:CC 17))]
11067 "TARGET_PARTIAL_REG_STALL
11068 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11069 {
11070 switch (get_attr_type (insn))
11071 {
11072 case TYPE_ALU:
11073 if (operands[2] != const1_rtx)
11074 abort ();
11075 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11076 return "add{l}\t{%k0, %k0|%k0, %k0}";
11077 else
11078 return "add{b}\t{%0, %0|%0, %0}";
11079
11080 default:
11081 if (REG_P (operands[2]))
11082 {
11083 if (get_attr_mode (insn) == MODE_SI)
11084 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11085 else
11086 return "sal{b}\t{%b2, %0|%0, %b2}";
11087 }
11088 else if (GET_CODE (operands[2]) == CONST_INT
11089 && INTVAL (operands[2]) == 1
11090 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11091 {
11092 if (get_attr_mode (insn) == MODE_SI)
11093 return "sal{l}\t%0";
11094 else
11095 return "sal{b}\t%0";
11096 }
11097 else
11098 {
11099 if (get_attr_mode (insn) == MODE_SI)
11100 return "sal{l}\t{%2, %k0|%k0, %2}";
11101 else
11102 return "sal{b}\t{%2, %0|%0, %2}";
11103 }
11104 }
11105 }
11106 [(set (attr "type")
11107 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11108 (const_int 0))
11109 (match_operand 0 "register_operand" ""))
11110 (match_operand 2 "const1_operand" ""))
11111 (const_string "alu")
11112 ]
11113 (const_string "ishift")))
11114 (set_attr "mode" "QI,SI")])
11115
11116 ;; This pattern can't accept a variable shift count, since shifts by
11117 ;; zero don't affect the flags. We assume that shifts by constant
11118 ;; zero are optimized away.
11119 (define_insn "*ashlqi3_cmp"
11120 [(set (reg 17)
11121 (compare
11122 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11123 (match_operand:QI 2 "immediate_operand" "I"))
11124 (const_int 0)))
11125 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11126 (ashift:QI (match_dup 1) (match_dup 2)))]
11127 "ix86_match_ccmode (insn, CCGOCmode)
11128 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11129 {
11130 switch (get_attr_type (insn))
11131 {
11132 case TYPE_ALU:
11133 if (operands[2] != const1_rtx)
11134 abort ();
11135 return "add{b}\t{%0, %0|%0, %0}";
11136
11137 default:
11138 if (REG_P (operands[2]))
11139 return "sal{b}\t{%b2, %0|%0, %b2}";
11140 else if (GET_CODE (operands[2]) == CONST_INT
11141 && INTVAL (operands[2]) == 1
11142 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11143 return "sal{b}\t%0";
11144 else
11145 return "sal{b}\t{%2, %0|%0, %2}";
11146 }
11147 }
11148 [(set (attr "type")
11149 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11150 (const_int 0))
11151 (match_operand 0 "register_operand" ""))
11152 (match_operand 2 "const1_operand" ""))
11153 (const_string "alu")
11154 ]
11155 (const_string "ishift")))
11156 (set_attr "mode" "QI")])
11157
11158 ;; See comment above `ashldi3' about how this works.
11159
11160 (define_expand "ashrdi3"
11161 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11162 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11163 (match_operand:QI 2 "nonmemory_operand" "")))
11164 (clobber (reg:CC 17))])]
11165 ""
11166 {
11167 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11168 {
11169 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11170 DONE;
11171 }
11172 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11173 DONE;
11174 })
11175
11176 (define_insn "ashrdi3_63_rex64"
11177 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11178 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11179 (match_operand:DI 2 "const_int_operand" "i,i")))
11180 (clobber (reg:CC 17))]
11181 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11182 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11183 "@
11184 {cqto|cqo}
11185 sar{q}\t{%2, %0|%0, %2}"
11186 [(set_attr "type" "imovx,ishift")
11187 (set_attr "prefix_0f" "0,*")
11188 (set_attr "length_immediate" "0,*")
11189 (set_attr "modrm" "0,1")
11190 (set_attr "mode" "DI")])
11191
11192 (define_insn "*ashrdi3_1_one_bit_rex64"
11193 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11194 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11195 (match_operand:QI 2 "const_int_1_operand" "")))
11196 (clobber (reg:CC 17))]
11197 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11198 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11199 "sar{q}\t%0"
11200 [(set_attr "type" "ishift")
11201 (set (attr "length")
11202 (if_then_else (match_operand:DI 0 "register_operand" "")
11203 (const_string "2")
11204 (const_string "*")))])
11205
11206 (define_insn "*ashrdi3_1_rex64"
11207 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11208 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11209 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11210 (clobber (reg:CC 17))]
11211 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11212 "@
11213 sar{q}\t{%2, %0|%0, %2}
11214 sar{q}\t{%b2, %0|%0, %b2}"
11215 [(set_attr "type" "ishift")
11216 (set_attr "mode" "DI")])
11217
11218 ;; This pattern can't accept a variable shift count, since shifts by
11219 ;; zero don't affect the flags. We assume that shifts by constant
11220 ;; zero are optimized away.
11221 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11222 [(set (reg 17)
11223 (compare
11224 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11225 (match_operand:QI 2 "const_int_1_operand" ""))
11226 (const_int 0)))
11227 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11228 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11229 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11230 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11231 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11232 "sar{q}\t%0"
11233 [(set_attr "type" "ishift")
11234 (set (attr "length")
11235 (if_then_else (match_operand:DI 0 "register_operand" "")
11236 (const_string "2")
11237 (const_string "*")))])
11238
11239 ;; This pattern can't accept a variable shift count, since shifts by
11240 ;; zero don't affect the flags. We assume that shifts by constant
11241 ;; zero are optimized away.
11242 (define_insn "*ashrdi3_cmp_rex64"
11243 [(set (reg 17)
11244 (compare
11245 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11246 (match_operand:QI 2 "const_int_operand" "n"))
11247 (const_int 0)))
11248 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11249 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11250 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11251 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11252 "sar{q}\t{%2, %0|%0, %2}"
11253 [(set_attr "type" "ishift")
11254 (set_attr "mode" "DI")])
11255
11256
11257 (define_insn "ashrdi3_1"
11258 [(set (match_operand:DI 0 "register_operand" "=r")
11259 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11260 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11261 (clobber (match_scratch:SI 3 "=&r"))
11262 (clobber (reg:CC 17))]
11263 "!TARGET_64BIT && TARGET_CMOVE"
11264 "#"
11265 [(set_attr "type" "multi")])
11266
11267 (define_insn "*ashrdi3_2"
11268 [(set (match_operand:DI 0 "register_operand" "=r")
11269 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11270 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11271 (clobber (reg:CC 17))]
11272 "!TARGET_64BIT"
11273 "#"
11274 [(set_attr "type" "multi")])
11275
11276 (define_split
11277 [(set (match_operand:DI 0 "register_operand" "")
11278 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11279 (match_operand:QI 2 "nonmemory_operand" "")))
11280 (clobber (match_scratch:SI 3 ""))
11281 (clobber (reg:CC 17))]
11282 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11283 [(const_int 0)]
11284 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11285
11286 (define_split
11287 [(set (match_operand:DI 0 "register_operand" "")
11288 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11289 (match_operand:QI 2 "nonmemory_operand" "")))
11290 (clobber (reg:CC 17))]
11291 "!TARGET_64BIT && reload_completed"
11292 [(const_int 0)]
11293 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11294
11295 (define_insn "x86_shrd_1"
11296 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11297 (ior:SI (ashiftrt:SI (match_dup 0)
11298 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11299 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11300 (minus:QI (const_int 32) (match_dup 2)))))
11301 (clobber (reg:CC 17))]
11302 ""
11303 "@
11304 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11305 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11306 [(set_attr "type" "ishift")
11307 (set_attr "prefix_0f" "1")
11308 (set_attr "pent_pair" "np")
11309 (set_attr "ppro_uops" "few")
11310 (set_attr "mode" "SI")])
11311
11312 (define_expand "x86_shift_adj_3"
11313 [(use (match_operand:SI 0 "register_operand" ""))
11314 (use (match_operand:SI 1 "register_operand" ""))
11315 (use (match_operand:QI 2 "register_operand" ""))]
11316 ""
11317 {
11318 rtx label = gen_label_rtx ();
11319 rtx tmp;
11320
11321 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11322
11323 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11324 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11325 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11326 gen_rtx_LABEL_REF (VOIDmode, label),
11327 pc_rtx);
11328 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11329 JUMP_LABEL (tmp) = label;
11330
11331 emit_move_insn (operands[0], operands[1]);
11332 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11333
11334 emit_label (label);
11335 LABEL_NUSES (label) = 1;
11336
11337 DONE;
11338 })
11339
11340 (define_insn "ashrsi3_31"
11341 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11342 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11343 (match_operand:SI 2 "const_int_operand" "i,i")))
11344 (clobber (reg:CC 17))]
11345 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11346 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11347 "@
11348 {cltd|cdq}
11349 sar{l}\t{%2, %0|%0, %2}"
11350 [(set_attr "type" "imovx,ishift")
11351 (set_attr "prefix_0f" "0,*")
11352 (set_attr "length_immediate" "0,*")
11353 (set_attr "modrm" "0,1")
11354 (set_attr "mode" "SI")])
11355
11356 (define_insn "*ashrsi3_31_zext"
11357 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11358 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11359 (match_operand:SI 2 "const_int_operand" "i,i"))))
11360 (clobber (reg:CC 17))]
11361 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11362 && INTVAL (operands[2]) == 31
11363 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11364 "@
11365 {cltd|cdq}
11366 sar{l}\t{%2, %k0|%k0, %2}"
11367 [(set_attr "type" "imovx,ishift")
11368 (set_attr "prefix_0f" "0,*")
11369 (set_attr "length_immediate" "0,*")
11370 (set_attr "modrm" "0,1")
11371 (set_attr "mode" "SI")])
11372
11373 (define_expand "ashrsi3"
11374 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11375 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11376 (match_operand:QI 2 "nonmemory_operand" "")))
11377 (clobber (reg:CC 17))]
11378 ""
11379 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11380
11381 (define_insn "*ashrsi3_1_one_bit"
11382 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11383 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384 (match_operand:QI 2 "const_int_1_operand" "")))
11385 (clobber (reg:CC 17))]
11386 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11387 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11388 "sar{l}\t%0"
11389 [(set_attr "type" "ishift")
11390 (set (attr "length")
11391 (if_then_else (match_operand:SI 0 "register_operand" "")
11392 (const_string "2")
11393 (const_string "*")))])
11394
11395 (define_insn "*ashrsi3_1_one_bit_zext"
11396 [(set (match_operand:DI 0 "register_operand" "=r")
11397 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11398 (match_operand:QI 2 "const_int_1_operand" ""))))
11399 (clobber (reg:CC 17))]
11400 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11401 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11402 "sar{l}\t%k0"
11403 [(set_attr "type" "ishift")
11404 (set_attr "length" "2")])
11405
11406 (define_insn "*ashrsi3_1"
11407 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11408 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11409 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11410 (clobber (reg:CC 17))]
11411 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412 "@
11413 sar{l}\t{%2, %0|%0, %2}
11414 sar{l}\t{%b2, %0|%0, %b2}"
11415 [(set_attr "type" "ishift")
11416 (set_attr "mode" "SI")])
11417
11418 (define_insn "*ashrsi3_1_zext"
11419 [(set (match_operand:DI 0 "register_operand" "=r,r")
11420 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11421 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11422 (clobber (reg:CC 17))]
11423 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11424 "@
11425 sar{l}\t{%2, %k0|%k0, %2}
11426 sar{l}\t{%b2, %k0|%k0, %b2}"
11427 [(set_attr "type" "ishift")
11428 (set_attr "mode" "SI")])
11429
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags. We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrsi3_one_bit_cmp"
11434 [(set (reg 17)
11435 (compare
11436 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11437 (match_operand:QI 2 "const_int_1_operand" ""))
11438 (const_int 0)))
11439 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11440 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11441 "ix86_match_ccmode (insn, CCGOCmode)
11442 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11443 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11444 "sar{l}\t%0"
11445 [(set_attr "type" "ishift")
11446 (set (attr "length")
11447 (if_then_else (match_operand:SI 0 "register_operand" "")
11448 (const_string "2")
11449 (const_string "*")))])
11450
11451 (define_insn "*ashrsi3_one_bit_cmp_zext"
11452 [(set (reg 17)
11453 (compare
11454 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11455 (match_operand:QI 2 "const_int_1_operand" ""))
11456 (const_int 0)))
11457 (set (match_operand:DI 0 "register_operand" "=r")
11458 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11459 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11460 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11461 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11462 "sar{l}\t%k0"
11463 [(set_attr "type" "ishift")
11464 (set_attr "length" "2")])
11465
11466 ;; This pattern can't accept a variable shift count, since shifts by
11467 ;; zero don't affect the flags. We assume that shifts by constant
11468 ;; zero are optimized away.
11469 (define_insn "*ashrsi3_cmp"
11470 [(set (reg 17)
11471 (compare
11472 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11473 (match_operand:QI 2 "immediate_operand" "I"))
11474 (const_int 0)))
11475 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11476 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11477 "ix86_match_ccmode (insn, CCGOCmode)
11478 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11479 "sar{l}\t{%2, %0|%0, %2}"
11480 [(set_attr "type" "ishift")
11481 (set_attr "mode" "SI")])
11482
11483 (define_insn "*ashrsi3_cmp_zext"
11484 [(set (reg 17)
11485 (compare
11486 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11487 (match_operand:QI 2 "immediate_operand" "I"))
11488 (const_int 0)))
11489 (set (match_operand:DI 0 "register_operand" "=r")
11490 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11491 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11492 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11493 "sar{l}\t{%2, %k0|%k0, %2}"
11494 [(set_attr "type" "ishift")
11495 (set_attr "mode" "SI")])
11496
11497 (define_expand "ashrhi3"
11498 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11499 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11500 (match_operand:QI 2 "nonmemory_operand" "")))
11501 (clobber (reg:CC 17))]
11502 "TARGET_HIMODE_MATH"
11503 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11504
11505 (define_insn "*ashrhi3_1_one_bit"
11506 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11507 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11508 (match_operand:QI 2 "const_int_1_operand" "")))
11509 (clobber (reg:CC 17))]
11510 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11511 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11512 "sar{w}\t%0"
11513 [(set_attr "type" "ishift")
11514 (set (attr "length")
11515 (if_then_else (match_operand 0 "register_operand" "")
11516 (const_string "2")
11517 (const_string "*")))])
11518
11519 (define_insn "*ashrhi3_1"
11520 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11521 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11522 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11523 (clobber (reg:CC 17))]
11524 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11525 "@
11526 sar{w}\t{%2, %0|%0, %2}
11527 sar{w}\t{%b2, %0|%0, %b2}"
11528 [(set_attr "type" "ishift")
11529 (set_attr "mode" "HI")])
11530
11531 ;; This pattern can't accept a variable shift count, since shifts by
11532 ;; zero don't affect the flags. We assume that shifts by constant
11533 ;; zero are optimized away.
11534 (define_insn "*ashrhi3_one_bit_cmp"
11535 [(set (reg 17)
11536 (compare
11537 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11538 (match_operand:QI 2 "const_int_1_operand" ""))
11539 (const_int 0)))
11540 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11541 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11542 "ix86_match_ccmode (insn, CCGOCmode)
11543 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11544 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11545 "sar{w}\t%0"
11546 [(set_attr "type" "ishift")
11547 (set (attr "length")
11548 (if_then_else (match_operand 0 "register_operand" "")
11549 (const_string "2")
11550 (const_string "*")))])
11551
11552 ;; This pattern can't accept a variable shift count, since shifts by
11553 ;; zero don't affect the flags. We assume that shifts by constant
11554 ;; zero are optimized away.
11555 (define_insn "*ashrhi3_cmp"
11556 [(set (reg 17)
11557 (compare
11558 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11559 (match_operand:QI 2 "immediate_operand" "I"))
11560 (const_int 0)))
11561 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11562 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11563 "ix86_match_ccmode (insn, CCGOCmode)
11564 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11565 "sar{w}\t{%2, %0|%0, %2}"
11566 [(set_attr "type" "ishift")
11567 (set_attr "mode" "HI")])
11568
11569 (define_expand "ashrqi3"
11570 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11571 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11572 (match_operand:QI 2 "nonmemory_operand" "")))
11573 (clobber (reg:CC 17))]
11574 "TARGET_QIMODE_MATH"
11575 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11576
11577 (define_insn "*ashrqi3_1_one_bit"
11578 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11579 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11580 (match_operand:QI 2 "const_int_1_operand" "")))
11581 (clobber (reg:CC 17))]
11582 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11583 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11584 "sar{b}\t%0"
11585 [(set_attr "type" "ishift")
11586 (set (attr "length")
11587 (if_then_else (match_operand 0 "register_operand" "")
11588 (const_string "2")
11589 (const_string "*")))])
11590
11591 (define_insn "*ashrqi3_1"
11592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11593 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11594 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11595 (clobber (reg:CC 17))]
11596 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11597 "@
11598 sar{b}\t{%2, %0|%0, %2}
11599 sar{b}\t{%b2, %0|%0, %b2}"
11600 [(set_attr "type" "ishift")
11601 (set_attr "mode" "QI")])
11602
11603 ;; This pattern can't accept a variable shift count, since shifts by
11604 ;; zero don't affect the flags. We assume that shifts by constant
11605 ;; zero are optimized away.
11606 (define_insn "*ashrqi3_one_bit_cmp"
11607 [(set (reg 17)
11608 (compare
11609 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11610 (match_operand:QI 2 "const_int_1_operand" "I"))
11611 (const_int 0)))
11612 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11613 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11614 "ix86_match_ccmode (insn, CCGOCmode)
11615 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11616 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11617 "sar{b}\t%0"
11618 [(set_attr "type" "ishift")
11619 (set (attr "length")
11620 (if_then_else (match_operand 0 "register_operand" "")
11621 (const_string "2")
11622 (const_string "*")))])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrqi3_cmp"
11628 [(set (reg 17)
11629 (compare
11630 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "immediate_operand" "I"))
11632 (const_int 0)))
11633 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11635 "ix86_match_ccmode (insn, CCGOCmode)
11636 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11637 "sar{b}\t{%2, %0|%0, %2}"
11638 [(set_attr "type" "ishift")
11639 (set_attr "mode" "QI")])
11640 \f
11641 ;; Logical shift instructions
11642
11643 ;; See comment above `ashldi3' about how this works.
11644
11645 (define_expand "lshrdi3"
11646 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11647 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11648 (match_operand:QI 2 "nonmemory_operand" "")))
11649 (clobber (reg:CC 17))])]
11650 ""
11651 {
11652 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11653 {
11654 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11655 DONE;
11656 }
11657 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11658 DONE;
11659 })
11660
11661 (define_insn "*lshrdi3_1_one_bit_rex64"
11662 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11663 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11664 (match_operand:QI 2 "const_int_1_operand" "")))
11665 (clobber (reg:CC 17))]
11666 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11667 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11668 "shr{q}\t%0"
11669 [(set_attr "type" "ishift")
11670 (set (attr "length")
11671 (if_then_else (match_operand:DI 0 "register_operand" "")
11672 (const_string "2")
11673 (const_string "*")))])
11674
11675 (define_insn "*lshrdi3_1_rex64"
11676 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11677 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11678 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11679 (clobber (reg:CC 17))]
11680 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11681 "@
11682 shr{q}\t{%2, %0|%0, %2}
11683 shr{q}\t{%b2, %0|%0, %b2}"
11684 [(set_attr "type" "ishift")
11685 (set_attr "mode" "DI")])
11686
11687 ;; This pattern can't accept a variable shift count, since shifts by
11688 ;; zero don't affect the flags. We assume that shifts by constant
11689 ;; zero are optimized away.
11690 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11691 [(set (reg 17)
11692 (compare
11693 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11694 (match_operand:QI 2 "const_int_1_operand" ""))
11695 (const_int 0)))
11696 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11697 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11698 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11699 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11700 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11701 "shr{q}\t%0"
11702 [(set_attr "type" "ishift")
11703 (set (attr "length")
11704 (if_then_else (match_operand:DI 0 "register_operand" "")
11705 (const_string "2")
11706 (const_string "*")))])
11707
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags. We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*lshrdi3_cmp_rex64"
11712 [(set (reg 17)
11713 (compare
11714 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11715 (match_operand:QI 2 "const_int_operand" "e"))
11716 (const_int 0)))
11717 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11718 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11719 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11720 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11721 "shr{q}\t{%2, %0|%0, %2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "DI")])
11724
11725 (define_insn "lshrdi3_1"
11726 [(set (match_operand:DI 0 "register_operand" "=r")
11727 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11728 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11729 (clobber (match_scratch:SI 3 "=&r"))
11730 (clobber (reg:CC 17))]
11731 "!TARGET_64BIT && TARGET_CMOVE"
11732 "#"
11733 [(set_attr "type" "multi")])
11734
11735 (define_insn "*lshrdi3_2"
11736 [(set (match_operand:DI 0 "register_operand" "=r")
11737 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11738 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11739 (clobber (reg:CC 17))]
11740 "!TARGET_64BIT"
11741 "#"
11742 [(set_attr "type" "multi")])
11743
11744 (define_split
11745 [(set (match_operand:DI 0 "register_operand" "")
11746 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11747 (match_operand:QI 2 "nonmemory_operand" "")))
11748 (clobber (match_scratch:SI 3 ""))
11749 (clobber (reg:CC 17))]
11750 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11751 [(const_int 0)]
11752 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11753
11754 (define_split
11755 [(set (match_operand:DI 0 "register_operand" "")
11756 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11757 (match_operand:QI 2 "nonmemory_operand" "")))
11758 (clobber (reg:CC 17))]
11759 "!TARGET_64BIT && reload_completed"
11760 [(const_int 0)]
11761 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11762
11763 (define_expand "lshrsi3"
11764 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11765 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11766 (match_operand:QI 2 "nonmemory_operand" "")))
11767 (clobber (reg:CC 17))]
11768 ""
11769 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11770
11771 (define_insn "*lshrsi3_1_one_bit"
11772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11773 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11774 (match_operand:QI 2 "const_int_1_operand" "")))
11775 (clobber (reg:CC 17))]
11776 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11777 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11778 "shr{l}\t%0"
11779 [(set_attr "type" "ishift")
11780 (set (attr "length")
11781 (if_then_else (match_operand:SI 0 "register_operand" "")
11782 (const_string "2")
11783 (const_string "*")))])
11784
11785 (define_insn "*lshrsi3_1_one_bit_zext"
11786 [(set (match_operand:DI 0 "register_operand" "=r")
11787 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11788 (match_operand:QI 2 "const_int_1_operand" "")))
11789 (clobber (reg:CC 17))]
11790 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11791 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11792 "shr{l}\t%k0"
11793 [(set_attr "type" "ishift")
11794 (set_attr "length" "2")])
11795
11796 (define_insn "*lshrsi3_1"
11797 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11800 (clobber (reg:CC 17))]
11801 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802 "@
11803 shr{l}\t{%2, %0|%0, %2}
11804 shr{l}\t{%b2, %0|%0, %b2}"
11805 [(set_attr "type" "ishift")
11806 (set_attr "mode" "SI")])
11807
11808 (define_insn "*lshrsi3_1_zext"
11809 [(set (match_operand:DI 0 "register_operand" "=r,r")
11810 (zero_extend:DI
11811 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11812 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11813 (clobber (reg:CC 17))]
11814 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11815 "@
11816 shr{l}\t{%2, %k0|%k0, %2}
11817 shr{l}\t{%b2, %k0|%k0, %b2}"
11818 [(set_attr "type" "ishift")
11819 (set_attr "mode" "SI")])
11820
11821 ;; This pattern can't accept a variable shift count, since shifts by
11822 ;; zero don't affect the flags. We assume that shifts by constant
11823 ;; zero are optimized away.
11824 (define_insn "*lshrsi3_one_bit_cmp"
11825 [(set (reg 17)
11826 (compare
11827 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11828 (match_operand:QI 2 "const_int_1_operand" ""))
11829 (const_int 0)))
11830 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11831 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11832 "ix86_match_ccmode (insn, CCGOCmode)
11833 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11834 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11835 "shr{l}\t%0"
11836 [(set_attr "type" "ishift")
11837 (set (attr "length")
11838 (if_then_else (match_operand:SI 0 "register_operand" "")
11839 (const_string "2")
11840 (const_string "*")))])
11841
11842 (define_insn "*lshrsi3_cmp_one_bit_zext"
11843 [(set (reg 17)
11844 (compare
11845 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11846 (match_operand:QI 2 "const_int_1_operand" ""))
11847 (const_int 0)))
11848 (set (match_operand:DI 0 "register_operand" "=r")
11849 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11850 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11851 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11852 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11853 "shr{l}\t%k0"
11854 [(set_attr "type" "ishift")
11855 (set_attr "length" "2")])
11856
11857 ;; This pattern can't accept a variable shift count, since shifts by
11858 ;; zero don't affect the flags. We assume that shifts by constant
11859 ;; zero are optimized away.
11860 (define_insn "*lshrsi3_cmp"
11861 [(set (reg 17)
11862 (compare
11863 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11864 (match_operand:QI 2 "immediate_operand" "I"))
11865 (const_int 0)))
11866 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11867 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11868 "ix86_match_ccmode (insn, CCGOCmode)
11869 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11870 "shr{l}\t{%2, %0|%0, %2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "SI")])
11873
11874 (define_insn "*lshrsi3_cmp_zext"
11875 [(set (reg 17)
11876 (compare
11877 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11878 (match_operand:QI 2 "immediate_operand" "I"))
11879 (const_int 0)))
11880 (set (match_operand:DI 0 "register_operand" "=r")
11881 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11882 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11883 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11884 "shr{l}\t{%2, %k0|%k0, %2}"
11885 [(set_attr "type" "ishift")
11886 (set_attr "mode" "SI")])
11887
11888 (define_expand "lshrhi3"
11889 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11890 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11891 (match_operand:QI 2 "nonmemory_operand" "")))
11892 (clobber (reg:CC 17))]
11893 "TARGET_HIMODE_MATH"
11894 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11895
11896 (define_insn "*lshrhi3_1_one_bit"
11897 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11898 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899 (match_operand:QI 2 "const_int_1_operand" "")))
11900 (clobber (reg:CC 17))]
11901 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11902 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11903 "shr{w}\t%0"
11904 [(set_attr "type" "ishift")
11905 (set (attr "length")
11906 (if_then_else (match_operand 0 "register_operand" "")
11907 (const_string "2")
11908 (const_string "*")))])
11909
11910 (define_insn "*lshrhi3_1"
11911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11912 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11913 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11914 (clobber (reg:CC 17))]
11915 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11916 "@
11917 shr{w}\t{%2, %0|%0, %2}
11918 shr{w}\t{%b2, %0|%0, %b2}"
11919 [(set_attr "type" "ishift")
11920 (set_attr "mode" "HI")])
11921
11922 ;; This pattern can't accept a variable shift count, since shifts by
11923 ;; zero don't affect the flags. We assume that shifts by constant
11924 ;; zero are optimized away.
11925 (define_insn "*lshrhi3_one_bit_cmp"
11926 [(set (reg 17)
11927 (compare
11928 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const_int_1_operand" ""))
11930 (const_int 0)))
11931 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11932 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11933 "ix86_match_ccmode (insn, CCGOCmode)
11934 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11935 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11936 "shr{w}\t%0"
11937 [(set_attr "type" "ishift")
11938 (set (attr "length")
11939 (if_then_else (match_operand:SI 0 "register_operand" "")
11940 (const_string "2")
11941 (const_string "*")))])
11942
11943 ;; This pattern can't accept a variable shift count, since shifts by
11944 ;; zero don't affect the flags. We assume that shifts by constant
11945 ;; zero are optimized away.
11946 (define_insn "*lshrhi3_cmp"
11947 [(set (reg 17)
11948 (compare
11949 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11950 (match_operand:QI 2 "immediate_operand" "I"))
11951 (const_int 0)))
11952 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11953 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11954 "ix86_match_ccmode (insn, CCGOCmode)
11955 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11956 "shr{w}\t{%2, %0|%0, %2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "HI")])
11959
11960 (define_expand "lshrqi3"
11961 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11962 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11963 (match_operand:QI 2 "nonmemory_operand" "")))
11964 (clobber (reg:CC 17))]
11965 "TARGET_QIMODE_MATH"
11966 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11967
11968 (define_insn "*lshrqi3_1_one_bit"
11969 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11970 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11971 (match_operand:QI 2 "const_int_1_operand" "")))
11972 (clobber (reg:CC 17))]
11973 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11974 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11975 "shr{b}\t%0"
11976 [(set_attr "type" "ishift")
11977 (set (attr "length")
11978 (if_then_else (match_operand 0 "register_operand" "")
11979 (const_string "2")
11980 (const_string "*")))])
11981
11982 (define_insn "*lshrqi3_1"
11983 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11984 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11985 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986 (clobber (reg:CC 17))]
11987 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988 "@
11989 shr{b}\t{%2, %0|%0, %2}
11990 shr{b}\t{%b2, %0|%0, %b2}"
11991 [(set_attr "type" "ishift")
11992 (set_attr "mode" "QI")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*lshrqi2_one_bit_cmp"
11998 [(set (reg 17)
11999 (compare
12000 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const_int_1_operand" ""))
12002 (const_int 0)))
12003 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12005 "ix86_match_ccmode (insn, CCGOCmode)
12006 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
12007 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12008 "shr{b}\t%0"
12009 [(set_attr "type" "ishift")
12010 (set (attr "length")
12011 (if_then_else (match_operand:SI 0 "register_operand" "")
12012 (const_string "2")
12013 (const_string "*")))])
12014
12015 ;; This pattern can't accept a variable shift count, since shifts by
12016 ;; zero don't affect the flags. We assume that shifts by constant
12017 ;; zero are optimized away.
12018 (define_insn "*lshrqi2_cmp"
12019 [(set (reg 17)
12020 (compare
12021 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12022 (match_operand:QI 2 "immediate_operand" "I"))
12023 (const_int 0)))
12024 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12025 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12026 "ix86_match_ccmode (insn, CCGOCmode)
12027 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12028 "shr{b}\t{%2, %0|%0, %2}"
12029 [(set_attr "type" "ishift")
12030 (set_attr "mode" "QI")])
12031 \f
12032 ;; Rotate instructions
12033
12034 (define_expand "rotldi3"
12035 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12036 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12037 (match_operand:QI 2 "nonmemory_operand" "")))
12038 (clobber (reg:CC 17))]
12039 "TARGET_64BIT"
12040 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12041
12042 (define_insn "*rotlsi3_1_one_bit_rex64"
12043 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12044 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12045 (match_operand:QI 2 "const_int_1_operand" "")))
12046 (clobber (reg:CC 17))]
12047 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12048 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12049 "rol{q}\t%0"
12050 [(set_attr "type" "ishift")
12051 (set (attr "length")
12052 (if_then_else (match_operand:DI 0 "register_operand" "")
12053 (const_string "2")
12054 (const_string "*")))])
12055
12056 (define_insn "*rotldi3_1_rex64"
12057 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12058 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12059 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12060 (clobber (reg:CC 17))]
12061 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12062 "@
12063 rol{q}\t{%2, %0|%0, %2}
12064 rol{q}\t{%b2, %0|%0, %b2}"
12065 [(set_attr "type" "ishift")
12066 (set_attr "mode" "DI")])
12067
12068 (define_expand "rotlsi3"
12069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12070 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12071 (match_operand:QI 2 "nonmemory_operand" "")))
12072 (clobber (reg:CC 17))]
12073 ""
12074 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12075
12076 (define_insn "*rotlsi3_1_one_bit"
12077 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12078 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12079 (match_operand:QI 2 "const_int_1_operand" "")))
12080 (clobber (reg:CC 17))]
12081 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12082 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12083 "rol{l}\t%0"
12084 [(set_attr "type" "ishift")
12085 (set (attr "length")
12086 (if_then_else (match_operand:SI 0 "register_operand" "")
12087 (const_string "2")
12088 (const_string "*")))])
12089
12090 (define_insn "*rotlsi3_1_one_bit_zext"
12091 [(set (match_operand:DI 0 "register_operand" "=r")
12092 (zero_extend:DI
12093 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12094 (match_operand:QI 2 "const_int_1_operand" ""))))
12095 (clobber (reg:CC 17))]
12096 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12097 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12098 "rol{l}\t%k0"
12099 [(set_attr "type" "ishift")
12100 (set_attr "length" "2")])
12101
12102 (define_insn "*rotlsi3_1"
12103 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12104 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12105 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12106 (clobber (reg:CC 17))]
12107 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12108 "@
12109 rol{l}\t{%2, %0|%0, %2}
12110 rol{l}\t{%b2, %0|%0, %b2}"
12111 [(set_attr "type" "ishift")
12112 (set_attr "mode" "SI")])
12113
12114 (define_insn "*rotlsi3_1_zext"
12115 [(set (match_operand:DI 0 "register_operand" "=r,r")
12116 (zero_extend:DI
12117 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12118 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12119 (clobber (reg:CC 17))]
12120 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12121 "@
12122 rol{l}\t{%2, %k0|%k0, %2}
12123 rol{l}\t{%b2, %k0|%k0, %b2}"
12124 [(set_attr "type" "ishift")
12125 (set_attr "mode" "SI")])
12126
12127 (define_expand "rotlhi3"
12128 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12129 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12130 (match_operand:QI 2 "nonmemory_operand" "")))
12131 (clobber (reg:CC 17))]
12132 "TARGET_HIMODE_MATH"
12133 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12134
12135 (define_insn "*rotlhi3_1_one_bit"
12136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12137 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12138 (match_operand:QI 2 "const_int_1_operand" "")))
12139 (clobber (reg:CC 17))]
12140 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12141 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12142 "rol{w}\t%0"
12143 [(set_attr "type" "ishift")
12144 (set (attr "length")
12145 (if_then_else (match_operand 0 "register_operand" "")
12146 (const_string "2")
12147 (const_string "*")))])
12148
12149 (define_insn "*rotlhi3_1"
12150 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12151 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12152 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12153 (clobber (reg:CC 17))]
12154 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12155 "@
12156 rol{w}\t{%2, %0|%0, %2}
12157 rol{w}\t{%b2, %0|%0, %b2}"
12158 [(set_attr "type" "ishift")
12159 (set_attr "mode" "HI")])
12160
12161 (define_expand "rotlqi3"
12162 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12163 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12164 (match_operand:QI 2 "nonmemory_operand" "")))
12165 (clobber (reg:CC 17))]
12166 "TARGET_QIMODE_MATH"
12167 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12168
12169 (define_insn "*rotlqi3_1_one_bit"
12170 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12171 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12172 (match_operand:QI 2 "const_int_1_operand" "")))
12173 (clobber (reg:CC 17))]
12174 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12175 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12176 "rol{b}\t%0"
12177 [(set_attr "type" "ishift")
12178 (set (attr "length")
12179 (if_then_else (match_operand 0 "register_operand" "")
12180 (const_string "2")
12181 (const_string "*")))])
12182
12183 (define_insn "*rotlqi3_1"
12184 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12185 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12186 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12187 (clobber (reg:CC 17))]
12188 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12189 "@
12190 rol{b}\t{%2, %0|%0, %2}
12191 rol{b}\t{%b2, %0|%0, %b2}"
12192 [(set_attr "type" "ishift")
12193 (set_attr "mode" "QI")])
12194
12195 (define_expand "rotrdi3"
12196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12197 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12198 (match_operand:QI 2 "nonmemory_operand" "")))
12199 (clobber (reg:CC 17))]
12200 "TARGET_64BIT"
12201 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12202
12203 (define_insn "*rotrdi3_1_one_bit_rex64"
12204 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12205 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12206 (match_operand:QI 2 "const_int_1_operand" "")))
12207 (clobber (reg:CC 17))]
12208 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12209 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12210 "ror{q}\t%0"
12211 [(set_attr "type" "ishift")
12212 (set (attr "length")
12213 (if_then_else (match_operand:DI 0 "register_operand" "")
12214 (const_string "2")
12215 (const_string "*")))])
12216
12217 (define_insn "*rotrdi3_1_rex64"
12218 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12219 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12220 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12221 (clobber (reg:CC 17))]
12222 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12223 "@
12224 ror{q}\t{%2, %0|%0, %2}
12225 ror{q}\t{%b2, %0|%0, %b2}"
12226 [(set_attr "type" "ishift")
12227 (set_attr "mode" "DI")])
12228
12229 (define_expand "rotrsi3"
12230 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12231 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12232 (match_operand:QI 2 "nonmemory_operand" "")))
12233 (clobber (reg:CC 17))]
12234 ""
12235 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12236
12237 (define_insn "*rotrsi3_1_one_bit"
12238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12239 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_int_1_operand" "")))
12241 (clobber (reg:CC 17))]
12242 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12243 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12244 "ror{l}\t%0"
12245 [(set_attr "type" "ishift")
12246 (set (attr "length")
12247 (if_then_else (match_operand:SI 0 "register_operand" "")
12248 (const_string "2")
12249 (const_string "*")))])
12250
12251 (define_insn "*rotrsi3_1_one_bit_zext"
12252 [(set (match_operand:DI 0 "register_operand" "=r")
12253 (zero_extend:DI
12254 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12255 (match_operand:QI 2 "const_int_1_operand" ""))))
12256 (clobber (reg:CC 17))]
12257 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12258 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12259 "ror{l}\t%k0"
12260 [(set_attr "type" "ishift")
12261 (set (attr "length")
12262 (if_then_else (match_operand:SI 0 "register_operand" "")
12263 (const_string "2")
12264 (const_string "*")))])
12265
12266 (define_insn "*rotrsi3_1"
12267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12268 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12269 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12270 (clobber (reg:CC 17))]
12271 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12272 "@
12273 ror{l}\t{%2, %0|%0, %2}
12274 ror{l}\t{%b2, %0|%0, %b2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "SI")])
12277
12278 (define_insn "*rotrsi3_1_zext"
12279 [(set (match_operand:DI 0 "register_operand" "=r,r")
12280 (zero_extend:DI
12281 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12282 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12283 (clobber (reg:CC 17))]
12284 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12285 "@
12286 ror{l}\t{%2, %k0|%k0, %2}
12287 ror{l}\t{%b2, %k0|%k0, %b2}"
12288 [(set_attr "type" "ishift")
12289 (set_attr "mode" "SI")])
12290
12291 (define_expand "rotrhi3"
12292 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12293 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12294 (match_operand:QI 2 "nonmemory_operand" "")))
12295 (clobber (reg:CC 17))]
12296 "TARGET_HIMODE_MATH"
12297 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12298
12299 (define_insn "*rotrhi3_one_bit"
12300 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12301 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const_int_1_operand" "")))
12303 (clobber (reg:CC 17))]
12304 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12305 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12306 "ror{w}\t%0"
12307 [(set_attr "type" "ishift")
12308 (set (attr "length")
12309 (if_then_else (match_operand 0 "register_operand" "")
12310 (const_string "2")
12311 (const_string "*")))])
12312
12313 (define_insn "*rotrhi3"
12314 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12315 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12316 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12317 (clobber (reg:CC 17))]
12318 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12319 "@
12320 ror{w}\t{%2, %0|%0, %2}
12321 ror{w}\t{%b2, %0|%0, %b2}"
12322 [(set_attr "type" "ishift")
12323 (set_attr "mode" "HI")])
12324
12325 (define_expand "rotrqi3"
12326 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12327 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12328 (match_operand:QI 2 "nonmemory_operand" "")))
12329 (clobber (reg:CC 17))]
12330 "TARGET_QIMODE_MATH"
12331 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12332
12333 (define_insn "*rotrqi3_1_one_bit"
12334 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12335 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12336 (match_operand:QI 2 "const_int_1_operand" "")))
12337 (clobber (reg:CC 17))]
12338 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12339 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12340 "ror{b}\t%0"
12341 [(set_attr "type" "ishift")
12342 (set (attr "length")
12343 (if_then_else (match_operand 0 "register_operand" "")
12344 (const_string "2")
12345 (const_string "*")))])
12346
12347 (define_insn "*rotrqi3_1"
12348 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12349 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12350 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12351 (clobber (reg:CC 17))]
12352 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12353 "@
12354 ror{b}\t{%2, %0|%0, %2}
12355 ror{b}\t{%b2, %0|%0, %b2}"
12356 [(set_attr "type" "ishift")
12357 (set_attr "mode" "QI")])
12358 \f
12359 ;; Bit set / bit test instructions
12360
12361 (define_expand "extv"
12362 [(set (match_operand:SI 0 "register_operand" "")
12363 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12364 (match_operand:SI 2 "immediate_operand" "")
12365 (match_operand:SI 3 "immediate_operand" "")))]
12366 ""
12367 {
12368 /* Handle extractions from %ah et al. */
12369 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12370 FAIL;
12371
12372 /* From mips.md: extract_bit_field doesn't verify that our source
12373 matches the predicate, so check it again here. */
12374 if (! register_operand (operands[1], VOIDmode))
12375 FAIL;
12376 })
12377
12378 (define_expand "extzv"
12379 [(set (match_operand:SI 0 "register_operand" "")
12380 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12381 (match_operand:SI 2 "immediate_operand" "")
12382 (match_operand:SI 3 "immediate_operand" "")))]
12383 ""
12384 {
12385 /* Handle extractions from %ah et al. */
12386 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12387 FAIL;
12388
12389 /* From mips.md: extract_bit_field doesn't verify that our source
12390 matches the predicate, so check it again here. */
12391 if (! register_operand (operands[1], VOIDmode))
12392 FAIL;
12393 })
12394
12395 (define_expand "insv"
12396 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12397 (match_operand:SI 1 "immediate_operand" "")
12398 (match_operand:SI 2 "immediate_operand" ""))
12399 (match_operand:SI 3 "register_operand" ""))]
12400 ""
12401 {
12402 /* Handle extractions from %ah et al. */
12403 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12404 FAIL;
12405
12406 /* From mips.md: insert_bit_field doesn't verify that our source
12407 matches the predicate, so check it again here. */
12408 if (! register_operand (operands[0], VOIDmode))
12409 FAIL;
12410 })
12411
12412 ;; %%% bts, btr, btc, bt.
12413 \f
12414 ;; Store-flag instructions.
12415
12416 ;; For all sCOND expanders, also expand the compare or test insn that
12417 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12418
12419 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12420 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12421 ;; way, which can later delete the movzx if only QImode is needed.
12422
12423 (define_expand "seq"
12424 [(set (match_operand:QI 0 "register_operand" "")
12425 (eq:QI (reg:CC 17) (const_int 0)))]
12426 ""
12427 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12428
12429 (define_expand "sne"
12430 [(set (match_operand:QI 0 "register_operand" "")
12431 (ne:QI (reg:CC 17) (const_int 0)))]
12432 ""
12433 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12434
12435 (define_expand "sgt"
12436 [(set (match_operand:QI 0 "register_operand" "")
12437 (gt:QI (reg:CC 17) (const_int 0)))]
12438 ""
12439 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12440
12441 (define_expand "sgtu"
12442 [(set (match_operand:QI 0 "register_operand" "")
12443 (gtu:QI (reg:CC 17) (const_int 0)))]
12444 ""
12445 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12446
12447 (define_expand "slt"
12448 [(set (match_operand:QI 0 "register_operand" "")
12449 (lt:QI (reg:CC 17) (const_int 0)))]
12450 ""
12451 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12452
12453 (define_expand "sltu"
12454 [(set (match_operand:QI 0 "register_operand" "")
12455 (ltu:QI (reg:CC 17) (const_int 0)))]
12456 ""
12457 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12458
12459 (define_expand "sge"
12460 [(set (match_operand:QI 0 "register_operand" "")
12461 (ge:QI (reg:CC 17) (const_int 0)))]
12462 ""
12463 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12464
12465 (define_expand "sgeu"
12466 [(set (match_operand:QI 0 "register_operand" "")
12467 (geu:QI (reg:CC 17) (const_int 0)))]
12468 ""
12469 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12470
12471 (define_expand "sle"
12472 [(set (match_operand:QI 0 "register_operand" "")
12473 (le:QI (reg:CC 17) (const_int 0)))]
12474 ""
12475 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12476
12477 (define_expand "sleu"
12478 [(set (match_operand:QI 0 "register_operand" "")
12479 (leu:QI (reg:CC 17) (const_int 0)))]
12480 ""
12481 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12482
12483 (define_expand "sunordered"
12484 [(set (match_operand:QI 0 "register_operand" "")
12485 (unordered:QI (reg:CC 17) (const_int 0)))]
12486 "TARGET_80387 || TARGET_SSE"
12487 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12488
12489 (define_expand "sordered"
12490 [(set (match_operand:QI 0 "register_operand" "")
12491 (ordered:QI (reg:CC 17) (const_int 0)))]
12492 "TARGET_80387"
12493 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12494
12495 (define_expand "suneq"
12496 [(set (match_operand:QI 0 "register_operand" "")
12497 (uneq:QI (reg:CC 17) (const_int 0)))]
12498 "TARGET_80387 || TARGET_SSE"
12499 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12500
12501 (define_expand "sunge"
12502 [(set (match_operand:QI 0 "register_operand" "")
12503 (unge:QI (reg:CC 17) (const_int 0)))]
12504 "TARGET_80387 || TARGET_SSE"
12505 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12506
12507 (define_expand "sungt"
12508 [(set (match_operand:QI 0 "register_operand" "")
12509 (ungt:QI (reg:CC 17) (const_int 0)))]
12510 "TARGET_80387 || TARGET_SSE"
12511 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12512
12513 (define_expand "sunle"
12514 [(set (match_operand:QI 0 "register_operand" "")
12515 (unle:QI (reg:CC 17) (const_int 0)))]
12516 "TARGET_80387 || TARGET_SSE"
12517 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12518
12519 (define_expand "sunlt"
12520 [(set (match_operand:QI 0 "register_operand" "")
12521 (unlt:QI (reg:CC 17) (const_int 0)))]
12522 "TARGET_80387 || TARGET_SSE"
12523 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12524
12525 (define_expand "sltgt"
12526 [(set (match_operand:QI 0 "register_operand" "")
12527 (ltgt:QI (reg:CC 17) (const_int 0)))]
12528 "TARGET_80387 || TARGET_SSE"
12529 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12530
12531 (define_insn "*setcc_1"
12532 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12533 (match_operator:QI 1 "ix86_comparison_operator"
12534 [(reg 17) (const_int 0)]))]
12535 ""
12536 "set%C1\t%0"
12537 [(set_attr "type" "setcc")
12538 (set_attr "mode" "QI")])
12539
12540 (define_insn "setcc_2"
12541 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12542 (match_operator:QI 1 "ix86_comparison_operator"
12543 [(reg 17) (const_int 0)]))]
12544 ""
12545 "set%C1\t%0"
12546 [(set_attr "type" "setcc")
12547 (set_attr "mode" "QI")])
12548
12549 ;; In general it is not safe to assume too much about CCmode registers,
12550 ;; so simplify-rtx stops when it sees a second one. Under certain
12551 ;; conditions this is safe on x86, so help combine not create
12552 ;;
12553 ;; seta %al
12554 ;; testb %al, %al
12555 ;; sete %al
12556
12557 (define_split
12558 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12559 (ne:QI (match_operator 1 "ix86_comparison_operator"
12560 [(reg 17) (const_int 0)])
12561 (const_int 0)))]
12562 ""
12563 [(set (match_dup 0) (match_dup 1))]
12564 {
12565 PUT_MODE (operands[1], QImode);
12566 })
12567
12568 (define_split
12569 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12570 (ne:QI (match_operator 1 "ix86_comparison_operator"
12571 [(reg 17) (const_int 0)])
12572 (const_int 0)))]
12573 ""
12574 [(set (match_dup 0) (match_dup 1))]
12575 {
12576 PUT_MODE (operands[1], QImode);
12577 })
12578
12579 (define_split
12580 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12581 (eq:QI (match_operator 1 "ix86_comparison_operator"
12582 [(reg 17) (const_int 0)])
12583 (const_int 0)))]
12584 ""
12585 [(set (match_dup 0) (match_dup 1))]
12586 {
12587 rtx new_op1 = copy_rtx (operands[1]);
12588 operands[1] = new_op1;
12589 PUT_MODE (new_op1, QImode);
12590 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12591 GET_MODE (XEXP (new_op1, 0))));
12592
12593 /* Make sure that (a) the CCmode we have for the flags is strong
12594 enough for the reversed compare or (b) we have a valid FP compare. */
12595 if (! ix86_comparison_operator (new_op1, VOIDmode))
12596 FAIL;
12597 })
12598
12599 (define_split
12600 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12601 (eq:QI (match_operator 1 "ix86_comparison_operator"
12602 [(reg 17) (const_int 0)])
12603 (const_int 0)))]
12604 ""
12605 [(set (match_dup 0) (match_dup 1))]
12606 {
12607 rtx new_op1 = copy_rtx (operands[1]);
12608 operands[1] = new_op1;
12609 PUT_MODE (new_op1, QImode);
12610 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12611 GET_MODE (XEXP (new_op1, 0))));
12612
12613 /* Make sure that (a) the CCmode we have for the flags is strong
12614 enough for the reversed compare or (b) we have a valid FP compare. */
12615 if (! ix86_comparison_operator (new_op1, VOIDmode))
12616 FAIL;
12617 })
12618
12619 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12620 ;; subsequent logical operations are used to imitate conditional moves.
12621 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12622 ;; it directly. Futher holding this value in pseudo register might bring
12623 ;; problem in implicit normalization in spill code.
12624 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12625 ;; instructions after reload by splitting the conditional move patterns.
12626
12627 (define_insn "*sse_setccsf"
12628 [(set (match_operand:SF 0 "register_operand" "=x")
12629 (match_operator:SF 1 "sse_comparison_operator"
12630 [(match_operand:SF 2 "register_operand" "0")
12631 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12632 "TARGET_SSE && reload_completed"
12633 "cmp%D1ss\t{%3, %0|%0, %3}"
12634 [(set_attr "type" "sse")
12635 (set_attr "mode" "SF")])
12636
12637 (define_insn "*sse_setccdf"
12638 [(set (match_operand:DF 0 "register_operand" "=Y")
12639 (match_operator:DF 1 "sse_comparison_operator"
12640 [(match_operand:DF 2 "register_operand" "0")
12641 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12642 "TARGET_SSE2 && reload_completed"
12643 "cmp%D1sd\t{%3, %0|%0, %3}"
12644 [(set_attr "type" "sse")
12645 (set_attr "mode" "DF")])
12646 \f
12647 ;; Basic conditional jump instructions.
12648 ;; We ignore the overflow flag for signed branch instructions.
12649
12650 ;; For all bCOND expanders, also expand the compare or test insn that
12651 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12652
12653 (define_expand "beq"
12654 [(set (pc)
12655 (if_then_else (match_dup 1)
12656 (label_ref (match_operand 0 "" ""))
12657 (pc)))]
12658 ""
12659 "ix86_expand_branch (EQ, operands[0]); DONE;")
12660
12661 (define_expand "bne"
12662 [(set (pc)
12663 (if_then_else (match_dup 1)
12664 (label_ref (match_operand 0 "" ""))
12665 (pc)))]
12666 ""
12667 "ix86_expand_branch (NE, operands[0]); DONE;")
12668
12669 (define_expand "bgt"
12670 [(set (pc)
12671 (if_then_else (match_dup 1)
12672 (label_ref (match_operand 0 "" ""))
12673 (pc)))]
12674 ""
12675 "ix86_expand_branch (GT, operands[0]); DONE;")
12676
12677 (define_expand "bgtu"
12678 [(set (pc)
12679 (if_then_else (match_dup 1)
12680 (label_ref (match_operand 0 "" ""))
12681 (pc)))]
12682 ""
12683 "ix86_expand_branch (GTU, operands[0]); DONE;")
12684
12685 (define_expand "blt"
12686 [(set (pc)
12687 (if_then_else (match_dup 1)
12688 (label_ref (match_operand 0 "" ""))
12689 (pc)))]
12690 ""
12691 "ix86_expand_branch (LT, operands[0]); DONE;")
12692
12693 (define_expand "bltu"
12694 [(set (pc)
12695 (if_then_else (match_dup 1)
12696 (label_ref (match_operand 0 "" ""))
12697 (pc)))]
12698 ""
12699 "ix86_expand_branch (LTU, operands[0]); DONE;")
12700
12701 (define_expand "bge"
12702 [(set (pc)
12703 (if_then_else (match_dup 1)
12704 (label_ref (match_operand 0 "" ""))
12705 (pc)))]
12706 ""
12707 "ix86_expand_branch (GE, operands[0]); DONE;")
12708
12709 (define_expand "bgeu"
12710 [(set (pc)
12711 (if_then_else (match_dup 1)
12712 (label_ref (match_operand 0 "" ""))
12713 (pc)))]
12714 ""
12715 "ix86_expand_branch (GEU, operands[0]); DONE;")
12716
12717 (define_expand "ble"
12718 [(set (pc)
12719 (if_then_else (match_dup 1)
12720 (label_ref (match_operand 0 "" ""))
12721 (pc)))]
12722 ""
12723 "ix86_expand_branch (LE, operands[0]); DONE;")
12724
12725 (define_expand "bleu"
12726 [(set (pc)
12727 (if_then_else (match_dup 1)
12728 (label_ref (match_operand 0 "" ""))
12729 (pc)))]
12730 ""
12731 "ix86_expand_branch (LEU, operands[0]); DONE;")
12732
12733 (define_expand "bunordered"
12734 [(set (pc)
12735 (if_then_else (match_dup 1)
12736 (label_ref (match_operand 0 "" ""))
12737 (pc)))]
12738 "TARGET_80387 || TARGET_SSE"
12739 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12740
12741 (define_expand "bordered"
12742 [(set (pc)
12743 (if_then_else (match_dup 1)
12744 (label_ref (match_operand 0 "" ""))
12745 (pc)))]
12746 "TARGET_80387 || TARGET_SSE"
12747 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12748
12749 (define_expand "buneq"
12750 [(set (pc)
12751 (if_then_else (match_dup 1)
12752 (label_ref (match_operand 0 "" ""))
12753 (pc)))]
12754 "TARGET_80387 || TARGET_SSE"
12755 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12756
12757 (define_expand "bunge"
12758 [(set (pc)
12759 (if_then_else (match_dup 1)
12760 (label_ref (match_operand 0 "" ""))
12761 (pc)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12764
12765 (define_expand "bungt"
12766 [(set (pc)
12767 (if_then_else (match_dup 1)
12768 (label_ref (match_operand 0 "" ""))
12769 (pc)))]
12770 "TARGET_80387 || TARGET_SSE"
12771 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12772
12773 (define_expand "bunle"
12774 [(set (pc)
12775 (if_then_else (match_dup 1)
12776 (label_ref (match_operand 0 "" ""))
12777 (pc)))]
12778 "TARGET_80387 || TARGET_SSE"
12779 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12780
12781 (define_expand "bunlt"
12782 [(set (pc)
12783 (if_then_else (match_dup 1)
12784 (label_ref (match_operand 0 "" ""))
12785 (pc)))]
12786 "TARGET_80387 || TARGET_SSE"
12787 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12788
12789 (define_expand "bltgt"
12790 [(set (pc)
12791 (if_then_else (match_dup 1)
12792 (label_ref (match_operand 0 "" ""))
12793 (pc)))]
12794 "TARGET_80387 || TARGET_SSE"
12795 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12796
12797 (define_insn "*jcc_1"
12798 [(set (pc)
12799 (if_then_else (match_operator 1 "ix86_comparison_operator"
12800 [(reg 17) (const_int 0)])
12801 (label_ref (match_operand 0 "" ""))
12802 (pc)))]
12803 ""
12804 "%+j%C1\t%l0"
12805 [(set_attr "type" "ibr")
12806 (set (attr "prefix_0f")
12807 (if_then_else (and (ge (minus (match_dup 0) (pc))
12808 (const_int -128))
12809 (lt (minus (match_dup 0) (pc))
12810 (const_int 124)))
12811 (const_int 0)
12812 (const_int 1)))])
12813
12814 (define_insn "*jcc_2"
12815 [(set (pc)
12816 (if_then_else (match_operator 1 "ix86_comparison_operator"
12817 [(reg 17) (const_int 0)])
12818 (pc)
12819 (label_ref (match_operand 0 "" ""))))]
12820 ""
12821 "%+j%c1\t%l0"
12822 [(set_attr "type" "ibr")
12823 (set (attr "prefix_0f")
12824 (if_then_else (and (ge (minus (match_dup 0) (pc))
12825 (const_int -128))
12826 (lt (minus (match_dup 0) (pc))
12827 (const_int 124)))
12828 (const_int 0)
12829 (const_int 1)))])
12830
12831 ;; In general it is not safe to assume too much about CCmode registers,
12832 ;; so simplify-rtx stops when it sees a second one. Under certain
12833 ;; conditions this is safe on x86, so help combine not create
12834 ;;
12835 ;; seta %al
12836 ;; testb %al, %al
12837 ;; je Lfoo
12838
12839 (define_split
12840 [(set (pc)
12841 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12842 [(reg 17) (const_int 0)])
12843 (const_int 0))
12844 (label_ref (match_operand 1 "" ""))
12845 (pc)))]
12846 ""
12847 [(set (pc)
12848 (if_then_else (match_dup 0)
12849 (label_ref (match_dup 1))
12850 (pc)))]
12851 {
12852 PUT_MODE (operands[0], VOIDmode);
12853 })
12854
12855 (define_split
12856 [(set (pc)
12857 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12858 [(reg 17) (const_int 0)])
12859 (const_int 0))
12860 (label_ref (match_operand 1 "" ""))
12861 (pc)))]
12862 ""
12863 [(set (pc)
12864 (if_then_else (match_dup 0)
12865 (label_ref (match_dup 1))
12866 (pc)))]
12867 {
12868 rtx new_op0 = copy_rtx (operands[0]);
12869 operands[0] = new_op0;
12870 PUT_MODE (new_op0, VOIDmode);
12871 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12872 GET_MODE (XEXP (new_op0, 0))));
12873
12874 /* Make sure that (a) the CCmode we have for the flags is strong
12875 enough for the reversed compare or (b) we have a valid FP compare. */
12876 if (! ix86_comparison_operator (new_op0, VOIDmode))
12877 FAIL;
12878 })
12879
12880 ;; Define combination compare-and-branch fp compare instructions to use
12881 ;; during early optimization. Splitting the operation apart early makes
12882 ;; for bad code when we want to reverse the operation.
12883
12884 (define_insn "*fp_jcc_1"
12885 [(set (pc)
12886 (if_then_else (match_operator 0 "comparison_operator"
12887 [(match_operand 1 "register_operand" "f")
12888 (match_operand 2 "register_operand" "f")])
12889 (label_ref (match_operand 3 "" ""))
12890 (pc)))
12891 (clobber (reg:CCFP 18))
12892 (clobber (reg:CCFP 17))]
12893 "TARGET_CMOVE && TARGET_80387
12894 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12895 && FLOAT_MODE_P (GET_MODE (operands[1]))
12896 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12897 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12898 "#")
12899
12900 (define_insn "*fp_jcc_1_sse"
12901 [(set (pc)
12902 (if_then_else (match_operator 0 "comparison_operator"
12903 [(match_operand 1 "register_operand" "f#x,x#f")
12904 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12905 (label_ref (match_operand 3 "" ""))
12906 (pc)))
12907 (clobber (reg:CCFP 18))
12908 (clobber (reg:CCFP 17))]
12909 "TARGET_80387
12910 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12911 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12912 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12913 "#")
12914
12915 (define_insn "*fp_jcc_1_sse_only"
12916 [(set (pc)
12917 (if_then_else (match_operator 0 "comparison_operator"
12918 [(match_operand 1 "register_operand" "x")
12919 (match_operand 2 "nonimmediate_operand" "xm")])
12920 (label_ref (match_operand 3 "" ""))
12921 (pc)))
12922 (clobber (reg:CCFP 18))
12923 (clobber (reg:CCFP 17))]
12924 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12925 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12926 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12927 "#")
12928
12929 (define_insn "*fp_jcc_2"
12930 [(set (pc)
12931 (if_then_else (match_operator 0 "comparison_operator"
12932 [(match_operand 1 "register_operand" "f")
12933 (match_operand 2 "register_operand" "f")])
12934 (pc)
12935 (label_ref (match_operand 3 "" ""))))
12936 (clobber (reg:CCFP 18))
12937 (clobber (reg:CCFP 17))]
12938 "TARGET_CMOVE && TARGET_80387
12939 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12940 && FLOAT_MODE_P (GET_MODE (operands[1]))
12941 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12942 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12943 "#")
12944
12945 (define_insn "*fp_jcc_2_sse"
12946 [(set (pc)
12947 (if_then_else (match_operator 0 "comparison_operator"
12948 [(match_operand 1 "register_operand" "f#x,x#f")
12949 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12950 (pc)
12951 (label_ref (match_operand 3 "" ""))))
12952 (clobber (reg:CCFP 18))
12953 (clobber (reg:CCFP 17))]
12954 "TARGET_80387
12955 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12956 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12957 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12958 "#")
12959
12960 (define_insn "*fp_jcc_2_sse_only"
12961 [(set (pc)
12962 (if_then_else (match_operator 0 "comparison_operator"
12963 [(match_operand 1 "register_operand" "x")
12964 (match_operand 2 "nonimmediate_operand" "xm")])
12965 (pc)
12966 (label_ref (match_operand 3 "" ""))))
12967 (clobber (reg:CCFP 18))
12968 (clobber (reg:CCFP 17))]
12969 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12970 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12971 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12972 "#")
12973
12974 (define_insn "*fp_jcc_3"
12975 [(set (pc)
12976 (if_then_else (match_operator 0 "comparison_operator"
12977 [(match_operand 1 "register_operand" "f")
12978 (match_operand 2 "nonimmediate_operand" "fm")])
12979 (label_ref (match_operand 3 "" ""))
12980 (pc)))
12981 (clobber (reg:CCFP 18))
12982 (clobber (reg:CCFP 17))
12983 (clobber (match_scratch:HI 4 "=a"))]
12984 "TARGET_80387
12985 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12987 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12988 && SELECT_CC_MODE (GET_CODE (operands[0]),
12989 operands[1], operands[2]) == CCFPmode
12990 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12991 "#")
12992
12993 (define_insn "*fp_jcc_4"
12994 [(set (pc)
12995 (if_then_else (match_operator 0 "comparison_operator"
12996 [(match_operand 1 "register_operand" "f")
12997 (match_operand 2 "nonimmediate_operand" "fm")])
12998 (pc)
12999 (label_ref (match_operand 3 "" ""))))
13000 (clobber (reg:CCFP 18))
13001 (clobber (reg:CCFP 17))
13002 (clobber (match_scratch:HI 4 "=a"))]
13003 "TARGET_80387
13004 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13005 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13006 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13007 && SELECT_CC_MODE (GET_CODE (operands[0]),
13008 operands[1], operands[2]) == CCFPmode
13009 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13010 "#")
13011
13012 (define_insn "*fp_jcc_5"
13013 [(set (pc)
13014 (if_then_else (match_operator 0 "comparison_operator"
13015 [(match_operand 1 "register_operand" "f")
13016 (match_operand 2 "register_operand" "f")])
13017 (label_ref (match_operand 3 "" ""))
13018 (pc)))
13019 (clobber (reg:CCFP 18))
13020 (clobber (reg:CCFP 17))
13021 (clobber (match_scratch:HI 4 "=a"))]
13022 "TARGET_80387
13023 && FLOAT_MODE_P (GET_MODE (operands[1]))
13024 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13025 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13026 "#")
13027
13028 (define_insn "*fp_jcc_6"
13029 [(set (pc)
13030 (if_then_else (match_operator 0 "comparison_operator"
13031 [(match_operand 1 "register_operand" "f")
13032 (match_operand 2 "register_operand" "f")])
13033 (pc)
13034 (label_ref (match_operand 3 "" ""))))
13035 (clobber (reg:CCFP 18))
13036 (clobber (reg:CCFP 17))
13037 (clobber (match_scratch:HI 4 "=a"))]
13038 "TARGET_80387
13039 && FLOAT_MODE_P (GET_MODE (operands[1]))
13040 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13041 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13042 "#")
13043
13044 (define_split
13045 [(set (pc)
13046 (if_then_else (match_operator 0 "comparison_operator"
13047 [(match_operand 1 "register_operand" "")
13048 (match_operand 2 "nonimmediate_operand" "")])
13049 (match_operand 3 "" "")
13050 (match_operand 4 "" "")))
13051 (clobber (reg:CCFP 18))
13052 (clobber (reg:CCFP 17))]
13053 "reload_completed"
13054 [(const_int 0)]
13055 {
13056 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13057 operands[3], operands[4], NULL_RTX);
13058 DONE;
13059 })
13060
13061 (define_split
13062 [(set (pc)
13063 (if_then_else (match_operator 0 "comparison_operator"
13064 [(match_operand 1 "register_operand" "")
13065 (match_operand 2 "nonimmediate_operand" "")])
13066 (match_operand 3 "" "")
13067 (match_operand 4 "" "")))
13068 (clobber (reg:CCFP 18))
13069 (clobber (reg:CCFP 17))
13070 (clobber (match_scratch:HI 5 "=a"))]
13071 "reload_completed"
13072 [(set (pc)
13073 (if_then_else (match_dup 6)
13074 (match_dup 3)
13075 (match_dup 4)))]
13076 {
13077 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13078 operands[3], operands[4], operands[5]);
13079 DONE;
13080 })
13081 \f
13082 ;; Unconditional and other jump instructions
13083
13084 (define_insn "jump"
13085 [(set (pc)
13086 (label_ref (match_operand 0 "" "")))]
13087 ""
13088 "jmp\t%l0"
13089 [(set_attr "type" "ibr")])
13090
13091 (define_expand "indirect_jump"
13092 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13093 ""
13094 "")
13095
13096 (define_insn "*indirect_jump"
13097 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13098 "!TARGET_64BIT"
13099 "jmp\t%A0"
13100 [(set_attr "type" "ibr")
13101 (set_attr "length_immediate" "0")])
13102
13103 (define_insn "*indirect_jump_rtx64"
13104 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13105 "TARGET_64BIT"
13106 "jmp\t%A0"
13107 [(set_attr "type" "ibr")
13108 (set_attr "length_immediate" "0")])
13109
13110 (define_expand "tablejump"
13111 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13112 (use (label_ref (match_operand 1 "" "")))])]
13113 ""
13114 {
13115 /* In PIC mode, the table entries are stored GOT-relative. Convert
13116 the relative address to an absolute address. */
13117 if (flag_pic)
13118 {
13119 if (TARGET_64BIT)
13120 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13121 gen_rtx_LABEL_REF (Pmode, operands[1]),
13122 NULL_RTX, 0,
13123 OPTAB_DIRECT);
13124 else if (HAVE_AS_GOTOFF_IN_DATA)
13125 {
13126 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
13127 pic_offset_table_rtx, NULL_RTX,
13128 1, OPTAB_DIRECT);
13129 current_function_uses_pic_offset_table = 1;
13130 }
13131 else
13132 {
13133 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
13134 operands[0], NULL_RTX, 1,
13135 OPTAB_DIRECT);
13136 current_function_uses_pic_offset_table = 1;
13137 }
13138 }
13139 })
13140
13141 (define_insn "*tablejump_1"
13142 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13143 (use (label_ref (match_operand 1 "" "")))]
13144 "!TARGET_64BIT"
13145 "jmp\t%A0"
13146 [(set_attr "type" "ibr")
13147 (set_attr "length_immediate" "0")])
13148
13149 (define_insn "*tablejump_1_rtx64"
13150 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13151 (use (label_ref (match_operand 1 "" "")))]
13152 "TARGET_64BIT"
13153 "jmp\t%A0"
13154 [(set_attr "type" "ibr")
13155 (set_attr "length_immediate" "0")])
13156 \f
13157 ;; Loop instruction
13158 ;;
13159 ;; This is all complicated by the fact that since this is a jump insn
13160 ;; we must handle our own reloads.
13161
13162 (define_expand "doloop_end"
13163 [(use (match_operand 0 "" "")) ; loop pseudo
13164 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13165 (use (match_operand 2 "" "")) ; max iterations
13166 (use (match_operand 3 "" "")) ; loop level
13167 (use (match_operand 4 "" ""))] ; label
13168 "!TARGET_64BIT && TARGET_USE_LOOP"
13169 "
13170 {
13171 /* Only use cloop on innermost loops. */
13172 if (INTVAL (operands[3]) > 1)
13173 FAIL;
13174 if (GET_MODE (operands[0]) != SImode)
13175 FAIL;
13176 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13177 operands[0]));
13178 DONE;
13179 }")
13180
13181 (define_insn "doloop_end_internal"
13182 [(set (pc)
13183 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13184 (const_int 1))
13185 (label_ref (match_operand 0 "" ""))
13186 (pc)))
13187 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13188 (plus:SI (match_dup 1)
13189 (const_int -1)))
13190 (clobber (match_scratch:SI 3 "=X,X,r"))
13191 (clobber (reg:CC 17))]
13192 "!TARGET_64BIT && TARGET_USE_LOOP"
13193 {
13194 if (which_alternative != 0)
13195 return "#";
13196 if (get_attr_length (insn) == 2)
13197 return "%+loop\t%l0";
13198 else
13199 return "dec{l}\t%1\;%+jne\t%l0";
13200 }
13201 [(set_attr "ppro_uops" "many")
13202 (set (attr "type")
13203 (if_then_else (and (eq_attr "alternative" "0")
13204 (and (ge (minus (match_dup 0) (pc))
13205 (const_int -128))
13206 (lt (minus (match_dup 0) (pc))
13207 (const_int 124))))
13208 (const_string "ibr")
13209 (const_string "multi")))])
13210
13211 (define_split
13212 [(set (pc)
13213 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13214 (const_int 1))
13215 (match_operand 0 "" "")
13216 (pc)))
13217 (set (match_dup 1)
13218 (plus:SI (match_dup 1)
13219 (const_int -1)))
13220 (clobber (match_scratch:SI 2 ""))
13221 (clobber (reg:CC 17))]
13222 "!TARGET_64BIT && TARGET_USE_LOOP
13223 && reload_completed
13224 && REGNO (operands[1]) != 2"
13225 [(parallel [(set (reg:CCZ 17)
13226 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13227 (const_int 0)))
13228 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13229 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13230 (match_dup 0)
13231 (pc)))]
13232 "")
13233
13234 (define_split
13235 [(set (pc)
13236 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13237 (const_int 1))
13238 (match_operand 0 "" "")
13239 (pc)))
13240 (set (match_operand:SI 2 "nonimmediate_operand" "")
13241 (plus:SI (match_dup 1)
13242 (const_int -1)))
13243 (clobber (match_scratch:SI 3 ""))
13244 (clobber (reg:CC 17))]
13245 "!TARGET_64BIT && TARGET_USE_LOOP
13246 && reload_completed
13247 && (! REG_P (operands[2])
13248 || ! rtx_equal_p (operands[1], operands[2]))"
13249 [(set (match_dup 3) (match_dup 1))
13250 (parallel [(set (reg:CCZ 17)
13251 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13252 (const_int 0)))
13253 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13254 (set (match_dup 2) (match_dup 3))
13255 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13256 (match_dup 0)
13257 (pc)))]
13258 "")
13259
13260 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13261
13262 (define_peephole2
13263 [(set (reg 17) (match_operand 0 "" ""))
13264 (set (match_operand:QI 1 "register_operand" "")
13265 (match_operator:QI 2 "ix86_comparison_operator"
13266 [(reg 17) (const_int 0)]))
13267 (set (match_operand 3 "q_regs_operand" "")
13268 (zero_extend (match_dup 1)))]
13269 "(peep2_reg_dead_p (3, operands[1])
13270 || operands_match_p (operands[1], operands[3]))
13271 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13272 [(set (match_dup 4) (match_dup 0))
13273 (set (strict_low_part (match_dup 5))
13274 (match_dup 2))]
13275 {
13276 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13277 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13278 ix86_expand_clear (operands[3]);
13279 })
13280
13281 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13282
13283 (define_peephole2
13284 [(set (reg 17) (match_operand 0 "" ""))
13285 (set (match_operand:QI 1 "register_operand" "")
13286 (match_operator:QI 2 "ix86_comparison_operator"
13287 [(reg 17) (const_int 0)]))
13288 (parallel [(set (match_operand 3 "q_regs_operand" "")
13289 (zero_extend (match_dup 1)))
13290 (clobber (reg:CC 17))])]
13291 "(peep2_reg_dead_p (3, operands[1])
13292 || operands_match_p (operands[1], operands[3]))
13293 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13294 [(set (match_dup 4) (match_dup 0))
13295 (set (strict_low_part (match_dup 5))
13296 (match_dup 2))]
13297 {
13298 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13299 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
13300 ix86_expand_clear (operands[3]);
13301 })
13302 \f
13303 ;; Call instructions.
13304
13305 ;; The predicates normally associated with named expanders are not properly
13306 ;; checked for calls. This is a bug in the generic code, but it isn't that
13307 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13308
13309 ;; Call subroutine returning no value.
13310
13311 (define_expand "call_pop"
13312 [(parallel [(call (match_operand:QI 0 "" "")
13313 (match_operand:SI 1 "" ""))
13314 (set (reg:SI 7)
13315 (plus:SI (reg:SI 7)
13316 (match_operand:SI 3 "" "")))])]
13317 "!TARGET_64BIT"
13318 {
13319 if (operands[3] == const0_rtx)
13320 {
13321 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
13322 DONE;
13323 }
13324 /* Static functions and indirect calls don't need
13325 current_function_uses_pic_offset_table. */
13326 if (flag_pic
13327 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13328 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13329 current_function_uses_pic_offset_table = 1;
13330 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13331 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13332 if (TARGET_64BIT)
13333 abort();
13334 })
13335
13336 (define_insn "*call_pop_0"
13337 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13338 (match_operand:SI 1 "" ""))
13339 (set (reg:SI 7) (plus:SI (reg:SI 7)
13340 (match_operand:SI 2 "immediate_operand" "")))]
13341 "!TARGET_64BIT"
13342 {
13343 if (SIBLING_CALL_P (insn))
13344 return "jmp\t%P0";
13345 else
13346 return "call\t%P0";
13347 }
13348 [(set_attr "type" "call")])
13349
13350 (define_insn "*call_pop_1"
13351 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13352 (match_operand:SI 1 "" ""))
13353 (set (reg:SI 7) (plus:SI (reg:SI 7)
13354 (match_operand:SI 2 "immediate_operand" "i")))]
13355 "!TARGET_64BIT"
13356 {
13357 if (constant_call_address_operand (operands[0], Pmode))
13358 {
13359 if (SIBLING_CALL_P (insn))
13360 return "jmp\t%P0";
13361 else
13362 return "call\t%P0";
13363 }
13364 if (SIBLING_CALL_P (insn))
13365 return "jmp\t%A0";
13366 else
13367 return "call\t%A0";
13368 }
13369 [(set_attr "type" "call")])
13370
13371 (define_expand "call"
13372 [(call (match_operand:QI 0 "" "")
13373 (match_operand 1 "" ""))
13374 (use (match_operand 2 "" ""))]
13375 ;; Operand 1 not used on the i386.
13376 ""
13377 {
13378 rtx insn;
13379 /* Static functions and indirect calls don't need
13380 current_function_uses_pic_offset_table. */
13381 if (flag_pic
13382 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13383 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13384 current_function_uses_pic_offset_table = 1;
13385
13386 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13387 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13388 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13389 {
13390 rtx reg = gen_rtx_REG (QImode, 0);
13391 emit_move_insn (reg, operands[2]);
13392 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13393 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13394 DONE;
13395 }
13396 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13397 DONE;
13398 })
13399
13400 (define_expand "call_exp"
13401 [(call (match_operand:QI 0 "" "")
13402 (match_operand 1 "" ""))]
13403 ""
13404 "")
13405
13406 (define_insn "*call_0"
13407 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13408 (match_operand 1 "" ""))]
13409 ""
13410 {
13411 if (SIBLING_CALL_P (insn))
13412 return "jmp\t%P0";
13413 else
13414 return "call\t%P0";
13415 }
13416 [(set_attr "type" "call")])
13417
13418 (define_insn "*call_1"
13419 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13420 (match_operand 1 "" ""))]
13421 "!TARGET_64BIT"
13422 {
13423 if (constant_call_address_operand (operands[0], QImode))
13424 {
13425 if (SIBLING_CALL_P (insn))
13426 return "jmp\t%P0";
13427 else
13428 return "call\t%P0";
13429 }
13430 if (SIBLING_CALL_P (insn))
13431 return "jmp\t%A0";
13432 else
13433 return "call\t%A0";
13434 }
13435 [(set_attr "type" "call")])
13436
13437 (define_insn "*call_1_rex64"
13438 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13439 (match_operand 1 "" ""))]
13440 "TARGET_64BIT"
13441 {
13442 if (constant_call_address_operand (operands[0], QImode))
13443 {
13444 if (SIBLING_CALL_P (insn))
13445 return "jmp\t%P0";
13446 else
13447 return "call\t%P0";
13448 }
13449 if (SIBLING_CALL_P (insn))
13450 return "jmp\t%A0";
13451 else
13452 return "call\t%A0";
13453 }
13454 [(set_attr "type" "call")])
13455
13456 ;; Call subroutine, returning value in operand 0
13457 ;; (which must be a hard register).
13458
13459 (define_expand "call_value_pop"
13460 [(parallel [(set (match_operand 0 "" "")
13461 (call (match_operand:QI 1 "" "")
13462 (match_operand:SI 2 "" "")))
13463 (set (reg:SI 7)
13464 (plus:SI (reg:SI 7)
13465 (match_operand:SI 4 "" "")))])]
13466 "!TARGET_64BIT"
13467 {
13468 if (operands[4] == const0_rtx)
13469 {
13470 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13471 constm1_rtx));
13472 DONE;
13473 }
13474 /* Static functions and indirect calls don't need
13475 current_function_uses_pic_offset_table. */
13476 if (flag_pic
13477 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13478 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13479 current_function_uses_pic_offset_table = 1;
13480 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13481 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13482 })
13483
13484 (define_expand "call_value"
13485 [(set (match_operand 0 "" "")
13486 (call (match_operand:QI 1 "" "")
13487 (match_operand:SI 2 "" "")))
13488 (use (match_operand:SI 3 "" ""))]
13489 ;; Operand 2 not used on the i386.
13490 ""
13491 {
13492 rtx insn;
13493 /* Static functions and indirect calls don't need
13494 current_function_uses_pic_offset_table. */
13495 if (flag_pic
13496 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13497 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13498 current_function_uses_pic_offset_table = 1;
13499 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13500 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13501 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13502 {
13503 rtx reg = gen_rtx_REG (QImode, 0);
13504 emit_move_insn (reg, operands[3]);
13505 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13506 operands[2]));
13507 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13508 DONE;
13509 }
13510 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13511 operands[2]));
13512 DONE;
13513 })
13514
13515 (define_expand "call_value_exp"
13516 [(set (match_operand 0 "" "")
13517 (call (match_operand:QI 1 "" "")
13518 (match_operand:SI 2 "" "")))]
13519 ""
13520 "")
13521
13522 ;; Call subroutine returning any type.
13523
13524 (define_expand "untyped_call"
13525 [(parallel [(call (match_operand 0 "" "")
13526 (const_int 0))
13527 (match_operand 1 "" "")
13528 (match_operand 2 "" "")])]
13529 ""
13530 {
13531 int i;
13532
13533 /* In order to give reg-stack an easier job in validating two
13534 coprocessor registers as containing a possible return value,
13535 simply pretend the untyped call returns a complex long double
13536 value. */
13537
13538 emit_call_insn (TARGET_80387
13539 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13540 operands[0], const0_rtx,
13541 GEN_INT (SSE_REGPARM_MAX - 1))
13542 : gen_call (operands[0], const0_rtx,
13543 GEN_INT (SSE_REGPARM_MAX - 1)));
13544
13545 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13546 {
13547 rtx set = XVECEXP (operands[2], 0, i);
13548 emit_move_insn (SET_DEST (set), SET_SRC (set));
13549 }
13550
13551 /* The optimizer does not know that the call sets the function value
13552 registers we stored in the result block. We avoid problems by
13553 claiming that all hard registers are used and clobbered at this
13554 point. */
13555 emit_insn (gen_blockage ());
13556
13557 DONE;
13558 })
13559 \f
13560 ;; Prologue and epilogue instructions
13561
13562 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13563 ;; all of memory. This blocks insns from being moved across this point.
13564
13565 (define_insn "blockage"
13566 [(unspec_volatile [(const_int 0)] 0)]
13567 ""
13568 ""
13569 [(set_attr "length" "0")])
13570
13571 ;; Insn emitted into the body of a function to return from a function.
13572 ;; This is only done if the function's epilogue is known to be simple.
13573 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13574
13575 (define_expand "return"
13576 [(return)]
13577 "ix86_can_use_return_insn_p ()"
13578 {
13579 if (current_function_pops_args)
13580 {
13581 rtx popc = GEN_INT (current_function_pops_args);
13582 emit_jump_insn (gen_return_pop_internal (popc));
13583 DONE;
13584 }
13585 })
13586
13587 (define_insn "return_internal"
13588 [(return)]
13589 "reload_completed"
13590 "ret"
13591 [(set_attr "length" "1")
13592 (set_attr "length_immediate" "0")
13593 (set_attr "modrm" "0")])
13594
13595 (define_insn "return_pop_internal"
13596 [(return)
13597 (use (match_operand:SI 0 "const_int_operand" ""))]
13598 "reload_completed"
13599 "ret\t%0"
13600 [(set_attr "length" "3")
13601 (set_attr "length_immediate" "2")
13602 (set_attr "modrm" "0")])
13603
13604 (define_insn "return_indirect_internal"
13605 [(return)
13606 (use (match_operand:SI 0 "register_operand" "r"))]
13607 "reload_completed"
13608 "jmp\t%A0"
13609 [(set_attr "type" "ibr")
13610 (set_attr "length_immediate" "0")])
13611
13612 (define_insn "nop"
13613 [(const_int 0)]
13614 ""
13615 "nop"
13616 [(set_attr "length" "1")
13617 (set_attr "length_immediate" "0")
13618 (set_attr "modrm" "0")
13619 (set_attr "ppro_uops" "one")])
13620
13621 (define_expand "prologue"
13622 [(const_int 1)]
13623 ""
13624 "ix86_expand_prologue (); DONE;")
13625
13626 (define_insn "prologue_set_got"
13627 [(set (match_operand:SI 0 "register_operand" "=r")
13628 (unspec_volatile:SI
13629 [(plus:SI (match_dup 0)
13630 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13631 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13632 (clobber (reg:CC 17))]
13633 "!TARGET_64BIT"
13634 {
13635 if (GET_CODE (operands[2]) == LABEL_REF)
13636 operands[2] = XEXP (operands[2], 0);
13637 if (TARGET_DEEP_BRANCH_PREDICTION)
13638 return "add{l}\t{%1, %0|%0, %1}";
13639 else
13640 return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13641 }
13642 [(set_attr "type" "alu")
13643 ; Since this insn may have two constant operands, we must set the
13644 ; length manually.
13645 (set_attr "length_immediate" "4")
13646 (set_attr "mode" "SI")])
13647
13648 (define_insn "prologue_get_pc"
13649 [(set (match_operand:SI 0 "register_operand" "=r")
13650 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13651 "!TARGET_64BIT"
13652 {
13653 if (GET_CODE (operands[1]) == LABEL_REF)
13654 operands[1] = XEXP (operands[1], 0);
13655 output_asm_insn ("call\t%X1", operands);
13656 if (! TARGET_DEEP_BRANCH_PREDICTION)
13657 {
13658 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
13659 CODE_LABEL_NUMBER (operands[1]));
13660 }
13661 RET;
13662 }
13663 [(set_attr "type" "multi")])
13664
13665 (define_expand "epilogue"
13666 [(const_int 1)]
13667 ""
13668 "ix86_expand_epilogue (1); DONE;")
13669
13670 (define_expand "sibcall_epilogue"
13671 [(const_int 1)]
13672 ""
13673 "ix86_expand_epilogue (0); DONE;")
13674
13675 (define_expand "eh_return"
13676 [(use (match_operand 0 "register_operand" ""))
13677 (use (match_operand 1 "register_operand" ""))]
13678 ""
13679 {
13680 rtx tmp, sa = operands[0], ra = operands[1];
13681
13682 /* Tricky bit: we write the address of the handler to which we will
13683 be returning into someone else's stack frame, one word below the
13684 stack address we wish to restore. */
13685 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13686 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13687 tmp = gen_rtx_MEM (Pmode, tmp);
13688 emit_move_insn (tmp, ra);
13689
13690 if (Pmode == SImode)
13691 emit_insn (gen_eh_return_si (sa));
13692 else
13693 emit_insn (gen_eh_return_di (sa));
13694 emit_barrier ();
13695 DONE;
13696 })
13697
13698 (define_insn_and_split "eh_return_si"
13699 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
13700 "!TARGET_64BIT"
13701 "#"
13702 "reload_completed"
13703 [(const_int 1)]
13704 "ix86_expand_epilogue (2); DONE;")
13705
13706 (define_insn_and_split "eh_return_di"
13707 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
13708 "TARGET_64BIT"
13709 "#"
13710 "reload_completed"
13711 [(const_int 1)]
13712 "ix86_expand_epilogue (2); DONE;")
13713
13714 (define_insn "leave"
13715 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13716 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13717 (clobber (mem:BLK (scratch)))]
13718 "!TARGET_64BIT"
13719 "leave"
13720 [(set_attr "length_immediate" "0")
13721 (set_attr "length" "1")
13722 (set_attr "modrm" "0")
13723 (set_attr "modrm" "0")
13724 (set_attr "athlon_decode" "vector")
13725 (set_attr "ppro_uops" "few")])
13726
13727 (define_insn "leave_rex64"
13728 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13729 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13730 (clobber (mem:BLK (scratch)))]
13731 "TARGET_64BIT"
13732 "leave"
13733 [(set_attr "length_immediate" "0")
13734 (set_attr "length" "1")
13735 (set_attr "modrm" "0")
13736 (set_attr "modrm" "0")
13737 (set_attr "athlon_decode" "vector")
13738 (set_attr "ppro_uops" "few")])
13739 \f
13740 (define_expand "ffssi2"
13741 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13742 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13743 ""
13744 {
13745 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13746 rtx in = operands[1];
13747
13748 if (TARGET_CMOVE)
13749 {
13750 emit_move_insn (tmp, constm1_rtx);
13751 emit_insn (gen_ffssi_1 (out, in));
13752 emit_insn (gen_rtx_SET (VOIDmode, out,
13753 gen_rtx_IF_THEN_ELSE (SImode,
13754 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13755 const0_rtx),
13756 tmp,
13757 out)));
13758 emit_insn (gen_addsi3 (out, out, const1_rtx));
13759 emit_move_insn (operands[0], out);
13760 }
13761
13762 /* Pentium bsf instruction is extremly slow. The following code is
13763 recommended by the Intel Optimizing Manual as a reasonable replacement:
13764 TEST EAX,EAX
13765 JZ SHORT BS2
13766 XOR ECX,ECX
13767 MOV DWORD PTR [TEMP+4],ECX
13768 SUB ECX,EAX
13769 AND EAX,ECX
13770 MOV DWORD PTR [TEMP],EAX
13771 FILD QWORD PTR [TEMP]
13772 FSTP QWORD PTR [TEMP]
13773 WAIT ; WAIT only needed for compatibility with
13774 ; earlier processors
13775 MOV ECX, DWORD PTR [TEMP+4]
13776 SHR ECX,20
13777 SUB ECX,3FFH
13778 TEST EAX,EAX ; clear zero flag
13779 BS2:
13780 Following piece of code expand ffs to similar beast.
13781 */
13782
13783 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13784 {
13785 rtx label = gen_label_rtx ();
13786 rtx lo, hi;
13787 rtx mem = assign_386_stack_local (DImode, 0);
13788 rtx fptmp = gen_reg_rtx (DFmode);
13789 split_di (&mem, 1, &lo, &hi);
13790
13791 emit_move_insn (out, const0_rtx);
13792
13793 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
13794
13795 emit_move_insn (hi, out);
13796 emit_insn (gen_subsi3 (out, out, in));
13797 emit_insn (gen_andsi3 (out, out, in));
13798 emit_move_insn (lo, out);
13799 emit_insn (gen_floatdidf2 (fptmp,mem));
13800 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13801 emit_move_insn (out, hi);
13802 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13803 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13804
13805 emit_label (label);
13806 LABEL_NUSES (label) = 1;
13807
13808 emit_move_insn (operands[0], out);
13809 }
13810 else
13811 {
13812 emit_move_insn (tmp, const0_rtx);
13813 emit_insn (gen_ffssi_1 (out, in));
13814 emit_insn (gen_rtx_SET (VOIDmode,
13815 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13816 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13817 const0_rtx)));
13818 emit_insn (gen_negsi2 (tmp, tmp));
13819 emit_insn (gen_iorsi3 (out, out, tmp));
13820 emit_insn (gen_addsi3 (out, out, const1_rtx));
13821 emit_move_insn (operands[0], out);
13822 }
13823 DONE;
13824 })
13825
13826 (define_insn "ffssi_1"
13827 [(set (reg:CCZ 17)
13828 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13829 (const_int 0)))
13830 (set (match_operand:SI 0 "register_operand" "=r")
13831 (unspec:SI [(match_dup 1)] 5))]
13832 ""
13833 "bsf{l}\t{%1, %0|%0, %1}"
13834 [(set_attr "prefix_0f" "1")
13835 (set_attr "ppro_uops" "few")])
13836
13837 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13838 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
13839 \f
13840 ;; These patterns match the binary 387 instructions for addM3, subM3,
13841 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13842 ;; SFmode. The first is the normal insn, the second the same insn but
13843 ;; with one operand a conversion, and the third the same insn but with
13844 ;; the other operand a conversion. The conversion may be SFmode or
13845 ;; SImode if the target mode DFmode, but only SImode if the target mode
13846 ;; is SFmode.
13847
13848 ;; Gcc is slightly more smart about handling normal two address instructions
13849 ;; so use special patterns for add and mull.
13850 (define_insn "*fop_sf_comm_nosse"
13851 [(set (match_operand:SF 0 "register_operand" "=f")
13852 (match_operator:SF 3 "binary_fp_operator"
13853 [(match_operand:SF 1 "register_operand" "%0")
13854 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13855 "TARGET_80387 && !TARGET_SSE_MATH
13856 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13857 "* return output_387_binary_op (insn, operands);"
13858 [(set (attr "type")
13859 (if_then_else (match_operand:SF 3 "mult_operator" "")
13860 (const_string "fmul")
13861 (const_string "fop")))
13862 (set_attr "mode" "SF")])
13863
13864 (define_insn "*fop_sf_comm"
13865 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13866 (match_operator:SF 3 "binary_fp_operator"
13867 [(match_operand:SF 1 "register_operand" "%0,0")
13868 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13869 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13870 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13871 "* return output_387_binary_op (insn, operands);"
13872 [(set (attr "type")
13873 (if_then_else (eq_attr "alternative" "1")
13874 (const_string "sse")
13875 (if_then_else (match_operand:SF 3 "mult_operator" "")
13876 (const_string "fmul")
13877 (const_string "fop"))))
13878 (set_attr "mode" "SF")])
13879
13880 (define_insn "*fop_sf_comm_sse"
13881 [(set (match_operand:SF 0 "register_operand" "=x")
13882 (match_operator:SF 3 "binary_fp_operator"
13883 [(match_operand:SF 1 "register_operand" "%0")
13884 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13885 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13886 "* return output_387_binary_op (insn, operands);"
13887 [(set_attr "type" "sse")
13888 (set_attr "mode" "SF")])
13889
13890 (define_insn "*fop_df_comm_nosse"
13891 [(set (match_operand:DF 0 "register_operand" "=f")
13892 (match_operator:DF 3 "binary_fp_operator"
13893 [(match_operand:DF 1 "register_operand" "%0")
13894 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
13895 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
13896 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13897 "* return output_387_binary_op (insn, operands);"
13898 [(set (attr "type")
13899 (if_then_else (match_operand:SF 3 "mult_operator" "")
13900 (const_string "fmul")
13901 (const_string "fop")))
13902 (set_attr "mode" "DF")])
13903
13904 (define_insn "*fop_df_comm"
13905 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13906 (match_operator:DF 3 "binary_fp_operator"
13907 [(match_operand:DF 1 "register_operand" "%0,0")
13908 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13909 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
13910 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13911 "* return output_387_binary_op (insn, operands);"
13912 [(set (attr "type")
13913 (if_then_else (eq_attr "alternative" "1")
13914 (const_string "sse")
13915 (if_then_else (match_operand:SF 3 "mult_operator" "")
13916 (const_string "fmul")
13917 (const_string "fop"))))
13918 (set_attr "mode" "DF")])
13919
13920 (define_insn "*fop_df_comm_sse"
13921 [(set (match_operand:DF 0 "register_operand" "=Y")
13922 (match_operator:DF 3 "binary_fp_operator"
13923 [(match_operand:DF 1 "register_operand" "%0")
13924 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13925 "TARGET_SSE2 && TARGET_SSE_MATH
13926 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13927 "* return output_387_binary_op (insn, operands);"
13928 [(set_attr "type" "sse")
13929 (set_attr "mode" "DF")])
13930
13931 (define_insn "*fop_xf_comm"
13932 [(set (match_operand:XF 0 "register_operand" "=f")
13933 (match_operator:XF 3 "binary_fp_operator"
13934 [(match_operand:XF 1 "register_operand" "%0")
13935 (match_operand:XF 2 "register_operand" "f")]))]
13936 "!TARGET_64BIT && TARGET_80387
13937 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13938 "* return output_387_binary_op (insn, operands);"
13939 [(set (attr "type")
13940 (if_then_else (match_operand:XF 3 "mult_operator" "")
13941 (const_string "fmul")
13942 (const_string "fop")))
13943 (set_attr "mode" "XF")])
13944
13945 (define_insn "*fop_tf_comm"
13946 [(set (match_operand:TF 0 "register_operand" "=f")
13947 (match_operator:TF 3 "binary_fp_operator"
13948 [(match_operand:TF 1 "register_operand" "%0")
13949 (match_operand:TF 2 "register_operand" "f")]))]
13950 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13951 "* return output_387_binary_op (insn, operands);"
13952 [(set (attr "type")
13953 (if_then_else (match_operand:TF 3 "mult_operator" "")
13954 (const_string "fmul")
13955 (const_string "fop")))
13956 (set_attr "mode" "XF")])
13957
13958 (define_insn "*fop_sf_1_nosse"
13959 [(set (match_operand:SF 0 "register_operand" "=f,f")
13960 (match_operator:SF 3 "binary_fp_operator"
13961 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
13962 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
13963 "TARGET_80387 && !TARGET_SSE_MATH
13964 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13965 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13966 "* return output_387_binary_op (insn, operands);"
13967 [(set (attr "type")
13968 (cond [(match_operand:SF 3 "mult_operator" "")
13969 (const_string "fmul")
13970 (match_operand:SF 3 "div_operator" "")
13971 (const_string "fdiv")
13972 ]
13973 (const_string "fop")))
13974 (set_attr "mode" "SF")])
13975
13976 (define_insn "*fop_sf_1"
13977 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13978 (match_operator:SF 3 "binary_fp_operator"
13979 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13980 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13981 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
13982 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13983 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13984 "* return output_387_binary_op (insn, operands);"
13985 [(set (attr "type")
13986 (cond [(eq_attr "alternative" "2")
13987 (const_string "sse")
13988 (match_operand:SF 3 "mult_operator" "")
13989 (const_string "fmul")
13990 (match_operand:SF 3 "div_operator" "")
13991 (const_string "fdiv")
13992 ]
13993 (const_string "fop")))
13994 (set_attr "mode" "SF")])
13995
13996 (define_insn "*fop_sf_1_sse"
13997 [(set (match_operand:SF 0 "register_operand" "=x")
13998 (match_operator:SF 3 "binary_fp_operator"
13999 [(match_operand:SF 1 "register_operand" "0")
14000 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14001 "TARGET_SSE_MATH
14002 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14003 "* return output_387_binary_op (insn, operands);"
14004 [(set_attr "type" "sse")
14005 (set_attr "mode" "SF")])
14006
14007 ;; ??? Add SSE splitters for these!
14008 (define_insn "*fop_sf_2"
14009 [(set (match_operand:SF 0 "register_operand" "=f,f")
14010 (match_operator:SF 3 "binary_fp_operator"
14011 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14012 (match_operand:SF 2 "register_operand" "0,0")]))]
14013 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14014 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14015 [(set (attr "type")
14016 (cond [(match_operand:SF 3 "mult_operator" "")
14017 (const_string "fmul")
14018 (match_operand:SF 3 "div_operator" "")
14019 (const_string "fdiv")
14020 ]
14021 (const_string "fop")))
14022 (set_attr "fp_int_src" "true")
14023 (set_attr "ppro_uops" "many")
14024 (set_attr "mode" "SI")])
14025
14026 (define_insn "*fop_sf_3"
14027 [(set (match_operand:SF 0 "register_operand" "=f,f")
14028 (match_operator:SF 3 "binary_fp_operator"
14029 [(match_operand:SF 1 "register_operand" "0,0")
14030 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14031 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14032 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14033 [(set (attr "type")
14034 (cond [(match_operand:SF 3 "mult_operator" "")
14035 (const_string "fmul")
14036 (match_operand:SF 3 "div_operator" "")
14037 (const_string "fdiv")
14038 ]
14039 (const_string "fop")))
14040 (set_attr "fp_int_src" "true")
14041 (set_attr "ppro_uops" "many")
14042 (set_attr "mode" "SI")])
14043
14044 (define_insn "*fop_df_1_nosse"
14045 [(set (match_operand:DF 0 "register_operand" "=f,f")
14046 (match_operator:DF 3 "binary_fp_operator"
14047 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14048 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14049 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14050 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14051 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14052 "* return output_387_binary_op (insn, operands);"
14053 [(set (attr "type")
14054 (cond [(match_operand:DF 3 "mult_operator" "")
14055 (const_string "fmul")
14056 (match_operand:DF 3 "div_operator" "")
14057 (const_string "fdiv")
14058 ]
14059 (const_string "fop")))
14060 (set_attr "mode" "DF")])
14061
14062
14063 (define_insn "*fop_df_1"
14064 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14065 (match_operator:DF 3 "binary_fp_operator"
14066 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14067 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14068 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14069 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14071 "* return output_387_binary_op (insn, operands);"
14072 [(set (attr "type")
14073 (cond [(eq_attr "alternative" "2")
14074 (const_string "sse")
14075 (match_operand:DF 3 "mult_operator" "")
14076 (const_string "fmul")
14077 (match_operand:DF 3 "div_operator" "")
14078 (const_string "fdiv")
14079 ]
14080 (const_string "fop")))
14081 (set_attr "mode" "DF")])
14082
14083 (define_insn "*fop_df_1_sse"
14084 [(set (match_operand:DF 0 "register_operand" "=Y")
14085 (match_operator:DF 3 "binary_fp_operator"
14086 [(match_operand:DF 1 "register_operand" "0")
14087 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14088 "TARGET_SSE2 && TARGET_SSE_MATH
14089 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14090 "* return output_387_binary_op (insn, operands);"
14091 [(set_attr "type" "sse")])
14092
14093 ;; ??? Add SSE splitters for these!
14094 (define_insn "*fop_df_2"
14095 [(set (match_operand:DF 0 "register_operand" "=f,f")
14096 (match_operator:DF 3 "binary_fp_operator"
14097 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14098 (match_operand:DF 2 "register_operand" "0,0")]))]
14099 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14100 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14101 [(set (attr "type")
14102 (cond [(match_operand:DF 3 "mult_operator" "")
14103 (const_string "fmul")
14104 (match_operand:DF 3 "div_operator" "")
14105 (const_string "fdiv")
14106 ]
14107 (const_string "fop")))
14108 (set_attr "fp_int_src" "true")
14109 (set_attr "ppro_uops" "many")
14110 (set_attr "mode" "SI")])
14111
14112 (define_insn "*fop_df_3"
14113 [(set (match_operand:DF 0 "register_operand" "=f,f")
14114 (match_operator:DF 3 "binary_fp_operator"
14115 [(match_operand:DF 1 "register_operand" "0,0")
14116 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14117 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14118 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14119 [(set (attr "type")
14120 (cond [(match_operand:DF 3 "mult_operator" "")
14121 (const_string "fmul")
14122 (match_operand:DF 3 "div_operator" "")
14123 (const_string "fdiv")
14124 ]
14125 (const_string "fop")))
14126 (set_attr "fp_int_src" "true")
14127 (set_attr "ppro_uops" "many")
14128 (set_attr "mode" "SI")])
14129
14130 (define_insn "*fop_df_4"
14131 [(set (match_operand:DF 0 "register_operand" "=f,f")
14132 (match_operator:DF 3 "binary_fp_operator"
14133 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14134 (match_operand:DF 2 "register_operand" "0,f")]))]
14135 "TARGET_80387
14136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14137 "* return output_387_binary_op (insn, operands);"
14138 [(set (attr "type")
14139 (cond [(match_operand:DF 3 "mult_operator" "")
14140 (const_string "fmul")
14141 (match_operand:DF 3 "div_operator" "")
14142 (const_string "fdiv")
14143 ]
14144 (const_string "fop")))
14145 (set_attr "mode" "SF")])
14146
14147 (define_insn "*fop_df_5"
14148 [(set (match_operand:DF 0 "register_operand" "=f,f")
14149 (match_operator:DF 3 "binary_fp_operator"
14150 [(match_operand:DF 1 "register_operand" "0,f")
14151 (float_extend:DF
14152 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14153 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14154 "* return output_387_binary_op (insn, operands);"
14155 [(set (attr "type")
14156 (cond [(match_operand:DF 3 "mult_operator" "")
14157 (const_string "fmul")
14158 (match_operand:DF 3 "div_operator" "")
14159 (const_string "fdiv")
14160 ]
14161 (const_string "fop")))
14162 (set_attr "mode" "SF")])
14163
14164 (define_insn "*fop_xf_1"
14165 [(set (match_operand:XF 0 "register_operand" "=f,f")
14166 (match_operator:XF 3 "binary_fp_operator"
14167 [(match_operand:XF 1 "register_operand" "0,f")
14168 (match_operand:XF 2 "register_operand" "f,0")]))]
14169 "!TARGET_64BIT && TARGET_80387
14170 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14171 "* return output_387_binary_op (insn, operands);"
14172 [(set (attr "type")
14173 (cond [(match_operand:XF 3 "mult_operator" "")
14174 (const_string "fmul")
14175 (match_operand:XF 3 "div_operator" "")
14176 (const_string "fdiv")
14177 ]
14178 (const_string "fop")))
14179 (set_attr "mode" "XF")])
14180
14181 (define_insn "*fop_tf_1"
14182 [(set (match_operand:TF 0 "register_operand" "=f,f")
14183 (match_operator:TF 3 "binary_fp_operator"
14184 [(match_operand:TF 1 "register_operand" "0,f")
14185 (match_operand:TF 2 "register_operand" "f,0")]))]
14186 "TARGET_80387
14187 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14188 "* return output_387_binary_op (insn, operands);"
14189 [(set (attr "type")
14190 (cond [(match_operand:TF 3 "mult_operator" "")
14191 (const_string "fmul")
14192 (match_operand:TF 3 "div_operator" "")
14193 (const_string "fdiv")
14194 ]
14195 (const_string "fop")))
14196 (set_attr "mode" "XF")])
14197
14198 (define_insn "*fop_xf_2"
14199 [(set (match_operand:XF 0 "register_operand" "=f,f")
14200 (match_operator:XF 3 "binary_fp_operator"
14201 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14202 (match_operand:XF 2 "register_operand" "0,0")]))]
14203 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14204 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14205 [(set (attr "type")
14206 (cond [(match_operand:XF 3 "mult_operator" "")
14207 (const_string "fmul")
14208 (match_operand:XF 3 "div_operator" "")
14209 (const_string "fdiv")
14210 ]
14211 (const_string "fop")))
14212 (set_attr "fp_int_src" "true")
14213 (set_attr "mode" "SI")
14214 (set_attr "ppro_uops" "many")])
14215
14216 (define_insn "*fop_tf_2"
14217 [(set (match_operand:TF 0 "register_operand" "=f,f")
14218 (match_operator:TF 3 "binary_fp_operator"
14219 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14220 (match_operand:TF 2 "register_operand" "0,0")]))]
14221 "TARGET_80387 && TARGET_USE_FIOP"
14222 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14223 [(set (attr "type")
14224 (cond [(match_operand:TF 3 "mult_operator" "")
14225 (const_string "fmul")
14226 (match_operand:TF 3 "div_operator" "")
14227 (const_string "fdiv")
14228 ]
14229 (const_string "fop")))
14230 (set_attr "fp_int_src" "true")
14231 (set_attr "mode" "SI")
14232 (set_attr "ppro_uops" "many")])
14233
14234 (define_insn "*fop_xf_3"
14235 [(set (match_operand:XF 0 "register_operand" "=f,f")
14236 (match_operator:XF 3 "binary_fp_operator"
14237 [(match_operand:XF 1 "register_operand" "0,0")
14238 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14239 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14240 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14241 [(set (attr "type")
14242 (cond [(match_operand:XF 3 "mult_operator" "")
14243 (const_string "fmul")
14244 (match_operand:XF 3 "div_operator" "")
14245 (const_string "fdiv")
14246 ]
14247 (const_string "fop")))
14248 (set_attr "fp_int_src" "true")
14249 (set_attr "mode" "SI")
14250 (set_attr "ppro_uops" "many")])
14251
14252 (define_insn "*fop_tf_3"
14253 [(set (match_operand:TF 0 "register_operand" "=f,f")
14254 (match_operator:TF 3 "binary_fp_operator"
14255 [(match_operand:TF 1 "register_operand" "0,0")
14256 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14257 "TARGET_80387 && TARGET_USE_FIOP"
14258 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14259 [(set (attr "type")
14260 (cond [(match_operand:TF 3 "mult_operator" "")
14261 (const_string "fmul")
14262 (match_operand:TF 3 "div_operator" "")
14263 (const_string "fdiv")
14264 ]
14265 (const_string "fop")))
14266 (set_attr "fp_int_src" "true")
14267 (set_attr "mode" "SI")
14268 (set_attr "ppro_uops" "many")])
14269
14270 (define_insn "*fop_xf_4"
14271 [(set (match_operand:XF 0 "register_operand" "=f,f")
14272 (match_operator:XF 3 "binary_fp_operator"
14273 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14274 (match_operand:XF 2 "register_operand" "0,f")]))]
14275 "!TARGET_64BIT && TARGET_80387"
14276 "* return output_387_binary_op (insn, operands);"
14277 [(set (attr "type")
14278 (cond [(match_operand:XF 3 "mult_operator" "")
14279 (const_string "fmul")
14280 (match_operand:XF 3 "div_operator" "")
14281 (const_string "fdiv")
14282 ]
14283 (const_string "fop")))
14284 (set_attr "mode" "SF")])
14285
14286 (define_insn "*fop_tf_4"
14287 [(set (match_operand:TF 0 "register_operand" "=f,f")
14288 (match_operator:TF 3 "binary_fp_operator"
14289 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14290 (match_operand:TF 2 "register_operand" "0,f")]))]
14291 "TARGET_80387"
14292 "* return output_387_binary_op (insn, operands);"
14293 [(set (attr "type")
14294 (cond [(match_operand:TF 3 "mult_operator" "")
14295 (const_string "fmul")
14296 (match_operand:TF 3 "div_operator" "")
14297 (const_string "fdiv")
14298 ]
14299 (const_string "fop")))
14300 (set_attr "mode" "SF")])
14301
14302 (define_insn "*fop_xf_5"
14303 [(set (match_operand:XF 0 "register_operand" "=f,f")
14304 (match_operator:XF 3 "binary_fp_operator"
14305 [(match_operand:XF 1 "register_operand" "0,f")
14306 (float_extend:XF
14307 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14308 "!TARGET_64BIT && TARGET_80387"
14309 "* return output_387_binary_op (insn, operands);"
14310 [(set (attr "type")
14311 (cond [(match_operand:XF 3 "mult_operator" "")
14312 (const_string "fmul")
14313 (match_operand:XF 3 "div_operator" "")
14314 (const_string "fdiv")
14315 ]
14316 (const_string "fop")))
14317 (set_attr "mode" "SF")])
14318
14319 (define_insn "*fop_tf_5"
14320 [(set (match_operand:TF 0 "register_operand" "=f,f")
14321 (match_operator:TF 3 "binary_fp_operator"
14322 [(match_operand:TF 1 "register_operand" "0,f")
14323 (float_extend:TF
14324 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14325 "TARGET_80387"
14326 "* return output_387_binary_op (insn, operands);"
14327 [(set (attr "type")
14328 (cond [(match_operand:TF 3 "mult_operator" "")
14329 (const_string "fmul")
14330 (match_operand:TF 3 "div_operator" "")
14331 (const_string "fdiv")
14332 ]
14333 (const_string "fop")))
14334 (set_attr "mode" "SF")])
14335
14336 (define_insn "*fop_xf_6"
14337 [(set (match_operand:XF 0 "register_operand" "=f,f")
14338 (match_operator:XF 3 "binary_fp_operator"
14339 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14340 (match_operand:XF 2 "register_operand" "0,f")]))]
14341 "!TARGET_64BIT && TARGET_80387"
14342 "* return output_387_binary_op (insn, operands);"
14343 [(set (attr "type")
14344 (cond [(match_operand:XF 3 "mult_operator" "")
14345 (const_string "fmul")
14346 (match_operand:XF 3 "div_operator" "")
14347 (const_string "fdiv")
14348 ]
14349 (const_string "fop")))
14350 (set_attr "mode" "DF")])
14351
14352 (define_insn "*fop_tf_6"
14353 [(set (match_operand:TF 0 "register_operand" "=f,f")
14354 (match_operator:TF 3 "binary_fp_operator"
14355 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14356 (match_operand:TF 2 "register_operand" "0,f")]))]
14357 "TARGET_80387"
14358 "* return output_387_binary_op (insn, operands);"
14359 [(set (attr "type")
14360 (cond [(match_operand:TF 3 "mult_operator" "")
14361 (const_string "fmul")
14362 (match_operand:TF 3 "div_operator" "")
14363 (const_string "fdiv")
14364 ]
14365 (const_string "fop")))
14366 (set_attr "mode" "DF")])
14367
14368 (define_insn "*fop_xf_7"
14369 [(set (match_operand:XF 0 "register_operand" "=f,f")
14370 (match_operator:XF 3 "binary_fp_operator"
14371 [(match_operand:XF 1 "register_operand" "0,f")
14372 (float_extend:XF
14373 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14374 "!TARGET_64BIT && TARGET_80387"
14375 "* return output_387_binary_op (insn, operands);"
14376 [(set (attr "type")
14377 (cond [(match_operand:XF 3 "mult_operator" "")
14378 (const_string "fmul")
14379 (match_operand:XF 3 "div_operator" "")
14380 (const_string "fdiv")
14381 ]
14382 (const_string "fop")))
14383 (set_attr "mode" "DF")])
14384
14385 (define_insn "*fop_tf_7"
14386 [(set (match_operand:TF 0 "register_operand" "=f,f")
14387 (match_operator:TF 3 "binary_fp_operator"
14388 [(match_operand:TF 1 "register_operand" "0,f")
14389 (float_extend:TF
14390 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14391 "TARGET_80387"
14392 "* return output_387_binary_op (insn, operands);"
14393 [(set (attr "type")
14394 (cond [(match_operand:TF 3 "mult_operator" "")
14395 (const_string "fmul")
14396 (match_operand:TF 3 "div_operator" "")
14397 (const_string "fdiv")
14398 ]
14399 (const_string "fop")))
14400 (set_attr "mode" "DF")])
14401
14402 (define_split
14403 [(set (match_operand 0 "register_operand" "")
14404 (match_operator 3 "binary_fp_operator"
14405 [(float (match_operand:SI 1 "register_operand" ""))
14406 (match_operand 2 "register_operand" "")]))]
14407 "TARGET_80387 && reload_completed
14408 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14409 [(const_int 0)]
14410 {
14411 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14412 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14413 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14414 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14415 GET_MODE (operands[3]),
14416 operands[4],
14417 operands[2])));
14418 ix86_free_from_memory (GET_MODE (operands[1]));
14419 DONE;
14420 })
14421
14422 (define_split
14423 [(set (match_operand 0 "register_operand" "")
14424 (match_operator 3 "binary_fp_operator"
14425 [(match_operand 1 "register_operand" "")
14426 (float (match_operand:SI 2 "register_operand" ""))]))]
14427 "TARGET_80387 && reload_completed
14428 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14429 [(const_int 0)]
14430 {
14431 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14432 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14433 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14434 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14435 GET_MODE (operands[3]),
14436 operands[1],
14437 operands[4])));
14438 ix86_free_from_memory (GET_MODE (operands[2]));
14439 DONE;
14440 })
14441 \f
14442 ;; FPU special functions.
14443
14444 (define_expand "sqrtsf2"
14445 [(set (match_operand:SF 0 "register_operand" "")
14446 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14447 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14448 {
14449 if (!TARGET_SSE_MATH)
14450 operands[1] = force_reg (SFmode, operands[1]);
14451 })
14452
14453 (define_insn "sqrtsf2_1"
14454 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14455 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14456 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14457 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14458 "@
14459 fsqrt
14460 sqrtss\t{%1, %0|%0, %1}"
14461 [(set_attr "type" "fpspc,sse")
14462 (set_attr "mode" "SF,SF")
14463 (set_attr "athlon_decode" "direct,*")])
14464
14465 (define_insn "sqrtsf2_1_sse_only"
14466 [(set (match_operand:SF 0 "register_operand" "=x")
14467 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14468 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14469 "sqrtss\t{%1, %0|%0, %1}"
14470 [(set_attr "type" "sse")
14471 (set_attr "mode" "SF")
14472 (set_attr "athlon_decode" "*")])
14473
14474 (define_insn "sqrtsf2_i387"
14475 [(set (match_operand:SF 0 "register_operand" "=f")
14476 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14477 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14478 && !TARGET_SSE_MATH"
14479 "fsqrt"
14480 [(set_attr "type" "fpspc")
14481 (set_attr "mode" "SF")
14482 (set_attr "athlon_decode" "direct")])
14483
14484 (define_expand "sqrtdf2"
14485 [(set (match_operand:DF 0 "register_operand" "")
14486 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14487 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14488 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14489 {
14490 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14491 operands[1] = force_reg (DFmode, operands[1]);
14492 })
14493
14494 (define_insn "sqrtdf2_1"
14495 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14496 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14497 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14498 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14499 "@
14500 fsqrt
14501 sqrtsd\t{%1, %0|%0, %1}"
14502 [(set_attr "type" "fpspc,sse")
14503 (set_attr "mode" "DF,DF")
14504 (set_attr "athlon_decode" "direct,*")])
14505
14506 (define_insn "sqrtdf2_1_sse_only"
14507 [(set (match_operand:DF 0 "register_operand" "=Y")
14508 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14509 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14510 "sqrtsd\t{%1, %0|%0, %1}"
14511 [(set_attr "type" "sse")
14512 (set_attr "mode" "DF")
14513 (set_attr "athlon_decode" "*")])
14514
14515 (define_insn "sqrtdf2_i387"
14516 [(set (match_operand:DF 0 "register_operand" "=f")
14517 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14518 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14519 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14520 "fsqrt"
14521 [(set_attr "type" "fpspc")
14522 (set_attr "mode" "DF")
14523 (set_attr "athlon_decode" "direct")])
14524
14525 (define_insn "*sqrtextendsfdf2"
14526 [(set (match_operand:DF 0 "register_operand" "=f")
14527 (sqrt:DF (float_extend:DF
14528 (match_operand:SF 1 "register_operand" "0"))))]
14529 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14530 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14531 "fsqrt"
14532 [(set_attr "type" "fpspc")
14533 (set_attr "mode" "DF")
14534 (set_attr "athlon_decode" "direct")])
14535
14536 (define_insn "sqrtxf2"
14537 [(set (match_operand:XF 0 "register_operand" "=f")
14538 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14539 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14540 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14541 "fsqrt"
14542 [(set_attr "type" "fpspc")
14543 (set_attr "mode" "XF")
14544 (set_attr "athlon_decode" "direct")])
14545
14546 (define_insn "sqrttf2"
14547 [(set (match_operand:TF 0 "register_operand" "=f")
14548 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14549 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14550 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14551 "fsqrt"
14552 [(set_attr "type" "fpspc")
14553 (set_attr "mode" "XF")
14554 (set_attr "athlon_decode" "direct")])
14555
14556 (define_insn "*sqrtextenddfxf2"
14557 [(set (match_operand:XF 0 "register_operand" "=f")
14558 (sqrt:XF (float_extend:XF
14559 (match_operand:DF 1 "register_operand" "0"))))]
14560 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14561 "fsqrt"
14562 [(set_attr "type" "fpspc")
14563 (set_attr "mode" "XF")
14564 (set_attr "athlon_decode" "direct")])
14565
14566 (define_insn "*sqrtextenddftf2"
14567 [(set (match_operand:TF 0 "register_operand" "=f")
14568 (sqrt:TF (float_extend:TF
14569 (match_operand:DF 1 "register_operand" "0"))))]
14570 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14571 "fsqrt"
14572 [(set_attr "type" "fpspc")
14573 (set_attr "mode" "XF")
14574 (set_attr "athlon_decode" "direct")])
14575
14576 (define_insn "*sqrtextendsfxf2"
14577 [(set (match_operand:XF 0 "register_operand" "=f")
14578 (sqrt:XF (float_extend:XF
14579 (match_operand:SF 1 "register_operand" "0"))))]
14580 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14581 "fsqrt"
14582 [(set_attr "type" "fpspc")
14583 (set_attr "mode" "XF")
14584 (set_attr "athlon_decode" "direct")])
14585
14586 (define_insn "*sqrtextendsftf2"
14587 [(set (match_operand:TF 0 "register_operand" "=f")
14588 (sqrt:TF (float_extend:TF
14589 (match_operand:SF 1 "register_operand" "0"))))]
14590 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14591 "fsqrt"
14592 [(set_attr "type" "fpspc")
14593 (set_attr "mode" "XF")
14594 (set_attr "athlon_decode" "direct")])
14595
14596 (define_insn "sindf2"
14597 [(set (match_operand:DF 0 "register_operand" "=f")
14598 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14599 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14600 && flag_unsafe_math_optimizations"
14601 "fsin"
14602 [(set_attr "type" "fpspc")
14603 (set_attr "mode" "DF")])
14604
14605 (define_insn "sinsf2"
14606 [(set (match_operand:SF 0 "register_operand" "=f")
14607 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14608 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14609 && flag_unsafe_math_optimizations"
14610 "fsin"
14611 [(set_attr "type" "fpspc")
14612 (set_attr "mode" "SF")])
14613
14614 (define_insn "*sinextendsfdf2"
14615 [(set (match_operand:DF 0 "register_operand" "=f")
14616 (unspec:DF [(float_extend:DF
14617 (match_operand:SF 1 "register_operand" "0"))] 1))]
14618 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14619 && flag_unsafe_math_optimizations"
14620 "fsin"
14621 [(set_attr "type" "fpspc")
14622 (set_attr "mode" "DF")])
14623
14624 (define_insn "sinxf2"
14625 [(set (match_operand:XF 0 "register_operand" "=f")
14626 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14627 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations"
14629 "fsin"
14630 [(set_attr "type" "fpspc")
14631 (set_attr "mode" "XF")])
14632
14633 (define_insn "sintf2"
14634 [(set (match_operand:TF 0 "register_operand" "=f")
14635 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14636 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14637 && flag_unsafe_math_optimizations"
14638 "fsin"
14639 [(set_attr "type" "fpspc")
14640 (set_attr "mode" "XF")])
14641
14642 (define_insn "cosdf2"
14643 [(set (match_operand:DF 0 "register_operand" "=f")
14644 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14645 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14646 && flag_unsafe_math_optimizations"
14647 "fcos"
14648 [(set_attr "type" "fpspc")
14649 (set_attr "mode" "DF")])
14650
14651 (define_insn "cossf2"
14652 [(set (match_operand:SF 0 "register_operand" "=f")
14653 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14654 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14655 && flag_unsafe_math_optimizations"
14656 "fcos"
14657 [(set_attr "type" "fpspc")
14658 (set_attr "mode" "SF")])
14659
14660 (define_insn "*cosextendsfdf2"
14661 [(set (match_operand:DF 0 "register_operand" "=f")
14662 (unspec:DF [(float_extend:DF
14663 (match_operand:SF 1 "register_operand" "0"))] 2))]
14664 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14665 && flag_unsafe_math_optimizations"
14666 "fcos"
14667 [(set_attr "type" "fpspc")
14668 (set_attr "mode" "DF")])
14669
14670 (define_insn "cosxf2"
14671 [(set (match_operand:XF 0 "register_operand" "=f")
14672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14673 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14674 && flag_unsafe_math_optimizations"
14675 "fcos"
14676 [(set_attr "type" "fpspc")
14677 (set_attr "mode" "XF")])
14678
14679 (define_insn "costf2"
14680 [(set (match_operand:TF 0 "register_operand" "=f")
14681 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14682 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14683 && flag_unsafe_math_optimizations"
14684 "fcos"
14685 [(set_attr "type" "fpspc")
14686 (set_attr "mode" "XF")])
14687 \f
14688 ;; Block operation instructions
14689
14690 (define_insn "cld"
14691 [(set (reg:SI 19) (const_int 0))]
14692 ""
14693 "cld"
14694 [(set_attr "type" "cld")])
14695
14696 (define_expand "movstrsi"
14697 [(use (match_operand:BLK 0 "memory_operand" ""))
14698 (use (match_operand:BLK 1 "memory_operand" ""))
14699 (use (match_operand:SI 2 "nonmemory_operand" ""))
14700 (use (match_operand:SI 3 "const_int_operand" ""))]
14701 ""
14702 {
14703 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14704 DONE;
14705 else
14706 FAIL;
14707 })
14708
14709 (define_expand "movstrdi"
14710 [(use (match_operand:BLK 0 "memory_operand" ""))
14711 (use (match_operand:BLK 1 "memory_operand" ""))
14712 (use (match_operand:DI 2 "nonmemory_operand" ""))
14713 (use (match_operand:DI 3 "const_int_operand" ""))]
14714 "TARGET_64BIT"
14715 {
14716 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14717 DONE;
14718 else
14719 FAIL;
14720 })
14721
14722 ;; Most CPUs don't like single string operations
14723 ;; Handle this case here to simplify previous expander.
14724
14725 (define_expand "strmovdi_rex64"
14726 [(set (match_dup 2)
14727 (mem:DI (match_operand:DI 1 "register_operand" "")))
14728 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14729 (match_dup 2))
14730 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14731 (clobber (reg:CC 17))])
14732 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14733 (clobber (reg:CC 17))])]
14734 "TARGET_64BIT"
14735 {
14736 if (TARGET_SINGLE_STRINGOP || optimize_size)
14737 {
14738 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14739 operands[1]));
14740 DONE;
14741 }
14742 else
14743 operands[2] = gen_reg_rtx (DImode);
14744 })
14745
14746
14747 (define_expand "strmovsi"
14748 [(set (match_dup 2)
14749 (mem:SI (match_operand:SI 1 "register_operand" "")))
14750 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14751 (match_dup 2))
14752 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14753 (clobber (reg:CC 17))])
14754 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14755 (clobber (reg:CC 17))])]
14756 ""
14757 {
14758 if (TARGET_64BIT)
14759 {
14760 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14761 DONE;
14762 }
14763 if (TARGET_SINGLE_STRINGOP || optimize_size)
14764 {
14765 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14766 operands[1]));
14767 DONE;
14768 }
14769 else
14770 operands[2] = gen_reg_rtx (SImode);
14771 })
14772
14773 (define_expand "strmovsi_rex64"
14774 [(set (match_dup 2)
14775 (mem:SI (match_operand:DI 1 "register_operand" "")))
14776 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14777 (match_dup 2))
14778 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14779 (clobber (reg:CC 17))])
14780 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14781 (clobber (reg:CC 17))])]
14782 "TARGET_64BIT"
14783 {
14784 if (TARGET_SINGLE_STRINGOP || optimize_size)
14785 {
14786 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14787 operands[1]));
14788 DONE;
14789 }
14790 else
14791 operands[2] = gen_reg_rtx (SImode);
14792 })
14793
14794 (define_expand "strmovhi"
14795 [(set (match_dup 2)
14796 (mem:HI (match_operand:SI 1 "register_operand" "")))
14797 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14798 (match_dup 2))
14799 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14800 (clobber (reg:CC 17))])
14801 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14802 (clobber (reg:CC 17))])]
14803 ""
14804 {
14805 if (TARGET_64BIT)
14806 {
14807 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14808 DONE;
14809 }
14810 if (TARGET_SINGLE_STRINGOP || optimize_size)
14811 {
14812 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14813 operands[1]));
14814 DONE;
14815 }
14816 else
14817 operands[2] = gen_reg_rtx (HImode);
14818 })
14819
14820 (define_expand "strmovhi_rex64"
14821 [(set (match_dup 2)
14822 (mem:HI (match_operand:DI 1 "register_operand" "")))
14823 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14824 (match_dup 2))
14825 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14826 (clobber (reg:CC 17))])
14827 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14828 (clobber (reg:CC 17))])]
14829 "TARGET_64BIT"
14830 {
14831 if (TARGET_SINGLE_STRINGOP || optimize_size)
14832 {
14833 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14834 operands[1]));
14835 DONE;
14836 }
14837 else
14838 operands[2] = gen_reg_rtx (HImode);
14839 })
14840
14841 (define_expand "strmovqi"
14842 [(set (match_dup 2)
14843 (mem:QI (match_operand:SI 1 "register_operand" "")))
14844 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14845 (match_dup 2))
14846 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14847 (clobber (reg:CC 17))])
14848 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14849 (clobber (reg:CC 17))])]
14850 ""
14851 {
14852 if (TARGET_64BIT)
14853 {
14854 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14855 DONE;
14856 }
14857 if (TARGET_SINGLE_STRINGOP || optimize_size)
14858 {
14859 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14860 operands[1]));
14861 DONE;
14862 }
14863 else
14864 operands[2] = gen_reg_rtx (QImode);
14865 })
14866
14867 (define_expand "strmovqi_rex64"
14868 [(set (match_dup 2)
14869 (mem:QI (match_operand:DI 1 "register_operand" "")))
14870 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14871 (match_dup 2))
14872 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14873 (clobber (reg:CC 17))])
14874 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14875 (clobber (reg:CC 17))])]
14876 "TARGET_64BIT"
14877 {
14878 if (TARGET_SINGLE_STRINGOP || optimize_size)
14879 {
14880 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14881 operands[1]));
14882 DONE;
14883 }
14884 else
14885 operands[2] = gen_reg_rtx (QImode);
14886 })
14887
14888 (define_insn "strmovdi_rex_1"
14889 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14890 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14891 (set (match_operand:DI 0 "register_operand" "=D")
14892 (plus:DI (match_dup 2)
14893 (const_int 8)))
14894 (set (match_operand:DI 1 "register_operand" "=S")
14895 (plus:DI (match_dup 3)
14896 (const_int 8)))
14897 (use (reg:SI 19))]
14898 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14899 "movsq"
14900 [(set_attr "type" "str")
14901 (set_attr "mode" "DI")
14902 (set_attr "memory" "both")])
14903
14904 (define_insn "strmovsi_1"
14905 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14906 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14907 (set (match_operand:SI 0 "register_operand" "=D")
14908 (plus:SI (match_dup 2)
14909 (const_int 4)))
14910 (set (match_operand:SI 1 "register_operand" "=S")
14911 (plus:SI (match_dup 3)
14912 (const_int 4)))
14913 (use (reg:SI 19))]
14914 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14915 "{movsl|movsd}"
14916 [(set_attr "type" "str")
14917 (set_attr "mode" "SI")
14918 (set_attr "memory" "both")])
14919
14920 (define_insn "strmovsi_rex_1"
14921 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14922 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14923 (set (match_operand:DI 0 "register_operand" "=D")
14924 (plus:DI (match_dup 2)
14925 (const_int 4)))
14926 (set (match_operand:DI 1 "register_operand" "=S")
14927 (plus:DI (match_dup 3)
14928 (const_int 4)))
14929 (use (reg:SI 19))]
14930 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14931 "{movsl|movsd}"
14932 [(set_attr "type" "str")
14933 (set_attr "mode" "SI")
14934 (set_attr "memory" "both")])
14935
14936 (define_insn "strmovhi_1"
14937 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14938 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14939 (set (match_operand:SI 0 "register_operand" "=D")
14940 (plus:SI (match_dup 2)
14941 (const_int 2)))
14942 (set (match_operand:SI 1 "register_operand" "=S")
14943 (plus:SI (match_dup 3)
14944 (const_int 2)))
14945 (use (reg:SI 19))]
14946 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14947 "movsw"
14948 [(set_attr "type" "str")
14949 (set_attr "memory" "both")
14950 (set_attr "mode" "HI")])
14951
14952 (define_insn "strmovhi_rex_1"
14953 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14954 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14955 (set (match_operand:DI 0 "register_operand" "=D")
14956 (plus:DI (match_dup 2)
14957 (const_int 2)))
14958 (set (match_operand:DI 1 "register_operand" "=S")
14959 (plus:DI (match_dup 3)
14960 (const_int 2)))
14961 (use (reg:SI 19))]
14962 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14963 "movsw"
14964 [(set_attr "type" "str")
14965 (set_attr "memory" "both")
14966 (set_attr "mode" "HI")])
14967
14968 (define_insn "strmovqi_1"
14969 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14970 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14971 (set (match_operand:SI 0 "register_operand" "=D")
14972 (plus:SI (match_dup 2)
14973 (const_int 1)))
14974 (set (match_operand:SI 1 "register_operand" "=S")
14975 (plus:SI (match_dup 3)
14976 (const_int 1)))
14977 (use (reg:SI 19))]
14978 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14979 "movsb"
14980 [(set_attr "type" "str")
14981 (set_attr "memory" "both")
14982 (set_attr "mode" "QI")])
14983
14984 (define_insn "strmovqi_rex_1"
14985 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14986 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14987 (set (match_operand:DI 0 "register_operand" "=D")
14988 (plus:DI (match_dup 2)
14989 (const_int 1)))
14990 (set (match_operand:DI 1 "register_operand" "=S")
14991 (plus:DI (match_dup 3)
14992 (const_int 1)))
14993 (use (reg:SI 19))]
14994 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14995 "movsb"
14996 [(set_attr "type" "str")
14997 (set_attr "memory" "both")
14998 (set_attr "mode" "QI")])
14999
15000 (define_insn "rep_movdi_rex64"
15001 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15002 (set (match_operand:DI 0 "register_operand" "=D")
15003 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15004 (const_int 3))
15005 (match_operand:DI 3 "register_operand" "0")))
15006 (set (match_operand:DI 1 "register_operand" "=S")
15007 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15008 (match_operand:DI 4 "register_operand" "1")))
15009 (set (mem:BLK (match_dup 3))
15010 (mem:BLK (match_dup 4)))
15011 (use (match_dup 5))
15012 (use (reg:SI 19))]
15013 "TARGET_64BIT"
15014 "{rep\;movsq|rep movsq}"
15015 [(set_attr "type" "str")
15016 (set_attr "prefix_rep" "1")
15017 (set_attr "memory" "both")
15018 (set_attr "mode" "DI")])
15019
15020 (define_insn "rep_movsi"
15021 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15022 (set (match_operand:SI 0 "register_operand" "=D")
15023 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15024 (const_int 2))
15025 (match_operand:SI 3 "register_operand" "0")))
15026 (set (match_operand:SI 1 "register_operand" "=S")
15027 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15028 (match_operand:SI 4 "register_operand" "1")))
15029 (set (mem:BLK (match_dup 3))
15030 (mem:BLK (match_dup 4)))
15031 (use (match_dup 5))
15032 (use (reg:SI 19))]
15033 "!TARGET_64BIT"
15034 "{rep\;movsl|rep movsd}"
15035 [(set_attr "type" "str")
15036 (set_attr "prefix_rep" "1")
15037 (set_attr "memory" "both")
15038 (set_attr "mode" "SI")])
15039
15040 (define_insn "rep_movsi_rex64"
15041 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15042 (set (match_operand:DI 0 "register_operand" "=D")
15043 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15044 (const_int 2))
15045 (match_operand:DI 3 "register_operand" "0")))
15046 (set (match_operand:DI 1 "register_operand" "=S")
15047 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15048 (match_operand:DI 4 "register_operand" "1")))
15049 (set (mem:BLK (match_dup 3))
15050 (mem:BLK (match_dup 4)))
15051 (use (match_dup 5))
15052 (use (reg:SI 19))]
15053 "TARGET_64BIT"
15054 "{rep\;movsl|rep movsd}"
15055 [(set_attr "type" "str")
15056 (set_attr "prefix_rep" "1")
15057 (set_attr "memory" "both")
15058 (set_attr "mode" "SI")])
15059
15060 (define_insn "rep_movqi"
15061 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15062 (set (match_operand:SI 0 "register_operand" "=D")
15063 (plus:SI (match_operand:SI 3 "register_operand" "0")
15064 (match_operand:SI 5 "register_operand" "2")))
15065 (set (match_operand:SI 1 "register_operand" "=S")
15066 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15067 (set (mem:BLK (match_dup 3))
15068 (mem:BLK (match_dup 4)))
15069 (use (match_dup 5))
15070 (use (reg:SI 19))]
15071 "!TARGET_64BIT"
15072 "{rep\;movsb|rep movsb}"
15073 [(set_attr "type" "str")
15074 (set_attr "prefix_rep" "1")
15075 (set_attr "memory" "both")
15076 (set_attr "mode" "SI")])
15077
15078 (define_insn "rep_movqi_rex64"
15079 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15080 (set (match_operand:DI 0 "register_operand" "=D")
15081 (plus:DI (match_operand:DI 3 "register_operand" "0")
15082 (match_operand:DI 5 "register_operand" "2")))
15083 (set (match_operand:DI 1 "register_operand" "=S")
15084 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15085 (set (mem:BLK (match_dup 3))
15086 (mem:BLK (match_dup 4)))
15087 (use (match_dup 5))
15088 (use (reg:SI 19))]
15089 "TARGET_64BIT"
15090 "{rep\;movsb|rep movsb}"
15091 [(set_attr "type" "str")
15092 (set_attr "prefix_rep" "1")
15093 (set_attr "memory" "both")
15094 (set_attr "mode" "SI")])
15095
15096 (define_expand "clrstrsi"
15097 [(use (match_operand:BLK 0 "memory_operand" ""))
15098 (use (match_operand:SI 1 "nonmemory_operand" ""))
15099 (use (match_operand 2 "const_int_operand" ""))]
15100 ""
15101 {
15102 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15103 DONE;
15104 else
15105 FAIL;
15106 })
15107
15108 (define_expand "clrstrdi"
15109 [(use (match_operand:BLK 0 "memory_operand" ""))
15110 (use (match_operand:DI 1 "nonmemory_operand" ""))
15111 (use (match_operand 2 "const_int_operand" ""))]
15112 "TARGET_64BIT"
15113 {
15114 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15115 DONE;
15116 else
15117 FAIL;
15118 })
15119
15120 ;; Most CPUs don't like single string operations
15121 ;; Handle this case here to simplify previous expander.
15122
15123 (define_expand "strsetdi_rex64"
15124 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15125 (match_operand:DI 1 "register_operand" ""))
15126 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15127 (clobber (reg:CC 17))])]
15128 "TARGET_64BIT"
15129 {
15130 if (TARGET_SINGLE_STRINGOP || optimize_size)
15131 {
15132 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15133 DONE;
15134 }
15135 })
15136
15137 (define_expand "strsetsi"
15138 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15139 (match_operand:SI 1 "register_operand" ""))
15140 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15141 (clobber (reg:CC 17))])]
15142 ""
15143 {
15144 if (TARGET_64BIT)
15145 {
15146 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15147 DONE;
15148 }
15149 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15150 {
15151 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15152 DONE;
15153 }
15154 })
15155
15156 (define_expand "strsetsi_rex64"
15157 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15158 (match_operand:SI 1 "register_operand" ""))
15159 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15160 (clobber (reg:CC 17))])]
15161 "TARGET_64BIT"
15162 {
15163 if (TARGET_SINGLE_STRINGOP || optimize_size)
15164 {
15165 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15166 DONE;
15167 }
15168 })
15169
15170 (define_expand "strsethi"
15171 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15172 (match_operand:HI 1 "register_operand" ""))
15173 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15174 (clobber (reg:CC 17))])]
15175 ""
15176 {
15177 if (TARGET_64BIT)
15178 {
15179 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15180 DONE;
15181 }
15182 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15183 {
15184 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15185 DONE;
15186 }
15187 })
15188
15189 (define_expand "strsethi_rex64"
15190 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15191 (match_operand:HI 1 "register_operand" ""))
15192 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15193 (clobber (reg:CC 17))])]
15194 "TARGET_64BIT"
15195 {
15196 if (TARGET_SINGLE_STRINGOP || optimize_size)
15197 {
15198 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15199 DONE;
15200 }
15201 })
15202
15203 (define_expand "strsetqi"
15204 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15205 (match_operand:QI 1 "register_operand" ""))
15206 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15207 (clobber (reg:CC 17))])]
15208 ""
15209 {
15210 if (TARGET_64BIT)
15211 {
15212 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15213 DONE;
15214 }
15215 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15216 {
15217 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15218 DONE;
15219 }
15220 })
15221
15222 (define_expand "strsetqi_rex64"
15223 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15224 (match_operand:QI 1 "register_operand" ""))
15225 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15226 (clobber (reg:CC 17))])]
15227 "TARGET_64BIT"
15228 {
15229 if (TARGET_SINGLE_STRINGOP || optimize_size)
15230 {
15231 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15232 DONE;
15233 }
15234 })
15235
15236 (define_insn "strsetdi_rex_1"
15237 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15238 (match_operand:SI 2 "register_operand" "a"))
15239 (set (match_operand:DI 0 "register_operand" "=D")
15240 (plus:DI (match_dup 1)
15241 (const_int 8)))
15242 (use (reg:SI 19))]
15243 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15244 "stosq"
15245 [(set_attr "type" "str")
15246 (set_attr "memory" "store")
15247 (set_attr "mode" "DI")])
15248
15249 (define_insn "strsetsi_1"
15250 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15251 (match_operand:SI 2 "register_operand" "a"))
15252 (set (match_operand:SI 0 "register_operand" "=D")
15253 (plus:SI (match_dup 1)
15254 (const_int 4)))
15255 (use (reg:SI 19))]
15256 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15257 "{stosl|stosd}"
15258 [(set_attr "type" "str")
15259 (set_attr "memory" "store")
15260 (set_attr "mode" "SI")])
15261
15262 (define_insn "strsetsi_rex_1"
15263 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15264 (match_operand:SI 2 "register_operand" "a"))
15265 (set (match_operand:DI 0 "register_operand" "=D")
15266 (plus:DI (match_dup 1)
15267 (const_int 4)))
15268 (use (reg:SI 19))]
15269 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15270 "{stosl|stosd}"
15271 [(set_attr "type" "str")
15272 (set_attr "memory" "store")
15273 (set_attr "mode" "SI")])
15274
15275 (define_insn "strsethi_1"
15276 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15277 (match_operand:HI 2 "register_operand" "a"))
15278 (set (match_operand:SI 0 "register_operand" "=D")
15279 (plus:SI (match_dup 1)
15280 (const_int 2)))
15281 (use (reg:SI 19))]
15282 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15283 "stosw"
15284 [(set_attr "type" "str")
15285 (set_attr "memory" "store")
15286 (set_attr "mode" "HI")])
15287
15288 (define_insn "strsethi_rex_1"
15289 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15290 (match_operand:HI 2 "register_operand" "a"))
15291 (set (match_operand:DI 0 "register_operand" "=D")
15292 (plus:DI (match_dup 1)
15293 (const_int 2)))
15294 (use (reg:SI 19))]
15295 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15296 "stosw"
15297 [(set_attr "type" "str")
15298 (set_attr "memory" "store")
15299 (set_attr "mode" "HI")])
15300
15301 (define_insn "strsetqi_1"
15302 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15303 (match_operand:QI 2 "register_operand" "a"))
15304 (set (match_operand:SI 0 "register_operand" "=D")
15305 (plus:SI (match_dup 1)
15306 (const_int 1)))
15307 (use (reg:SI 19))]
15308 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15309 "stosb"
15310 [(set_attr "type" "str")
15311 (set_attr "memory" "store")
15312 (set_attr "mode" "QI")])
15313
15314 (define_insn "strsetqi_rex_1"
15315 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15316 (match_operand:QI 2 "register_operand" "a"))
15317 (set (match_operand:DI 0 "register_operand" "=D")
15318 (plus:DI (match_dup 1)
15319 (const_int 1)))
15320 (use (reg:SI 19))]
15321 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15322 "stosb"
15323 [(set_attr "type" "str")
15324 (set_attr "memory" "store")
15325 (set_attr "mode" "QI")])
15326
15327 (define_insn "rep_stosdi_rex64"
15328 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15329 (set (match_operand:DI 0 "register_operand" "=D")
15330 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15331 (const_int 3))
15332 (match_operand:DI 3 "register_operand" "0")))
15333 (set (mem:BLK (match_dup 3))
15334 (const_int 0))
15335 (use (match_operand:DI 2 "register_operand" "a"))
15336 (use (match_dup 4))
15337 (use (reg:SI 19))]
15338 "TARGET_64BIT"
15339 "{rep\;stosq|rep stosq}"
15340 [(set_attr "type" "str")
15341 (set_attr "prefix_rep" "1")
15342 (set_attr "memory" "store")
15343 (set_attr "mode" "DI")])
15344
15345 (define_insn "rep_stossi"
15346 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15347 (set (match_operand:SI 0 "register_operand" "=D")
15348 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15349 (const_int 2))
15350 (match_operand:SI 3 "register_operand" "0")))
15351 (set (mem:BLK (match_dup 3))
15352 (const_int 0))
15353 (use (match_operand:SI 2 "register_operand" "a"))
15354 (use (match_dup 4))
15355 (use (reg:SI 19))]
15356 "!TARGET_64BIT"
15357 "{rep\;stosl|rep stosd}"
15358 [(set_attr "type" "str")
15359 (set_attr "prefix_rep" "1")
15360 (set_attr "memory" "store")
15361 (set_attr "mode" "SI")])
15362
15363 (define_insn "rep_stossi_rex64"
15364 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15365 (set (match_operand:DI 0 "register_operand" "=D")
15366 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15367 (const_int 2))
15368 (match_operand:DI 3 "register_operand" "0")))
15369 (set (mem:BLK (match_dup 3))
15370 (const_int 0))
15371 (use (match_operand:SI 2 "register_operand" "a"))
15372 (use (match_dup 4))
15373 (use (reg:SI 19))]
15374 "TARGET_64BIT"
15375 "{rep\;stosl|rep stosd}"
15376 [(set_attr "type" "str")
15377 (set_attr "prefix_rep" "1")
15378 (set_attr "memory" "store")
15379 (set_attr "mode" "SI")])
15380
15381 (define_insn "rep_stosqi"
15382 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15383 (set (match_operand:SI 0 "register_operand" "=D")
15384 (plus:SI (match_operand:SI 3 "register_operand" "0")
15385 (match_operand:SI 4 "register_operand" "1")))
15386 (set (mem:BLK (match_dup 3))
15387 (const_int 0))
15388 (use (match_operand:QI 2 "register_operand" "a"))
15389 (use (match_dup 4))
15390 (use (reg:SI 19))]
15391 "!TARGET_64BIT"
15392 "{rep\;stosb|rep stosb}"
15393 [(set_attr "type" "str")
15394 (set_attr "prefix_rep" "1")
15395 (set_attr "memory" "store")
15396 (set_attr "mode" "QI")])
15397
15398 (define_insn "rep_stosqi_rex64"
15399 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15400 (set (match_operand:DI 0 "register_operand" "=D")
15401 (plus:DI (match_operand:DI 3 "register_operand" "0")
15402 (match_operand:DI 4 "register_operand" "1")))
15403 (set (mem:BLK (match_dup 3))
15404 (const_int 0))
15405 (use (match_operand:QI 2 "register_operand" "a"))
15406 (use (match_dup 4))
15407 (use (reg:DI 19))]
15408 "TARGET_64BIT"
15409 "{rep\;stosb|rep stosb}"
15410 [(set_attr "type" "str")
15411 (set_attr "prefix_rep" "1")
15412 (set_attr "memory" "store")
15413 (set_attr "mode" "QI")])
15414
15415 (define_expand "cmpstrsi"
15416 [(set (match_operand:SI 0 "register_operand" "")
15417 (compare:SI (match_operand:BLK 1 "general_operand" "")
15418 (match_operand:BLK 2 "general_operand" "")))
15419 (use (match_operand 3 "general_operand" ""))
15420 (use (match_operand 4 "immediate_operand" ""))]
15421 ""
15422 {
15423 rtx addr1, addr2, out, outlow, count, countreg, align;
15424
15425 out = operands[0];
15426 if (GET_CODE (out) != REG)
15427 out = gen_reg_rtx (SImode);
15428
15429 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15430 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15431
15432 count = operands[3];
15433 countreg = ix86_zero_extend_to_Pmode (count);
15434
15435 /* %%% Iff we are testing strict equality, we can use known alignment
15436 to good advantage. This may be possible with combine, particularly
15437 once cc0 is dead. */
15438 align = operands[4];
15439
15440 emit_insn (gen_cld ());
15441 if (GET_CODE (count) == CONST_INT)
15442 {
15443 if (INTVAL (count) == 0)
15444 {
15445 emit_move_insn (operands[0], const0_rtx);
15446 DONE;
15447 }
15448 if (TARGET_64BIT)
15449 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15450 addr1, addr2, countreg));
15451 else
15452 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15453 addr1, addr2, countreg));
15454 }
15455 else
15456 {
15457 if (TARGET_64BIT)
15458 {
15459 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15460 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15461 addr1, addr2, countreg));
15462 }
15463 else
15464 {
15465 emit_insn (gen_cmpsi_1 (countreg, countreg));
15466 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15467 addr1, addr2, countreg));
15468 }
15469 }
15470
15471 outlow = gen_lowpart (QImode, out);
15472 emit_insn (gen_cmpintqi (outlow));
15473 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15474
15475 if (operands[0] != out)
15476 emit_move_insn (operands[0], out);
15477
15478 DONE;
15479 })
15480
15481 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15482
15483 (define_expand "cmpintqi"
15484 [(set (match_dup 1)
15485 (gtu:QI (reg:CC 17) (const_int 0)))
15486 (set (match_dup 2)
15487 (ltu:QI (reg:CC 17) (const_int 0)))
15488 (parallel [(set (match_operand:QI 0 "register_operand" "")
15489 (minus:QI (match_dup 1)
15490 (match_dup 2)))
15491 (clobber (reg:CC 17))])]
15492 ""
15493 "operands[1] = gen_reg_rtx (QImode);
15494 operands[2] = gen_reg_rtx (QImode);")
15495
15496 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15497 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15498
15499 (define_insn "cmpstrqi_nz_1"
15500 [(set (reg:CC 17)
15501 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15502 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15503 (use (match_operand:SI 6 "register_operand" "2"))
15504 (use (match_operand:SI 3 "immediate_operand" "i"))
15505 (use (reg:SI 19))
15506 (clobber (match_operand:SI 0 "register_operand" "=S"))
15507 (clobber (match_operand:SI 1 "register_operand" "=D"))
15508 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15509 "!TARGET_64BIT"
15510 "repz{\;| }cmpsb"
15511 [(set_attr "type" "str")
15512 (set_attr "mode" "QI")
15513 (set_attr "prefix_rep" "1")])
15514
15515 (define_insn "cmpstrqi_nz_rex_1"
15516 [(set (reg:CC 17)
15517 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15518 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15519 (use (match_operand:DI 6 "register_operand" "2"))
15520 (use (match_operand:SI 3 "immediate_operand" "i"))
15521 (use (reg:SI 19))
15522 (clobber (match_operand:DI 0 "register_operand" "=S"))
15523 (clobber (match_operand:DI 1 "register_operand" "=D"))
15524 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15525 "TARGET_64BIT"
15526 "repz{\;| }cmpsb"
15527 [(set_attr "type" "str")
15528 (set_attr "mode" "QI")
15529 (set_attr "prefix_rep" "1")])
15530
15531 ;; The same, but the count is not known to not be zero.
15532
15533 (define_insn "cmpstrqi_1"
15534 [(set (reg:CC 17)
15535 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15536 (const_int 0))
15537 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15538 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15539 (const_int 0)))
15540 (use (match_operand:SI 3 "immediate_operand" "i"))
15541 (use (reg:CC 17))
15542 (use (reg:SI 19))
15543 (clobber (match_operand:SI 0 "register_operand" "=S"))
15544 (clobber (match_operand:SI 1 "register_operand" "=D"))
15545 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15546 "!TARGET_64BIT"
15547 "repz{\;| }cmpsb"
15548 [(set_attr "type" "str")
15549 (set_attr "mode" "QI")
15550 (set_attr "prefix_rep" "1")])
15551
15552 (define_insn "cmpstrqi_rex_1"
15553 [(set (reg:CC 17)
15554 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15555 (const_int 0))
15556 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15557 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15558 (const_int 0)))
15559 (use (match_operand:SI 3 "immediate_operand" "i"))
15560 (use (reg:CC 17))
15561 (use (reg:SI 19))
15562 (clobber (match_operand:DI 0 "register_operand" "=S"))
15563 (clobber (match_operand:DI 1 "register_operand" "=D"))
15564 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15565 "TARGET_64BIT"
15566 "repz{\;| }cmpsb"
15567 [(set_attr "type" "str")
15568 (set_attr "mode" "QI")
15569 (set_attr "prefix_rep" "1")])
15570
15571 (define_expand "strlensi"
15572 [(set (match_operand:SI 0 "register_operand" "")
15573 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15574 (match_operand:QI 2 "immediate_operand" "")
15575 (match_operand 3 "immediate_operand" "")] 0))]
15576 ""
15577 {
15578 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15579 DONE;
15580 else
15581 FAIL;
15582 })
15583
15584 (define_expand "strlendi"
15585 [(set (match_operand:DI 0 "register_operand" "")
15586 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15587 (match_operand:QI 2 "immediate_operand" "")
15588 (match_operand 3 "immediate_operand" "")] 0))]
15589 ""
15590 {
15591 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15592 DONE;
15593 else
15594 FAIL;
15595 })
15596
15597 (define_insn "strlenqi_1"
15598 [(set (match_operand:SI 0 "register_operand" "=&c")
15599 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15600 (match_operand:QI 2 "register_operand" "a")
15601 (match_operand:SI 3 "immediate_operand" "i")
15602 (match_operand:SI 4 "register_operand" "0")] 0))
15603 (use (reg:SI 19))
15604 (clobber (match_operand:SI 1 "register_operand" "=D"))
15605 (clobber (reg:CC 17))]
15606 "!TARGET_64BIT"
15607 "repnz{\;| }scasb"
15608 [(set_attr "type" "str")
15609 (set_attr "mode" "QI")
15610 (set_attr "prefix_rep" "1")])
15611
15612 (define_insn "strlenqi_rex_1"
15613 [(set (match_operand:DI 0 "register_operand" "=&c")
15614 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15615 (match_operand:QI 2 "register_operand" "a")
15616 (match_operand:DI 3 "immediate_operand" "i")
15617 (match_operand:DI 4 "register_operand" "0")] 0))
15618 (use (reg:SI 19))
15619 (clobber (match_operand:DI 1 "register_operand" "=D"))
15620 (clobber (reg:CC 17))]
15621 "TARGET_64BIT"
15622 "repnz{\;| }scasb"
15623 [(set_attr "type" "str")
15624 (set_attr "mode" "QI")
15625 (set_attr "prefix_rep" "1")])
15626
15627 ;; Peephole optimizations to clean up after cmpstr*. This should be
15628 ;; handled in combine, but it is not currently up to the task.
15629 ;; When used for their truth value, the cmpstr* expanders generate
15630 ;; code like this:
15631 ;;
15632 ;; repz cmpsb
15633 ;; seta %al
15634 ;; setb %dl
15635 ;; cmpb %al, %dl
15636 ;; jcc label
15637 ;;
15638 ;; The intermediate three instructions are unnecessary.
15639
15640 ;; This one handles cmpstr*_nz_1...
15641 (define_peephole2
15642 [(parallel[
15643 (set (reg:CC 17)
15644 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15645 (mem:BLK (match_operand 5 "register_operand" ""))))
15646 (use (match_operand 6 "register_operand" ""))
15647 (use (match_operand:SI 3 "immediate_operand" ""))
15648 (use (reg:SI 19))
15649 (clobber (match_operand 0 "register_operand" ""))
15650 (clobber (match_operand 1 "register_operand" ""))
15651 (clobber (match_operand 2 "register_operand" ""))])
15652 (set (match_operand:QI 7 "register_operand" "")
15653 (gtu:QI (reg:CC 17) (const_int 0)))
15654 (set (match_operand:QI 8 "register_operand" "")
15655 (ltu:QI (reg:CC 17) (const_int 0)))
15656 (set (reg 17)
15657 (compare (match_dup 7) (match_dup 8)))
15658 ]
15659 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15660 [(parallel[
15661 (set (reg:CC 17)
15662 (compare:CC (mem:BLK (match_dup 4))
15663 (mem:BLK (match_dup 5))))
15664 (use (match_dup 6))
15665 (use (match_dup 3))
15666 (use (reg:SI 19))
15667 (clobber (match_dup 0))
15668 (clobber (match_dup 1))
15669 (clobber (match_dup 2))])]
15670 "")
15671
15672 ;; ...and this one handles cmpstr*_1.
15673 (define_peephole2
15674 [(parallel[
15675 (set (reg:CC 17)
15676 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15677 (const_int 0))
15678 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15679 (mem:BLK (match_operand 5 "register_operand" "")))
15680 (const_int 0)))
15681 (use (match_operand:SI 3 "immediate_operand" ""))
15682 (use (reg:CC 17))
15683 (use (reg:SI 19))
15684 (clobber (match_operand 0 "register_operand" ""))
15685 (clobber (match_operand 1 "register_operand" ""))
15686 (clobber (match_operand 2 "register_operand" ""))])
15687 (set (match_operand:QI 7 "register_operand" "")
15688 (gtu:QI (reg:CC 17) (const_int 0)))
15689 (set (match_operand:QI 8 "register_operand" "")
15690 (ltu:QI (reg:CC 17) (const_int 0)))
15691 (set (reg 17)
15692 (compare (match_dup 7) (match_dup 8)))
15693 ]
15694 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15695 [(parallel[
15696 (set (reg:CC 17)
15697 (if_then_else:CC (ne (match_dup 6)
15698 (const_int 0))
15699 (compare:CC (mem:BLK (match_dup 4))
15700 (mem:BLK (match_dup 5)))
15701 (const_int 0)))
15702 (use (match_dup 3))
15703 (use (reg:CC 17))
15704 (use (reg:SI 19))
15705 (clobber (match_dup 0))
15706 (clobber (match_dup 1))
15707 (clobber (match_dup 2))])]
15708 "")
15709
15710
15711 \f
15712 ;; Conditional move instructions.
15713
15714 (define_expand "movdicc"
15715 [(set (match_operand:DI 0 "register_operand" "")
15716 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15717 (match_operand:DI 2 "general_operand" "")
15718 (match_operand:DI 3 "general_operand" "")))]
15719 "TARGET_64BIT"
15720 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15721
15722 (define_insn "x86_movdicc_0_m1_rex64"
15723 [(set (match_operand:DI 0 "register_operand" "=r")
15724 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15725 (const_int -1)
15726 (const_int 0)))
15727 (clobber (reg:CC 17))]
15728 "TARGET_64BIT"
15729 "sbb{q}\t%0, %0"
15730 ; Since we don't have the proper number of operands for an alu insn,
15731 ; fill in all the blanks.
15732 [(set_attr "type" "alu")
15733 (set_attr "memory" "none")
15734 (set_attr "imm_disp" "false")
15735 (set_attr "mode" "DI")
15736 (set_attr "length_immediate" "0")])
15737
15738 (define_insn "*movdicc_c_rex64"
15739 [(set (match_operand:DI 0 "register_operand" "=r,r")
15740 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15741 [(reg 17) (const_int 0)])
15742 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15743 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15744 "TARGET_64BIT && TARGET_CMOVE
15745 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15746 "@
15747 cmov%C1\t{%2, %0|%0, %2}
15748 cmov%c1\t{%3, %0|%0, %3}"
15749 [(set_attr "type" "icmov")
15750 (set_attr "mode" "DI")])
15751
15752 (define_expand "movsicc"
15753 [(set (match_operand:SI 0 "register_operand" "")
15754 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15755 (match_operand:SI 2 "general_operand" "")
15756 (match_operand:SI 3 "general_operand" "")))]
15757 ""
15758 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15759
15760 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15761 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15762 ;; So just document what we're doing explicitly.
15763
15764 (define_insn "x86_movsicc_0_m1"
15765 [(set (match_operand:SI 0 "register_operand" "=r")
15766 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15767 (const_int -1)
15768 (const_int 0)))
15769 (clobber (reg:CC 17))]
15770 ""
15771 "sbb{l}\t%0, %0"
15772 ; Since we don't have the proper number of operands for an alu insn,
15773 ; fill in all the blanks.
15774 [(set_attr "type" "alu")
15775 (set_attr "memory" "none")
15776 (set_attr "imm_disp" "false")
15777 (set_attr "mode" "SI")
15778 (set_attr "length_immediate" "0")])
15779
15780 (define_insn "*movsicc_noc"
15781 [(set (match_operand:SI 0 "register_operand" "=r,r")
15782 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15783 [(reg 17) (const_int 0)])
15784 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15785 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15786 "TARGET_CMOVE
15787 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15788 "@
15789 cmov%C1\t{%2, %0|%0, %2}
15790 cmov%c1\t{%3, %0|%0, %3}"
15791 [(set_attr "type" "icmov")
15792 (set_attr "mode" "SI")])
15793
15794 (define_expand "movhicc"
15795 [(set (match_operand:HI 0 "register_operand" "")
15796 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15797 (match_operand:HI 2 "nonimmediate_operand" "")
15798 (match_operand:HI 3 "nonimmediate_operand" "")))]
15799 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15800 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15801
15802 (define_insn "*movhicc_noc"
15803 [(set (match_operand:HI 0 "register_operand" "=r,r")
15804 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15805 [(reg 17) (const_int 0)])
15806 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15807 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15808 "TARGET_CMOVE
15809 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15810 "@
15811 cmov%C1\t{%2, %0|%0, %2}
15812 cmov%c1\t{%3, %0|%0, %3}"
15813 [(set_attr "type" "icmov")
15814 (set_attr "mode" "HI")])
15815
15816 (define_expand "movsfcc"
15817 [(set (match_operand:SF 0 "register_operand" "")
15818 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15819 (match_operand:SF 2 "register_operand" "")
15820 (match_operand:SF 3 "register_operand" "")))]
15821 "TARGET_CMOVE"
15822 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15823
15824 (define_insn "*movsfcc_1"
15825 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15826 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15827 [(reg 17) (const_int 0)])
15828 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15829 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15830 "TARGET_CMOVE
15831 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15832 "@
15833 fcmov%F1\t{%2, %0|%0, %2}
15834 fcmov%f1\t{%3, %0|%0, %3}
15835 cmov%C1\t{%2, %0|%0, %2}
15836 cmov%c1\t{%3, %0|%0, %3}"
15837 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15838 (set_attr "mode" "SF,SF,SI,SI")])
15839
15840 (define_expand "movdfcc"
15841 [(set (match_operand:DF 0 "register_operand" "")
15842 (if_then_else:DF (match_operand 1 "comparison_operator" "")
15843 (match_operand:DF 2 "register_operand" "")
15844 (match_operand:DF 3 "register_operand" "")))]
15845 "TARGET_CMOVE"
15846 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15847
15848 (define_insn "*movdfcc_1"
15849 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15850 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15851 [(reg 17) (const_int 0)])
15852 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15853 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15854 "!TARGET_64BIT && TARGET_CMOVE
15855 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15856 "@
15857 fcmov%F1\t{%2, %0|%0, %2}
15858 fcmov%f1\t{%3, %0|%0, %3}
15859 #
15860 #"
15861 [(set_attr "type" "fcmov,fcmov,multi,multi")
15862 (set_attr "mode" "DF")])
15863
15864 (define_insn "*movdfcc_1_rex64"
15865 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15866 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15867 [(reg 17) (const_int 0)])
15868 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15869 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15870 "TARGET_64BIT && TARGET_CMOVE
15871 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15872 "@
15873 fcmov%F1\t{%2, %0|%0, %2}
15874 fcmov%f1\t{%3, %0|%0, %3}
15875 cmov%C1\t{%2, %0|%0, %2}
15876 cmov%c1\t{%3, %0|%0, %3}"
15877 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15878 (set_attr "mode" "DF")])
15879
15880 (define_split
15881 [(set (match_operand:DF 0 "register_operand" "")
15882 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15883 [(match_operand 4 "" "") (const_int 0)])
15884 (match_operand:DF 2 "nonimmediate_operand" "")
15885 (match_operand:DF 3 "nonimmediate_operand" "")))]
15886 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
15887 [(set (match_dup 2)
15888 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15889 (match_dup 5)
15890 (match_dup 7)))
15891 (set (match_dup 3)
15892 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15893 (match_dup 6)
15894 (match_dup 8)))]
15895 "split_di (operands+2, 1, operands+5, operands+6);
15896 split_di (operands+3, 1, operands+7, operands+8);
15897 split_di (operands, 1, operands+2, operands+3);")
15898
15899 (define_expand "movxfcc"
15900 [(set (match_operand:XF 0 "register_operand" "")
15901 (if_then_else:XF (match_operand 1 "comparison_operator" "")
15902 (match_operand:XF 2 "register_operand" "")
15903 (match_operand:XF 3 "register_operand" "")))]
15904 "!TARGET_64BIT && TARGET_CMOVE"
15905 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15906
15907 (define_expand "movtfcc"
15908 [(set (match_operand:TF 0 "register_operand" "")
15909 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15910 (match_operand:TF 2 "register_operand" "")
15911 (match_operand:TF 3 "register_operand" "")))]
15912 "TARGET_CMOVE"
15913 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15914
15915 (define_insn "*movxfcc_1"
15916 [(set (match_operand:XF 0 "register_operand" "=f,f")
15917 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15918 [(reg 17) (const_int 0)])
15919 (match_operand:XF 2 "register_operand" "f,0")
15920 (match_operand:XF 3 "register_operand" "0,f")))]
15921 "!TARGET_64BIT && TARGET_CMOVE"
15922 "@
15923 fcmov%F1\t{%2, %0|%0, %2}
15924 fcmov%f1\t{%3, %0|%0, %3}"
15925 [(set_attr "type" "fcmov")
15926 (set_attr "mode" "XF")])
15927
15928 (define_insn "*movtfcc_1"
15929 [(set (match_operand:TF 0 "register_operand" "=f,f")
15930 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15931 [(reg 17) (const_int 0)])
15932 (match_operand:TF 2 "register_operand" "f,0")
15933 (match_operand:TF 3 "register_operand" "0,f")))]
15934 "TARGET_CMOVE"
15935 "@
15936 fcmov%F1\t{%2, %0|%0, %2}
15937 fcmov%f1\t{%3, %0|%0, %3}"
15938 [(set_attr "type" "fcmov")
15939 (set_attr "mode" "XF")])
15940
15941 (define_expand "minsf3"
15942 [(parallel [
15943 (set (match_operand:SF 0 "register_operand" "")
15944 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15945 (match_operand:SF 2 "nonimmediate_operand" ""))
15946 (match_dup 1)
15947 (match_dup 2)))
15948 (clobber (reg:CC 17))])]
15949 "TARGET_SSE"
15950 "")
15951
15952 (define_insn "*minsf"
15953 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15954 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15955 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15956 (match_dup 1)
15957 (match_dup 2)))
15958 (clobber (reg:CC 17))]
15959 "TARGET_SSE && TARGET_IEEE_FP"
15960 "#")
15961
15962 (define_insn "*minsf_nonieee"
15963 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15964 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
15965 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15966 (match_dup 1)
15967 (match_dup 2)))
15968 (clobber (reg:CC 17))]
15969 "TARGET_SSE && !TARGET_IEEE_FP"
15970 "#")
15971
15972 (define_split
15973 [(set (match_operand:SF 0 "register_operand" "")
15974 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15975 (match_operand:SF 2 "nonimmediate_operand" ""))
15976 (match_operand:SF 3 "register_operand" "")
15977 (match_operand:SF 4 "nonimmediate_operand" "")))
15978 (clobber (reg:CC 17))]
15979 "SSE_REG_P (operands[0]) && reload_completed
15980 && ((operands_match_p (operands[1], operands[3])
15981 && operands_match_p (operands[2], operands[4]))
15982 || (operands_match_p (operands[1], operands[4])
15983 && operands_match_p (operands[2], operands[3])))"
15984 [(set (match_dup 0)
15985 (if_then_else:SF (lt (match_dup 1)
15986 (match_dup 2))
15987 (match_dup 1)
15988 (match_dup 2)))])
15989
15990 ;; We can't represent the LT test directly. Do this by swapping the operands.
15991
15992 (define_split
15993 [(set (match_operand:SF 0 "register_operand" "")
15994 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15995 (match_operand:SF 2 "register_operand" ""))
15996 (match_operand:DF 3 "register_operand" "")
15997 (match_operand:DF 4 "register_operand" "")))
15998 (clobber (reg:CC 17))]
15999 "FP_REG_P (operands[0]) && reload_completed
16000 && ((operands_match_p (operands[1], operands[3])
16001 && operands_match_p (operands[2], operands[4]))
16002 || (operands_match_p (operands[1], operands[4])
16003 && operands_match_p (operands[2], operands[3])))"
16004 [(set (reg:CCFP 17)
16005 (compare:CCFP (match_dup 2)
16006 (match_dup 1)))
16007 (set (match_dup 0)
16008 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16009 (match_dup 1)
16010 (match_dup 2)))])
16011
16012 (define_insn "*minsf_sse"
16013 [(set (match_operand:SF 0 "register_operand" "=x")
16014 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16015 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16016 (match_dup 1)
16017 (match_dup 2)))]
16018 "TARGET_SSE && reload_completed"
16019 "minss\t{%2, %0|%0, %2}"
16020 [(set_attr "type" "sse")
16021 (set_attr "mode" "SF")])
16022
16023 (define_expand "mindf3"
16024 [(parallel [
16025 (set (match_operand:DF 0 "register_operand" "")
16026 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16027 (match_operand:DF 2 "nonimmediate_operand" ""))
16028 (match_dup 1)
16029 (match_dup 2)))
16030 (clobber (reg:CC 17))])]
16031 "TARGET_SSE2 && TARGET_SSE_MATH"
16032 "#")
16033
16034 (define_insn "*mindf"
16035 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16036 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16037 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16038 (match_dup 1)
16039 (match_dup 2)))
16040 (clobber (reg:CC 17))]
16041 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16042 "#")
16043
16044 (define_insn "*mindf_nonieee"
16045 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16046 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
16047 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
16048 (match_dup 1)
16049 (match_dup 2)))
16050 (clobber (reg:CC 17))]
16051 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
16052 "#")
16053
16054 (define_split
16055 [(set (match_operand:DF 0 "register_operand" "")
16056 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16057 (match_operand:DF 2 "nonimmediate_operand" ""))
16058 (match_operand:DF 3 "register_operand" "")
16059 (match_operand:DF 4 "nonimmediate_operand" "")))
16060 (clobber (reg:CC 17))]
16061 "SSE_REG_P (operands[0]) && reload_completed
16062 && ((operands_match_p (operands[1], operands[3])
16063 && operands_match_p (operands[2], operands[4]))
16064 || (operands_match_p (operands[1], operands[4])
16065 && operands_match_p (operands[2], operands[3])))"
16066 [(set (match_dup 0)
16067 (if_then_else:DF (lt (match_dup 1)
16068 (match_dup 2))
16069 (match_dup 1)
16070 (match_dup 2)))])
16071
16072 ;; We can't represent the LT test directly. Do this by swapping the operands.
16073 (define_split
16074 [(set (match_operand:DF 0 "register_operand" "")
16075 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16076 (match_operand:DF 2 "register_operand" ""))
16077 (match_operand:DF 3 "register_operand" "")
16078 (match_operand:DF 4 "register_operand" "")))
16079 (clobber (reg:CC 17))]
16080 "FP_REG_P (operands[0]) && reload_completed
16081 && ((operands_match_p (operands[1], operands[3])
16082 && operands_match_p (operands[2], operands[4]))
16083 || (operands_match_p (operands[1], operands[4])
16084 && operands_match_p (operands[2], operands[3])))"
16085 [(set (reg:CCFP 17)
16086 (compare:CCFP (match_dup 2)
16087 (match_dup 2)))
16088 (set (match_dup 0)
16089 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16090 (match_dup 1)
16091 (match_dup 2)))])
16092
16093 (define_insn "*mindf_sse"
16094 [(set (match_operand:DF 0 "register_operand" "=Y")
16095 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16096 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16097 (match_dup 1)
16098 (match_dup 2)))]
16099 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16100 "minsd\t{%2, %0|%0, %2}"
16101 [(set_attr "type" "sse")
16102 (set_attr "mode" "DF")])
16103
16104 (define_expand "maxsf3"
16105 [(parallel [
16106 (set (match_operand:SF 0 "register_operand" "")
16107 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16108 (match_operand:SF 2 "nonimmediate_operand" ""))
16109 (match_dup 1)
16110 (match_dup 2)))
16111 (clobber (reg:CC 17))])]
16112 "TARGET_SSE"
16113 "#")
16114
16115 (define_insn "*maxsf"
16116 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16117 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16118 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
16119 (match_dup 1)
16120 (match_dup 2)))
16121 (clobber (reg:CC 17))]
16122 "TARGET_SSE && TARGET_IEEE_FP"
16123 "#")
16124
16125 (define_insn "*maxsf_nonieee"
16126 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16127 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
16128 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
16129 (match_dup 1)
16130 (match_dup 2)))
16131 (clobber (reg:CC 17))]
16132 "TARGET_SSE && !TARGET_IEEE_FP"
16133 "#")
16134
16135 (define_split
16136 [(set (match_operand:SF 0 "register_operand" "")
16137 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16138 (match_operand:SF 2 "nonimmediate_operand" ""))
16139 (match_operand:SF 3 "register_operand" "")
16140 (match_operand:SF 4 "nonimmediate_operand" "")))
16141 (clobber (reg:CC 17))]
16142 "SSE_REG_P (operands[0]) && reload_completed
16143 && ((operands_match_p (operands[1], operands[3])
16144 && operands_match_p (operands[2], operands[4]))
16145 || (operands_match_p (operands[1], operands[4])
16146 && operands_match_p (operands[2], operands[3])))"
16147 [(set (match_dup 0)
16148 (if_then_else:SF (gt (match_dup 1)
16149 (match_dup 2))
16150 (match_dup 1)
16151 (match_dup 2)))])
16152
16153 (define_split
16154 [(set (match_operand:SF 0 "register_operand" "")
16155 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16156 (match_operand:SF 2 "register_operand" ""))
16157 (match_operand:SF 3 "register_operand" "")
16158 (match_operand:SF 4 "register_operand" "")))
16159 (clobber (reg:CC 17))]
16160 "FP_REG_P (operands[0]) && reload_completed
16161 && ((operands_match_p (operands[1], operands[3])
16162 && operands_match_p (operands[2], operands[4]))
16163 || (operands_match_p (operands[1], operands[4])
16164 && operands_match_p (operands[2], operands[3])))"
16165 [(set (reg:CCFP 17)
16166 (compare:CCFP (match_dup 1)
16167 (match_dup 2)))
16168 (set (match_dup 0)
16169 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16170 (match_dup 1)
16171 (match_dup 2)))])
16172
16173 (define_insn "*maxsf_sse"
16174 [(set (match_operand:SF 0 "register_operand" "=x")
16175 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16176 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16177 (match_dup 1)
16178 (match_dup 2)))]
16179 "TARGET_SSE && reload_completed"
16180 "maxss\t{%2, %0|%0, %2}"
16181 [(set_attr "type" "sse")
16182 (set_attr "mode" "SF")])
16183
16184 (define_expand "maxdf3"
16185 [(parallel [
16186 (set (match_operand:DF 0 "register_operand" "")
16187 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16188 (match_operand:DF 2 "nonimmediate_operand" ""))
16189 (match_dup 1)
16190 (match_dup 2)))
16191 (clobber (reg:CC 17))])]
16192 "TARGET_SSE2 && TARGET_SSE_MATH"
16193 "#")
16194
16195 (define_insn "*maxdf"
16196 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16197 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16198 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
16199 (match_dup 1)
16200 (match_dup 2)))
16201 (clobber (reg:CC 17))]
16202 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16203 "#")
16204
16205 (define_insn "*maxdf_nonieee"
16206 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16207 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
16208 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
16209 (match_dup 1)
16210 (match_dup 2)))
16211 (clobber (reg:CC 17))]
16212 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
16213 "#")
16214
16215 (define_split
16216 [(set (match_operand:DF 0 "register_operand" "")
16217 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16218 (match_operand:DF 2 "nonimmediate_operand" ""))
16219 (match_operand:DF 3 "register_operand" "")
16220 (match_operand:DF 4 "nonimmediate_operand" "")))
16221 (clobber (reg:CC 17))]
16222 "SSE_REG_P (operands[0]) && reload_completed
16223 && ((operands_match_p (operands[1], operands[3])
16224 && operands_match_p (operands[2], operands[4]))
16225 || (operands_match_p (operands[1], operands[4])
16226 && operands_match_p (operands[2], operands[3])))"
16227 [(set (match_dup 0)
16228 (if_then_else:DF (gt (match_dup 1)
16229 (match_dup 2))
16230 (match_dup 1)
16231 (match_dup 2)))])
16232
16233 (define_split
16234 [(set (match_operand:DF 0 "register_operand" "")
16235 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16236 (match_operand:DF 2 "register_operand" ""))
16237 (match_operand:DF 3 "register_operand" "")
16238 (match_operand:DF 4 "register_operand" "")))
16239 (clobber (reg:CC 17))]
16240 "FP_REG_P (operands[0]) && reload_completed
16241 && ((operands_match_p (operands[1], operands[3])
16242 && operands_match_p (operands[2], operands[4]))
16243 || (operands_match_p (operands[1], operands[4])
16244 && operands_match_p (operands[2], operands[3])))"
16245 [(set (reg:CCFP 17)
16246 (compare:CCFP (match_dup 1)
16247 (match_dup 2)))
16248 (set (match_dup 0)
16249 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16250 (match_dup 1)
16251 (match_dup 2)))])
16252
16253 (define_insn "*maxdf_sse"
16254 [(set (match_operand:DF 0 "register_operand" "=Y")
16255 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16256 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16257 (match_dup 1)
16258 (match_dup 2)))]
16259 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16260 "maxsd\t{%2, %0|%0, %2}"
16261 [(set_attr "type" "sse")
16262 (set_attr "mode" "DF")])
16263 \f
16264 ;; Misc patterns (?)
16265
16266 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16267 ;; Otherwise there will be nothing to keep
16268 ;;
16269 ;; [(set (reg ebp) (reg esp))]
16270 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16271 ;; (clobber (eflags)]
16272 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16273 ;;
16274 ;; in proper program order.
16275 (define_expand "pro_epilogue_adjust_stack"
16276 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16277 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16278 (match_operand:SI 2 "immediate_operand" "i,i")))
16279 (clobber (reg:CC 17))
16280 (clobber (mem:BLK (scratch)))])]
16281 ""
16282 {
16283 if (TARGET_64BIT)
16284 {
16285 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16286 (operands[0], operands[1], operands[2]));
16287 DONE;
16288 }
16289 })
16290
16291 (define_insn "*pro_epilogue_adjust_stack_1"
16292 [(set (match_operand:SI 0 "register_operand" "=r,r")
16293 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16294 (match_operand:SI 2 "immediate_operand" "i,i")))
16295 (clobber (reg:CC 17))
16296 (clobber (mem:BLK (scratch)))]
16297 "!TARGET_64BIT"
16298 {
16299 switch (get_attr_type (insn))
16300 {
16301 case TYPE_IMOV:
16302 return "mov{l}\t{%1, %0|%0, %1}";
16303
16304 case TYPE_ALU:
16305 if (GET_CODE (operands[2]) == CONST_INT
16306 && (INTVAL (operands[2]) == 128
16307 || (INTVAL (operands[2]) < 0
16308 && INTVAL (operands[2]) != -128)))
16309 {
16310 operands[2] = GEN_INT (-INTVAL (operands[2]));
16311 return "sub{l}\t{%2, %0|%0, %2}";
16312 }
16313 return "add{l}\t{%2, %0|%0, %2}";
16314
16315 case TYPE_LEA:
16316 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16317 return "lea{l}\t{%a2, %0|%0, %a2}";
16318
16319 default:
16320 abort ();
16321 }
16322 }
16323 [(set (attr "type")
16324 (cond [(eq_attr "alternative" "0")
16325 (const_string "alu")
16326 (match_operand:SI 2 "const0_operand" "")
16327 (const_string "imov")
16328 ]
16329 (const_string "lea")))
16330 (set_attr "mode" "SI")])
16331
16332 (define_insn "pro_epilogue_adjust_stack_rex64"
16333 [(set (match_operand:DI 0 "register_operand" "=r,r")
16334 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16335 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16336 (clobber (reg:CC 17))
16337 (clobber (mem:BLK (scratch)))]
16338 "TARGET_64BIT"
16339 {
16340 switch (get_attr_type (insn))
16341 {
16342 case TYPE_IMOV:
16343 return "mov{q}\t{%1, %0|%0, %1}";
16344
16345 case TYPE_ALU:
16346 if (GET_CODE (operands[2]) == CONST_INT
16347 && (INTVAL (operands[2]) == 128
16348 || (INTVAL (operands[2]) < 0
16349 && INTVAL (operands[2]) != -128)))
16350 {
16351 operands[2] = GEN_INT (-INTVAL (operands[2]));
16352 return "sub{q}\t{%2, %0|%0, %2}";
16353 }
16354 return "add{q}\t{%2, %0|%0, %2}";
16355
16356 case TYPE_LEA:
16357 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16358 return "lea{q}\t{%a2, %0|%0, %a2}";
16359
16360 default:
16361 abort ();
16362 }
16363 }
16364 [(set (attr "type")
16365 (cond [(eq_attr "alternative" "0")
16366 (const_string "alu")
16367 (match_operand:DI 2 "const0_operand" "")
16368 (const_string "imov")
16369 ]
16370 (const_string "lea")))
16371 (set_attr "mode" "DI")])
16372
16373
16374 ;; Placeholder for the conditional moves. This one is split either to SSE
16375 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16376 ;; fact is that compares supported by the cmp??ss instructions are exactly
16377 ;; swapped of those supported by cmove sequence.
16378 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16379 ;; supported by i387 comparisons and we do need to emit two conditional moves
16380 ;; in tandem.
16381
16382 (define_insn "sse_movsfcc"
16383 [(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")
16384 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16385 [(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")
16386 (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")])
16387 (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")
16388 (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")))
16389 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16390 (clobber (reg:CC 17))]
16391 "TARGET_SSE
16392 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16393 && (!TARGET_IEEE_FP
16394 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16395 "#")
16396
16397 (define_insn "sse_movsfcc_eq"
16398 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16399 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16400 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16401 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16402 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16403 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16404 (clobber (reg:CC 17))]
16405 "TARGET_SSE
16406 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16407 "#")
16408
16409 (define_insn "sse_movdfcc"
16410 [(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")
16411 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16412 [(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")
16413 (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")])
16414 (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")
16415 (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")))
16416 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16417 (clobber (reg:CC 17))]
16418 "TARGET_SSE2
16419 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16420 && (!TARGET_IEEE_FP
16421 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16422 "#")
16423
16424 (define_insn "sse_movdfcc_eq"
16425 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16426 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16427 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16428 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16429 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16430 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16431 (clobber (reg:CC 17))]
16432 "TARGET_SSE
16433 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16434 "#")
16435
16436 ;; For non-sse moves just expand the usual cmove sequence.
16437 (define_split
16438 [(set (match_operand 0 "register_operand" "")
16439 (if_then_else (match_operator 1 "comparison_operator"
16440 [(match_operand 4 "nonimmediate_operand" "")
16441 (match_operand 5 "register_operand" "")])
16442 (match_operand 2 "nonimmediate_operand" "")
16443 (match_operand 3 "nonimmediate_operand" "")))
16444 (clobber (match_operand 6 "" ""))
16445 (clobber (reg:CC 17))]
16446 "!SSE_REG_P (operands[0]) && reload_completed
16447 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16448 [(const_int 0)]
16449 {
16450 ix86_compare_op0 = operands[5];
16451 ix86_compare_op1 = operands[4];
16452 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16453 VOIDmode, operands[5], operands[4]);
16454 ix86_expand_fp_movcc (operands);
16455 DONE;
16456 })
16457
16458 ;; Split SSE based conditional move into seqence:
16459 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16460 ;; and op2, op0 - zero op2 if comparison was false
16461 ;; nand op0, op3 - load op3 to op0 if comparison was false
16462 ;; or op2, op0 - get the non-zero one into the result.
16463 (define_split
16464 [(set (match_operand 0 "register_operand" "")
16465 (if_then_else (match_operator 1 "sse_comparison_operator"
16466 [(match_operand 4 "register_operand" "")
16467 (match_operand 5 "nonimmediate_operand" "")])
16468 (match_operand 2 "register_operand" "")
16469 (match_operand 3 "register_operand" "")))
16470 (clobber (match_operand 6 "" ""))
16471 (clobber (reg:CC 17))]
16472 "SSE_REG_P (operands[0]) && reload_completed"
16473 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16474 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16475 (subreg:TI (match_dup 4) 0)))
16476 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16477 (subreg:TI (match_dup 3) 0)))
16478 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16479 (subreg:TI (match_dup 7) 0)))]
16480 {
16481 PUT_MODE (operands[1], GET_MODE (operands[0]));
16482 if (operands_match_p (operands[0], operands[4]))
16483 operands[6] = operands[4], operands[7] = operands[2];
16484 else
16485 operands[6] = operands[2], operands[7] = operands[4];
16486 })
16487
16488 ;; Special case of conditional move we can handle effectivly.
16489 ;; Do not brother with the integer/floating point case, since these are
16490 ;; bot considerably slower, unlike in the generic case.
16491 (define_insn "*sse_movsfcc_const0_1"
16492 [(set (match_operand:SF 0 "register_operand" "=x")
16493 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16494 [(match_operand:SF 4 "register_operand" "0")
16495 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16496 (match_operand:SF 2 "register_operand" "x")
16497 (match_operand:SF 3 "const0_operand" "X")))]
16498 "TARGET_SSE"
16499 "#")
16500
16501 (define_insn "*sse_movsfcc_const0_2"
16502 [(set (match_operand:SF 0 "register_operand" "=x")
16503 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16504 [(match_operand:SF 4 "register_operand" "0")
16505 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16506 (match_operand:SF 2 "const0_operand" "x")
16507 (match_operand:SF 3 "register_operand" "X")))]
16508 "TARGET_SSE"
16509 "#")
16510
16511 (define_insn "*sse_movsfcc_const0_3"
16512 [(set (match_operand:SF 0 "register_operand" "=x")
16513 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16514 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16515 (match_operand:SF 5 "register_operand" "0")])
16516 (match_operand:SF 2 "register_operand" "x")
16517 (match_operand:SF 3 "const0_operand" "X")))]
16518 "TARGET_SSE"
16519 "#")
16520
16521 (define_insn "*sse_movsfcc_const0_4"
16522 [(set (match_operand:SF 0 "register_operand" "=x")
16523 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16524 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16525 (match_operand:SF 5 "register_operand" "0")])
16526 (match_operand:SF 2 "const0_operand" "x")
16527 (match_operand:SF 3 "register_operand" "X")))]
16528 "TARGET_SSE"
16529 "#")
16530
16531 (define_insn "*sse_movdfcc_const0_1"
16532 [(set (match_operand:SF 0 "register_operand" "=x")
16533 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16534 [(match_operand:SF 4 "register_operand" "0")
16535 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16536 (match_operand:SF 2 "register_operand" "x")
16537 (match_operand:SF 3 "const0_operand" "X")))]
16538 "TARGET_SSE2"
16539 "#")
16540
16541 (define_insn "*sse_movdfcc_const0_2"
16542 [(set (match_operand:SF 0 "register_operand" "=x")
16543 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16544 [(match_operand:SF 4 "register_operand" "0")
16545 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16546 (match_operand:SF 2 "const0_operand" "x")
16547 (match_operand:SF 3 "register_operand" "X")))]
16548 "TARGET_SSE2"
16549 "#")
16550
16551 (define_insn "*sse_movdfcc_const0_3"
16552 [(set (match_operand:SF 0 "register_operand" "=x")
16553 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16554 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16555 (match_operand:SF 5 "register_operand" "0")])
16556 (match_operand:SF 2 "register_operand" "x")
16557 (match_operand:SF 3 "const0_operand" "X")))]
16558 "TARGET_SSE2"
16559 "#")
16560
16561 (define_insn "*sse_movdfcc_const0_4"
16562 [(set (match_operand:SF 0 "register_operand" "=x")
16563 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16564 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16565 (match_operand:SF 5 "register_operand" "0")])
16566 (match_operand:SF 2 "const0_operand" "x")
16567 (match_operand:SF 3 "register_operand" "X")))]
16568 "TARGET_SSE2"
16569 "#")
16570
16571 (define_split
16572 [(set (match_operand 0 "register_operand" "")
16573 (if_then_else (match_operator 1 "comparison_operator"
16574 [(match_operand 4 "register_operand" "")
16575 (match_operand 5 "nonimmediate_operand" "")])
16576 (match_operand 2 "nonmemory_operand" "")
16577 (match_operand 3 "nonmemory_operand" "")))]
16578 "SSE_REG_P (operands[0]) && reload_completed
16579 && (const0_operand (operands[2], GET_MODE (operands[0]))
16580 || const0_operand (operands[3], GET_MODE (operands[0])))"
16581 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16582 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16583 (subreg:TI (match_dup 7) 0)))]
16584 {
16585 PUT_MODE (operands[1], GET_MODE (operands[0]));
16586 if (!sse_comparison_operator (operands[1], VOIDmode))
16587 {
16588 rtx tmp = operands[5];
16589 operands[5] = operands[4];
16590 operands[4] = tmp;
16591 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16592 }
16593 if (const0_operand (operands[2], GET_MODE (operands[0])))
16594 {
16595 operands[7] = operands[3];
16596 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16597 0));
16598 }
16599 else
16600 {
16601 operands[7] = operands[2];
16602 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16603 }
16604 })
16605
16606 (define_expand "allocate_stack_worker"
16607 [(match_operand:SI 0 "register_operand" "")]
16608 "TARGET_STACK_PROBE"
16609 {
16610 if (TARGET_64BIT)
16611 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16612 else
16613 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16614 DONE;
16615 })
16616
16617 (define_insn "allocate_stack_worker_1"
16618 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16619 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16620 (clobber (match_dup 0))
16621 (clobber (reg:CC 17))]
16622 "!TARGET_64BIT && TARGET_STACK_PROBE"
16623 "call\t__alloca"
16624 [(set_attr "type" "multi")
16625 (set_attr "length" "5")])
16626
16627 (define_insn "allocate_stack_worker_rex64"
16628 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16629 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16630 (clobber (match_dup 0))
16631 (clobber (reg:CC 17))]
16632 "TARGET_64BIT && TARGET_STACK_PROBE"
16633 "call\t__alloca"
16634 [(set_attr "type" "multi")
16635 (set_attr "length" "5")])
16636
16637 (define_expand "allocate_stack"
16638 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16639 (minus:SI (reg:SI 7)
16640 (match_operand:SI 1 "general_operand" "")))
16641 (clobber (reg:CC 17))])
16642 (parallel [(set (reg:SI 7)
16643 (minus:SI (reg:SI 7) (match_dup 1)))
16644 (clobber (reg:CC 17))])]
16645 "TARGET_STACK_PROBE"
16646 {
16647 #ifdef CHECK_STACK_LIMIT
16648 if (GET_CODE (operands[1]) == CONST_INT
16649 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16650 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16651 operands[1]));
16652 else
16653 #endif
16654 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16655 operands[1])));
16656
16657 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16658 DONE;
16659 })
16660
16661 (define_expand "builtin_setjmp_receiver"
16662 [(label_ref (match_operand 0 "" ""))]
16663 "!TARGET_64BIT && flag_pic"
16664 {
16665 load_pic_register ();
16666 DONE;
16667 })
16668 \f
16669 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16670
16671 (define_split
16672 [(set (match_operand 0 "register_operand" "")
16673 (match_operator 3 "promotable_binary_operator"
16674 [(match_operand 1 "register_operand" "")
16675 (match_operand 2 "aligned_operand" "")]))
16676 (clobber (reg:CC 17))]
16677 "! TARGET_PARTIAL_REG_STALL && reload_completed
16678 && ((GET_MODE (operands[0]) == HImode
16679 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16680 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16681 || (GET_MODE (operands[0]) == QImode
16682 && (TARGET_PROMOTE_QImode || optimize_size)))"
16683 [(parallel [(set (match_dup 0)
16684 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16685 (clobber (reg:CC 17))])]
16686 "operands[0] = gen_lowpart (SImode, operands[0]);
16687 operands[1] = gen_lowpart (SImode, operands[1]);
16688 if (GET_CODE (operands[3]) != ASHIFT)
16689 operands[2] = gen_lowpart (SImode, operands[2]);
16690 PUT_MODE (operands[3], SImode);")
16691
16692 (define_split
16693 [(set (reg 17)
16694 (compare (and (match_operand 1 "aligned_operand" "")
16695 (match_operand 2 "const_int_operand" ""))
16696 (const_int 0)))
16697 (set (match_operand 0 "register_operand" "")
16698 (and (match_dup 1) (match_dup 2)))]
16699 "! TARGET_PARTIAL_REG_STALL && reload_completed
16700 && ix86_match_ccmode (insn, CCNOmode)
16701 && (GET_MODE (operands[0]) == HImode
16702 || (GET_MODE (operands[0]) == QImode
16703 && (TARGET_PROMOTE_QImode || optimize_size)))"
16704 [(parallel [(set (reg:CCNO 17)
16705 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16706 (const_int 0)))
16707 (set (match_dup 0)
16708 (and:SI (match_dup 1) (match_dup 2)))])]
16709 "operands[2]
16710 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16711 & GET_MODE_MASK (GET_MODE (operands[0])),
16712 SImode));
16713 operands[0] = gen_lowpart (SImode, operands[0]);
16714 operands[1] = gen_lowpart (SImode, operands[1]);")
16715
16716 (define_split
16717 [(set (reg 17)
16718 (compare (and (match_operand 0 "aligned_operand" "")
16719 (match_operand 1 "const_int_operand" ""))
16720 (const_int 0)))]
16721 "! TARGET_PARTIAL_REG_STALL && reload_completed
16722 && ix86_match_ccmode (insn, CCNOmode)
16723 && (GET_MODE (operands[0]) == HImode
16724 || (GET_MODE (operands[0]) == QImode
16725 && (TARGET_PROMOTE_QImode || optimize_size)))"
16726 [(set (reg:CCNO 17)
16727 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16728 (const_int 0)))]
16729 "operands[1]
16730 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16731 & GET_MODE_MASK (GET_MODE (operands[0])),
16732 SImode));
16733 operands[0] = gen_lowpart (SImode, operands[0]);")
16734
16735 (define_split
16736 [(set (match_operand 0 "register_operand" "")
16737 (neg (match_operand 1 "register_operand" "")))
16738 (clobber (reg:CC 17))]
16739 "! TARGET_PARTIAL_REG_STALL && reload_completed
16740 && (GET_MODE (operands[0]) == HImode
16741 || (GET_MODE (operands[0]) == QImode
16742 && (TARGET_PROMOTE_QImode || optimize_size)))"
16743 [(parallel [(set (match_dup 0)
16744 (neg:SI (match_dup 1)))
16745 (clobber (reg:CC 17))])]
16746 "operands[0] = gen_lowpart (SImode, operands[0]);
16747 operands[1] = gen_lowpart (SImode, operands[1]);")
16748
16749 (define_split
16750 [(set (match_operand 0 "register_operand" "")
16751 (not (match_operand 1 "register_operand" "")))]
16752 "! TARGET_PARTIAL_REG_STALL && reload_completed
16753 && (GET_MODE (operands[0]) == HImode
16754 || (GET_MODE (operands[0]) == QImode
16755 && (TARGET_PROMOTE_QImode || optimize_size)))"
16756 [(set (match_dup 0)
16757 (not:SI (match_dup 1)))]
16758 "operands[0] = gen_lowpart (SImode, operands[0]);
16759 operands[1] = gen_lowpart (SImode, operands[1]);")
16760
16761 (define_split
16762 [(set (match_operand 0 "register_operand" "")
16763 (if_then_else (match_operator 1 "comparison_operator"
16764 [(reg 17) (const_int 0)])
16765 (match_operand 2 "register_operand" "")
16766 (match_operand 3 "register_operand" "")))]
16767 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16768 && (GET_MODE (operands[0]) == HImode
16769 || (GET_MODE (operands[0]) == QImode
16770 && (TARGET_PROMOTE_QImode || optimize_size)))"
16771 [(set (match_dup 0)
16772 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16773 "operands[0] = gen_lowpart (SImode, operands[0]);
16774 operands[2] = gen_lowpart (SImode, operands[2]);
16775 operands[3] = gen_lowpart (SImode, operands[3]);")
16776
16777 \f
16778 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16779 ;; transform a complex memory operation into two memory to register operations.
16780
16781 ;; Don't push memory operands
16782 (define_peephole2
16783 [(set (match_operand:SI 0 "push_operand" "")
16784 (match_operand:SI 1 "memory_operand" ""))
16785 (match_scratch:SI 2 "r")]
16786 "! optimize_size && ! TARGET_PUSH_MEMORY"
16787 [(set (match_dup 2) (match_dup 1))
16788 (set (match_dup 0) (match_dup 2))]
16789 "")
16790
16791 (define_peephole2
16792 [(set (match_operand:DI 0 "push_operand" "")
16793 (match_operand:DI 1 "memory_operand" ""))
16794 (match_scratch:DI 2 "r")]
16795 "! optimize_size && ! TARGET_PUSH_MEMORY"
16796 [(set (match_dup 2) (match_dup 1))
16797 (set (match_dup 0) (match_dup 2))]
16798 "")
16799
16800 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16801 ;; SImode pushes.
16802 (define_peephole2
16803 [(set (match_operand:SF 0 "push_operand" "")
16804 (match_operand:SF 1 "memory_operand" ""))
16805 (match_scratch:SF 2 "r")]
16806 "! optimize_size && ! TARGET_PUSH_MEMORY"
16807 [(set (match_dup 2) (match_dup 1))
16808 (set (match_dup 0) (match_dup 2))]
16809 "")
16810
16811 (define_peephole2
16812 [(set (match_operand:HI 0 "push_operand" "")
16813 (match_operand:HI 1 "memory_operand" ""))
16814 (match_scratch:HI 2 "r")]
16815 "! optimize_size && ! TARGET_PUSH_MEMORY"
16816 [(set (match_dup 2) (match_dup 1))
16817 (set (match_dup 0) (match_dup 2))]
16818 "")
16819
16820 (define_peephole2
16821 [(set (match_operand:QI 0 "push_operand" "")
16822 (match_operand:QI 1 "memory_operand" ""))
16823 (match_scratch:QI 2 "q")]
16824 "! optimize_size && ! TARGET_PUSH_MEMORY"
16825 [(set (match_dup 2) (match_dup 1))
16826 (set (match_dup 0) (match_dup 2))]
16827 "")
16828
16829 ;; Don't move an immediate directly to memory when the instruction
16830 ;; gets too big.
16831 (define_peephole2
16832 [(match_scratch:SI 1 "r")
16833 (set (match_operand:SI 0 "memory_operand" "")
16834 (const_int 0))]
16835 "! optimize_size
16836 && ! TARGET_USE_MOV0
16837 && TARGET_SPLIT_LONG_MOVES
16838 && get_attr_length (insn) >= ix86_cost->large_insn
16839 && peep2_regno_dead_p (0, FLAGS_REG)"
16840 [(parallel [(set (match_dup 1) (const_int 0))
16841 (clobber (reg:CC 17))])
16842 (set (match_dup 0) (match_dup 1))]
16843 "")
16844
16845 (define_peephole2
16846 [(match_scratch:HI 1 "r")
16847 (set (match_operand:HI 0 "memory_operand" "")
16848 (const_int 0))]
16849 "! optimize_size
16850 && ! TARGET_USE_MOV0
16851 && TARGET_SPLIT_LONG_MOVES
16852 && get_attr_length (insn) >= ix86_cost->large_insn
16853 && peep2_regno_dead_p (0, FLAGS_REG)"
16854 [(parallel [(set (match_dup 2) (const_int 0))
16855 (clobber (reg:CC 17))])
16856 (set (match_dup 0) (match_dup 1))]
16857 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16858
16859 (define_peephole2
16860 [(match_scratch:QI 1 "q")
16861 (set (match_operand:QI 0 "memory_operand" "")
16862 (const_int 0))]
16863 "! optimize_size
16864 && ! TARGET_USE_MOV0
16865 && TARGET_SPLIT_LONG_MOVES
16866 && get_attr_length (insn) >= ix86_cost->large_insn
16867 && peep2_regno_dead_p (0, FLAGS_REG)"
16868 [(parallel [(set (match_dup 2) (const_int 0))
16869 (clobber (reg:CC 17))])
16870 (set (match_dup 0) (match_dup 1))]
16871 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16872
16873 (define_peephole2
16874 [(match_scratch:SI 2 "r")
16875 (set (match_operand:SI 0 "memory_operand" "")
16876 (match_operand:SI 1 "immediate_operand" ""))]
16877 "! optimize_size
16878 && get_attr_length (insn) >= ix86_cost->large_insn
16879 && TARGET_SPLIT_LONG_MOVES"
16880 [(set (match_dup 2) (match_dup 1))
16881 (set (match_dup 0) (match_dup 2))]
16882 "")
16883
16884 (define_peephole2
16885 [(match_scratch:HI 2 "r")
16886 (set (match_operand:HI 0 "memory_operand" "")
16887 (match_operand:HI 1 "immediate_operand" ""))]
16888 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16889 && TARGET_SPLIT_LONG_MOVES"
16890 [(set (match_dup 2) (match_dup 1))
16891 (set (match_dup 0) (match_dup 2))]
16892 "")
16893
16894 (define_peephole2
16895 [(match_scratch:QI 2 "q")
16896 (set (match_operand:QI 0 "memory_operand" "")
16897 (match_operand:QI 1 "immediate_operand" ""))]
16898 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16899 && TARGET_SPLIT_LONG_MOVES"
16900 [(set (match_dup 2) (match_dup 1))
16901 (set (match_dup 0) (match_dup 2))]
16902 "")
16903
16904 ;; Don't compare memory with zero, load and use a test instead.
16905 (define_peephole2
16906 [(set (reg 17)
16907 (compare (match_operand:SI 0 "memory_operand" "")
16908 (const_int 0)))
16909 (match_scratch:SI 3 "r")]
16910 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16911 [(set (match_dup 3) (match_dup 0))
16912 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16913 "")
16914
16915 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16916 ;; Don't split NOTs with a displacement operand, because resulting XOR
16917 ;; will not be pariable anyway.
16918 ;;
16919 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
16920 ;; represented using a modRM byte. The XOR replacement is long decoded,
16921 ;; so this split helps here as well.
16922 ;;
16923 ;; Note: Can't do this as a regular split because we can't get proper
16924 ;; lifetime information then.
16925
16926 (define_peephole2
16927 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16928 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16929 "!optimize_size
16930 && peep2_regno_dead_p (0, FLAGS_REG)
16931 && ((TARGET_PENTIUM
16932 && (GET_CODE (operands[0]) != MEM
16933 || !memory_displacement_operand (operands[0], SImode)))
16934 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16935 [(parallel [(set (match_dup 0)
16936 (xor:SI (match_dup 1) (const_int -1)))
16937 (clobber (reg:CC 17))])]
16938 "")
16939
16940 (define_peephole2
16941 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16942 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16943 "!optimize_size
16944 && peep2_regno_dead_p (0, FLAGS_REG)
16945 && ((TARGET_PENTIUM
16946 && (GET_CODE (operands[0]) != MEM
16947 || !memory_displacement_operand (operands[0], HImode)))
16948 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16949 [(parallel [(set (match_dup 0)
16950 (xor:HI (match_dup 1) (const_int -1)))
16951 (clobber (reg:CC 17))])]
16952 "")
16953
16954 (define_peephole2
16955 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16956 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16957 "!optimize_size
16958 && peep2_regno_dead_p (0, FLAGS_REG)
16959 && ((TARGET_PENTIUM
16960 && (GET_CODE (operands[0]) != MEM
16961 || !memory_displacement_operand (operands[0], QImode)))
16962 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16963 [(parallel [(set (match_dup 0)
16964 (xor:QI (match_dup 1) (const_int -1)))
16965 (clobber (reg:CC 17))])]
16966 "")
16967
16968 ;; Non pairable "test imm, reg" instructions can be translated to
16969 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16970 ;; byte opcode instead of two, have a short form for byte operands),
16971 ;; so do it for other CPUs as well. Given that the value was dead,
16972 ;; this should not create any new dependencies. Pass on the sub-word
16973 ;; versions if we're concerned about partial register stalls.
16974
16975 (define_peephole2
16976 [(set (reg 17)
16977 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16978 (match_operand:SI 1 "immediate_operand" ""))
16979 (const_int 0)))]
16980 "ix86_match_ccmode (insn, CCNOmode)
16981 && (true_regnum (operands[0]) != 0
16982 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
16983 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16984 [(parallel
16985 [(set (reg:CCNO 17)
16986 (compare:CCNO (and:SI (match_dup 0)
16987 (match_dup 1))
16988 (const_int 0)))
16989 (set (match_dup 0)
16990 (and:SI (match_dup 0) (match_dup 1)))])]
16991 "")
16992
16993 ;; We don't need to handle HImode case, because it will be promoted to SImode
16994 ;; on ! TARGET_PARTIAL_REG_STALL
16995
16996 (define_peephole2
16997 [(set (reg 17)
16998 (compare (and:QI (match_operand:QI 0 "register_operand" "")
16999 (match_operand:QI 1 "immediate_operand" ""))
17000 (const_int 0)))]
17001 "! TARGET_PARTIAL_REG_STALL
17002 && ix86_match_ccmode (insn, CCNOmode)
17003 && true_regnum (operands[0]) != 0
17004 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17005 [(parallel
17006 [(set (reg:CCNO 17)
17007 (compare:CCNO (and:QI (match_dup 0)
17008 (match_dup 1))
17009 (const_int 0)))
17010 (set (match_dup 0)
17011 (and:QI (match_dup 0) (match_dup 1)))])]
17012 "")
17013
17014 (define_peephole2
17015 [(set (reg 17)
17016 (compare
17017 (and:SI
17018 (zero_extract:SI
17019 (match_operand 0 "ext_register_operand" "")
17020 (const_int 8)
17021 (const_int 8))
17022 (match_operand 1 "const_int_operand" ""))
17023 (const_int 0)))]
17024 "! TARGET_PARTIAL_REG_STALL
17025 && ix86_match_ccmode (insn, CCNOmode)
17026 && true_regnum (operands[0]) != 0
17027 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17028 [(parallel [(set (reg:CCNO 17)
17029 (compare:CCNO
17030 (and:SI
17031 (zero_extract:SI
17032 (match_dup 0)
17033 (const_int 8)
17034 (const_int 8))
17035 (match_dup 1))
17036 (const_int 0)))
17037 (set (zero_extract:SI (match_dup 0)
17038 (const_int 8)
17039 (const_int 8))
17040 (and:SI
17041 (zero_extract:SI
17042 (match_dup 0)
17043 (const_int 8)
17044 (const_int 8))
17045 (match_dup 1)))])]
17046 "")
17047
17048 ;; Don't do logical operations with memory inputs.
17049 (define_peephole2
17050 [(match_scratch:SI 2 "r")
17051 (parallel [(set (match_operand:SI 0 "register_operand" "")
17052 (match_operator:SI 3 "arith_or_logical_operator"
17053 [(match_dup 0)
17054 (match_operand:SI 1 "memory_operand" "")]))
17055 (clobber (reg:CC 17))])]
17056 "! optimize_size && ! TARGET_READ_MODIFY"
17057 [(set (match_dup 2) (match_dup 1))
17058 (parallel [(set (match_dup 0)
17059 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17060 (clobber (reg:CC 17))])]
17061 "")
17062
17063 (define_peephole2
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand" "")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17067 [(match_operand:SI 1 "memory_operand" "")
17068 (match_dup 0)]))
17069 (clobber (reg:CC 17))])]
17070 "! optimize_size && ! TARGET_READ_MODIFY"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17074 (clobber (reg:CC 17))])]
17075 "")
17076
17077 ; Don't do logical operations with memory outputs
17078 ;
17079 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17080 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17081 ; the same decoder scheduling characteristics as the original.
17082
17083 (define_peephole2
17084 [(match_scratch:SI 2 "r")
17085 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17086 (match_operator:SI 3 "arith_or_logical_operator"
17087 [(match_dup 0)
17088 (match_operand:SI 1 "nonmemory_operand" "")]))
17089 (clobber (reg:CC 17))])]
17090 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17091 [(set (match_dup 2) (match_dup 0))
17092 (parallel [(set (match_dup 2)
17093 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17094 (clobber (reg:CC 17))])
17095 (set (match_dup 0) (match_dup 2))]
17096 "")
17097
17098 (define_peephole2
17099 [(match_scratch:SI 2 "r")
17100 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17101 (match_operator:SI 3 "arith_or_logical_operator"
17102 [(match_operand:SI 1 "nonmemory_operand" "")
17103 (match_dup 0)]))
17104 (clobber (reg:CC 17))])]
17105 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17106 [(set (match_dup 2) (match_dup 0))
17107 (parallel [(set (match_dup 2)
17108 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17109 (clobber (reg:CC 17))])
17110 (set (match_dup 0) (match_dup 2))]
17111 "")
17112
17113 ;; Attempt to always use XOR for zeroing registers.
17114 (define_peephole2
17115 [(set (match_operand 0 "register_operand" "")
17116 (const_int 0))]
17117 "(GET_MODE (operands[0]) == QImode
17118 || GET_MODE (operands[0]) == HImode
17119 || GET_MODE (operands[0]) == SImode
17120 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17121 && (! TARGET_USE_MOV0 || optimize_size)
17122 && peep2_regno_dead_p (0, FLAGS_REG)"
17123 [(parallel [(set (match_dup 0) (const_int 0))
17124 (clobber (reg:CC 17))])]
17125 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17126 true_regnum (operands[0]));")
17127
17128 (define_peephole2
17129 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17130 (const_int 0))]
17131 "(GET_MODE (operands[0]) == QImode
17132 || GET_MODE (operands[0]) == HImode)
17133 && (! TARGET_USE_MOV0 || optimize_size)
17134 && peep2_regno_dead_p (0, FLAGS_REG)"
17135 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17136 (clobber (reg:CC 17))])])
17137
17138 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17139 (define_peephole2
17140 [(set (match_operand 0 "register_operand" "")
17141 (const_int -1))]
17142 "(GET_MODE (operands[0]) == HImode
17143 || GET_MODE (operands[0]) == SImode
17144 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17145 && (optimize_size || TARGET_PENTIUM)
17146 && peep2_regno_dead_p (0, FLAGS_REG)"
17147 [(parallel [(set (match_dup 0) (const_int -1))
17148 (clobber (reg:CC 17))])]
17149 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17150 true_regnum (operands[0]));")
17151
17152 ;; Attempt to convert simple leas to adds. These can be created by
17153 ;; move expanders.
17154 (define_peephole2
17155 [(set (match_operand:SI 0 "register_operand" "")
17156 (plus:SI (match_dup 0)
17157 (match_operand:SI 1 "nonmemory_operand" "")))]
17158 "peep2_regno_dead_p (0, FLAGS_REG)"
17159 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17160 (clobber (reg:CC 17))])]
17161 "")
17162
17163 (define_peephole2
17164 [(set (match_operand:SI 0 "register_operand" "")
17165 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17166 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17167 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17168 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17169 (clobber (reg:CC 17))])]
17170 "operands[2] = gen_lowpart (SImode, operands[2]);")
17171
17172 (define_peephole2
17173 [(set (match_operand:DI 0 "register_operand" "")
17174 (plus:DI (match_dup 0)
17175 (match_operand:DI 1 "x86_64_general_operand" "")))]
17176 "peep2_regno_dead_p (0, FLAGS_REG)"
17177 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17178 (clobber (reg:CC 17))])]
17179 "")
17180
17181 (define_peephole2
17182 [(set (match_operand:SI 0 "register_operand" "")
17183 (mult:SI (match_dup 0)
17184 (match_operand:SI 1 "const_int_operand" "")))]
17185 "exact_log2 (INTVAL (operands[1])) >= 0
17186 && peep2_regno_dead_p (0, FLAGS_REG)"
17187 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17188 (clobber (reg:CC 17))])]
17189 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17190
17191 (define_peephole2
17192 [(set (match_operand:DI 0 "register_operand" "")
17193 (mult:DI (match_dup 0)
17194 (match_operand:DI 1 "const_int_operand" "")))]
17195 "exact_log2 (INTVAL (operands[1])) >= 0
17196 && peep2_regno_dead_p (0, FLAGS_REG)"
17197 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17198 (clobber (reg:CC 17))])]
17199 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17200
17201 (define_peephole2
17202 [(set (match_operand:SI 0 "register_operand" "")
17203 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17204 (match_operand:DI 2 "const_int_operand" "")) 0))]
17205 "exact_log2 (INTVAL (operands[1])) >= 0
17206 && REGNO (operands[0]) == REGNO (operands[1])
17207 && peep2_regno_dead_p (0, FLAGS_REG)"
17208 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17209 (clobber (reg:CC 17))])]
17210 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17211
17212 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17213 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17214 ;; many CPUs it is also faster, since special hardware to avoid esp
17215 ;; dependencies is present.
17216
17217 ;; While some of these conversions may be done using splitters, we use peepholes
17218 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17219
17220 ;; Convert prologue esp subtractions to push.
17221 ;; We need register to push. In order to keep verify_flow_info happy we have
17222 ;; two choices
17223 ;; - use scratch and clobber it in order to avoid dependencies
17224 ;; - use already live register
17225 ;; We can't use the second way right now, since there is no reliable way how to
17226 ;; verify that given register is live. First choice will also most likely in
17227 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17228 ;; call clobbered registers are dead. We may want to use base pointer as an
17229 ;; alternative when no register is available later.
17230
17231 (define_peephole2
17232 [(match_scratch:SI 0 "r")
17233 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17234 (clobber (reg:CC 17))
17235 (clobber (mem:BLK (scratch)))])]
17236 "optimize_size || !TARGET_SUB_ESP_4"
17237 [(clobber (match_dup 0))
17238 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17239 (clobber (mem:BLK (scratch)))])])
17240
17241 (define_peephole2
17242 [(match_scratch:SI 0 "r")
17243 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17244 (clobber (reg:CC 17))
17245 (clobber (mem:BLK (scratch)))])]
17246 "optimize_size || !TARGET_SUB_ESP_8"
17247 [(clobber (match_dup 0))
17248 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17249 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17250 (clobber (mem:BLK (scratch)))])])
17251
17252 ;; Convert esp subtractions to push.
17253 (define_peephole2
17254 [(match_scratch:SI 0 "r")
17255 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17256 (clobber (reg:CC 17))])]
17257 "optimize_size || !TARGET_SUB_ESP_4"
17258 [(clobber (match_dup 0))
17259 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17260
17261 (define_peephole2
17262 [(match_scratch:SI 0 "r")
17263 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17264 (clobber (reg:CC 17))])]
17265 "optimize_size || !TARGET_SUB_ESP_8"
17266 [(clobber (match_dup 0))
17267 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17268 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17269
17270 ;; Convert epilogue deallocator to pop.
17271 (define_peephole2
17272 [(match_scratch:SI 0 "r")
17273 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17274 (clobber (reg:CC 17))
17275 (clobber (mem:BLK (scratch)))])]
17276 "optimize_size || !TARGET_ADD_ESP_4"
17277 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17278 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17279 (clobber (mem:BLK (scratch)))])]
17280 "")
17281
17282 ;; Two pops case is tricky, since pop causes dependency on destination register.
17283 ;; We use two registers if available.
17284 (define_peephole2
17285 [(match_scratch:SI 0 "r")
17286 (match_scratch:SI 1 "r")
17287 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17288 (clobber (reg:CC 17))
17289 (clobber (mem:BLK (scratch)))])]
17290 "optimize_size || !TARGET_ADD_ESP_8"
17291 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17292 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17293 (clobber (mem:BLK (scratch)))])
17294 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17295 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17296 "")
17297
17298 (define_peephole2
17299 [(match_scratch:SI 0 "r")
17300 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17301 (clobber (reg:CC 17))
17302 (clobber (mem:BLK (scratch)))])]
17303 "optimize_size"
17304 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17305 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17306 (clobber (mem:BLK (scratch)))])
17307 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17308 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17309 "")
17310
17311 ;; Convert esp additions to pop.
17312 (define_peephole2
17313 [(match_scratch:SI 0 "r")
17314 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17315 (clobber (reg:CC 17))])]
17316 ""
17317 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17318 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17319 "")
17320
17321 ;; Two pops case is tricky, since pop causes dependency on destination register.
17322 ;; We use two registers if available.
17323 (define_peephole2
17324 [(match_scratch:SI 0 "r")
17325 (match_scratch:SI 1 "r")
17326 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17327 (clobber (reg:CC 17))])]
17328 ""
17329 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17330 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17331 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17332 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17333 "")
17334
17335 (define_peephole2
17336 [(match_scratch:SI 0 "r")
17337 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17338 (clobber (reg:CC 17))])]
17339 "optimize_size"
17340 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17341 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17342 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17343 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17344 "")
17345 \f
17346 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17347 ;; required and register dies.
17348 (define_peephole2
17349 [(set (reg 17)
17350 (compare (match_operand:SI 0 "register_operand" "")
17351 (match_operand:SI 1 "incdec_operand" "")))]
17352 "ix86_match_ccmode (insn, CCGCmode)
17353 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17354 [(parallel [(set (reg:CCGC 17)
17355 (compare:CCGC (match_dup 0)
17356 (match_dup 1)))
17357 (clobber (match_dup 0))])]
17358 "")
17359
17360 (define_peephole2
17361 [(set (reg 17)
17362 (compare (match_operand:HI 0 "register_operand" "")
17363 (match_operand:HI 1 "incdec_operand" "")))]
17364 "ix86_match_ccmode (insn, CCGCmode)
17365 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17366 [(parallel [(set (reg:CCGC 17)
17367 (compare:CCGC (match_dup 0)
17368 (match_dup 1)))
17369 (clobber (match_dup 0))])]
17370 "")
17371
17372 (define_peephole2
17373 [(set (reg 17)
17374 (compare (match_operand:QI 0 "register_operand" "")
17375 (match_operand:QI 1 "incdec_operand" "")))]
17376 "ix86_match_ccmode (insn, CCGCmode)
17377 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17378 [(parallel [(set (reg:CCGC 17)
17379 (compare:CCGC (match_dup 0)
17380 (match_dup 1)))
17381 (clobber (match_dup 0))])]
17382 "")
17383
17384 ;; Convert compares with 128 to shorter add -128
17385 (define_peephole2
17386 [(set (reg 17)
17387 (compare (match_operand:SI 0 "register_operand" "")
17388 (const_int 128)))]
17389 "ix86_match_ccmode (insn, CCGCmode)
17390 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17391 [(parallel [(set (reg:CCGC 17)
17392 (compare:CCGC (match_dup 0)
17393 (const_int 128)))
17394 (clobber (match_dup 0))])]
17395 "")
17396
17397 (define_peephole2
17398 [(set (reg 17)
17399 (compare (match_operand:HI 0 "register_operand" "")
17400 (const_int 128)))]
17401 "ix86_match_ccmode (insn, CCGCmode)
17402 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17403 [(parallel [(set (reg:CCGC 17)
17404 (compare:CCGC (match_dup 0)
17405 (const_int 128)))
17406 (clobber (match_dup 0))])]
17407 "")
17408 \f
17409 (define_peephole2
17410 [(match_scratch:DI 0 "r")
17411 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17412 (clobber (reg:CC 17))
17413 (clobber (mem:BLK (scratch)))])]
17414 "optimize_size || !TARGET_SUB_ESP_4"
17415 [(clobber (match_dup 0))
17416 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17417 (clobber (mem:BLK (scratch)))])])
17418
17419 (define_peephole2
17420 [(match_scratch:DI 0 "r")
17421 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17422 (clobber (reg:CC 17))
17423 (clobber (mem:BLK (scratch)))])]
17424 "optimize_size || !TARGET_SUB_ESP_8"
17425 [(clobber (match_dup 0))
17426 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17427 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17428 (clobber (mem:BLK (scratch)))])])
17429
17430 ;; Convert esp subtractions to push.
17431 (define_peephole2
17432 [(match_scratch:DI 0 "r")
17433 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17434 (clobber (reg:CC 17))])]
17435 "optimize_size || !TARGET_SUB_ESP_4"
17436 [(clobber (match_dup 0))
17437 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17438
17439 (define_peephole2
17440 [(match_scratch:DI 0 "r")
17441 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17442 (clobber (reg:CC 17))])]
17443 "optimize_size || !TARGET_SUB_ESP_8"
17444 [(clobber (match_dup 0))
17445 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17446 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17447
17448 ;; Convert epilogue deallocator to pop.
17449 (define_peephole2
17450 [(match_scratch:DI 0 "r")
17451 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17452 (clobber (reg:CC 17))
17453 (clobber (mem:BLK (scratch)))])]
17454 "optimize_size || !TARGET_ADD_ESP_4"
17455 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17456 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17457 (clobber (mem:BLK (scratch)))])]
17458 "")
17459
17460 ;; Two pops case is tricky, since pop causes dependency on destination register.
17461 ;; We use two registers if available.
17462 (define_peephole2
17463 [(match_scratch:DI 0 "r")
17464 (match_scratch:DI 1 "r")
17465 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17466 (clobber (reg:CC 17))
17467 (clobber (mem:BLK (scratch)))])]
17468 "optimize_size || !TARGET_ADD_ESP_8"
17469 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17470 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17471 (clobber (mem:BLK (scratch)))])
17472 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17473 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17474 "")
17475
17476 (define_peephole2
17477 [(match_scratch:DI 0 "r")
17478 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17479 (clobber (reg:CC 17))
17480 (clobber (mem:BLK (scratch)))])]
17481 "optimize_size"
17482 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17483 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17484 (clobber (mem:BLK (scratch)))])
17485 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17486 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17487 "")
17488
17489 ;; Convert esp additions to pop.
17490 (define_peephole2
17491 [(match_scratch:DI 0 "r")
17492 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17493 (clobber (reg:CC 17))])]
17494 ""
17495 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17496 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17497 "")
17498
17499 ;; Two pops case is tricky, since pop causes dependency on destination register.
17500 ;; We use two registers if available.
17501 (define_peephole2
17502 [(match_scratch:DI 0 "r")
17503 (match_scratch:DI 1 "r")
17504 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17505 (clobber (reg:CC 17))])]
17506 ""
17507 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17508 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17509 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17510 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17511 "")
17512
17513 (define_peephole2
17514 [(match_scratch:DI 0 "r")
17515 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17516 (clobber (reg:CC 17))])]
17517 "optimize_size"
17518 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17519 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17520 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17521 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17522 "")
17523 \f
17524 ;; Call-value patterns last so that the wildcard operand does not
17525 ;; disrupt insn-recog's switch tables.
17526
17527 (define_insn "*call_value_pop_0"
17528 [(set (match_operand 0 "" "")
17529 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17530 (match_operand:SI 2 "" "")))
17531 (set (reg:SI 7) (plus:SI (reg:SI 7)
17532 (match_operand:SI 3 "immediate_operand" "")))]
17533 "!TARGET_64BIT"
17534 {
17535 if (SIBLING_CALL_P (insn))
17536 return "jmp\t%P1";
17537 else
17538 return "call\t%P1";
17539 }
17540 [(set_attr "type" "callv")])
17541
17542 (define_insn "*call_value_pop_1"
17543 [(set (match_operand 0 "" "")
17544 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17545 (match_operand:SI 2 "" "")))
17546 (set (reg:SI 7) (plus:SI (reg:SI 7)
17547 (match_operand:SI 3 "immediate_operand" "i")))]
17548 "!TARGET_64BIT"
17549 {
17550 if (constant_call_address_operand (operands[1], QImode))
17551 {
17552 if (SIBLING_CALL_P (insn))
17553 return "jmp\t%P1";
17554 else
17555 return "call\t%P1";
17556 }
17557 if (SIBLING_CALL_P (insn))
17558 return "jmp\t%A1";
17559 else
17560 return "call\t%A1";
17561 }
17562 [(set_attr "type" "callv")])
17563
17564 (define_insn "*call_value_0"
17565 [(set (match_operand 0 "" "")
17566 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17567 (match_operand:SI 2 "" "")))]
17568 "!TARGET_64BIT"
17569 {
17570 if (SIBLING_CALL_P (insn))
17571 return "jmp\t%P1";
17572 else
17573 return "call\t%P1";
17574 }
17575 [(set_attr "type" "callv")])
17576
17577 (define_insn "*call_value_0_rex64"
17578 [(set (match_operand 0 "" "")
17579 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17580 (match_operand:DI 2 "const_int_operand" "")))]
17581 "TARGET_64BIT"
17582 {
17583 if (SIBLING_CALL_P (insn))
17584 return "jmp\t%P1";
17585 else
17586 return "call\t%P1";
17587 }
17588 [(set_attr "type" "callv")])
17589
17590 (define_insn "*call_value_1"
17591 [(set (match_operand 0 "" "")
17592 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17593 (match_operand:SI 2 "" "")))]
17594 "!TARGET_64BIT"
17595 {
17596 if (constant_call_address_operand (operands[1], QImode))
17597 {
17598 if (SIBLING_CALL_P (insn))
17599 return "jmp\t%P1";
17600 else
17601 return "call\t%P1";
17602 }
17603 if (SIBLING_CALL_P (insn))
17604 return "jmp\t%*%1";
17605 else
17606 return "call\t%*%1";
17607 }
17608 [(set_attr "type" "callv")])
17609
17610 (define_insn "*call_value_1_rex64"
17611 [(set (match_operand 0 "" "")
17612 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17613 (match_operand:DI 2 "" "")))]
17614 "TARGET_64BIT"
17615 {
17616 if (constant_call_address_operand (operands[1], QImode))
17617 {
17618 if (SIBLING_CALL_P (insn))
17619 return "jmp\t%P1";
17620 else
17621 return "call\t%P1";
17622 }
17623 if (SIBLING_CALL_P (insn))
17624 return "jmp\t%A1";
17625 else
17626 return "call\t%A1";
17627 }
17628 [(set_attr "type" "callv")])
17629 \f
17630 (define_insn "trap"
17631 [(trap_if (const_int 1) (const_int 5))]
17632 ""
17633 "int\t$5")
17634
17635 ;;; ix86 doesn't have conditional trap instructions, but we fake them
17636 ;;; for the sake of bounds checking. By emitting bounds checks as
17637 ;;; conditional traps rather than as conditional jumps around
17638 ;;; unconditional traps we avoid introducing spurious basic-block
17639 ;;; boundaries and facilitate elimination of redundant checks. In
17640 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17641 ;;; interrupt 5.
17642 ;;;
17643 ;;; FIXME: Static branch prediction rules for ix86 are such that
17644 ;;; forward conditional branches predict as untaken. As implemented
17645 ;;; below, pseudo conditional traps violate that rule. We should use
17646 ;;; .pushsection/.popsection to place all of the `int 5's in a special
17647 ;;; section loaded at the end of the text segment and branch forward
17648 ;;; there on bounds-failure, and then jump back immediately (in case
17649 ;;; the system chooses to ignore bounds violations, or to report
17650 ;;; violations and continue execution).
17651
17652 (define_expand "conditional_trap"
17653 [(trap_if (match_operator 0 "comparison_operator"
17654 [(match_dup 2) (const_int 0)])
17655 (match_operand 1 "const_int_operand" ""))]
17656 ""
17657 {
17658 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17659 ix86_expand_compare (GET_CODE (operands[0]),
17660 NULL, NULL),
17661 operands[1]));
17662 DONE;
17663 })
17664
17665 (define_insn "*conditional_trap_1"
17666 [(trap_if (match_operator 0 "comparison_operator"
17667 [(reg 17) (const_int 0)])
17668 (match_operand 1 "const_int_operand" ""))]
17669 ""
17670 {
17671 operands[2] = gen_label_rtx ();
17672 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17673 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17674 CODE_LABEL_NUMBER (operands[2]));
17675 RET;
17676 })
17677
17678 ;; Pentium III SIMD instructions.
17679
17680 ;; Moves for SSE/MMX regs.
17681
17682 (define_insn "movv4sf_internal"
17683 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17684 (match_operand:V4SF 1 "general_operand" "xm,x"))]
17685 "TARGET_SSE"
17686 ;; @@@ let's try to use movaps here.
17687 "movaps\t{%1, %0|%0, %1}"
17688 [(set_attr "type" "sse")])
17689
17690 (define_insn "movv4si_internal"
17691 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17692 (match_operand:V4SI 1 "general_operand" "xm,x"))]
17693 "TARGET_SSE"
17694 ;; @@@ let's try to use movaps here.
17695 "movaps\t{%1, %0|%0, %1}"
17696 [(set_attr "type" "sse")])
17697
17698 (define_insn "movv8qi_internal"
17699 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17700 (match_operand:V8QI 1 "general_operand" "ym,y"))]
17701 "TARGET_MMX"
17702 "movq\t{%1, %0|%0, %1}"
17703 [(set_attr "type" "mmx")])
17704
17705 (define_insn "movv4hi_internal"
17706 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17707 (match_operand:V4HI 1 "general_operand" "ym,y"))]
17708 "TARGET_MMX"
17709 "movq\t{%1, %0|%0, %1}"
17710 [(set_attr "type" "mmx")])
17711
17712 (define_insn "movv2si_internal"
17713 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17714 (match_operand:V2SI 1 "general_operand" "ym,y"))]
17715 "TARGET_MMX"
17716 "movq\t{%1, %0|%0, %1}"
17717 [(set_attr "type" "mmx")])
17718
17719 (define_insn "movv2sf_internal"
17720 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17721 (match_operand:V2SF 1 "general_operand" "ym,y"))]
17722 "TARGET_3DNOW"
17723 "movq\\t{%1, %0|%0, %1}"
17724 [(set_attr "type" "mmx")])
17725
17726 (define_expand "movti"
17727 [(set (match_operand:TI 0 "general_operand" "")
17728 (match_operand:TI 1 "general_operand" ""))]
17729 "TARGET_SSE || TARGET_64BIT"
17730 {
17731 if (TARGET_64BIT)
17732 {
17733 ix86_expand_move (TImode, operands);
17734 DONE;
17735 }
17736 /* For constants other than zero into memory. We do not know how the
17737 instructions used to build constants modify the upper 64 bits
17738 of the register, once we have that information we may be able
17739 to handle some of them more efficiently. */
17740 if ((reload_in_progress | reload_completed) == 0
17741 && register_operand (operands[0], TImode)
17742 && CONSTANT_P (operands[1]))
17743 {
17744 rtx addr = gen_reg_rtx (Pmode);
17745
17746 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
17747 operands[1] = gen_rtx_MEM (TImode, addr);
17748 }
17749
17750 /* Make operand1 a register if it isn't already. */
17751 if ((reload_in_progress | reload_completed) == 0
17752 && !register_operand (operands[0], TImode)
17753 && !register_operand (operands[1], TImode)
17754 && operands[1] != CONST0_RTX (TImode))
17755 {
17756 rtx temp = force_reg (TImode, operands[1]);
17757 emit_move_insn (operands[0], temp);
17758 DONE;
17759 }
17760 })
17761
17762 (define_expand "movv4sf"
17763 [(set (match_operand:V4SF 0 "general_operand" "")
17764 (match_operand:V4SF 1 "general_operand" ""))]
17765 "TARGET_SSE"
17766 {
17767 /* For constants other than zero into memory. We do not know how the
17768 instructions used to build constants modify the upper 64 bits
17769 of the register, once we have that information we may be able
17770 to handle some of them more efficiently. */
17771 if ((reload_in_progress | reload_completed) == 0
17772 && register_operand (operands[0], V4SFmode)
17773 && CONSTANT_P (operands[1]))
17774 {
17775 rtx addr = gen_reg_rtx (Pmode);
17776
17777 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
17778 operands[1] = gen_rtx_MEM (V4SFmode, addr);
17779 }
17780
17781 /* Make operand1 a register if it isn't already. */
17782 if ((reload_in_progress | reload_completed) == 0
17783 && !register_operand (operands[0], V4SFmode)
17784 && !register_operand (operands[1], V4SFmode)
17785 && operands[1] != CONST0_RTX (V4SFmode))
17786 {
17787 rtx temp = force_reg (V4SFmode, operands[1]);
17788 emit_move_insn (operands[0], temp);
17789 DONE;
17790 }
17791 })
17792
17793 (define_expand "movv4si"
17794 [(set (match_operand:V4SI 0 "general_operand" "")
17795 (match_operand:V4SI 1 "general_operand" ""))]
17796 "TARGET_MMX"
17797 {
17798 /* For constants other than zero into memory. We do not know how the
17799 instructions used to build constants modify the upper 64 bits
17800 of the register, once we have that information we may be able
17801 to handle some of them more efficiently. */
17802 if ((reload_in_progress | reload_completed) == 0
17803 && register_operand (operands[0], V4SImode)
17804 && CONSTANT_P (operands[1]))
17805 {
17806 rtx addr = gen_reg_rtx (Pmode);
17807
17808 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
17809 operands[1] = gen_rtx_MEM (V4SImode, addr);
17810 }
17811
17812 /* Make operand1 a register if it isn't already. */
17813 if ((reload_in_progress | reload_completed) == 0
17814 && !register_operand (operands[0], V4SImode)
17815 && !register_operand (operands[1], V4SImode)
17816 && operands[1] != CONST0_RTX (V4SImode))
17817 {
17818 rtx temp = force_reg (V4SImode, operands[1]);
17819 emit_move_insn (operands[0], temp);
17820 DONE;
17821 }
17822 })
17823
17824 (define_expand "movv2si"
17825 [(set (match_operand:V2SI 0 "general_operand" "")
17826 (match_operand:V2SI 1 "general_operand" ""))]
17827 "TARGET_MMX"
17828 {
17829 /* For constants other than zero into memory. We do not know how the
17830 instructions used to build constants modify the upper 64 bits
17831 of the register, once we have that information we may be able
17832 to handle some of them more efficiently. */
17833 if ((reload_in_progress | reload_completed) == 0
17834 && register_operand (operands[0], V2SImode)
17835 && CONSTANT_P (operands[1]))
17836 {
17837 rtx addr = gen_reg_rtx (Pmode);
17838
17839 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
17840 operands[1] = gen_rtx_MEM (V2SImode, addr);
17841 }
17842
17843 /* Make operand1 a register if it isn't already. */
17844 if ((reload_in_progress | reload_completed) == 0
17845 && !register_operand (operands[0], V2SImode)
17846 && !register_operand (operands[1], V2SImode)
17847 && operands[1] != CONST0_RTX (V2SImode))
17848 {
17849 rtx temp = force_reg (V2SImode, operands[1]);
17850 emit_move_insn (operands[0], temp);
17851 DONE;
17852 }
17853 })
17854
17855 (define_expand "movv4hi"
17856 [(set (match_operand:V4HI 0 "general_operand" "")
17857 (match_operand:V4HI 1 "general_operand" ""))]
17858 "TARGET_MMX"
17859 {
17860 /* For constants other than zero into memory. We do not know how the
17861 instructions used to build constants modify the upper 64 bits
17862 of the register, once we have that information we may be able
17863 to handle some of them more efficiently. */
17864 if ((reload_in_progress | reload_completed) == 0
17865 && register_operand (operands[0], V4HImode)
17866 && CONSTANT_P (operands[1]))
17867 {
17868 rtx addr = gen_reg_rtx (Pmode);
17869
17870 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
17871 operands[1] = gen_rtx_MEM (V4HImode, addr);
17872 }
17873
17874 /* Make operand1 a register if it isn't already. */
17875 if ((reload_in_progress | reload_completed) == 0
17876 && !register_operand (operands[0], V4HImode)
17877 && !register_operand (operands[1], V4HImode)
17878 && operands[1] != CONST0_RTX (V4HImode))
17879 {
17880 rtx temp = force_reg (V4HImode, operands[1]);
17881 emit_move_insn (operands[0], temp);
17882 DONE;
17883 }
17884 })
17885
17886 (define_expand "movv8qi"
17887 [(set (match_operand:V8QI 0 "general_operand" "")
17888 (match_operand:V8QI 1 "general_operand" ""))]
17889 "TARGET_MMX"
17890 {
17891 /* For constants other than zero into memory. We do not know how the
17892 instructions used to build constants modify the upper 64 bits
17893 of the register, once we have that information we may be able
17894 to handle some of them more efficiently. */
17895 if ((reload_in_progress | reload_completed) == 0
17896 && register_operand (operands[0], V8QImode)
17897 && CONSTANT_P (operands[1]))
17898 {
17899 rtx addr = gen_reg_rtx (Pmode);
17900
17901 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
17902 operands[1] = gen_rtx_MEM (V8QImode, addr);
17903 }
17904
17905 /* Make operand1 a register if it isn't already. */
17906 if ((reload_in_progress | reload_completed) == 0
17907 && !register_operand (operands[0], V8QImode)
17908 && !register_operand (operands[1], V8QImode)
17909 && operands[1] != CONST0_RTX (V8QImode))
17910 {
17911 rtx temp = force_reg (V8QImode, operands[1]);
17912 emit_move_insn (operands[0], temp);
17913 DONE;
17914 }
17915 })
17916
17917 (define_expand "movv2sf"
17918 [(set (match_operand:V2SF 0 "general_operand" "")
17919 (match_operand:V2SF 1 "general_operand" ""))]
17920 "TARGET_3DNOW"
17921 "
17922 {
17923 /* For constants other than zero into memory. We do not know how the
17924 instructions used to build constants modify the upper 64 bits
17925 of the register, once we have that information we may be able
17926 to handle some of them more efficiently. */
17927 if ((reload_in_progress | reload_completed) == 0
17928 && register_operand (operands[0], V2SFmode)
17929 && CONSTANT_P (operands[1]))
17930 {
17931 rtx addr = gen_reg_rtx (Pmode);
17932
17933 emit_move_insn (addr,
17934 XEXP (force_const_mem (V2SFmode, operands[1]), 0));
17935 operands[1] = gen_rtx_MEM (V2SFmode, addr);
17936 }
17937
17938 /* Make operand1 a register is it isn't already. */
17939 if ((reload_in_progress | reload_completed) == 0
17940 && !register_operand (operands[0], V2SFmode)
17941 && !register_operand (operands[1], V2SFmode)
17942 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
17943 && operands[1] != CONST0_RTX (V2SFmode))
17944 {
17945 rtx temp = force_reg (V2SFmode, operands[1]);
17946 emit_move_insn (operands[0], temp);
17947 DONE;
17948 }
17949 }")
17950
17951 (define_insn_and_split "*pushti"
17952 [(set (match_operand:TI 0 "push_operand" "=<")
17953 (match_operand:TI 1 "nonmemory_operand" "x"))]
17954 "TARGET_SSE"
17955 "#"
17956 ""
17957 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17958 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17959 ""
17960 [(set_attr "type" "sse")])
17961
17962 (define_insn_and_split "*pushv4sf"
17963 [(set (match_operand:V4SF 0 "push_operand" "=<")
17964 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17965 "TARGET_SSE"
17966 "#"
17967 ""
17968 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17969 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17970 ""
17971 [(set_attr "type" "sse")])
17972
17973 (define_insn_and_split "*pushv4si"
17974 [(set (match_operand:V4SI 0 "push_operand" "=<")
17975 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17976 "TARGET_SSE"
17977 "#"
17978 ""
17979 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17980 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17981 ""
17982 [(set_attr "type" "sse")])
17983
17984 (define_insn_and_split "*pushv2si"
17985 [(set (match_operand:V2SI 0 "push_operand" "=<")
17986 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17987 "TARGET_MMX"
17988 "#"
17989 ""
17990 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17991 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17992 ""
17993 [(set_attr "type" "mmx")])
17994
17995 (define_insn_and_split "*pushv4hi"
17996 [(set (match_operand:V4HI 0 "push_operand" "=<")
17997 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17998 "TARGET_MMX"
17999 "#"
18000 ""
18001 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18002 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
18003 ""
18004 [(set_attr "type" "mmx")])
18005
18006 (define_insn_and_split "*pushv8qi"
18007 [(set (match_operand:V8QI 0 "push_operand" "=<")
18008 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
18009 "TARGET_MMX"
18010 "#"
18011 ""
18012 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18013 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
18014 ""
18015 [(set_attr "type" "mmx")])
18016
18017 (define_insn_and_split "*pushv2sf"
18018 [(set (match_operand:V2SF 0 "push_operand" "=<")
18019 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
18020 "TARGET_3DNOW"
18021 "#"
18022 ""
18023 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18024 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
18025 ""
18026 [(set_attr "type" "mmx")])
18027
18028 (define_insn "movti_internal"
18029 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
18030 (match_operand:TI 1 "general_operand" "xm,x"))]
18031 "TARGET_SSE && !TARGET_64BIT"
18032 "@
18033 movaps\t{%1, %0|%0, %1}
18034 movaps\t{%1, %0|%0, %1}"
18035 [(set_attr "type" "sse")])
18036
18037 (define_insn "*movti_rex64"
18038 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,mx,x")
18039 (match_operand:TI 1 "general_operand" "riFo,riF,x,m"))]
18040 "TARGET_64BIT
18041 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18042 "@
18043 #
18044 #
18045 movaps\\t{%1, %0|%0, %1}
18046 movaps\\t{%1, %0|%0, %1}"
18047 [(set_attr "type" "*,*,sse,sse")
18048 (set_attr "mode" "TI")])
18049
18050 (define_split
18051 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18052 (match_operand:TI 1 "general_operand" ""))]
18053 "reload_completed && !SSE_REG_P (operands[0])
18054 && !SSE_REG_P (operands[1])"
18055 [(const_int 0)]
18056 "ix86_split_long_move (operands); DONE;")
18057
18058 ;; These two patterns are useful for specifying exactly whether to use
18059 ;; movaps or movups
18060 (define_insn "sse_movaps"
18061 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18062 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
18063 "TARGET_SSE"
18064 "@
18065 movaps\t{%1, %0|%0, %1}
18066 movaps\t{%1, %0|%0, %1}"
18067 [(set_attr "type" "sse")])
18068
18069 (define_insn "sse_movups"
18070 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18071 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
18072 "TARGET_SSE"
18073 "@
18074 movups\t{%1, %0|%0, %1}
18075 movups\t{%1, %0|%0, %1}"
18076 [(set_attr "type" "sse")])
18077
18078
18079 ;; SSE Strange Moves.
18080
18081 (define_insn "sse_movmskps"
18082 [(set (match_operand:SI 0 "register_operand" "=r")
18083 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
18084 "TARGET_SSE"
18085 "movmskps\t{%1, %0|%0, %1}"
18086 [(set_attr "type" "sse")])
18087
18088 (define_insn "mmx_pmovmskb"
18089 [(set (match_operand:SI 0 "register_operand" "=r")
18090 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
18091 "TARGET_SSE || TARGET_3DNOW_A"
18092 "pmovmskb\t{%1, %0|%0, %1}"
18093 [(set_attr "type" "sse")])
18094
18095 (define_insn "mmx_maskmovq"
18096 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
18097 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
18098 (match_operand:V8QI 2 "register_operand" "y")] 32))]
18099 "TARGET_SSE || TARGET_3DNOW_A"
18100 ;; @@@ check ordering of operands in intel/nonintel syntax
18101 "maskmovq\t{%2, %1|%1, %2}"
18102 [(set_attr "type" "sse")])
18103
18104 (define_insn "sse_movntv4sf"
18105 [(set (match_operand:V4SF 0 "memory_operand" "=m")
18106 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
18107 "TARGET_SSE"
18108 "movntps\t{%1, %0|%0, %1}"
18109 [(set_attr "type" "sse")])
18110
18111 (define_insn "sse_movntdi"
18112 [(set (match_operand:DI 0 "memory_operand" "=m")
18113 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
18114 "TARGET_SSE || TARGET_3DNOW_A"
18115 "movntq\t{%1, %0|%0, %1}"
18116 [(set_attr "type" "sse")])
18117
18118 (define_insn "sse_movhlps"
18119 [(set (match_operand:V4SF 0 "register_operand" "=x")
18120 (vec_merge:V4SF
18121 (match_operand:V4SF 1 "register_operand" "0")
18122 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18123 (parallel [(const_int 2)
18124 (const_int 3)
18125 (const_int 0)
18126 (const_int 1)]))
18127 (const_int 3)))]
18128 "TARGET_SSE"
18129 "movhlps\t{%2, %0|%0, %2}"
18130 [(set_attr "type" "sse")])
18131
18132 (define_insn "sse_movlhps"
18133 [(set (match_operand:V4SF 0 "register_operand" "=x")
18134 (vec_merge:V4SF
18135 (match_operand:V4SF 1 "register_operand" "0")
18136 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18137 (parallel [(const_int 2)
18138 (const_int 3)
18139 (const_int 0)
18140 (const_int 1)]))
18141 (const_int 12)))]
18142 "TARGET_SSE"
18143 "movlhps\t{%2, %0|%0, %2}"
18144 [(set_attr "type" "sse")])
18145
18146 (define_insn "sse_movhps"
18147 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18148 (vec_merge:V4SF
18149 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18150 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18151 (const_int 12)))]
18152 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18153 "movhps\t{%2, %0|%0, %2}"
18154 [(set_attr "type" "sse")])
18155
18156 (define_insn "sse_movlps"
18157 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
18158 (vec_merge:V4SF
18159 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
18160 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
18161 (const_int 3)))]
18162 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
18163 "movlps\t{%2, %0|%0, %2}"
18164 [(set_attr "type" "sse")])
18165
18166 (define_insn "sse_loadss"
18167 [(set (match_operand:V4SF 0 "register_operand" "=x")
18168 (vec_merge:V4SF
18169 (match_operand:V4SF 1 "memory_operand" "m")
18170 (vec_duplicate:V4SF (float:SF (const_int 0)))
18171 (const_int 1)))]
18172 "TARGET_SSE"
18173 "movss\t{%1, %0|%0, %1}"
18174 [(set_attr "type" "sse")])
18175
18176 (define_insn "sse_movss"
18177 [(set (match_operand:V4SF 0 "register_operand" "=x")
18178 (vec_merge:V4SF
18179 (match_operand:V4SF 1 "register_operand" "0")
18180 (match_operand:V4SF 2 "register_operand" "x")
18181 (const_int 1)))]
18182 "TARGET_SSE"
18183 "movss\t{%2, %0|%0, %2}"
18184 [(set_attr "type" "sse")])
18185
18186 (define_insn "sse_storess"
18187 [(set (match_operand:SF 0 "memory_operand" "=m")
18188 (vec_select:SF
18189 (match_operand:V4SF 1 "register_operand" "x")
18190 (parallel [(const_int 0)])))]
18191 "TARGET_SSE"
18192 "movss\t{%1, %0|%0, %1}"
18193 [(set_attr "type" "sse")])
18194
18195 (define_insn "sse_shufps"
18196 [(set (match_operand:V4SF 0 "register_operand" "=x")
18197 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
18198 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
18199 (match_operand:SI 3 "immediate_operand" "i")] 41))]
18200 "TARGET_SSE"
18201 ;; @@@ check operand order for intel/nonintel syntax
18202 "shufps\t{%3, %2, %0|%0, %2, %3}"
18203 [(set_attr "type" "sse")])
18204
18205
18206 ;; SSE arithmetic
18207
18208 (define_insn "addv4sf3"
18209 [(set (match_operand:V4SF 0 "register_operand" "=x")
18210 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18211 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18212 "TARGET_SSE"
18213 "addps\t{%2, %0|%0, %2}"
18214 [(set_attr "type" "sse")])
18215
18216 (define_insn "vmaddv4sf3"
18217 [(set (match_operand:V4SF 0 "register_operand" "=x")
18218 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18219 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18220 (match_dup 1)
18221 (const_int 1)))]
18222 "TARGET_SSE"
18223 "addss\t{%2, %0|%0, %2}"
18224 [(set_attr "type" "sse")])
18225
18226 (define_insn "subv4sf3"
18227 [(set (match_operand:V4SF 0 "register_operand" "=x")
18228 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18229 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18230 "TARGET_SSE"
18231 "subps\t{%2, %0|%0, %2}"
18232 [(set_attr "type" "sse")])
18233
18234 (define_insn "vmsubv4sf3"
18235 [(set (match_operand:V4SF 0 "register_operand" "=x")
18236 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
18237 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18238 (match_dup 1)
18239 (const_int 1)))]
18240 "TARGET_SSE"
18241 "subss\t{%2, %0|%0, %2}"
18242 [(set_attr "type" "sse")])
18243
18244 (define_insn "mulv4sf3"
18245 [(set (match_operand:V4SF 0 "register_operand" "=x")
18246 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18247 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18248 "TARGET_SSE"
18249 "mulps\t{%2, %0|%0, %2}"
18250 [(set_attr "type" "sse")])
18251
18252 (define_insn "vmmulv4sf3"
18253 [(set (match_operand:V4SF 0 "register_operand" "=x")
18254 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
18255 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18256 (match_dup 1)
18257 (const_int 1)))]
18258 "TARGET_SSE"
18259 "mulss\t{%2, %0|%0, %2}"
18260 [(set_attr "type" "sse")])
18261
18262 (define_insn "divv4sf3"
18263 [(set (match_operand:V4SF 0 "register_operand" "=x")
18264 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18265 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18266 "TARGET_SSE"
18267 "divps\t{%2, %0|%0, %2}"
18268 [(set_attr "type" "sse")])
18269
18270 (define_insn "vmdivv4sf3"
18271 [(set (match_operand:V4SF 0 "register_operand" "=x")
18272 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18273 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18274 (match_dup 1)
18275 (const_int 1)))]
18276 "TARGET_SSE"
18277 "divss\t{%2, %0|%0, %2}"
18278 [(set_attr "type" "sse")])
18279
18280
18281 ;; SSE square root/reciprocal
18282
18283 (define_insn "rcpv4sf2"
18284 [(set (match_operand:V4SF 0 "register_operand" "=x")
18285 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
18286 "TARGET_SSE"
18287 "rcpps\t{%1, %0|%0, %1}"
18288 [(set_attr "type" "sse")])
18289
18290 (define_insn "vmrcpv4sf2"
18291 [(set (match_operand:V4SF 0 "register_operand" "=x")
18292 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
18293 (match_operand:V4SF 2 "register_operand" "0")
18294 (const_int 1)))]
18295 "TARGET_SSE"
18296 "rcpss\t{%1, %0|%0, %1}"
18297 [(set_attr "type" "sse")])
18298
18299 (define_insn "rsqrtv4sf2"
18300 [(set (match_operand:V4SF 0 "register_operand" "=x")
18301 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
18302 "TARGET_SSE"
18303 "rsqrtps\t{%1, %0|%0, %1}"
18304 [(set_attr "type" "sse")])
18305
18306 (define_insn "vmrsqrtv4sf2"
18307 [(set (match_operand:V4SF 0 "register_operand" "=x")
18308 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
18309 (match_operand:V4SF 2 "register_operand" "0")
18310 (const_int 1)))]
18311 "TARGET_SSE"
18312 "rsqrtss\t{%1, %0|%0, %1}"
18313 [(set_attr "type" "sse")])
18314
18315 (define_insn "sqrtv4sf2"
18316 [(set (match_operand:V4SF 0 "register_operand" "=x")
18317 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
18318 "TARGET_SSE"
18319 "sqrtps\t{%1, %0|%0, %1}"
18320 [(set_attr "type" "sse")])
18321
18322 (define_insn "vmsqrtv4sf2"
18323 [(set (match_operand:V4SF 0 "register_operand" "=x")
18324 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
18325 (match_operand:V4SF 2 "register_operand" "0")
18326 (const_int 1)))]
18327 "TARGET_SSE"
18328 "sqrtss\t{%1, %0|%0, %1}"
18329 [(set_attr "type" "sse")])
18330
18331
18332 ;; SSE logical operations.
18333
18334 ;; These are not called andti3 etc. because we really really don't want
18335 ;; the compiler to widen DImode ands to TImode ands and then try to move
18336 ;; into DImode subregs of SSE registers, and them together, and move out
18337 ;; of DImode subregs again!
18338
18339 (define_insn "*sse_andti3_df_1"
18340 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18341 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18342 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18343 "TARGET_SSE2"
18344 "andpd\t{%2, %0|%0, %2}"
18345 [(set_attr "type" "sse")])
18346
18347 (define_insn "*sse_andti3_df_2"
18348 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18349 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18350 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18351 "TARGET_SSE2"
18352 "andpd\t{%2, %0|%0, %2}"
18353 [(set_attr "type" "sse")])
18354
18355 (define_insn "*sse_andti3_sf_1"
18356 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18357 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18358 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18359 "TARGET_SSE"
18360 "andps\t{%2, %0|%0, %2}"
18361 [(set_attr "type" "sse")])
18362
18363 (define_insn "*sse_andti3_sf_2"
18364 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18365 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18366 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18367 "TARGET_SSE"
18368 "andps\t{%2, %0|%0, %2}"
18369 [(set_attr "type" "sse")])
18370
18371 (define_insn "sse_andti3"
18372 [(set (match_operand:TI 0 "register_operand" "=x")
18373 (and:TI (match_operand:TI 1 "register_operand" "%0")
18374 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18375 "TARGET_SSE && !TARGET_SSE2"
18376 "andps\t{%2, %0|%0, %2}"
18377 [(set_attr "type" "sse")])
18378
18379 (define_insn "*sse_andti3_sse2"
18380 [(set (match_operand:TI 0 "register_operand" "=x")
18381 (and:TI (match_operand:TI 1 "register_operand" "%0")
18382 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18383 "TARGET_SSE2"
18384 "pand\t{%2, %0|%0, %2}"
18385 [(set_attr "type" "sse")])
18386
18387 (define_insn "*sse_nandti3_df"
18388 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18389 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18390 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18391 "TARGET_SSE2"
18392 "andnpd\t{%2, %0|%0, %2}"
18393 [(set_attr "type" "sse")])
18394
18395 (define_insn "*sse_nandti3_sf"
18396 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18397 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18398 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18399 "TARGET_SSE"
18400 "andnps\t{%2, %0|%0, %2}"
18401 [(set_attr "type" "sse")])
18402
18403 (define_insn "sse_nandti3"
18404 [(set (match_operand:TI 0 "register_operand" "=x")
18405 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18406 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18407 "TARGET_SSE && !TARGET_SSE2"
18408 "andnps\t{%2, %0|%0, %2}"
18409 [(set_attr "type" "sse")])
18410
18411 (define_insn "*sse_nandti3_sse2"
18412 [(set (match_operand:TI 0 "register_operand" "=x")
18413 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18414 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18415 "TARGET_SSE2"
18416 "pnand\t{%2, %0|%0, %2}"
18417 [(set_attr "type" "sse")])
18418
18419 (define_insn "*sse_iorti3_df_1"
18420 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18421 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18422 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18423 "TARGET_SSE2"
18424 "orpd\t{%2, %0|%0, %2}"
18425 [(set_attr "type" "sse")])
18426
18427 (define_insn "*sse_iorti3_df_2"
18428 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18429 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18430 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18431 "TARGET_SSE2"
18432 "orpd\t{%2, %0|%0, %2}"
18433 [(set_attr "type" "sse")])
18434
18435 (define_insn "*sse_iorti3_sf_1"
18436 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18437 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18438 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18439 "TARGET_SSE"
18440 "orps\t{%2, %0|%0, %2}"
18441 [(set_attr "type" "sse")])
18442
18443 (define_insn "*sse_iorti3_sf_2"
18444 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18445 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18446 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18447 "TARGET_SSE"
18448 "orps\t{%2, %0|%0, %2}"
18449 [(set_attr "type" "sse")])
18450
18451 (define_insn "sse_iorti3"
18452 [(set (match_operand:TI 0 "register_operand" "=x")
18453 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18454 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18455 "TARGET_SSE && !TARGET_SSE2"
18456 "orps\t{%2, %0|%0, %2}"
18457 [(set_attr "type" "sse")])
18458
18459 (define_insn "*sse_iorti3_sse2"
18460 [(set (match_operand:TI 0 "register_operand" "=x")
18461 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18462 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18463 "TARGET_SSE2"
18464 "por\t{%2, %0|%0, %2}"
18465 [(set_attr "type" "sse")])
18466
18467 (define_insn "*sse_xorti3_df_1"
18468 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18469 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18470 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18471 "TARGET_SSE2"
18472 "xorpd\t{%2, %0|%0, %2}"
18473 [(set_attr "type" "sse")])
18474
18475 (define_insn "*sse_xorti3_df_2"
18476 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18477 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18478 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18479 "TARGET_SSE2"
18480 "xorpd\t{%2, %0|%0, %2}"
18481 [(set_attr "type" "sse")])
18482
18483 (define_insn "*sse_xorti3_sf_1"
18484 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18485 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18486 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18487 "TARGET_SSE"
18488 "xorps\t{%2, %0|%0, %2}"
18489 [(set_attr "type" "sse")])
18490
18491 (define_insn "*sse_xorti3_sf_2"
18492 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18493 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18494 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18495 "TARGET_SSE"
18496 "xorps\t{%2, %0|%0, %2}"
18497 [(set_attr "type" "sse")])
18498
18499 (define_insn "sse_xorti3"
18500 [(set (match_operand:TI 0 "register_operand" "=x")
18501 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18502 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18503 "TARGET_SSE && !TARGET_SSE2"
18504 "xorps\t{%2, %0|%0, %2}"
18505 [(set_attr "type" "sse")])
18506
18507 (define_insn "*sse_xorti3_sse2"
18508 [(set (match_operand:TI 0 "register_operand" "=x")
18509 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18510 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18511 "TARGET_SSE2"
18512 "pxor\t{%2, %0|%0, %2}"
18513 [(set_attr "type" "sse")])
18514
18515 ;; Use xor, but don't show input operands so they aren't live before
18516 ;; this insn.
18517 (define_insn "sse_clrti"
18518 [(set (match_operand:TI 0 "register_operand" "=x")
18519 (unspec:TI [(const_int 0)] 45))]
18520 "TARGET_SSE"
18521 "xorps\t{%0, %0|%0, %0}"
18522 [(set_attr "type" "sse")
18523 (set_attr "memory" "none")])
18524
18525 ;; SSE mask-generating compares
18526
18527 (define_insn "maskcmpv4sf3"
18528 [(set (match_operand:V4SI 0 "register_operand" "=x")
18529 (match_operator:V4SI 3 "sse_comparison_operator"
18530 [(match_operand:V4SF 1 "register_operand" "0")
18531 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
18532 "TARGET_SSE"
18533 "cmp%D3ps\t{%2, %0|%0, %2}"
18534 [(set_attr "type" "sse")])
18535
18536 (define_insn "maskncmpv4sf3"
18537 [(set (match_operand:V4SI 0 "register_operand" "=x")
18538 (not:V4SI
18539 (match_operator:V4SI 3 "sse_comparison_operator"
18540 [(match_operand:V4SF 1 "register_operand" "0")
18541 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
18542 "TARGET_SSE"
18543 "*
18544 {
18545 if (GET_CODE (operands[3]) == UNORDERED)
18546 return \"cmpordps\t{%2, %0|%0, %2}\";
18547
18548 return \"cmpn%D3ps\t{%2, %0|%0, %2}\";
18549 }"
18550 [(set_attr "type" "sse")])
18551
18552 (define_insn "vmmaskcmpv4sf3"
18553 [(set (match_operand:V4SI 0 "register_operand" "=x")
18554 (vec_merge:V4SI
18555 (match_operator:V4SI 3 "sse_comparison_operator"
18556 [(match_operand:V4SF 1 "register_operand" "0")
18557 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
18558 (match_dup 1)
18559 (const_int 1)))]
18560 "TARGET_SSE"
18561 "cmp%D3ss\t{%2, %0|%0, %2}"
18562 [(set_attr "type" "sse")])
18563
18564 (define_insn "vmmaskncmpv4sf3"
18565 [(set (match_operand:V4SI 0 "register_operand" "=x")
18566 (vec_merge:V4SI
18567 (not:V4SI
18568 (match_operator:V4SI 3 "sse_comparison_operator"
18569 [(match_operand:V4SF 1 "register_operand" "0")
18570 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
18571 (subreg:V4SI (match_dup 1) 0)
18572 (const_int 1)))]
18573 "TARGET_SSE"
18574 "*
18575 {
18576 if (GET_CODE (operands[3]) == UNORDERED)
18577 return \"cmpordss\t{%2, %0|%0, %2}\";
18578
18579 return \"cmpn%D3ss\t{%2, %0|%0, %2}\";
18580 }"
18581 [(set_attr "type" "sse")])
18582
18583 (define_insn "sse_comi"
18584 [(set (reg:CCFP 17)
18585 (match_operator:CCFP 2 "sse_comparison_operator"
18586 [(vec_select:SF
18587 (match_operand:V4SF 0 "register_operand" "x")
18588 (parallel [(const_int 0)]))
18589 (vec_select:SF
18590 (match_operand:V4SF 1 "register_operand" "x")
18591 (parallel [(const_int 0)]))]))]
18592 "TARGET_SSE"
18593 "comiss\t{%1, %0|%0, %1}"
18594 [(set_attr "type" "sse")])
18595
18596 (define_insn "sse_ucomi"
18597 [(set (reg:CCFPU 17)
18598 (match_operator:CCFPU 2 "sse_comparison_operator"
18599 [(vec_select:SF
18600 (match_operand:V4SF 0 "register_operand" "x")
18601 (parallel [(const_int 0)]))
18602 (vec_select:SF
18603 (match_operand:V4SF 1 "register_operand" "x")
18604 (parallel [(const_int 0)]))]))]
18605 "TARGET_SSE"
18606 "ucomiss\t{%1, %0|%0, %1}"
18607 [(set_attr "type" "sse")])
18608
18609
18610 ;; SSE unpack
18611
18612 (define_insn "sse_unpckhps"
18613 [(set (match_operand:V4SF 0 "register_operand" "=x")
18614 (vec_merge:V4SF
18615 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18616 (parallel [(const_int 2)
18617 (const_int 0)
18618 (const_int 3)
18619 (const_int 1)]))
18620 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18621 (parallel [(const_int 0)
18622 (const_int 2)
18623 (const_int 1)
18624 (const_int 3)]))
18625 (const_int 5)))]
18626 "TARGET_SSE"
18627 "unpckhps\t{%2, %0|%0, %2}"
18628 [(set_attr "type" "sse")])
18629
18630 (define_insn "sse_unpcklps"
18631 [(set (match_operand:V4SF 0 "register_operand" "=x")
18632 (vec_merge:V4SF
18633 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18634 (parallel [(const_int 0)
18635 (const_int 2)
18636 (const_int 1)
18637 (const_int 3)]))
18638 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18639 (parallel [(const_int 2)
18640 (const_int 0)
18641 (const_int 3)
18642 (const_int 1)]))
18643 (const_int 5)))]
18644 "TARGET_SSE"
18645 "unpcklps\t{%2, %0|%0, %2}"
18646 [(set_attr "type" "sse")])
18647
18648
18649 ;; SSE min/max
18650
18651 (define_insn "smaxv4sf3"
18652 [(set (match_operand:V4SF 0 "register_operand" "=x")
18653 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18654 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18655 "TARGET_SSE"
18656 "maxps\t{%2, %0|%0, %2}"
18657 [(set_attr "type" "sse")])
18658
18659 (define_insn "vmsmaxv4sf3"
18660 [(set (match_operand:V4SF 0 "register_operand" "=x")
18661 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18662 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18663 (match_dup 1)
18664 (const_int 1)))]
18665 "TARGET_SSE"
18666 "maxss\t{%2, %0|%0, %2}"
18667 [(set_attr "type" "sse")])
18668
18669 (define_insn "sminv4sf3"
18670 [(set (match_operand:V4SF 0 "register_operand" "=x")
18671 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18672 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18673 "TARGET_SSE"
18674 "minps\t{%2, %0|%0, %2}"
18675 [(set_attr "type" "sse")])
18676
18677 (define_insn "vmsminv4sf3"
18678 [(set (match_operand:V4SF 0 "register_operand" "=x")
18679 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18680 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18681 (match_dup 1)
18682 (const_int 1)))]
18683 "TARGET_SSE"
18684 "minss\t{%2, %0|%0, %2}"
18685 [(set_attr "type" "sse")])
18686
18687
18688 ;; SSE <-> integer/MMX conversions
18689
18690 (define_insn "cvtpi2ps"
18691 [(set (match_operand:V4SF 0 "register_operand" "=x")
18692 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18693 (vec_duplicate:V4SF
18694 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
18695 (const_int 12)))]
18696 "TARGET_SSE"
18697 "cvtpi2ps\t{%2, %0|%0, %2}"
18698 [(set_attr "type" "sse")])
18699
18700 (define_insn "cvtps2pi"
18701 [(set (match_operand:V2SI 0 "register_operand" "=y")
18702 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18703 (parallel
18704 [(const_int 0)
18705 (const_int 1)])))]
18706 "TARGET_SSE"
18707 "cvtps2pi\t{%1, %0|%0, %1}"
18708 [(set_attr "type" "sse")])
18709
18710 (define_insn "cvttps2pi"
18711 [(set (match_operand:V2SI 0 "register_operand" "=y")
18712 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18713 (parallel
18714 [(const_int 0)
18715 (const_int 1)])))]
18716 "TARGET_SSE"
18717 "cvttps2pi\t{%1, %0|%0, %1}"
18718 [(set_attr "type" "sse")])
18719
18720 (define_insn "cvtsi2ss"
18721 [(set (match_operand:V4SF 0 "register_operand" "=x")
18722 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18723 (vec_duplicate:V4SF
18724 (float:SF (match_operand:SI 2 "register_operand" "rm")))
18725 (const_int 14)))]
18726 "TARGET_SSE"
18727 "cvtsi2ss\t{%2, %0|%0, %2}"
18728 [(set_attr "type" "sse")])
18729
18730 (define_insn "cvtss2si"
18731 [(set (match_operand:SI 0 "register_operand" "=r")
18732 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18733 (parallel [(const_int 0)])))]
18734 "TARGET_SSE"
18735 "cvtss2si\t{%1, %0|%0, %1}"
18736 [(set_attr "type" "sse")])
18737
18738 (define_insn "cvttss2si"
18739 [(set (match_operand:SI 0 "register_operand" "=r")
18740 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18741 (parallel [(const_int 0)])))]
18742 "TARGET_SSE"
18743 "cvttss2si\t{%1, %0|%0, %1}"
18744 [(set_attr "type" "sse")])
18745
18746
18747 ;; MMX insns
18748
18749 ;; MMX arithmetic
18750
18751 (define_insn "addv8qi3"
18752 [(set (match_operand:V8QI 0 "register_operand" "=y")
18753 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18754 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18755 "TARGET_MMX"
18756 "paddb\t{%2, %0|%0, %2}"
18757 [(set_attr "type" "mmx")])
18758
18759 (define_insn "addv4hi3"
18760 [(set (match_operand:V4HI 0 "register_operand" "=y")
18761 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18762 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18763 "TARGET_MMX"
18764 "paddw\t{%2, %0|%0, %2}"
18765 [(set_attr "type" "mmx")])
18766
18767 (define_insn "addv2si3"
18768 [(set (match_operand:V2SI 0 "register_operand" "=y")
18769 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18770 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18771 "TARGET_MMX"
18772 "paddd\t{%2, %0|%0, %2}"
18773 [(set_attr "type" "mmx")])
18774
18775 (define_insn "ssaddv8qi3"
18776 [(set (match_operand:V8QI 0 "register_operand" "=y")
18777 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18778 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18779 "TARGET_MMX"
18780 "paddsb\t{%2, %0|%0, %2}"
18781 [(set_attr "type" "mmx")])
18782
18783 (define_insn "ssaddv4hi3"
18784 [(set (match_operand:V4HI 0 "register_operand" "=y")
18785 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18786 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18787 "TARGET_MMX"
18788 "paddsw\t{%2, %0|%0, %2}"
18789 [(set_attr "type" "mmx")])
18790
18791 (define_insn "usaddv8qi3"
18792 [(set (match_operand:V8QI 0 "register_operand" "=y")
18793 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18794 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18795 "TARGET_MMX"
18796 "paddusb\t{%2, %0|%0, %2}"
18797 [(set_attr "type" "mmx")])
18798
18799 (define_insn "usaddv4hi3"
18800 [(set (match_operand:V4HI 0 "register_operand" "=y")
18801 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18802 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18803 "TARGET_MMX"
18804 "paddusw\t{%2, %0|%0, %2}"
18805 [(set_attr "type" "mmx")])
18806
18807 (define_insn "subv8qi3"
18808 [(set (match_operand:V8QI 0 "register_operand" "=y")
18809 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18810 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18811 "TARGET_MMX"
18812 "psubb\t{%2, %0|%0, %2}"
18813 [(set_attr "type" "mmx")])
18814
18815 (define_insn "subv4hi3"
18816 [(set (match_operand:V4HI 0 "register_operand" "=y")
18817 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18818 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18819 "TARGET_MMX"
18820 "psubw\t{%2, %0|%0, %2}"
18821 [(set_attr "type" "mmx")])
18822
18823 (define_insn "subv2si3"
18824 [(set (match_operand:V2SI 0 "register_operand" "=y")
18825 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18826 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18827 "TARGET_MMX"
18828 "psubd\t{%2, %0|%0, %2}"
18829 [(set_attr "type" "mmx")])
18830
18831 (define_insn "sssubv8qi3"
18832 [(set (match_operand:V8QI 0 "register_operand" "=y")
18833 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18834 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18835 "TARGET_MMX"
18836 "psubsb\t{%2, %0|%0, %2}"
18837 [(set_attr "type" "mmx")])
18838
18839 (define_insn "sssubv4hi3"
18840 [(set (match_operand:V4HI 0 "register_operand" "=y")
18841 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18842 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18843 "TARGET_MMX"
18844 "psubsw\t{%2, %0|%0, %2}"
18845 [(set_attr "type" "mmx")])
18846
18847 (define_insn "ussubv8qi3"
18848 [(set (match_operand:V8QI 0 "register_operand" "=y")
18849 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18850 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18851 "TARGET_MMX"
18852 "psubusb\t{%2, %0|%0, %2}"
18853 [(set_attr "type" "mmx")])
18854
18855 (define_insn "ussubv4hi3"
18856 [(set (match_operand:V4HI 0 "register_operand" "=y")
18857 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18858 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18859 "TARGET_MMX"
18860 "psubusw\t{%2, %0|%0, %2}"
18861 [(set_attr "type" "mmx")])
18862
18863 (define_insn "mulv4hi3"
18864 [(set (match_operand:V4HI 0 "register_operand" "=y")
18865 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18866 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18867 "TARGET_MMX"
18868 "pmullw\t{%2, %0|%0, %2}"
18869 [(set_attr "type" "mmx")])
18870
18871 (define_insn "smulv4hi3_highpart"
18872 [(set (match_operand:V4HI 0 "register_operand" "=y")
18873 (truncate:V4HI
18874 (lshiftrt:V4SI
18875 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18876 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18877 (const_int 16))))]
18878 "TARGET_MMX"
18879 "pmulhw\t{%2, %0|%0, %2}"
18880 [(set_attr "type" "mmx")])
18881
18882 (define_insn "umulv4hi3_highpart"
18883 [(set (match_operand:V4HI 0 "register_operand" "=y")
18884 (truncate:V4HI
18885 (lshiftrt:V4SI
18886 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18887 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18888 (const_int 16))))]
18889 "TARGET_SSE || TARGET_3DNOW_A"
18890 "pmulhuw\t{%2, %0|%0, %2}"
18891 [(set_attr "type" "mmx")])
18892
18893 (define_insn "mmx_pmaddwd"
18894 [(set (match_operand:V2SI 0 "register_operand" "=y")
18895 (plus:V2SI
18896 (mult:V2SI
18897 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18898 (parallel [(const_int 0)
18899 (const_int 2)])))
18900 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18901 (parallel [(const_int 0)
18902 (const_int 2)]))))
18903 (mult:V2SI
18904 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18905 (parallel [(const_int 1)
18906 (const_int 3)])))
18907 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18908 (parallel [(const_int 1)
18909 (const_int 3)]))))))]
18910 "TARGET_MMX"
18911 "pmaddwd\t{%2, %0|%0, %2}"
18912 [(set_attr "type" "mmx")])
18913
18914
18915 ;; MMX logical operations
18916 ;; Note we don't want to declare these as regular iordi3 insns to prevent
18917 ;; normal code that also wants to use the FPU from getting broken.
18918 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
18919 (define_insn "mmx_iordi3"
18920 [(set (match_operand:DI 0 "register_operand" "=y")
18921 (unspec:DI
18922 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18923 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18924 "TARGET_MMX"
18925 "por\t{%2, %0|%0, %2}"
18926 [(set_attr "type" "mmx")])
18927
18928 (define_insn "mmx_xordi3"
18929 [(set (match_operand:DI 0 "register_operand" "=y")
18930 (unspec:DI
18931 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18932 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18933 "TARGET_MMX"
18934 "pxor\t{%2, %0|%0, %2}"
18935 [(set_attr "type" "mmx")
18936 (set_attr "memory" "none")])
18937
18938 ;; Same as pxor, but don't show input operands so that we don't think
18939 ;; they are live.
18940 (define_insn "mmx_clrdi"
18941 [(set (match_operand:DI 0 "register_operand" "=y")
18942 (unspec:DI [(const_int 0)] 45))]
18943 "TARGET_MMX"
18944 "pxor\t{%0, %0|%0, %0}"
18945 [(set_attr "type" "mmx")])
18946
18947 (define_insn "mmx_anddi3"
18948 [(set (match_operand:DI 0 "register_operand" "=y")
18949 (unspec:DI
18950 [(and:DI (match_operand:DI 1 "register_operand" "0")
18951 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18952 "TARGET_MMX"
18953 "pand\t{%2, %0|%0, %2}"
18954 [(set_attr "type" "mmx")])
18955
18956 (define_insn "mmx_nanddi3"
18957 [(set (match_operand:DI 0 "register_operand" "=y")
18958 (unspec:DI
18959 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18960 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18961 "TARGET_MMX"
18962 "pandn\t{%2, %0|%0, %2}"
18963 [(set_attr "type" "mmx")])
18964
18965
18966 ;; MMX unsigned averages/sum of absolute differences
18967
18968 (define_insn "mmx_uavgv8qi3"
18969 [(set (match_operand:V8QI 0 "register_operand" "=y")
18970 (ashiftrt:V8QI
18971 (plus:V8QI (plus:V8QI
18972 (match_operand:V8QI 1 "register_operand" "0")
18973 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18974 (vec_const:V8QI (parallel [(const_int 1)
18975 (const_int 1)
18976 (const_int 1)
18977 (const_int 1)
18978 (const_int 1)
18979 (const_int 1)
18980 (const_int 1)
18981 (const_int 1)])))
18982 (const_int 1)))]
18983 "TARGET_SSE || TARGET_3DNOW_A"
18984 "pavgb\t{%2, %0|%0, %2}"
18985 [(set_attr "type" "sse")])
18986
18987 (define_insn "mmx_uavgv4hi3"
18988 [(set (match_operand:V4HI 0 "register_operand" "=y")
18989 (ashiftrt:V4HI
18990 (plus:V4HI (plus:V4HI
18991 (match_operand:V4HI 1 "register_operand" "0")
18992 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18993 (vec_const:V4HI (parallel [(const_int 1)
18994 (const_int 1)
18995 (const_int 1)
18996 (const_int 1)])))
18997 (const_int 1)))]
18998 "TARGET_SSE || TARGET_3DNOW_A"
18999 "pavgw\t{%2, %0|%0, %2}"
19000 [(set_attr "type" "sse")])
19001
19002 (define_insn "mmx_psadbw"
19003 [(set (match_operand:V8QI 0 "register_operand" "=y")
19004 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
19005 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
19006 "TARGET_SSE || TARGET_3DNOW_A"
19007 "psadbw\t{%2, %0|%0, %2}"
19008 [(set_attr "type" "sse")])
19009
19010
19011 ;; MMX insert/extract/shuffle
19012
19013 (define_insn "mmx_pinsrw"
19014 [(set (match_operand:V4HI 0 "register_operand" "=y")
19015 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
19016 (vec_duplicate:V4HI
19017 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
19018 (match_operand:SI 3 "immediate_operand" "i")))]
19019 "TARGET_SSE || TARGET_3DNOW_A"
19020 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
19021 [(set_attr "type" "sse")])
19022
19023 (define_insn "mmx_pextrw"
19024 [(set (match_operand:SI 0 "register_operand" "=r")
19025 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
19026 (parallel
19027 [(match_operand:SI 2 "immediate_operand" "i")]))))]
19028 "TARGET_SSE || TARGET_3DNOW_A"
19029 "pextrw\t{%2, %1, %0|%0, %1, %2}"
19030 [(set_attr "type" "sse")])
19031
19032 (define_insn "mmx_pshufw"
19033 [(set (match_operand:V4HI 0 "register_operand" "=y")
19034 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
19035 (match_operand:SI 2 "immediate_operand" "i")] 41))]
19036 "TARGET_SSE || TARGET_3DNOW_A"
19037 "pshufw\t{%2, %1, %0|%0, %1, %2}"
19038 [(set_attr "type" "sse")])
19039
19040
19041 ;; MMX mask-generating comparisons
19042
19043 (define_insn "eqv8qi3"
19044 [(set (match_operand:V8QI 0 "register_operand" "=y")
19045 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
19046 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19047 "TARGET_MMX"
19048 "pcmpeqb\t{%2, %0|%0, %2}"
19049 [(set_attr "type" "mmx")])
19050
19051 (define_insn "eqv4hi3"
19052 [(set (match_operand:V4HI 0 "register_operand" "=y")
19053 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
19054 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19055 "TARGET_MMX"
19056 "pcmpeqw\t{%2, %0|%0, %2}"
19057 [(set_attr "type" "mmx")])
19058
19059 (define_insn "eqv2si3"
19060 [(set (match_operand:V2SI 0 "register_operand" "=y")
19061 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
19062 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19063 "TARGET_MMX"
19064 "pcmpeqd\t{%2, %0|%0, %2}"
19065 [(set_attr "type" "mmx")])
19066
19067 (define_insn "gtv8qi3"
19068 [(set (match_operand:V8QI 0 "register_operand" "=y")
19069 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
19070 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19071 "TARGET_MMX"
19072 "pcmpgtb\t{%2, %0|%0, %2}"
19073 [(set_attr "type" "mmx")])
19074
19075 (define_insn "gtv4hi3"
19076 [(set (match_operand:V4HI 0 "register_operand" "=y")
19077 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19078 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19079 "TARGET_MMX"
19080 "pcmpgtw\t{%2, %0|%0, %2}"
19081 [(set_attr "type" "mmx")])
19082
19083 (define_insn "gtv2si3"
19084 [(set (match_operand:V2SI 0 "register_operand" "=y")
19085 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19086 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
19087 "TARGET_MMX"
19088 "pcmpgtd\t{%2, %0|%0, %2}"
19089 [(set_attr "type" "mmx")])
19090
19091
19092 ;; MMX max/min insns
19093
19094 (define_insn "umaxv8qi3"
19095 [(set (match_operand:V8QI 0 "register_operand" "=y")
19096 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
19097 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19098 "TARGET_SSE || TARGET_3DNOW_A"
19099 "pmaxub\t{%2, %0|%0, %2}"
19100 [(set_attr "type" "sse")])
19101
19102 (define_insn "smaxv4hi3"
19103 [(set (match_operand:V4HI 0 "register_operand" "=y")
19104 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
19105 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19106 "TARGET_SSE || TARGET_3DNOW_A"
19107 "pmaxsw\t{%2, %0|%0, %2}"
19108 [(set_attr "type" "sse")])
19109
19110 (define_insn "uminv8qi3"
19111 [(set (match_operand:V8QI 0 "register_operand" "=y")
19112 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
19113 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
19114 "TARGET_SSE || TARGET_3DNOW_A"
19115 "pminub\t{%2, %0|%0, %2}"
19116 [(set_attr "type" "sse")])
19117
19118 (define_insn "sminv4hi3"
19119 [(set (match_operand:V4HI 0 "register_operand" "=y")
19120 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
19121 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
19122 "TARGET_SSE || TARGET_3DNOW_A"
19123 "pminsw\t{%2, %0|%0, %2}"
19124 [(set_attr "type" "sse")])
19125
19126
19127 ;; MMX shifts
19128
19129 (define_insn "ashrv4hi3"
19130 [(set (match_operand:V4HI 0 "register_operand" "=y")
19131 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19132 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19133 "TARGET_MMX"
19134 "psraw\t{%2, %0|%0, %2}"
19135 [(set_attr "type" "mmx")])
19136
19137 (define_insn "ashrv2si3"
19138 [(set (match_operand:V2SI 0 "register_operand" "=y")
19139 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19140 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19141 "TARGET_MMX"
19142 "psrad\t{%2, %0|%0, %2}"
19143 [(set_attr "type" "mmx")])
19144
19145 (define_insn "lshrv4hi3"
19146 [(set (match_operand:V4HI 0 "register_operand" "=y")
19147 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
19148 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19149 "TARGET_MMX"
19150 "psrlw\t{%2, %0|%0, %2}"
19151 [(set_attr "type" "mmx")])
19152
19153 (define_insn "lshrv2si3"
19154 [(set (match_operand:V2SI 0 "register_operand" "=y")
19155 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
19156 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19157 "TARGET_MMX"
19158 "psrld\t{%2, %0|%0, %2}"
19159 [(set_attr "type" "mmx")])
19160
19161 ;; See logical MMX insns.
19162 (define_insn "mmx_lshrdi3"
19163 [(set (match_operand:DI 0 "register_operand" "=y")
19164 (unspec:DI
19165 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
19166 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19167 "TARGET_MMX"
19168 "psrlq\t{%2, %0|%0, %2}"
19169 [(set_attr "type" "mmx")])
19170
19171 (define_insn "ashlv4hi3"
19172 [(set (match_operand:V4HI 0 "register_operand" "=y")
19173 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
19174 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19175 "TARGET_MMX"
19176 "psllw\t{%2, %0|%0, %2}"
19177 [(set_attr "type" "mmx")])
19178
19179 (define_insn "ashlv2si3"
19180 [(set (match_operand:V2SI 0 "register_operand" "=y")
19181 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
19182 (match_operand:DI 2 "nonmemory_operand" "yi")))]
19183 "TARGET_MMX"
19184 "pslld\t{%2, %0|%0, %2}"
19185 [(set_attr "type" "mmx")])
19186
19187 ;; See logical MMX insns.
19188 (define_insn "mmx_ashldi3"
19189 [(set (match_operand:DI 0 "register_operand" "=y")
19190 (unspec:DI
19191 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
19192 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
19193 "TARGET_MMX"
19194 "psllq\t{%2, %0|%0, %2}"
19195 [(set_attr "type" "mmx")])
19196
19197
19198 ;; MMX pack/unpack insns.
19199
19200 (define_insn "mmx_packsswb"
19201 [(set (match_operand:V8QI 0 "register_operand" "=y")
19202 (vec_concat:V8QI
19203 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19204 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19205 "TARGET_MMX"
19206 "packsswb\t{%2, %0|%0, %2}"
19207 [(set_attr "type" "mmx")])
19208
19209 (define_insn "mmx_packssdw"
19210 [(set (match_operand:V4HI 0 "register_operand" "=y")
19211 (vec_concat:V4HI
19212 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
19213 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
19214 "TARGET_MMX"
19215 "packssdw\t{%2, %0|%0, %2}"
19216 [(set_attr "type" "mmx")])
19217
19218 (define_insn "mmx_packuswb"
19219 [(set (match_operand:V8QI 0 "register_operand" "=y")
19220 (vec_concat:V8QI
19221 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
19222 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
19223 "TARGET_MMX"
19224 "packuswb\t{%2, %0|%0, %2}"
19225 [(set_attr "type" "mmx")])
19226
19227 (define_insn "mmx_punpckhbw"
19228 [(set (match_operand:V8QI 0 "register_operand" "=y")
19229 (vec_merge:V8QI
19230 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19231 (parallel [(const_int 4)
19232 (const_int 0)
19233 (const_int 5)
19234 (const_int 1)
19235 (const_int 6)
19236 (const_int 2)
19237 (const_int 7)
19238 (const_int 3)]))
19239 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19240 (parallel [(const_int 0)
19241 (const_int 4)
19242 (const_int 1)
19243 (const_int 5)
19244 (const_int 2)
19245 (const_int 6)
19246 (const_int 3)
19247 (const_int 7)]))
19248 (const_int 85)))]
19249 "TARGET_MMX"
19250 "punpckhbw\t{%2, %0|%0, %2}"
19251 [(set_attr "type" "mmx")])
19252
19253 (define_insn "mmx_punpckhwd"
19254 [(set (match_operand:V4HI 0 "register_operand" "=y")
19255 (vec_merge:V4HI
19256 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19257 (parallel [(const_int 0)
19258 (const_int 2)
19259 (const_int 1)
19260 (const_int 3)]))
19261 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19262 (parallel [(const_int 2)
19263 (const_int 0)
19264 (const_int 3)
19265 (const_int 1)]))
19266 (const_int 5)))]
19267 "TARGET_MMX"
19268 "punpckhwd\t{%2, %0|%0, %2}"
19269 [(set_attr "type" "mmx")])
19270
19271 (define_insn "mmx_punpckhdq"
19272 [(set (match_operand:V2SI 0 "register_operand" "=y")
19273 (vec_merge:V2SI
19274 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19275 (parallel [(const_int 0)
19276 (const_int 1)]))
19277 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19278 (parallel [(const_int 1)
19279 (const_int 0)]))
19280 (const_int 1)))]
19281 "TARGET_MMX"
19282 "punpckhdq\t{%2, %0|%0, %2}"
19283 [(set_attr "type" "mmx")])
19284
19285 (define_insn "mmx_punpcklbw"
19286 [(set (match_operand:V8QI 0 "register_operand" "=y")
19287 (vec_merge:V8QI
19288 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19289 (parallel [(const_int 0)
19290 (const_int 4)
19291 (const_int 1)
19292 (const_int 5)
19293 (const_int 2)
19294 (const_int 6)
19295 (const_int 3)
19296 (const_int 7)]))
19297 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19298 (parallel [(const_int 4)
19299 (const_int 0)
19300 (const_int 5)
19301 (const_int 1)
19302 (const_int 6)
19303 (const_int 2)
19304 (const_int 7)
19305 (const_int 3)]))
19306 (const_int 85)))]
19307 "TARGET_MMX"
19308 "punpcklbw\t{%2, %0|%0, %2}"
19309 [(set_attr "type" "mmx")])
19310
19311 (define_insn "mmx_punpcklwd"
19312 [(set (match_operand:V4HI 0 "register_operand" "=y")
19313 (vec_merge:V4HI
19314 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19315 (parallel [(const_int 2)
19316 (const_int 0)
19317 (const_int 3)
19318 (const_int 1)]))
19319 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19320 (parallel [(const_int 0)
19321 (const_int 2)
19322 (const_int 1)
19323 (const_int 3)]))
19324 (const_int 5)))]
19325 "TARGET_MMX"
19326 "punpcklwd\t{%2, %0|%0, %2}"
19327 [(set_attr "type" "mmx")])
19328
19329 (define_insn "mmx_punpckldq"
19330 [(set (match_operand:V2SI 0 "register_operand" "=y")
19331 (vec_merge:V2SI
19332 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19333 (parallel [(const_int 1)
19334 (const_int 0)]))
19335 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19336 (parallel [(const_int 0)
19337 (const_int 1)]))
19338 (const_int 1)))]
19339 "TARGET_MMX"
19340 "punpckldq\t{%2, %0|%0, %2}"
19341 [(set_attr "type" "mmx")])
19342
19343
19344 ;; Miscellaneous stuff
19345
19346 (define_insn "emms"
19347 [(unspec_volatile [(const_int 0)] 31)
19348 (clobber (reg:XF 8))
19349 (clobber (reg:XF 9))
19350 (clobber (reg:XF 10))
19351 (clobber (reg:XF 11))
19352 (clobber (reg:XF 12))
19353 (clobber (reg:XF 13))
19354 (clobber (reg:XF 14))
19355 (clobber (reg:XF 15))
19356 (clobber (reg:DI 29))
19357 (clobber (reg:DI 30))
19358 (clobber (reg:DI 31))
19359 (clobber (reg:DI 32))
19360 (clobber (reg:DI 33))
19361 (clobber (reg:DI 34))
19362 (clobber (reg:DI 35))
19363 (clobber (reg:DI 36))]
19364 "TARGET_MMX"
19365 "emms"
19366 [(set_attr "type" "mmx")
19367 (set_attr "memory" "unknown")])
19368
19369 (define_insn "ldmxcsr"
19370 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19371 "TARGET_MMX"
19372 "ldmxcsr\t%0"
19373 [(set_attr "type" "mmx")
19374 (set_attr "memory" "load")])
19375
19376 (define_insn "stmxcsr"
19377 [(set (match_operand:SI 0 "memory_operand" "=m")
19378 (unspec_volatile:SI [(const_int 0)] 40))]
19379 "TARGET_MMX"
19380 "stmxcsr\t%0"
19381 [(set_attr "type" "mmx")
19382 (set_attr "memory" "store")])
19383
19384 (define_expand "sfence"
19385 [(set (match_dup 0)
19386 (unspec:BLK [(match_dup 0)] 44))]
19387 "TARGET_SSE || TARGET_3DNOW_A"
19388 {
19389 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19390 MEM_VOLATILE_P (operands[0]) = 1;
19391 })
19392
19393 (define_insn "*sfence_insn"
19394 [(set (match_operand:BLK 0 "" "")
19395 (unspec:BLK [(match_dup 0)] 44))]
19396 "TARGET_SSE || TARGET_3DNOW_A"
19397 "sfence"
19398 [(set_attr "type" "sse")
19399 (set_attr "memory" "unknown")])
19400
19401 (define_expand "prefetch"
19402 [(prefetch (match_operand:SI 0 "address_operand" "p")
19403 (match_operand:SI 1 "const_int_operand" "n")
19404 (match_operand:SI 2 "const_int_operand" "n"))]
19405 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19406 "
19407 {
19408 int rw = INTVAL (operands[1]);
19409 int locality = INTVAL (operands[2]);
19410 if (rw != 0 && rw != 1)
19411 abort ();
19412 if (locality < 0 || locality > 3)
19413 abort ();
19414 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19415 suported by SSE counterpart or the SSE prefetch is not available
19416 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19417 of locality. */
19418 if (TARGET_3DNOW
19419 && (!TARGET_PREFETCH_SSE || rw))
19420 {
19421 emit_insn (gen_prefetch_3dnow (operands[0], operands[1]));
19422 }
19423 else
19424 {
19425 int i;
19426 switch (locality)
19427 {
19428 case 0: /* No temporal locality. */
19429 i = 0;
19430 break;
19431 case 1: /* Lowest level of temporal locality. */
19432 i = 3;
19433 break;
19434 case 2: /* Moderate level of temporal locality. */
19435 i = 2;
19436 break;
19437 case 3: /* Highest level of temporal locality. */
19438 i = 1;
19439 break;
19440 default:
19441 abort (); /* We already checked for valid values above. */
19442 break;
19443 }
19444 emit_insn (gen_prefetch_sse (operands[0], GEN_INT (i)));
19445 }
19446 DONE;
19447 }")
19448
19449 (define_insn "prefetch_sse"
19450 [(unspec [(match_operand:SI 0 "address_operand" "p")
19451 (match_operand:SI 1 "immediate_operand" "n")] 35)]
19452 "TARGET_PREFETCH_SSE"
19453 {
19454 switch (INTVAL (operands[1]))
19455 {
19456 case 0:
19457 return "prefetchnta\t%a0";
19458 case 1:
19459 return "prefetcht0\t%a0";
19460 case 2:
19461 return "prefetcht1\t%a0";
19462 case 3:
19463 return "prefetcht2\t%a0";
19464 default:
19465 abort ();
19466 }
19467 }
19468 [(set_attr "type" "sse")])
19469
19470 (define_expand "sse_prologue_save"
19471 [(parallel [(set (match_operand:BLK 0 "" "")
19472 (unspec:BLK [(reg:DI 21)
19473 (reg:DI 22)
19474 (reg:DI 23)
19475 (reg:DI 24)
19476 (reg:DI 25)
19477 (reg:DI 26)
19478 (reg:DI 27)
19479 (reg:DI 28)] 13))
19480 (use (match_operand:DI 1 "register_operand" ""))
19481 (use (match_operand:DI 2 "immediate_operand" ""))
19482 (use (label_ref:DI (match_operand 3 "" "")))])]
19483 "TARGET_64BIT"
19484 "")
19485
19486 (define_insn "*sse_prologue_save_insn"
19487 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19488 (match_operand:DI 4 "const_int_operand" "n")))
19489 (unspec:BLK [(reg:DI 21)
19490 (reg:DI 22)
19491 (reg:DI 23)
19492 (reg:DI 24)
19493 (reg:DI 25)
19494 (reg:DI 26)
19495 (reg:DI 27)
19496 (reg:DI 28)] 13))
19497 (use (match_operand:DI 1 "register_operand" "r"))
19498 (use (match_operand:DI 2 "const_int_operand" "i"))
19499 (use (label_ref:DI (match_operand 3 "" "X")))]
19500 "TARGET_64BIT
19501 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19502 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19503 "*
19504 {
19505 int i;
19506 operands[0] = gen_rtx_MEM (Pmode,
19507 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19508 output_asm_insn (\"jmp\\t%A1\", operands);
19509 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19510 {
19511 operands[4] = adjust_address (operands[0], DImode, i*16);
19512 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19513 PUT_MODE (operands[4], TImode);
19514 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19515 output_asm_insn (\"rex\", operands);
19516 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19517 }
19518 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19519 CODE_LABEL_NUMBER (operands[3]));
19520 RET;
19521 }
19522 "
19523 [(set_attr "type" "other")
19524 (set_attr "length_immediate" "0")
19525 (set_attr "length_address" "0")
19526 (set_attr "length" "135")
19527 (set_attr "memory" "store")
19528 (set_attr "modrm" "0")
19529 (set_attr "mode" "DI")])
19530
19531 ;; 3Dnow! instructions
19532
19533 (define_insn "addv2sf3"
19534 [(set (match_operand:V2SF 0 "register_operand" "=y")
19535 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19536 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19537 "TARGET_3DNOW"
19538 "pfadd\\t{%2, %0|%0, %2}"
19539 [(set_attr "type" "mmx")])
19540
19541 (define_insn "subv2sf3"
19542 [(set (match_operand:V2SF 0 "register_operand" "=y")
19543 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19544 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19545 "TARGET_3DNOW"
19546 "pfsub\\t{%2, %0|%0, %2}"
19547 [(set_attr "type" "mmx")])
19548
19549 (define_insn "subrv2sf3"
19550 [(set (match_operand:V2SF 0 "register_operand" "=y")
19551 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19552 (match_operand:V2SF 1 "register_operand" "0")))]
19553 "TARGET_3DNOW"
19554 "pfsubr\\t{%2, %0|%0, %2}"
19555 [(set_attr "type" "mmx")])
19556
19557 (define_insn "gtv2sf3"
19558 [(set (match_operand:V2SI 0 "register_operand" "=y")
19559 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19560 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19561 "TARGET_3DNOW"
19562 "pfcmpgt\\t{%2, %0|%0, %2}"
19563 [(set_attr "type" "mmx")])
19564
19565 (define_insn "gev2sf3"
19566 [(set (match_operand:V2SI 0 "register_operand" "=y")
19567 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19568 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19569 "TARGET_3DNOW"
19570 "pfcmpge\\t{%2, %0|%0, %2}"
19571 [(set_attr "type" "mmx")])
19572
19573 (define_insn "eqv2sf3"
19574 [(set (match_operand:V2SI 0 "register_operand" "=y")
19575 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19576 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19577 "TARGET_3DNOW"
19578 "pfcmpeq\\t{%2, %0|%0, %2}"
19579 [(set_attr "type" "mmx")])
19580
19581 (define_insn "pfmaxv2sf3"
19582 [(set (match_operand:V2SF 0 "register_operand" "=y")
19583 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19584 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19585 "TARGET_3DNOW"
19586 "pfmax\\t{%2, %0|%0, %2}"
19587 [(set_attr "type" "mmx")])
19588
19589 (define_insn "pfminv2sf3"
19590 [(set (match_operand:V2SF 0 "register_operand" "=y")
19591 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19592 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19593 "TARGET_3DNOW"
19594 "pfmin\\t{%2, %0|%0, %2}"
19595 [(set_attr "type" "mmx")])
19596
19597 (define_insn "mulv2sf3"
19598 [(set (match_operand:V2SF 0 "register_operand" "=y")
19599 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19600 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19601 "TARGET_3DNOW"
19602 "pfmul\\t{%2, %0|%0, %2}"
19603 [(set_attr "type" "mmx")])
19604
19605 (define_insn "femms"
19606 [(unspec_volatile [(const_int 0)] 46)
19607 (clobber (reg:XF 8))
19608 (clobber (reg:XF 9))
19609 (clobber (reg:XF 10))
19610 (clobber (reg:XF 11))
19611 (clobber (reg:XF 12))
19612 (clobber (reg:XF 13))
19613 (clobber (reg:XF 14))
19614 (clobber (reg:XF 15))
19615 (clobber (reg:DI 29))
19616 (clobber (reg:DI 30))
19617 (clobber (reg:DI 31))
19618 (clobber (reg:DI 32))
19619 (clobber (reg:DI 33))
19620 (clobber (reg:DI 34))
19621 (clobber (reg:DI 35))
19622 (clobber (reg:DI 36))]
19623 "TARGET_3DNOW"
19624 "femms"
19625 [(set_attr "type" "mmx")])
19626
19627 (define_insn "prefetch_3dnow"
19628 [(prefetch (match_operand:SI 0 "address_operand" "p")
19629 (match_operand:SI 1 "const_int_operand" "n")
19630 (const_int 0))]
19631 "TARGET_3DNOW"
19632 {
19633 if (INTVAL (operands[1]) == 0)
19634 return "prefetch\t%a0";
19635 else
19636 return "prefetchw\t%a0";
19637 }
19638 [(set_attr "type" "mmx")])
19639
19640 (define_insn "pf2id"
19641 [(set (match_operand:V2SI 0 "register_operand" "=y")
19642 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19643 "TARGET_3DNOW"
19644 "pf2id\\t{%1, %0|%0, %1}"
19645 [(set_attr "type" "mmx")])
19646
19647 (define_insn "pf2iw"
19648 [(set (match_operand:V2SI 0 "register_operand" "=y")
19649 (sign_extend:V2SI
19650 (ss_truncate:V2HI
19651 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19652 "TARGET_3DNOW_A"
19653 "pf2iw\\t{%1, %0|%0, %1}"
19654 [(set_attr "type" "mmx")])
19655
19656 (define_insn "pfacc"
19657 [(set (match_operand:V2SF 0 "register_operand" "=y")
19658 (vec_concat:V2SF
19659 (plus:SF
19660 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19661 (parallel [(const_int 0)]))
19662 (vec_select:SF (match_dup 1)
19663 (parallel [(const_int 1)])))
19664 (plus:SF
19665 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19666 (parallel [(const_int 0)]))
19667 (vec_select:SF (match_dup 2)
19668 (parallel [(const_int 1)])))))]
19669 "TARGET_3DNOW"
19670 "pfacc\\t{%2, %0|%0, %2}"
19671 [(set_attr "type" "mmx")])
19672
19673 (define_insn "pfnacc"
19674 [(set (match_operand:V2SF 0 "register_operand" "=y")
19675 (vec_concat:V2SF
19676 (minus:SF
19677 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19678 (parallel [(const_int 0)]))
19679 (vec_select:SF (match_dup 1)
19680 (parallel [(const_int 1)])))
19681 (minus:SF
19682 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19683 (parallel [(const_int 0)]))
19684 (vec_select:SF (match_dup 2)
19685 (parallel [(const_int 1)])))))]
19686 "TARGET_3DNOW_A"
19687 "pfnacc\\t{%2, %0|%0, %2}"
19688 [(set_attr "type" "mmx")])
19689
19690 (define_insn "pfpnacc"
19691 [(set (match_operand:V2SF 0 "register_operand" "=y")
19692 (vec_concat:V2SF
19693 (minus:SF
19694 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19695 (parallel [(const_int 0)]))
19696 (vec_select:SF (match_dup 1)
19697 (parallel [(const_int 1)])))
19698 (plus:SF
19699 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19700 (parallel [(const_int 0)]))
19701 (vec_select:SF (match_dup 2)
19702 (parallel [(const_int 1)])))))]
19703 "TARGET_3DNOW_A"
19704 "pfpnacc\\t{%2, %0|%0, %2}"
19705 [(set_attr "type" "mmx")])
19706
19707 (define_insn "pi2fw"
19708 [(set (match_operand:V2SF 0 "register_operand" "=y")
19709 (float:V2SF
19710 (vec_concat:V2SI
19711 (sign_extend:SI
19712 (truncate:HI
19713 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19714 (parallel [(const_int 0)]))))
19715 (sign_extend:SI
19716 (truncate:HI
19717 (vec_select:SI (match_dup 1)
19718 (parallel [(const_int 1)])))))))]
19719 "TARGET_3DNOW_A"
19720 "pi2fw\\t{%1, %0|%0, %1}"
19721 [(set_attr "type" "mmx")])
19722
19723 (define_insn "floatv2si2"
19724 [(set (match_operand:V2SF 0 "register_operand" "=y")
19725 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19726 "TARGET_3DNOW"
19727 "pi2fd\\t{%1, %0|%0, %1}"
19728 [(set_attr "type" "mmx")])
19729
19730 ;; This insn is identical to pavgb in operation, but the opcode is
19731 ;; different. To avoid accidentally matching pavgb, use an unspec.
19732
19733 (define_insn "pavgusb"
19734 [(set (match_operand:V8QI 0 "register_operand" "=y")
19735 (unspec:V8QI
19736 [(match_operand:V8QI 1 "register_operand" "0")
19737 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19738 "TARGET_3DNOW"
19739 "pavgusb\\t{%2, %0|%0, %2}"
19740 [(set_attr "type" "mmx")])
19741
19742 ;; 3DNow reciprical and sqrt
19743
19744 (define_insn "pfrcpv2sf2"
19745 [(set (match_operand:V2SF 0 "register_operand" "=y")
19746 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19747 "TARGET_3DNOW"
19748 "pfrcp\\t{%1, %0|%0, %1}"
19749 [(set_attr "type" "mmx")])
19750
19751 (define_insn "pfrcpit1v2sf3"
19752 [(set (match_operand:V2SF 0 "register_operand" "=y")
19753 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19754 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19755 "TARGET_3DNOW"
19756 "pfrcpit1\\t{%2, %0|%0, %2}"
19757 [(set_attr "type" "mmx")])
19758
19759 (define_insn "pfrcpit2v2sf3"
19760 [(set (match_operand:V2SF 0 "register_operand" "=y")
19761 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19762 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19763 "TARGET_3DNOW"
19764 "pfrcpit2\\t{%2, %0|%0, %2}"
19765 [(set_attr "type" "mmx")])
19766
19767 (define_insn "pfrsqrtv2sf2"
19768 [(set (match_operand:V2SF 0 "register_operand" "=y")
19769 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19770 "TARGET_3DNOW"
19771 "pfrsqrt\\t{%1, %0|%0, %1}"
19772 [(set_attr "type" "mmx")])
19773
19774 (define_insn "pfrsqit1v2sf3"
19775 [(set (match_operand:V2SF 0 "register_operand" "=y")
19776 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19777 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19778 "TARGET_3DNOW"
19779 "pfrsqit1\\t{%2, %0|%0, %2}"
19780 [(set_attr "type" "mmx")])
19781
19782 (define_insn "pmulhrwv4hi3"
19783 [(set (match_operand:V4HI 0 "register_operand" "=y")
19784 (truncate:V4HI
19785 (lshiftrt:V4SI
19786 (plus:V4SI
19787 (mult:V4SI
19788 (sign_extend:V4SI
19789 (match_operand:V4HI 1 "register_operand" "0"))
19790 (sign_extend:V4SI
19791 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19792 (vec_const:V4SI
19793 (parallel [(const_int 32768)
19794 (const_int 32768)
19795 (const_int 32768)
19796 (const_int 32768)])))
19797 (const_int 16))))]
19798 "TARGET_3DNOW"
19799 "pmulhrw\\t{%2, %0|%0, %2}"
19800 [(set_attr "type" "mmx")])
19801
19802 (define_insn "pswapdv2si2"
19803 [(set (match_operand:V2SI 0 "register_operand" "=y")
19804 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19805 (parallel [(const_int 1) (const_int 0)])))]
19806 "TARGET_3DNOW_A"
19807 "pswapd\\t{%1, %0|%0, %1}"
19808 [(set_attr "type" "mmx")])
19809
19810 (define_insn "pswapdv2sf2"
19811 [(set (match_operand:V2SF 0 "register_operand" "=y")
19812 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19813 (parallel [(const_int 1) (const_int 0)])))]
19814 "TARGET_3DNOW_A"
19815 "pswapd\\t{%1, %0|%0, %1}"
19816 [(set_attr "type" "mmx")])