c2e05cb8d925b75150bcc8d81c66ab2a7df58d82
[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
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' 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 ;; 47 This is a `prefetch' (3DNow) operation.
97 ;; 48 This is a `prefetchw' operation.
98 ;; 49 This is a 'pavgusb' operation.
99 ;; 50 This is a `pfrcp' operation.
100 ;; 51 This is a `pfrcpit1' operation.
101 ;; 52 This is a `pfrcpit2' operation.
102 ;; 53 This is a `pfrsqrt' operation.
103 ;; 54 This is a `pfrsqrit1' operation.
104
105 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
106 ;; from i386.c.
107
108 ;; In C guard expressions, put expressions which may be compile-time
109 ;; constants first. This allows for better optimization. For
110 ;; example, write "TARGET_64BIT && reload_completed", not
111 ;; "reload_completed && TARGET_64BIT".
112
113 \f
114 ;; Processor type. This attribute must exactly match the processor_type
115 ;; enumeration in i386.h.
116 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
117 (const (symbol_ref "ix86_cpu")))
118
119 ;; A basic instruction type. Refinements due to arguments to be
120 ;; provided in other attributes.
121 (define_attr "type"
122 "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
123 (const_string "other"))
124
125 ;; Main data type used by the insn
126 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
127 (const_string "unknown"))
128
129 ;; Set for i387 operations.
130 (define_attr "i387" ""
131 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
132 (const_int 1)
133 (const_int 0)))
134
135 ;; The (bounding maximum) length of an instruction immediate.
136 (define_attr "length_immediate" ""
137 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
138 (const_int 0)
139 (eq_attr "i387" "1")
140 (const_int 0)
141 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
142 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
143 (eq_attr "type" "imov,test")
144 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
145 (eq_attr "type" "call")
146 (if_then_else (match_operand 0 "constant_call_address_operand" "")
147 (const_int 4)
148 (const_int 0))
149 (eq_attr "type" "callv")
150 (if_then_else (match_operand 1 "constant_call_address_operand" "")
151 (const_int 4)
152 (const_int 0))
153 (eq_attr "type" "ibr")
154 (if_then_else (and (ge (minus (match_dup 0) (pc))
155 (const_int -128))
156 (lt (minus (match_dup 0) (pc))
157 (const_int 124)))
158 (const_int 1)
159 (const_int 4))
160 ]
161 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
162
163 ;; The (bounding maximum) length of an instruction address.
164 (define_attr "length_address" ""
165 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
166 (const_int 0)
167 (and (eq_attr "type" "call")
168 (match_operand 1 "constant_call_address_operand" ""))
169 (const_int 0)
170 (and (eq_attr "type" "callv")
171 (match_operand 1 "constant_call_address_operand" ""))
172 (const_int 0)
173 ]
174 (symbol_ref "ix86_attr_length_address_default (insn)")))
175
176 ;; Set when length prefix is used.
177 (define_attr "prefix_data16" ""
178 (if_then_else (eq_attr "mode" "HI")
179 (const_int 1)
180 (const_int 0)))
181
182 ;; Set when string REP prefix is used.
183 (define_attr "prefix_rep" "" (const_int 0))
184
185 ;; Set when 0f opcode prefix is used.
186 (define_attr "prefix_0f" ""
187 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
188 (const_int 1)
189 (const_int 0)))
190
191 ;; Set when modrm byte is used.
192 (define_attr "modrm" ""
193 (cond [(eq_attr "type" "str,cld")
194 (const_int 0)
195 (eq_attr "i387" "1")
196 (const_int 0)
197 (and (eq_attr "type" "incdec")
198 (ior (match_operand:SI 1 "register_operand" "")
199 (match_operand:HI 1 "register_operand" "")))
200 (const_int 0)
201 (and (eq_attr "type" "push")
202 (not (match_operand 1 "memory_operand" "")))
203 (const_int 0)
204 (and (eq_attr "type" "pop")
205 (not (match_operand 0 "memory_operand" "")))
206 (const_int 0)
207 (and (eq_attr "type" "imov")
208 (and (match_operand 0 "register_operand" "")
209 (match_operand 1 "immediate_operand" "")))
210 (const_int 0)
211 ]
212 (const_int 1)))
213
214 ;; The (bounding maximum) length of an instruction in bytes.
215 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
216 ;; to split it and compute proper length as for other insns.
217 (define_attr "length" ""
218 (cond [(eq_attr "type" "other,multi,fistp")
219 (const_int 16)
220 ]
221 (plus (plus (attr "modrm")
222 (plus (attr "prefix_0f")
223 (plus (attr "i387")
224 (const_int 1))))
225 (plus (attr "prefix_rep")
226 (plus (attr "prefix_data16")
227 (plus (attr "length_immediate")
228 (attr "length_address")))))))
229
230 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
231 ;; `store' if there is a simple memory reference therein, or `unknown'
232 ;; if the instruction is complex.
233
234 (define_attr "memory" "none,load,store,both,unknown"
235 (cond [(eq_attr "type" "other,multi,str")
236 (const_string "unknown")
237 (eq_attr "type" "lea,fcmov,fpspc,cld")
238 (const_string "none")
239 (eq_attr "type" "fistp")
240 (const_string "both")
241 (eq_attr "type" "push")
242 (if_then_else (match_operand 1 "memory_operand" "")
243 (const_string "both")
244 (const_string "store"))
245 (eq_attr "type" "pop,setcc")
246 (if_then_else (match_operand 0 "memory_operand" "")
247 (const_string "both")
248 (const_string "load"))
249 (eq_attr "type" "icmp,test")
250 (if_then_else (ior (match_operand 0 "memory_operand" "")
251 (match_operand 1 "memory_operand" ""))
252 (const_string "load")
253 (const_string "none"))
254 (eq_attr "type" "ibr")
255 (if_then_else (match_operand 0 "memory_operand" "")
256 (const_string "load")
257 (const_string "none"))
258 (eq_attr "type" "call")
259 (if_then_else (match_operand 0 "constant_call_address_operand" "")
260 (const_string "none")
261 (const_string "load"))
262 (eq_attr "type" "callv")
263 (if_then_else (match_operand 1 "constant_call_address_operand" "")
264 (const_string "none")
265 (const_string "load"))
266 (and (eq_attr "type" "alu1,negnot")
267 (match_operand 1 "memory_operand" ""))
268 (const_string "both")
269 (and (match_operand 0 "memory_operand" "")
270 (match_operand 1 "memory_operand" ""))
271 (const_string "both")
272 (match_operand 0 "memory_operand" "")
273 (const_string "store")
274 (match_operand 1 "memory_operand" "")
275 (const_string "load")
276 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
277 (match_operand 2 "memory_operand" ""))
278 (const_string "load")
279 (and (eq_attr "type" "icmov")
280 (match_operand 3 "memory_operand" ""))
281 (const_string "load")
282 ]
283 (const_string "none")))
284
285 ;; Indicates if an instruction has both an immediate and a displacement.
286
287 (define_attr "imm_disp" "false,true,unknown"
288 (cond [(eq_attr "type" "other,multi")
289 (const_string "unknown")
290 (and (eq_attr "type" "icmp,test,imov")
291 (and (match_operand 0 "memory_displacement_operand" "")
292 (match_operand 1 "immediate_operand" "")))
293 (const_string "true")
294 (and (eq_attr "type" "alu,ishift,imul,idiv")
295 (and (match_operand 0 "memory_displacement_operand" "")
296 (match_operand 2 "immediate_operand" "")))
297 (const_string "true")
298 ]
299 (const_string "false")))
300
301 ;; Indicates if an FP operation has an integer source.
302
303 (define_attr "fp_int_src" "false,true"
304 (const_string "false"))
305
306 ;; Describe a user's asm statement.
307 (define_asm_attributes
308 [(set_attr "length" "128")
309 (set_attr "type" "multi")])
310 \f
311 ;; Pentium Scheduling
312 ;;
313 ;; The Pentium is an in-order core with two integer pipelines.
314
315 ;; True for insns that behave like prefixed insns on the Pentium.
316 (define_attr "pent_prefix" "false,true"
317 (if_then_else (ior (eq_attr "prefix_0f" "1")
318 (ior (eq_attr "prefix_data16" "1")
319 (eq_attr "prefix_rep" "1")))
320 (const_string "true")
321 (const_string "false")))
322
323 ;; Categorize how an instruction slots.
324
325 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
326 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
327 ;; rules, because it results in noticeably better code on non-MMX Pentium
328 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
329 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
330
331 (define_attr "pent_pair" "uv,pu,pv,np"
332 (cond [(eq_attr "imm_disp" "true")
333 (const_string "np")
334 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
335 (and (eq_attr "type" "pop,push")
336 (eq_attr "memory" "!both")))
337 (if_then_else (eq_attr "pent_prefix" "true")
338 (const_string "pu")
339 (const_string "uv"))
340 (eq_attr "type" "ibr")
341 (const_string "pv")
342 (and (eq_attr "type" "ishift")
343 (match_operand 2 "const_int_operand" ""))
344 (const_string "pu")
345 (and (eq_attr "type" "call")
346 (match_operand 0 "constant_call_address_operand" ""))
347 (const_string "pv")
348 (and (eq_attr "type" "callv")
349 (match_operand 1 "constant_call_address_operand" ""))
350 (const_string "pv")
351 ]
352 (const_string "np")))
353
354 ;; Rough readiness numbers. Fine tuning happens in i386.c.
355 ;;
356 ;; u describes pipe U
357 ;; v describes pipe V
358 ;; uv describes either pipe U or V for those that can issue to either
359 ;; np describes not paring
360 ;; fpu describes fpu
361 ;; fpm describes fp insns of different types are not pipelined.
362 ;;
363 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
364
365 (define_function_unit "pent_np" 1 0
366 (and (eq_attr "cpu" "pentium")
367 (eq_attr "type" "imul"))
368 11 11)
369
370 (define_function_unit "pent_mul" 1 1
371 (and (eq_attr "cpu" "pentium")
372 (eq_attr "type" "imul"))
373 11 11)
374
375 ;; Rep movs takes minimally 12 cycles.
376 (define_function_unit "pent_np" 1 0
377 (and (eq_attr "cpu" "pentium")
378 (eq_attr "type" "str"))
379 12 12)
380
381 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
382 (define_function_unit "pent_np" 1 0
383 (and (eq_attr "cpu" "pentium")
384 (eq_attr "type" "idiv"))
385 46 46)
386
387 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
388 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
389 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
390 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
391 ; like normal fp operation and fist takes 6 cycles.
392
393 (define_function_unit "fpu" 1 0
394 (and (eq_attr "cpu" "pentium")
395 (and (eq_attr "type" "fmov")
396 (and (eq_attr "memory" "load,store")
397 (eq_attr "mode" "XF"))))
398 3 3)
399
400 (define_function_unit "pent_np" 1 0
401 (and (eq_attr "cpu" "pentium")
402 (and (eq_attr "type" "fmov")
403 (and (eq_attr "memory" "load,store")
404 (eq_attr "mode" "XF"))))
405 3 3)
406
407 (define_function_unit "fpu" 1 0
408 (and (eq_attr "cpu" "pentium")
409 (and (eq_attr "type" "fmov")
410 (ior (match_operand 1 "immediate_operand" "")
411 (eq_attr "memory" "store"))))
412 2 2)
413
414 (define_function_unit "pent_np" 1 0
415 (and (eq_attr "cpu" "pentium")
416 (and (eq_attr "type" "fmov")
417 (ior (match_operand 1 "immediate_operand" "")
418 (eq_attr "memory" "store"))))
419 2 2)
420
421 (define_function_unit "pent_np" 1 0
422 (and (eq_attr "cpu" "pentium")
423 (eq_attr "type" "cld"))
424 2 2)
425
426 (define_function_unit "fpu" 1 0
427 (and (eq_attr "cpu" "pentium")
428 (and (eq_attr "type" "fmov")
429 (eq_attr "memory" "none,load")))
430 1 1)
431
432 ; Read/Modify/Write instructions usually take 3 cycles.
433 (define_function_unit "pent_u" 1 0
434 (and (eq_attr "cpu" "pentium")
435 (and (eq_attr "type" "alu,alu1,ishift")
436 (and (eq_attr "pent_pair" "pu")
437 (eq_attr "memory" "both"))))
438 3 3)
439
440 (define_function_unit "pent_uv" 2 0
441 (and (eq_attr "cpu" "pentium")
442 (and (eq_attr "type" "alu,alu1,ishift")
443 (and (eq_attr "pent_pair" "!np")
444 (eq_attr "memory" "both"))))
445 3 3)
446
447 (define_function_unit "pent_np" 1 0
448 (and (eq_attr "cpu" "pentium")
449 (and (eq_attr "type" "alu,alu1,negnot,ishift")
450 (and (eq_attr "pent_pair" "np")
451 (eq_attr "memory" "both"))))
452 3 3)
453
454 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
455 (define_function_unit "pent_u" 1 0
456 (and (eq_attr "cpu" "pentium")
457 (and (eq_attr "type" "alu,ishift")
458 (and (eq_attr "pent_pair" "pu")
459 (eq_attr "memory" "load,store"))))
460 2 2)
461
462 (define_function_unit "pent_uv" 2 0
463 (and (eq_attr "cpu" "pentium")
464 (and (eq_attr "type" "alu,ishift")
465 (and (eq_attr "pent_pair" "!np")
466 (eq_attr "memory" "load,store"))))
467 2 2)
468
469 (define_function_unit "pent_np" 1 0
470 (and (eq_attr "cpu" "pentium")
471 (and (eq_attr "type" "alu,ishift")
472 (and (eq_attr "pent_pair" "np")
473 (eq_attr "memory" "load,store"))))
474 2 2)
475
476 ; Insns w/o memory operands and move instructions usually take one cycle.
477 (define_function_unit "pent_u" 1 0
478 (and (eq_attr "cpu" "pentium")
479 (eq_attr "pent_pair" "pu"))
480 1 1)
481
482 (define_function_unit "pent_v" 1 0
483 (and (eq_attr "cpu" "pentium")
484 (eq_attr "pent_pair" "pv"))
485 1 1)
486
487 (define_function_unit "pent_uv" 2 0
488 (and (eq_attr "cpu" "pentium")
489 (eq_attr "pent_pair" "!np"))
490 1 1)
491
492 (define_function_unit "pent_np" 1 0
493 (and (eq_attr "cpu" "pentium")
494 (eq_attr "pent_pair" "np"))
495 1 1)
496
497 ; Pairable insns only conflict with other non-pairable insns.
498 (define_function_unit "pent_np" 1 0
499 (and (eq_attr "cpu" "pentium")
500 (and (eq_attr "type" "alu,alu1,ishift")
501 (and (eq_attr "pent_pair" "!np")
502 (eq_attr "memory" "both"))))
503 3 3
504 [(eq_attr "pent_pair" "np")])
505
506 (define_function_unit "pent_np" 1 0
507 (and (eq_attr "cpu" "pentium")
508 (and (eq_attr "type" "alu,alu1,ishift")
509 (and (eq_attr "pent_pair" "!np")
510 (eq_attr "memory" "load,store"))))
511 2 2
512 [(eq_attr "pent_pair" "np")])
513
514 (define_function_unit "pent_np" 1 0
515 (and (eq_attr "cpu" "pentium")
516 (eq_attr "pent_pair" "!np"))
517 1 1
518 [(eq_attr "pent_pair" "np")])
519
520 ; Floating point instructions usually blocks cycle longer when combined with
521 ; integer instructions, because of the inpaired fxch instruction.
522 (define_function_unit "pent_np" 1 0
523 (and (eq_attr "cpu" "pentium")
524 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
525 2 2
526 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
527
528 (define_function_unit "fpu" 1 0
529 (and (eq_attr "cpu" "pentium")
530 (eq_attr "type" "fcmp,fxch,fsgn"))
531 1 1)
532
533 ; Addition takes 3 cycles; assume other random cruft does as well.
534 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
535 (define_function_unit "fpu" 1 0
536 (and (eq_attr "cpu" "pentium")
537 (eq_attr "type" "fop,fop1,fistp"))
538 3 1)
539
540 ; Multiplication takes 3 cycles and is only half pipelined.
541 (define_function_unit "fpu" 1 0
542 (and (eq_attr "cpu" "pentium")
543 (eq_attr "type" "fmul"))
544 3 1)
545
546 (define_function_unit "pent_mul" 1 1
547 (and (eq_attr "cpu" "pentium")
548 (eq_attr "type" "fmul"))
549 2 2)
550
551 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
552 ; They can overlap with integer insns. Only the last two cycles can overlap
553 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
554 ; Only last two cycles of fsin/fcos can overlap with other instructions.
555 (define_function_unit "fpu" 1 0
556 (and (eq_attr "cpu" "pentium")
557 (eq_attr "type" "fdiv"))
558 39 37)
559
560 (define_function_unit "pent_mul" 1 1
561 (and (eq_attr "cpu" "pentium")
562 (eq_attr "type" "fdiv"))
563 39 39)
564
565 (define_function_unit "fpu" 1 0
566 (and (eq_attr "cpu" "pentium")
567 (eq_attr "type" "fpspc"))
568 70 68)
569
570 (define_function_unit "pent_mul" 1 1
571 (and (eq_attr "cpu" "pentium")
572 (eq_attr "type" "fpspc"))
573 70 70)
574 \f
575 ;; Pentium Pro/PII Scheduling
576 ;;
577 ;; The PPro has an out-of-order core, but the instruction decoders are
578 ;; naturally in-order and asymmetric. We get best performance by scheduling
579 ;; for the decoders, for in doing so we give the oo execution unit the
580 ;; most choices.
581
582 ;; Categorize how many uops an ia32 instruction evaluates to:
583 ;; one -- an instruction with 1 uop can be decoded by any of the
584 ;; three decoders.
585 ;; few -- an instruction with 1 to 4 uops can be decoded only by
586 ;; decoder 0.
587 ;; many -- a complex instruction may take an unspecified number of
588 ;; cycles to decode in decoder 0.
589
590 (define_attr "ppro_uops" "one,few,many"
591 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
592 (const_string "many")
593 (eq_attr "type" "icmov,fcmov,str,cld")
594 (const_string "few")
595 (eq_attr "type" "imov")
596 (if_then_else (eq_attr "memory" "store,both")
597 (const_string "few")
598 (const_string "one"))
599 (eq_attr "memory" "!none")
600 (const_string "few")
601 ]
602 (const_string "one")))
603
604 ;; Rough readiness numbers. Fine tuning happens in i386.c.
605 ;;
606 ;; p0 describes port 0.
607 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
608 ;; p2 describes port 2 for loads.
609 ;; p34 describes ports 3 and 4 for stores.
610 ;; fpu describes the fpu accessed via port 0.
611 ;; ??? It is less than clear if there are separate fadd and fmul units
612 ;; that could operate in parallel.
613 ;;
614 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
615
616 (define_function_unit "ppro_p0" 1 0
617 (and (eq_attr "cpu" "pentiumpro")
618 (eq_attr "type" "ishift,lea,ibr,cld"))
619 1 1)
620
621 (define_function_unit "ppro_p0" 1 0
622 (and (eq_attr "cpu" "pentiumpro")
623 (eq_attr "type" "imul"))
624 4 1)
625
626 ;; ??? Does the divider lock out the pipe while it works,
627 ;; or is there a disconnected unit?
628 (define_function_unit "ppro_p0" 1 0
629 (and (eq_attr "cpu" "pentiumpro")
630 (eq_attr "type" "idiv"))
631 17 17)
632
633 (define_function_unit "ppro_p0" 1 0
634 (and (eq_attr "cpu" "pentiumpro")
635 (eq_attr "type" "fop,fop1,fsgn,fistp"))
636 3 1)
637
638 (define_function_unit "ppro_p0" 1 0
639 (and (eq_attr "cpu" "pentiumpro")
640 (eq_attr "type" "fcmov"))
641 2 1)
642
643 (define_function_unit "ppro_p0" 1 0
644 (and (eq_attr "cpu" "pentiumpro")
645 (eq_attr "type" "fcmp"))
646 1 1)
647
648 (define_function_unit "ppro_p0" 1 0
649 (and (eq_attr "cpu" "pentiumpro")
650 (eq_attr "type" "fmov"))
651 1 1)
652
653 (define_function_unit "ppro_p0" 1 0
654 (and (eq_attr "cpu" "pentiumpro")
655 (eq_attr "type" "fmul"))
656 5 1)
657
658 (define_function_unit "ppro_p0" 1 0
659 (and (eq_attr "cpu" "pentiumpro")
660 (eq_attr "type" "fdiv,fpspc"))
661 56 1)
662
663 (define_function_unit "ppro_p01" 2 0
664 (and (eq_attr "cpu" "pentiumpro")
665 (eq_attr "type" "!imov,fmov"))
666 1 1)
667
668 (define_function_unit "ppro_p01" 2 0
669 (and (and (eq_attr "cpu" "pentiumpro")
670 (eq_attr "type" "imov,fmov"))
671 (eq_attr "memory" "none"))
672 1 1)
673
674 (define_function_unit "ppro_p2" 1 0
675 (and (eq_attr "cpu" "pentiumpro")
676 (ior (eq_attr "type" "pop")
677 (eq_attr "memory" "load,both")))
678 3 1)
679
680 (define_function_unit "ppro_p34" 1 0
681 (and (eq_attr "cpu" "pentiumpro")
682 (ior (eq_attr "type" "push")
683 (eq_attr "memory" "store,both")))
684 1 1)
685
686 (define_function_unit "fpu" 1 0
687 (and (eq_attr "cpu" "pentiumpro")
688 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
689 1 1)
690
691 (define_function_unit "fpu" 1 0
692 (and (eq_attr "cpu" "pentiumpro")
693 (eq_attr "type" "fmul"))
694 5 2)
695
696 (define_function_unit "fpu" 1 0
697 (and (eq_attr "cpu" "pentiumpro")
698 (eq_attr "type" "fdiv,fpspc"))
699 56 56)
700
701 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
702 (define_function_unit "fpu" 1 0
703 (and (eq_attr "cpu" "pentiumpro")
704 (eq_attr "type" "imul"))
705 4 1)
706 \f
707 ;; AMD K6/K6-2 Scheduling
708 ;;
709 ;; The K6 has similar architecture to PPro. Important difference is, that
710 ;; there are only two decoders and they seems to be much slower than execution
711 ;; units. So we have to pay much more attention to proper decoding for
712 ;; schedulers. We share most of scheduler code for PPro in i386.c
713 ;;
714 ;; The fp unit is not pipelined and do one operation per two cycles including
715 ;; the FXCH.
716 ;;
717 ;; alu describes both ALU units (ALU-X and ALU-Y).
718 ;; alux describes X alu unit
719 ;; fpu describes FPU unit
720 ;; load describes load unit.
721 ;; branch describes branch unit.
722 ;; store decsribes store unit. This unit is not modelled completely and only
723 ;; used to model lea operation. Otherwise it lie outside of the critical
724 ;; path.
725 ;;
726 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
727
728 ;; The decoder specification is in the PPro section above!
729
730 ;; Shift instructions and certain arithmetic are issued only to X pipe.
731 (define_function_unit "k6_alux" 1 0
732 (and (eq_attr "cpu" "k6")
733 (eq_attr "type" "ishift,alu1,negnot,cld"))
734 1 1)
735
736 ;; The QI mode arithmetic is issued to X pipe only.
737 (define_function_unit "k6_alux" 1 0
738 (and (eq_attr "cpu" "k6")
739 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
740 (match_operand:QI 0 "general_operand" "")))
741 1 1)
742
743 (define_function_unit "k6_alu" 2 0
744 (and (eq_attr "cpu" "k6")
745 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
746 1 1)
747
748 (define_function_unit "k6_alu" 2 0
749 (and (eq_attr "cpu" "k6")
750 (and (eq_attr "type" "imov")
751 (eq_attr "memory" "none")))
752 1 1)
753
754 (define_function_unit "k6_branch" 1 0
755 (and (eq_attr "cpu" "k6")
756 (eq_attr "type" "call,callv,ibr"))
757 1 1)
758
759 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
760 (define_function_unit "k6_load" 1 0
761 (and (eq_attr "cpu" "k6")
762 (ior (eq_attr "type" "pop")
763 (eq_attr "memory" "load,both")))
764 1 1)
765
766 (define_function_unit "k6_load" 1 0
767 (and (eq_attr "cpu" "k6")
768 (and (eq_attr "type" "str")
769 (eq_attr "memory" "load,both")))
770 10 10)
771
772 ;; Lea have two instructions, so latency is probably 2
773 (define_function_unit "k6_store" 1 0
774 (and (eq_attr "cpu" "k6")
775 (eq_attr "type" "lea"))
776 2 1)
777
778 (define_function_unit "k6_store" 1 0
779 (and (eq_attr "cpu" "k6")
780 (eq_attr "type" "str"))
781 10 10)
782
783 (define_function_unit "k6_store" 1 0
784 (and (eq_attr "cpu" "k6")
785 (ior (eq_attr "type" "push")
786 (eq_attr "memory" "store,both")))
787 1 1)
788
789 (define_function_unit "k6_fpu" 1 1
790 (and (eq_attr "cpu" "k6")
791 (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
792 2 2)
793
794 (define_function_unit "k6_fpu" 1 1
795 (and (eq_attr "cpu" "k6")
796 (eq_attr "type" "fmul"))
797 2 2)
798
799 ;; ??? Guess
800 (define_function_unit "k6_fpu" 1 1
801 (and (eq_attr "cpu" "k6")
802 (eq_attr "type" "fdiv,fpspc"))
803 56 56)
804
805 (define_function_unit "k6_alu" 2 0
806 (and (eq_attr "cpu" "k6")
807 (eq_attr "type" "imul"))
808 2 2)
809
810 (define_function_unit "k6_alux" 1 0
811 (and (eq_attr "cpu" "k6")
812 (eq_attr "type" "imul"))
813 2 2)
814
815 ;; ??? Guess
816 (define_function_unit "k6_alu" 2 0
817 (and (eq_attr "cpu" "k6")
818 (eq_attr "type" "idiv"))
819 17 17)
820
821 (define_function_unit "k6_alux" 1 0
822 (and (eq_attr "cpu" "k6")
823 (eq_attr "type" "idiv"))
824 17 17)
825 \f
826 ;; AMD Athlon Scheduling
827 ;;
828 ;; The Athlon does contain three pipelined FP units, three integer units and
829 ;; three address generation units.
830 ;;
831 ;; The predecode logic is determining boundaries of instructions in the 64
832 ;; byte cache line. So the cache line straddling problem of K6 might be issue
833 ;; here as well, but it is not noted in the documentation.
834 ;;
835 ;; Three DirectPath instructions decoders and only one VectorPath decoder
836 ;; is available. They can decode three DirectPath instructions or one VectorPath
837 ;; instruction per cycle.
838 ;; Decoded macro instructions are then passed to 72 entry instruction control
839 ;; unit, that passes
840 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
841 ;;
842 ;; The load/store queue unit is not attached to the schedulers but
843 ;; communicates with all the execution units seperately instead.
844
845 (define_attr "athlon_decode" "direct,vector"
846 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
847 (const_string "vector")
848 (and (eq_attr "type" "push")
849 (match_operand 1 "memory_operand" ""))
850 (const_string "vector")
851 (and (eq_attr "type" "fmov")
852 (and (eq_attr "memory" "load,store")
853 (eq_attr "mode" "XF")))
854 (const_string "vector")]
855 (const_string "direct")))
856
857 (define_function_unit "athlon_vectordec" 1 0
858 (and (eq_attr "cpu" "athlon")
859 (eq_attr "athlon_decode" "vector"))
860 1 1)
861
862 (define_function_unit "athlon_directdec" 3 0
863 (and (eq_attr "cpu" "athlon")
864 (eq_attr "athlon_decode" "direct"))
865 1 1)
866
867 (define_function_unit "athlon_vectordec" 1 0
868 (and (eq_attr "cpu" "athlon")
869 (eq_attr "athlon_decode" "direct"))
870 1 1 [(eq_attr "athlon_decode" "vector")])
871
872 (define_function_unit "athlon_ieu" 3 0
873 (and (eq_attr "cpu" "athlon")
874 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
875 1 1)
876
877 (define_function_unit "athlon_ieu" 3 0
878 (and (eq_attr "cpu" "athlon")
879 (eq_attr "type" "str"))
880 15 15)
881
882 (define_function_unit "athlon_ieu" 3 0
883 (and (eq_attr "cpu" "athlon")
884 (eq_attr "type" "imul"))
885 5 0)
886
887 (define_function_unit "athlon_ieu" 3 0
888 (and (eq_attr "cpu" "athlon")
889 (eq_attr "type" "idiv"))
890 42 0)
891
892 (define_function_unit "athlon_muldiv" 1 0
893 (and (eq_attr "cpu" "athlon")
894 (eq_attr "type" "imul"))
895 5 0)
896
897 (define_function_unit "athlon_muldiv" 1 0
898 (and (eq_attr "cpu" "athlon")
899 (eq_attr "type" "idiv"))
900 42 42)
901
902 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
903 (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
904 (const_string "add")
905 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
906 (const_string "mul")
907 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
908 (const_string "store")
909 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
910 (const_string "any")
911 (and (eq_attr "type" "fmov")
912 (ior (match_operand:SI 1 "register_operand" "")
913 (match_operand 1 "immediate_operand" "")))
914 (const_string "store")
915 (eq_attr "type" "fmov")
916 (const_string "muladd")]
917 (const_string "none")))
918
919 ;; We use latencies 1 for definitions. This is OK to model colisions
920 ;; in execution units. The real latencies are modeled in the "fp" pipeline.
921
922 ;; fsin, fcos: 96-192
923 ;; fsincos: 107-211
924 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
925 (define_function_unit "athlon_fp" 3 0
926 (and (eq_attr "cpu" "athlon")
927 (eq_attr "type" "fpspc"))
928 100 1)
929
930 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
931 (define_function_unit "athlon_fp" 3 0
932 (and (eq_attr "cpu" "athlon")
933 (eq_attr "type" "fdiv"))
934 24 1)
935
936 (define_function_unit "athlon_fp" 3 0
937 (and (eq_attr "cpu" "athlon")
938 (eq_attr "type" "fop,fop1,fmul,fistp"))
939 4 1)
940
941 ;; XFmode loads are slow.
942 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
943 ;; there are no dependent instructions.
944
945 (define_function_unit "athlon_fp" 3 0
946 (and (eq_attr "cpu" "athlon")
947 (and (eq_attr "type" "fmov")
948 (and (eq_attr "memory" "load")
949 (eq_attr "mode" "XF"))))
950 10 1)
951
952 (define_function_unit "athlon_fp" 3 0
953 (and (eq_attr "cpu" "athlon")
954 (eq_attr "type" "fmov,fsgn"))
955 2 1)
956
957 ;; fcmp and ftst instructions
958 (define_function_unit "athlon_fp" 3 0
959 (and (eq_attr "cpu" "athlon")
960 (and (eq_attr "type" "fcmp")
961 (eq_attr "athlon_decode" "direct")))
962 3 1)
963
964 ;; fcmpi instructions.
965 (define_function_unit "athlon_fp" 3 0
966 (and (eq_attr "cpu" "athlon")
967 (and (eq_attr "type" "fcmp")
968 (eq_attr "athlon_decode" "vector")))
969 3 1)
970
971 (define_function_unit "athlon_fp" 3 0
972 (and (eq_attr "cpu" "athlon")
973 (eq_attr "type" "fcmov"))
974 7 1)
975
976 (define_function_unit "athlon_fp_mul" 1 0
977 (and (eq_attr "cpu" "athlon")
978 (eq_attr "athlon_fpunits" "mul"))
979 1 1)
980
981 (define_function_unit "athlon_fp_add" 1 0
982 (and (eq_attr "cpu" "athlon")
983 (eq_attr "athlon_fpunits" "add"))
984 1 1)
985
986 (define_function_unit "athlon_fp_muladd" 2 0
987 (and (eq_attr "cpu" "athlon")
988 (eq_attr "athlon_fpunits" "muladd,mul,add"))
989 1 1)
990
991 (define_function_unit "athlon_fp_store" 1 0
992 (and (eq_attr "cpu" "athlon")
993 (eq_attr "athlon_fpunits" "store"))
994 1 1)
995
996 ;; We don't need to model the Adress Generation Unit, since we don't model
997 ;; the re-order buffer yet and thus we never schedule more than three operations
998 ;; at time. Later we may want to experiment with MD_SCHED macros modeling the
999 ;; decoders independently on the functional units.
1000
1001 ;(define_function_unit "athlon_agu" 3 0
1002 ; (and (eq_attr "cpu" "athlon")
1003 ; (and (eq_attr "memory" "!none")
1004 ; (eq_attr "athlon_fpunits" "none")))
1005 ; 1 1)
1006
1007 ;; Model load unit to avoid too long sequences of loads. We don't need to
1008 ;; model store queue, since it is hardly going to be bottleneck.
1009
1010 (define_function_unit "athlon_load" 2 0
1011 (and (eq_attr "cpu" "athlon")
1012 (eq_attr "memory" "load,both"))
1013 1 1)
1014
1015 \f
1016 ;; Compare instructions.
1017
1018 ;; All compare insns have expanders that save the operands away without
1019 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
1020 ;; after the cmp) will actually emit the cmpM.
1021
1022 (define_expand "cmpdi"
1023 [(set (reg:CC 17)
1024 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1025 (match_operand:DI 1 "x86_64_general_operand" "")))]
1026 ""
1027 {
1028 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1029 operands[0] = force_reg (DImode, operands[0]);
1030 ix86_compare_op0 = operands[0];
1031 ix86_compare_op1 = operands[1];
1032 DONE;
1033 })
1034
1035 (define_expand "cmpsi"
1036 [(set (reg:CC 17)
1037 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1038 (match_operand:SI 1 "general_operand" "")))]
1039 ""
1040 {
1041 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1042 operands[0] = force_reg (SImode, operands[0]);
1043 ix86_compare_op0 = operands[0];
1044 ix86_compare_op1 = operands[1];
1045 DONE;
1046 })
1047
1048 (define_expand "cmphi"
1049 [(set (reg:CC 17)
1050 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
1051 (match_operand:HI 1 "general_operand" "")))]
1052 ""
1053 {
1054 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1055 operands[0] = force_reg (HImode, operands[0]);
1056 ix86_compare_op0 = operands[0];
1057 ix86_compare_op1 = operands[1];
1058 DONE;
1059 })
1060
1061 (define_expand "cmpqi"
1062 [(set (reg:CC 17)
1063 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
1064 (match_operand:QI 1 "general_operand" "")))]
1065 "TARGET_QIMODE_MATH"
1066 {
1067 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1068 operands[0] = force_reg (QImode, operands[0]);
1069 ix86_compare_op0 = operands[0];
1070 ix86_compare_op1 = operands[1];
1071 DONE;
1072 })
1073
1074 (define_insn "cmpdi_ccno_1_rex64"
1075 [(set (reg 17)
1076 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1077 (match_operand:DI 1 "const0_operand" "n,n")))]
1078 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1079 "@
1080 test{q}\t{%0, %0|%0, %0}
1081 cmp{q}\t{%1, %0|%0, %1}"
1082 [(set_attr "type" "test,icmp")
1083 (set_attr "length_immediate" "0,1")
1084 (set_attr "mode" "DI")])
1085
1086 (define_insn "*cmpdi_minus_1_rex64"
1087 [(set (reg 17)
1088 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1089 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1090 (const_int 0)))]
1091 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
1092 "cmp{q}\t{%1, %0|%0, %1}"
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "DI")])
1095
1096 (define_expand "cmpdi_1_rex64"
1097 [(set (reg:CC 17)
1098 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1099 (match_operand:DI 1 "general_operand" "")))]
1100 "TARGET_64BIT"
1101 "")
1102
1103 (define_insn "cmpdi_1_insn_rex64"
1104 [(set (reg 17)
1105 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1106 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1107 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1108 "cmp{q}\t{%1, %0|%0, %1}"
1109 [(set_attr "type" "icmp")
1110 (set_attr "mode" "DI")])
1111
1112
1113 (define_insn "*cmpsi_ccno_1"
1114 [(set (reg 17)
1115 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1116 (match_operand:SI 1 "const0_operand" "n,n")))]
1117 "ix86_match_ccmode (insn, CCNOmode)"
1118 "@
1119 test{l}\t{%0, %0|%0, %0}
1120 cmp{l}\t{%1, %0|%0, %1}"
1121 [(set_attr "type" "test,icmp")
1122 (set_attr "length_immediate" "0,1")
1123 (set_attr "mode" "SI")])
1124
1125 (define_insn "*cmpsi_minus_1"
1126 [(set (reg 17)
1127 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1128 (match_operand:SI 1 "general_operand" "ri,mr"))
1129 (const_int 0)))]
1130 "ix86_match_ccmode (insn, CCGOCmode)"
1131 "cmp{l}\t{%1, %0|%0, %1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "mode" "SI")])
1134
1135 (define_expand "cmpsi_1"
1136 [(set (reg:CC 17)
1137 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1138 (match_operand:SI 1 "general_operand" "ri,mr")))]
1139 ""
1140 "")
1141
1142 (define_insn "*cmpsi_1_insn"
1143 [(set (reg 17)
1144 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1145 (match_operand:SI 1 "general_operand" "ri,mr")))]
1146 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1147 && ix86_match_ccmode (insn, CCmode)"
1148 "cmp{l}\t{%1, %0|%0, %1}"
1149 [(set_attr "type" "icmp")
1150 (set_attr "mode" "SI")])
1151
1152 (define_insn "*cmphi_ccno_1"
1153 [(set (reg 17)
1154 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1155 (match_operand:HI 1 "const0_operand" "n,n")))]
1156 "ix86_match_ccmode (insn, CCNOmode)"
1157 "@
1158 test{w}\t{%0, %0|%0, %0}
1159 cmp{w}\t{%1, %0|%0, %1}"
1160 [(set_attr "type" "test,icmp")
1161 (set_attr "length_immediate" "0,1")
1162 (set_attr "mode" "HI")])
1163
1164 (define_insn "*cmphi_minus_1"
1165 [(set (reg 17)
1166 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1167 (match_operand:HI 1 "general_operand" "ri,mr"))
1168 (const_int 0)))]
1169 "ix86_match_ccmode (insn, CCGOCmode)"
1170 "cmp{w}\t{%1, %0|%0, %1}"
1171 [(set_attr "type" "icmp")
1172 (set_attr "mode" "HI")])
1173
1174 (define_insn "*cmphi_1"
1175 [(set (reg 17)
1176 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1177 (match_operand:HI 1 "general_operand" "ri,mr")))]
1178 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1179 && ix86_match_ccmode (insn, CCmode)"
1180 "cmp{w}\t{%1, %0|%0, %1}"
1181 [(set_attr "type" "icmp")
1182 (set_attr "mode" "HI")])
1183
1184 (define_insn "*cmpqi_ccno_1"
1185 [(set (reg 17)
1186 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1187 (match_operand:QI 1 "const0_operand" "n,n")))]
1188 "ix86_match_ccmode (insn, CCNOmode)"
1189 "@
1190 test{b}\t{%0, %0|%0, %0}
1191 cmp{b}\t{$0, %0|%0, 0}"
1192 [(set_attr "type" "test,icmp")
1193 (set_attr "length_immediate" "0,1")
1194 (set_attr "mode" "QI")])
1195
1196 (define_insn "*cmpqi_1"
1197 [(set (reg 17)
1198 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1199 (match_operand:QI 1 "general_operand" "qi,mq")))]
1200 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1201 && ix86_match_ccmode (insn, CCmode)"
1202 "cmp{b}\t{%1, %0|%0, %1}"
1203 [(set_attr "type" "icmp")
1204 (set_attr "mode" "QI")])
1205
1206 (define_insn "*cmpqi_minus_1"
1207 [(set (reg 17)
1208 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1209 (match_operand:QI 1 "general_operand" "qi,mq"))
1210 (const_int 0)))]
1211 "ix86_match_ccmode (insn, CCGOCmode)"
1212 "cmp{b}\t{%1, %0|%0, %1}"
1213 [(set_attr "type" "icmp")
1214 (set_attr "mode" "QI")])
1215
1216 (define_insn "*cmpqi_ext_1"
1217 [(set (reg 17)
1218 (compare
1219 (match_operand:QI 0 "general_operand" "Qm")
1220 (subreg:QI
1221 (zero_extract:SI
1222 (match_operand 1 "ext_register_operand" "Q")
1223 (const_int 8)
1224 (const_int 8)) 0)))]
1225 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1226 "cmp{b}\t{%h1, %0|%0, %h1}"
1227 [(set_attr "type" "icmp")
1228 (set_attr "mode" "QI")])
1229
1230 (define_insn "*cmpqi_ext_1_rex64"
1231 [(set (reg 17)
1232 (compare
1233 (match_operand:QI 0 "register_operand" "Q")
1234 (subreg:QI
1235 (zero_extract:SI
1236 (match_operand 1 "ext_register_operand" "Q")
1237 (const_int 8)
1238 (const_int 8)) 0)))]
1239 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1240 "cmp{b}\t{%h1, %0|%0, %h1}"
1241 [(set_attr "type" "icmp")
1242 (set_attr "mode" "QI")])
1243
1244 (define_insn "*cmpqi_ext_2"
1245 [(set (reg 17)
1246 (compare
1247 (subreg:QI
1248 (zero_extract:SI
1249 (match_operand 0 "ext_register_operand" "Q")
1250 (const_int 8)
1251 (const_int 8)) 0)
1252 (match_operand:QI 1 "const0_operand" "n")))]
1253 "ix86_match_ccmode (insn, CCNOmode)"
1254 "test{b}\t%h0, %h0"
1255 [(set_attr "type" "test")
1256 (set_attr "length_immediate" "0")
1257 (set_attr "mode" "QI")])
1258
1259 (define_expand "cmpqi_ext_3"
1260 [(set (reg:CC 17)
1261 (compare:CC
1262 (subreg:QI
1263 (zero_extract:SI
1264 (match_operand 0 "ext_register_operand" "")
1265 (const_int 8)
1266 (const_int 8)) 0)
1267 (match_operand:QI 1 "general_operand" "")))]
1268 ""
1269 "")
1270
1271 (define_insn "cmpqi_ext_3_insn"
1272 [(set (reg 17)
1273 (compare
1274 (subreg:QI
1275 (zero_extract:SI
1276 (match_operand 0 "ext_register_operand" "Q")
1277 (const_int 8)
1278 (const_int 8)) 0)
1279 (match_operand:QI 1 "general_operand" "Qmn")))]
1280 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1281 "cmp{b}\t{%1, %h0|%h0, %1}"
1282 [(set_attr "type" "icmp")
1283 (set_attr "mode" "QI")])
1284
1285 (define_insn "cmpqi_ext_3_insn_rex64"
1286 [(set (reg 17)
1287 (compare
1288 (subreg:QI
1289 (zero_extract:SI
1290 (match_operand 0 "ext_register_operand" "Q")
1291 (const_int 8)
1292 (const_int 8)) 0)
1293 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1294 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1295 "cmp{b}\t{%1, %h0|%h0, %1}"
1296 [(set_attr "type" "icmp")
1297 (set_attr "mode" "QI")])
1298
1299 (define_insn "*cmpqi_ext_4"
1300 [(set (reg 17)
1301 (compare
1302 (subreg:QI
1303 (zero_extract:SI
1304 (match_operand 0 "ext_register_operand" "Q")
1305 (const_int 8)
1306 (const_int 8)) 0)
1307 (subreg:QI
1308 (zero_extract:SI
1309 (match_operand 1 "ext_register_operand" "Q")
1310 (const_int 8)
1311 (const_int 8)) 0)))]
1312 "ix86_match_ccmode (insn, CCmode)"
1313 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1314 [(set_attr "type" "icmp")
1315 (set_attr "mode" "QI")])
1316
1317 ;; These implement float point compares.
1318 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1319 ;; which would allow mix and match FP modes on the compares. Which is what
1320 ;; the old patterns did, but with many more of them.
1321
1322 (define_expand "cmpxf"
1323 [(set (reg:CC 17)
1324 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1325 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1326 "!TARGET_64BIT && TARGET_80387"
1327 {
1328 ix86_compare_op0 = operands[0];
1329 ix86_compare_op1 = operands[1];
1330 DONE;
1331 })
1332
1333 (define_expand "cmptf"
1334 [(set (reg:CC 17)
1335 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1336 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1337 "TARGET_80387"
1338 {
1339 ix86_compare_op0 = operands[0];
1340 ix86_compare_op1 = operands[1];
1341 DONE;
1342 })
1343
1344 (define_expand "cmpdf"
1345 [(set (reg:CC 17)
1346 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1347 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1348 "TARGET_80387 || TARGET_SSE2"
1349 {
1350 ix86_compare_op0 = operands[0];
1351 ix86_compare_op1 = operands[1];
1352 DONE;
1353 })
1354
1355 (define_expand "cmpsf"
1356 [(set (reg:CC 17)
1357 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1358 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1359 "TARGET_80387 || TARGET_SSE"
1360 {
1361 ix86_compare_op0 = operands[0];
1362 ix86_compare_op1 = operands[1];
1363 DONE;
1364 })
1365
1366 ;; FP compares, step 1:
1367 ;; Set the FP condition codes.
1368 ;;
1369 ;; CCFPmode compare with exceptions
1370 ;; CCFPUmode compare with no exceptions
1371
1372 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1373 ;; and that fp moves clobber the condition codes, and that there is
1374 ;; currently no way to describe this fact to reg-stack. So there are
1375 ;; no splitters yet for this.
1376
1377 ;; %%% YIKES! This scheme does not retain a strong connection between
1378 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1379 ;; work! Only allow tos/mem with tos in op 0.
1380 ;;
1381 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1382 ;; things aren't as bad as they sound...
1383
1384 (define_insn "*cmpfp_0"
1385 [(set (match_operand:HI 0 "register_operand" "=a")
1386 (unspec:HI
1387 [(compare:CCFP (match_operand 1 "register_operand" "f")
1388 (match_operand 2 "const0_operand" "X"))] 9))]
1389 "TARGET_80387
1390 && FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1392 {
1393 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1394 return "ftst\;fnstsw\t%0\;fstp\t%y0";
1395 else
1396 return "ftst\;fnstsw\t%0";
1397 }
1398 [(set_attr "type" "multi")
1399 (set_attr "mode" "unknownfp")])
1400
1401 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1402 ;; used to manage the reg stack popping would not be preserved.
1403
1404 (define_insn "*cmpfp_2_sf"
1405 [(set (reg:CCFP 18)
1406 (compare:CCFP
1407 (match_operand:SF 0 "register_operand" "f")
1408 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1409 "TARGET_80387"
1410 "* return output_fp_compare (insn, operands, 0, 0);"
1411 [(set_attr "type" "fcmp")
1412 (set_attr "mode" "SF")])
1413
1414 (define_insn "*cmpfp_2_sf_1"
1415 [(set (match_operand:HI 0 "register_operand" "=a")
1416 (unspec:HI
1417 [(compare:CCFP
1418 (match_operand:SF 1 "register_operand" "f")
1419 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1420 "TARGET_80387"
1421 "* return output_fp_compare (insn, operands, 2, 0);"
1422 [(set_attr "type" "fcmp")
1423 (set_attr "mode" "SF")])
1424
1425 (define_insn "*cmpfp_2_df"
1426 [(set (reg:CCFP 18)
1427 (compare:CCFP
1428 (match_operand:DF 0 "register_operand" "f")
1429 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1430 "TARGET_80387"
1431 "* return output_fp_compare (insn, operands, 0, 0);"
1432 [(set_attr "type" "fcmp")
1433 (set_attr "mode" "DF")])
1434
1435 (define_insn "*cmpfp_2_df_1"
1436 [(set (match_operand:HI 0 "register_operand" "=a")
1437 (unspec:HI
1438 [(compare:CCFP
1439 (match_operand:DF 1 "register_operand" "f")
1440 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1441 "TARGET_80387"
1442 "* return output_fp_compare (insn, operands, 2, 0);"
1443 [(set_attr "type" "multi")
1444 (set_attr "mode" "DF")])
1445
1446 (define_insn "*cmpfp_2_xf"
1447 [(set (reg:CCFP 18)
1448 (compare:CCFP
1449 (match_operand:XF 0 "register_operand" "f")
1450 (match_operand:XF 1 "register_operand" "f")))]
1451 "!TARGET_64BIT && TARGET_80387"
1452 "* return output_fp_compare (insn, operands, 0, 0);"
1453 [(set_attr "type" "fcmp")
1454 (set_attr "mode" "XF")])
1455
1456 (define_insn "*cmpfp_2_tf"
1457 [(set (reg:CCFP 18)
1458 (compare:CCFP
1459 (match_operand:TF 0 "register_operand" "f")
1460 (match_operand:TF 1 "register_operand" "f")))]
1461 "TARGET_80387"
1462 "* return output_fp_compare (insn, operands, 0, 0);"
1463 [(set_attr "type" "fcmp")
1464 (set_attr "mode" "XF")])
1465
1466 (define_insn "*cmpfp_2_xf_1"
1467 [(set (match_operand:HI 0 "register_operand" "=a")
1468 (unspec:HI
1469 [(compare:CCFP
1470 (match_operand:XF 1 "register_operand" "f")
1471 (match_operand:XF 2 "register_operand" "f"))] 9))]
1472 "!TARGET_64BIT && TARGET_80387"
1473 "* return output_fp_compare (insn, operands, 2, 0);"
1474 [(set_attr "type" "multi")
1475 (set_attr "mode" "XF")])
1476
1477 (define_insn "*cmpfp_2_tf_1"
1478 [(set (match_operand:HI 0 "register_operand" "=a")
1479 (unspec:HI
1480 [(compare:CCFP
1481 (match_operand:TF 1 "register_operand" "f")
1482 (match_operand:TF 2 "register_operand" "f"))] 9))]
1483 "TARGET_80387"
1484 "* return output_fp_compare (insn, operands, 2, 0);"
1485 [(set_attr "type" "multi")
1486 (set_attr "mode" "XF")])
1487
1488 (define_insn "*cmpfp_2u"
1489 [(set (reg:CCFPU 18)
1490 (compare:CCFPU
1491 (match_operand 0 "register_operand" "f")
1492 (match_operand 1 "register_operand" "f")))]
1493 "TARGET_80387
1494 && FLOAT_MODE_P (GET_MODE (operands[0]))
1495 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1496 "* return output_fp_compare (insn, operands, 0, 1);"
1497 [(set_attr "type" "fcmp")
1498 (set_attr "mode" "unknownfp")])
1499
1500 (define_insn "*cmpfp_2u_1"
1501 [(set (match_operand:HI 0 "register_operand" "=a")
1502 (unspec:HI
1503 [(compare:CCFPU
1504 (match_operand 1 "register_operand" "f")
1505 (match_operand 2 "register_operand" "f"))] 9))]
1506 "TARGET_80387
1507 && FLOAT_MODE_P (GET_MODE (operands[1]))
1508 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1509 "* return output_fp_compare (insn, operands, 2, 1);"
1510 [(set_attr "type" "multi")
1511 (set_attr "mode" "unknownfp")])
1512
1513 ;; Patterns to match the SImode-in-memory ficom instructions.
1514 ;;
1515 ;; %%% Play games with accepting gp registers, as otherwise we have to
1516 ;; force them to memory during rtl generation, which is no good. We
1517 ;; can get rid of this once we teach reload to do memory input reloads
1518 ;; via pushes.
1519
1520 (define_insn "*ficom_1"
1521 [(set (reg:CCFP 18)
1522 (compare:CCFP
1523 (match_operand 0 "register_operand" "f,f")
1524 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1525 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1527 "#")
1528
1529 ;; Split the not-really-implemented gp register case into a
1530 ;; push-op-pop sequence.
1531 ;;
1532 ;; %%% This is most efficient, but am I gonna get in trouble
1533 ;; for separating cc0_setter and cc0_user?
1534
1535 (define_split
1536 [(set (reg:CCFP 18)
1537 (compare:CCFP
1538 (match_operand:SF 0 "register_operand" "")
1539 (float (match_operand:SI 1 "register_operand" ""))))]
1540 "0 && TARGET_80387 && reload_completed"
1541 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1542 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1543 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1544 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1545 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1546 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1547
1548 ;; FP compares, step 2
1549 ;; Move the fpsw to ax.
1550
1551 (define_insn "x86_fnstsw_1"
1552 [(set (match_operand:HI 0 "register_operand" "=a")
1553 (unspec:HI [(reg 18)] 9))]
1554 "TARGET_80387"
1555 "fnstsw\t%0"
1556 [(set_attr "length" "2")
1557 (set_attr "mode" "SI")
1558 (set_attr "i387" "1")
1559 (set_attr "ppro_uops" "few")])
1560
1561 ;; FP compares, step 3
1562 ;; Get ax into flags, general case.
1563
1564 (define_insn "x86_sahf_1"
1565 [(set (reg:CC 17)
1566 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1567 "!TARGET_64BIT"
1568 "sahf"
1569 [(set_attr "length" "1")
1570 (set_attr "athlon_decode" "vector")
1571 (set_attr "mode" "SI")
1572 (set_attr "ppro_uops" "one")])
1573
1574 ;; Pentium Pro can do steps 1 through 3 in one go.
1575
1576 (define_insn "*cmpfp_i"
1577 [(set (reg:CCFP 17)
1578 (compare:CCFP (match_operand 0 "register_operand" "f")
1579 (match_operand 1 "register_operand" "f")))]
1580 "TARGET_80387 && TARGET_CMOVE
1581 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1582 && FLOAT_MODE_P (GET_MODE (operands[0]))
1583 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1584 "* return output_fp_compare (insn, operands, 1, 0);"
1585 [(set_attr "type" "fcmp")
1586 (set_attr "mode" "unknownfp")
1587 (set_attr "athlon_decode" "vector")])
1588
1589 (define_insn "*cmpfp_i_sse"
1590 [(set (reg:CCFP 17)
1591 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1592 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1593 "TARGET_80387
1594 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1596 "* return output_fp_compare (insn, operands, 1, 0);"
1597 [(set_attr "type" "fcmp,sse")
1598 (set_attr "mode" "unknownfp")
1599 (set_attr "athlon_decode" "vector")])
1600
1601 (define_insn "*cmpfp_i_sse_only"
1602 [(set (reg:CCFP 17)
1603 (compare:CCFP (match_operand 0 "register_operand" "x")
1604 (match_operand 1 "nonimmediate_operand" "xm")))]
1605 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1606 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1607 "* return output_fp_compare (insn, operands, 1, 0);"
1608 [(set_attr "type" "sse")
1609 (set_attr "mode" "unknownfp")
1610 (set_attr "athlon_decode" "vector")])
1611
1612 (define_insn "*cmpfp_iu"
1613 [(set (reg:CCFPU 17)
1614 (compare:CCFPU (match_operand 0 "register_operand" "f")
1615 (match_operand 1 "register_operand" "f")))]
1616 "TARGET_80387 && TARGET_CMOVE
1617 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1618 && FLOAT_MODE_P (GET_MODE (operands[0]))
1619 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1620 "* return output_fp_compare (insn, operands, 1, 1);"
1621 [(set_attr "type" "fcmp")
1622 (set_attr "mode" "unknownfp")
1623 (set_attr "athlon_decode" "vector")])
1624
1625 (define_insn "*cmpfp_iu_sse"
1626 [(set (reg:CCFPU 17)
1627 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1628 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1629 "TARGET_80387
1630 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1631 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1632 "* return output_fp_compare (insn, operands, 1, 1);"
1633 [(set_attr "type" "fcmp,sse")
1634 (set_attr "mode" "unknownfp")
1635 (set_attr "athlon_decode" "vector")])
1636
1637 (define_insn "*cmpfp_iu_sse_only"
1638 [(set (reg:CCFPU 17)
1639 (compare:CCFPU (match_operand 0 "register_operand" "x")
1640 (match_operand 1 "nonimmediate_operand" "xm")))]
1641 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1642 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1643 "* return output_fp_compare (insn, operands, 1, 1);"
1644 [(set_attr "type" "sse")
1645 (set_attr "mode" "unknownfp")
1646 (set_attr "athlon_decode" "vector")])
1647 \f
1648 ;; Move instructions.
1649
1650 ;; General case of fullword move.
1651
1652 (define_expand "movsi"
1653 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1654 (match_operand:SI 1 "general_operand" ""))]
1655 ""
1656 "ix86_expand_move (SImode, operands); DONE;")
1657
1658 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1659 ;; general_operand.
1660 ;;
1661 ;; %%% We don't use a post-inc memory reference because x86 is not a
1662 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1663 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1664 ;; targets without our curiosities, and it is just as easy to represent
1665 ;; this differently.
1666
1667 (define_insn "*pushsi2"
1668 [(set (match_operand:SI 0 "push_operand" "=<")
1669 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1670 "!TARGET_64BIT"
1671 "push{l}\t%1"
1672 [(set_attr "type" "push")
1673 (set_attr "mode" "SI")])
1674
1675 ;; For 64BIT abi we always round up to 8 bytes.
1676 (define_insn "*pushsi2_rex64"
1677 [(set (match_operand:SI 0 "push_operand" "=X")
1678 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1679 "TARGET_64BIT"
1680 "push{q}\t%q1"
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1683
1684 (define_insn "*pushsi2_prologue"
1685 [(set (match_operand:SI 0 "push_operand" "=<")
1686 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1687 (clobber (mem:BLK (scratch)))]
1688 "!TARGET_64BIT"
1689 "push{l}\t%1"
1690 [(set_attr "type" "push")
1691 (set_attr "mode" "SI")])
1692
1693 (define_insn "*popsi1_epilogue"
1694 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1695 (mem:SI (reg:SI 7)))
1696 (set (reg:SI 7)
1697 (plus:SI (reg:SI 7) (const_int 4)))
1698 (clobber (mem:BLK (scratch)))]
1699 "!TARGET_64BIT"
1700 "pop{l}\t%0"
1701 [(set_attr "type" "pop")
1702 (set_attr "mode" "SI")])
1703
1704 (define_insn "popsi1"
1705 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1706 (mem:SI (reg:SI 7)))
1707 (set (reg:SI 7)
1708 (plus:SI (reg:SI 7) (const_int 4)))]
1709 "!TARGET_64BIT"
1710 "pop{l}\t%0"
1711 [(set_attr "type" "pop")
1712 (set_attr "mode" "SI")])
1713
1714 (define_insn "*movsi_xor"
1715 [(set (match_operand:SI 0 "register_operand" "=r")
1716 (match_operand:SI 1 "const0_operand" "i"))
1717 (clobber (reg:CC 17))]
1718 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1719 "xor{l}\t{%0, %0|%0, %0}"
1720 [(set_attr "type" "alu1")
1721 (set_attr "mode" "SI")
1722 (set_attr "length_immediate" "0")])
1723
1724 (define_insn "*movsi_or"
1725 [(set (match_operand:SI 0 "register_operand" "=r")
1726 (match_operand:SI 1 "immediate_operand" "i"))
1727 (clobber (reg:CC 17))]
1728 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1729 && INTVAL (operands[1]) == -1
1730 && (TARGET_PENTIUM || optimize_size)"
1731 {
1732 operands[1] = constm1_rtx;
1733 return "or{l}\t{%1, %0|%0, %1}";
1734 }
1735 [(set_attr "type" "alu1")
1736 (set_attr "mode" "SI")
1737 (set_attr "length_immediate" "1")])
1738
1739 (define_insn "*movsi_1"
1740 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
1741 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
1742 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1743 {
1744 switch (get_attr_type (insn))
1745 {
1746 case TYPE_SSE:
1747 if (get_attr_mode (insn) == TImode)
1748 return "movdqa\t{%1, %0|%0, %1}";
1749 return "movd\t{%1, %0|%0, %1}";
1750
1751 case TYPE_MMX:
1752 return "movd\t{%1, %0|%0, %1}";
1753
1754 case TYPE_LEA:
1755 return "lea{l}\t{%1, %0|%0, %1}";
1756
1757 default:
1758 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1759 abort();
1760 return "mov{l}\t{%1, %0|%0, %1}";
1761 }
1762 }
1763 [(set (attr "type")
1764 (cond [(eq_attr "alternative" "4,5")
1765 (const_string "mmx")
1766 (eq_attr "alternative" "6,7,8")
1767 (const_string "sse")
1768 (and (ne (symbol_ref "flag_pic") (const_int 0))
1769 (match_operand:SI 1 "symbolic_operand" ""))
1770 (const_string "lea")
1771 ]
1772 (const_string "imov")))
1773 (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
1774 (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
1775
1776 ;; Stores and loads of ax to arbitary constant address.
1777 ;; We fake an second form of instruction to force reload to load address
1778 ;; into register when rax is not available
1779 (define_insn "*movabssi_1_rex64"
1780 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1781 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1782 "TARGET_64BIT"
1783 "@
1784 movabs{l}\t{%1, %P0|%P0, %1}
1785 mov{l}\t{%1, %a0|%a0, %1}
1786 movabs{l}\t{%1, %a0|%a0, %1}"
1787 [(set_attr "type" "imov")
1788 (set_attr "modrm" "0,*,*")
1789 (set_attr "length_address" "8,0,0")
1790 (set_attr "length_immediate" "0,*,*")
1791 (set_attr "memory" "store")
1792 (set_attr "mode" "SI")])
1793
1794 (define_insn "*movabssi_2_rex64"
1795 [(set (match_operand:SI 0 "register_operand" "=a,r")
1796 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1797 "TARGET_64BIT"
1798 "@
1799 movabs{l}\t{%P1, %0|%0, %P1}
1800 mov{l}\t{%a1, %0|%0, %a1}"
1801 [(set_attr "type" "imov")
1802 (set_attr "modrm" "0,*")
1803 (set_attr "length_address" "8,0")
1804 (set_attr "length_immediate" "0")
1805 (set_attr "memory" "load")
1806 (set_attr "mode" "SI")])
1807
1808 (define_insn "*swapsi"
1809 [(set (match_operand:SI 0 "register_operand" "+r")
1810 (match_operand:SI 1 "register_operand" "+r"))
1811 (set (match_dup 1)
1812 (match_dup 0))]
1813 ""
1814 "xchg{l}\t%1, %0"
1815 [(set_attr "type" "imov")
1816 (set_attr "pent_pair" "np")
1817 (set_attr "athlon_decode" "vector")
1818 (set_attr "mode" "SI")
1819 (set_attr "modrm" "0")
1820 (set_attr "ppro_uops" "few")])
1821
1822 (define_expand "movhi"
1823 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1824 (match_operand:HI 1 "general_operand" ""))]
1825 ""
1826 "ix86_expand_move (HImode, operands); DONE;")
1827
1828 (define_insn "*pushhi2"
1829 [(set (match_operand:HI 0 "push_operand" "=<,<")
1830 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1831 "!TARGET_64BIT"
1832 "@
1833 push{w}\t{|WORD PTR }%1
1834 push{w}\t%1"
1835 [(set_attr "type" "push")
1836 (set_attr "mode" "HI")])
1837
1838 ;; For 64BIT abi we always round up to 8 bytes.
1839 (define_insn "*pushhi2_rex64"
1840 [(set (match_operand:HI 0 "push_operand" "=X")
1841 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1842 "TARGET_64BIT"
1843 "push{q}\t%q1"
1844 [(set_attr "type" "push")
1845 (set_attr "mode" "QI")])
1846
1847 (define_insn "*movhi_1"
1848 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1849 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1850 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1851 {
1852 switch (get_attr_type (insn))
1853 {
1854 case TYPE_IMOVX:
1855 /* movzwl is faster than movw on p2 due to partial word stalls,
1856 though not as fast as an aligned movl. */
1857 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1858 default:
1859 if (get_attr_mode (insn) == MODE_SI)
1860 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1861 else
1862 return "mov{w}\t{%1, %0|%0, %1}";
1863 }
1864 }
1865 [(set (attr "type")
1866 (cond [(and (eq_attr "alternative" "0,1")
1867 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1868 (const_int 0))
1869 (eq (symbol_ref "TARGET_HIMODE_MATH")
1870 (const_int 0))))
1871 (const_string "imov")
1872 (and (eq_attr "alternative" "2,3,4")
1873 (match_operand:HI 1 "aligned_operand" ""))
1874 (const_string "imov")
1875 (and (ne (symbol_ref "TARGET_MOVX")
1876 (const_int 0))
1877 (eq_attr "alternative" "0,1,3,4"))
1878 (const_string "imovx")
1879 ]
1880 (const_string "imov")))
1881 (set (attr "mode")
1882 (cond [(eq_attr "type" "imovx")
1883 (const_string "SI")
1884 (and (eq_attr "alternative" "2,3,4")
1885 (match_operand:HI 1 "aligned_operand" ""))
1886 (const_string "SI")
1887 (and (eq_attr "alternative" "0,1")
1888 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1889 (const_int 0))
1890 (eq (symbol_ref "TARGET_HIMODE_MATH")
1891 (const_int 0))))
1892 (const_string "SI")
1893 ]
1894 (const_string "HI")))
1895 (set_attr "modrm" "0,*,*,0,*,*")])
1896
1897 ;; Stores and loads of ax to arbitary constant address.
1898 ;; We fake an second form of instruction to force reload to load address
1899 ;; into register when rax is not available
1900 (define_insn "*movabshi_1_rex64"
1901 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1902 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1903 "TARGET_64BIT"
1904 "@
1905 movabs{w}\t{%1, %P0|%P0, %1}
1906 mov{w}\t{%1, %a0|%a0, %1}
1907 movabs{w}\t{%1, %a0|%a0, %1}"
1908 [(set_attr "type" "imov")
1909 (set_attr "modrm" "0,*,*")
1910 (set_attr "length_address" "8,0,0")
1911 (set_attr "length_immediate" "0,*,*")
1912 (set_attr "memory" "store")
1913 (set_attr "mode" "HI")])
1914
1915 (define_insn "*movabshi_2_rex64"
1916 [(set (match_operand:HI 0 "register_operand" "=a,r")
1917 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1918 "TARGET_64BIT"
1919 "@
1920 movabs{w}\t{%P1, %0|%0, %P1}
1921 mov{w}\t{%a1, %0|%0, %a1}"
1922 [(set_attr "type" "imov")
1923 (set_attr "modrm" "0,*")
1924 (set_attr "length_address" "8,0")
1925 (set_attr "length_immediate" "0")
1926 (set_attr "memory" "load")
1927 (set_attr "mode" "HI")])
1928
1929 (define_insn "*swaphi_1"
1930 [(set (match_operand:HI 0 "register_operand" "+r")
1931 (match_operand:HI 1 "register_operand" "+r"))
1932 (set (match_dup 1)
1933 (match_dup 0))]
1934 "TARGET_PARTIAL_REG_STALL"
1935 "xchg{w}\t%1, %0"
1936 [(set_attr "type" "imov")
1937 (set_attr "pent_pair" "np")
1938 (set_attr "mode" "HI")
1939 (set_attr "modrm" "0")
1940 (set_attr "ppro_uops" "few")])
1941
1942 (define_insn "*swaphi_2"
1943 [(set (match_operand:HI 0 "register_operand" "+r")
1944 (match_operand:HI 1 "register_operand" "+r"))
1945 (set (match_dup 1)
1946 (match_dup 0))]
1947 "! TARGET_PARTIAL_REG_STALL"
1948 "xchg{l}\t%k1, %k0"
1949 [(set_attr "type" "imov")
1950 (set_attr "pent_pair" "np")
1951 (set_attr "mode" "SI")
1952 (set_attr "modrm" "0")
1953 (set_attr "ppro_uops" "few")])
1954
1955 (define_expand "movstricthi"
1956 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1957 (match_operand:HI 1 "general_operand" ""))]
1958 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1959 {
1960 /* Don't generate memory->memory moves, go through a register */
1961 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1962 operands[1] = force_reg (HImode, operands[1]);
1963 })
1964
1965 (define_insn "*movstricthi_1"
1966 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1967 (match_operand:HI 1 "general_operand" "rn,m"))]
1968 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1969 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1970 "mov{w}\t{%1, %0|%0, %1}"
1971 [(set_attr "type" "imov")
1972 (set_attr "mode" "HI")])
1973
1974 (define_insn "*movstricthi_xor"
1975 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1976 (match_operand:HI 1 "const0_operand" "i"))
1977 (clobber (reg:CC 17))]
1978 "reload_completed
1979 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1980 "xor{w}\t{%0, %0|%0, %0}"
1981 [(set_attr "type" "alu1")
1982 (set_attr "mode" "HI")
1983 (set_attr "length_immediate" "0")])
1984
1985 (define_expand "movqi"
1986 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1987 (match_operand:QI 1 "general_operand" ""))]
1988 ""
1989 "ix86_expand_move (QImode, operands); DONE;")
1990
1991 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1992 ;; "push a byte". But actually we use pushw, which has the effect
1993 ;; of rounding the amount pushed up to a halfword.
1994
1995 (define_insn "*pushqi2"
1996 [(set (match_operand:QI 0 "push_operand" "=X,X")
1997 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1998 "!TARGET_64BIT"
1999 "@
2000 push{w}\t{|word ptr }%1
2001 push{w}\t%w1"
2002 [(set_attr "type" "push")
2003 (set_attr "mode" "HI")])
2004
2005 ;; For 64BIT abi we always round up to 8 bytes.
2006 (define_insn "*pushqi2_rex64"
2007 [(set (match_operand:QI 0 "push_operand" "=X")
2008 (match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
2009 "TARGET_64BIT"
2010 "push{q}\t%q1"
2011 [(set_attr "type" "push")
2012 (set_attr "mode" "QI")])
2013
2014 ;; Situation is quite tricky about when to choose full sized (SImode) move
2015 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2016 ;; partial register dependency machines (such as AMD Athlon), where QImode
2017 ;; moves issue extra dependency and for partial register stalls machines
2018 ;; that don't use QImode patterns (and QImode move cause stall on the next
2019 ;; instruction).
2020 ;;
2021 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2022 ;; register stall machines with, where we use QImode instructions, since
2023 ;; partial register stall can be caused there. Then we use movzx.
2024 (define_insn "*movqi_1"
2025 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2026 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2027 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2028 {
2029 switch (get_attr_type (insn))
2030 {
2031 case TYPE_IMOVX:
2032 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2033 abort ();
2034 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2035 default:
2036 if (get_attr_mode (insn) == MODE_SI)
2037 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2038 else
2039 return "mov{b}\t{%1, %0|%0, %1}";
2040 }
2041 }
2042 [(set (attr "type")
2043 (cond [(and (eq_attr "alternative" "3")
2044 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2045 (const_int 0))
2046 (eq (symbol_ref "TARGET_QIMODE_MATH")
2047 (const_int 0))))
2048 (const_string "imov")
2049 (eq_attr "alternative" "3,5")
2050 (const_string "imovx")
2051 (and (ne (symbol_ref "TARGET_MOVX")
2052 (const_int 0))
2053 (eq_attr "alternative" "2"))
2054 (const_string "imovx")
2055 ]
2056 (const_string "imov")))
2057 (set (attr "mode")
2058 (cond [(eq_attr "alternative" "3,4,5")
2059 (const_string "SI")
2060 (eq_attr "alternative" "6")
2061 (const_string "QI")
2062 (eq_attr "type" "imovx")
2063 (const_string "SI")
2064 (and (eq_attr "type" "imov")
2065 (and (eq_attr "alternative" "0,1,2")
2066 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2067 (const_int 0))))
2068 (const_string "SI")
2069 ;; Avoid partial register stalls when not using QImode arithmetic
2070 (and (eq_attr "type" "imov")
2071 (and (eq_attr "alternative" "0,1,2")
2072 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2073 (const_int 0))
2074 (eq (symbol_ref "TARGET_QIMODE_MATH")
2075 (const_int 0)))))
2076 (const_string "SI")
2077 ]
2078 (const_string "QI")))])
2079
2080 (define_expand "reload_outqi"
2081 [(parallel [(match_operand:QI 0 "" "=m")
2082 (match_operand:QI 1 "register_operand" "r")
2083 (match_operand:QI 2 "register_operand" "=&q")])]
2084 ""
2085 {
2086 rtx op0, op1, op2;
2087 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2088
2089 if (reg_overlap_mentioned_p (op2, op0))
2090 abort ();
2091 if (! q_regs_operand (op1, QImode))
2092 {
2093 emit_insn (gen_movqi (op2, op1));
2094 op1 = op2;
2095 }
2096 emit_insn (gen_movqi (op0, op1));
2097 DONE;
2098 })
2099
2100 (define_insn "*swapqi"
2101 [(set (match_operand:QI 0 "register_operand" "+r")
2102 (match_operand:QI 1 "register_operand" "+r"))
2103 (set (match_dup 1)
2104 (match_dup 0))]
2105 ""
2106 "xchg{b}\t%1, %0"
2107 [(set_attr "type" "imov")
2108 (set_attr "pent_pair" "np")
2109 (set_attr "mode" "QI")
2110 (set_attr "modrm" "0")
2111 (set_attr "ppro_uops" "few")])
2112
2113 (define_expand "movstrictqi"
2114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2115 (match_operand:QI 1 "general_operand" ""))]
2116 "! TARGET_PARTIAL_REG_STALL"
2117 {
2118 /* Don't generate memory->memory moves, go through a register */
2119 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2120 operands[1] = force_reg (QImode, operands[1]);
2121 })
2122
2123 (define_insn "*movstrictqi_1"
2124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2125 (match_operand:QI 1 "general_operand" "*qn,m"))]
2126 "! TARGET_PARTIAL_REG_STALL
2127 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2128 "mov{b}\t{%1, %0|%0, %1}"
2129 [(set_attr "type" "imov")
2130 (set_attr "mode" "QI")])
2131
2132 (define_insn "*movstrictqi_xor"
2133 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2134 (match_operand:QI 1 "const0_operand" "i"))
2135 (clobber (reg:CC 17))]
2136 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2137 "xor{b}\t{%0, %0|%0, %0}"
2138 [(set_attr "type" "alu1")
2139 (set_attr "mode" "QI")
2140 (set_attr "length_immediate" "0")])
2141
2142 (define_insn "*movsi_extv_1"
2143 [(set (match_operand:SI 0 "register_operand" "=R")
2144 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2145 (const_int 8)
2146 (const_int 8)))]
2147 ""
2148 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2149 [(set_attr "type" "imovx")
2150 (set_attr "mode" "SI")])
2151
2152 (define_insn "*movhi_extv_1"
2153 [(set (match_operand:HI 0 "register_operand" "=R")
2154 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2155 (const_int 8)
2156 (const_int 8)))]
2157 ""
2158 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2159 [(set_attr "type" "imovx")
2160 (set_attr "mode" "SI")])
2161
2162 (define_insn "*movqi_extv_1"
2163 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2164 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2165 (const_int 8)
2166 (const_int 8)))]
2167 "!TARGET_64BIT"
2168 {
2169 switch (get_attr_type (insn))
2170 {
2171 case TYPE_IMOVX:
2172 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2173 default:
2174 return "mov{b}\t{%h1, %0|%0, %h1}";
2175 }
2176 }
2177 [(set (attr "type")
2178 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2179 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2180 (ne (symbol_ref "TARGET_MOVX")
2181 (const_int 0))))
2182 (const_string "imovx")
2183 (const_string "imov")))
2184 (set (attr "mode")
2185 (if_then_else (eq_attr "type" "imovx")
2186 (const_string "SI")
2187 (const_string "QI")))])
2188
2189 (define_insn "*movqi_extv_1_rex64"
2190 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2191 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2192 (const_int 8)
2193 (const_int 8)))]
2194 "TARGET_64BIT"
2195 {
2196 switch (get_attr_type (insn))
2197 {
2198 case TYPE_IMOVX:
2199 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2200 default:
2201 return "mov{b}\t{%h1, %0|%0, %h1}";
2202 }
2203 }
2204 [(set (attr "type")
2205 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2206 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2207 (ne (symbol_ref "TARGET_MOVX")
2208 (const_int 0))))
2209 (const_string "imovx")
2210 (const_string "imov")))
2211 (set (attr "mode")
2212 (if_then_else (eq_attr "type" "imovx")
2213 (const_string "SI")
2214 (const_string "QI")))])
2215
2216 ;; Stores and loads of ax to arbitary constant address.
2217 ;; We fake an second form of instruction to force reload to load address
2218 ;; into register when rax is not available
2219 (define_insn "*movabsqi_1_rex64"
2220 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2221 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2222 "TARGET_64BIT"
2223 "@
2224 movabs{q}\t{%1, %P0|%P0, %1}
2225 mov{q}\t{%1, %a0|%a0, %1}
2226 movabs{q}\t{%1, %a0|%a0, %1}"
2227 [(set_attr "type" "imov")
2228 (set_attr "modrm" "0,*,*")
2229 (set_attr "length_address" "8,0,0")
2230 (set_attr "length_immediate" "0,*,*")
2231 (set_attr "memory" "store")
2232 (set_attr "mode" "QI")])
2233
2234 (define_insn "*movabsqi_2_rex64"
2235 [(set (match_operand:QI 0 "register_operand" "=a,r")
2236 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2237 "TARGET_64BIT"
2238 "@
2239 movabs{q}\t{%P1, %0|%0, %P1}
2240 mov{q}\t{%a1, %0|%0, %a1}"
2241 [(set_attr "type" "imov")
2242 (set_attr "modrm" "0,*")
2243 (set_attr "length_address" "8,0")
2244 (set_attr "length_immediate" "0")
2245 (set_attr "memory" "load")
2246 (set_attr "mode" "QI")])
2247
2248 (define_insn "*movsi_extzv_1"
2249 [(set (match_operand:SI 0 "register_operand" "=R")
2250 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2251 (const_int 8)
2252 (const_int 8)))]
2253 ""
2254 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2255 [(set_attr "type" "imovx")
2256 (set_attr "mode" "SI")])
2257
2258 (define_insn "*movqi_extzv_2"
2259 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2260 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2261 (const_int 8)
2262 (const_int 8)) 0))]
2263 "!TARGET_64BIT"
2264 {
2265 switch (get_attr_type (insn))
2266 {
2267 case TYPE_IMOVX:
2268 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2269 default:
2270 return "mov{b}\t{%h1, %0|%0, %h1}";
2271 }
2272 }
2273 [(set (attr "type")
2274 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2275 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2276 (ne (symbol_ref "TARGET_MOVX")
2277 (const_int 0))))
2278 (const_string "imovx")
2279 (const_string "imov")))
2280 (set (attr "mode")
2281 (if_then_else (eq_attr "type" "imovx")
2282 (const_string "SI")
2283 (const_string "QI")))])
2284
2285 (define_insn "*movqi_extzv_2_rex64"
2286 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2287 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2288 (const_int 8)
2289 (const_int 8)) 0))]
2290 "TARGET_64BIT"
2291 {
2292 switch (get_attr_type (insn))
2293 {
2294 case TYPE_IMOVX:
2295 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2296 default:
2297 return "mov{b}\t{%h1, %0|%0, %h1}";
2298 }
2299 }
2300 [(set (attr "type")
2301 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2302 (ne (symbol_ref "TARGET_MOVX")
2303 (const_int 0)))
2304 (const_string "imovx")
2305 (const_string "imov")))
2306 (set (attr "mode")
2307 (if_then_else (eq_attr "type" "imovx")
2308 (const_string "SI")
2309 (const_string "QI")))])
2310
2311 (define_insn "movsi_insv_1"
2312 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2313 (const_int 8)
2314 (const_int 8))
2315 (match_operand:SI 1 "general_operand" "Qmn"))]
2316 "!TARGET_64BIT"
2317 "mov{b}\t{%b1, %h0|%h0, %b1}"
2318 [(set_attr "type" "imov")
2319 (set_attr "mode" "QI")])
2320
2321 (define_insn "*movsi_insv_1_rex64"
2322 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2323 (const_int 8)
2324 (const_int 8))
2325 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2326 "TARGET_64BIT"
2327 "mov{b}\t{%b1, %h0|%h0, %b1}"
2328 [(set_attr "type" "imov")
2329 (set_attr "mode" "QI")])
2330
2331 (define_insn "*movqi_insv_2"
2332 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2333 (const_int 8)
2334 (const_int 8))
2335 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2336 (const_int 8))
2337 (const_int 255)))]
2338 ""
2339 "mov{b}\t{%h1, %h0|%h0, %h1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "mode" "QI")])
2342
2343 (define_expand "movdi"
2344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2345 (match_operand:DI 1 "general_operand" ""))]
2346 ""
2347 "ix86_expand_move (DImode, operands); DONE;")
2348
2349 (define_insn "*pushdi"
2350 [(set (match_operand:DI 0 "push_operand" "=<")
2351 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2352 "!TARGET_64BIT"
2353 "#")
2354
2355 (define_insn "pushdi2_rex64"
2356 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2357 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2358 "TARGET_64BIT"
2359 "@
2360 push{q}\t%1
2361 #"
2362 [(set_attr "type" "push,multi")
2363 (set_attr "mode" "DI")])
2364
2365 ;; Convert impossible pushes of immediate to existing instructions.
2366 ;; First try to get scratch register and go trought it. In case this
2367 ;; fails, push sign extended lower part first and then overwrite
2368 ;; upper part by 32bit move.
2369 (define_peephole2
2370 [(match_scratch:DI 2 "r")
2371 (set (match_operand:DI 0 "push_operand" "")
2372 (match_operand:DI 1 "immediate_operand" ""))]
2373 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2374 && !x86_64_immediate_operand (operands[1], DImode)"
2375 [(set (match_dup 2) (match_dup 1))
2376 (set (match_dup 0) (match_dup 2))]
2377 "")
2378
2379 ;; We need to define this as both peepholer and splitter for case
2380 ;; peephole2 pass is not run.
2381 (define_peephole2
2382 [(set (match_operand:DI 0 "push_operand" "")
2383 (match_operand:DI 1 "immediate_operand" ""))]
2384 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2385 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2386 [(set (match_dup 0) (match_dup 1))
2387 (set (match_dup 2) (match_dup 3))]
2388 "split_di (operands + 1, 1, operands + 2, operands + 3);
2389 operands[1] = gen_lowpart (DImode, operands[2]);
2390 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2391 GEN_INT (4)));
2392 ")
2393
2394 (define_split
2395 [(set (match_operand:DI 0 "push_operand" "")
2396 (match_operand:DI 1 "immediate_operand" ""))]
2397 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2398 && !symbolic_operand (operands[1], DImode)
2399 && !x86_64_immediate_operand (operands[1], DImode)"
2400 [(set (match_dup 0) (match_dup 1))
2401 (set (match_dup 2) (match_dup 3))]
2402 "split_di (operands + 1, 1, operands + 2, operands + 3);
2403 operands[1] = gen_lowpart (DImode, operands[2]);
2404 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2405 GEN_INT (4)));
2406 ")
2407
2408 (define_insn "*pushdi2_prologue_rex64"
2409 [(set (match_operand:DI 0 "push_operand" "=<")
2410 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2411 (clobber (mem:BLK (scratch)))]
2412 "TARGET_64BIT"
2413 "push{q}\t%1"
2414 [(set_attr "type" "push")
2415 (set_attr "mode" "DI")])
2416
2417 (define_insn "*popdi1_epilogue_rex64"
2418 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2419 (mem:DI (reg:DI 7)))
2420 (set (reg:DI 7)
2421 (plus:DI (reg:DI 7) (const_int 8)))
2422 (clobber (mem:BLK (scratch)))]
2423 "TARGET_64BIT"
2424 "pop{q}\t%0"
2425 [(set_attr "type" "pop")
2426 (set_attr "mode" "DI")])
2427
2428 (define_insn "popdi1"
2429 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2430 (mem:DI (reg:DI 7)))
2431 (set (reg:DI 7)
2432 (plus:DI (reg:DI 7) (const_int 8)))]
2433 "TARGET_64BIT"
2434 "pop{q}\t%0"
2435 [(set_attr "type" "pop")
2436 (set_attr "mode" "DI")])
2437
2438 (define_insn "*movdi_xor_rex64"
2439 [(set (match_operand:DI 0 "register_operand" "=r")
2440 (match_operand:DI 1 "const0_operand" "i"))
2441 (clobber (reg:CC 17))]
2442 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2443 && reload_completed"
2444 "xor{l}\t{%k0, %k0|%k0, %k0}"
2445 [(set_attr "type" "alu1")
2446 (set_attr "mode" "SI")
2447 (set_attr "length_immediate" "0")])
2448
2449 (define_insn "*movdi_or_rex64"
2450 [(set (match_operand:DI 0 "register_operand" "=r")
2451 (match_operand:DI 1 "const_int_operand" "i"))
2452 (clobber (reg:CC 17))]
2453 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
2454 && reload_completed
2455 && GET_CODE (operands[1]) == CONST_INT
2456 && INTVAL (operands[1]) == -1"
2457 {
2458 operands[1] = constm1_rtx;
2459 return "or{q}\t{%1, %0|%0, %1}";
2460 }
2461 [(set_attr "type" "alu1")
2462 (set_attr "mode" "DI")
2463 (set_attr "length_immediate" "1")])
2464
2465 (define_insn "*movdi_2"
2466 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
2467 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
2468 "!TARGET_64BIT
2469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2470 "@
2471 #
2472 #
2473 movq\t{%1, %0|%0, %1}
2474 movq\t{%1, %0|%0, %1}
2475 movq\t{%1, %0|%0, %1}
2476 movdqa\t{%1, %0|%0, %1}
2477 movq\t{%1, %0|%0, %1}"
2478 [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
2479 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
2480
2481 (define_split
2482 [(set (match_operand:DI 0 "push_operand" "")
2483 (match_operand:DI 1 "general_operand" ""))]
2484 "!TARGET_64BIT && reload_completed
2485 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2486 [(const_int 0)]
2487 "ix86_split_long_move (operands); DONE;")
2488
2489 ;; %%% This multiword shite has got to go.
2490 (define_split
2491 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2492 (match_operand:DI 1 "general_operand" ""))]
2493 "!TARGET_64BIT && reload_completed
2494 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2495 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2496 [(const_int 0)]
2497 "ix86_split_long_move (operands); DONE;")
2498
2499 (define_insn "*movdi_1_rex64"
2500 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
2501 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
2502 "TARGET_64BIT
2503 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2504 {
2505 switch (get_attr_type (insn))
2506 {
2507 case TYPE_SSE:
2508 if (register_operand (operands[0], DImode)
2509 && register_operand (operands[1], DImode))
2510 return "movdqa\t{%1, %0|%0, %1}";
2511 /* FALLTHRU */
2512 case TYPE_MMX:
2513 return "movq\t{%1, %0|%0, %1}";
2514 case TYPE_MULTI:
2515 return "#";
2516 case TYPE_LEA:
2517 return "lea{q}\t{%a1, %0|%0, %a1}";
2518 default:
2519 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2520 abort ();
2521 if (get_attr_mode (insn) == MODE_SI)
2522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2523 else if (which_alternative == 2)
2524 return "movabs{q}\t{%1, %0|%0, %1}";
2525 else
2526 return "mov{q}\t{%1, %0|%0, %1}";
2527 }
2528 }
2529 [(set (attr "type")
2530 (cond [(eq_attr "alternative" "5,6")
2531 (const_string "mmx")
2532 (eq_attr "alternative" "7,8")
2533 (const_string "sse")
2534 (eq_attr "alternative" "4")
2535 (const_string "multi")
2536 (and (ne (symbol_ref "flag_pic") (const_int 0))
2537 (match_operand:DI 1 "symbolic_operand" ""))
2538 (const_string "lea")
2539 ]
2540 (const_string "imov")))
2541 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
2542 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
2543 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
2544
2545 ;; Stores and loads of ax to arbitary constant address.
2546 ;; We fake an second form of instruction to force reload to load address
2547 ;; into register when rax is not available
2548 (define_insn "*movabsdi_1_rex64"
2549 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2550 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2551 "TARGET_64BIT"
2552 "@
2553 movabs{q}\t{%1, %P0|%P0, %1}
2554 mov{q}\t{%1, %a0|%a0, %1}
2555 movabs{q}\t{%1, %a0|%a0, %1}"
2556 [(set_attr "type" "imov")
2557 (set_attr "modrm" "0,*,*")
2558 (set_attr "length_address" "8,0,0")
2559 (set_attr "length_immediate" "0,*,*")
2560 (set_attr "memory" "store")
2561 (set_attr "mode" "DI")])
2562
2563 (define_insn "*movabsdi_2_rex64"
2564 [(set (match_operand:DI 0 "register_operand" "=a,r")
2565 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2566 "TARGET_64BIT"
2567 "@
2568 movabs{q}\t{%P1, %0|%0, %P1}
2569 mov{q}\t{%a1, %0|%0, %a1}"
2570 [(set_attr "type" "imov")
2571 (set_attr "modrm" "0,*")
2572 (set_attr "length_address" "8,0")
2573 (set_attr "length_immediate" "0")
2574 (set_attr "memory" "load")
2575 (set_attr "mode" "DI")])
2576
2577 ;; Convert impossible stores of immediate to existing instructions.
2578 ;; First try to get scratch register and go trought it. In case this
2579 ;; fails, move by 32bit parts.
2580 (define_peephole2
2581 [(match_scratch:DI 2 "r")
2582 (set (match_operand:DI 0 "memory_operand" "")
2583 (match_operand:DI 1 "immediate_operand" ""))]
2584 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2585 && !x86_64_immediate_operand (operands[1], DImode)"
2586 [(set (match_dup 2) (match_dup 1))
2587 (set (match_dup 0) (match_dup 2))]
2588 "")
2589
2590 ;; We need to define this as both peepholer and splitter for case
2591 ;; peephole2 pass is not run.
2592 (define_peephole2
2593 [(set (match_operand:DI 0 "memory_operand" "")
2594 (match_operand:DI 1 "immediate_operand" ""))]
2595 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2596 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2597 [(set (match_dup 2) (match_dup 3))
2598 (set (match_dup 4) (match_dup 5))]
2599 "split_di (operands, 2, operands + 2, operands + 4);")
2600
2601 (define_split
2602 [(set (match_operand:DI 0 "memory_operand" "")
2603 (match_operand:DI 1 "immediate_operand" ""))]
2604 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2605 && !symbolic_operand (operands[1], DImode)
2606 && !x86_64_immediate_operand (operands[1], DImode)"
2607 [(set (match_dup 2) (match_dup 3))
2608 (set (match_dup 4) (match_dup 5))]
2609 "split_di (operands, 2, operands + 2, operands + 4);")
2610
2611 (define_insn "*swapdi_rex64"
2612 [(set (match_operand:DI 0 "register_operand" "+r")
2613 (match_operand:DI 1 "register_operand" "+r"))
2614 (set (match_dup 1)
2615 (match_dup 0))]
2616 "TARGET_64BIT"
2617 "xchg{q}\t%1, %0"
2618 [(set_attr "type" "imov")
2619 (set_attr "pent_pair" "np")
2620 (set_attr "athlon_decode" "vector")
2621 (set_attr "mode" "DI")
2622 (set_attr "modrm" "0")
2623 (set_attr "ppro_uops" "few")])
2624
2625
2626 (define_expand "movsf"
2627 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2628 (match_operand:SF 1 "general_operand" ""))]
2629 ""
2630 "ix86_expand_move (SFmode, operands); DONE;")
2631
2632 (define_insn "*pushsf"
2633 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2634 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2635 "!TARGET_64BIT"
2636 {
2637 switch (which_alternative)
2638 {
2639 case 0:
2640 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2641 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2642 operands[2] = stack_pointer_rtx;
2643 operands[3] = GEN_INT (4);
2644 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2645 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2646 else
2647 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2648
2649 case 1:
2650 return "push{l}\t%1";
2651 case 2:
2652 return "#";
2653
2654 default:
2655 abort ();
2656 }
2657 }
2658 [(set_attr "type" "multi,push,multi")
2659 (set_attr "mode" "SF,SI,SF")])
2660
2661 (define_insn "*pushsf_rex64"
2662 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2663 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2664 "TARGET_64BIT"
2665 {
2666 switch (which_alternative)
2667 {
2668 case 0:
2669 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2670 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2671 operands[2] = stack_pointer_rtx;
2672 operands[3] = GEN_INT (8);
2673 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2674 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2675 else
2676 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2677
2678 case 1:
2679 return "push{q}\t%q1";
2680
2681 case 2:
2682 return "#";
2683
2684 default:
2685 abort ();
2686 }
2687 }
2688 [(set_attr "type" "multi,push,multi")
2689 (set_attr "mode" "SF,DI,SF")])
2690
2691 (define_split
2692 [(set (match_operand:SF 0 "push_operand" "")
2693 (match_operand:SF 1 "memory_operand" ""))]
2694 "reload_completed
2695 && GET_CODE (operands[1]) == MEM
2696 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2697 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2698 [(set (match_dup 0)
2699 (match_dup 1))]
2700 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2701
2702
2703 ;; %%% Kill this when call knows how to work this out.
2704 (define_split
2705 [(set (match_operand:SF 0 "push_operand" "")
2706 (match_operand:SF 1 "register_operand" ""))]
2707 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2708 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2709 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2710
2711 (define_split
2712 [(set (match_operand:SF 0 "push_operand" "")
2713 (match_operand:SF 1 "register_operand" ""))]
2714 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2715 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2716 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2717
2718 (define_insn "*movsf_1"
2719 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2720 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
2721 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2722 && (reload_in_progress || reload_completed
2723 || GET_CODE (operands[1]) != CONST_DOUBLE
2724 || memory_operand (operands[0], SFmode))"
2725 {
2726 switch (which_alternative)
2727 {
2728 case 0:
2729 if (REG_P (operands[1])
2730 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2731 return "fstp\t%y0";
2732 else if (STACK_TOP_P (operands[0]))
2733 return "fld%z1\t%y1";
2734 else
2735 return "fst\t%y0";
2736
2737 case 1:
2738 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2739 return "fstp%z0\t%y0";
2740 else
2741 return "fst%z0\t%y0";
2742
2743 case 2:
2744 switch (standard_80387_constant_p (operands[1]))
2745 {
2746 case 1:
2747 return "fldz";
2748 case 2:
2749 return "fld1";
2750 }
2751 abort();
2752
2753 case 3:
2754 case 4:
2755 return "mov{l}\t{%1, %0|%0, %1}";
2756 case 5:
2757 return "pxor\t%0, %0";
2758 case 6:
2759 if (TARGET_PARTIAL_REG_DEPENDENCY)
2760 return "movaps\t{%1, %0|%0, %1}";
2761 else
2762 return "movss\t{%1, %0|%0, %1}";
2763 case 7:
2764 case 8:
2765 return "movss\t{%1, %0|%0, %1}";
2766
2767 default:
2768 abort();
2769 }
2770 }
2771 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2772 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
2773
2774 (define_insn "*swapsf"
2775 [(set (match_operand:SF 0 "register_operand" "+f")
2776 (match_operand:SF 1 "register_operand" "+f"))
2777 (set (match_dup 1)
2778 (match_dup 0))]
2779 "reload_completed || !TARGET_SSE2"
2780 {
2781 if (STACK_TOP_P (operands[0]))
2782 return "fxch\t%1";
2783 else
2784 return "fxch\t%0";
2785 }
2786 [(set_attr "type" "fxch")
2787 (set_attr "mode" "SF")])
2788
2789 (define_expand "movdf"
2790 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2791 (match_operand:DF 1 "general_operand" ""))]
2792 ""
2793 "ix86_expand_move (DFmode, operands); DONE;")
2794
2795 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2796 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2797 ;; On the average, pushdf using integers can be still shorter. Allow this
2798 ;; pattern for optimize_size too.
2799
2800 (define_insn "*pushdf_nointeger"
2801 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2802 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2803 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2804 {
2805 switch (which_alternative)
2806 {
2807 case 0:
2808 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2809 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2810 operands[2] = stack_pointer_rtx;
2811 operands[3] = GEN_INT (8);
2812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2813 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2814 else
2815 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2816
2817 case 1:
2818 case 2:
2819 case 3:
2820 return "#";
2821
2822 default:
2823 abort ();
2824 }
2825 }
2826 [(set_attr "type" "multi")
2827 (set_attr "mode" "DF,SI,SI,DF")])
2828
2829 (define_insn "*pushdf_integer"
2830 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2831 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2832 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2833 {
2834 switch (which_alternative)
2835 {
2836 case 0:
2837 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2838 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2839 operands[2] = stack_pointer_rtx;
2840 operands[3] = GEN_INT (8);
2841 if (TARGET_64BIT)
2842 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2843 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2844 else
2845 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2846 else
2847 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2848 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
2849 else
2850 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
2851
2852
2853 case 1:
2854 case 2:
2855 return "#";
2856
2857 default:
2858 abort ();
2859 }
2860 }
2861 [(set_attr "type" "multi")
2862 (set_attr "mode" "DF,SI,DF")])
2863
2864 ;; %%% Kill this when call knows how to work this out.
2865 (define_split
2866 [(set (match_operand:DF 0 "push_operand" "")
2867 (match_operand:DF 1 "register_operand" ""))]
2868 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2869 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2870 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2871 "")
2872
2873 (define_split
2874 [(set (match_operand:DF 0 "push_operand" "")
2875 (match_operand:DF 1 "register_operand" ""))]
2876 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2877 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2878 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2879 "")
2880
2881 (define_split
2882 [(set (match_operand:DF 0 "push_operand" "")
2883 (match_operand:DF 1 "general_operand" ""))]
2884 "reload_completed"
2885 [(const_int 0)]
2886 "ix86_split_long_move (operands); DONE;")
2887
2888 ;; Moving is usually shorter when only FP registers are used. This separate
2889 ;; movdf pattern avoids the use of integer registers for FP operations
2890 ;; when optimizing for size.
2891
2892 (define_insn "*movdf_nointeger"
2893 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2894 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2895 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2896 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2897 && (reload_in_progress || reload_completed
2898 || GET_CODE (operands[1]) != CONST_DOUBLE
2899 || memory_operand (operands[0], DFmode))"
2900 {
2901 switch (which_alternative)
2902 {
2903 case 0:
2904 if (REG_P (operands[1])
2905 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2906 return "fstp\t%y0";
2907 else if (STACK_TOP_P (operands[0]))
2908 return "fld%z1\t%y1";
2909 else
2910 return "fst\t%y0";
2911
2912 case 1:
2913 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2914 return "fstp%z0\t%y0";
2915 else
2916 return "fst%z0\t%y0";
2917
2918 case 2:
2919 switch (standard_80387_constant_p (operands[1]))
2920 {
2921 case 1:
2922 return "fldz";
2923 case 2:
2924 return "fld1";
2925 }
2926 abort();
2927
2928 case 3:
2929 case 4:
2930 return "#";
2931 case 5:
2932 return "pxor\t%0, %0";
2933 case 6:
2934 if (TARGET_PARTIAL_REG_DEPENDENCY)
2935 return "movapd\t{%1, %0|%0, %1}";
2936 else
2937 return "movsd\t{%1, %0|%0, %1}";
2938 case 7:
2939 case 8:
2940 return "movsd\t{%1, %0|%0, %1}";
2941
2942 default:
2943 abort();
2944 }
2945 }
2946 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2947 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2948
2949 (define_insn "*movdf_integer"
2950 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2951 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2952 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2953 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2954 && (reload_in_progress || reload_completed
2955 || GET_CODE (operands[1]) != CONST_DOUBLE
2956 || memory_operand (operands[0], DFmode))"
2957 {
2958 switch (which_alternative)
2959 {
2960 case 0:
2961 if (REG_P (operands[1])
2962 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2963 return "fstp\t%y0";
2964 else if (STACK_TOP_P (operands[0]))
2965 return "fld%z1\t%y1";
2966 else
2967 return "fst\t%y0";
2968
2969 case 1:
2970 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2971 return "fstp%z0\t%y0";
2972 else
2973 return "fst%z0\t%y0";
2974
2975 case 2:
2976 switch (standard_80387_constant_p (operands[1]))
2977 {
2978 case 1:
2979 return "fldz";
2980 case 2:
2981 return "fld1";
2982 }
2983 abort();
2984
2985 case 3:
2986 case 4:
2987 return "#";
2988
2989 case 5:
2990 return "pxor\t%0, %0";
2991 case 6:
2992 if (TARGET_PARTIAL_REG_DEPENDENCY)
2993 return "movapd\t{%1, %0|%0, %1}";
2994 else
2995 return "movsd\t{%1, %0|%0, %1}";
2996 case 7:
2997 case 8:
2998 return "movsd\t{%1, %0|%0, %1}";
2999
3000 default:
3001 abort();
3002 }
3003 }
3004 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
3005 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
3006
3007 (define_split
3008 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3009 (match_operand:DF 1 "general_operand" ""))]
3010 "reload_completed
3011 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3012 && ! (ANY_FP_REG_P (operands[0]) ||
3013 (GET_CODE (operands[0]) == SUBREG
3014 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3015 && ! (ANY_FP_REG_P (operands[1]) ||
3016 (GET_CODE (operands[1]) == SUBREG
3017 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3018 [(const_int 0)]
3019 "ix86_split_long_move (operands); DONE;")
3020
3021 (define_insn "*swapdf"
3022 [(set (match_operand:DF 0 "register_operand" "+f")
3023 (match_operand:DF 1 "register_operand" "+f"))
3024 (set (match_dup 1)
3025 (match_dup 0))]
3026 "reload_completed || !TARGET_SSE2"
3027 {
3028 if (STACK_TOP_P (operands[0]))
3029 return "fxch\t%1";
3030 else
3031 return "fxch\t%0";
3032 }
3033 [(set_attr "type" "fxch")
3034 (set_attr "mode" "DF")])
3035
3036 (define_expand "movxf"
3037 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3038 (match_operand:XF 1 "general_operand" ""))]
3039 "!TARGET_64BIT"
3040 "ix86_expand_move (XFmode, operands); DONE;")
3041
3042 (define_expand "movtf"
3043 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3044 (match_operand:TF 1 "general_operand" ""))]
3045 ""
3046 "ix86_expand_move (TFmode, operands); DONE;")
3047
3048 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3049 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
3050 ;; Pushing using integer instructions is longer except for constants
3051 ;; and direct memory references.
3052 ;; (assuming that any given constant is pushed only once, but this ought to be
3053 ;; handled elsewhere).
3054
3055 (define_insn "*pushxf_nointeger"
3056 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3057 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3058 "!TARGET_64BIT && optimize_size"
3059 {
3060 switch (which_alternative)
3061 {
3062 case 0:
3063 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3064 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3065 operands[2] = stack_pointer_rtx;
3066 operands[3] = GEN_INT (12);
3067 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3068 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3069 else
3070 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3071
3072 case 1:
3073 case 2:
3074 return "#";
3075
3076 default:
3077 abort ();
3078 }
3079 }
3080 [(set_attr "type" "multi")
3081 (set_attr "mode" "XF,SI,SI")])
3082
3083 (define_insn "*pushtf_nointeger"
3084 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3085 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3086 "optimize_size"
3087 {
3088 switch (which_alternative)
3089 {
3090 case 0:
3091 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3092 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3093 operands[2] = stack_pointer_rtx;
3094 operands[3] = GEN_INT (16);
3095 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3096 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3097 else
3098 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3099
3100 case 1:
3101 case 2:
3102 return "#";
3103
3104 default:
3105 abort ();
3106 }
3107 }
3108 [(set_attr "type" "multi")
3109 (set_attr "mode" "XF,SI,SI")])
3110
3111 (define_insn "*pushxf_integer"
3112 [(set (match_operand:XF 0 "push_operand" "=<,<")
3113 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3114 "!TARGET_64BIT && !optimize_size"
3115 {
3116 switch (which_alternative)
3117 {
3118 case 0:
3119 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3120 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3121 operands[2] = stack_pointer_rtx;
3122 operands[3] = GEN_INT (12);
3123 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3124 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3125 else
3126 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3127
3128 case 1:
3129 return "#";
3130
3131 default:
3132 abort ();
3133 }
3134 }
3135 [(set_attr "type" "multi")
3136 (set_attr "mode" "XF,SI")])
3137
3138 (define_insn "*pushtf_integer"
3139 [(set (match_operand:TF 0 "push_operand" "=<,<")
3140 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3141 "!optimize_size"
3142 {
3143 switch (which_alternative)
3144 {
3145 case 0:
3146 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3147 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3148 operands[2] = stack_pointer_rtx;
3149 operands[3] = GEN_INT (16);
3150 if (TARGET_64BIT)
3151 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3152 return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3153 else
3154 return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3155 else
3156 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3157 return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
3158 else
3159 return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
3160
3161 case 1:
3162 return "#";
3163
3164 default:
3165 abort ();
3166 }
3167 }
3168 [(set_attr "type" "multi")
3169 (set_attr "mode" "XF,SI")])
3170
3171 (define_split
3172 [(set (match_operand 0 "push_operand" "")
3173 (match_operand 1 "general_operand" ""))]
3174 "reload_completed
3175 && (GET_MODE (operands[0]) == XFmode
3176 || GET_MODE (operands[0]) == TFmode
3177 || GET_MODE (operands[0]) == DFmode)
3178 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3179 [(const_int 0)]
3180 "ix86_split_long_move (operands); DONE;")
3181
3182 (define_split
3183 [(set (match_operand:XF 0 "push_operand" "")
3184 (match_operand:XF 1 "register_operand" ""))]
3185 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3186 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3187 (set (mem:XF (reg:SI 7)) (match_dup 1))])
3188
3189 (define_split
3190 [(set (match_operand:TF 0 "push_operand" "")
3191 (match_operand:TF 1 "register_operand" ""))]
3192 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3193 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3194 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3195
3196 (define_split
3197 [(set (match_operand:TF 0 "push_operand" "")
3198 (match_operand:TF 1 "register_operand" ""))]
3199 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3200 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3201 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3202
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3207 "!TARGET_64BIT
3208 && optimize_size
3209 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3210 && (reload_in_progress || reload_completed
3211 || GET_CODE (operands[1]) != CONST_DOUBLE
3212 || memory_operand (operands[0], XFmode))"
3213 {
3214 switch (which_alternative)
3215 {
3216 case 0:
3217 if (REG_P (operands[1])
3218 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3219 return "fstp\t%y0";
3220 else if (STACK_TOP_P (operands[0]))
3221 return "fld%z1\t%y1";
3222 else
3223 return "fst\t%y0";
3224
3225 case 1:
3226 /* There is no non-popping store to memory for XFmode. So if
3227 we need one, follow the store with a load. */
3228 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3229 return "fstp%z0\t%y0\;fld%z0\t%y0";
3230 else
3231 return "fstp%z0\t%y0";
3232
3233 case 2:
3234 switch (standard_80387_constant_p (operands[1]))
3235 {
3236 case 1:
3237 return "fldz";
3238 case 2:
3239 return "fld1";
3240 }
3241 break;
3242
3243 case 3: case 4:
3244 return "#";
3245 }
3246 abort();
3247 }
3248 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3249 (set_attr "mode" "XF,XF,XF,SI,SI")])
3250
3251 (define_insn "*movtf_nointeger"
3252 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3253 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3254 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3255 && optimize_size
3256 && (reload_in_progress || reload_completed
3257 || GET_CODE (operands[1]) != CONST_DOUBLE
3258 || memory_operand (operands[0], TFmode))"
3259 {
3260 switch (which_alternative)
3261 {
3262 case 0:
3263 if (REG_P (operands[1])
3264 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3265 return "fstp\t%y0";
3266 else if (STACK_TOP_P (operands[0]))
3267 return "fld%z1\t%y1";
3268 else
3269 return "fst\t%y0";
3270
3271 case 1:
3272 /* There is no non-popping store to memory for XFmode. So if
3273 we need one, follow the store with a load. */
3274 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3275 return "fstp%z0\t%y0\;fld%z0\t%y0";
3276 else
3277 return "fstp%z0\t%y0";
3278
3279 case 2:
3280 switch (standard_80387_constant_p (operands[1]))
3281 {
3282 case 1:
3283 return "fldz";
3284 case 2:
3285 return "fld1";
3286 }
3287 break;
3288
3289 case 3: case 4:
3290 return "#";
3291 }
3292 abort();
3293 }
3294 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3295 (set_attr "mode" "XF,XF,XF,SI,SI")])
3296
3297 (define_insn "*movxf_integer"
3298 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3299 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3300 "!TARGET_64BIT
3301 && !optimize_size
3302 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3303 && (reload_in_progress || reload_completed
3304 || GET_CODE (operands[1]) != CONST_DOUBLE
3305 || memory_operand (operands[0], XFmode))"
3306 {
3307 switch (which_alternative)
3308 {
3309 case 0:
3310 if (REG_P (operands[1])
3311 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3312 return "fstp\t%y0";
3313 else if (STACK_TOP_P (operands[0]))
3314 return "fld%z1\t%y1";
3315 else
3316 return "fst\t%y0";
3317
3318 case 1:
3319 /* There is no non-popping store to memory for XFmode. So if
3320 we need one, follow the store with a load. */
3321 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3322 return "fstp%z0\t%y0\;fld%z0\t%y0";
3323 else
3324 return "fstp%z0\t%y0";
3325
3326 case 2:
3327 switch (standard_80387_constant_p (operands[1]))
3328 {
3329 case 1:
3330 return "fldz";
3331 case 2:
3332 return "fld1";
3333 }
3334 break;
3335
3336 case 3: case 4:
3337 return "#";
3338 }
3339 abort();
3340 }
3341 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3342 (set_attr "mode" "XF,XF,XF,SI,SI")])
3343
3344 (define_insn "*movtf_integer"
3345 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3346 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3347 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3348 && !optimize_size
3349 && (reload_in_progress || reload_completed
3350 || GET_CODE (operands[1]) != CONST_DOUBLE
3351 || memory_operand (operands[0], TFmode))"
3352 {
3353 switch (which_alternative)
3354 {
3355 case 0:
3356 if (REG_P (operands[1])
3357 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3358 return "fstp\t%y0";
3359 else if (STACK_TOP_P (operands[0]))
3360 return "fld%z1\t%y1";
3361 else
3362 return "fst\t%y0";
3363
3364 case 1:
3365 /* There is no non-popping store to memory for XFmode. So if
3366 we need one, follow the store with a load. */
3367 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3368 return "fstp%z0\t%y0\;fld%z0\t%y0";
3369 else
3370 return "fstp%z0\t%y0";
3371
3372 case 2:
3373 switch (standard_80387_constant_p (operands[1]))
3374 {
3375 case 1:
3376 return "fldz";
3377 case 2:
3378 return "fld1";
3379 }
3380 break;
3381
3382 case 3: case 4:
3383 return "#";
3384 }
3385 abort();
3386 }
3387 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3388 (set_attr "mode" "XF,XF,XF,SI,SI")])
3389
3390 (define_split
3391 [(set (match_operand 0 "nonimmediate_operand" "")
3392 (match_operand 1 "general_operand" ""))]
3393 "reload_completed
3394 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3395 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3396 && ! (ANY_FP_REG_P (operands[0]) ||
3397 (GET_CODE (operands[0]) == SUBREG
3398 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3399 && ! (ANY_FP_REG_P (operands[1]) ||
3400 (GET_CODE (operands[1]) == SUBREG
3401 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3402 [(const_int 0)]
3403 "ix86_split_long_move (operands); DONE;")
3404
3405 (define_split
3406 [(set (match_operand 0 "register_operand" "")
3407 (match_operand 1 "memory_operand" ""))]
3408 "reload_completed
3409 && GET_CODE (operands[1]) == MEM
3410 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3411 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3412 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3413 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3414 && (!(SSE_REG_P (operands[0]) ||
3415 (GET_CODE (operands[0]) == SUBREG
3416 && SSE_REG_P (SUBREG_REG (operands[0]))))
3417 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3418 && (!(FP_REG_P (operands[0]) ||
3419 (GET_CODE (operands[0]) == SUBREG
3420 && FP_REG_P (SUBREG_REG (operands[0]))))
3421 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3422 [(set (match_dup 0)
3423 (match_dup 1))]
3424 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3425
3426 (define_insn "swapxf"
3427 [(set (match_operand:XF 0 "register_operand" "+f")
3428 (match_operand:XF 1 "register_operand" "+f"))
3429 (set (match_dup 1)
3430 (match_dup 0))]
3431 ""
3432 {
3433 if (STACK_TOP_P (operands[0]))
3434 return "fxch\t%1";
3435 else
3436 return "fxch\t%0";
3437 }
3438 [(set_attr "type" "fxch")
3439 (set_attr "mode" "XF")])
3440
3441 (define_insn "swaptf"
3442 [(set (match_operand:TF 0 "register_operand" "+f")
3443 (match_operand:TF 1 "register_operand" "+f"))
3444 (set (match_dup 1)
3445 (match_dup 0))]
3446 ""
3447 {
3448 if (STACK_TOP_P (operands[0]))
3449 return "fxch\t%1";
3450 else
3451 return "fxch\t%0";
3452 }
3453 [(set_attr "type" "fxch")
3454 (set_attr "mode" "XF")])
3455 \f
3456 ;; Zero extension instructions
3457
3458 (define_expand "zero_extendhisi2"
3459 [(set (match_operand:SI 0 "register_operand" "")
3460 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3461 ""
3462 {
3463 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3464 {
3465 operands[1] = force_reg (HImode, operands[1]);
3466 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3467 DONE;
3468 }
3469 })
3470
3471 (define_insn "zero_extendhisi2_and"
3472 [(set (match_operand:SI 0 "register_operand" "=r")
3473 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3474 (clobber (reg:CC 17))]
3475 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3476 "#"
3477 [(set_attr "type" "alu1")
3478 (set_attr "mode" "SI")])
3479
3480 (define_split
3481 [(set (match_operand:SI 0 "register_operand" "")
3482 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3483 (clobber (reg:CC 17))]
3484 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3485 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3486 (clobber (reg:CC 17))])]
3487 "")
3488
3489 (define_insn "*zero_extendhisi2_movzwl"
3490 [(set (match_operand:SI 0 "register_operand" "=r")
3491 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3492 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3493 "movz{wl|x}\t{%1, %0|%0, %1}"
3494 [(set_attr "type" "imovx")
3495 (set_attr "mode" "SI")])
3496
3497 (define_expand "zero_extendqihi2"
3498 [(parallel
3499 [(set (match_operand:HI 0 "register_operand" "")
3500 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3501 (clobber (reg:CC 17))])]
3502 ""
3503 "")
3504
3505 (define_insn "*zero_extendqihi2_and"
3506 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3507 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3508 (clobber (reg:CC 17))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3510 "#"
3511 [(set_attr "type" "alu1")
3512 (set_attr "mode" "HI")])
3513
3514 (define_insn "*zero_extendqihi2_movzbw_and"
3515 [(set (match_operand:HI 0 "register_operand" "=r,r")
3516 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3517 (clobber (reg:CC 17))]
3518 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3519 "#"
3520 [(set_attr "type" "imovx,alu1")
3521 (set_attr "mode" "HI")])
3522
3523 (define_insn "*zero_extendqihi2_movzbw"
3524 [(set (match_operand:HI 0 "register_operand" "=r")
3525 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3526 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3527 "movz{bw|x}\t{%1, %0|%0, %1}"
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "HI")])
3530
3531 ;; For the movzbw case strip only the clobber
3532 (define_split
3533 [(set (match_operand:HI 0 "register_operand" "")
3534 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC 17))]
3536 "reload_completed
3537 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3538 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3541
3542 ;; When source and destination does not overlap, clear destination
3543 ;; first and then do the movb
3544 (define_split
3545 [(set (match_operand:HI 0 "register_operand" "")
3546 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3547 (clobber (reg:CC 17))]
3548 "reload_completed
3549 && ANY_QI_REG_P (operands[0])
3550 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3551 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3552 [(set (match_dup 0) (const_int 0))
3553 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3554 "operands[2] = gen_lowpart (QImode, operands[0]);")
3555
3556 ;; Rest is handled by single and.
3557 (define_split
3558 [(set (match_operand:HI 0 "register_operand" "")
3559 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3560 (clobber (reg:CC 17))]
3561 "reload_completed
3562 && true_regnum (operands[0]) == true_regnum (operands[1])"
3563 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3564 (clobber (reg:CC 17))])]
3565 "")
3566
3567 (define_expand "zero_extendqisi2"
3568 [(parallel
3569 [(set (match_operand:SI 0 "register_operand" "")
3570 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3571 (clobber (reg:CC 17))])]
3572 ""
3573 "")
3574
3575 (define_insn "*zero_extendqisi2_and"
3576 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3577 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3578 (clobber (reg:CC 17))]
3579 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3580 "#"
3581 [(set_attr "type" "alu1")
3582 (set_attr "mode" "SI")])
3583
3584 (define_insn "*zero_extendqisi2_movzbw_and"
3585 [(set (match_operand:SI 0 "register_operand" "=r,r")
3586 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3587 (clobber (reg:CC 17))]
3588 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3589 "#"
3590 [(set_attr "type" "imovx,alu1")
3591 (set_attr "mode" "SI")])
3592
3593 (define_insn "*zero_extendqisi2_movzbw"
3594 [(set (match_operand:SI 0 "register_operand" "=r")
3595 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3596 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3597 "movz{bl|x}\t{%1, %0|%0, %1}"
3598 [(set_attr "type" "imovx")
3599 (set_attr "mode" "SI")])
3600
3601 ;; For the movzbl case strip only the clobber
3602 (define_split
3603 [(set (match_operand:SI 0 "register_operand" "")
3604 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605 (clobber (reg:CC 17))]
3606 "reload_completed
3607 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3608 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3609 [(set (match_dup 0)
3610 (zero_extend:SI (match_dup 1)))])
3611
3612 ;; When source and destination does not overlap, clear destination
3613 ;; first and then do the movb
3614 (define_split
3615 [(set (match_operand:SI 0 "register_operand" "")
3616 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3617 (clobber (reg:CC 17))]
3618 "reload_completed
3619 && ANY_QI_REG_P (operands[0])
3620 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3621 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3622 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3623 [(set (match_dup 0) (const_int 0))
3624 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3625 "operands[2] = gen_lowpart (QImode, operands[0]);")
3626
3627 ;; Rest is handled by single and.
3628 (define_split
3629 [(set (match_operand:SI 0 "register_operand" "")
3630 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3631 (clobber (reg:CC 17))]
3632 "reload_completed
3633 && true_regnum (operands[0]) == true_regnum (operands[1])"
3634 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3635 (clobber (reg:CC 17))])]
3636 "")
3637
3638 ;; %%% Kill me once multi-word ops are sane.
3639 (define_expand "zero_extendsidi2"
3640 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3642 ""
3643 "if (!TARGET_64BIT)
3644 {
3645 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3646 DONE;
3647 }
3648 ")
3649
3650 (define_insn "zero_extendsidi2_32"
3651 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3652 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3653 (clobber (reg:CC 17))]
3654 "!TARGET_64BIT"
3655 "#"
3656 [(set_attr "mode" "SI")])
3657
3658 (define_insn "zero_extendsidi2_rex64"
3659 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3660 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3661 "TARGET_64BIT"
3662 "@
3663 mov\t{%k1, %k0|%k0, %k1}
3664 #"
3665 [(set_attr "type" "imovx,imov")
3666 (set_attr "mode" "SI,DI")])
3667
3668 (define_split
3669 [(set (match_operand:DI 0 "memory_operand" "")
3670 (zero_extend:DI (match_dup 0)))]
3671 "TARGET_64BIT"
3672 [(set (match_dup 4) (const_int 0))]
3673 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3674
3675 (define_split
3676 [(set (match_operand:DI 0 "register_operand" "")
3677 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3678 (clobber (reg:CC 17))]
3679 "!TARGET_64BIT && reload_completed
3680 && true_regnum (operands[0]) == true_regnum (operands[1])"
3681 [(set (match_dup 4) (const_int 0))]
3682 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3683
3684 (define_split
3685 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3686 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3687 (clobber (reg:CC 17))]
3688 "!TARGET_64BIT && reload_completed"
3689 [(set (match_dup 3) (match_dup 1))
3690 (set (match_dup 4) (const_int 0))]
3691 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3692
3693 (define_insn "zero_extendhidi2"
3694 [(set (match_operand:DI 0 "register_operand" "=r,r")
3695 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3696 "TARGET_64BIT"
3697 "@
3698 movz{wl|x}\t{%1, %k0|%k0, %1}
3699 movz{wq|x}\t{%1, %0|%0, %1}"
3700 [(set_attr "type" "imovx")
3701 (set_attr "mode" "SI,DI")])
3702
3703 (define_insn "zero_extendqidi2"
3704 [(set (match_operand:DI 0 "register_operand" "=r,r")
3705 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3706 "TARGET_64BIT"
3707 "@
3708 movz{bl|x}\t{%1, %k0|%k0, %1}
3709 movz{bq|x}\t{%1, %0|%0, %1}"
3710 [(set_attr "type" "imovx")
3711 (set_attr "mode" "SI,DI")])
3712 \f
3713 ;; Sign extension instructions
3714
3715 (define_expand "extendsidi2"
3716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC 17))
3719 (clobber (match_scratch:SI 2 ""))])]
3720 ""
3721 {
3722 if (TARGET_64BIT)
3723 {
3724 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3725 DONE;
3726 }
3727 })
3728
3729 (define_insn "*extendsidi2_1"
3730 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3732 (clobber (reg:CC 17))
3733 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3734 "!TARGET_64BIT"
3735 "#")
3736
3737 (define_insn "extendsidi2_rex64"
3738 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3740 "TARGET_64BIT"
3741 "@
3742 {cltq|cdqe}
3743 movs{lq|x}\t{%1,%0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "DI")
3746 (set_attr "prefix_0f" "0")
3747 (set_attr "modrm" "0,1")])
3748
3749 (define_insn "extendhidi2"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3752 "TARGET_64BIT"
3753 "movs{wq|x}\t{%1,%0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3756
3757 (define_insn "extendqidi2"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3759 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760 "TARGET_64BIT"
3761 "movs{bq|x}\t{%1,%0|%0, %1}"
3762 [(set_attr "type" "imovx")
3763 (set_attr "mode" "DI")])
3764
3765 ;; Extend to memory case when source register does die.
3766 (define_split
3767 [(set (match_operand:DI 0 "memory_operand" "")
3768 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3769 (clobber (reg:CC 17))
3770 (clobber (match_operand:SI 2 "register_operand" ""))]
3771 "(reload_completed
3772 && dead_or_set_p (insn, operands[1])
3773 && !reg_mentioned_p (operands[1], operands[0]))"
3774 [(set (match_dup 3) (match_dup 1))
3775 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776 (clobber (reg:CC 17))])
3777 (set (match_dup 4) (match_dup 1))]
3778 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3779
3780 ;; Extend to memory case when source register does not die.
3781 (define_split
3782 [(set (match_operand:DI 0 "memory_operand" "")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3784 (clobber (reg:CC 17))
3785 (clobber (match_operand:SI 2 "register_operand" ""))]
3786 "reload_completed"
3787 [(const_int 0)]
3788 {
3789 split_di (&operands[0], 1, &operands[3], &operands[4]);
3790
3791 emit_move_insn (operands[3], operands[1]);
3792
3793 /* Generate a cltd if possible and doing so it profitable. */
3794 if (true_regnum (operands[1]) == 0
3795 && true_regnum (operands[2]) == 1
3796 && (optimize_size || TARGET_USE_CLTD))
3797 {
3798 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3799 }
3800 else
3801 {
3802 emit_move_insn (operands[2], operands[1]);
3803 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3804 }
3805 emit_move_insn (operands[4], operands[2]);
3806 DONE;
3807 })
3808
3809 ;; Extend to register case. Optimize case where source and destination
3810 ;; registers match and cases where we can use cltd.
3811 (define_split
3812 [(set (match_operand:DI 0 "register_operand" "")
3813 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3814 (clobber (reg:CC 17))
3815 (clobber (match_scratch:SI 2 ""))]
3816 "reload_completed"
3817 [(const_int 0)]
3818 {
3819 split_di (&operands[0], 1, &operands[3], &operands[4]);
3820
3821 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822 emit_move_insn (operands[3], operands[1]);
3823
3824 /* Generate a cltd if possible and doing so it profitable. */
3825 if (true_regnum (operands[3]) == 0
3826 && (optimize_size || TARGET_USE_CLTD))
3827 {
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3829 DONE;
3830 }
3831
3832 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833 emit_move_insn (operands[4], operands[1]);
3834
3835 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3836 DONE;
3837 })
3838
3839 (define_insn "extendhisi2"
3840 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3842 ""
3843 {
3844 switch (get_attr_prefix_0f (insn))
3845 {
3846 case 0:
3847 return "{cwtl|cwde}";
3848 default:
3849 return "movs{wl|x}\t{%1,%0|%0, %1}";
3850 }
3851 }
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "SI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3858 (const_string "0")
3859 (const_string "1")))
3860 (set (attr "modrm")
3861 (if_then_else (eq_attr "prefix_0f" "0")
3862 (const_string "0")
3863 (const_string "1")))])
3864
3865 (define_insn "*extendhisi2_zext"
3866 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3867 (zero_extend:DI
3868 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3869 "TARGET_64BIT"
3870 {
3871 switch (get_attr_prefix_0f (insn))
3872 {
3873 case 0:
3874 return "{cwtl|cwde}";
3875 default:
3876 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3877 }
3878 }
3879 [(set_attr "type" "imovx")
3880 (set_attr "mode" "SI")
3881 (set (attr "prefix_0f")
3882 ;; movsx is short decodable while cwtl is vector decoded.
3883 (if_then_else (and (eq_attr "cpu" "!k6")
3884 (eq_attr "alternative" "0"))
3885 (const_string "0")
3886 (const_string "1")))
3887 (set (attr "modrm")
3888 (if_then_else (eq_attr "prefix_0f" "0")
3889 (const_string "0")
3890 (const_string "1")))])
3891
3892 (define_insn "extendqihi2"
3893 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3895 ""
3896 {
3897 switch (get_attr_prefix_0f (insn))
3898 {
3899 case 0:
3900 return "{cbtw|cbw}";
3901 default:
3902 return "movs{bw|x}\t{%1,%0|%0, %1}";
3903 }
3904 }
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "HI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3911 (const_string "0")
3912 (const_string "1")))
3913 (set (attr "modrm")
3914 (if_then_else (eq_attr "prefix_0f" "0")
3915 (const_string "0")
3916 (const_string "1")))])
3917
3918 (define_insn "extendqisi2"
3919 [(set (match_operand:SI 0 "register_operand" "=r")
3920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3921 ""
3922 "movs{bl|x}\t{%1,%0|%0, %1}"
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "SI")])
3925
3926 (define_insn "*extendqisi2_zext"
3927 [(set (match_operand:DI 0 "register_operand" "=r")
3928 (zero_extend:DI
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3930 "TARGET_64BIT"
3931 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3934 \f
3935 ;; Conversions between float and double.
3936
3937 ;; These are all no-ops in the model used for the 80387. So just
3938 ;; emit moves.
3939
3940 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3941 (define_insn "*dummy_extendsfdf2"
3942 [(set (match_operand:DF 0 "push_operand" "=<")
3943 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3944 "0"
3945 "#")
3946
3947 (define_split
3948 [(set (match_operand:DF 0 "push_operand" "")
3949 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3950 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3951 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3952 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3953
3954 (define_split
3955 [(set (match_operand:DF 0 "push_operand" "")
3956 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3957 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3958 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3959 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3960
3961 (define_insn "*dummy_extendsfxf2"
3962 [(set (match_operand:XF 0 "push_operand" "=<")
3963 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3964 "0"
3965 "#")
3966
3967 (define_split
3968 [(set (match_operand:XF 0 "push_operand" "")
3969 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3970 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3971 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3972 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3973
3974 (define_insn "*dummy_extendsftf2"
3975 [(set (match_operand:TF 0 "push_operand" "=<")
3976 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3977 "0"
3978 "#")
3979
3980 (define_split
3981 [(set (match_operand:TF 0 "push_operand" "")
3982 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3983 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3984 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3985 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3986
3987 (define_split
3988 [(set (match_operand:TF 0 "push_operand" "")
3989 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3990 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
3991 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3992 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3993
3994 (define_insn "*dummy_extenddfxf2"
3995 [(set (match_operand:XF 0 "push_operand" "=<")
3996 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3997 "0"
3998 "#")
3999
4000 (define_split
4001 [(set (match_operand:XF 0 "push_operand" "")
4002 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4003 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4004 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4005 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4006
4007 (define_insn "*dummy_extenddftf2"
4008 [(set (match_operand:TF 0 "push_operand" "=<")
4009 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4010 "0"
4011 "#")
4012
4013 (define_split
4014 [(set (match_operand:TF 0 "push_operand" "")
4015 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4016 "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4017 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4018 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4019
4020 (define_split
4021 [(set (match_operand:TF 0 "push_operand" "")
4022 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4023 "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
4024 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4025 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
4026
4027 (define_expand "extendsfdf2"
4028 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4029 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4030 "TARGET_80387 || TARGET_SSE2"
4031 {
4032 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4033 operands[1] = force_reg (SFmode, operands[1]);
4034 })
4035
4036 (define_insn "*extendsfdf2_1"
4037 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
4038 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
4039 "(TARGET_80387 || TARGET_SSE2)
4040 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4041 {
4042 switch (which_alternative)
4043 {
4044 case 0:
4045 if (REG_P (operands[1])
4046 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4047 return "fstp\t%y0";
4048 else if (STACK_TOP_P (operands[0]))
4049 return "fld%z1\t%y1";
4050 else
4051 return "fst\t%y0";
4052
4053 case 1:
4054 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4055 return "fstp%z0\t%y0";
4056
4057 else
4058 return "fst%z0\t%y0";
4059 case 2:
4060 return "cvtss2sd\t{%1, %0|%0, %1}";
4061
4062 default:
4063 abort ();
4064 }
4065 }
4066 [(set_attr "type" "fmov,fmov,sse")
4067 (set_attr "mode" "SF,XF,DF")])
4068
4069 (define_insn "*extendsfdf2_1_sse_only"
4070 [(set (match_operand:DF 0 "register_operand" "=Y")
4071 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4072 "!TARGET_80387 && TARGET_SSE2
4073 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4074 "cvtss2sd\t{%1, %0|%0, %1}"
4075 [(set_attr "type" "sse")
4076 (set_attr "mode" "DF")])
4077
4078 (define_expand "extendsfxf2"
4079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4080 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4081 "!TARGET_64BIT && TARGET_80387"
4082 {
4083 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4084 operands[1] = force_reg (SFmode, operands[1]);
4085 })
4086
4087 (define_insn "*extendsfxf2_1"
4088 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4089 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4090 "!TARGET_64BIT && TARGET_80387
4091 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4092 {
4093 switch (which_alternative)
4094 {
4095 case 0:
4096 if (REG_P (operands[1])
4097 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4098 return "fstp\t%y0";
4099 else if (STACK_TOP_P (operands[0]))
4100 return "fld%z1\t%y1";
4101 else
4102 return "fst\t%y0";
4103
4104 case 1:
4105 /* There is no non-popping store to memory for XFmode. So if
4106 we need one, follow the store with a load. */
4107 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4108 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4109 else
4110 return "fstp%z0\t%y0";
4111
4112 default:
4113 abort ();
4114 }
4115 }
4116 [(set_attr "type" "fmov")
4117 (set_attr "mode" "SF,XF")])
4118
4119 (define_expand "extendsftf2"
4120 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4121 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4122 "TARGET_80387"
4123 {
4124 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4125 operands[1] = force_reg (SFmode, operands[1]);
4126 })
4127
4128 (define_insn "*extendsftf2_1"
4129 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4130 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4131 "TARGET_80387
4132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4133 {
4134 switch (which_alternative)
4135 {
4136 case 0:
4137 if (REG_P (operands[1])
4138 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp\t%y0";
4140 else if (STACK_TOP_P (operands[0]))
4141 return "fld%z1\t%y1";
4142 else
4143 return "fst\t%y0";
4144
4145 case 1:
4146 /* There is no non-popping store to memory for XFmode. So if
4147 we need one, follow the store with a load. */
4148 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4149 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4150 else
4151 return "fstp%z0\t%y0";
4152
4153 default:
4154 abort ();
4155 }
4156 }
4157 [(set_attr "type" "fmov")
4158 (set_attr "mode" "SF,XF")])
4159
4160 (define_expand "extenddfxf2"
4161 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4162 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4163 "!TARGET_64BIT && TARGET_80387"
4164 {
4165 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4166 operands[1] = force_reg (DFmode, operands[1]);
4167 })
4168
4169 (define_insn "*extenddfxf2_1"
4170 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4171 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4172 "!TARGET_64BIT && TARGET_80387
4173 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4174 {
4175 switch (which_alternative)
4176 {
4177 case 0:
4178 if (REG_P (operands[1])
4179 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4180 return "fstp\t%y0";
4181 else if (STACK_TOP_P (operands[0]))
4182 return "fld%z1\t%y1";
4183 else
4184 return "fst\t%y0";
4185
4186 case 1:
4187 /* There is no non-popping store to memory for XFmode. So if
4188 we need one, follow the store with a load. */
4189 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4190 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4191 else
4192 return "fstp%z0\t%y0";
4193
4194 default:
4195 abort ();
4196 }
4197 }
4198 [(set_attr "type" "fmov")
4199 (set_attr "mode" "DF,XF")])
4200
4201 (define_expand "extenddftf2"
4202 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4203 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4204 "TARGET_80387"
4205 {
4206 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4207 operands[1] = force_reg (DFmode, operands[1]);
4208 })
4209
4210 (define_insn "*extenddftf2_1"
4211 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4212 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4213 "TARGET_80387
4214 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4215 {
4216 switch (which_alternative)
4217 {
4218 case 0:
4219 if (REG_P (operands[1])
4220 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221 return "fstp\t%y0";
4222 else if (STACK_TOP_P (operands[0]))
4223 return "fld%z1\t%y1";
4224 else
4225 return "fst\t%y0";
4226
4227 case 1:
4228 /* There is no non-popping store to memory for XFmode. So if
4229 we need one, follow the store with a load. */
4230 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4231 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
4232 else
4233 return "fstp%z0\t%y0";
4234
4235 default:
4236 abort ();
4237 }
4238 }
4239 [(set_attr "type" "fmov")
4240 (set_attr "mode" "DF,XF")])
4241
4242 ;; %%% This seems bad bad news.
4243 ;; This cannot output into an f-reg because there is no way to be sure
4244 ;; of truncating in that case. Otherwise this is just like a simple move
4245 ;; insn. So we pretend we can output to a reg in order to get better
4246 ;; register preferencing, but we really use a stack slot.
4247
4248 (define_expand "truncdfsf2"
4249 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4250 (float_truncate:SF
4251 (match_operand:DF 1 "register_operand" "")))
4252 (clobber (match_dup 2))])]
4253 "TARGET_80387 || TARGET_SSE2"
4254 "
4255 if (TARGET_80387)
4256 operands[2] = assign_386_stack_local (SFmode, 0);
4257 else
4258 {
4259 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4260 DONE;
4261 }
4262 ")
4263
4264 (define_insn "*truncdfsf2_1"
4265 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4266 (float_truncate:SF
4267 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4268 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4269 "TARGET_80387 && !TARGET_SSE2"
4270 {
4271 switch (which_alternative)
4272 {
4273 case 0:
4274 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4275 return "fstp%z0\t%y0";
4276 else
4277 return "fst%z0\t%y0";
4278 default:
4279 abort ();
4280 }
4281 }
4282 [(set_attr "type" "fmov,multi,multi,multi")
4283 (set_attr "mode" "SF,SF,SF,SF")])
4284
4285 (define_insn "*truncdfsf2_1_sse"
4286 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4287 (float_truncate:SF
4288 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4289 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4290 "TARGET_80387 && TARGET_SSE2"
4291 {
4292 switch (which_alternative)
4293 {
4294 case 0:
4295 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4296 return "fstp%z0\t%y0";
4297 else
4298 return "fst%z0\t%y0";
4299 case 4:
4300 return "cvtsd2ss\t{%1, %0|%0, %1}";
4301 default:
4302 abort ();
4303 }
4304 }
4305 [(set_attr "type" "fmov,multi,multi,multi,sse")
4306 (set_attr "mode" "SF,SF,SF,SF,DF")])
4307
4308 (define_insn "*truncdfsf2_2"
4309 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4310 (float_truncate:SF
4311 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4312 "TARGET_80387 && TARGET_SSE2
4313 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4314 {
4315 switch (which_alternative)
4316 {
4317 case 0:
4318 return "cvtsd2ss\t{%1, %0|%0, %1}";
4319 case 1:
4320 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4321 return "fstp%z0\t%y0";
4322 else
4323 return "fst%z0\t%y0";
4324 default:
4325 abort ();
4326 }
4327 }
4328 [(set_attr "type" "sse,fmov")
4329 (set_attr "mode" "DF,SF")])
4330
4331 (define_insn "truncdfsf2_3"
4332 [(set (match_operand:SF 0 "memory_operand" "=m")
4333 (float_truncate:SF
4334 (match_operand:DF 1 "register_operand" "f")))]
4335 "TARGET_80387"
4336 {
4337 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4338 return "fstp%z0\t%y0";
4339 else
4340 return "fst%z0\t%y0";
4341 }
4342 [(set_attr "type" "fmov")
4343 (set_attr "mode" "SF")])
4344
4345 (define_insn "truncdfsf2_sse_only"
4346 [(set (match_operand:SF 0 "register_operand" "=Y")
4347 (float_truncate:SF
4348 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4349 "!TARGET_80387 && TARGET_SSE2"
4350 "cvtsd2ss\t{%1, %0|%0, %1}"
4351 [(set_attr "type" "sse")
4352 (set_attr "mode" "DF")])
4353
4354 (define_split
4355 [(set (match_operand:SF 0 "memory_operand" "")
4356 (float_truncate:SF
4357 (match_operand:DF 1 "register_operand" "")))
4358 (clobber (match_operand:SF 2 "memory_operand" ""))]
4359 "TARGET_80387"
4360 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4361 "")
4362
4363 (define_split
4364 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4365 (float_truncate:SF
4366 (match_operand:DF 1 "nonimmediate_operand" "")))
4367 (clobber (match_operand 2 "" ""))]
4368 "TARGET_80387 && reload_completed
4369 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4370 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4371 "")
4372
4373 (define_split
4374 [(set (match_operand:SF 0 "register_operand" "")
4375 (float_truncate:SF
4376 (match_operand:DF 1 "register_operand" "")))
4377 (clobber (match_operand:SF 2 "memory_operand" ""))]
4378 "TARGET_80387 && reload_completed
4379 && FP_REG_P (operands[1])"
4380 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4381 (set (match_dup 0) (match_dup 2))]
4382 "")
4383
4384 (define_expand "truncxfsf2"
4385 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4386 (float_truncate:SF
4387 (match_operand:XF 1 "register_operand" "")))
4388 (clobber (match_dup 2))])]
4389 "!TARGET_64BIT && TARGET_80387"
4390 "operands[2] = assign_386_stack_local (SFmode, 0);")
4391
4392 (define_insn "*truncxfsf2_1"
4393 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4394 (float_truncate:SF
4395 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4396 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4397 "!TARGET_64BIT && TARGET_80387"
4398 {
4399 switch (which_alternative)
4400 {
4401 case 0:
4402 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4403 return "fstp%z0\t%y0";
4404 else
4405 return "fst%z0\t%y0";
4406 default:
4407 abort();
4408 }
4409 }
4410 [(set_attr "type" "fmov,multi,multi,multi")
4411 (set_attr "mode" "SF")])
4412
4413 (define_insn "*truncxfsf2_2"
4414 [(set (match_operand:SF 0 "memory_operand" "=m")
4415 (float_truncate:SF
4416 (match_operand:XF 1 "register_operand" "f")))]
4417 "!TARGET_64BIT && TARGET_80387"
4418 {
4419 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4420 return "fstp%z0\t%y0";
4421 else
4422 return "fst%z0\t%y0";
4423 }
4424 [(set_attr "type" "fmov")
4425 (set_attr "mode" "SF")])
4426
4427 (define_split
4428 [(set (match_operand:SF 0 "memory_operand" "")
4429 (float_truncate:SF
4430 (match_operand:XF 1 "register_operand" "")))
4431 (clobber (match_operand:SF 2 "memory_operand" ""))]
4432 "TARGET_80387"
4433 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4434 "")
4435
4436 (define_split
4437 [(set (match_operand:SF 0 "register_operand" "")
4438 (float_truncate:SF
4439 (match_operand:XF 1 "register_operand" "")))
4440 (clobber (match_operand:SF 2 "memory_operand" ""))]
4441 "TARGET_80387 && reload_completed"
4442 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4443 (set (match_dup 0) (match_dup 2))]
4444 "")
4445
4446 (define_expand "trunctfsf2"
4447 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4448 (float_truncate:SF
4449 (match_operand:TF 1 "register_operand" "")))
4450 (clobber (match_dup 2))])]
4451 "TARGET_80387"
4452 "operands[2] = assign_386_stack_local (SFmode, 0);")
4453
4454 (define_insn "*trunctfsf2_1"
4455 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4456 (float_truncate:SF
4457 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4458 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4459 "TARGET_80387"
4460 {
4461 switch (which_alternative)
4462 {
4463 case 0:
4464 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4465 return "fstp%z0\t%y0";
4466 else
4467 return "fst%z0\t%y0";
4468 default:
4469 abort();
4470 }
4471 }
4472 [(set_attr "type" "fmov,multi,multi,multi")
4473 (set_attr "mode" "SF")])
4474
4475 (define_insn "*trunctfsf2_2"
4476 [(set (match_operand:SF 0 "memory_operand" "=m")
4477 (float_truncate:SF
4478 (match_operand:TF 1 "register_operand" "f")))]
4479 "TARGET_80387"
4480 {
4481 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4482 return "fstp%z0\t%y0";
4483 else
4484 return "fst%z0\t%y0";
4485 }
4486 [(set_attr "type" "fmov")
4487 (set_attr "mode" "SF")])
4488
4489 (define_split
4490 [(set (match_operand:SF 0 "memory_operand" "")
4491 (float_truncate:SF
4492 (match_operand:TF 1 "register_operand" "")))
4493 (clobber (match_operand:SF 2 "memory_operand" ""))]
4494 "TARGET_80387"
4495 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4496 "")
4497
4498 (define_split
4499 [(set (match_operand:SF 0 "register_operand" "")
4500 (float_truncate:SF
4501 (match_operand:TF 1 "register_operand" "")))
4502 (clobber (match_operand:SF 2 "memory_operand" ""))]
4503 "TARGET_80387 && reload_completed"
4504 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4505 (set (match_dup 0) (match_dup 2))]
4506 "")
4507
4508
4509 (define_expand "truncxfdf2"
4510 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4511 (float_truncate:DF
4512 (match_operand:XF 1 "register_operand" "")))
4513 (clobber (match_dup 2))])]
4514 "!TARGET_64BIT && TARGET_80387"
4515 "operands[2] = assign_386_stack_local (DFmode, 0);")
4516
4517 (define_insn "*truncxfdf2_1"
4518 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4519 (float_truncate:DF
4520 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4521 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4522 "!TARGET_64BIT && TARGET_80387"
4523 {
4524 switch (which_alternative)
4525 {
4526 case 0:
4527 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4528 return "fstp%z0\t%y0";
4529 else
4530 return "fst%z0\t%y0";
4531 default:
4532 abort();
4533 }
4534 abort ();
4535 }
4536 [(set_attr "type" "fmov,multi,multi,multi")
4537 (set_attr "mode" "DF")])
4538
4539 (define_insn "*truncxfdf2_2"
4540 [(set (match_operand:DF 0 "memory_operand" "=m")
4541 (float_truncate:DF
4542 (match_operand:XF 1 "register_operand" "f")))]
4543 "!TARGET_64BIT && TARGET_80387"
4544 {
4545 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4546 return "fstp%z0\t%y0";
4547 else
4548 return "fst%z0\t%y0";
4549 }
4550 [(set_attr "type" "fmov")
4551 (set_attr "mode" "DF")])
4552
4553 (define_split
4554 [(set (match_operand:DF 0 "memory_operand" "")
4555 (float_truncate:DF
4556 (match_operand:XF 1 "register_operand" "")))
4557 (clobber (match_operand:DF 2 "memory_operand" ""))]
4558 "TARGET_80387"
4559 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4560 "")
4561
4562 (define_split
4563 [(set (match_operand:DF 0 "register_operand" "")
4564 (float_truncate:DF
4565 (match_operand:XF 1 "register_operand" "")))
4566 (clobber (match_operand:DF 2 "memory_operand" ""))]
4567 "TARGET_80387 && reload_completed"
4568 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4569 (set (match_dup 0) (match_dup 2))]
4570 "")
4571
4572 (define_expand "trunctfdf2"
4573 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4574 (float_truncate:DF
4575 (match_operand:TF 1 "register_operand" "")))
4576 (clobber (match_dup 2))])]
4577 "TARGET_80387"
4578 "operands[2] = assign_386_stack_local (DFmode, 0);")
4579
4580 (define_insn "*trunctfdf2_1"
4581 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4582 (float_truncate:DF
4583 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4584 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4585 "TARGET_80387"
4586 {
4587 switch (which_alternative)
4588 {
4589 case 0:
4590 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4591 return "fstp%z0\t%y0";
4592 else
4593 return "fst%z0\t%y0";
4594 default:
4595 abort();
4596 }
4597 abort ();
4598 }
4599 [(set_attr "type" "fmov,multi,multi,multi")
4600 (set_attr "mode" "DF")])
4601
4602 (define_insn "*trunctfdf2_2"
4603 [(set (match_operand:DF 0 "memory_operand" "=m")
4604 (float_truncate:DF
4605 (match_operand:TF 1 "register_operand" "f")))]
4606 "TARGET_80387"
4607 {
4608 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4609 return "fstp%z0\t%y0";
4610 else
4611 return "fst%z0\t%y0";
4612 }
4613 [(set_attr "type" "fmov")
4614 (set_attr "mode" "DF")])
4615
4616 (define_split
4617 [(set (match_operand:DF 0 "memory_operand" "")
4618 (float_truncate:DF
4619 (match_operand:TF 1 "register_operand" "")))
4620 (clobber (match_operand:DF 2 "memory_operand" ""))]
4621 "TARGET_80387"
4622 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4623 "")
4624
4625 (define_split
4626 [(set (match_operand:DF 0 "register_operand" "")
4627 (float_truncate:DF
4628 (match_operand:TF 1 "register_operand" "")))
4629 (clobber (match_operand:DF 2 "memory_operand" ""))]
4630 "TARGET_80387 && reload_completed"
4631 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4632 (set (match_dup 0) (match_dup 2))]
4633 "")
4634
4635 \f
4636 ;; %%% Break up all these bad boys.
4637
4638 ;; Signed conversion to DImode.
4639
4640 (define_expand "fix_truncxfdi2"
4641 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4642 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4643 "!TARGET_64BIT && TARGET_80387"
4644 "")
4645
4646 (define_expand "fix_trunctfdi2"
4647 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4648 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4649 "TARGET_80387"
4650 "")
4651
4652 (define_expand "fix_truncdfdi2"
4653 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4654 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4655 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4656 {
4657 if (TARGET_64BIT && TARGET_SSE2)
4658 {
4659 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4660 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4661 if (out != operands[0])
4662 emit_move_insn (operands[0], out);
4663 DONE;
4664 }
4665 })
4666
4667 (define_expand "fix_truncsfdi2"
4668 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4669 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4670 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4671 {
4672 if (TARGET_SSE && TARGET_64BIT)
4673 {
4674 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4675 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4676 if (out != operands[0])
4677 emit_move_insn (operands[0], out);
4678 DONE;
4679 }
4680 })
4681
4682 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4683 ;; of the machinery.
4684 (define_insn_and_split "*fix_truncdi_1"
4685 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4686 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4687 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4688 && !reload_completed && !reload_in_progress
4689 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4690 "#"
4691 "&& 1"
4692 [(const_int 0)]
4693 {
4694 operands[2] = assign_386_stack_local (HImode, 1);
4695 operands[3] = assign_386_stack_local (HImode, 2);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4698 operands[2], operands[3]));
4699 else
4700 {
4701 operands[4] = assign_386_stack_local (DImode, 0);
4702 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4703 operands[2], operands[3],
4704 operands[4]));
4705 }
4706 DONE;
4707 }
4708 [(set_attr "type" "fistp")])
4709
4710 (define_insn "fix_truncdi_nomemory"
4711 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4712 (fix:DI (match_operand 1 "register_operand" "f,f")))
4713 (use (match_operand:HI 2 "memory_operand" "m,m"))
4714 (use (match_operand:HI 3 "memory_operand" "m,m"))
4715 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4716 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4717 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4719 "#"
4720 [(set_attr "type" "fistp")])
4721
4722 (define_insn "fix_truncdi_memory"
4723 [(set (match_operand:DI 0 "memory_operand" "=m")
4724 (fix:DI (match_operand 1 "register_operand" "f")))
4725 (use (match_operand:HI 2 "memory_operand" "m"))
4726 (use (match_operand:HI 3 "memory_operand" "m"))
4727 (clobber (match_scratch:DF 4 "=&1f"))]
4728 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4729 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4730 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4731 [(set_attr "type" "fistp")])
4732
4733 (define_split
4734 [(set (match_operand:DI 0 "register_operand" "")
4735 (fix:DI (match_operand 1 "register_operand" "")))
4736 (use (match_operand:HI 2 "memory_operand" ""))
4737 (use (match_operand:HI 3 "memory_operand" ""))
4738 (clobber (match_operand:DI 4 "memory_operand" ""))
4739 (clobber (match_scratch 5 ""))]
4740 "reload_completed"
4741 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4742 (use (match_dup 2))
4743 (use (match_dup 3))
4744 (clobber (match_dup 5))])
4745 (set (match_dup 0) (match_dup 4))]
4746 "")
4747
4748 (define_split
4749 [(set (match_operand:DI 0 "memory_operand" "")
4750 (fix:DI (match_operand 1 "register_operand" "")))
4751 (use (match_operand:HI 2 "memory_operand" ""))
4752 (use (match_operand:HI 3 "memory_operand" ""))
4753 (clobber (match_operand:DI 4 "memory_operand" ""))
4754 (clobber (match_scratch 5 ""))]
4755 "reload_completed"
4756 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4757 (use (match_dup 2))
4758 (use (match_dup 3))
4759 (clobber (match_dup 5))])]
4760 "")
4761
4762 ;; When SSE available, it is always faster to use it!
4763 (define_insn "fix_truncsfdi_sse"
4764 [(set (match_operand:DI 0 "register_operand" "=r")
4765 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4766 "TARGET_64BIT && TARGET_SSE"
4767 "cvttss2si{q}\t{%1, %0|%0, %1}"
4768 [(set_attr "type" "sse")])
4769
4770 (define_insn "fix_truncdfdi_sse"
4771 [(set (match_operand:DI 0 "register_operand" "=r")
4772 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4773 "TARGET_64BIT && TARGET_SSE2"
4774 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4775 [(set_attr "type" "sse")])
4776
4777 ;; Signed conversion to SImode.
4778
4779 (define_expand "fix_truncxfsi2"
4780 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4781 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4782 "!TARGET_64BIT && TARGET_80387"
4783 "")
4784
4785 (define_expand "fix_trunctfsi2"
4786 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4787 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4788 "TARGET_80387"
4789 "")
4790
4791 (define_expand "fix_truncdfsi2"
4792 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4793 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4794 "TARGET_80387 || TARGET_SSE2"
4795 {
4796 if (TARGET_SSE2)
4797 {
4798 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4799 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4800 if (out != operands[0])
4801 emit_move_insn (operands[0], out);
4802 DONE;
4803 }
4804 })
4805
4806 (define_expand "fix_truncsfsi2"
4807 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4808 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4809 "TARGET_80387 || TARGET_SSE"
4810 {
4811 if (TARGET_SSE)
4812 {
4813 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4814 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4815 if (out != operands[0])
4816 emit_move_insn (operands[0], out);
4817 DONE;
4818 }
4819 })
4820
4821 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4822 ;; of the machinery.
4823 (define_insn_and_split "*fix_truncsi_1"
4824 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4825 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4826 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4827 && !reload_completed && !reload_in_progress
4828 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4829 "#"
4830 "&& 1"
4831 [(const_int 0)]
4832 {
4833 operands[2] = assign_386_stack_local (HImode, 1);
4834 operands[3] = assign_386_stack_local (HImode, 2);
4835 if (memory_operand (operands[0], VOIDmode))
4836 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4837 operands[2], operands[3]));
4838 else
4839 {
4840 operands[4] = assign_386_stack_local (SImode, 0);
4841 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4842 operands[2], operands[3],
4843 operands[4]));
4844 }
4845 DONE;
4846 }
4847 [(set_attr "type" "fistp")])
4848
4849 (define_insn "fix_truncsi_nomemory"
4850 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4851 (fix:SI (match_operand 1 "register_operand" "f,f")))
4852 (use (match_operand:HI 2 "memory_operand" "m,m"))
4853 (use (match_operand:HI 3 "memory_operand" "m,m"))
4854 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4855 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4856 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4857 "#"
4858 [(set_attr "type" "fistp")])
4859
4860 (define_insn "fix_truncsi_memory"
4861 [(set (match_operand:SI 0 "memory_operand" "=m")
4862 (fix:SI (match_operand 1 "register_operand" "f")))
4863 (use (match_operand:HI 2 "memory_operand" "m"))
4864 (use (match_operand:HI 3 "memory_operand" "m"))]
4865 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4866 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4867 "* return output_fix_trunc (insn, operands);"
4868 [(set_attr "type" "fistp")])
4869
4870 ;; When SSE available, it is always faster to use it!
4871 (define_insn "fix_truncsfsi_sse"
4872 [(set (match_operand:SI 0 "register_operand" "=r")
4873 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4874 "TARGET_SSE"
4875 "cvttss2si\t{%1, %0|%0, %1}"
4876 [(set_attr "type" "sse")])
4877
4878 (define_insn "fix_truncdfsi_sse"
4879 [(set (match_operand:SI 0 "register_operand" "=r")
4880 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4881 "TARGET_SSE2"
4882 "cvttsd2si\t{%1, %0|%0, %1}"
4883 [(set_attr "type" "sse")])
4884
4885 (define_split
4886 [(set (match_operand:SI 0 "register_operand" "")
4887 (fix:SI (match_operand 1 "register_operand" "")))
4888 (use (match_operand:HI 2 "memory_operand" ""))
4889 (use (match_operand:HI 3 "memory_operand" ""))
4890 (clobber (match_operand:SI 4 "memory_operand" ""))]
4891 "reload_completed"
4892 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4893 (use (match_dup 2))
4894 (use (match_dup 3))])
4895 (set (match_dup 0) (match_dup 4))]
4896 "")
4897
4898 (define_split
4899 [(set (match_operand:SI 0 "memory_operand" "")
4900 (fix:SI (match_operand 1 "register_operand" "")))
4901 (use (match_operand:HI 2 "memory_operand" ""))
4902 (use (match_operand:HI 3 "memory_operand" ""))
4903 (clobber (match_operand:SI 4 "memory_operand" ""))]
4904 "reload_completed"
4905 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4906 (use (match_dup 2))
4907 (use (match_dup 3))])]
4908 "")
4909
4910 ;; Signed conversion to HImode.
4911
4912 (define_expand "fix_truncxfhi2"
4913 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4914 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4915 "!TARGET_64BIT && TARGET_80387"
4916 "")
4917
4918 (define_expand "fix_trunctfhi2"
4919 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4920 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4921 "TARGET_80387"
4922 "")
4923
4924 (define_expand "fix_truncdfhi2"
4925 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4926 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4927 "TARGET_80387 && !TARGET_SSE2"
4928 "")
4929
4930 (define_expand "fix_truncsfhi2"
4931 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4932 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4933 "TARGET_80387 && !TARGET_SSE"
4934 "")
4935
4936 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4937 ;; of the machinery.
4938 (define_insn_and_split "*fix_trunchi_1"
4939 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4940 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4941 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4942 && !reload_completed && !reload_in_progress
4943 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4944 "#"
4945 ""
4946 [(const_int 0)]
4947 {
4948 operands[2] = assign_386_stack_local (HImode, 1);
4949 operands[3] = assign_386_stack_local (HImode, 2);
4950 if (memory_operand (operands[0], VOIDmode))
4951 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4952 operands[2], operands[3]));
4953 else
4954 {
4955 operands[4] = assign_386_stack_local (HImode, 0);
4956 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4957 operands[2], operands[3],
4958 operands[4]));
4959 }
4960 DONE;
4961 }
4962 [(set_attr "type" "fistp")])
4963
4964 (define_insn "fix_trunchi_nomemory"
4965 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4966 (fix:HI (match_operand 1 "register_operand" "f,f")))
4967 (use (match_operand:HI 2 "memory_operand" "m,m"))
4968 (use (match_operand:HI 3 "memory_operand" "m,m"))
4969 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4970 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4971 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4972 "#"
4973 [(set_attr "type" "fistp")])
4974
4975 (define_insn "fix_trunchi_memory"
4976 [(set (match_operand:HI 0 "memory_operand" "=m")
4977 (fix:HI (match_operand 1 "register_operand" "f")))
4978 (use (match_operand:HI 2 "memory_operand" "m"))
4979 (use (match_operand:HI 3 "memory_operand" "m"))]
4980 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4981 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4982 "* return output_fix_trunc (insn, operands);"
4983 [(set_attr "type" "fistp")])
4984
4985 (define_split
4986 [(set (match_operand:HI 0 "memory_operand" "")
4987 (fix:HI (match_operand 1 "register_operand" "")))
4988 (use (match_operand:HI 2 "memory_operand" ""))
4989 (use (match_operand:HI 3 "memory_operand" ""))
4990 (clobber (match_operand:HI 4 "memory_operand" ""))]
4991 "reload_completed"
4992 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4993 (use (match_dup 2))
4994 (use (match_dup 3))])]
4995 "")
4996
4997 (define_split
4998 [(set (match_operand:HI 0 "register_operand" "")
4999 (fix:HI (match_operand 1 "register_operand" "")))
5000 (use (match_operand:HI 2 "memory_operand" ""))
5001 (use (match_operand:HI 3 "memory_operand" ""))
5002 (clobber (match_operand:HI 4 "memory_operand" ""))]
5003 "reload_completed"
5004 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
5005 (use (match_dup 2))
5006 (use (match_dup 3))
5007 (clobber (match_dup 4))])
5008 (set (match_dup 0) (match_dup 4))]
5009 "")
5010
5011 ;; %% Not used yet.
5012 (define_insn "x86_fnstcw_1"
5013 [(set (match_operand:HI 0 "memory_operand" "=m")
5014 (unspec:HI [(reg:HI 18)] 11))]
5015 "TARGET_80387"
5016 "fnstcw\t%0"
5017 [(set_attr "length" "2")
5018 (set_attr "mode" "HI")
5019 (set_attr "i387" "1")
5020 (set_attr "ppro_uops" "few")])
5021
5022 (define_insn "x86_fldcw_1"
5023 [(set (reg:HI 18)
5024 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
5025 "TARGET_80387"
5026 "fldcw\t%0"
5027 [(set_attr "length" "2")
5028 (set_attr "mode" "HI")
5029 (set_attr "i387" "1")
5030 (set_attr "athlon_decode" "vector")
5031 (set_attr "ppro_uops" "few")])
5032 \f
5033 ;; Conversion between fixed point and floating point.
5034
5035 ;; Even though we only accept memory inputs, the backend _really_
5036 ;; wants to be able to do this between registers.
5037
5038 (define_insn "floathisf2"
5039 [(set (match_operand:SF 0 "register_operand" "=f,f")
5040 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5041 "TARGET_80387 && !TARGET_SSE"
5042 "@
5043 fild%z1\t%1
5044 #"
5045 [(set_attr "type" "fmov,multi")
5046 (set_attr "mode" "SF")
5047 (set_attr "fp_int_src" "true")])
5048
5049 (define_expand "floatsisf2"
5050 [(set (match_operand:SF 0 "register_operand" "")
5051 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5052 "TARGET_SSE || TARGET_80387"
5053 "")
5054
5055 (define_insn "*floatsisf2_i387"
5056 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5057 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5058 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5059 "@
5060 fild%z1\t%1
5061 #
5062 cvtsi2ss\t{%1, %0|%0, %1}"
5063 [(set_attr "type" "fmov,multi,sse")
5064 (set_attr "mode" "SF")
5065 (set_attr "fp_int_src" "true")])
5066
5067 (define_insn "*floatsisf2_sse"
5068 [(set (match_operand:SF 0 "register_operand" "=x")
5069 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5070 "TARGET_SSE"
5071 "cvtsi2ss\t{%1, %0|%0, %1}"
5072 [(set_attr "type" "sse")
5073 (set_attr "mode" "SF")
5074 (set_attr "fp_int_src" "true")])
5075
5076 (define_expand "floatdisf2"
5077 [(set (match_operand:SF 0 "register_operand" "")
5078 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5079 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
5080 "")
5081
5082 (define_insn "*floatdisf2_i387_only"
5083 [(set (match_operand:SF 0 "register_operand" "=f,?f")
5084 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5085 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5086 "@
5087 fild%z1\t%1
5088 #"
5089 [(set_attr "type" "fmov,multi")
5090 (set_attr "mode" "SF")
5091 (set_attr "fp_int_src" "true")])
5092
5093 (define_insn "*floatdisf2_i387"
5094 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5095 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5096 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5097 "@
5098 fild%z1\t%1
5099 #
5100 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5101 [(set_attr "type" "fmov,multi,sse")
5102 (set_attr "mode" "SF")
5103 (set_attr "fp_int_src" "true")])
5104
5105 (define_insn "*floatdisf2_sse"
5106 [(set (match_operand:SF 0 "register_operand" "=x")
5107 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5108 "TARGET_64BIT && TARGET_SSE"
5109 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5110 [(set_attr "type" "sse")
5111 (set_attr "mode" "SF")
5112 (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "floathidf2"
5115 [(set (match_operand:DF 0 "register_operand" "=f,f")
5116 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5117 "TARGET_80387 && !TARGET_SSE2"
5118 "@
5119 fild%z1\t%1
5120 #"
5121 [(set_attr "type" "fmov,multi")
5122 (set_attr "mode" "DF")
5123 (set_attr "fp_int_src" "true")])
5124
5125 (define_expand "floatsidf2"
5126 [(set (match_operand:DF 0 "register_operand" "")
5127 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5128 ""
5129 "")
5130
5131 (define_insn "*floatsidf2_i387"
5132 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5133 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5134 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5135 "@
5136 fild%z1\t%1
5137 #
5138 cvtsi2sd\t{%1, %0|%0, %1}"
5139 [(set_attr "type" "fmov,multi,sse")
5140 (set_attr "mode" "DF")
5141 (set_attr "fp_int_src" "true")])
5142
5143 (define_insn "*floatsidf2_sse"
5144 [(set (match_operand:DF 0 "register_operand" "=Y")
5145 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5146 "TARGET_SSE2"
5147 "cvtsi2sd\t{%1, %0|%0, %1}"
5148 [(set_attr "type" "sse")
5149 (set_attr "mode" "DF")
5150 (set_attr "fp_int_src" "true")])
5151
5152 (define_expand "floatdidf2"
5153 [(set (match_operand:DF 0 "register_operand" "")
5154 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5155 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5156 "")
5157
5158 (define_insn "*floatdidf2_i387_only"
5159 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5160 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5161 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5162 "@
5163 fild%z1\t%1
5164 #"
5165 [(set_attr "type" "fmov,multi")
5166 (set_attr "mode" "DF")
5167 (set_attr "fp_int_src" "true")])
5168
5169 (define_insn "*floatdidf2_i387"
5170 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5171 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5172 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5173 "@
5174 fild%z1\t%1
5175 #
5176 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5177 [(set_attr "type" "fmov,multi,sse")
5178 (set_attr "mode" "DF")
5179 (set_attr "fp_int_src" "true")])
5180
5181 (define_insn "*floatdidf2_sse"
5182 [(set (match_operand:DF 0 "register_operand" "=Y")
5183 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5184 "TARGET_SSE2"
5185 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5186 [(set_attr "type" "sse")
5187 (set_attr "mode" "DF")
5188 (set_attr "fp_int_src" "true")])
5189
5190 (define_insn "floathixf2"
5191 [(set (match_operand:XF 0 "register_operand" "=f,f")
5192 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5193 "!TARGET_64BIT && TARGET_80387"
5194 "@
5195 fild%z1\t%1
5196 #"
5197 [(set_attr "type" "fmov,multi")
5198 (set_attr "mode" "XF")
5199 (set_attr "fp_int_src" "true")])
5200
5201 (define_insn "floathitf2"
5202 [(set (match_operand:TF 0 "register_operand" "=f,f")
5203 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5204 "TARGET_80387"
5205 "@
5206 fild%z1\t%1
5207 #"
5208 [(set_attr "type" "fmov,multi")
5209 (set_attr "mode" "XF")
5210 (set_attr "fp_int_src" "true")])
5211
5212 (define_insn "floatsixf2"
5213 [(set (match_operand:XF 0 "register_operand" "=f,f")
5214 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5215 "!TARGET_64BIT && TARGET_80387"
5216 "@
5217 fild%z1\t%1
5218 #"
5219 [(set_attr "type" "fmov,multi")
5220 (set_attr "mode" "XF")
5221 (set_attr "fp_int_src" "true")])
5222
5223 (define_insn "floatsitf2"
5224 [(set (match_operand:TF 0 "register_operand" "=f,f")
5225 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5226 "TARGET_80387"
5227 "@
5228 fild%z1\t%1
5229 #"
5230 [(set_attr "type" "fmov,multi")
5231 (set_attr "mode" "XF")
5232 (set_attr "fp_int_src" "true")])
5233
5234 (define_insn "floatdixf2"
5235 [(set (match_operand:XF 0 "register_operand" "=f,f")
5236 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5237 "!TARGET_64BIT && TARGET_80387"
5238 "@
5239 fild%z1\t%1
5240 #"
5241 [(set_attr "type" "fmov,multi")
5242 (set_attr "mode" "XF")
5243 (set_attr "fp_int_src" "true")])
5244
5245 (define_insn "floatditf2"
5246 [(set (match_operand:TF 0 "register_operand" "=f,f")
5247 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5248 "TARGET_80387"
5249 "@
5250 fild%z1\t%1
5251 #"
5252 [(set_attr "type" "fmov,multi")
5253 (set_attr "mode" "XF")
5254 (set_attr "fp_int_src" "true")])
5255
5256 ;; %%% Kill these when reload knows how to do it.
5257 (define_split
5258 [(set (match_operand 0 "register_operand" "")
5259 (float (match_operand 1 "register_operand" "")))]
5260 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5261 && FP_REG_P (operands[0])"
5262 [(const_int 0)]
5263 {
5264 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5265 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5267 ix86_free_from_memory (GET_MODE (operands[1]));
5268 DONE;
5269 })
5270 \f
5271 ;; Add instructions
5272
5273 ;; %%% splits for addsidi3
5274 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5275 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5276 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5277
5278 (define_expand "adddi3"
5279 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5280 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5281 (match_operand:DI 2 "x86_64_general_operand" "")))
5282 (clobber (reg:CC 17))]
5283 ""
5284 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5285
5286 (define_insn "*adddi3_1"
5287 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5288 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5289 (match_operand:DI 2 "general_operand" "roiF,riF")))
5290 (clobber (reg:CC 17))]
5291 "!TARGET_64BIT"
5292 "#")
5293
5294 (define_split
5295 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5296 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5297 (match_operand:DI 2 "general_operand" "")))
5298 (clobber (reg:CC 17))]
5299 "!TARGET_64BIT && reload_completed"
5300 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5301 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5302 (parallel [(set (match_dup 3)
5303 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5304 (match_dup 4))
5305 (match_dup 5)))
5306 (clobber (reg:CC 17))])]
5307 "split_di (operands+0, 1, operands+0, operands+3);
5308 split_di (operands+1, 1, operands+1, operands+4);
5309 split_di (operands+2, 1, operands+2, operands+5);")
5310
5311 (define_insn "*adddi3_carry_rex64"
5312 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5313 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5314 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5315 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5316 (clobber (reg:CC 17))]
5317 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5318 "adc{q}\t{%2, %0|%0, %2}"
5319 [(set_attr "type" "alu")
5320 (set_attr "pent_pair" "pu")
5321 (set_attr "mode" "DI")
5322 (set_attr "ppro_uops" "few")])
5323
5324 (define_insn "*adddi3_cc_rex64"
5325 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5326 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5327 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5328 (plus:DI (match_dup 1) (match_dup 2)))]
5329 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5330 "add{q}\t{%2, %0|%0, %2}"
5331 [(set_attr "type" "alu")
5332 (set_attr "mode" "DI")])
5333
5334 (define_insn "*addsi3_carry"
5335 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5336 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5337 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5338 (match_operand:SI 2 "general_operand" "ri,rm")))
5339 (clobber (reg:CC 17))]
5340 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5341 "adc{l}\t{%2, %0|%0, %2}"
5342 [(set_attr "type" "alu")
5343 (set_attr "pent_pair" "pu")
5344 (set_attr "mode" "SI")
5345 (set_attr "ppro_uops" "few")])
5346
5347 (define_insn "*addsi3_carry_zext"
5348 [(set (match_operand:DI 0 "register_operand" "=r")
5349 (zero_extend:DI
5350 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5351 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5352 (match_operand:SI 2 "general_operand" "rim"))))
5353 (clobber (reg:CC 17))]
5354 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5355 "adc{l}\t{%2, %k0|%k0, %2}"
5356 [(set_attr "type" "alu")
5357 (set_attr "pent_pair" "pu")
5358 (set_attr "mode" "SI")
5359 (set_attr "ppro_uops" "few")])
5360
5361 (define_insn "*addsi3_cc"
5362 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5363 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5364 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5365 (plus:SI (match_dup 1) (match_dup 2)))]
5366 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5367 "add{l}\t{%2, %0|%0, %2}"
5368 [(set_attr "type" "alu")
5369 (set_attr "mode" "SI")])
5370
5371 (define_insn "addqi3_cc"
5372 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5373 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5374 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5375 (plus:QI (match_dup 1) (match_dup 2)))]
5376 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5377 "add{b}\t{%2, %0|%0, %2}"
5378 [(set_attr "type" "alu")
5379 (set_attr "mode" "QI")])
5380
5381 (define_expand "addsi3"
5382 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5383 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5384 (match_operand:SI 2 "general_operand" "")))
5385 (clobber (reg:CC 17))])]
5386 ""
5387 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5388
5389 (define_insn "*lea_1"
5390 [(set (match_operand:SI 0 "register_operand" "=r")
5391 (match_operand:SI 1 "address_operand" "p"))]
5392 "!TARGET_64BIT"
5393 "lea{l}\t{%a1, %0|%0, %a1}"
5394 [(set_attr "type" "lea")
5395 (set_attr "mode" "SI")])
5396
5397 (define_insn "*lea_1_rex64"
5398 [(set (match_operand:SI 0 "register_operand" "=r")
5399 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5400 "TARGET_64BIT"
5401 "lea{l}\t{%a1, %0|%0, %a1}"
5402 [(set_attr "type" "lea")
5403 (set_attr "mode" "SI")])
5404
5405 (define_insn "*lea_1_zext"
5406 [(set (match_operand:DI 0 "register_operand" "=r")
5407 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5408 "TARGET_64BIT"
5409 "lea{l}\t{%a1, %k0|%k0, %a1}"
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "SI")])
5412
5413 (define_insn "*lea_2_rex64"
5414 [(set (match_operand:DI 0 "register_operand" "=r")
5415 (match_operand:DI 1 "address_operand" "p"))]
5416 "TARGET_64BIT"
5417 "lea{q}\t{%a1, %0|%0, %a1}"
5418 [(set_attr "type" "lea")
5419 (set_attr "mode" "DI")])
5420
5421 ;; The lea patterns for non-Pmodes needs to be matched by several
5422 ;; insns converted to real lea by splitters.
5423
5424 (define_insn_and_split "*lea_general_1"
5425 [(set (match_operand 0 "register_operand" "=r")
5426 (plus (plus (match_operand 1 "register_operand" "r")
5427 (match_operand 2 "register_operand" "r"))
5428 (match_operand 3 "immediate_operand" "i")))]
5429 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5430 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5431 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5432 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5433 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5434 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5435 || GET_MODE (operands[3]) == VOIDmode)"
5436 "#"
5437 "&& reload_completed"
5438 [(const_int 0)]
5439 {
5440 rtx pat;
5441 operands[0] = gen_lowpart (SImode, operands[0]);
5442 operands[1] = gen_lowpart (Pmode, operands[1]);
5443 operands[2] = gen_lowpart (Pmode, operands[2]);
5444 operands[3] = gen_lowpart (Pmode, operands[3]);
5445 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5446 operands[3]);
5447 if (Pmode != SImode)
5448 pat = gen_rtx_SUBREG (SImode, pat, 0);
5449 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5450 DONE;
5451 }
5452 [(set_attr "type" "lea")
5453 (set_attr "mode" "SI")])
5454
5455 (define_insn_and_split "*lea_general_1_zext"
5456 [(set (match_operand:DI 0 "register_operand" "=r")
5457 (zero_extend:DI
5458 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5459 (match_operand:SI 2 "register_operand" "r"))
5460 (match_operand:SI 3 "immediate_operand" "i"))))]
5461 "TARGET_64BIT"
5462 "#"
5463 "&& reload_completed"
5464 [(set (match_dup 0)
5465 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5466 (match_dup 2))
5467 (match_dup 3)) 0)))]
5468 {
5469 operands[1] = gen_lowpart (Pmode, operands[1]);
5470 operands[2] = gen_lowpart (Pmode, operands[2]);
5471 operands[3] = gen_lowpart (Pmode, operands[3]);
5472 }
5473 [(set_attr "type" "lea")
5474 (set_attr "mode" "SI")])
5475
5476 (define_insn_and_split "*lea_general_2"
5477 [(set (match_operand 0 "register_operand" "=r")
5478 (plus (mult (match_operand 1 "register_operand" "r")
5479 (match_operand 2 "const248_operand" "i"))
5480 (match_operand 3 "nonmemory_operand" "ri")))]
5481 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5482 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5483 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5484 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5485 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5486 || GET_MODE (operands[3]) == VOIDmode)"
5487 "#"
5488 "&& reload_completed"
5489 [(const_int 0)]
5490 {
5491 rtx pat;
5492 operands[0] = gen_lowpart (SImode, operands[0]);
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[3] = gen_lowpart (Pmode, operands[3]);
5495 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5496 operands[3]);
5497 if (Pmode != SImode)
5498 pat = gen_rtx_SUBREG (SImode, pat, 0);
5499 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5500 DONE;
5501 }
5502 [(set_attr "type" "lea")
5503 (set_attr "mode" "SI")])
5504
5505 (define_insn_and_split "*lea_general_2_zext"
5506 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (zero_extend:DI
5508 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5509 (match_operand:SI 2 "const248_operand" "n"))
5510 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5511 "TARGET_64BIT"
5512 "#"
5513 "&& reload_completed"
5514 [(set (match_dup 0)
5515 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5516 (match_dup 2))
5517 (match_dup 3)) 0)))]
5518 {
5519 operands[1] = gen_lowpart (Pmode, operands[1]);
5520 operands[3] = gen_lowpart (Pmode, operands[3]);
5521 }
5522 [(set_attr "type" "lea")
5523 (set_attr "mode" "SI")])
5524
5525 (define_insn_and_split "*lea_general_3"
5526 [(set (match_operand 0 "register_operand" "=r")
5527 (plus (plus (mult (match_operand 1 "register_operand" "r")
5528 (match_operand 2 "const248_operand" "i"))
5529 (match_operand 3 "register_operand" "r"))
5530 (match_operand 4 "immediate_operand" "i")))]
5531 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5532 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5533 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5534 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5535 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5536 "#"
5537 "&& reload_completed"
5538 [(const_int 0)]
5539 {
5540 rtx pat;
5541 operands[0] = gen_lowpart (SImode, operands[0]);
5542 operands[1] = gen_lowpart (Pmode, operands[1]);
5543 operands[3] = gen_lowpart (Pmode, operands[3]);
5544 operands[4] = gen_lowpart (Pmode, operands[4]);
5545 pat = gen_rtx_PLUS (Pmode,
5546 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5547 operands[2]),
5548 operands[3]),
5549 operands[4]);
5550 if (Pmode != SImode)
5551 pat = gen_rtx_SUBREG (SImode, pat, 0);
5552 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5553 DONE;
5554 }
5555 [(set_attr "type" "lea")
5556 (set_attr "mode" "SI")])
5557
5558 (define_insn_and_split "*lea_general_3_zext"
5559 [(set (match_operand:DI 0 "register_operand" "=r")
5560 (zero_extend:DI
5561 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5562 (match_operand:SI 2 "const248_operand" "n"))
5563 (match_operand:SI 3 "register_operand" "r"))
5564 (match_operand:SI 4 "immediate_operand" "i"))))]
5565 "TARGET_64BIT"
5566 "#"
5567 "&& reload_completed"
5568 [(set (match_dup 0)
5569 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5570 (match_dup 2))
5571 (match_dup 3))
5572 (match_dup 4)) 0)))]
5573 {
5574 operands[1] = gen_lowpart (Pmode, operands[1]);
5575 operands[3] = gen_lowpart (Pmode, operands[3]);
5576 operands[4] = gen_lowpart (Pmode, operands[4]);
5577 }
5578 [(set_attr "type" "lea")
5579 (set_attr "mode" "SI")])
5580
5581 (define_insn "*adddi_1_rex64"
5582 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5583 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5584 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5585 (clobber (reg:CC 17))]
5586 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5587 {
5588 switch (get_attr_type (insn))
5589 {
5590 case TYPE_LEA:
5591 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5592 return "lea{q}\t{%a2, %0|%0, %a2}";
5593
5594 case TYPE_INCDEC:
5595 if (! rtx_equal_p (operands[0], operands[1]))
5596 abort ();
5597 if (operands[2] == const1_rtx)
5598 return "inc{q}\t%0";
5599 else if (operands[2] == constm1_rtx)
5600 return "dec{q}\t%0";
5601 else
5602 abort ();
5603
5604 default:
5605 if (! rtx_equal_p (operands[0], operands[1]))
5606 abort ();
5607
5608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5610 if (GET_CODE (operands[2]) == CONST_INT
5611 /* Avoid overflows. */
5612 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5616 {
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
5618 return "sub{q}\t{%2, %0|%0, %2}";
5619 }
5620 return "add{q}\t{%2, %0|%0, %2}";
5621 }
5622 }
5623 [(set (attr "type")
5624 (cond [(eq_attr "alternative" "2")
5625 (const_string "lea")
5626 ; Current assemblers are broken and do not allow @GOTOFF in
5627 ; ought but a memory context.
5628 (match_operand:DI 2 "pic_symbolic_operand" "")
5629 (const_string "lea")
5630 (match_operand:DI 2 "incdec_operand" "")
5631 (const_string "incdec")
5632 ]
5633 (const_string "alu")))
5634 (set_attr "mode" "DI")])
5635
5636 ;; Convert lea to the lea pattern to avoid flags dependency.
5637 (define_split
5638 [(set (match_operand:DI 0 "register_operand" "")
5639 (plus:DI (match_operand:DI 1 "register_operand" "")
5640 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5641 (clobber (reg:CC 17))]
5642 "TARGET_64BIT && reload_completed
5643 && true_regnum (operands[0]) != true_regnum (operands[1])"
5644 [(set (match_dup 0)
5645 (plus:DI (match_dup 1)
5646 (match_dup 2)))]
5647 "")
5648
5649 (define_insn "*adddi_2_rex64"
5650 [(set (reg 17)
5651 (compare
5652 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5653 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5654 (const_int 0)))
5655 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5656 (plus:DI (match_dup 1) (match_dup 2)))]
5657 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5658 && ix86_binary_operator_ok (PLUS, DImode, operands)
5659 /* Current assemblers are broken and do not allow @GOTOFF in
5660 ought but a memory context. */
5661 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5662 {
5663 switch (get_attr_type (insn))
5664 {
5665 case TYPE_INCDEC:
5666 if (! rtx_equal_p (operands[0], operands[1]))
5667 abort ();
5668 if (operands[2] == const1_rtx)
5669 return "inc{q}\t%0";
5670 else if (operands[2] == constm1_rtx)
5671 return "dec{q}\t%0";
5672 else
5673 abort ();
5674
5675 default:
5676 if (! rtx_equal_p (operands[0], operands[1]))
5677 abort ();
5678 /* ???? We ought to handle there the 32bit case too
5679 - do we need new constrant? */
5680 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5681 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5682 if (GET_CODE (operands[2]) == CONST_INT
5683 /* Avoid overflows. */
5684 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5685 && (INTVAL (operands[2]) == 128
5686 || (INTVAL (operands[2]) < 0
5687 && INTVAL (operands[2]) != -128)))
5688 {
5689 operands[2] = GEN_INT (-INTVAL (operands[2]));
5690 return "sub{q}\t{%2, %0|%0, %2}";
5691 }
5692 return "add{q}\t{%2, %0|%0, %2}";
5693 }
5694 }
5695 [(set (attr "type")
5696 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5697 (const_string "incdec")
5698 (const_string "alu")))
5699 (set_attr "mode" "DI")])
5700
5701 (define_insn "*adddi_3_rex64"
5702 [(set (reg 17)
5703 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5704 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5705 (clobber (match_scratch:DI 0 "=r"))]
5706 "TARGET_64BIT
5707 && ix86_match_ccmode (insn, CCZmode)
5708 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5709 /* Current assemblers are broken and do not allow @GOTOFF in
5710 ought but a memory context. */
5711 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5712 {
5713 switch (get_attr_type (insn))
5714 {
5715 case TYPE_INCDEC:
5716 if (! rtx_equal_p (operands[0], operands[1]))
5717 abort ();
5718 if (operands[2] == const1_rtx)
5719 return "inc{q}\t%0";
5720 else if (operands[2] == constm1_rtx)
5721 return "dec{q}\t%0";
5722 else
5723 abort ();
5724
5725 default:
5726 if (! rtx_equal_p (operands[0], operands[1]))
5727 abort ();
5728 /* ???? We ought to handle there the 32bit case too
5729 - do we need new constrant? */
5730 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5731 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5732 if (GET_CODE (operands[2]) == CONST_INT
5733 /* Avoid overflows. */
5734 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5735 && (INTVAL (operands[2]) == 128
5736 || (INTVAL (operands[2]) < 0
5737 && INTVAL (operands[2]) != -128)))
5738 {
5739 operands[2] = GEN_INT (-INTVAL (operands[2]));
5740 return "sub{q}\t{%2, %0|%0, %2}";
5741 }
5742 return "add{q}\t{%2, %0|%0, %2}";
5743 }
5744 }
5745 [(set (attr "type")
5746 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5747 (const_string "incdec")
5748 (const_string "alu")))
5749 (set_attr "mode" "DI")])
5750
5751 ; For comparisons against 1, -1 and 128, we may generate better code
5752 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5753 ; is matched then. We can't accept general immediate, because for
5754 ; case of overflows, the result is messed up.
5755 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5756 ; when negated.
5757 ; Also carry flag is reversed compared to cmp, so this converison is valid
5758 ; only for comparisons not depending on it.
5759 (define_insn "*adddi_4_rex64"
5760 [(set (reg 17)
5761 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5762 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5763 (clobber (match_scratch:DI 0 "=rm"))]
5764 "TARGET_64BIT
5765 && ix86_match_ccmode (insn, CCGCmode)"
5766 {
5767 switch (get_attr_type (insn))
5768 {
5769 case TYPE_INCDEC:
5770 if (operands[2] == constm1_rtx)
5771 return "inc{q}\t%0";
5772 else if (operands[2] == const1_rtx)
5773 return "dec{q}\t%0";
5774 else
5775 abort();
5776
5777 default:
5778 if (! rtx_equal_p (operands[0], operands[1]))
5779 abort ();
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if ((INTVAL (operands[2]) == -128
5783 || (INTVAL (operands[2]) > 0
5784 && INTVAL (operands[2]) != 128))
5785 /* Avoid overflows. */
5786 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5787 return "sub{q}\t{%2, %0|%0, %2}";
5788 operands[2] = GEN_INT (-INTVAL (operands[2]));
5789 return "add{q}\t{%2, %0|%0, %2}";
5790 }
5791 }
5792 [(set (attr "type")
5793 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "DI")])
5797
5798 (define_insn "*adddi_5_rex64"
5799 [(set (reg 17)
5800 (compare
5801 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5802 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5803 (const_int 0)))
5804 (clobber (match_scratch:DI 0 "=r"))]
5805 "TARGET_64BIT
5806 && ix86_match_ccmode (insn, CCGOCmode)
5807 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5808 /* Current assemblers are broken and do not allow @GOTOFF in
5809 ought but a memory context. */
5810 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5811 {
5812 switch (get_attr_type (insn))
5813 {
5814 case TYPE_INCDEC:
5815 if (! rtx_equal_p (operands[0], operands[1]))
5816 abort ();
5817 if (operands[2] == const1_rtx)
5818 return "inc{q}\t%0";
5819 else if (operands[2] == constm1_rtx)
5820 return "dec{q}\t%0";
5821 else
5822 abort();
5823
5824 default:
5825 if (! rtx_equal_p (operands[0], operands[1]))
5826 abort ();
5827 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5828 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5829 if (GET_CODE (operands[2]) == CONST_INT
5830 /* Avoid overflows. */
5831 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5832 && (INTVAL (operands[2]) == 128
5833 || (INTVAL (operands[2]) < 0
5834 && INTVAL (operands[2]) != -128)))
5835 {
5836 operands[2] = GEN_INT (-INTVAL (operands[2]));
5837 return "sub{q}\t{%2, %0|%0, %2}";
5838 }
5839 return "add{q}\t{%2, %0|%0, %2}";
5840 }
5841 }
5842 [(set (attr "type")
5843 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5844 (const_string "incdec")
5845 (const_string "alu")))
5846 (set_attr "mode" "DI")])
5847
5848
5849 (define_insn "*addsi_1"
5850 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5851 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5852 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5853 (clobber (reg:CC 17))]
5854 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5855 {
5856 switch (get_attr_type (insn))
5857 {
5858 case TYPE_LEA:
5859 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5860 return "lea{l}\t{%a2, %0|%0, %a2}";
5861
5862 case TYPE_INCDEC:
5863 if (! rtx_equal_p (operands[0], operands[1]))
5864 abort ();
5865 if (operands[2] == const1_rtx)
5866 return "inc{l}\t%0";
5867 else if (operands[2] == constm1_rtx)
5868 return "dec{l}\t%0";
5869 else
5870 abort();
5871
5872 default:
5873 if (! rtx_equal_p (operands[0], operands[1]))
5874 abort ();
5875
5876 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5877 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5878 if (GET_CODE (operands[2]) == CONST_INT
5879 && (INTVAL (operands[2]) == 128
5880 || (INTVAL (operands[2]) < 0
5881 && INTVAL (operands[2]) != -128)))
5882 {
5883 operands[2] = GEN_INT (-INTVAL (operands[2]));
5884 return "sub{l}\t{%2, %0|%0, %2}";
5885 }
5886 return "add{l}\t{%2, %0|%0, %2}";
5887 }
5888 }
5889 [(set (attr "type")
5890 (cond [(eq_attr "alternative" "2")
5891 (const_string "lea")
5892 ; Current assemblers are broken and do not allow @GOTOFF in
5893 ; ought but a memory context.
5894 (match_operand:SI 2 "pic_symbolic_operand" "")
5895 (const_string "lea")
5896 (match_operand:SI 2 "incdec_operand" "")
5897 (const_string "incdec")
5898 ]
5899 (const_string "alu")))
5900 (set_attr "mode" "SI")])
5901
5902 ;; Convert lea to the lea pattern to avoid flags dependency.
5903 (define_split
5904 [(set (match_operand 0 "register_operand" "")
5905 (plus (match_operand 1 "register_operand" "")
5906 (match_operand 2 "nonmemory_operand" "")))
5907 (clobber (reg:CC 17))]
5908 "reload_completed
5909 && true_regnum (operands[0]) != true_regnum (operands[1])"
5910 [(const_int 0)]
5911 {
5912 rtx pat;
5913 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5914 may confuse gen_lowpart. */
5915 if (GET_MODE (operands[0]) != Pmode)
5916 {
5917 operands[1] = gen_lowpart (Pmode, operands[1]);
5918 operands[2] = gen_lowpart (Pmode, operands[2]);
5919 }
5920 operands[0] = gen_lowpart (SImode, operands[0]);
5921 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5922 if (Pmode != SImode)
5923 pat = gen_rtx_SUBREG (SImode, pat, 0);
5924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5925 DONE;
5926 })
5927
5928 ;; It may seem that nonimmediate operand is proper one for operand 1.
5929 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5930 ;; we take care in ix86_binary_operator_ok to not allow two memory
5931 ;; operands so proper swapping will be done in reload. This allow
5932 ;; patterns constructed from addsi_1 to match.
5933 (define_insn "addsi_1_zext"
5934 [(set (match_operand:DI 0 "register_operand" "=r,r")
5935 (zero_extend:DI
5936 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5937 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5938 (clobber (reg:CC 17))]
5939 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5940 {
5941 switch (get_attr_type (insn))
5942 {
5943 case TYPE_LEA:
5944 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5945 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5946
5947 case TYPE_INCDEC:
5948 if (operands[2] == const1_rtx)
5949 return "inc{l}\t%k0";
5950 else if (operands[2] == constm1_rtx)
5951 return "dec{l}\t%k0";
5952 else
5953 abort();
5954
5955 default:
5956 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5957 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5958 if (GET_CODE (operands[2]) == CONST_INT
5959 && (INTVAL (operands[2]) == 128
5960 || (INTVAL (operands[2]) < 0
5961 && INTVAL (operands[2]) != -128)))
5962 {
5963 operands[2] = GEN_INT (-INTVAL (operands[2]));
5964 return "sub{l}\t{%2, %k0|%k0, %2}";
5965 }
5966 return "add{l}\t{%2, %k0|%k0, %2}";
5967 }
5968 }
5969 [(set (attr "type")
5970 (cond [(eq_attr "alternative" "1")
5971 (const_string "lea")
5972 ; Current assemblers are broken and do not allow @GOTOFF in
5973 ; ought but a memory context.
5974 (match_operand:SI 2 "pic_symbolic_operand" "")
5975 (const_string "lea")
5976 (match_operand:SI 2 "incdec_operand" "")
5977 (const_string "incdec")
5978 ]
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5981
5982 ;; Convert lea to the lea pattern to avoid flags dependency.
5983 (define_split
5984 [(set (match_operand:DI 0 "register_operand" "")
5985 (zero_extend:DI
5986 (plus:SI (match_operand:SI 1 "register_operand" "")
5987 (match_operand:SI 2 "nonmemory_operand" ""))))
5988 (clobber (reg:CC 17))]
5989 "reload_completed
5990 && true_regnum (operands[0]) != true_regnum (operands[1])"
5991 [(set (match_dup 0)
5992 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5993 {
5994 operands[1] = gen_lowpart (Pmode, operands[1]);
5995 operands[2] = gen_lowpart (Pmode, operands[2]);
5996 })
5997
5998 (define_insn "*addsi_2"
5999 [(set (reg 17)
6000 (compare
6001 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6002 (match_operand:SI 2 "general_operand" "rmni,rni"))
6003 (const_int 0)))
6004 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6005 (plus:SI (match_dup 1) (match_dup 2)))]
6006 "ix86_match_ccmode (insn, CCGOCmode)
6007 && ix86_binary_operator_ok (PLUS, SImode, operands)
6008 /* Current assemblers are broken and do not allow @GOTOFF in
6009 ought but a memory context. */
6010 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6011 {
6012 switch (get_attr_type (insn))
6013 {
6014 case TYPE_INCDEC:
6015 if (! rtx_equal_p (operands[0], operands[1]))
6016 abort ();
6017 if (operands[2] == const1_rtx)
6018 return "inc{l}\t%0";
6019 else if (operands[2] == constm1_rtx)
6020 return "dec{l}\t%0";
6021 else
6022 abort();
6023
6024 default:
6025 if (! rtx_equal_p (operands[0], operands[1]))
6026 abort ();
6027 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6028 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6029 if (GET_CODE (operands[2]) == CONST_INT
6030 && (INTVAL (operands[2]) == 128
6031 || (INTVAL (operands[2]) < 0
6032 && INTVAL (operands[2]) != -128)))
6033 {
6034 operands[2] = GEN_INT (-INTVAL (operands[2]));
6035 return "sub{l}\t{%2, %0|%0, %2}";
6036 }
6037 return "add{l}\t{%2, %0|%0, %2}";
6038 }
6039 }
6040 [(set (attr "type")
6041 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set_attr "mode" "SI")])
6045
6046 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6047 (define_insn "*addsi_2_zext"
6048 [(set (reg 17)
6049 (compare
6050 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6051 (match_operand:SI 2 "general_operand" "rmni"))
6052 (const_int 0)))
6053 (set (match_operand:DI 0 "register_operand" "=r")
6054 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6055 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6056 && ix86_binary_operator_ok (PLUS, SImode, operands)
6057 /* Current assemblers are broken and do not allow @GOTOFF in
6058 ought but a memory context. */
6059 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6060 {
6061 switch (get_attr_type (insn))
6062 {
6063 case TYPE_INCDEC:
6064 if (operands[2] == const1_rtx)
6065 return "inc{l}\t%k0";
6066 else if (operands[2] == constm1_rtx)
6067 return "dec{l}\t%k0";
6068 else
6069 abort();
6070
6071 default:
6072 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6073 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6074 if (GET_CODE (operands[2]) == CONST_INT
6075 && (INTVAL (operands[2]) == 128
6076 || (INTVAL (operands[2]) < 0
6077 && INTVAL (operands[2]) != -128)))
6078 {
6079 operands[2] = GEN_INT (-INTVAL (operands[2]));
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6081 }
6082 return "add{l}\t{%2, %k0|%k0, %2}";
6083 }
6084 }
6085 [(set (attr "type")
6086 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set_attr "mode" "SI")])
6090
6091 (define_insn "*addsi_3"
6092 [(set (reg 17)
6093 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6094 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6095 (clobber (match_scratch:SI 0 "=r"))]
6096 "ix86_match_ccmode (insn, CCZmode)
6097 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6098 /* Current assemblers are broken and do not allow @GOTOFF in
6099 ought but a memory context. */
6100 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6101 {
6102 switch (get_attr_type (insn))
6103 {
6104 case TYPE_INCDEC:
6105 if (! rtx_equal_p (operands[0], operands[1]))
6106 abort ();
6107 if (operands[2] == const1_rtx)
6108 return "inc{l}\t%0";
6109 else if (operands[2] == constm1_rtx)
6110 return "dec{l}\t%0";
6111 else
6112 abort();
6113
6114 default:
6115 if (! rtx_equal_p (operands[0], operands[1]))
6116 abort ();
6117 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6118 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6119 if (GET_CODE (operands[2]) == CONST_INT
6120 && (INTVAL (operands[2]) == 128
6121 || (INTVAL (operands[2]) < 0
6122 && INTVAL (operands[2]) != -128)))
6123 {
6124 operands[2] = GEN_INT (-INTVAL (operands[2]));
6125 return "sub{l}\t{%2, %0|%0, %2}";
6126 }
6127 return "add{l}\t{%2, %0|%0, %2}";
6128 }
6129 }
6130 [(set (attr "type")
6131 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6132 (const_string "incdec")
6133 (const_string "alu")))
6134 (set_attr "mode" "SI")])
6135
6136 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6137 (define_insn "*addsi_3_zext"
6138 [(set (reg 17)
6139 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6140 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6141 (set (match_operand:DI 0 "register_operand" "=r")
6142 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6143 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6144 && ix86_binary_operator_ok (PLUS, SImode, operands)
6145 /* Current assemblers are broken and do not allow @GOTOFF in
6146 ought but a memory context. */
6147 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6148 {
6149 switch (get_attr_type (insn))
6150 {
6151 case TYPE_INCDEC:
6152 if (operands[2] == const1_rtx)
6153 return "inc{l}\t%k0";
6154 else if (operands[2] == constm1_rtx)
6155 return "dec{l}\t%k0";
6156 else
6157 abort();
6158
6159 default:
6160 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6162 if (GET_CODE (operands[2]) == CONST_INT
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6166 {
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
6168 return "sub{l}\t{%2, %k0|%k0, %2}";
6169 }
6170 return "add{l}\t{%2, %k0|%k0, %2}";
6171 }
6172 }
6173 [(set (attr "type")
6174 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set_attr "mode" "SI")])
6178
6179 ; For comparisons agains 1, -1 and 128, we may generate better code
6180 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6181 ; is matched then. We can't accept general immediate, because for
6182 ; case of overflows, the result is messed up.
6183 ; This pattern also don't hold of 0x80000000, since the value overflows
6184 ; when negated.
6185 ; Also carry flag is reversed compared to cmp, so this converison is valid
6186 ; only for comparisons not depending on it.
6187 (define_insn "*addsi_4"
6188 [(set (reg 17)
6189 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6190 (match_operand:SI 2 "const_int_operand" "n")))
6191 (clobber (match_scratch:SI 0 "=rm"))]
6192 "ix86_match_ccmode (insn, CCGCmode)
6193 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6194 {
6195 switch (get_attr_type (insn))
6196 {
6197 case TYPE_INCDEC:
6198 if (operands[2] == constm1_rtx)
6199 return "inc{l}\t%0";
6200 else if (operands[2] == const1_rtx)
6201 return "dec{l}\t%0";
6202 else
6203 abort();
6204
6205 default:
6206 if (! rtx_equal_p (operands[0], operands[1]))
6207 abort ();
6208 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6209 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6210 if ((INTVAL (operands[2]) == -128
6211 || (INTVAL (operands[2]) > 0
6212 && INTVAL (operands[2]) != 128)))
6213 return "sub{l}\t{%2, %0|%0, %2}";
6214 operands[2] = GEN_INT (-INTVAL (operands[2]));
6215 return "add{l}\t{%2, %0|%0, %2}";
6216 }
6217 }
6218 [(set (attr "type")
6219 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6220 (const_string "incdec")
6221 (const_string "alu")))
6222 (set_attr "mode" "SI")])
6223
6224 (define_insn "*addsi_5"
6225 [(set (reg 17)
6226 (compare
6227 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6228 (match_operand:SI 2 "general_operand" "rmni"))
6229 (const_int 0)))
6230 (clobber (match_scratch:SI 0 "=r"))]
6231 "ix86_match_ccmode (insn, CCGOCmode)
6232 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6233 /* Current assemblers are broken and do not allow @GOTOFF in
6234 ought but a memory context. */
6235 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6236 {
6237 switch (get_attr_type (insn))
6238 {
6239 case TYPE_INCDEC:
6240 if (! rtx_equal_p (operands[0], operands[1]))
6241 abort ();
6242 if (operands[2] == const1_rtx)
6243 return "inc{l}\t%0";
6244 else if (operands[2] == constm1_rtx)
6245 return "dec{l}\t%0";
6246 else
6247 abort();
6248
6249 default:
6250 if (! rtx_equal_p (operands[0], operands[1]))
6251 abort ();
6252 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6253 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6254 if (GET_CODE (operands[2]) == CONST_INT
6255 && (INTVAL (operands[2]) == 128
6256 || (INTVAL (operands[2]) < 0
6257 && INTVAL (operands[2]) != -128)))
6258 {
6259 operands[2] = GEN_INT (-INTVAL (operands[2]));
6260 return "sub{l}\t{%2, %0|%0, %2}";
6261 }
6262 return "add{l}\t{%2, %0|%0, %2}";
6263 }
6264 }
6265 [(set (attr "type")
6266 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6267 (const_string "incdec")
6268 (const_string "alu")))
6269 (set_attr "mode" "SI")])
6270
6271 (define_expand "addhi3"
6272 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6273 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6274 (match_operand:HI 2 "general_operand" "")))
6275 (clobber (reg:CC 17))])]
6276 "TARGET_HIMODE_MATH"
6277 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6278
6279 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6280 ;; type optimizations enabled by define-splits. This is not important
6281 ;; for PII, and in fact harmful because of partial register stalls.
6282
6283 (define_insn "*addhi_1_lea"
6284 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6285 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6286 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6287 (clobber (reg:CC 17))]
6288 "!TARGET_PARTIAL_REG_STALL
6289 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6290 {
6291 switch (get_attr_type (insn))
6292 {
6293 case TYPE_LEA:
6294 return "#";
6295 case TYPE_INCDEC:
6296 if (operands[2] == const1_rtx)
6297 return "inc{w}\t%0";
6298 else if (operands[2] == constm1_rtx
6299 || (GET_CODE (operands[2]) == CONST_INT
6300 && INTVAL (operands[2]) == 65535))
6301 return "dec{w}\t%0";
6302 abort();
6303
6304 default:
6305 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6306 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6307 if (GET_CODE (operands[2]) == CONST_INT
6308 && (INTVAL (operands[2]) == 128
6309 || (INTVAL (operands[2]) < 0
6310 && INTVAL (operands[2]) != -128)))
6311 {
6312 operands[2] = GEN_INT (-INTVAL (operands[2]));
6313 return "sub{w}\t{%2, %0|%0, %2}";
6314 }
6315 return "add{w}\t{%2, %0|%0, %2}";
6316 }
6317 }
6318 [(set (attr "type")
6319 (if_then_else (eq_attr "alternative" "2")
6320 (const_string "lea")
6321 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6322 (const_string "incdec")
6323 (const_string "alu"))))
6324 (set_attr "mode" "HI,HI,SI")])
6325
6326 (define_insn "*addhi_1"
6327 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6328 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6329 (match_operand:HI 2 "general_operand" "ri,rm")))
6330 (clobber (reg:CC 17))]
6331 "TARGET_PARTIAL_REG_STALL
6332 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6333 {
6334 switch (get_attr_type (insn))
6335 {
6336 case TYPE_INCDEC:
6337 if (operands[2] == const1_rtx)
6338 return "inc{w}\t%0";
6339 else if (operands[2] == constm1_rtx
6340 || (GET_CODE (operands[2]) == CONST_INT
6341 && INTVAL (operands[2]) == 65535))
6342 return "dec{w}\t%0";
6343 abort();
6344
6345 default:
6346 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6347 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6348 if (GET_CODE (operands[2]) == CONST_INT
6349 && (INTVAL (operands[2]) == 128
6350 || (INTVAL (operands[2]) < 0
6351 && INTVAL (operands[2]) != -128)))
6352 {
6353 operands[2] = GEN_INT (-INTVAL (operands[2]));
6354 return "sub{w}\t{%2, %0|%0, %2}";
6355 }
6356 return "add{w}\t{%2, %0|%0, %2}";
6357 }
6358 }
6359 [(set (attr "type")
6360 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6361 (const_string "incdec")
6362 (const_string "alu")))
6363 (set_attr "mode" "HI")])
6364
6365 (define_insn "*addhi_2"
6366 [(set (reg 17)
6367 (compare
6368 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6369 (match_operand:HI 2 "general_operand" "rmni,rni"))
6370 (const_int 0)))
6371 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6372 (plus:HI (match_dup 1) (match_dup 2)))]
6373 "ix86_match_ccmode (insn, CCGOCmode)
6374 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6375 {
6376 switch (get_attr_type (insn))
6377 {
6378 case TYPE_INCDEC:
6379 if (operands[2] == const1_rtx)
6380 return "inc{w}\t%0";
6381 else if (operands[2] == constm1_rtx
6382 || (GET_CODE (operands[2]) == CONST_INT
6383 && INTVAL (operands[2]) == 65535))
6384 return "dec{w}\t%0";
6385 abort();
6386
6387 default:
6388 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6389 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6390 if (GET_CODE (operands[2]) == CONST_INT
6391 && (INTVAL (operands[2]) == 128
6392 || (INTVAL (operands[2]) < 0
6393 && INTVAL (operands[2]) != -128)))
6394 {
6395 operands[2] = GEN_INT (-INTVAL (operands[2]));
6396 return "sub{w}\t{%2, %0|%0, %2}";
6397 }
6398 return "add{w}\t{%2, %0|%0, %2}";
6399 }
6400 }
6401 [(set (attr "type")
6402 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6403 (const_string "incdec")
6404 (const_string "alu")))
6405 (set_attr "mode" "HI")])
6406
6407 (define_insn "*addhi_3"
6408 [(set (reg 17)
6409 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6410 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6411 (clobber (match_scratch:HI 0 "=r"))]
6412 "ix86_match_ccmode (insn, CCZmode)
6413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6414 {
6415 switch (get_attr_type (insn))
6416 {
6417 case TYPE_INCDEC:
6418 if (operands[2] == const1_rtx)
6419 return "inc{w}\t%0";
6420 else if (operands[2] == constm1_rtx
6421 || (GET_CODE (operands[2]) == CONST_INT
6422 && INTVAL (operands[2]) == 65535))
6423 return "dec{w}\t%0";
6424 abort();
6425
6426 default:
6427 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6428 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6429 if (GET_CODE (operands[2]) == CONST_INT
6430 && (INTVAL (operands[2]) == 128
6431 || (INTVAL (operands[2]) < 0
6432 && INTVAL (operands[2]) != -128)))
6433 {
6434 operands[2] = GEN_INT (-INTVAL (operands[2]));
6435 return "sub{w}\t{%2, %0|%0, %2}";
6436 }
6437 return "add{w}\t{%2, %0|%0, %2}";
6438 }
6439 }
6440 [(set (attr "type")
6441 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6442 (const_string "incdec")
6443 (const_string "alu")))
6444 (set_attr "mode" "HI")])
6445
6446 ; See comments above addsi_3_imm for details.
6447 (define_insn "*addhi_4"
6448 [(set (reg 17)
6449 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6450 (match_operand:HI 2 "const_int_operand" "n")))
6451 (clobber (match_scratch:HI 0 "=rm"))]
6452 "ix86_match_ccmode (insn, CCGCmode)
6453 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6454 {
6455 switch (get_attr_type (insn))
6456 {
6457 case TYPE_INCDEC:
6458 if (operands[2] == constm1_rtx
6459 || (GET_CODE (operands[2]) == CONST_INT
6460 && INTVAL (operands[2]) == 65535))
6461 return "inc{w}\t%0";
6462 else if (operands[2] == const1_rtx)
6463 return "dec{w}\t%0";
6464 else
6465 abort();
6466
6467 default:
6468 if (! rtx_equal_p (operands[0], operands[1]))
6469 abort ();
6470 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6471 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6472 if ((INTVAL (operands[2]) == -128
6473 || (INTVAL (operands[2]) > 0
6474 && INTVAL (operands[2]) != 128)))
6475 return "sub{w}\t{%2, %0|%0, %2}";
6476 operands[2] = GEN_INT (-INTVAL (operands[2]));
6477 return "add{w}\t{%2, %0|%0, %2}";
6478 }
6479 }
6480 [(set (attr "type")
6481 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6482 (const_string "incdec")
6483 (const_string "alu")))
6484 (set_attr "mode" "SI")])
6485
6486
6487 (define_insn "*addhi_5"
6488 [(set (reg 17)
6489 (compare
6490 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6491 (match_operand:HI 2 "general_operand" "rmni"))
6492 (const_int 0)))
6493 (clobber (match_scratch:HI 0 "=r"))]
6494 "ix86_match_ccmode (insn, CCGOCmode)
6495 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6496 {
6497 switch (get_attr_type (insn))
6498 {
6499 case TYPE_INCDEC:
6500 if (operands[2] == const1_rtx)
6501 return "inc{w}\t%0";
6502 else if (operands[2] == constm1_rtx
6503 || (GET_CODE (operands[2]) == CONST_INT
6504 && INTVAL (operands[2]) == 65535))
6505 return "dec{w}\t%0";
6506 abort();
6507
6508 default:
6509 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6510 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6511 if (GET_CODE (operands[2]) == CONST_INT
6512 && (INTVAL (operands[2]) == 128
6513 || (INTVAL (operands[2]) < 0
6514 && INTVAL (operands[2]) != -128)))
6515 {
6516 operands[2] = GEN_INT (-INTVAL (operands[2]));
6517 return "sub{w}\t{%2, %0|%0, %2}";
6518 }
6519 return "add{w}\t{%2, %0|%0, %2}";
6520 }
6521 }
6522 [(set (attr "type")
6523 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6524 (const_string "incdec")
6525 (const_string "alu")))
6526 (set_attr "mode" "HI")])
6527
6528 (define_expand "addqi3"
6529 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6530 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6531 (match_operand:QI 2 "general_operand" "")))
6532 (clobber (reg:CC 17))])]
6533 "TARGET_QIMODE_MATH"
6534 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6535
6536 ;; %%% Potential partial reg stall on alternative 2. What to do?
6537 (define_insn "*addqi_1_lea"
6538 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6539 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6540 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6541 (clobber (reg:CC 17))]
6542 "!TARGET_PARTIAL_REG_STALL
6543 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6544 {
6545 int widen = (which_alternative == 2);
6546 switch (get_attr_type (insn))
6547 {
6548 case TYPE_LEA:
6549 return "#";
6550 case TYPE_INCDEC:
6551 if (operands[2] == const1_rtx)
6552 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6553 else if (operands[2] == constm1_rtx
6554 || (GET_CODE (operands[2]) == CONST_INT
6555 && INTVAL (operands[2]) == 255))
6556 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6557 abort();
6558
6559 default:
6560 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6561 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6562 if (GET_CODE (operands[2]) == CONST_INT
6563 && (INTVAL (operands[2]) == 128
6564 || (INTVAL (operands[2]) < 0
6565 && INTVAL (operands[2]) != -128)))
6566 {
6567 operands[2] = GEN_INT (-INTVAL (operands[2]));
6568 if (widen)
6569 return "sub{l}\t{%2, %k0|%k0, %2}";
6570 else
6571 return "sub{b}\t{%2, %0|%0, %2}";
6572 }
6573 if (widen)
6574 return "add{l}\t{%k2, %k0|%k0, %k2}";
6575 else
6576 return "add{b}\t{%2, %0|%0, %2}";
6577 }
6578 }
6579 [(set (attr "type")
6580 (if_then_else (eq_attr "alternative" "3")
6581 (const_string "lea")
6582 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6583 (const_string "incdec")
6584 (const_string "alu"))))
6585 (set_attr "mode" "QI,QI,SI,SI")])
6586
6587 (define_insn "*addqi_1"
6588 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6589 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6590 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6591 (clobber (reg:CC 17))]
6592 "TARGET_PARTIAL_REG_STALL
6593 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6594 {
6595 int widen = (which_alternative == 2);
6596 switch (get_attr_type (insn))
6597 {
6598 case TYPE_INCDEC:
6599 if (operands[2] == const1_rtx)
6600 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6601 else if (operands[2] == constm1_rtx
6602 || (GET_CODE (operands[2]) == CONST_INT
6603 && INTVAL (operands[2]) == 255))
6604 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6605 abort();
6606
6607 default:
6608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6610 if (GET_CODE (operands[2]) == CONST_INT
6611 && (INTVAL (operands[2]) == 128
6612 || (INTVAL (operands[2]) < 0
6613 && INTVAL (operands[2]) != -128)))
6614 {
6615 operands[2] = GEN_INT (-INTVAL (operands[2]));
6616 if (widen)
6617 return "sub{l}\t{%2, %k0|%k0, %2}";
6618 else
6619 return "sub{b}\t{%2, %0|%0, %2}";
6620 }
6621 if (widen)
6622 return "add{l}\t{%k2, %k0|%k0, %k2}";
6623 else
6624 return "add{b}\t{%2, %0|%0, %2}";
6625 }
6626 }
6627 [(set (attr "type")
6628 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6629 (const_string "incdec")
6630 (const_string "alu")))
6631 (set_attr "mode" "QI,QI,SI")])
6632
6633 (define_insn "*addqi_2"
6634 [(set (reg 17)
6635 (compare
6636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6637 (match_operand:QI 2 "general_operand" "qmni,qni"))
6638 (const_int 0)))
6639 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6640 (plus:QI (match_dup 1) (match_dup 2)))]
6641 "ix86_match_ccmode (insn, CCGOCmode)
6642 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6643 {
6644 switch (get_attr_type (insn))
6645 {
6646 case TYPE_INCDEC:
6647 if (operands[2] == const1_rtx)
6648 return "inc{b}\t%0";
6649 else if (operands[2] == constm1_rtx
6650 || (GET_CODE (operands[2]) == CONST_INT
6651 && INTVAL (operands[2]) == 255))
6652 return "dec{b}\t%0";
6653 abort();
6654
6655 default:
6656 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6657 if (GET_CODE (operands[2]) == CONST_INT
6658 && INTVAL (operands[2]) < 0)
6659 {
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
6661 return "sub{b}\t{%2, %0|%0, %2}";
6662 }
6663 return "add{b}\t{%2, %0|%0, %2}";
6664 }
6665 }
6666 [(set (attr "type")
6667 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6668 (const_string "incdec")
6669 (const_string "alu")))
6670 (set_attr "mode" "QI")])
6671
6672 (define_insn "*addqi_3"
6673 [(set (reg 17)
6674 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6675 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6676 (clobber (match_scratch:QI 0 "=q"))]
6677 "ix86_match_ccmode (insn, CCZmode)
6678 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6679 {
6680 switch (get_attr_type (insn))
6681 {
6682 case TYPE_INCDEC:
6683 if (operands[2] == const1_rtx)
6684 return "inc{b}\t%0";
6685 else if (operands[2] == constm1_rtx
6686 || (GET_CODE (operands[2]) == CONST_INT
6687 && INTVAL (operands[2]) == 255))
6688 return "dec{b}\t%0";
6689 abort();
6690
6691 default:
6692 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6693 if (GET_CODE (operands[2]) == CONST_INT
6694 && INTVAL (operands[2]) < 0)
6695 {
6696 operands[2] = GEN_INT (-INTVAL (operands[2]));
6697 return "sub{b}\t{%2, %0|%0, %2}";
6698 }
6699 return "add{b}\t{%2, %0|%0, %2}";
6700 }
6701 }
6702 [(set (attr "type")
6703 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6704 (const_string "incdec")
6705 (const_string "alu")))
6706 (set_attr "mode" "QI")])
6707
6708 ; See comments above addsi_3_imm for details.
6709 (define_insn "*addqi_4"
6710 [(set (reg 17)
6711 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6712 (match_operand:QI 2 "const_int_operand" "n")))
6713 (clobber (match_scratch:QI 0 "=qm"))]
6714 "ix86_match_ccmode (insn, CCGCmode)
6715 && (INTVAL (operands[2]) & 0xff) != 0x80"
6716 {
6717 switch (get_attr_type (insn))
6718 {
6719 case TYPE_INCDEC:
6720 if (operands[2] == constm1_rtx
6721 || (GET_CODE (operands[2]) == CONST_INT
6722 && INTVAL (operands[2]) == 255))
6723 return "inc{b}\t%0";
6724 else if (operands[2] == const1_rtx)
6725 return "dec{b}\t%0";
6726 else
6727 abort();
6728
6729 default:
6730 if (! rtx_equal_p (operands[0], operands[1]))
6731 abort ();
6732 if (INTVAL (operands[2]) < 0)
6733 {
6734 operands[2] = GEN_INT (-INTVAL (operands[2]));
6735 return "add{b}\t{%2, %0|%0, %2}";
6736 }
6737 return "sub{b}\t{%2, %0|%0, %2}";
6738 }
6739 }
6740 [(set (attr "type")
6741 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6742 (const_string "incdec")
6743 (const_string "alu")))
6744 (set_attr "mode" "QI")])
6745
6746
6747 (define_insn "*addqi_5"
6748 [(set (reg 17)
6749 (compare
6750 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6751 (match_operand:QI 2 "general_operand" "qmni"))
6752 (const_int 0)))
6753 (clobber (match_scratch:QI 0 "=q"))]
6754 "ix86_match_ccmode (insn, CCGOCmode)
6755 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6756 {
6757 switch (get_attr_type (insn))
6758 {
6759 case TYPE_INCDEC:
6760 if (operands[2] == const1_rtx)
6761 return "inc{b}\t%0";
6762 else if (operands[2] == constm1_rtx
6763 || (GET_CODE (operands[2]) == CONST_INT
6764 && INTVAL (operands[2]) == 255))
6765 return "dec{b}\t%0";
6766 abort();
6767
6768 default:
6769 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6770 if (GET_CODE (operands[2]) == CONST_INT
6771 && INTVAL (operands[2]) < 0)
6772 {
6773 operands[2] = GEN_INT (-INTVAL (operands[2]));
6774 return "sub{b}\t{%2, %0|%0, %2}";
6775 }
6776 return "add{b}\t{%2, %0|%0, %2}";
6777 }
6778 }
6779 [(set (attr "type")
6780 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6781 (const_string "incdec")
6782 (const_string "alu")))
6783 (set_attr "mode" "QI")])
6784
6785
6786 (define_insn "addqi_ext_1"
6787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6788 (const_int 8)
6789 (const_int 8))
6790 (plus:SI
6791 (zero_extract:SI
6792 (match_operand 1 "ext_register_operand" "0")
6793 (const_int 8)
6794 (const_int 8))
6795 (match_operand:QI 2 "general_operand" "Qmn")))
6796 (clobber (reg:CC 17))]
6797 "!TARGET_64BIT"
6798 {
6799 switch (get_attr_type (insn))
6800 {
6801 case TYPE_INCDEC:
6802 if (operands[2] == const1_rtx)
6803 return "inc{b}\t%h0";
6804 else if (operands[2] == constm1_rtx
6805 || (GET_CODE (operands[2]) == CONST_INT
6806 && INTVAL (operands[2]) == 255))
6807 return "dec{b}\t%h0";
6808 abort();
6809
6810 default:
6811 return "add{b}\t{%2, %h0|%h0, %2}";
6812 }
6813 }
6814 [(set (attr "type")
6815 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6816 (const_string "incdec")
6817 (const_string "alu")))
6818 (set_attr "mode" "QI")])
6819
6820 (define_insn "*addqi_ext_1_rex64"
6821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6822 (const_int 8)
6823 (const_int 8))
6824 (plus:SI
6825 (zero_extract:SI
6826 (match_operand 1 "ext_register_operand" "0")
6827 (const_int 8)
6828 (const_int 8))
6829 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6830 (clobber (reg:CC 17))]
6831 "TARGET_64BIT"
6832 {
6833 switch (get_attr_type (insn))
6834 {
6835 case TYPE_INCDEC:
6836 if (operands[2] == const1_rtx)
6837 return "inc{b}\t%h0";
6838 else if (operands[2] == constm1_rtx
6839 || (GET_CODE (operands[2]) == CONST_INT
6840 && INTVAL (operands[2]) == 255))
6841 return "dec{b}\t%h0";
6842 abort();
6843
6844 default:
6845 return "add{b}\t{%2, %h0|%h0, %2}";
6846 }
6847 }
6848 [(set (attr "type")
6849 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6850 (const_string "incdec")
6851 (const_string "alu")))
6852 (set_attr "mode" "QI")])
6853
6854 (define_insn "*addqi_ext_2"
6855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6856 (const_int 8)
6857 (const_int 8))
6858 (plus:SI
6859 (zero_extract:SI
6860 (match_operand 1 "ext_register_operand" "%0")
6861 (const_int 8)
6862 (const_int 8))
6863 (zero_extract:SI
6864 (match_operand 2 "ext_register_operand" "Q")
6865 (const_int 8)
6866 (const_int 8))))
6867 (clobber (reg:CC 17))]
6868 ""
6869 "add{b}\t{%h2, %h0|%h0, %h2}"
6870 [(set_attr "type" "alu")
6871 (set_attr "mode" "QI")])
6872
6873 ;; The patterns that match these are at the end of this file.
6874
6875 (define_expand "addxf3"
6876 [(set (match_operand:XF 0 "register_operand" "")
6877 (plus:XF (match_operand:XF 1 "register_operand" "")
6878 (match_operand:XF 2 "register_operand" "")))]
6879 "!TARGET_64BIT && TARGET_80387"
6880 "")
6881
6882 (define_expand "addtf3"
6883 [(set (match_operand:TF 0 "register_operand" "")
6884 (plus:TF (match_operand:TF 1 "register_operand" "")
6885 (match_operand:TF 2 "register_operand" "")))]
6886 "TARGET_80387"
6887 "")
6888
6889 (define_expand "adddf3"
6890 [(set (match_operand:DF 0 "register_operand" "")
6891 (plus:DF (match_operand:DF 1 "register_operand" "")
6892 (match_operand:DF 2 "nonimmediate_operand" "")))]
6893 "TARGET_80387 || TARGET_SSE2"
6894 "")
6895
6896 (define_expand "addsf3"
6897 [(set (match_operand:SF 0 "register_operand" "")
6898 (plus:SF (match_operand:SF 1 "register_operand" "")
6899 (match_operand:SF 2 "nonimmediate_operand" "")))]
6900 "TARGET_80387 || TARGET_SSE"
6901 "")
6902 \f
6903 ;; Subtract instructions
6904
6905 ;; %%% splits for subsidi3
6906
6907 (define_expand "subdi3"
6908 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6909 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6910 (match_operand:DI 2 "x86_64_general_operand" "")))
6911 (clobber (reg:CC 17))])]
6912 ""
6913 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6914
6915 (define_insn "*subdi3_1"
6916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6917 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6918 (match_operand:DI 2 "general_operand" "roiF,riF")))
6919 (clobber (reg:CC 17))]
6920 "!TARGET_64BIT"
6921 "#")
6922
6923 (define_split
6924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6925 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6926 (match_operand:DI 2 "general_operand" "")))
6927 (clobber (reg:CC 17))]
6928 "!TARGET_64BIT && reload_completed"
6929 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6930 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6931 (parallel [(set (match_dup 3)
6932 (minus:SI (match_dup 4)
6933 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6934 (match_dup 5))))
6935 (clobber (reg:CC 17))])]
6936 "split_di (operands+0, 1, operands+0, operands+3);
6937 split_di (operands+1, 1, operands+1, operands+4);
6938 split_di (operands+2, 1, operands+2, operands+5);")
6939
6940 (define_insn "subdi3_carry_rex64"
6941 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6942 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6943 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6944 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6945 (clobber (reg:CC 17))]
6946 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6947 "sbb{q}\t{%2, %0|%0, %2}"
6948 [(set_attr "type" "alu")
6949 (set_attr "pent_pair" "pu")
6950 (set_attr "ppro_uops" "few")
6951 (set_attr "mode" "DI")])
6952
6953 (define_insn "*subdi_1_rex64"
6954 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6955 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6956 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6957 (clobber (reg:CC 17))]
6958 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6959 "sub{q}\t{%2, %0|%0, %2}"
6960 [(set_attr "type" "alu")
6961 (set_attr "mode" "DI")])
6962
6963 (define_insn "*subdi_2_rex64"
6964 [(set (reg 17)
6965 (compare
6966 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6967 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6968 (const_int 0)))
6969 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6970 (minus:DI (match_dup 1) (match_dup 2)))]
6971 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6972 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6973 "sub{q}\t{%2, %0|%0, %2}"
6974 [(set_attr "type" "alu")
6975 (set_attr "mode" "DI")])
6976
6977 (define_insn "*subdi_3_rex63"
6978 [(set (reg 17)
6979 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6980 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6981 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6982 (minus:DI (match_dup 1) (match_dup 2)))]
6983 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6984 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6985 "sub{q}\t{%2, %0|%0, %2}"
6986 [(set_attr "type" "alu")
6987 (set_attr "mode" "DI")])
6988
6989
6990 (define_insn "subsi3_carry"
6991 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6992 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6993 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6994 (match_operand:SI 2 "general_operand" "ri,rm"))))
6995 (clobber (reg:CC 17))]
6996 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6997 "sbb{l}\t{%2, %0|%0, %2}"
6998 [(set_attr "type" "alu")
6999 (set_attr "pent_pair" "pu")
7000 (set_attr "ppro_uops" "few")
7001 (set_attr "mode" "SI")])
7002
7003 (define_insn "subsi3_carry_zext"
7004 [(set (match_operand:DI 0 "register_operand" "=rm,r")
7005 (zero_extend:DI
7006 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
7007 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7008 (match_operand:SI 2 "general_operand" "ri,rm")))))
7009 (clobber (reg:CC 17))]
7010 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sbb{l}\t{%2, %k0|%k0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "pent_pair" "pu")
7014 (set_attr "ppro_uops" "few")
7015 (set_attr "mode" "SI")])
7016
7017 (define_expand "subsi3"
7018 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7019 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7020 (match_operand:SI 2 "general_operand" "")))
7021 (clobber (reg:CC 17))])]
7022 ""
7023 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7024
7025 (define_insn "*subsi_1"
7026 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7027 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7028 (match_operand:SI 2 "general_operand" "ri,rm")))
7029 (clobber (reg:CC 17))]
7030 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7031 "sub{l}\t{%2, %0|%0, %2}"
7032 [(set_attr "type" "alu")
7033 (set_attr "mode" "SI")])
7034
7035 (define_insn "*subsi_1_zext"
7036 [(set (match_operand:DI 0 "register_operand" "=r")
7037 (zero_extend:DI
7038 (minus:SI (match_operand:SI 1 "register_operand" "0")
7039 (match_operand:SI 2 "general_operand" "rim"))))
7040 (clobber (reg:CC 17))]
7041 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7042 "sub{l}\t{%2, %k0|%k0, %2}"
7043 [(set_attr "type" "alu")
7044 (set_attr "mode" "SI")])
7045
7046 (define_insn "*subsi_2"
7047 [(set (reg 17)
7048 (compare
7049 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7050 (match_operand:SI 2 "general_operand" "ri,rm"))
7051 (const_int 0)))
7052 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7053 (minus:SI (match_dup 1) (match_dup 2)))]
7054 "ix86_match_ccmode (insn, CCGOCmode)
7055 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7056 "sub{l}\t{%2, %0|%0, %2}"
7057 [(set_attr "type" "alu")
7058 (set_attr "mode" "SI")])
7059
7060 (define_insn "*subsi_2_zext"
7061 [(set (reg 17)
7062 (compare
7063 (minus:SI (match_operand:SI 1 "register_operand" "0")
7064 (match_operand:SI 2 "general_operand" "rim"))
7065 (const_int 0)))
7066 (set (match_operand:DI 0 "register_operand" "=r")
7067 (zero_extend:DI
7068 (minus:SI (match_dup 1)
7069 (match_dup 2))))]
7070 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7071 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7072 "sub{l}\t{%2, %k0|%k0, %2}"
7073 [(set_attr "type" "alu")
7074 (set_attr "mode" "SI")])
7075
7076 (define_insn "*subsi_3"
7077 [(set (reg 17)
7078 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7079 (match_operand:SI 2 "general_operand" "ri,rm")))
7080 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7081 (minus:SI (match_dup 1) (match_dup 2)))]
7082 "ix86_match_ccmode (insn, CCmode)
7083 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7084 "sub{l}\t{%2, %0|%0, %2}"
7085 [(set_attr "type" "alu")
7086 (set_attr "mode" "SI")])
7087
7088 (define_insn "*subsi_3_zext"
7089 [(set (reg 17)
7090 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7091 (match_operand:SI 2 "general_operand" "rim")))
7092 (set (match_operand:DI 0 "register_operand" "=r")
7093 (zero_extend:DI
7094 (minus:SI (match_dup 1)
7095 (match_dup 2))))]
7096 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7097 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7098 "sub{q}\t{%2, %0|%0, %2}"
7099 [(set_attr "type" "alu")
7100 (set_attr "mode" "DI")])
7101
7102 (define_expand "subhi3"
7103 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7104 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7105 (match_operand:HI 2 "general_operand" "")))
7106 (clobber (reg:CC 17))])]
7107 "TARGET_HIMODE_MATH"
7108 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7109
7110 (define_insn "*subhi_1"
7111 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7112 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7113 (match_operand:HI 2 "general_operand" "ri,rm")))
7114 (clobber (reg:CC 17))]
7115 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7116 "sub{w}\t{%2, %0|%0, %2}"
7117 [(set_attr "type" "alu")
7118 (set_attr "mode" "HI")])
7119
7120 (define_insn "*subhi_2"
7121 [(set (reg 17)
7122 (compare
7123 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7124 (match_operand:HI 2 "general_operand" "ri,rm"))
7125 (const_int 0)))
7126 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7127 (minus:HI (match_dup 1) (match_dup 2)))]
7128 "ix86_match_ccmode (insn, CCGOCmode)
7129 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7130 "sub{w}\t{%2, %0|%0, %2}"
7131 [(set_attr "type" "alu")
7132 (set_attr "mode" "HI")])
7133
7134 (define_insn "*subhi_3"
7135 [(set (reg 17)
7136 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:HI 2 "general_operand" "ri,rm")))
7138 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7139 (minus:HI (match_dup 1) (match_dup 2)))]
7140 "ix86_match_ccmode (insn, CCmode)
7141 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7142 "sub{w}\t{%2, %0|%0, %2}"
7143 [(set_attr "type" "alu")
7144 (set_attr "mode" "HI")])
7145
7146 (define_expand "subqi3"
7147 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7148 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7149 (match_operand:QI 2 "general_operand" "")))
7150 (clobber (reg:CC 17))])]
7151 "TARGET_QIMODE_MATH"
7152 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7153
7154 (define_insn "*subqi_1"
7155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7156 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7157 (match_operand:QI 2 "general_operand" "qn,qmn")))
7158 (clobber (reg:CC 17))]
7159 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7160 "sub{b}\t{%2, %0|%0, %2}"
7161 [(set_attr "type" "alu")
7162 (set_attr "mode" "QI")])
7163
7164 (define_insn "*subqi_2"
7165 [(set (reg 17)
7166 (compare
7167 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7168 (match_operand:QI 2 "general_operand" "qi,qm"))
7169 (const_int 0)))
7170 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7171 (minus:HI (match_dup 1) (match_dup 2)))]
7172 "ix86_match_ccmode (insn, CCGOCmode)
7173 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7174 "sub{b}\t{%2, %0|%0, %2}"
7175 [(set_attr "type" "alu")
7176 (set_attr "mode" "QI")])
7177
7178 (define_insn "*subqi_3"
7179 [(set (reg 17)
7180 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7181 (match_operand:QI 2 "general_operand" "qi,qm")))
7182 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7183 (minus:HI (match_dup 1) (match_dup 2)))]
7184 "ix86_match_ccmode (insn, CCmode)
7185 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7186 "sub{b}\t{%2, %0|%0, %2}"
7187 [(set_attr "type" "alu")
7188 (set_attr "mode" "QI")])
7189
7190 ;; The patterns that match these are at the end of this file.
7191
7192 (define_expand "subxf3"
7193 [(set (match_operand:XF 0 "register_operand" "")
7194 (minus:XF (match_operand:XF 1 "register_operand" "")
7195 (match_operand:XF 2 "register_operand" "")))]
7196 "!TARGET_64BIT && TARGET_80387"
7197 "")
7198
7199 (define_expand "subtf3"
7200 [(set (match_operand:TF 0 "register_operand" "")
7201 (minus:TF (match_operand:TF 1 "register_operand" "")
7202 (match_operand:TF 2 "register_operand" "")))]
7203 "TARGET_80387"
7204 "")
7205
7206 (define_expand "subdf3"
7207 [(set (match_operand:DF 0 "register_operand" "")
7208 (minus:DF (match_operand:DF 1 "register_operand" "")
7209 (match_operand:DF 2 "nonimmediate_operand" "")))]
7210 "TARGET_80387 || TARGET_SSE2"
7211 "")
7212
7213 (define_expand "subsf3"
7214 [(set (match_operand:SF 0 "register_operand" "")
7215 (minus:SF (match_operand:SF 1 "register_operand" "")
7216 (match_operand:SF 2 "nonimmediate_operand" "")))]
7217 "TARGET_80387 || TARGET_SSE"
7218 "")
7219 \f
7220 ;; Multiply instructions
7221
7222 (define_expand "muldi3"
7223 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7224 (mult:DI (match_operand:DI 1 "register_operand" "")
7225 (match_operand:DI 2 "x86_64_general_operand" "")))
7226 (clobber (reg:CC 17))])]
7227 "TARGET_64BIT"
7228 "")
7229
7230 (define_insn "*muldi3_1_rex64"
7231 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7232 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7233 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7234 (clobber (reg:CC 17))]
7235 "TARGET_64BIT
7236 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7237 "@
7238 imul{q}\t{%2, %1, %0|%0, %1, %2}
7239 imul{q}\t{%2, %1, %0|%0, %1, %2}
7240 imul{q}\t{%2, %0|%0, %2}"
7241 [(set_attr "type" "imul")
7242 (set_attr "prefix_0f" "0,0,1")
7243 (set_attr "mode" "DI")])
7244
7245 (define_expand "mulsi3"
7246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:SI (match_operand:SI 1 "register_operand" "")
7248 (match_operand:SI 2 "general_operand" "")))
7249 (clobber (reg:CC 17))])]
7250 ""
7251 "")
7252
7253 (define_insn "*mulsi3_1"
7254 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7256 (match_operand:SI 2 "general_operand" "K,i,mr")))
7257 (clobber (reg:CC 17))]
7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7259 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7260 ; there are two ways of writing the exact same machine instruction
7261 ; in assembly language. One, for example, is:
7262 ;
7263 ; imul $12, %eax
7264 ;
7265 ; while the other is:
7266 ;
7267 ; imul $12, %eax, %eax
7268 ;
7269 ; The first is simply short-hand for the latter. But, some assemblers,
7270 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7271 "@
7272 imul{l}\t{%2, %1, %0|%0, %1, %2}
7273 imul{l}\t{%2, %1, %0|%0, %1, %2}
7274 imul{l}\t{%2, %0|%0, %2}"
7275 [(set_attr "type" "imul")
7276 (set_attr "prefix_0f" "0,0,1")
7277 (set_attr "mode" "SI")])
7278
7279 (define_insn "*mulsi3_1_zext"
7280 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7281 (zero_extend:DI
7282 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7283 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7284 (clobber (reg:CC 17))]
7285 "TARGET_64BIT
7286 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7288 ; there are two ways of writing the exact same machine instruction
7289 ; in assembly language. One, for example, is:
7290 ;
7291 ; imul $12, %eax
7292 ;
7293 ; while the other is:
7294 ;
7295 ; imul $12, %eax, %eax
7296 ;
7297 ; The first is simply short-hand for the latter. But, some assemblers,
7298 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7299 "@
7300 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7301 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7302 imul{l}\t{%2, %k0|%k0, %2}"
7303 [(set_attr "type" "imul")
7304 (set_attr "prefix_0f" "0,0,1")
7305 (set_attr "mode" "SI")])
7306
7307 (define_expand "mulhi3"
7308 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7309 (mult:HI (match_operand:HI 1 "register_operand" "")
7310 (match_operand:HI 2 "general_operand" "")))
7311 (clobber (reg:CC 17))])]
7312 "TARGET_HIMODE_MATH"
7313 "")
7314
7315 (define_insn "*mulhi3_1"
7316 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7317 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7318 (match_operand:HI 2 "general_operand" "K,i,mr")))
7319 (clobber (reg:CC 17))]
7320 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7321 ; %%% There was a note about "Assembler has weird restrictions",
7322 ; concerning alternative 1 when op1 == op0. True?
7323 "@
7324 imul{w}\t{%2, %1, %0|%0, %1, %2}
7325 imul{w}\t{%2, %1, %0|%0, %1, %2}
7326 imul{w}\t{%2, %0|%0, %2}"
7327 [(set_attr "type" "imul")
7328 (set_attr "prefix_0f" "0,0,1")
7329 (set_attr "mode" "HI")])
7330
7331 (define_insn "mulqi3"
7332 [(set (match_operand:QI 0 "register_operand" "=a")
7333 (mult:QI (match_operand:QI 1 "register_operand" "%0")
7334 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7335 (clobber (reg:CC 17))]
7336 "TARGET_QIMODE_MATH"
7337 "mul{b}\t%2"
7338 [(set_attr "type" "imul")
7339 (set_attr "length_immediate" "0")
7340 (set_attr "mode" "QI")])
7341
7342 (define_insn "umulqihi3"
7343 [(set (match_operand:HI 0 "register_operand" "=a")
7344 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7345 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7346 (clobber (reg:CC 17))]
7347 "TARGET_QIMODE_MATH"
7348 "mul{b}\t%2"
7349 [(set_attr "type" "imul")
7350 (set_attr "length_immediate" "0")
7351 (set_attr "mode" "QI")])
7352
7353 (define_insn "mulqihi3"
7354 [(set (match_operand:HI 0 "register_operand" "=a")
7355 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7356 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7357 (clobber (reg:CC 17))]
7358 "TARGET_QIMODE_MATH"
7359 "imul{b}\t%2"
7360 [(set_attr "type" "imul")
7361 (set_attr "length_immediate" "0")
7362 (set_attr "mode" "QI")])
7363
7364 (define_insn "umulditi3"
7365 [(set (match_operand:TI 0 "register_operand" "=A")
7366 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7367 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7368 (clobber (reg:CC 17))]
7369 "TARGET_64BIT"
7370 "mul{q}\t%2"
7371 [(set_attr "type" "imul")
7372 (set_attr "ppro_uops" "few")
7373 (set_attr "length_immediate" "0")
7374 (set_attr "mode" "DI")])
7375
7376 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7377 (define_insn "umulsidi3"
7378 [(set (match_operand:DI 0 "register_operand" "=A")
7379 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7380 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7381 (clobber (reg:CC 17))]
7382 "!TARGET_64BIT"
7383 "mul{l}\t%2"
7384 [(set_attr "type" "imul")
7385 (set_attr "ppro_uops" "few")
7386 (set_attr "length_immediate" "0")
7387 (set_attr "mode" "SI")])
7388
7389 (define_insn "mulditi3"
7390 [(set (match_operand:TI 0 "register_operand" "=A")
7391 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7392 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7393 (clobber (reg:CC 17))]
7394 "TARGET_64BIT"
7395 "imul{q}\t%2"
7396 [(set_attr "type" "imul")
7397 (set_attr "length_immediate" "0")
7398 (set_attr "mode" "DI")])
7399
7400 (define_insn "mulsidi3"
7401 [(set (match_operand:DI 0 "register_operand" "=A")
7402 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7403 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7404 (clobber (reg:CC 17))]
7405 "!TARGET_64BIT"
7406 "imul{l}\t%2"
7407 [(set_attr "type" "imul")
7408 (set_attr "length_immediate" "0")
7409 (set_attr "mode" "SI")])
7410
7411 (define_insn "*umuldi3_highpart_rex64"
7412 [(set (match_operand:DI 0 "register_operand" "=d")
7413 (truncate:DI
7414 (lshiftrt:TI
7415 (mult:TI (zero_extend:TI
7416 (match_operand:DI 1 "register_operand" "%a"))
7417 (zero_extend:TI
7418 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7419 (const_int 64))))
7420 (clobber (match_scratch:DI 3 "=a"))
7421 (clobber (reg:CC 17))]
7422 "TARGET_64BIT"
7423 "mul{q}\t%2"
7424 [(set_attr "type" "imul")
7425 (set_attr "ppro_uops" "few")
7426 (set_attr "length_immediate" "0")
7427 (set_attr "mode" "DI")])
7428
7429 (define_insn "umulsi3_highpart"
7430 [(set (match_operand:SI 0 "register_operand" "=d")
7431 (truncate:SI
7432 (lshiftrt:DI
7433 (mult:DI (zero_extend:DI
7434 (match_operand:SI 1 "register_operand" "%a"))
7435 (zero_extend:DI
7436 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7437 (const_int 32))))
7438 (clobber (match_scratch:SI 3 "=a"))
7439 (clobber (reg:CC 17))]
7440 ""
7441 "mul{l}\t%2"
7442 [(set_attr "type" "imul")
7443 (set_attr "ppro_uops" "few")
7444 (set_attr "length_immediate" "0")
7445 (set_attr "mode" "SI")])
7446
7447 (define_insn "*umulsi3_highpart_zext"
7448 [(set (match_operand:DI 0 "register_operand" "=d")
7449 (zero_extend:DI (truncate:SI
7450 (lshiftrt:DI
7451 (mult:DI (zero_extend:DI
7452 (match_operand:SI 1 "register_operand" "%a"))
7453 (zero_extend:DI
7454 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7455 (const_int 32)))))
7456 (clobber (match_scratch:SI 3 "=a"))
7457 (clobber (reg:CC 17))]
7458 "TARGET_64BIT"
7459 "mul{l}\t%2"
7460 [(set_attr "type" "imul")
7461 (set_attr "ppro_uops" "few")
7462 (set_attr "length_immediate" "0")
7463 (set_attr "mode" "SI")])
7464
7465 (define_insn "*smuldi3_highpart_rex64"
7466 [(set (match_operand:DI 0 "register_operand" "=d")
7467 (truncate:DI
7468 (lshiftrt:TI
7469 (mult:TI (sign_extend:TI
7470 (match_operand:DI 1 "register_operand" "%a"))
7471 (sign_extend:TI
7472 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473 (const_int 64))))
7474 (clobber (match_scratch:DI 3 "=a"))
7475 (clobber (reg:CC 17))]
7476 "TARGET_64BIT"
7477 "imul{q}\t%2"
7478 [(set_attr "type" "imul")
7479 (set_attr "ppro_uops" "few")
7480 (set_attr "mode" "DI")])
7481
7482 (define_insn "smulsi3_highpart"
7483 [(set (match_operand:SI 0 "register_operand" "=d")
7484 (truncate:SI
7485 (lshiftrt:DI
7486 (mult:DI (sign_extend:DI
7487 (match_operand:SI 1 "register_operand" "%a"))
7488 (sign_extend:DI
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (const_int 32))))
7491 (clobber (match_scratch:SI 3 "=a"))
7492 (clobber (reg:CC 17))]
7493 ""
7494 "imul{l}\t%2"
7495 [(set_attr "type" "imul")
7496 (set_attr "ppro_uops" "few")
7497 (set_attr "mode" "SI")])
7498
7499 (define_insn "*smulsi3_highpart_zext"
7500 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (zero_extend:DI (truncate:SI
7502 (lshiftrt:DI
7503 (mult:DI (sign_extend:DI
7504 (match_operand:SI 1 "register_operand" "%a"))
7505 (sign_extend:DI
7506 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7507 (const_int 32)))))
7508 (clobber (match_scratch:SI 3 "=a"))
7509 (clobber (reg:CC 17))]
7510 "TARGET_64BIT"
7511 "imul{l}\t%2"
7512 [(set_attr "type" "imul")
7513 (set_attr "ppro_uops" "few")
7514 (set_attr "mode" "SI")])
7515
7516 ;; The patterns that match these are at the end of this file.
7517
7518 (define_expand "mulxf3"
7519 [(set (match_operand:XF 0 "register_operand" "")
7520 (mult:XF (match_operand:XF 1 "register_operand" "")
7521 (match_operand:XF 2 "register_operand" "")))]
7522 "!TARGET_64BIT && TARGET_80387"
7523 "")
7524
7525 (define_expand "multf3"
7526 [(set (match_operand:TF 0 "register_operand" "")
7527 (mult:TF (match_operand:TF 1 "register_operand" "")
7528 (match_operand:TF 2 "register_operand" "")))]
7529 "TARGET_80387"
7530 "")
7531
7532 (define_expand "muldf3"
7533 [(set (match_operand:DF 0 "register_operand" "")
7534 (mult:DF (match_operand:DF 1 "register_operand" "")
7535 (match_operand:DF 2 "nonimmediate_operand" "")))]
7536 "TARGET_80387 || TARGET_SSE2"
7537 "")
7538
7539 (define_expand "mulsf3"
7540 [(set (match_operand:SF 0 "register_operand" "")
7541 (mult:SF (match_operand:SF 1 "register_operand" "")
7542 (match_operand:SF 2 "nonimmediate_operand" "")))]
7543 "TARGET_80387 || TARGET_SSE"
7544 "")
7545 \f
7546 ;; Divide instructions
7547
7548 (define_insn "divqi3"
7549 [(set (match_operand:QI 0 "register_operand" "=a")
7550 (div:QI (match_operand:HI 1 "register_operand" "0")
7551 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7552 (clobber (reg:CC 17))]
7553 "TARGET_QIMODE_MATH"
7554 "idiv{b}\t%2"
7555 [(set_attr "type" "idiv")
7556 (set_attr "mode" "QI")
7557 (set_attr "ppro_uops" "few")])
7558
7559 (define_insn "udivqi3"
7560 [(set (match_operand:QI 0 "register_operand" "=a")
7561 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7562 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7563 (clobber (reg:CC 17))]
7564 "TARGET_QIMODE_MATH"
7565 "div{b}\t%2"
7566 [(set_attr "type" "idiv")
7567 (set_attr "mode" "QI")
7568 (set_attr "ppro_uops" "few")])
7569
7570 ;; The patterns that match these are at the end of this file.
7571
7572 (define_expand "divxf3"
7573 [(set (match_operand:XF 0 "register_operand" "")
7574 (div:XF (match_operand:XF 1 "register_operand" "")
7575 (match_operand:XF 2 "register_operand" "")))]
7576 "!TARGET_64BIT && TARGET_80387"
7577 "")
7578
7579 (define_expand "divtf3"
7580 [(set (match_operand:TF 0 "register_operand" "")
7581 (div:TF (match_operand:TF 1 "register_operand" "")
7582 (match_operand:TF 2 "register_operand" "")))]
7583 "TARGET_80387"
7584 "")
7585
7586 (define_expand "divdf3"
7587 [(set (match_operand:DF 0 "register_operand" "")
7588 (div:DF (match_operand:DF 1 "register_operand" "")
7589 (match_operand:DF 2 "nonimmediate_operand" "")))]
7590 "TARGET_80387 || TARGET_SSE2"
7591 "")
7592
7593 (define_expand "divsf3"
7594 [(set (match_operand:SF 0 "register_operand" "")
7595 (div:SF (match_operand:SF 1 "register_operand" "")
7596 (match_operand:SF 2 "nonimmediate_operand" "")))]
7597 "TARGET_80387 || TARGET_SSE"
7598 "")
7599 \f
7600 ;; Remainder instructions.
7601
7602 (define_expand "divmoddi4"
7603 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7604 (div:DI (match_operand:DI 1 "register_operand" "")
7605 (match_operand:DI 2 "nonimmediate_operand" "")))
7606 (set (match_operand:DI 3 "register_operand" "")
7607 (mod:DI (match_dup 1) (match_dup 2)))
7608 (clobber (reg:CC 17))])]
7609 "TARGET_64BIT"
7610 "")
7611
7612 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7613 ;; Penalize eax case sligthly because it results in worse scheduling
7614 ;; of code.
7615 (define_insn "*divmoddi4_nocltd_rex64"
7616 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7617 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7618 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7619 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7620 (mod:DI (match_dup 2) (match_dup 3)))
7621 (clobber (reg:CC 17))]
7622 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7623 "#"
7624 [(set_attr "type" "multi")])
7625
7626 (define_insn "*divmoddi4_cltd_rex64"
7627 [(set (match_operand:DI 0 "register_operand" "=a")
7628 (div:DI (match_operand:DI 2 "register_operand" "a")
7629 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7630 (set (match_operand:DI 1 "register_operand" "=&d")
7631 (mod:DI (match_dup 2) (match_dup 3)))
7632 (clobber (reg:CC 17))]
7633 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7634 "#"
7635 [(set_attr "type" "multi")])
7636
7637 (define_insn "*divmoddi_noext_rex64"
7638 [(set (match_operand:DI 0 "register_operand" "=a")
7639 (div:DI (match_operand:DI 1 "register_operand" "0")
7640 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7641 (set (match_operand:DI 3 "register_operand" "=d")
7642 (mod:DI (match_dup 1) (match_dup 2)))
7643 (use (match_operand:DI 4 "register_operand" "3"))
7644 (clobber (reg:CC 17))]
7645 "TARGET_64BIT"
7646 "idiv{q}\t%2"
7647 [(set_attr "type" "idiv")
7648 (set_attr "mode" "DI")
7649 (set_attr "ppro_uops" "few")])
7650
7651 (define_split
7652 [(set (match_operand:DI 0 "register_operand" "")
7653 (div:DI (match_operand:DI 1 "register_operand" "")
7654 (match_operand:DI 2 "nonimmediate_operand" "")))
7655 (set (match_operand:DI 3 "register_operand" "")
7656 (mod:DI (match_dup 1) (match_dup 2)))
7657 (clobber (reg:CC 17))]
7658 "TARGET_64BIT && reload_completed"
7659 [(parallel [(set (match_dup 3)
7660 (ashiftrt:DI (match_dup 4) (const_int 63)))
7661 (clobber (reg:CC 17))])
7662 (parallel [(set (match_dup 0)
7663 (div:DI (reg:DI 0) (match_dup 2)))
7664 (set (match_dup 3)
7665 (mod:DI (reg:DI 0) (match_dup 2)))
7666 (use (match_dup 3))
7667 (clobber (reg:CC 17))])]
7668 {
7669 /* Avoid use of cltd in favour of a mov+shift. */
7670 if (!TARGET_USE_CLTD && !optimize_size)
7671 {
7672 if (true_regnum (operands[1]))
7673 emit_move_insn (operands[0], operands[1]);
7674 else
7675 emit_move_insn (operands[3], operands[1]);
7676 operands[4] = operands[3];
7677 }
7678 else
7679 {
7680 if (true_regnum (operands[1]))
7681 abort();
7682 operands[4] = operands[1];
7683 }
7684 })
7685
7686
7687 (define_expand "divmodsi4"
7688 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7689 (div:SI (match_operand:SI 1 "register_operand" "")
7690 (match_operand:SI 2 "nonimmediate_operand" "")))
7691 (set (match_operand:SI 3 "register_operand" "")
7692 (mod:SI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC 17))])]
7694 ""
7695 "")
7696
7697 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7698 ;; Penalize eax case sligthly because it results in worse scheduling
7699 ;; of code.
7700 (define_insn "*divmodsi4_nocltd"
7701 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7702 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7703 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7704 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7705 (mod:SI (match_dup 2) (match_dup 3)))
7706 (clobber (reg:CC 17))]
7707 "!optimize_size && !TARGET_USE_CLTD"
7708 "#"
7709 [(set_attr "type" "multi")])
7710
7711 (define_insn "*divmodsi4_cltd"
7712 [(set (match_operand:SI 0 "register_operand" "=a")
7713 (div:SI (match_operand:SI 2 "register_operand" "a")
7714 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7715 (set (match_operand:SI 1 "register_operand" "=&d")
7716 (mod:SI (match_dup 2) (match_dup 3)))
7717 (clobber (reg:CC 17))]
7718 "optimize_size || TARGET_USE_CLTD"
7719 "#"
7720 [(set_attr "type" "multi")])
7721
7722 (define_insn "*divmodsi_noext"
7723 [(set (match_operand:SI 0 "register_operand" "=a")
7724 (div:SI (match_operand:SI 1 "register_operand" "0")
7725 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7726 (set (match_operand:SI 3 "register_operand" "=d")
7727 (mod:SI (match_dup 1) (match_dup 2)))
7728 (use (match_operand:SI 4 "register_operand" "3"))
7729 (clobber (reg:CC 17))]
7730 ""
7731 "idiv{l}\t%2"
7732 [(set_attr "type" "idiv")
7733 (set_attr "mode" "SI")
7734 (set_attr "ppro_uops" "few")])
7735
7736 (define_split
7737 [(set (match_operand:SI 0 "register_operand" "")
7738 (div:SI (match_operand:SI 1 "register_operand" "")
7739 (match_operand:SI 2 "nonimmediate_operand" "")))
7740 (set (match_operand:SI 3 "register_operand" "")
7741 (mod:SI (match_dup 1) (match_dup 2)))
7742 (clobber (reg:CC 17))]
7743 "reload_completed"
7744 [(parallel [(set (match_dup 3)
7745 (ashiftrt:SI (match_dup 4) (const_int 31)))
7746 (clobber (reg:CC 17))])
7747 (parallel [(set (match_dup 0)
7748 (div:SI (reg:SI 0) (match_dup 2)))
7749 (set (match_dup 3)
7750 (mod:SI (reg:SI 0) (match_dup 2)))
7751 (use (match_dup 3))
7752 (clobber (reg:CC 17))])]
7753 {
7754 /* Avoid use of cltd in favour of a mov+shift. */
7755 if (!TARGET_USE_CLTD && !optimize_size)
7756 {
7757 if (true_regnum (operands[1]))
7758 emit_move_insn (operands[0], operands[1]);
7759 else
7760 emit_move_insn (operands[3], operands[1]);
7761 operands[4] = operands[3];
7762 }
7763 else
7764 {
7765 if (true_regnum (operands[1]))
7766 abort();
7767 operands[4] = operands[1];
7768 }
7769 })
7770 ;; %%% Split me.
7771 (define_insn "divmodhi4"
7772 [(set (match_operand:HI 0 "register_operand" "=a")
7773 (div:HI (match_operand:HI 1 "register_operand" "0")
7774 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7775 (set (match_operand:HI 3 "register_operand" "=&d")
7776 (mod:HI (match_dup 1) (match_dup 2)))
7777 (clobber (reg:CC 17))]
7778 "TARGET_HIMODE_MATH"
7779 "cwtd\;idiv{w}\t%2"
7780 [(set_attr "type" "multi")
7781 (set_attr "length_immediate" "0")
7782 (set_attr "mode" "SI")])
7783
7784 (define_insn "udivmoddi4"
7785 [(set (match_operand:DI 0 "register_operand" "=a")
7786 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7787 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7788 (set (match_operand:DI 3 "register_operand" "=&d")
7789 (umod:DI (match_dup 1) (match_dup 2)))
7790 (clobber (reg:CC 17))]
7791 "TARGET_64BIT"
7792 "xor{q}\t%3, %3\;div{q}\t%2"
7793 [(set_attr "type" "multi")
7794 (set_attr "length_immediate" "0")
7795 (set_attr "mode" "DI")])
7796
7797 (define_insn "*udivmoddi4_noext"
7798 [(set (match_operand:DI 0 "register_operand" "=a")
7799 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7800 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7801 (set (match_operand:DI 3 "register_operand" "=d")
7802 (umod:DI (match_dup 1) (match_dup 2)))
7803 (use (match_dup 3))
7804 (clobber (reg:CC 17))]
7805 "TARGET_64BIT"
7806 "div{q}\t%2"
7807 [(set_attr "type" "idiv")
7808 (set_attr "ppro_uops" "few")
7809 (set_attr "mode" "DI")])
7810
7811 (define_split
7812 [(set (match_operand:DI 0 "register_operand" "")
7813 (udiv:DI (match_operand:DI 1 "register_operand" "")
7814 (match_operand:DI 2 "nonimmediate_operand" "")))
7815 (set (match_operand:DI 3 "register_operand" "")
7816 (umod:DI (match_dup 1) (match_dup 2)))
7817 (clobber (reg:CC 17))]
7818 "TARGET_64BIT && reload_completed"
7819 [(set (match_dup 3) (const_int 0))
7820 (parallel [(set (match_dup 0)
7821 (udiv:DI (match_dup 1) (match_dup 2)))
7822 (set (match_dup 3)
7823 (umod:DI (match_dup 1) (match_dup 2)))
7824 (use (match_dup 3))
7825 (clobber (reg:CC 17))])]
7826 "")
7827
7828 (define_insn "udivmodsi4"
7829 [(set (match_operand:SI 0 "register_operand" "=a")
7830 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7831 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7832 (set (match_operand:SI 3 "register_operand" "=&d")
7833 (umod:SI (match_dup 1) (match_dup 2)))
7834 (clobber (reg:CC 17))]
7835 ""
7836 "xor{l}\t%3, %3\;div{l}\t%2"
7837 [(set_attr "type" "multi")
7838 (set_attr "length_immediate" "0")
7839 (set_attr "mode" "SI")])
7840
7841 (define_insn "*udivmodsi4_noext"
7842 [(set (match_operand:SI 0 "register_operand" "=a")
7843 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7844 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7845 (set (match_operand:SI 3 "register_operand" "=d")
7846 (umod:SI (match_dup 1) (match_dup 2)))
7847 (use (match_dup 3))
7848 (clobber (reg:CC 17))]
7849 ""
7850 "div{l}\t%2"
7851 [(set_attr "type" "idiv")
7852 (set_attr "ppro_uops" "few")
7853 (set_attr "mode" "SI")])
7854
7855 (define_split
7856 [(set (match_operand:SI 0 "register_operand" "")
7857 (udiv:SI (match_operand:SI 1 "register_operand" "")
7858 (match_operand:SI 2 "nonimmediate_operand" "")))
7859 (set (match_operand:SI 3 "register_operand" "")
7860 (umod:SI (match_dup 1) (match_dup 2)))
7861 (clobber (reg:CC 17))]
7862 "reload_completed"
7863 [(set (match_dup 3) (const_int 0))
7864 (parallel [(set (match_dup 0)
7865 (udiv:SI (match_dup 1) (match_dup 2)))
7866 (set (match_dup 3)
7867 (umod:SI (match_dup 1) (match_dup 2)))
7868 (use (match_dup 3))
7869 (clobber (reg:CC 17))])]
7870 "")
7871
7872 (define_expand "udivmodhi4"
7873 [(set (match_dup 4) (const_int 0))
7874 (parallel [(set (match_operand:HI 0 "register_operand" "")
7875 (udiv:HI (match_operand:HI 1 "register_operand" "")
7876 (match_operand:HI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:HI 3 "register_operand" "")
7878 (umod:HI (match_dup 1) (match_dup 2)))
7879 (use (match_dup 4))
7880 (clobber (reg:CC 17))])]
7881 "TARGET_HIMODE_MATH"
7882 "operands[4] = gen_reg_rtx (HImode);")
7883
7884 (define_insn "*udivmodhi_noext"
7885 [(set (match_operand:HI 0 "register_operand" "=a")
7886 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7887 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7888 (set (match_operand:HI 3 "register_operand" "=d")
7889 (umod:HI (match_dup 1) (match_dup 2)))
7890 (use (match_operand:HI 4 "register_operand" "3"))
7891 (clobber (reg:CC 17))]
7892 ""
7893 "div{w}\t%2"
7894 [(set_attr "type" "idiv")
7895 (set_attr "mode" "HI")
7896 (set_attr "ppro_uops" "few")])
7897
7898 ;; We can not use div/idiv for double division, because it causes
7899 ;; "division by zero" on the overflow and that's not what we expect
7900 ;; from truncate. Because true (non truncating) double division is
7901 ;; never generated, we can't create this insn anyway.
7902 ;
7903 ;(define_insn ""
7904 ; [(set (match_operand:SI 0 "register_operand" "=a")
7905 ; (truncate:SI
7906 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7907 ; (zero_extend:DI
7908 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7909 ; (set (match_operand:SI 3 "register_operand" "=d")
7910 ; (truncate:SI
7911 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7912 ; (clobber (reg:CC 17))]
7913 ; ""
7914 ; "div{l}\t{%2, %0|%0, %2}"
7915 ; [(set_attr "type" "idiv")
7916 ; (set_attr "ppro_uops" "few")])
7917 \f
7918 ;;- Logical AND instructions
7919
7920 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7921 ;; Note that this excludes ah.
7922
7923 (define_insn "*testdi_1_rex64"
7924 [(set (reg 17)
7925 (compare
7926 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7927 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7928 (const_int 0)))]
7929 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7930 "@
7931 test{l}\t{%k1, %k0|%k0, %k1}
7932 test{l}\t{%k1, %k0|%k0, %k1}
7933 test{q}\t{%1, %0|%0, %1}
7934 test{q}\t{%1, %0|%0, %1}
7935 test{q}\t{%1, %0|%0, %1}"
7936 [(set_attr "type" "test")
7937 (set_attr "modrm" "0,1,0,1,1")
7938 (set_attr "mode" "SI,SI,DI,DI,DI")
7939 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7940
7941 (define_insn "testsi_1"
7942 [(set (reg 17)
7943 (compare
7944 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7945 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7946 (const_int 0)))]
7947 "ix86_match_ccmode (insn, CCNOmode)"
7948 "test{l}\t{%1, %0|%0, %1}"
7949 [(set_attr "type" "test")
7950 (set_attr "modrm" "0,1,1")
7951 (set_attr "mode" "SI")
7952 (set_attr "pent_pair" "uv,np,uv")])
7953
7954 (define_expand "testsi_ccno_1"
7955 [(set (reg:CCNO 17)
7956 (compare:CCNO
7957 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7958 (match_operand:SI 1 "nonmemory_operand" ""))
7959 (const_int 0)))]
7960 ""
7961 "")
7962
7963 (define_insn "*testhi_1"
7964 [(set (reg 17)
7965 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7966 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7967 (const_int 0)))]
7968 "ix86_match_ccmode (insn, CCNOmode)"
7969 "test{w}\t{%1, %0|%0, %1}"
7970 [(set_attr "type" "test")
7971 (set_attr "modrm" "0,1,1")
7972 (set_attr "mode" "HI")
7973 (set_attr "pent_pair" "uv,np,uv")])
7974
7975 (define_expand "testqi_ccz_1"
7976 [(set (reg:CCZ 17)
7977 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7978 (match_operand:QI 1 "nonmemory_operand" ""))
7979 (const_int 0)))]
7980 ""
7981 "")
7982
7983 (define_insn "*testqi_1"
7984 [(set (reg 17)
7985 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7986 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7987 (const_int 0)))]
7988 "ix86_match_ccmode (insn, CCNOmode)"
7989 {
7990 if (which_alternative == 3)
7991 {
7992 if (GET_CODE (operands[1]) == CONST_INT
7993 && (INTVAL (operands[1]) & 0xffffff00))
7994 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7995 return "test{l}\t{%1, %k0|%k0, %1}";
7996 }
7997 return "test{b}\t{%1, %0|%0, %1}";
7998 }
7999 [(set_attr "type" "test")
8000 (set_attr "modrm" "0,1,1,1")
8001 (set_attr "mode" "QI,QI,QI,SI")
8002 (set_attr "pent_pair" "uv,np,uv,np")])
8003
8004 (define_expand "testqi_ext_ccno_0"
8005 [(set (reg:CCNO 17)
8006 (compare:CCNO
8007 (and:SI
8008 (zero_extract:SI
8009 (match_operand 0 "ext_register_operand" "")
8010 (const_int 8)
8011 (const_int 8))
8012 (match_operand 1 "const_int_operand" ""))
8013 (const_int 0)))]
8014 ""
8015 "")
8016
8017 (define_insn "*testqi_ext_0"
8018 [(set (reg 17)
8019 (compare
8020 (and:SI
8021 (zero_extract:SI
8022 (match_operand 0 "ext_register_operand" "Q")
8023 (const_int 8)
8024 (const_int 8))
8025 (match_operand 1 "const_int_operand" "n"))
8026 (const_int 0)))]
8027 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
8028 && ix86_match_ccmode (insn, CCNOmode)"
8029 "test{b}\t{%1, %h0|%h0, %1}"
8030 [(set_attr "type" "test")
8031 (set_attr "mode" "QI")
8032 (set_attr "length_immediate" "1")
8033 (set_attr "pent_pair" "np")])
8034
8035 (define_insn "*testqi_ext_1"
8036 [(set (reg 17)
8037 (compare
8038 (and:SI
8039 (zero_extract:SI
8040 (match_operand 0 "ext_register_operand" "Q")
8041 (const_int 8)
8042 (const_int 8))
8043 (zero_extend:SI
8044 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8045 (const_int 0)))]
8046 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8047 "test{b}\t{%1, %h0|%h0, %1}"
8048 [(set_attr "type" "test")
8049 (set_attr "mode" "QI")])
8050
8051 (define_insn "*testqi_ext_1_rex64"
8052 [(set (reg 17)
8053 (compare
8054 (and:SI
8055 (zero_extract:SI
8056 (match_operand 0 "ext_register_operand" "Q")
8057 (const_int 8)
8058 (const_int 8))
8059 (zero_extend:SI
8060 (match_operand:QI 1 "register_operand" "Q")))
8061 (const_int 0)))]
8062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8063 "test{b}\t{%1, %h0|%h0, %1}"
8064 [(set_attr "type" "test")
8065 (set_attr "mode" "QI")])
8066
8067 (define_insn "*testqi_ext_2"
8068 [(set (reg 17)
8069 (compare
8070 (and:SI
8071 (zero_extract:SI
8072 (match_operand 0 "ext_register_operand" "Q")
8073 (const_int 8)
8074 (const_int 8))
8075 (zero_extract:SI
8076 (match_operand 1 "ext_register_operand" "Q")
8077 (const_int 8)
8078 (const_int 8)))
8079 (const_int 0)))]
8080 "ix86_match_ccmode (insn, CCNOmode)"
8081 "test{b}\t{%h1, %h0|%h0, %h1}"
8082 [(set_attr "type" "test")
8083 (set_attr "mode" "QI")])
8084
8085 ;; Combine likes to form bit extractions for some tests. Humor it.
8086 (define_insn "*testqi_ext_3"
8087 [(set (reg 17)
8088 (compare (zero_extract:SI
8089 (match_operand 0 "nonimmediate_operand" "rm")
8090 (match_operand:SI 1 "const_int_operand" "")
8091 (match_operand:SI 2 "const_int_operand" ""))
8092 (const_int 0)))]
8093 "ix86_match_ccmode (insn, CCNOmode)
8094 && (GET_MODE (operands[0]) == SImode
8095 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8096 || GET_MODE (operands[0]) == HImode
8097 || GET_MODE (operands[0]) == QImode)"
8098 "#")
8099
8100 (define_insn "*testqi_ext_3_rex64"
8101 [(set (reg 17)
8102 (compare (zero_extract:DI
8103 (match_operand 0 "nonimmediate_operand" "rm")
8104 (match_operand:DI 1 "const_int_operand" "")
8105 (match_operand:DI 2 "const_int_operand" ""))
8106 (const_int 0)))]
8107 "TARGET_64BIT
8108 && ix86_match_ccmode (insn, CCNOmode)
8109 && (GET_MODE (operands[0]) == SImode
8110 || GET_MODE (operands[0]) == DImode
8111 || GET_MODE (operands[0]) == HImode
8112 || GET_MODE (operands[0]) == QImode)"
8113 "#")
8114
8115 (define_split
8116 [(set (reg 17)
8117 (compare (zero_extract
8118 (match_operand 0 "nonimmediate_operand" "")
8119 (match_operand 1 "const_int_operand" "")
8120 (match_operand 2 "const_int_operand" ""))
8121 (const_int 0)))]
8122 "ix86_match_ccmode (insn, CCNOmode)"
8123 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8124 {
8125 HOST_WIDE_INT len = INTVAL (operands[1]);
8126 HOST_WIDE_INT pos = INTVAL (operands[2]);
8127 HOST_WIDE_INT mask;
8128 enum machine_mode mode;
8129
8130 mode = GET_MODE (operands[0]);
8131 if (GET_CODE (operands[0]) == MEM)
8132 {
8133 /* ??? Combine likes to put non-volatile mem extractions in QImode
8134 no matter the size of the test. So find a mode that works. */
8135 if (! MEM_VOLATILE_P (operands[0]))
8136 {
8137 mode = smallest_mode_for_size (pos + len, MODE_INT);
8138 operands[0] = adjust_address (operands[0], mode, 0);
8139 }
8140 }
8141 else if (mode == HImode && pos + len <= 8)
8142 {
8143 /* Small HImode tests can be converted to QImode. */
8144 mode = QImode;
8145 operands[0] = gen_lowpart (QImode, operands[0]);
8146 }
8147
8148 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8149 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8150
8151 operands[3] = gen_rtx_AND (mode, operands[0],
8152 GEN_INT (trunc_int_for_mode (mask, mode)));
8153 })
8154
8155 ;; %%% This used to optimize known byte-wide and operations to memory,
8156 ;; and sometimes to QImode registers. If this is considered useful,
8157 ;; it should be done with splitters.
8158
8159 (define_expand "anddi3"
8160 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8161 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8162 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8163 (clobber (reg:CC 17))]
8164 "TARGET_64BIT"
8165 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8166
8167 (define_insn "*anddi_1_rex64"
8168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8169 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8170 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8171 (clobber (reg:CC 17))]
8172 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8173 {
8174 switch (get_attr_type (insn))
8175 {
8176 case TYPE_IMOVX:
8177 {
8178 enum machine_mode mode;
8179
8180 if (GET_CODE (operands[2]) != CONST_INT)
8181 abort ();
8182 if (INTVAL (operands[2]) == 0xff)
8183 mode = QImode;
8184 else if (INTVAL (operands[2]) == 0xffff)
8185 mode = HImode;
8186 else
8187 abort ();
8188
8189 operands[1] = gen_lowpart (mode, operands[1]);
8190 if (mode == QImode)
8191 return "movz{bq|x}\t{%1,%0|%0, %1}";
8192 else
8193 return "movz{wq|x}\t{%1,%0|%0, %1}";
8194 }
8195
8196 default:
8197 if (! rtx_equal_p (operands[0], operands[1]))
8198 abort ();
8199 if (get_attr_mode (insn) == MODE_SI)
8200 return "and{l}\t{%k2, %k0|%k0, %k2}";
8201 else
8202 return "and{q}\t{%2, %0|%0, %2}";
8203 }
8204 }
8205 [(set_attr "type" "alu,alu,alu,imovx")
8206 (set_attr "length_immediate" "*,*,*,0")
8207 (set_attr "mode" "SI,DI,DI,DI")])
8208
8209 (define_insn "*anddi_2"
8210 [(set (reg 17)
8211 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8212 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8213 (const_int 0)))
8214 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8215 (and:DI (match_dup 1) (match_dup 2)))]
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8217 && ix86_binary_operator_ok (AND, DImode, operands)"
8218 "@
8219 and{l}\t{%k2, %k0|%k0, %k2}
8220 and{q}\t{%2, %0|%0, %2}
8221 and{q}\t{%2, %0|%0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "SI,DI,DI")])
8224
8225 (define_expand "andsi3"
8226 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8227 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8228 (match_operand:SI 2 "general_operand" "")))
8229 (clobber (reg:CC 17))]
8230 ""
8231 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8232
8233 (define_insn "*andsi_1"
8234 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8235 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8236 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8237 (clobber (reg:CC 17))]
8238 "ix86_binary_operator_ok (AND, SImode, operands)"
8239 {
8240 switch (get_attr_type (insn))
8241 {
8242 case TYPE_IMOVX:
8243 {
8244 enum machine_mode mode;
8245
8246 if (GET_CODE (operands[2]) != CONST_INT)
8247 abort ();
8248 if (INTVAL (operands[2]) == 0xff)
8249 mode = QImode;
8250 else if (INTVAL (operands[2]) == 0xffff)
8251 mode = HImode;
8252 else
8253 abort ();
8254
8255 operands[1] = gen_lowpart (mode, operands[1]);
8256 if (mode == QImode)
8257 return "movz{bl|x}\t{%1,%0|%0, %1}";
8258 else
8259 return "movz{wl|x}\t{%1,%0|%0, %1}";
8260 }
8261
8262 default:
8263 if (! rtx_equal_p (operands[0], operands[1]))
8264 abort ();
8265 return "and{l}\t{%2, %0|%0, %2}";
8266 }
8267 }
8268 [(set_attr "type" "alu,alu,imovx")
8269 (set_attr "length_immediate" "*,*,0")
8270 (set_attr "mode" "SI")])
8271
8272 (define_split
8273 [(set (match_operand 0 "register_operand" "")
8274 (and (match_dup 0)
8275 (const_int -65536)))
8276 (clobber (reg:CC 17))]
8277 "optimize_size"
8278 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8279 "operands[1] = gen_lowpart (HImode, operands[0]);")
8280
8281 (define_split
8282 [(set (match_operand 0 "ext_register_operand" "")
8283 (and (match_dup 0)
8284 (const_int -256)))
8285 (clobber (reg:CC 17))]
8286 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8287 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8288 "operands[1] = gen_lowpart (QImode, operands[0]);")
8289
8290 (define_split
8291 [(set (match_operand 0 "ext_register_operand" "")
8292 (and (match_dup 0)
8293 (const_int -65281)))
8294 (clobber (reg:CC 17))]
8295 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8296 [(parallel [(set (zero_extract:SI (match_dup 0)
8297 (const_int 8)
8298 (const_int 8))
8299 (xor:SI
8300 (zero_extract:SI (match_dup 0)
8301 (const_int 8)
8302 (const_int 8))
8303 (zero_extract:SI (match_dup 0)
8304 (const_int 8)
8305 (const_int 8))))
8306 (clobber (reg:CC 17))])]
8307 "operands[0] = gen_lowpart (SImode, operands[0]);")
8308
8309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8310 (define_insn "*andsi_1_zext"
8311 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (zero_extend:DI
8313 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8314 (match_operand:SI 2 "general_operand" "rim"))))
8315 (clobber (reg:CC 17))]
8316 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8317 "and{l}\t{%2, %k0|%k0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8320
8321 (define_insn "*andsi_2"
8322 [(set (reg 17)
8323 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8324 (match_operand:SI 2 "general_operand" "rim,ri"))
8325 (const_int 0)))
8326 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8327 (and:SI (match_dup 1) (match_dup 2)))]
8328 "ix86_match_ccmode (insn, CCNOmode)
8329 && ix86_binary_operator_ok (AND, SImode, operands)"
8330 "and{l}\t{%2, %0|%0, %2}"
8331 [(set_attr "type" "alu")
8332 (set_attr "mode" "SI")])
8333
8334 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8335 (define_insn "*andsi_2_zext"
8336 [(set (reg 17)
8337 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8338 (match_operand:SI 2 "general_operand" "rim"))
8339 (const_int 0)))
8340 (set (match_operand:DI 0 "register_operand" "=r")
8341 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8342 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8343 && ix86_binary_operator_ok (AND, SImode, operands)"
8344 "and{l}\t{%2, %k0|%k0, %2}"
8345 [(set_attr "type" "alu")
8346 (set_attr "mode" "SI")])
8347
8348 (define_expand "andhi3"
8349 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8350 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8351 (match_operand:HI 2 "general_operand" "")))
8352 (clobber (reg:CC 17))]
8353 "TARGET_HIMODE_MATH"
8354 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8355
8356 (define_insn "*andhi_1"
8357 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8358 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8359 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8360 (clobber (reg:CC 17))]
8361 "ix86_binary_operator_ok (AND, HImode, operands)"
8362 {
8363 switch (get_attr_type (insn))
8364 {
8365 case TYPE_IMOVX:
8366 if (GET_CODE (operands[2]) != CONST_INT)
8367 abort ();
8368 if (INTVAL (operands[2]) == 0xff)
8369 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8370 abort ();
8371
8372 default:
8373 if (! rtx_equal_p (operands[0], operands[1]))
8374 abort ();
8375
8376 return "and{w}\t{%2, %0|%0, %2}";
8377 }
8378 }
8379 [(set_attr "type" "alu,alu,imovx")
8380 (set_attr "length_immediate" "*,*,0")
8381 (set_attr "mode" "HI,HI,SI")])
8382
8383 (define_insn "*andhi_2"
8384 [(set (reg 17)
8385 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8386 (match_operand:HI 2 "general_operand" "rim,ri"))
8387 (const_int 0)))
8388 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8389 (and:HI (match_dup 1) (match_dup 2)))]
8390 "ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (AND, HImode, operands)"
8392 "and{w}\t{%2, %0|%0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "HI")])
8395
8396 (define_expand "andqi3"
8397 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8398 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8399 (match_operand:QI 2 "general_operand" "")))
8400 (clobber (reg:CC 17))]
8401 "TARGET_QIMODE_MATH"
8402 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8403
8404 ;; %%% Potential partial reg stall on alternative 2. What to do?
8405 (define_insn "*andqi_1"
8406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8407 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8408 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8409 (clobber (reg:CC 17))]
8410 "ix86_binary_operator_ok (AND, QImode, operands)"
8411 "@
8412 and{b}\t{%2, %0|%0, %2}
8413 and{b}\t{%2, %0|%0, %2}
8414 and{l}\t{%k2, %k0|%k0, %k2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "mode" "QI,QI,SI")])
8417
8418 (define_insn "*andqi_1_slp"
8419 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8420 (and:QI (match_dup 0)
8421 (match_operand:QI 1 "general_operand" "qi,qmi")))
8422 (clobber (reg:CC 17))]
8423 ""
8424 "and{b}\t{%1, %0|%0, %1}"
8425 [(set_attr "type" "alu1")
8426 (set_attr "mode" "QI")])
8427
8428 (define_insn "*andqi_2"
8429 [(set (reg 17)
8430 (compare (and:QI
8431 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8432 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8433 (const_int 0)))
8434 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8435 (and:QI (match_dup 1) (match_dup 2)))]
8436 "ix86_match_ccmode (insn, CCNOmode)
8437 && ix86_binary_operator_ok (AND, QImode, operands)"
8438 {
8439 if (which_alternative == 2)
8440 {
8441 if (GET_CODE (operands[2]) == CONST_INT
8442 && (INTVAL (operands[2]) & 0xffffff00))
8443 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8444 return "and{l}\t{%2, %k0|%k0, %2}";
8445 }
8446 return "and{b}\t{%2, %0|%0, %2}";
8447 }
8448 [(set_attr "type" "alu")
8449 (set_attr "mode" "QI,QI,SI")])
8450
8451 (define_insn "*andqi_2_slp"
8452 [(set (reg 17)
8453 (compare (and:QI
8454 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8455 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8456 (const_int 0)))
8457 (set (strict_low_part (match_dup 0))
8458 (and:QI (match_dup 0) (match_dup 1)))]
8459 "ix86_match_ccmode (insn, CCNOmode)"
8460 "and{b}\t{%1, %0|%0, %1}"
8461 [(set_attr "type" "alu1")
8462 (set_attr "mode" "QI")])
8463
8464 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8465 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8466 ;; for a QImode operand, which of course failed.
8467
8468 (define_insn "andqi_ext_0"
8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470 (const_int 8)
8471 (const_int 8))
8472 (and:SI
8473 (zero_extract:SI
8474 (match_operand 1 "ext_register_operand" "0")
8475 (const_int 8)
8476 (const_int 8))
8477 (match_operand 2 "const_int_operand" "n")))
8478 (clobber (reg:CC 17))]
8479 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8480 "and{b}\t{%2, %h0|%h0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "length_immediate" "1")
8483 (set_attr "mode" "QI")])
8484
8485 ;; Generated by peephole translating test to and. This shows up
8486 ;; often in fp comparisons.
8487
8488 (define_insn "*andqi_ext_0_cc"
8489 [(set (reg 17)
8490 (compare
8491 (and:SI
8492 (zero_extract:SI
8493 (match_operand 1 "ext_register_operand" "0")
8494 (const_int 8)
8495 (const_int 8))
8496 (match_operand 2 "const_int_operand" "n"))
8497 (const_int 0)))
8498 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8499 (const_int 8)
8500 (const_int 8))
8501 (and:SI
8502 (zero_extract:SI
8503 (match_dup 1)
8504 (const_int 8)
8505 (const_int 8))
8506 (match_dup 2)))]
8507 "ix86_match_ccmode (insn, CCNOmode)
8508 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8509 "and{b}\t{%2, %h0|%h0, %2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "length_immediate" "1")
8512 (set_attr "mode" "QI")])
8513
8514 (define_insn "*andqi_ext_1"
8515 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8516 (const_int 8)
8517 (const_int 8))
8518 (and:SI
8519 (zero_extract:SI
8520 (match_operand 1 "ext_register_operand" "0")
8521 (const_int 8)
8522 (const_int 8))
8523 (zero_extend:SI
8524 (match_operand:QI 2 "general_operand" "Qm"))))
8525 (clobber (reg:CC 17))]
8526 "!TARGET_64BIT"
8527 "and{b}\t{%2, %h0|%h0, %2}"
8528 [(set_attr "type" "alu")
8529 (set_attr "length_immediate" "0")
8530 (set_attr "mode" "QI")])
8531
8532 (define_insn "*andqi_ext_1_rex64"
8533 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8534 (const_int 8)
8535 (const_int 8))
8536 (and:SI
8537 (zero_extract:SI
8538 (match_operand 1 "ext_register_operand" "0")
8539 (const_int 8)
8540 (const_int 8))
8541 (zero_extend:SI
8542 (match_operand 2 "ext_register_operand" "Q"))))
8543 (clobber (reg:CC 17))]
8544 "TARGET_64BIT"
8545 "and{b}\t{%2, %h0|%h0, %2}"
8546 [(set_attr "type" "alu")
8547 (set_attr "length_immediate" "0")
8548 (set_attr "mode" "QI")])
8549
8550 (define_insn "*andqi_ext_2"
8551 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8552 (const_int 8)
8553 (const_int 8))
8554 (and:SI
8555 (zero_extract:SI
8556 (match_operand 1 "ext_register_operand" "%0")
8557 (const_int 8)
8558 (const_int 8))
8559 (zero_extract:SI
8560 (match_operand 2 "ext_register_operand" "Q")
8561 (const_int 8)
8562 (const_int 8))))
8563 (clobber (reg:CC 17))]
8564 ""
8565 "and{b}\t{%h2, %h0|%h0, %h2}"
8566 [(set_attr "type" "alu")
8567 (set_attr "length_immediate" "0")
8568 (set_attr "mode" "QI")])
8569 \f
8570 ;; Logical inclusive OR instructions
8571
8572 ;; %%% This used to optimize known byte-wide and operations to memory.
8573 ;; If this is considered useful, it should be done with splitters.
8574
8575 (define_expand "iordi3"
8576 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8577 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8578 (match_operand:DI 2 "x86_64_general_operand" "")))
8579 (clobber (reg:CC 17))]
8580 "TARGET_64BIT"
8581 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8582
8583 (define_insn "*iordi_1_rex64"
8584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8585 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8587 (clobber (reg:CC 17))]
8588 "TARGET_64BIT
8589 && ix86_binary_operator_ok (IOR, DImode, operands)"
8590 "or{q}\t{%2, %0|%0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "mode" "DI")])
8593
8594 (define_insn "*iordi_2_rex64"
8595 [(set (reg 17)
8596 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8597 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8598 (const_int 0)))
8599 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8600 (ior:DI (match_dup 1) (match_dup 2)))]
8601 "TARGET_64BIT
8602 && ix86_match_ccmode (insn, CCNOmode)
8603 && ix86_binary_operator_ok (IOR, DImode, operands)"
8604 "or{q}\t{%2, %0|%0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "DI")])
8607
8608 (define_insn "*iordi_3_rex64"
8609 [(set (reg 17)
8610 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8611 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8612 (const_int 0)))
8613 (clobber (match_scratch:DI 0 "=r"))]
8614 "TARGET_64BIT
8615 && ix86_match_ccmode (insn, CCNOmode)
8616 && ix86_binary_operator_ok (IOR, DImode, operands)"
8617 "or{q}\t{%2, %0|%0, %2}"
8618 [(set_attr "type" "alu")
8619 (set_attr "mode" "DI")])
8620
8621
8622 (define_expand "iorsi3"
8623 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8624 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8625 (match_operand:SI 2 "general_operand" "")))
8626 (clobber (reg:CC 17))]
8627 ""
8628 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8629
8630 (define_insn "*iorsi_1"
8631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8632 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8633 (match_operand:SI 2 "general_operand" "ri,rmi")))
8634 (clobber (reg:CC 17))]
8635 "ix86_binary_operator_ok (IOR, SImode, operands)"
8636 "or{l}\t{%2, %0|%0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "SI")])
8639
8640 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8641 (define_insn "*iorsi_1_zext"
8642 [(set (match_operand:DI 0 "register_operand" "=rm")
8643 (zero_extend:DI
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8645 (match_operand:SI 2 "general_operand" "rim"))))
8646 (clobber (reg:CC 17))]
8647 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %k0|%k0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8651
8652 (define_insn "*iorsi_1_zext_imm"
8653 [(set (match_operand:DI 0 "register_operand" "=rm")
8654 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8655 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8656 (clobber (reg:CC 17))]
8657 "TARGET_64BIT"
8658 "or{l}\t{%2, %k0|%k0, %2}"
8659 [(set_attr "type" "alu")
8660 (set_attr "mode" "SI")])
8661
8662 (define_insn "*iorsi_2"
8663 [(set (reg 17)
8664 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8665 (match_operand:SI 2 "general_operand" "rim,ri"))
8666 (const_int 0)))
8667 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8668 (ior:SI (match_dup 1) (match_dup 2)))]
8669 "ix86_match_ccmode (insn, CCNOmode)
8670 && ix86_binary_operator_ok (IOR, SImode, operands)"
8671 "or{l}\t{%2, %0|%0, %2}"
8672 [(set_attr "type" "alu")
8673 (set_attr "mode" "SI")])
8674
8675 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8676 ;; ??? Special case for immediate operand is missing - it is tricky.
8677 (define_insn "*iorsi_2_zext"
8678 [(set (reg 17)
8679 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680 (match_operand:SI 2 "general_operand" "rim"))
8681 (const_int 0)))
8682 (set (match_operand:DI 0 "register_operand" "=r")
8683 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685 && ix86_binary_operator_ok (IOR, SImode, operands)"
8686 "or{l}\t{%2, %k0|%k0, %2}"
8687 [(set_attr "type" "alu")
8688 (set_attr "mode" "SI")])
8689
8690 (define_insn "*iorsi_2_zext_imm"
8691 [(set (reg 17)
8692 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8694 (const_int 0)))
8695 (set (match_operand:DI 0 "register_operand" "=r")
8696 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8697 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, SImode, operands)"
8699 "or{l}\t{%2, %k0|%k0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "SI")])
8702
8703 (define_insn "*iorsi_3"
8704 [(set (reg 17)
8705 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8706 (match_operand:SI 2 "general_operand" "rim"))
8707 (const_int 0)))
8708 (clobber (match_scratch:SI 0 "=r"))]
8709 "ix86_match_ccmode (insn, CCNOmode)
8710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8711 "or{l}\t{%2, %0|%0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8714
8715 (define_expand "iorhi3"
8716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8717 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8718 (match_operand:HI 2 "general_operand" "")))
8719 (clobber (reg:CC 17))]
8720 "TARGET_HIMODE_MATH"
8721 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8722
8723 (define_insn "*iorhi_1"
8724 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8725 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726 (match_operand:HI 2 "general_operand" "rmi,ri")))
8727 (clobber (reg:CC 17))]
8728 "ix86_binary_operator_ok (IOR, HImode, operands)"
8729 "or{w}\t{%2, %0|%0, %2}"
8730 [(set_attr "type" "alu")
8731 (set_attr "mode" "HI")])
8732
8733 (define_insn "*iorhi_2"
8734 [(set (reg 17)
8735 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8736 (match_operand:HI 2 "general_operand" "rim,ri"))
8737 (const_int 0)))
8738 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8739 (ior:HI (match_dup 1) (match_dup 2)))]
8740 "ix86_match_ccmode (insn, CCNOmode)
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_3"
8747 [(set (reg 17)
8748 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8749 (match_operand:HI 2 "general_operand" "rim"))
8750 (const_int 0)))
8751 (clobber (match_scratch:HI 0 "=r"))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8754 "or{w}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8757
8758 (define_expand "iorqi3"
8759 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8760 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8761 (match_operand:QI 2 "general_operand" "")))
8762 (clobber (reg:CC 17))]
8763 "TARGET_QIMODE_MATH"
8764 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8765
8766 ;; %%% Potential partial reg stall on alternative 2. What to do?
8767 (define_insn "*iorqi_1"
8768 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8769 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8770 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8771 (clobber (reg:CC 17))]
8772 "ix86_binary_operator_ok (IOR, QImode, operands)"
8773 "@
8774 or{b}\t{%2, %0|%0, %2}
8775 or{b}\t{%2, %0|%0, %2}
8776 or{l}\t{%k2, %k0|%k0, %k2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "mode" "QI,QI,SI")])
8779
8780 (define_insn "*iorqi_1_slp"
8781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8782 (ior:QI (match_dup 0)
8783 (match_operand:QI 1 "general_operand" "qmi,qi")))
8784 (clobber (reg:CC 17))]
8785 ""
8786 "or{b}\t{%1, %0|%0, %1}"
8787 [(set_attr "type" "alu1")
8788 (set_attr "mode" "QI")])
8789
8790 (define_insn "*iorqi_2"
8791 [(set (reg 17)
8792 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8793 (match_operand:QI 2 "general_operand" "qim,qi"))
8794 (const_int 0)))
8795 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8796 (ior:QI (match_dup 1) (match_dup 2)))]
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && ix86_binary_operator_ok (IOR, QImode, operands)"
8799 "or{b}\t{%2, %0|%0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI")])
8802
8803 (define_insn "*iorqi_2_slp"
8804 [(set (reg 17)
8805 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8806 (match_operand:QI 1 "general_operand" "qim,qi"))
8807 (const_int 0)))
8808 (set (strict_low_part (match_dup 0))
8809 (ior:QI (match_dup 0) (match_dup 1)))]
8810 "ix86_match_ccmode (insn, CCNOmode)"
8811 "or{b}\t{%1, %0|%0, %1}"
8812 [(set_attr "type" "alu1")
8813 (set_attr "mode" "QI")])
8814
8815 (define_insn "*iorqi_3"
8816 [(set (reg 17)
8817 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8818 (match_operand:QI 2 "general_operand" "qim"))
8819 (const_int 0)))
8820 (clobber (match_scratch:QI 0 "=q"))]
8821 "ix86_match_ccmode (insn, CCNOmode)
8822 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8823 "or{b}\t{%2, %0|%0, %2}"
8824 [(set_attr "type" "alu")
8825 (set_attr "mode" "QI")])
8826
8827 \f
8828 ;; Logical XOR instructions
8829
8830 ;; %%% This used to optimize known byte-wide and operations to memory.
8831 ;; If this is considered useful, it should be done with splitters.
8832
8833 (define_expand "xordi3"
8834 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8835 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8836 (match_operand:DI 2 "x86_64_general_operand" "")))
8837 (clobber (reg:CC 17))]
8838 "TARGET_64BIT"
8839 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8840
8841 (define_insn "*xordi_1_rex64"
8842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8843 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8845 (clobber (reg:CC 17))]
8846 "TARGET_64BIT
8847 && ix86_binary_operator_ok (XOR, DImode, operands)"
8848 "@
8849 xor{q}\t{%2, %0|%0, %2}
8850 xor{q}\t{%2, %0|%0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "mode" "DI,DI")])
8853
8854 (define_insn "*xordi_2_rex64"
8855 [(set (reg 17)
8856 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8857 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8858 (const_int 0)))
8859 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8860 (xor:DI (match_dup 1) (match_dup 2)))]
8861 "TARGET_64BIT
8862 && ix86_match_ccmode (insn, CCNOmode)
8863 && ix86_binary_operator_ok (XOR, DImode, operands)"
8864 "@
8865 xor{q}\t{%2, %0|%0, %2}
8866 xor{q}\t{%2, %0|%0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "DI,DI")])
8869
8870 (define_insn "*xordi_3_rex64"
8871 [(set (reg 17)
8872 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8873 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8874 (const_int 0)))
8875 (clobber (match_scratch:DI 0 "=r"))]
8876 "TARGET_64BIT
8877 && ix86_match_ccmode (insn, CCNOmode)
8878 && ix86_binary_operator_ok (XOR, DImode, operands)"
8879 "xor{q}\t{%2, %0|%0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "DI")])
8882
8883 (define_expand "xorsi3"
8884 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8885 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8886 (match_operand:SI 2 "general_operand" "")))
8887 (clobber (reg:CC 17))]
8888 ""
8889 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8890
8891 (define_insn "*xorsi_1"
8892 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8893 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8894 (match_operand:SI 2 "general_operand" "ri,rm")))
8895 (clobber (reg:CC 17))]
8896 "ix86_binary_operator_ok (XOR, SImode, operands)"
8897 "xor{l}\t{%2, %0|%0, %2}"
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "SI")])
8900
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 ;; Add speccase for immediates
8903 (define_insn "*xorsi_1_zext"
8904 [(set (match_operand:DI 0 "register_operand" "=r")
8905 (zero_extend:DI
8906 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8907 (match_operand:SI 2 "general_operand" "rim"))))
8908 (clobber (reg:CC 17))]
8909 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8910 "xor{l}\t{%2, %k0|%k0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI")])
8913
8914 (define_insn "*xorsi_1_zext_imm"
8915 [(set (match_operand:DI 0 "register_operand" "=r")
8916 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8917 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8918 (clobber (reg:CC 17))]
8919 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8920 "xor{l}\t{%2, %k0|%k0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "SI")])
8923
8924 (define_insn "*xorsi_2"
8925 [(set (reg 17)
8926 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8927 (match_operand:SI 2 "general_operand" "rim,ri"))
8928 (const_int 0)))
8929 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8930 (xor:SI (match_dup 1) (match_dup 2)))]
8931 "ix86_match_ccmode (insn, CCNOmode)
8932 && ix86_binary_operator_ok (XOR, SImode, operands)"
8933 "xor{l}\t{%2, %0|%0, %2}"
8934 [(set_attr "type" "alu")
8935 (set_attr "mode" "SI")])
8936
8937 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8938 ;; ??? Special case for immediate operand is missing - it is tricky.
8939 (define_insn "*xorsi_2_zext"
8940 [(set (reg 17)
8941 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8942 (match_operand:SI 2 "general_operand" "rim"))
8943 (const_int 0)))
8944 (set (match_operand:DI 0 "register_operand" "=r")
8945 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8946 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8947 && ix86_binary_operator_ok (XOR, SImode, operands)"
8948 "xor{l}\t{%2, %k0|%k0, %2}"
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "SI")])
8951
8952 (define_insn "*xorsi_2_zext_imm"
8953 [(set (reg 17)
8954 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8955 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8956 (const_int 0)))
8957 (set (match_operand:DI 0 "register_operand" "=r")
8958 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8960 && ix86_binary_operator_ok (XOR, SImode, operands)"
8961 "xor{l}\t{%2, %k0|%k0, %2}"
8962 [(set_attr "type" "alu")
8963 (set_attr "mode" "SI")])
8964
8965 (define_insn "*xorsi_3"
8966 [(set (reg 17)
8967 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8968 (match_operand:SI 2 "general_operand" "rim"))
8969 (const_int 0)))
8970 (clobber (match_scratch:SI 0 "=r"))]
8971 "ix86_match_ccmode (insn, CCNOmode)
8972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8973 "xor{l}\t{%2, %0|%0, %2}"
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "SI")])
8976
8977 (define_expand "xorhi3"
8978 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8979 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8980 (match_operand:HI 2 "general_operand" "")))
8981 (clobber (reg:CC 17))]
8982 "TARGET_HIMODE_MATH"
8983 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8984
8985 (define_insn "*xorhi_1"
8986 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8987 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8988 (match_operand:HI 2 "general_operand" "rmi,ri")))
8989 (clobber (reg:CC 17))]
8990 "ix86_binary_operator_ok (XOR, HImode, operands)"
8991 "xor{w}\t{%2, %0|%0, %2}"
8992 [(set_attr "type" "alu")
8993 (set_attr "mode" "HI")])
8994
8995 (define_insn "*xorhi_2"
8996 [(set (reg 17)
8997 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:HI 2 "general_operand" "rim,ri"))
8999 (const_int 0)))
9000 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9001 (xor:HI (match_dup 1) (match_dup 2)))]
9002 "ix86_match_ccmode (insn, CCNOmode)
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_3"
9009 [(set (reg 17)
9010 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9011 (match_operand:HI 2 "general_operand" "rim"))
9012 (const_int 0)))
9013 (clobber (match_scratch:HI 0 "=r"))]
9014 "ix86_match_ccmode (insn, CCNOmode)
9015 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9016 "xor{w}\t{%2, %0|%0, %2}"
9017 [(set_attr "type" "alu")
9018 (set_attr "mode" "HI")])
9019
9020 (define_expand "xorqi3"
9021 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9022 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9023 (match_operand:QI 2 "general_operand" "")))
9024 (clobber (reg:CC 17))]
9025 "TARGET_QIMODE_MATH"
9026 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9027
9028 ;; %%% Potential partial reg stall on alternative 2. What to do?
9029 (define_insn "*xorqi_1"
9030 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9031 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9032 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9033 (clobber (reg:CC 17))]
9034 "ix86_binary_operator_ok (XOR, QImode, operands)"
9035 "@
9036 xor{b}\t{%2, %0|%0, %2}
9037 xor{b}\t{%2, %0|%0, %2}
9038 xor{l}\t{%k2, %k0|%k0, %k2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "QI,QI,SI")])
9041
9042 (define_insn "*xorqi_ext_1"
9043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9044 (const_int 8)
9045 (const_int 8))
9046 (xor:SI
9047 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9048 (const_int 8)
9049 (const_int 8))
9050 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9051 (const_int 8)
9052 (const_int 8))))
9053 (clobber (reg:CC 17))]
9054 ""
9055 "xor{b}\t{%h2, %h0|%h0, %h2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "length_immediate" "0")
9058 (set_attr "mode" "QI")])
9059
9060 (define_insn "*xorqi_cc_1"
9061 [(set (reg 17)
9062 (compare
9063 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9064 (match_operand:QI 2 "general_operand" "qim,qi"))
9065 (const_int 0)))
9066 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9067 (xor:QI (match_dup 1) (match_dup 2)))]
9068 "ix86_match_ccmode (insn, CCNOmode)
9069 && ix86_binary_operator_ok (XOR, QImode, operands)"
9070 "xor{b}\t{%2, %0|%0, %2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "mode" "QI")])
9073
9074 (define_insn "*xorqi_cc_2"
9075 [(set (reg 17)
9076 (compare
9077 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9078 (match_operand:QI 2 "general_operand" "qim"))
9079 (const_int 0)))
9080 (clobber (match_scratch:QI 0 "=q"))]
9081 "ix86_match_ccmode (insn, CCNOmode)
9082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9083 "xor{b}\t{%2, %0|%0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*xorqi_cc_ext_1"
9088 [(set (reg 17)
9089 (compare
9090 (xor:SI
9091 (zero_extract:SI
9092 (match_operand 1 "ext_register_operand" "0")
9093 (const_int 8)
9094 (const_int 8))
9095 (match_operand:QI 2 "general_operand" "qmn"))
9096 (const_int 0)))
9097 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9098 (const_int 8)
9099 (const_int 8))
9100 (xor:SI
9101 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9102 (match_dup 2)))]
9103 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9104 "xor{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "QI")])
9107
9108 (define_insn "*xorqi_cc_ext_1_rex64"
9109 [(set (reg 17)
9110 (compare
9111 (xor:SI
9112 (zero_extract:SI
9113 (match_operand 1 "ext_register_operand" "0")
9114 (const_int 8)
9115 (const_int 8))
9116 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9117 (const_int 0)))
9118 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119 (const_int 8)
9120 (const_int 8))
9121 (xor:SI
9122 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9123 (match_dup 2)))]
9124 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9125 "xor{b}\t{%2, %h0|%h0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "QI")])
9128
9129 (define_expand "xorqi_cc_ext_1"
9130 [(parallel [
9131 (set (reg:CCNO 17)
9132 (compare:CCNO
9133 (xor:SI
9134 (zero_extract:SI
9135 (match_operand 1 "ext_register_operand" "")
9136 (const_int 8)
9137 (const_int 8))
9138 (match_operand:QI 2 "general_operand" ""))
9139 (const_int 0)))
9140 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9141 (const_int 8)
9142 (const_int 8))
9143 (xor:SI
9144 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9145 (match_dup 2)))])]
9146 ""
9147 "")
9148 \f
9149 ;; Negation instructions
9150
9151 (define_expand "negdi2"
9152 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9153 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9154 (clobber (reg:CC 17))])]
9155 ""
9156 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9157
9158 (define_insn "*negdi2_1"
9159 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9160 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9161 (clobber (reg:CC 17))]
9162 "!TARGET_64BIT
9163 && ix86_unary_operator_ok (NEG, DImode, operands)"
9164 "#")
9165
9166 (define_split
9167 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9168 (neg:DI (match_operand:DI 1 "general_operand" "")))
9169 (clobber (reg:CC 17))]
9170 "!TARGET_64BIT && reload_completed"
9171 [(parallel
9172 [(set (reg:CCZ 17)
9173 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9174 (set (match_dup 0) (neg:SI (match_dup 2)))])
9175 (parallel
9176 [(set (match_dup 1)
9177 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9178 (match_dup 3))
9179 (const_int 0)))
9180 (clobber (reg:CC 17))])
9181 (parallel
9182 [(set (match_dup 1)
9183 (neg:SI (match_dup 1)))
9184 (clobber (reg:CC 17))])]
9185 "split_di (operands+1, 1, operands+2, operands+3);
9186 split_di (operands+0, 1, operands+0, operands+1);")
9187
9188 (define_insn "*negdi2_1_rex64"
9189 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9190 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9191 (clobber (reg:CC 17))]
9192 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9193 "neg{q}\t%0"
9194 [(set_attr "type" "negnot")
9195 (set_attr "mode" "DI")])
9196
9197 ;; The problem with neg is that it does not perform (compare x 0),
9198 ;; it really performs (compare 0 x), which leaves us with the zero
9199 ;; flag being the only useful item.
9200
9201 (define_insn "*negdi2_cmpz_rex64"
9202 [(set (reg:CCZ 17)
9203 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9204 (const_int 0)))
9205 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9206 (neg:DI (match_dup 1)))]
9207 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9208 "neg{q}\t%0"
9209 [(set_attr "type" "negnot")
9210 (set_attr "mode" "DI")])
9211
9212
9213 (define_expand "negsi2"
9214 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9215 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9216 (clobber (reg:CC 17))])]
9217 ""
9218 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9219
9220 (define_insn "*negsi2_1"
9221 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9222 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9223 (clobber (reg:CC 17))]
9224 "ix86_unary_operator_ok (NEG, SImode, operands)"
9225 "neg{l}\t%0"
9226 [(set_attr "type" "negnot")
9227 (set_attr "mode" "SI")])
9228
9229 ;; Combine is quite creative about this pattern.
9230 (define_insn "*negsi2_1_zext"
9231 [(set (match_operand:DI 0 "register_operand" "=r")
9232 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9233 (const_int 32)))
9234 (const_int 32)))
9235 (clobber (reg:CC 17))]
9236 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9237 "neg{l}\t%k0"
9238 [(set_attr "type" "negnot")
9239 (set_attr "mode" "SI")])
9240
9241 ;; The problem with neg is that it does not perform (compare x 0),
9242 ;; it really performs (compare 0 x), which leaves us with the zero
9243 ;; flag being the only useful item.
9244
9245 (define_insn "*negsi2_cmpz"
9246 [(set (reg:CCZ 17)
9247 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9248 (const_int 0)))
9249 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9250 (neg:SI (match_dup 1)))]
9251 "ix86_unary_operator_ok (NEG, SImode, operands)"
9252 "neg{l}\t%0"
9253 [(set_attr "type" "negnot")
9254 (set_attr "mode" "SI")])
9255
9256 (define_insn "*negsi2_cmpz_zext"
9257 [(set (reg:CCZ 17)
9258 (compare:CCZ (lshiftrt:DI
9259 (neg:DI (ashift:DI
9260 (match_operand:DI 1 "register_operand" "0")
9261 (const_int 32)))
9262 (const_int 32))
9263 (const_int 0)))
9264 (set (match_operand:DI 0 "register_operand" "=r")
9265 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9266 (const_int 32)))
9267 (const_int 32)))]
9268 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9269 "neg{l}\t%k0"
9270 [(set_attr "type" "negnot")
9271 (set_attr "mode" "SI")])
9272
9273 (define_expand "neghi2"
9274 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9275 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9276 (clobber (reg:CC 17))])]
9277 "TARGET_HIMODE_MATH"
9278 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9279
9280 (define_insn "*neghi2_1"
9281 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9282 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9283 (clobber (reg:CC 17))]
9284 "ix86_unary_operator_ok (NEG, HImode, operands)"
9285 "neg{w}\t%0"
9286 [(set_attr "type" "negnot")
9287 (set_attr "mode" "HI")])
9288
9289 (define_insn "*neghi2_cmpz"
9290 [(set (reg:CCZ 17)
9291 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9292 (const_int 0)))
9293 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9294 (neg:HI (match_dup 1)))]
9295 "ix86_unary_operator_ok (NEG, HImode, operands)"
9296 "neg{w}\t%0"
9297 [(set_attr "type" "negnot")
9298 (set_attr "mode" "HI")])
9299
9300 (define_expand "negqi2"
9301 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9302 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9303 (clobber (reg:CC 17))])]
9304 "TARGET_QIMODE_MATH"
9305 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9306
9307 (define_insn "*negqi2_1"
9308 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9309 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9310 (clobber (reg:CC 17))]
9311 "ix86_unary_operator_ok (NEG, QImode, operands)"
9312 "neg{b}\t%0"
9313 [(set_attr "type" "negnot")
9314 (set_attr "mode" "QI")])
9315
9316 (define_insn "*negqi2_cmpz"
9317 [(set (reg:CCZ 17)
9318 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9319 (const_int 0)))
9320 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9321 (neg:QI (match_dup 1)))]
9322 "ix86_unary_operator_ok (NEG, QImode, operands)"
9323 "neg{b}\t%0"
9324 [(set_attr "type" "negnot")
9325 (set_attr "mode" "QI")])
9326
9327 ;; Changing of sign for FP values is doable using integer unit too.
9328
9329 (define_expand "negsf2"
9330 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9331 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9332 (clobber (reg:CC 17))])]
9333 "TARGET_80387"
9334 "if (TARGET_SSE)
9335 {
9336 /* In case operand is in memory, we will not use SSE. */
9337 if (memory_operand (operands[0], VOIDmode)
9338 && rtx_equal_p (operands[0], operands[1]))
9339 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9340 else
9341 {
9342 /* Using SSE is tricky, since we need bitwise negation of -0
9343 in register. */
9344 rtx reg = gen_reg_rtx (SFmode);
9345 rtx dest = operands[0];
9346
9347 operands[1] = force_reg (SFmode, operands[1]);
9348 operands[0] = force_reg (SFmode, operands[0]);
9349 emit_move_insn (reg,
9350 gen_lowpart (SFmode,
9351 GEN_INT (trunc_int_for_mode (0x80000000,
9352 SImode))));
9353 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9354 if (dest != operands[0])
9355 emit_move_insn (dest, operands[0]);
9356 }
9357 DONE;
9358 }
9359 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9360
9361 (define_insn "negsf2_memory"
9362 [(set (match_operand:SF 0 "memory_operand" "=m")
9363 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9364 (clobber (reg:CC 17))]
9365 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9366 "#")
9367
9368 (define_insn "negsf2_ifs"
9369 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9370 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9371 (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
9372 (clobber (reg:CC 17))]
9373 "TARGET_SSE
9374 && (reload_in_progress || reload_completed
9375 || (register_operand (operands[0], VOIDmode)
9376 && register_operand (operands[1], VOIDmode)))"
9377 "#")
9378
9379 (define_split
9380 [(set (match_operand:SF 0 "memory_operand" "")
9381 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9382 (use (match_operand:SF 2 "" ""))
9383 (clobber (reg:CC 17))]
9384 ""
9385 [(parallel [(set (match_dup 0)
9386 (neg:SF (match_dup 1)))
9387 (clobber (reg:CC 17))])])
9388
9389 (define_split
9390 [(set (match_operand:SF 0 "register_operand" "")
9391 (neg:SF (match_operand:SF 1 "register_operand" "")))
9392 (use (match_operand:SF 2 "" ""))
9393 (clobber (reg:CC 17))]
9394 "reload_completed && !SSE_REG_P (operands[0])"
9395 [(parallel [(set (match_dup 0)
9396 (neg:SF (match_dup 1)))
9397 (clobber (reg:CC 17))])])
9398
9399 (define_split
9400 [(set (match_operand:SF 0 "register_operand" "")
9401 (neg:SF (match_operand:SF 1 "register_operand" "")))
9402 (use (match_operand:SF 2 "register_operand" ""))
9403 (clobber (reg:CC 17))]
9404 "reload_completed && SSE_REG_P (operands[0])"
9405 [(set (subreg:TI (match_dup 0) 0)
9406 (xor:TI (subreg:TI (match_dup 1) 0)
9407 (subreg:TI (match_dup 2) 0)))]
9408 {
9409 if (operands_match_p (operands[0], operands[2]))
9410 {
9411 rtx tmp;
9412 tmp = operands[1];
9413 operands[1] = operands[2];
9414 operands[2] = tmp;
9415 }
9416 })
9417
9418
9419 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9420 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9421 ;; to itself.
9422 (define_insn "*negsf2_if"
9423 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9424 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9425 (clobber (reg:CC 17))]
9426 "TARGET_80387 && !TARGET_SSE
9427 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9428 "#")
9429
9430 (define_split
9431 [(set (match_operand:SF 0 "register_operand" "")
9432 (neg:SF (match_operand:SF 1 "register_operand" "")))
9433 (clobber (reg:CC 17))]
9434 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9435 [(set (match_dup 0)
9436 (neg:SF (match_dup 1)))]
9437 "")
9438
9439 (define_split
9440 [(set (match_operand:SF 0 "register_operand" "")
9441 (neg:SF (match_operand:SF 1 "register_operand" "")))
9442 (clobber (reg:CC 17))]
9443 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9444 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9445 (clobber (reg:CC 17))])]
9446 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9447 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9448
9449 (define_split
9450 [(set (match_operand 0 "memory_operand" "")
9451 (neg (match_operand 1 "memory_operand" "")))
9452 (clobber (reg:CC 17))]
9453 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9454 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9455 (clobber (reg:CC 17))])]
9456 {
9457 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9458
9459 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9460 if (size >= 12)
9461 size = 10;
9462 operands[0] = adjust_address (operands[0], QImode, size - 1);
9463 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9464 })
9465
9466 (define_expand "negdf2"
9467 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9468 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9469 (clobber (reg:CC 17))])]
9470 "TARGET_80387"
9471 "if (TARGET_SSE2)
9472 {
9473 /* In case operand is in memory, we will not use SSE. */
9474 if (memory_operand (operands[0], VOIDmode)
9475 && rtx_equal_p (operands[0], operands[1]))
9476 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9477 else
9478 {
9479 /* Using SSE is tricky, since we need bitwise negation of -0
9480 in register. */
9481 rtx reg = gen_reg_rtx (DFmode);
9482 #if HOST_BITS_PER_WIDE_INT >= 64
9483 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9484 DImode));
9485 #else
9486 rtx imm = immed_double_const (0, 0x80000000, DImode);
9487 #endif
9488 rtx dest = operands[0];
9489
9490 operands[1] = force_reg (DFmode, operands[1]);
9491 operands[0] = force_reg (DFmode, operands[0]);
9492 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9493 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9494 if (dest != operands[0])
9495 emit_move_insn (dest, operands[0]);
9496 }
9497 DONE;
9498 }
9499 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9500
9501 (define_insn "negdf2_memory"
9502 [(set (match_operand:DF 0 "memory_operand" "=m")
9503 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9504 (clobber (reg:CC 17))]
9505 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9506 "#")
9507
9508 (define_insn "negdf2_ifs"
9509 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9510 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9511 (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
9512 (clobber (reg:CC 17))]
9513 "!TARGET_64BIT && TARGET_SSE2
9514 && (reload_in_progress || reload_completed
9515 || (register_operand (operands[0], VOIDmode)
9516 && register_operand (operands[1], VOIDmode)))"
9517 "#")
9518
9519 (define_insn "*negdf2_ifs_rex64"
9520 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
9521 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9522 (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
9523 (clobber (reg:CC 17))]
9524 "TARGET_64BIT && TARGET_SSE2
9525 && (reload_in_progress || reload_completed
9526 || (register_operand (operands[0], VOIDmode)
9527 && register_operand (operands[1], VOIDmode)))"
9528 "#")
9529
9530 (define_split
9531 [(set (match_operand:DF 0 "memory_operand" "")
9532 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9533 (use (match_operand:DF 2 "" ""))
9534 (clobber (reg:CC 17))]
9535 ""
9536 [(parallel [(set (match_dup 0)
9537 (neg:DF (match_dup 1)))
9538 (clobber (reg:CC 17))])])
9539
9540 (define_split
9541 [(set (match_operand:DF 0 "register_operand" "")
9542 (neg:DF (match_operand:DF 1 "register_operand" "")))
9543 (use (match_operand:DF 2 "" ""))
9544 (clobber (reg:CC 17))]
9545 "reload_completed && !SSE_REG_P (operands[0])
9546 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9547 [(parallel [(set (match_dup 0)
9548 (neg:DF (match_dup 1)))
9549 (clobber (reg:CC 17))])])
9550
9551 (define_split
9552 [(set (match_operand:DF 0 "register_operand" "")
9553 (neg:DF (match_operand:DF 1 "register_operand" "")))
9554 (use (match_operand:DF 2 "" ""))
9555 (clobber (reg:CC 17))]
9556 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9557 [(parallel [(set (match_dup 0)
9558 (xor:DI (match_dup 1) (match_dup 2)))
9559 (clobber (reg:CC 17))])]
9560 "operands[0] = gen_lowpart (DImode, operands[0]);
9561 operands[1] = gen_lowpart (DImode, operands[1]);
9562 operands[2] = gen_lowpart (DImode, operands[2]);")
9563
9564 (define_split
9565 [(set (match_operand:DF 0 "register_operand" "")
9566 (neg:DF (match_operand:DF 1 "register_operand" "")))
9567 (use (match_operand:DF 2 "register_operand" ""))
9568 (clobber (reg:CC 17))]
9569 "reload_completed && SSE_REG_P (operands[0])"
9570 [(set (subreg:TI (match_dup 0) 0)
9571 (xor:TI (subreg:TI (match_dup 1) 0)
9572 (subreg:TI (match_dup 2) 0)))]
9573 {
9574 if (operands_match_p (operands[0], operands[2]))
9575 {
9576 rtx tmp;
9577 tmp = operands[1];
9578 operands[1] = operands[2];
9579 operands[2] = tmp;
9580 }
9581 })
9582
9583 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9584 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9585 ;; to itself.
9586 (define_insn "*negdf2_if"
9587 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9588 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9589 (clobber (reg:CC 17))]
9590 "!TARGET_64BIT && TARGET_80387
9591 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9592 "#")
9593
9594 ;; FIXME: We should to allow integer registers here. Problem is that
9595 ;; we need another scratch register to get constant from.
9596 ;; Forcing constant to mem if no register available in peep2 should be
9597 ;; safe even for PIC mode, because of RIP relative addressing.
9598 (define_insn "*negdf2_if_rex64"
9599 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9600 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9601 (clobber (reg:CC 17))]
9602 "TARGET_64BIT && TARGET_80387
9603 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9604 "#")
9605
9606 (define_split
9607 [(set (match_operand:DF 0 "register_operand" "")
9608 (neg:DF (match_operand:DF 1 "register_operand" "")))
9609 (clobber (reg:CC 17))]
9610 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9611 [(set (match_dup 0)
9612 (neg:DF (match_dup 1)))]
9613 "")
9614
9615 (define_split
9616 [(set (match_operand:DF 0 "register_operand" "")
9617 (neg:DF (match_operand:DF 1 "register_operand" "")))
9618 (clobber (reg:CC 17))]
9619 "!TARGET_64BIT && TARGET_80387 && reload_completed
9620 && !FP_REGNO_P (REGNO (operands[0]))"
9621 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9622 (clobber (reg:CC 17))])]
9623 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9624 split_di (operands+0, 1, operands+2, operands+3);")
9625
9626 (define_expand "negxf2"
9627 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9628 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9629 (clobber (reg:CC 17))])]
9630 "!TARGET_64BIT && TARGET_80387"
9631 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9632
9633 (define_expand "negtf2"
9634 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9635 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9636 (clobber (reg:CC 17))])]
9637 "TARGET_80387"
9638 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9639
9640 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9641 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9642 ;; to itself.
9643 (define_insn "*negxf2_if"
9644 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9645 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9646 (clobber (reg:CC 17))]
9647 "!TARGET_64BIT && TARGET_80387
9648 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9649 "#")
9650
9651 (define_split
9652 [(set (match_operand:XF 0 "register_operand" "")
9653 (neg:XF (match_operand:XF 1 "register_operand" "")))
9654 (clobber (reg:CC 17))]
9655 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9656 [(set (match_dup 0)
9657 (neg:XF (match_dup 1)))]
9658 "")
9659
9660 (define_split
9661 [(set (match_operand:XF 0 "register_operand" "")
9662 (neg:XF (match_operand:XF 1 "register_operand" "")))
9663 (clobber (reg:CC 17))]
9664 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9665 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9666 (clobber (reg:CC 17))])]
9667 "operands[1] = GEN_INT (0x8000);
9668 operands[0] = gen_rtx_REG (SImode,
9669 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9670
9671 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9672 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9673 ;; to itself.
9674 (define_insn "*negtf2_if"
9675 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9676 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9677 (clobber (reg:CC 17))]
9678 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9679 "#")
9680
9681 (define_split
9682 [(set (match_operand:TF 0 "register_operand" "")
9683 (neg:TF (match_operand:TF 1 "register_operand" "")))
9684 (clobber (reg:CC 17))]
9685 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9686 [(set (match_dup 0)
9687 (neg:TF (match_dup 1)))]
9688 "")
9689
9690 (define_split
9691 [(set (match_operand:TF 0 "register_operand" "")
9692 (neg:TF (match_operand:TF 1 "register_operand" "")))
9693 (clobber (reg:CC 17))]
9694 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9695 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9696 (clobber (reg:CC 17))])]
9697 "operands[1] = GEN_INT (0x8000);
9698 operands[0] = gen_rtx_REG (SImode,
9699 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9700
9701 ;; Conditionize these after reload. If they matches before reload, we
9702 ;; lose the clobber and ability to use integer instructions.
9703
9704 (define_insn "*negsf2_1"
9705 [(set (match_operand:SF 0 "register_operand" "=f")
9706 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9707 "TARGET_80387 && reload_completed"
9708 "fchs"
9709 [(set_attr "type" "fsgn")
9710 (set_attr "mode" "SF")
9711 (set_attr "ppro_uops" "few")])
9712
9713 (define_insn "*negdf2_1"
9714 [(set (match_operand:DF 0 "register_operand" "=f")
9715 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9716 "TARGET_80387 && reload_completed"
9717 "fchs"
9718 [(set_attr "type" "fsgn")
9719 (set_attr "mode" "DF")
9720 (set_attr "ppro_uops" "few")])
9721
9722 (define_insn "*negextendsfdf2"
9723 [(set (match_operand:DF 0 "register_operand" "=f")
9724 (neg:DF (float_extend:DF
9725 (match_operand:SF 1 "register_operand" "0"))))]
9726 "TARGET_80387"
9727 "fchs"
9728 [(set_attr "type" "fsgn")
9729 (set_attr "mode" "DF")
9730 (set_attr "ppro_uops" "few")])
9731
9732 (define_insn "*negxf2_1"
9733 [(set (match_operand:XF 0 "register_operand" "=f")
9734 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9735 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9736 "fchs"
9737 [(set_attr "type" "fsgn")
9738 (set_attr "mode" "XF")
9739 (set_attr "ppro_uops" "few")])
9740
9741 (define_insn "*negextenddfxf2"
9742 [(set (match_operand:XF 0 "register_operand" "=f")
9743 (neg:XF (float_extend:XF
9744 (match_operand:DF 1 "register_operand" "0"))))]
9745 "!TARGET_64BIT && TARGET_80387"
9746 "fchs"
9747 [(set_attr "type" "fsgn")
9748 (set_attr "mode" "XF")
9749 (set_attr "ppro_uops" "few")])
9750
9751 (define_insn "*negextendsfxf2"
9752 [(set (match_operand:XF 0 "register_operand" "=f")
9753 (neg:XF (float_extend:XF
9754 (match_operand:SF 1 "register_operand" "0"))))]
9755 "!TARGET_64BIT && TARGET_80387"
9756 "fchs"
9757 [(set_attr "type" "fsgn")
9758 (set_attr "mode" "XF")
9759 (set_attr "ppro_uops" "few")])
9760
9761 (define_insn "*negtf2_1"
9762 [(set (match_operand:TF 0 "register_operand" "=f")
9763 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9764 "TARGET_80387 && reload_completed"
9765 "fchs"
9766 [(set_attr "type" "fsgn")
9767 (set_attr "mode" "XF")
9768 (set_attr "ppro_uops" "few")])
9769
9770 (define_insn "*negextenddftf2"
9771 [(set (match_operand:TF 0 "register_operand" "=f")
9772 (neg:TF (float_extend:TF
9773 (match_operand:DF 1 "register_operand" "0"))))]
9774 "TARGET_80387"
9775 "fchs"
9776 [(set_attr "type" "fsgn")
9777 (set_attr "mode" "XF")
9778 (set_attr "ppro_uops" "few")])
9779
9780 (define_insn "*negextendsftf2"
9781 [(set (match_operand:TF 0 "register_operand" "=f")
9782 (neg:TF (float_extend:TF
9783 (match_operand:SF 1 "register_operand" "0"))))]
9784 "TARGET_80387"
9785 "fchs"
9786 [(set_attr "type" "fsgn")
9787 (set_attr "mode" "XF")
9788 (set_attr "ppro_uops" "few")])
9789 \f
9790 ;; Absolute value instructions
9791
9792 (define_expand "abssf2"
9793 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9794 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9795 (clobber (reg:CC 17))])]
9796 "TARGET_80387"
9797 "if (TARGET_SSE)
9798 {
9799 /* In case operand is in memory, we will not use SSE. */
9800 if (memory_operand (operands[0], VOIDmode)
9801 && rtx_equal_p (operands[0], operands[1]))
9802 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9803 else
9804 {
9805 /* Using SSE is tricky, since we need bitwise negation of -0
9806 in register. */
9807 rtx reg = gen_reg_rtx (SFmode);
9808 rtx dest = operands[0];
9809
9810 operands[1] = force_reg (SFmode, operands[1]);
9811 operands[0] = force_reg (SFmode, operands[0]);
9812 emit_move_insn (reg,
9813 gen_lowpart (SFmode,
9814 GEN_INT (trunc_int_for_mode (0x80000000,
9815 SImode))));
9816 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9817 if (dest != operands[0])
9818 emit_move_insn (dest, operands[0]);
9819 }
9820 DONE;
9821 }
9822 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9823
9824 (define_insn "abssf2_memory"
9825 [(set (match_operand:SF 0 "memory_operand" "=m")
9826 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9827 (clobber (reg:CC 17))]
9828 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9829 "#")
9830
9831 (define_insn "abssf2_ifs"
9832 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
9833 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9834 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
9835 (clobber (reg:CC 17))]
9836 "TARGET_SSE
9837 && (reload_in_progress || reload_completed
9838 || (register_operand (operands[0], VOIDmode)
9839 && register_operand (operands[1], VOIDmode)))"
9840 "#")
9841
9842 (define_split
9843 [(set (match_operand:SF 0 "memory_operand" "")
9844 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9845 (use (match_operand:SF 2 "" ""))
9846 (clobber (reg:CC 17))]
9847 ""
9848 [(parallel [(set (match_dup 0)
9849 (abs:SF (match_dup 1)))
9850 (clobber (reg:CC 17))])])
9851
9852 (define_split
9853 [(set (match_operand:SF 0 "register_operand" "")
9854 (abs:SF (match_operand:SF 1 "register_operand" "")))
9855 (use (match_operand:SF 2 "" ""))
9856 (clobber (reg:CC 17))]
9857 "reload_completed && !SSE_REG_P (operands[0])"
9858 [(parallel [(set (match_dup 0)
9859 (abs:SF (match_dup 1)))
9860 (clobber (reg:CC 17))])])
9861
9862 (define_split
9863 [(set (match_operand:SF 0 "register_operand" "")
9864 (abs:SF (match_operand:SF 1 "register_operand" "")))
9865 (use (match_operand:SF 2 "register_operand" ""))
9866 (clobber (reg:CC 17))]
9867 "reload_completed && SSE_REG_P (operands[0])"
9868 [(set (subreg:TI (match_dup 0) 0)
9869 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9870 (subreg:TI (match_dup 1) 0)))])
9871
9872 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9873 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9874 ;; to itself.
9875 (define_insn "*abssf2_if"
9876 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9877 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9878 (clobber (reg:CC 17))]
9879 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9880 "#")
9881
9882 (define_split
9883 [(set (match_operand:SF 0 "register_operand" "")
9884 (abs:SF (match_operand:SF 1 "register_operand" "")))
9885 (clobber (reg:CC 17))]
9886 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9887 [(set (match_dup 0)
9888 (abs:SF (match_dup 1)))]
9889 "")
9890
9891 (define_split
9892 [(set (match_operand:SF 0 "register_operand" "")
9893 (abs:SF (match_operand:SF 1 "register_operand" "")))
9894 (clobber (reg:CC 17))]
9895 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9896 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9897 (clobber (reg:CC 17))])]
9898 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
9899 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9900
9901 (define_split
9902 [(set (match_operand 0 "memory_operand" "")
9903 (abs (match_operand 1 "memory_operand" "")))
9904 (clobber (reg:CC 17))]
9905 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9906 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9907 (clobber (reg:CC 17))])]
9908 {
9909 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9910
9911 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9912 if (size >= 12)
9913 size = 10;
9914 operands[0] = adjust_address (operands[0], QImode, size - 1);
9915 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
9916 })
9917
9918 (define_expand "absdf2"
9919 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9920 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9921 (clobber (reg:CC 17))])]
9922 "TARGET_80387"
9923 "if (TARGET_SSE2)
9924 {
9925 /* In case operand is in memory, we will not use SSE. */
9926 if (memory_operand (operands[0], VOIDmode)
9927 && rtx_equal_p (operands[0], operands[1]))
9928 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9929 else
9930 {
9931 /* Using SSE is tricky, since we need bitwise negation of -0
9932 in register. */
9933 rtx reg = gen_reg_rtx (DFmode);
9934 #if HOST_BITS_PER_WIDE_INT >= 64
9935 rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
9936 DImode));
9937 #else
9938 rtx imm = immed_double_const (0, 0x80000000, DImode);
9939 #endif
9940 rtx dest = operands[0];
9941
9942 operands[1] = force_reg (DFmode, operands[1]);
9943 operands[0] = force_reg (DFmode, operands[0]);
9944 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9945 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9946 if (dest != operands[0])
9947 emit_move_insn (dest, operands[0]);
9948 }
9949 DONE;
9950 }
9951 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9952
9953 (define_insn "absdf2_memory"
9954 [(set (match_operand:DF 0 "memory_operand" "=m")
9955 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9956 (clobber (reg:CC 17))]
9957 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9958 "#")
9959
9960 (define_insn "absdf2_ifs"
9961 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
9962 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9963 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
9964 (clobber (reg:CC 17))]
9965 "!TARGET_64BIT && TARGET_SSE2
9966 && (reload_in_progress || reload_completed
9967 || (register_operand (operands[0], VOIDmode)
9968 && register_operand (operands[1], VOIDmode)))"
9969 "#")
9970
9971 (define_insn "*absdf2_ifs_rex64"
9972 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
9973 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
9974 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
9975 (clobber (reg:CC 17))]
9976 "TARGET_64BIT && TARGET_SSE2
9977 && (reload_in_progress || reload_completed
9978 || (register_operand (operands[0], VOIDmode)
9979 && register_operand (operands[1], VOIDmode)))"
9980 "#")
9981
9982 (define_split
9983 [(set (match_operand:DF 0 "memory_operand" "")
9984 (abs:DF (match_operand:DF 1 "memory_operand" "")))
9985 (use (match_operand:DF 2 "" ""))
9986 (clobber (reg:CC 17))]
9987 ""
9988 [(parallel [(set (match_dup 0)
9989 (abs:DF (match_dup 1)))
9990 (clobber (reg:CC 17))])])
9991
9992 (define_split
9993 [(set (match_operand:DF 0 "register_operand" "")
9994 (abs:DF (match_operand:DF 1 "register_operand" "")))
9995 (use (match_operand:DF 2 "" ""))
9996 (clobber (reg:CC 17))]
9997 "reload_completed && !SSE_REG_P (operands[0])"
9998 [(parallel [(set (match_dup 0)
9999 (abs:DF (match_dup 1)))
10000 (clobber (reg:CC 17))])])
10001
10002 (define_split
10003 [(set (match_operand:DF 0 "register_operand" "")
10004 (abs:DF (match_operand:DF 1 "register_operand" "")))
10005 (use (match_operand:DF 2 "register_operand" ""))
10006 (clobber (reg:CC 17))]
10007 "reload_completed && SSE_REG_P (operands[0])"
10008 [(set (subreg:TI (match_dup 0) 0)
10009 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
10010 (subreg:TI (match_dup 1) 0)))])
10011
10012
10013 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10014 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10015 ;; to itself.
10016 (define_insn "*absdf2_if"
10017 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10018 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10019 (clobber (reg:CC 17))]
10020 "!TARGET_64BIT && TARGET_80387
10021 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10022 "#")
10023
10024 ;; FIXME: We should to allow integer registers here. Problem is that
10025 ;; we need another scratch register to get constant from.
10026 ;; Forcing constant to mem if no register available in peep2 should be
10027 ;; safe even for PIC mode, because of RIP relative addressing.
10028 (define_insn "*absdf2_if_rex64"
10029 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10030 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10031 (clobber (reg:CC 17))]
10032 "TARGET_64BIT && TARGET_80387
10033 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10034 "#")
10035
10036 (define_split
10037 [(set (match_operand:DF 0 "register_operand" "")
10038 (abs:DF (match_operand:DF 1 "register_operand" "")))
10039 (clobber (reg:CC 17))]
10040 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10041 [(set (match_dup 0)
10042 (abs:DF (match_dup 1)))]
10043 "")
10044
10045 (define_split
10046 [(set (match_operand:DF 0 "register_operand" "")
10047 (abs:DF (match_operand:DF 1 "register_operand" "")))
10048 (clobber (reg:CC 17))]
10049 "!TARGET_64BIT && TARGET_80387 && reload_completed &&
10050 !FP_REGNO_P (REGNO (operands[0]))"
10051 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10052 (clobber (reg:CC 17))])]
10053 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
10054 split_di (operands+0, 1, operands+2, operands+3);")
10055
10056 (define_expand "absxf2"
10057 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10058 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10059 (clobber (reg:CC 17))])]
10060 "!TARGET_64BIT && TARGET_80387"
10061 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10062
10063 (define_expand "abstf2"
10064 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10065 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10066 (clobber (reg:CC 17))])]
10067 "TARGET_80387"
10068 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10069
10070 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10071 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10072 ;; to itself.
10073 (define_insn "*absxf2_if"
10074 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10075 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10076 (clobber (reg:CC 17))]
10077 "!TARGET_64BIT && TARGET_80387
10078 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10079 "#")
10080
10081 (define_split
10082 [(set (match_operand:XF 0 "register_operand" "")
10083 (abs:XF (match_operand:XF 1 "register_operand" "")))
10084 (clobber (reg:CC 17))]
10085 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10086 [(set (match_dup 0)
10087 (abs:XF (match_dup 1)))]
10088 "")
10089
10090 (define_split
10091 [(set (match_operand:XF 0 "register_operand" "")
10092 (abs:XF (match_operand:XF 1 "register_operand" "")))
10093 (clobber (reg:CC 17))]
10094 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10095 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10096 (clobber (reg:CC 17))])]
10097 "operands[1] = GEN_INT (~0x8000);
10098 operands[0] = gen_rtx_REG (SImode,
10099 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10100
10101 (define_insn "*abstf2_if"
10102 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10103 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10104 (clobber (reg:CC 17))]
10105 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10106 "#")
10107
10108 (define_split
10109 [(set (match_operand:TF 0 "register_operand" "")
10110 (abs:TF (match_operand:TF 1 "register_operand" "")))
10111 (clobber (reg:CC 17))]
10112 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
10113 [(set (match_dup 0)
10114 (abs:TF (match_dup 1)))]
10115 "")
10116
10117 (define_split
10118 [(set (match_operand:TF 0 "register_operand" "")
10119 (abs:TF (match_operand:TF 1 "register_operand" "")))
10120 (clobber (reg:CC 17))]
10121 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
10122 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10123 (clobber (reg:CC 17))])]
10124 "operands[1] = GEN_INT (~0x8000);
10125 operands[0] = gen_rtx_REG (SImode,
10126 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10127
10128 (define_insn "*abssf2_1"
10129 [(set (match_operand:SF 0 "register_operand" "=f")
10130 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10131 "TARGET_80387 && reload_completed"
10132 "fabs"
10133 [(set_attr "type" "fsgn")
10134 (set_attr "mode" "SF")])
10135
10136 (define_insn "*absdf2_1"
10137 [(set (match_operand:DF 0 "register_operand" "=f")
10138 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10139 "TARGET_80387 && reload_completed"
10140 "fabs"
10141 [(set_attr "type" "fsgn")
10142 (set_attr "mode" "DF")])
10143
10144 (define_insn "*absextendsfdf2"
10145 [(set (match_operand:DF 0 "register_operand" "=f")
10146 (abs:DF (float_extend:DF
10147 (match_operand:SF 1 "register_operand" "0"))))]
10148 "TARGET_80387"
10149 "fabs"
10150 [(set_attr "type" "fsgn")
10151 (set_attr "mode" "DF")])
10152
10153 (define_insn "*absxf2_1"
10154 [(set (match_operand:XF 0 "register_operand" "=f")
10155 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10156 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10157 "fabs"
10158 [(set_attr "type" "fsgn")
10159 (set_attr "mode" "DF")])
10160
10161 (define_insn "*absextenddfxf2"
10162 [(set (match_operand:XF 0 "register_operand" "=f")
10163 (abs:XF (float_extend:XF
10164 (match_operand:DF 1 "register_operand" "0"))))]
10165 "!TARGET_64BIT && TARGET_80387"
10166 "fabs"
10167 [(set_attr "type" "fsgn")
10168 (set_attr "mode" "XF")])
10169
10170 (define_insn "*absextendsfxf2"
10171 [(set (match_operand:XF 0 "register_operand" "=f")
10172 (abs:XF (float_extend:XF
10173 (match_operand:SF 1 "register_operand" "0"))))]
10174 "!TARGET_64BIT && TARGET_80387"
10175 "fabs"
10176 [(set_attr "type" "fsgn")
10177 (set_attr "mode" "XF")])
10178
10179 (define_insn "*abstf2_1"
10180 [(set (match_operand:TF 0 "register_operand" "=f")
10181 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10182 "TARGET_80387 && reload_completed"
10183 "fabs"
10184 [(set_attr "type" "fsgn")
10185 (set_attr "mode" "DF")])
10186
10187 (define_insn "*absextenddftf2"
10188 [(set (match_operand:TF 0 "register_operand" "=f")
10189 (abs:TF (float_extend:TF
10190 (match_operand:DF 1 "register_operand" "0"))))]
10191 "TARGET_80387"
10192 "fabs"
10193 [(set_attr "type" "fsgn")
10194 (set_attr "mode" "XF")])
10195
10196 (define_insn "*absextendsftf2"
10197 [(set (match_operand:TF 0 "register_operand" "=f")
10198 (abs:TF (float_extend:TF
10199 (match_operand:SF 1 "register_operand" "0"))))]
10200 "TARGET_80387"
10201 "fabs"
10202 [(set_attr "type" "fsgn")
10203 (set_attr "mode" "XF")])
10204 \f
10205 ;; One complement instructions
10206
10207 (define_expand "one_cmpldi2"
10208 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10209 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10210 "TARGET_64BIT"
10211 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10212
10213 (define_insn "*one_cmpldi2_1_rex64"
10214 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10215 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10216 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10217 "not{q}\t%0"
10218 [(set_attr "type" "negnot")
10219 (set_attr "mode" "DI")])
10220
10221 (define_insn "*one_cmpldi2_2_rex64"
10222 [(set (reg 17)
10223 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10224 (const_int 0)))
10225 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10226 (not:DI (match_dup 1)))]
10227 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10228 && ix86_unary_operator_ok (NOT, DImode, operands)"
10229 "#"
10230 [(set_attr "type" "alu1")
10231 (set_attr "mode" "DI")])
10232
10233 (define_split
10234 [(set (reg 17)
10235 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10236 (const_int 0)))
10237 (set (match_operand:DI 0 "nonimmediate_operand" "")
10238 (not:DI (match_dup 1)))]
10239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10240 [(parallel [(set (reg:CCNO 17)
10241 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10242 (const_int 0)))
10243 (set (match_dup 0)
10244 (xor:DI (match_dup 1) (const_int -1)))])]
10245 "")
10246
10247 (define_expand "one_cmplsi2"
10248 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10249 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10250 ""
10251 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10252
10253 (define_insn "*one_cmplsi2_1"
10254 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10255 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10256 "ix86_unary_operator_ok (NOT, SImode, operands)"
10257 "not{l}\t%0"
10258 [(set_attr "type" "negnot")
10259 (set_attr "mode" "SI")])
10260
10261 ;; ??? Currently never generated - xor is used instead.
10262 (define_insn "*one_cmplsi2_1_zext"
10263 [(set (match_operand:DI 0 "register_operand" "=r")
10264 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10265 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10266 "not{l}\t%k0"
10267 [(set_attr "type" "negnot")
10268 (set_attr "mode" "SI")])
10269
10270 (define_insn "*one_cmplsi2_2"
10271 [(set (reg 17)
10272 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10273 (const_int 0)))
10274 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10275 (not:SI (match_dup 1)))]
10276 "ix86_match_ccmode (insn, CCNOmode)
10277 && ix86_unary_operator_ok (NOT, SImode, operands)"
10278 "#"
10279 [(set_attr "type" "alu1")
10280 (set_attr "mode" "SI")])
10281
10282 (define_split
10283 [(set (reg 17)
10284 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10285 (const_int 0)))
10286 (set (match_operand:SI 0 "nonimmediate_operand" "")
10287 (not:SI (match_dup 1)))]
10288 "ix86_match_ccmode (insn, CCNOmode)"
10289 [(parallel [(set (reg:CCNO 17)
10290 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10291 (const_int 0)))
10292 (set (match_dup 0)
10293 (xor:SI (match_dup 1) (const_int -1)))])]
10294 "")
10295
10296 ;; ??? Currently never generated - xor is used instead.
10297 (define_insn "*one_cmplsi2_2_zext"
10298 [(set (reg 17)
10299 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10300 (const_int 0)))
10301 (set (match_operand:DI 0 "register_operand" "=r")
10302 (zero_extend:DI (not:SI (match_dup 1))))]
10303 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10304 && ix86_unary_operator_ok (NOT, SImode, operands)"
10305 "#"
10306 [(set_attr "type" "alu1")
10307 (set_attr "mode" "SI")])
10308
10309 (define_split
10310 [(set (reg 17)
10311 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10312 (const_int 0)))
10313 (set (match_operand:DI 0 "register_operand" "")
10314 (zero_extend:DI (not:SI (match_dup 1))))]
10315 "ix86_match_ccmode (insn, CCNOmode)"
10316 [(parallel [(set (reg:CCNO 17)
10317 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10318 (const_int 0)))
10319 (set (match_dup 0)
10320 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10321 "")
10322
10323 (define_expand "one_cmplhi2"
10324 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10325 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10326 "TARGET_HIMODE_MATH"
10327 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10328
10329 (define_insn "*one_cmplhi2_1"
10330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10331 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10332 "ix86_unary_operator_ok (NOT, HImode, operands)"
10333 "not{w}\t%0"
10334 [(set_attr "type" "negnot")
10335 (set_attr "mode" "HI")])
10336
10337 (define_insn "*one_cmplhi2_2"
10338 [(set (reg 17)
10339 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10340 (const_int 0)))
10341 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10342 (not:HI (match_dup 1)))]
10343 "ix86_match_ccmode (insn, CCNOmode)
10344 && ix86_unary_operator_ok (NEG, HImode, operands)"
10345 "#"
10346 [(set_attr "type" "alu1")
10347 (set_attr "mode" "HI")])
10348
10349 (define_split
10350 [(set (reg 17)
10351 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10352 (const_int 0)))
10353 (set (match_operand:HI 0 "nonimmediate_operand" "")
10354 (not:HI (match_dup 1)))]
10355 "ix86_match_ccmode (insn, CCNOmode)"
10356 [(parallel [(set (reg:CCNO 17)
10357 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10358 (const_int 0)))
10359 (set (match_dup 0)
10360 (xor:HI (match_dup 1) (const_int -1)))])]
10361 "")
10362
10363 ;; %%% Potential partial reg stall on alternative 1. What to do?
10364 (define_expand "one_cmplqi2"
10365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10366 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10367 "TARGET_QIMODE_MATH"
10368 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10369
10370 (define_insn "*one_cmplqi2_1"
10371 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10372 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10373 "ix86_unary_operator_ok (NOT, QImode, operands)"
10374 "@
10375 not{b}\t%0
10376 not{l}\t%k0"
10377 [(set_attr "type" "negnot")
10378 (set_attr "mode" "QI,SI")])
10379
10380 (define_insn "*one_cmplqi2_2"
10381 [(set (reg 17)
10382 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10383 (const_int 0)))
10384 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10385 (not:QI (match_dup 1)))]
10386 "ix86_match_ccmode (insn, CCNOmode)
10387 && ix86_unary_operator_ok (NOT, QImode, operands)"
10388 "#"
10389 [(set_attr "type" "alu1")
10390 (set_attr "mode" "QI")])
10391
10392 (define_split
10393 [(set (reg 17)
10394 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10395 (const_int 0)))
10396 (set (match_operand:QI 0 "nonimmediate_operand" "")
10397 (not:QI (match_dup 1)))]
10398 "ix86_match_ccmode (insn, CCNOmode)"
10399 [(parallel [(set (reg:CCNO 17)
10400 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10401 (const_int 0)))
10402 (set (match_dup 0)
10403 (xor:QI (match_dup 1) (const_int -1)))])]
10404 "")
10405 \f
10406 ;; Arithmetic shift instructions
10407
10408 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10409 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10410 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10411 ;; from the assembler input.
10412 ;;
10413 ;; This instruction shifts the target reg/mem as usual, but instead of
10414 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10415 ;; is a left shift double, bits are taken from the high order bits of
10416 ;; reg, else if the insn is a shift right double, bits are taken from the
10417 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10418 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10419 ;;
10420 ;; Since sh[lr]d does not change the `reg' operand, that is done
10421 ;; separately, making all shifts emit pairs of shift double and normal
10422 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10423 ;; support a 63 bit shift, each shift where the count is in a reg expands
10424 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10425 ;;
10426 ;; If the shift count is a constant, we need never emit more than one
10427 ;; shift pair, instead using moves and sign extension for counts greater
10428 ;; than 31.
10429
10430 (define_expand "ashldi3"
10431 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10432 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10433 (match_operand:QI 2 "nonmemory_operand" "")))
10434 (clobber (reg:CC 17))])]
10435 ""
10436 {
10437 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10438 {
10439 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10440 DONE;
10441 }
10442 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10443 DONE;
10444 })
10445
10446 (define_insn "*ashldi3_1_rex64"
10447 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10448 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10449 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10450 (clobber (reg:CC 17))]
10451 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10452 {
10453 switch (get_attr_type (insn))
10454 {
10455 case TYPE_ALU:
10456 if (operands[2] != const1_rtx)
10457 abort ();
10458 if (!rtx_equal_p (operands[0], operands[1]))
10459 abort ();
10460 return "add{q}\t{%0, %0|%0, %0}";
10461
10462 case TYPE_LEA:
10463 if (GET_CODE (operands[2]) != CONST_INT
10464 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10465 abort ();
10466 operands[1] = gen_rtx_MULT (DImode, operands[1],
10467 GEN_INT (1 << INTVAL (operands[2])));
10468 return "lea{q}\t{%a1, %0|%0, %a1}";
10469
10470 default:
10471 if (REG_P (operands[2]))
10472 return "sal{q}\t{%b2, %0|%0, %b2}";
10473 else if (GET_CODE (operands[2]) == CONST_INT
10474 && INTVAL (operands[2]) == 1
10475 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10476 return "sal{q}\t%0";
10477 else
10478 return "sal{q}\t{%2, %0|%0, %2}";
10479 }
10480 }
10481 [(set (attr "type")
10482 (cond [(eq_attr "alternative" "1")
10483 (const_string "lea")
10484 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10485 (const_int 0))
10486 (match_operand 0 "register_operand" ""))
10487 (match_operand 2 "const1_operand" ""))
10488 (const_string "alu")
10489 ]
10490 (const_string "ishift")))
10491 (set_attr "mode" "DI")])
10492
10493 ;; Convert lea to the lea pattern to avoid flags dependency.
10494 (define_split
10495 [(set (match_operand:DI 0 "register_operand" "")
10496 (ashift:DI (match_operand:DI 1 "register_operand" "")
10497 (match_operand:QI 2 "immediate_operand" "")))
10498 (clobber (reg:CC 17))]
10499 "TARGET_64BIT && reload_completed
10500 && true_regnum (operands[0]) != true_regnum (operands[1])"
10501 [(set (match_dup 0)
10502 (mult:DI (match_dup 1)
10503 (match_dup 2)))]
10504 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10505 DImode));")
10506
10507 ;; This pattern can't accept a variable shift count, since shifts by
10508 ;; zero don't affect the flags. We assume that shifts by constant
10509 ;; zero are optimized away.
10510 (define_insn "*ashldi3_cmp_rex64"
10511 [(set (reg 17)
10512 (compare
10513 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10514 (match_operand:QI 2 "immediate_operand" "e"))
10515 (const_int 0)))
10516 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10517 (ashift:DI (match_dup 1) (match_dup 2)))]
10518 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10519 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10520 {
10521 switch (get_attr_type (insn))
10522 {
10523 case TYPE_ALU:
10524 if (operands[2] != const1_rtx)
10525 abort ();
10526 return "add{q}\t{%0, %0|%0, %0}";
10527
10528 default:
10529 if (REG_P (operands[2]))
10530 return "sal{q}\t{%b2, %0|%0, %b2}";
10531 else if (GET_CODE (operands[2]) == CONST_INT
10532 && INTVAL (operands[2]) == 1
10533 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10534 return "sal{q}\t%0";
10535 else
10536 return "sal{q}\t{%2, %0|%0, %2}";
10537 }
10538 }
10539 [(set (attr "type")
10540 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10541 (const_int 0))
10542 (match_operand 0 "register_operand" ""))
10543 (match_operand 2 "const1_operand" ""))
10544 (const_string "alu")
10545 ]
10546 (const_string "ishift")))
10547 (set_attr "mode" "DI")])
10548
10549 (define_insn "ashldi3_1"
10550 [(set (match_operand:DI 0 "register_operand" "=r")
10551 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10552 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10553 (clobber (match_scratch:SI 3 "=&r"))
10554 (clobber (reg:CC 17))]
10555 "!TARGET_64BIT && TARGET_CMOVE"
10556 "#"
10557 [(set_attr "type" "multi")])
10558
10559 (define_insn "*ashldi3_2"
10560 [(set (match_operand:DI 0 "register_operand" "=r")
10561 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10562 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10563 (clobber (reg:CC 17))]
10564 "!TARGET_64BIT"
10565 "#"
10566 [(set_attr "type" "multi")])
10567
10568 (define_split
10569 [(set (match_operand:DI 0 "register_operand" "")
10570 (ashift:DI (match_operand:DI 1 "register_operand" "")
10571 (match_operand:QI 2 "nonmemory_operand" "")))
10572 (clobber (match_scratch:SI 3 ""))
10573 (clobber (reg:CC 17))]
10574 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10575 [(const_int 0)]
10576 "ix86_split_ashldi (operands, operands[3]); DONE;")
10577
10578 (define_split
10579 [(set (match_operand:DI 0 "register_operand" "")
10580 (ashift:DI (match_operand:DI 1 "register_operand" "")
10581 (match_operand:QI 2 "nonmemory_operand" "")))
10582 (clobber (reg:CC 17))]
10583 "!TARGET_64BIT && reload_completed"
10584 [(const_int 0)]
10585 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10586
10587 (define_insn "x86_shld_1"
10588 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10589 (ior:SI (ashift:SI (match_dup 0)
10590 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10591 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10592 (minus:QI (const_int 32) (match_dup 2)))))
10593 (clobber (reg:CC 17))]
10594 ""
10595 "@
10596 shld{l}\t{%2, %1, %0|%0, %1, %2}
10597 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10598 [(set_attr "type" "ishift")
10599 (set_attr "prefix_0f" "1")
10600 (set_attr "mode" "SI")
10601 (set_attr "pent_pair" "np")
10602 (set_attr "athlon_decode" "vector")
10603 (set_attr "ppro_uops" "few")])
10604
10605 (define_expand "x86_shift_adj_1"
10606 [(set (reg:CCZ 17)
10607 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10608 (const_int 32))
10609 (const_int 0)))
10610 (set (match_operand:SI 0 "register_operand" "")
10611 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10612 (match_operand:SI 1 "register_operand" "")
10613 (match_dup 0)))
10614 (set (match_dup 1)
10615 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10616 (match_operand:SI 3 "register_operand" "r")
10617 (match_dup 1)))]
10618 "TARGET_CMOVE"
10619 "")
10620
10621 (define_expand "x86_shift_adj_2"
10622 [(use (match_operand:SI 0 "register_operand" ""))
10623 (use (match_operand:SI 1 "register_operand" ""))
10624 (use (match_operand:QI 2 "register_operand" ""))]
10625 ""
10626 {
10627 rtx label = gen_label_rtx ();
10628 rtx tmp;
10629
10630 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10631
10632 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10633 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10634 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10635 gen_rtx_LABEL_REF (VOIDmode, label),
10636 pc_rtx);
10637 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10638 JUMP_LABEL (tmp) = label;
10639
10640 emit_move_insn (operands[0], operands[1]);
10641 emit_move_insn (operands[1], const0_rtx);
10642
10643 emit_label (label);
10644 LABEL_NUSES (label) = 1;
10645
10646 DONE;
10647 })
10648
10649 (define_expand "ashlsi3"
10650 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10651 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10652 (match_operand:QI 2 "nonmemory_operand" "")))
10653 (clobber (reg:CC 17))]
10654 ""
10655 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10656
10657 (define_insn "*ashlsi3_1"
10658 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10659 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10660 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10661 (clobber (reg:CC 17))]
10662 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10663 {
10664 switch (get_attr_type (insn))
10665 {
10666 case TYPE_ALU:
10667 if (operands[2] != const1_rtx)
10668 abort ();
10669 if (!rtx_equal_p (operands[0], operands[1]))
10670 abort ();
10671 return "add{l}\t{%0, %0|%0, %0}";
10672
10673 case TYPE_LEA:
10674 return "#";
10675
10676 default:
10677 if (REG_P (operands[2]))
10678 return "sal{l}\t{%b2, %0|%0, %b2}";
10679 else if (GET_CODE (operands[2]) == CONST_INT
10680 && INTVAL (operands[2]) == 1
10681 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10682 return "sal{l}\t%0";
10683 else
10684 return "sal{l}\t{%2, %0|%0, %2}";
10685 }
10686 }
10687 [(set (attr "type")
10688 (cond [(eq_attr "alternative" "1")
10689 (const_string "lea")
10690 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10691 (const_int 0))
10692 (match_operand 0 "register_operand" ""))
10693 (match_operand 2 "const1_operand" ""))
10694 (const_string "alu")
10695 ]
10696 (const_string "ishift")))
10697 (set_attr "mode" "SI")])
10698
10699 ;; Convert lea to the lea pattern to avoid flags dependency.
10700 (define_split
10701 [(set (match_operand 0 "register_operand" "")
10702 (ashift (match_operand 1 "register_operand" "")
10703 (match_operand:QI 2 "const_int_operand" "")))
10704 (clobber (reg:CC 17))]
10705 "reload_completed
10706 && true_regnum (operands[0]) != true_regnum (operands[1])"
10707 [(const_int 0)]
10708 {
10709 rtx pat;
10710 operands[0] = gen_lowpart (SImode, operands[0]);
10711 operands[1] = gen_lowpart (Pmode, operands[1]);
10712 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10713 Pmode));
10714 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10715 if (Pmode != SImode)
10716 pat = gen_rtx_SUBREG (SImode, pat, 0);
10717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10718 DONE;
10719 })
10720
10721 (define_insn "*ashlsi3_1_zext"
10722 [(set (match_operand:DI 0 "register_operand" "=r,r")
10723 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10724 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10725 (clobber (reg:CC 17))]
10726 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10727 {
10728 switch (get_attr_type (insn))
10729 {
10730 case TYPE_ALU:
10731 if (operands[2] != const1_rtx)
10732 abort ();
10733 return "add{l}\t{%k0, %k0|%k0, %k0}";
10734
10735 case TYPE_LEA:
10736 return "#";
10737
10738 default:
10739 if (REG_P (operands[2]))
10740 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10741 else if (GET_CODE (operands[2]) == CONST_INT
10742 && INTVAL (operands[2]) == 1
10743 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10744 return "sal{l}\t%k0";
10745 else
10746 return "sal{l}\t{%2, %k0|%k0, %2}";
10747 }
10748 }
10749 [(set (attr "type")
10750 (cond [(eq_attr "alternative" "1")
10751 (const_string "lea")
10752 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10753 (const_int 0))
10754 (match_operand 2 "const1_operand" ""))
10755 (const_string "alu")
10756 ]
10757 (const_string "ishift")))
10758 (set_attr "mode" "SI")])
10759
10760 ;; Convert lea to the lea pattern to avoid flags dependency.
10761 (define_split
10762 [(set (match_operand:DI 0 "register_operand" "")
10763 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10764 (match_operand:QI 2 "const_int_operand" ""))))
10765 (clobber (reg:CC 17))]
10766 "reload_completed
10767 && true_regnum (operands[0]) != true_regnum (operands[1])"
10768 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10769 {
10770 operands[1] = gen_lowpart (Pmode, operands[1]);
10771 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10772 Pmode));
10773 })
10774
10775 ;; This pattern can't accept a variable shift count, since shifts by
10776 ;; zero don't affect the flags. We assume that shifts by constant
10777 ;; zero are optimized away.
10778 (define_insn "*ashlsi3_cmp"
10779 [(set (reg 17)
10780 (compare
10781 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "immediate_operand" "I"))
10783 (const_int 0)))
10784 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10785 (ashift:SI (match_dup 1) (match_dup 2)))]
10786 "ix86_match_ccmode (insn, CCGOCmode)
10787 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10788 {
10789 switch (get_attr_type (insn))
10790 {
10791 case TYPE_ALU:
10792 if (operands[2] != const1_rtx)
10793 abort ();
10794 return "add{l}\t{%0, %0|%0, %0}";
10795
10796 default:
10797 if (REG_P (operands[2]))
10798 return "sal{l}\t{%b2, %0|%0, %b2}";
10799 else if (GET_CODE (operands[2]) == CONST_INT
10800 && INTVAL (operands[2]) == 1
10801 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10802 return "sal{l}\t%0";
10803 else
10804 return "sal{l}\t{%2, %0|%0, %2}";
10805 }
10806 }
10807 [(set (attr "type")
10808 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10809 (const_int 0))
10810 (match_operand 0 "register_operand" ""))
10811 (match_operand 2 "const1_operand" ""))
10812 (const_string "alu")
10813 ]
10814 (const_string "ishift")))
10815 (set_attr "mode" "SI")])
10816
10817 (define_insn "*ashlsi3_cmp_zext"
10818 [(set (reg 17)
10819 (compare
10820 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10821 (match_operand:QI 2 "immediate_operand" "I"))
10822 (const_int 0)))
10823 (set (match_operand:DI 0 "register_operand" "=r")
10824 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10825 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10826 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10827 {
10828 switch (get_attr_type (insn))
10829 {
10830 case TYPE_ALU:
10831 if (operands[2] != const1_rtx)
10832 abort ();
10833 return "add{l}\t{%k0, %k0|%k0, %k0}";
10834
10835 default:
10836 if (REG_P (operands[2]))
10837 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10838 else if (GET_CODE (operands[2]) == CONST_INT
10839 && INTVAL (operands[2]) == 1
10840 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10841 return "sal{l}\t%k0";
10842 else
10843 return "sal{l}\t{%2, %k0|%k0, %2}";
10844 }
10845 }
10846 [(set (attr "type")
10847 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10848 (const_int 0))
10849 (match_operand 2 "const1_operand" ""))
10850 (const_string "alu")
10851 ]
10852 (const_string "ishift")))
10853 (set_attr "mode" "SI")])
10854
10855 (define_expand "ashlhi3"
10856 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10857 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10858 (match_operand:QI 2 "nonmemory_operand" "")))
10859 (clobber (reg:CC 17))]
10860 "TARGET_HIMODE_MATH"
10861 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10862
10863 (define_insn "*ashlhi3_1_lea"
10864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10865 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10866 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10867 (clobber (reg:CC 17))]
10868 "!TARGET_PARTIAL_REG_STALL
10869 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10870 {
10871 switch (get_attr_type (insn))
10872 {
10873 case TYPE_LEA:
10874 return "#";
10875 case TYPE_ALU:
10876 if (operands[2] != const1_rtx)
10877 abort ();
10878 return "add{w}\t{%0, %0|%0, %0}";
10879
10880 default:
10881 if (REG_P (operands[2]))
10882 return "sal{w}\t{%b2, %0|%0, %b2}";
10883 else if (GET_CODE (operands[2]) == CONST_INT
10884 && INTVAL (operands[2]) == 1
10885 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10886 return "sal{w}\t%0";
10887 else
10888 return "sal{w}\t{%2, %0|%0, %2}";
10889 }
10890 }
10891 [(set (attr "type")
10892 (cond [(eq_attr "alternative" "1")
10893 (const_string "lea")
10894 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10895 (const_int 0))
10896 (match_operand 0 "register_operand" ""))
10897 (match_operand 2 "const1_operand" ""))
10898 (const_string "alu")
10899 ]
10900 (const_string "ishift")))
10901 (set_attr "mode" "HI,SI")])
10902
10903 (define_insn "*ashlhi3_1"
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10905 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10906 (match_operand:QI 2 "nonmemory_operand" "cI")))
10907 (clobber (reg:CC 17))]
10908 "TARGET_PARTIAL_REG_STALL
10909 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10910 {
10911 switch (get_attr_type (insn))
10912 {
10913 case TYPE_ALU:
10914 if (operands[2] != const1_rtx)
10915 abort ();
10916 return "add{w}\t{%0, %0|%0, %0}";
10917
10918 default:
10919 if (REG_P (operands[2]))
10920 return "sal{w}\t{%b2, %0|%0, %b2}";
10921 else if (GET_CODE (operands[2]) == CONST_INT
10922 && INTVAL (operands[2]) == 1
10923 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10924 return "sal{w}\t%0";
10925 else
10926 return "sal{w}\t{%2, %0|%0, %2}";
10927 }
10928 }
10929 [(set (attr "type")
10930 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10931 (const_int 0))
10932 (match_operand 0 "register_operand" ""))
10933 (match_operand 2 "const1_operand" ""))
10934 (const_string "alu")
10935 ]
10936 (const_string "ishift")))
10937 (set_attr "mode" "HI")])
10938
10939 ;; This pattern can't accept a variable shift count, since shifts by
10940 ;; zero don't affect the flags. We assume that shifts by constant
10941 ;; zero are optimized away.
10942 (define_insn "*ashlhi3_cmp"
10943 [(set (reg 17)
10944 (compare
10945 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10946 (match_operand:QI 2 "immediate_operand" "I"))
10947 (const_int 0)))
10948 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10949 (ashift:HI (match_dup 1) (match_dup 2)))]
10950 "ix86_match_ccmode (insn, CCGOCmode)
10951 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10952 {
10953 switch (get_attr_type (insn))
10954 {
10955 case TYPE_ALU:
10956 if (operands[2] != const1_rtx)
10957 abort ();
10958 return "add{w}\t{%0, %0|%0, %0}";
10959
10960 default:
10961 if (REG_P (operands[2]))
10962 return "sal{w}\t{%b2, %0|%0, %b2}";
10963 else if (GET_CODE (operands[2]) == CONST_INT
10964 && INTVAL (operands[2]) == 1
10965 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10966 return "sal{w}\t%0";
10967 else
10968 return "sal{w}\t{%2, %0|%0, %2}";
10969 }
10970 }
10971 [(set (attr "type")
10972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973 (const_int 0))
10974 (match_operand 0 "register_operand" ""))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10977 ]
10978 (const_string "ishift")))
10979 (set_attr "mode" "HI")])
10980
10981 (define_expand "ashlqi3"
10982 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10983 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10984 (match_operand:QI 2 "nonmemory_operand" "")))
10985 (clobber (reg:CC 17))]
10986 "TARGET_QIMODE_MATH"
10987 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10988
10989 ;; %%% Potential partial reg stall on alternative 2. What to do?
10990
10991 (define_insn "*ashlqi3_1_lea"
10992 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10993 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10994 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10995 (clobber (reg:CC 17))]
10996 "!TARGET_PARTIAL_REG_STALL
10997 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10998 {
10999 switch (get_attr_type (insn))
11000 {
11001 case TYPE_LEA:
11002 return "#";
11003 case TYPE_ALU:
11004 if (operands[2] != const1_rtx)
11005 abort ();
11006 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11007 return "add{l}\t{%k0, %k0|%k0, %k0}";
11008 else
11009 return "add{b}\t{%0, %0|%0, %0}";
11010
11011 default:
11012 if (REG_P (operands[2]))
11013 {
11014 if (get_attr_mode (insn) == MODE_SI)
11015 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11016 else
11017 return "sal{b}\t{%b2, %0|%0, %b2}";
11018 }
11019 else if (GET_CODE (operands[2]) == CONST_INT
11020 && INTVAL (operands[2]) == 1
11021 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11022 {
11023 if (get_attr_mode (insn) == MODE_SI)
11024 return "sal{l}\t%0";
11025 else
11026 return "sal{b}\t%0";
11027 }
11028 else
11029 {
11030 if (get_attr_mode (insn) == MODE_SI)
11031 return "sal{l}\t{%2, %k0|%k0, %2}";
11032 else
11033 return "sal{b}\t{%2, %0|%0, %2}";
11034 }
11035 }
11036 }
11037 [(set (attr "type")
11038 (cond [(eq_attr "alternative" "2")
11039 (const_string "lea")
11040 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11041 (const_int 0))
11042 (match_operand 0 "register_operand" ""))
11043 (match_operand 2 "const1_operand" ""))
11044 (const_string "alu")
11045 ]
11046 (const_string "ishift")))
11047 (set_attr "mode" "QI,SI,SI")])
11048
11049 (define_insn "*ashlqi3_1"
11050 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11051 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11052 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11053 (clobber (reg:CC 17))]
11054 "TARGET_PARTIAL_REG_STALL
11055 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11056 {
11057 switch (get_attr_type (insn))
11058 {
11059 case TYPE_ALU:
11060 if (operands[2] != const1_rtx)
11061 abort ();
11062 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11063 return "add{l}\t{%k0, %k0|%k0, %k0}";
11064 else
11065 return "add{b}\t{%0, %0|%0, %0}";
11066
11067 default:
11068 if (REG_P (operands[2]))
11069 {
11070 if (get_attr_mode (insn) == MODE_SI)
11071 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11072 else
11073 return "sal{b}\t{%b2, %0|%0, %b2}";
11074 }
11075 else if (GET_CODE (operands[2]) == CONST_INT
11076 && INTVAL (operands[2]) == 1
11077 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11078 {
11079 if (get_attr_mode (insn) == MODE_SI)
11080 return "sal{l}\t%0";
11081 else
11082 return "sal{b}\t%0";
11083 }
11084 else
11085 {
11086 if (get_attr_mode (insn) == MODE_SI)
11087 return "sal{l}\t{%2, %k0|%k0, %2}";
11088 else
11089 return "sal{b}\t{%2, %0|%0, %2}";
11090 }
11091 }
11092 }
11093 [(set (attr "type")
11094 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11095 (const_int 0))
11096 (match_operand 0 "register_operand" ""))
11097 (match_operand 2 "const1_operand" ""))
11098 (const_string "alu")
11099 ]
11100 (const_string "ishift")))
11101 (set_attr "mode" "QI,SI")])
11102
11103 ;; This pattern can't accept a variable shift count, since shifts by
11104 ;; zero don't affect the flags. We assume that shifts by constant
11105 ;; zero are optimized away.
11106 (define_insn "*ashlqi3_cmp"
11107 [(set (reg 17)
11108 (compare
11109 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "immediate_operand" "I"))
11111 (const_int 0)))
11112 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11113 (ashift:QI (match_dup 1) (match_dup 2)))]
11114 "ix86_match_ccmode (insn, CCGOCmode)
11115 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11116 {
11117 switch (get_attr_type (insn))
11118 {
11119 case TYPE_ALU:
11120 if (operands[2] != const1_rtx)
11121 abort ();
11122 return "add{b}\t{%0, %0|%0, %0}";
11123
11124 default:
11125 if (REG_P (operands[2]))
11126 return "sal{b}\t{%b2, %0|%0, %b2}";
11127 else if (GET_CODE (operands[2]) == CONST_INT
11128 && INTVAL (operands[2]) == 1
11129 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
11130 return "sal{b}\t%0";
11131 else
11132 return "sal{b}\t{%2, %0|%0, %2}";
11133 }
11134 }
11135 [(set (attr "type")
11136 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11137 (const_int 0))
11138 (match_operand 0 "register_operand" ""))
11139 (match_operand 2 "const1_operand" ""))
11140 (const_string "alu")
11141 ]
11142 (const_string "ishift")))
11143 (set_attr "mode" "QI")])
11144
11145 ;; See comment above `ashldi3' about how this works.
11146
11147 (define_expand "ashrdi3"
11148 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11149 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11150 (match_operand:QI 2 "nonmemory_operand" "")))
11151 (clobber (reg:CC 17))])]
11152 ""
11153 {
11154 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11155 {
11156 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11157 DONE;
11158 }
11159 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11160 DONE;
11161 })
11162
11163 (define_insn "ashrdi3_63_rex64"
11164 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11165 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11166 (match_operand:DI 2 "const_int_operand" "i,i")))
11167 (clobber (reg:CC 17))]
11168 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11169 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11170 "@
11171 {cqto|cqo}
11172 sar{q}\t{%2, %0|%0, %2}"
11173 [(set_attr "type" "imovx,ishift")
11174 (set_attr "prefix_0f" "0,*")
11175 (set_attr "length_immediate" "0,*")
11176 (set_attr "modrm" "0,1")
11177 (set_attr "mode" "DI")])
11178
11179 (define_insn "*ashrdi3_1_one_bit_rex64"
11180 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11181 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11182 (match_operand:QI 2 "const_int_1_operand" "")))
11183 (clobber (reg:CC 17))]
11184 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11185 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11186 "sar{q}\t%0"
11187 [(set_attr "type" "ishift")
11188 (set (attr "length")
11189 (if_then_else (match_operand:DI 0 "register_operand" "")
11190 (const_string "2")
11191 (const_string "*")))])
11192
11193 (define_insn "*ashrdi3_1_rex64"
11194 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11195 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11196 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11197 (clobber (reg:CC 17))]
11198 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11199 "@
11200 sar{q}\t{%2, %0|%0, %2}
11201 sar{q}\t{%b2, %0|%0, %b2}"
11202 [(set_attr "type" "ishift")
11203 (set_attr "mode" "DI")])
11204
11205 ;; This pattern can't accept a variable shift count, since shifts by
11206 ;; zero don't affect the flags. We assume that shifts by constant
11207 ;; zero are optimized away.
11208 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11209 [(set (reg 17)
11210 (compare
11211 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11212 (match_operand:QI 2 "const_int_1_operand" ""))
11213 (const_int 0)))
11214 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11215 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11216 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11217 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11218 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11219 "sar{q}\t%0"
11220 [(set_attr "type" "ishift")
11221 (set (attr "length")
11222 (if_then_else (match_operand:DI 0 "register_operand" "")
11223 (const_string "2")
11224 (const_string "*")))])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags. We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashrdi3_cmp_rex64"
11230 [(set (reg 17)
11231 (compare
11232 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11233 (match_operand:QI 2 "const_int_operand" "n"))
11234 (const_int 0)))
11235 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11236 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11237 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11238 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11239 "sar{q}\t{%2, %0|%0, %2}"
11240 [(set_attr "type" "ishift")
11241 (set_attr "mode" "DI")])
11242
11243
11244 (define_insn "ashrdi3_1"
11245 [(set (match_operand:DI 0 "register_operand" "=r")
11246 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11247 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11248 (clobber (match_scratch:SI 3 "=&r"))
11249 (clobber (reg:CC 17))]
11250 "!TARGET_64BIT && TARGET_CMOVE"
11251 "#"
11252 [(set_attr "type" "multi")])
11253
11254 (define_insn "*ashrdi3_2"
11255 [(set (match_operand:DI 0 "register_operand" "=r")
11256 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11257 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11258 (clobber (reg:CC 17))]
11259 "!TARGET_64BIT"
11260 "#"
11261 [(set_attr "type" "multi")])
11262
11263 (define_split
11264 [(set (match_operand:DI 0 "register_operand" "")
11265 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11266 (match_operand:QI 2 "nonmemory_operand" "")))
11267 (clobber (match_scratch:SI 3 ""))
11268 (clobber (reg:CC 17))]
11269 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11270 [(const_int 0)]
11271 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11272
11273 (define_split
11274 [(set (match_operand:DI 0 "register_operand" "")
11275 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11276 (match_operand:QI 2 "nonmemory_operand" "")))
11277 (clobber (reg:CC 17))]
11278 "!TARGET_64BIT && reload_completed"
11279 [(const_int 0)]
11280 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11281
11282 (define_insn "x86_shrd_1"
11283 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11284 (ior:SI (ashiftrt:SI (match_dup 0)
11285 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11286 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11287 (minus:QI (const_int 32) (match_dup 2)))))
11288 (clobber (reg:CC 17))]
11289 ""
11290 "@
11291 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11292 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11293 [(set_attr "type" "ishift")
11294 (set_attr "prefix_0f" "1")
11295 (set_attr "pent_pair" "np")
11296 (set_attr "ppro_uops" "few")
11297 (set_attr "mode" "SI")])
11298
11299 (define_expand "x86_shift_adj_3"
11300 [(use (match_operand:SI 0 "register_operand" ""))
11301 (use (match_operand:SI 1 "register_operand" ""))
11302 (use (match_operand:QI 2 "register_operand" ""))]
11303 ""
11304 {
11305 rtx label = gen_label_rtx ();
11306 rtx tmp;
11307
11308 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11309
11310 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11311 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11312 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11313 gen_rtx_LABEL_REF (VOIDmode, label),
11314 pc_rtx);
11315 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11316 JUMP_LABEL (tmp) = label;
11317
11318 emit_move_insn (operands[0], operands[1]);
11319 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11320
11321 emit_label (label);
11322 LABEL_NUSES (label) = 1;
11323
11324 DONE;
11325 })
11326
11327 (define_insn "ashrsi3_31"
11328 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11329 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11330 (match_operand:SI 2 "const_int_operand" "i,i")))
11331 (clobber (reg:CC 17))]
11332 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11333 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11334 "@
11335 {cltd|cdq}
11336 sar{l}\t{%2, %0|%0, %2}"
11337 [(set_attr "type" "imovx,ishift")
11338 (set_attr "prefix_0f" "0,*")
11339 (set_attr "length_immediate" "0,*")
11340 (set_attr "modrm" "0,1")
11341 (set_attr "mode" "SI")])
11342
11343 (define_insn "*ashrsi3_31_zext"
11344 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11345 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11346 (match_operand:SI 2 "const_int_operand" "i,i"))))
11347 (clobber (reg:CC 17))]
11348 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11349 && INTVAL (operands[2]) == 31
11350 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11351 "@
11352 {cltd|cdq}
11353 sar{l}\t{%2, %k0|%k0, %2}"
11354 [(set_attr "type" "imovx,ishift")
11355 (set_attr "prefix_0f" "0,*")
11356 (set_attr "length_immediate" "0,*")
11357 (set_attr "modrm" "0,1")
11358 (set_attr "mode" "SI")])
11359
11360 (define_expand "ashrsi3"
11361 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11363 (match_operand:QI 2 "nonmemory_operand" "")))
11364 (clobber (reg:CC 17))]
11365 ""
11366 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11367
11368 (define_insn "*ashrsi3_1_one_bit"
11369 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11370 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11371 (match_operand:QI 2 "const_int_1_operand" "")))
11372 (clobber (reg:CC 17))]
11373 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11374 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11375 "sar{l}\t%0"
11376 [(set_attr "type" "ishift")
11377 (set (attr "length")
11378 (if_then_else (match_operand:SI 0 "register_operand" "")
11379 (const_string "2")
11380 (const_string "*")))])
11381
11382 (define_insn "*ashrsi3_1_one_bit_zext"
11383 [(set (match_operand:DI 0 "register_operand" "=r")
11384 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11385 (match_operand:QI 2 "const_int_1_operand" ""))))
11386 (clobber (reg:CC 17))]
11387 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11388 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11389 "sar{l}\t%k0"
11390 [(set_attr "type" "ishift")
11391 (set_attr "length" "2")])
11392
11393 (define_insn "*ashrsi3_1"
11394 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11395 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11397 (clobber (reg:CC 17))]
11398 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11399 "@
11400 sar{l}\t{%2, %0|%0, %2}
11401 sar{l}\t{%b2, %0|%0, %b2}"
11402 [(set_attr "type" "ishift")
11403 (set_attr "mode" "SI")])
11404
11405 (define_insn "*ashrsi3_1_zext"
11406 [(set (match_operand:DI 0 "register_operand" "=r,r")
11407 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11408 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11409 (clobber (reg:CC 17))]
11410 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11411 "@
11412 sar{l}\t{%2, %k0|%k0, %2}
11413 sar{l}\t{%b2, %k0|%k0, %b2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "SI")])
11416
11417 ;; This pattern can't accept a variable shift count, since shifts by
11418 ;; zero don't affect the flags. We assume that shifts by constant
11419 ;; zero are optimized away.
11420 (define_insn "*ashrsi3_one_bit_cmp"
11421 [(set (reg 17)
11422 (compare
11423 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11424 (match_operand:QI 2 "const_int_1_operand" ""))
11425 (const_int 0)))
11426 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11427 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11428 "ix86_match_ccmode (insn, CCGOCmode)
11429 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11430 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11431 "sar{l}\t%0"
11432 [(set_attr "type" "ishift")
11433 (set (attr "length")
11434 (if_then_else (match_operand:SI 0 "register_operand" "")
11435 (const_string "2")
11436 (const_string "*")))])
11437
11438 (define_insn "*ashrsi3_one_bit_cmp_zext"
11439 [(set (reg 17)
11440 (compare
11441 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11442 (match_operand:QI 2 "const_int_1_operand" ""))
11443 (const_int 0)))
11444 (set (match_operand:DI 0 "register_operand" "=r")
11445 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11447 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11448 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11449 "sar{l}\t%k0"
11450 [(set_attr "type" "ishift")
11451 (set_attr "length" "2")])
11452
11453 ;; This pattern can't accept a variable shift count, since shifts by
11454 ;; zero don't affect the flags. We assume that shifts by constant
11455 ;; zero are optimized away.
11456 (define_insn "*ashrsi3_cmp"
11457 [(set (reg 17)
11458 (compare
11459 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11460 (match_operand:QI 2 "immediate_operand" "I"))
11461 (const_int 0)))
11462 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11463 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11464 "ix86_match_ccmode (insn, CCGOCmode)
11465 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11466 "sar{l}\t{%2, %0|%0, %2}"
11467 [(set_attr "type" "ishift")
11468 (set_attr "mode" "SI")])
11469
11470 (define_insn "*ashrsi3_cmp_zext"
11471 [(set (reg 17)
11472 (compare
11473 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11474 (match_operand:QI 2 "immediate_operand" "I"))
11475 (const_int 0)))
11476 (set (match_operand:DI 0 "register_operand" "=r")
11477 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11478 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11479 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11480 "sar{l}\t{%2, %k0|%k0, %2}"
11481 [(set_attr "type" "ishift")
11482 (set_attr "mode" "SI")])
11483
11484 (define_expand "ashrhi3"
11485 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11486 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11487 (match_operand:QI 2 "nonmemory_operand" "")))
11488 (clobber (reg:CC 17))]
11489 "TARGET_HIMODE_MATH"
11490 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11491
11492 (define_insn "*ashrhi3_1_one_bit"
11493 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11494 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11495 (match_operand:QI 2 "const_int_1_operand" "")))
11496 (clobber (reg:CC 17))]
11497 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11498 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11499 "sar{w}\t%0"
11500 [(set_attr "type" "ishift")
11501 (set (attr "length")
11502 (if_then_else (match_operand 0 "register_operand" "")
11503 (const_string "2")
11504 (const_string "*")))])
11505
11506 (define_insn "*ashrhi3_1"
11507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11508 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11509 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11510 (clobber (reg:CC 17))]
11511 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11512 "@
11513 sar{w}\t{%2, %0|%0, %2}
11514 sar{w}\t{%b2, %0|%0, %b2}"
11515 [(set_attr "type" "ishift")
11516 (set_attr "mode" "HI")])
11517
11518 ;; This pattern can't accept a variable shift count, since shifts by
11519 ;; zero don't affect the flags. We assume that shifts by constant
11520 ;; zero are optimized away.
11521 (define_insn "*ashrhi3_one_bit_cmp"
11522 [(set (reg 17)
11523 (compare
11524 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11525 (match_operand:QI 2 "const_int_1_operand" ""))
11526 (const_int 0)))
11527 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11528 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11529 "ix86_match_ccmode (insn, CCGOCmode)
11530 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11531 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11532 "sar{w}\t%0"
11533 [(set_attr "type" "ishift")
11534 (set (attr "length")
11535 (if_then_else (match_operand 0 "register_operand" "")
11536 (const_string "2")
11537 (const_string "*")))])
11538
11539 ;; This pattern can't accept a variable shift count, since shifts by
11540 ;; zero don't affect the flags. We assume that shifts by constant
11541 ;; zero are optimized away.
11542 (define_insn "*ashrhi3_cmp"
11543 [(set (reg 17)
11544 (compare
11545 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11546 (match_operand:QI 2 "immediate_operand" "I"))
11547 (const_int 0)))
11548 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11549 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11550 "ix86_match_ccmode (insn, CCGOCmode)
11551 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11552 "sar{w}\t{%2, %0|%0, %2}"
11553 [(set_attr "type" "ishift")
11554 (set_attr "mode" "HI")])
11555
11556 (define_expand "ashrqi3"
11557 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11558 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11559 (match_operand:QI 2 "nonmemory_operand" "")))
11560 (clobber (reg:CC 17))]
11561 "TARGET_QIMODE_MATH"
11562 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11563
11564 (define_insn "*ashrqi3_1_one_bit"
11565 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11566 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11567 (match_operand:QI 2 "const_int_1_operand" "")))
11568 (clobber (reg:CC 17))]
11569 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11570 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11571 "sar{b}\t%0"
11572 [(set_attr "type" "ishift")
11573 (set (attr "length")
11574 (if_then_else (match_operand 0 "register_operand" "")
11575 (const_string "2")
11576 (const_string "*")))])
11577
11578 (define_insn "*ashrqi3_1"
11579 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11580 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11581 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11582 (clobber (reg:CC 17))]
11583 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584 "@
11585 sar{b}\t{%2, %0|%0, %2}
11586 sar{b}\t{%b2, %0|%0, %b2}"
11587 [(set_attr "type" "ishift")
11588 (set_attr "mode" "QI")])
11589
11590 ;; This pattern can't accept a variable shift count, since shifts by
11591 ;; zero don't affect the flags. We assume that shifts by constant
11592 ;; zero are optimized away.
11593 (define_insn "*ashrqi3_one_bit_cmp"
11594 [(set (reg 17)
11595 (compare
11596 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11597 (match_operand:QI 2 "const_int_1_operand" "I"))
11598 (const_int 0)))
11599 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11600 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11601 "ix86_match_ccmode (insn, CCGOCmode)
11602 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11603 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11604 "sar{b}\t%0"
11605 [(set_attr "type" "ishift")
11606 (set (attr "length")
11607 (if_then_else (match_operand 0 "register_operand" "")
11608 (const_string "2")
11609 (const_string "*")))])
11610
11611 ;; This pattern can't accept a variable shift count, since shifts by
11612 ;; zero don't affect the flags. We assume that shifts by constant
11613 ;; zero are optimized away.
11614 (define_insn "*ashrqi3_cmp"
11615 [(set (reg 17)
11616 (compare
11617 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11618 (match_operand:QI 2 "immediate_operand" "I"))
11619 (const_int 0)))
11620 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11621 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11622 "ix86_match_ccmode (insn, CCGOCmode)
11623 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11624 "sar{b}\t{%2, %0|%0, %2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "mode" "QI")])
11627 \f
11628 ;; Logical shift instructions
11629
11630 ;; See comment above `ashldi3' about how this works.
11631
11632 (define_expand "lshrdi3"
11633 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11634 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11635 (match_operand:QI 2 "nonmemory_operand" "")))
11636 (clobber (reg:CC 17))])]
11637 ""
11638 {
11639 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11640 {
11641 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11642 DONE;
11643 }
11644 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11645 DONE;
11646 })
11647
11648 (define_insn "*lshrdi3_1_one_bit_rex64"
11649 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11650 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const_int_1_operand" "")))
11652 (clobber (reg:CC 17))]
11653 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11654 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11655 "shr{q}\t%0"
11656 [(set_attr "type" "ishift")
11657 (set (attr "length")
11658 (if_then_else (match_operand:DI 0 "register_operand" "")
11659 (const_string "2")
11660 (const_string "*")))])
11661
11662 (define_insn "*lshrdi3_1_rex64"
11663 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11664 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11665 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11666 (clobber (reg:CC 17))]
11667 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11668 "@
11669 shr{q}\t{%2, %0|%0, %2}
11670 shr{q}\t{%b2, %0|%0, %b2}"
11671 [(set_attr "type" "ishift")
11672 (set_attr "mode" "DI")])
11673
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags. We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11678 [(set (reg 17)
11679 (compare
11680 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11681 (match_operand:QI 2 "const_int_1_operand" ""))
11682 (const_int 0)))
11683 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11685 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11686 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11687 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11688 "shr{q}\t%0"
11689 [(set_attr "type" "ishift")
11690 (set (attr "length")
11691 (if_then_else (match_operand:DI 0 "register_operand" "")
11692 (const_string "2")
11693 (const_string "*")))])
11694
11695 ;; This pattern can't accept a variable shift count, since shifts by
11696 ;; zero don't affect the flags. We assume that shifts by constant
11697 ;; zero are optimized away.
11698 (define_insn "*lshrdi3_cmp_rex64"
11699 [(set (reg 17)
11700 (compare
11701 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11702 (match_operand:QI 2 "const_int_operand" "e"))
11703 (const_int 0)))
11704 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11705 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11706 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11707 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11708 "shr{q}\t{%2, %0|%0, %2}"
11709 [(set_attr "type" "ishift")
11710 (set_attr "mode" "DI")])
11711
11712 (define_insn "lshrdi3_1"
11713 [(set (match_operand:DI 0 "register_operand" "=r")
11714 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11715 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11716 (clobber (match_scratch:SI 3 "=&r"))
11717 (clobber (reg:CC 17))]
11718 "!TARGET_64BIT && TARGET_CMOVE"
11719 "#"
11720 [(set_attr "type" "multi")])
11721
11722 (define_insn "*lshrdi3_2"
11723 [(set (match_operand:DI 0 "register_operand" "=r")
11724 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11725 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11726 (clobber (reg:CC 17))]
11727 "!TARGET_64BIT"
11728 "#"
11729 [(set_attr "type" "multi")])
11730
11731 (define_split
11732 [(set (match_operand:DI 0 "register_operand" "")
11733 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11734 (match_operand:QI 2 "nonmemory_operand" "")))
11735 (clobber (match_scratch:SI 3 ""))
11736 (clobber (reg:CC 17))]
11737 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11738 [(const_int 0)]
11739 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11740
11741 (define_split
11742 [(set (match_operand:DI 0 "register_operand" "")
11743 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11744 (match_operand:QI 2 "nonmemory_operand" "")))
11745 (clobber (reg:CC 17))]
11746 "!TARGET_64BIT && reload_completed"
11747 [(const_int 0)]
11748 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11749
11750 (define_expand "lshrsi3"
11751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (reg:CC 17))]
11755 ""
11756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11757
11758 (define_insn "*lshrsi3_1_one_bit"
11759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const_int_1_operand" "")))
11762 (clobber (reg:CC 17))]
11763 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11765 "shr{l}\t%0"
11766 [(set_attr "type" "ishift")
11767 (set (attr "length")
11768 (if_then_else (match_operand:SI 0 "register_operand" "")
11769 (const_string "2")
11770 (const_string "*")))])
11771
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773 [(set (match_operand:DI 0 "register_operand" "=r")
11774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775 (match_operand:QI 2 "const_int_1_operand" "")))
11776 (clobber (reg:CC 17))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11779 "shr{l}\t%k0"
11780 [(set_attr "type" "ishift")
11781 (set_attr "length" "2")])
11782
11783 (define_insn "*lshrsi3_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787 (clobber (reg:CC 17))]
11788 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789 "@
11790 shr{l}\t{%2, %0|%0, %2}
11791 shr{l}\t{%b2, %0|%0, %b2}"
11792 [(set_attr "type" "ishift")
11793 (set_attr "mode" "SI")])
11794
11795 (define_insn "*lshrsi3_1_zext"
11796 [(set (match_operand:DI 0 "register_operand" "=r,r")
11797 (zero_extend:DI
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800 (clobber (reg:CC 17))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802 "@
11803 shr{l}\t{%2, %k0|%k0, %2}
11804 shr{l}\t{%b2, %k0|%k0, %b2}"
11805 [(set_attr "type" "ishift")
11806 (set_attr "mode" "SI")])
11807
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags. We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812 [(set (reg 17)
11813 (compare
11814 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const_int_1_operand" ""))
11816 (const_int 0)))
11817 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819 "ix86_match_ccmode (insn, CCGOCmode)
11820 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822 "shr{l}\t%0"
11823 [(set_attr "type" "ishift")
11824 (set (attr "length")
11825 (if_then_else (match_operand:SI 0 "register_operand" "")
11826 (const_string "2")
11827 (const_string "*")))])
11828
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830 [(set (reg 17)
11831 (compare
11832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833 (match_operand:QI 2 "const_int_1_operand" ""))
11834 (const_int 0)))
11835 (set (match_operand:DI 0 "register_operand" "=r")
11836 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840 "shr{l}\t%k0"
11841 [(set_attr "type" "ishift")
11842 (set_attr "length" "2")])
11843
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags. We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848 [(set (reg 17)
11849 (compare
11850 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "immediate_operand" "I"))
11852 (const_int 0)))
11853 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855 "ix86_match_ccmode (insn, CCGOCmode)
11856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857 "shr{l}\t{%2, %0|%0, %2}"
11858 [(set_attr "type" "ishift")
11859 (set_attr "mode" "SI")])
11860
11861 (define_insn "*lshrsi3_cmp_zext"
11862 [(set (reg 17)
11863 (compare
11864 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865 (match_operand:QI 2 "immediate_operand" "I"))
11866 (const_int 0)))
11867 (set (match_operand:DI 0 "register_operand" "=r")
11868 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871 "shr{l}\t{%2, %k0|%k0, %2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "SI")])
11874
11875 (define_expand "lshrhi3"
11876 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878 (match_operand:QI 2 "nonmemory_operand" "")))
11879 (clobber (reg:CC 17))]
11880 "TARGET_HIMODE_MATH"
11881 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11882
11883 (define_insn "*lshrhi3_1_one_bit"
11884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const_int_1_operand" "")))
11887 (clobber (reg:CC 17))]
11888 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11890 "shr{w}\t%0"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand 0 "register_operand" "")
11894 (const_string "2")
11895 (const_string "*")))])
11896
11897 (define_insn "*lshrhi3_1"
11898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901 (clobber (reg:CC 17))]
11902 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11903 "@
11904 shr{w}\t{%2, %0|%0, %2}
11905 shr{w}\t{%b2, %0|%0, %b2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913 [(set (reg 17)
11914 (compare
11915 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const_int_1_operand" ""))
11917 (const_int 0)))
11918 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920 "ix86_match_ccmode (insn, CCGOCmode)
11921 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11923 "shr{w}\t%0"
11924 [(set_attr "type" "ishift")
11925 (set (attr "length")
11926 (if_then_else (match_operand:SI 0 "register_operand" "")
11927 (const_string "2")
11928 (const_string "*")))])
11929
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags. We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934 [(set (reg 17)
11935 (compare
11936 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "immediate_operand" "I"))
11938 (const_int 0)))
11939 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941 "ix86_match_ccmode (insn, CCGOCmode)
11942 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943 "shr{w}\t{%2, %0|%0, %2}"
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "HI")])
11946
11947 (define_expand "lshrqi3"
11948 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950 (match_operand:QI 2 "nonmemory_operand" "")))
11951 (clobber (reg:CC 17))]
11952 "TARGET_QIMODE_MATH"
11953 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11954
11955 (define_insn "*lshrqi3_1_one_bit"
11956 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958 (match_operand:QI 2 "const_int_1_operand" "")))
11959 (clobber (reg:CC 17))]
11960 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11962 "shr{b}\t%0"
11963 [(set_attr "type" "ishift")
11964 (set (attr "length")
11965 (if_then_else (match_operand 0 "register_operand" "")
11966 (const_string "2")
11967 (const_string "*")))])
11968
11969 (define_insn "*lshrqi3_1"
11970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11971 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11973 (clobber (reg:CC 17))]
11974 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11975 "@
11976 shr{b}\t{%2, %0|%0, %2}
11977 shr{b}\t{%b2, %0|%0, %b2}"
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "QI")])
11980
11981 ;; This pattern can't accept a variable shift count, since shifts by
11982 ;; zero don't affect the flags. We assume that shifts by constant
11983 ;; zero are optimized away.
11984 (define_insn "*lshrqi2_one_bit_cmp"
11985 [(set (reg 17)
11986 (compare
11987 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11988 (match_operand:QI 2 "const_int_1_operand" ""))
11989 (const_int 0)))
11990 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11991 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11992 "ix86_match_ccmode (insn, CCGOCmode)
11993 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11994 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11995 "shr{b}\t%0"
11996 [(set_attr "type" "ishift")
11997 (set (attr "length")
11998 (if_then_else (match_operand:SI 0 "register_operand" "")
11999 (const_string "2")
12000 (const_string "*")))])
12001
12002 ;; This pattern can't accept a variable shift count, since shifts by
12003 ;; zero don't affect the flags. We assume that shifts by constant
12004 ;; zero are optimized away.
12005 (define_insn "*lshrqi2_cmp"
12006 [(set (reg 17)
12007 (compare
12008 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "immediate_operand" "I"))
12010 (const_int 0)))
12011 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12012 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12013 "ix86_match_ccmode (insn, CCGOCmode)
12014 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12015 "shr{b}\t{%2, %0|%0, %2}"
12016 [(set_attr "type" "ishift")
12017 (set_attr "mode" "QI")])
12018 \f
12019 ;; Rotate instructions
12020
12021 (define_expand "rotldi3"
12022 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12023 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12024 (match_operand:QI 2 "nonmemory_operand" "")))
12025 (clobber (reg:CC 17))]
12026 "TARGET_64BIT"
12027 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12028
12029 (define_insn "*rotlsi3_1_one_bit_rex64"
12030 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12031 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12032 (match_operand:QI 2 "const_int_1_operand" "")))
12033 (clobber (reg:CC 17))]
12034 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12035 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12036 "rol{q}\t%0"
12037 [(set_attr "type" "ishift")
12038 (set (attr "length")
12039 (if_then_else (match_operand:DI 0 "register_operand" "")
12040 (const_string "2")
12041 (const_string "*")))])
12042
12043 (define_insn "*rotldi3_1_rex64"
12044 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12045 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12046 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12047 (clobber (reg:CC 17))]
12048 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12049 "@
12050 rol{q}\t{%2, %0|%0, %2}
12051 rol{q}\t{%b2, %0|%0, %b2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "DI")])
12054
12055 (define_expand "rotlsi3"
12056 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12057 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12058 (match_operand:QI 2 "nonmemory_operand" "")))
12059 (clobber (reg:CC 17))]
12060 ""
12061 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12062
12063 (define_insn "*rotlsi3_1_one_bit"
12064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12065 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12066 (match_operand:QI 2 "const_int_1_operand" "")))
12067 (clobber (reg:CC 17))]
12068 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12069 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12070 "rol{l}\t%0"
12071 [(set_attr "type" "ishift")
12072 (set (attr "length")
12073 (if_then_else (match_operand:SI 0 "register_operand" "")
12074 (const_string "2")
12075 (const_string "*")))])
12076
12077 (define_insn "*rotlsi3_1_one_bit_zext"
12078 [(set (match_operand:DI 0 "register_operand" "=r")
12079 (zero_extend:DI
12080 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12081 (match_operand:QI 2 "const_int_1_operand" ""))))
12082 (clobber (reg:CC 17))]
12083 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12084 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12085 "rol{l}\t%k0"
12086 [(set_attr "type" "ishift")
12087 (set_attr "length" "2")])
12088
12089 (define_insn "*rotlsi3_1"
12090 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12091 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093 (clobber (reg:CC 17))]
12094 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12095 "@
12096 rol{l}\t{%2, %0|%0, %2}
12097 rol{l}\t{%b2, %0|%0, %b2}"
12098 [(set_attr "type" "ishift")
12099 (set_attr "mode" "SI")])
12100
12101 (define_insn "*rotlsi3_1_zext"
12102 [(set (match_operand:DI 0 "register_operand" "=r,r")
12103 (zero_extend:DI
12104 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12105 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12106 (clobber (reg:CC 17))]
12107 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12108 "@
12109 rol{l}\t{%2, %k0|%k0, %2}
12110 rol{l}\t{%b2, %k0|%k0, %b2}"
12111 [(set_attr "type" "ishift")
12112 (set_attr "mode" "SI")])
12113
12114 (define_expand "rotlhi3"
12115 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12116 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))
12118 (clobber (reg:CC 17))]
12119 "TARGET_HIMODE_MATH"
12120 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12121
12122 (define_insn "*rotlhi3_1_one_bit"
12123 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12124 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12125 (match_operand:QI 2 "const_int_1_operand" "")))
12126 (clobber (reg:CC 17))]
12127 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12128 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12129 "rol{w}\t%0"
12130 [(set_attr "type" "ishift")
12131 (set (attr "length")
12132 (if_then_else (match_operand 0 "register_operand" "")
12133 (const_string "2")
12134 (const_string "*")))])
12135
12136 (define_insn "*rotlhi3_1"
12137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12138 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140 (clobber (reg:CC 17))]
12141 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12142 "@
12143 rol{w}\t{%2, %0|%0, %2}
12144 rol{w}\t{%b2, %0|%0, %b2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "HI")])
12147
12148 (define_expand "rotlqi3"
12149 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12150 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))
12152 (clobber (reg:CC 17))]
12153 "TARGET_QIMODE_MATH"
12154 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12155
12156 (define_insn "*rotlqi3_1_one_bit"
12157 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12158 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12159 (match_operand:QI 2 "const_int_1_operand" "")))
12160 (clobber (reg:CC 17))]
12161 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12162 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12163 "rol{b}\t%0"
12164 [(set_attr "type" "ishift")
12165 (set (attr "length")
12166 (if_then_else (match_operand 0 "register_operand" "")
12167 (const_string "2")
12168 (const_string "*")))])
12169
12170 (define_insn "*rotlqi3_1"
12171 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12172 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC 17))]
12175 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12176 "@
12177 rol{b}\t{%2, %0|%0, %2}
12178 rol{b}\t{%b2, %0|%0, %b2}"
12179 [(set_attr "type" "ishift")
12180 (set_attr "mode" "QI")])
12181
12182 (define_expand "rotrdi3"
12183 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12184 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12185 (match_operand:QI 2 "nonmemory_operand" "")))
12186 (clobber (reg:CC 17))]
12187 "TARGET_64BIT"
12188 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12189
12190 (define_insn "*rotrdi3_1_one_bit_rex64"
12191 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12192 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12193 (match_operand:QI 2 "const_int_1_operand" "")))
12194 (clobber (reg:CC 17))]
12195 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12196 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12197 "ror{q}\t%0"
12198 [(set_attr "type" "ishift")
12199 (set (attr "length")
12200 (if_then_else (match_operand:DI 0 "register_operand" "")
12201 (const_string "2")
12202 (const_string "*")))])
12203
12204 (define_insn "*rotrdi3_1_rex64"
12205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12206 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12207 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12208 (clobber (reg:CC 17))]
12209 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12210 "@
12211 ror{q}\t{%2, %0|%0, %2}
12212 ror{q}\t{%b2, %0|%0, %b2}"
12213 [(set_attr "type" "ishift")
12214 (set_attr "mode" "DI")])
12215
12216 (define_expand "rotrsi3"
12217 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12218 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12219 (match_operand:QI 2 "nonmemory_operand" "")))
12220 (clobber (reg:CC 17))]
12221 ""
12222 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12223
12224 (define_insn "*rotrsi3_1_one_bit"
12225 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12226 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227 (match_operand:QI 2 "const_int_1_operand" "")))
12228 (clobber (reg:CC 17))]
12229 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12230 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12231 "ror{l}\t%0"
12232 [(set_attr "type" "ishift")
12233 (set (attr "length")
12234 (if_then_else (match_operand:SI 0 "register_operand" "")
12235 (const_string "2")
12236 (const_string "*")))])
12237
12238 (define_insn "*rotrsi3_1_one_bit_zext"
12239 [(set (match_operand:DI 0 "register_operand" "=r")
12240 (zero_extend:DI
12241 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12242 (match_operand:QI 2 "const_int_1_operand" ""))))
12243 (clobber (reg:CC 17))]
12244 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12245 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12246 "ror{l}\t%k0"
12247 [(set_attr "type" "ishift")
12248 (set (attr "length")
12249 (if_then_else (match_operand:SI 0 "register_operand" "")
12250 (const_string "2")
12251 (const_string "*")))])
12252
12253 (define_insn "*rotrsi3_1"
12254 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12255 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12256 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12257 (clobber (reg:CC 17))]
12258 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12259 "@
12260 ror{l}\t{%2, %0|%0, %2}
12261 ror{l}\t{%b2, %0|%0, %b2}"
12262 [(set_attr "type" "ishift")
12263 (set_attr "mode" "SI")])
12264
12265 (define_insn "*rotrsi3_1_zext"
12266 [(set (match_operand:DI 0 "register_operand" "=r,r")
12267 (zero_extend:DI
12268 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12269 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12270 (clobber (reg:CC 17))]
12271 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12272 "@
12273 ror{l}\t{%2, %k0|%k0, %2}
12274 ror{l}\t{%b2, %k0|%k0, %b2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "SI")])
12277
12278 (define_expand "rotrhi3"
12279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12280 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12281 (match_operand:QI 2 "nonmemory_operand" "")))
12282 (clobber (reg:CC 17))]
12283 "TARGET_HIMODE_MATH"
12284 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12285
12286 (define_insn "*rotrhi3_one_bit"
12287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12288 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12289 (match_operand:QI 2 "const_int_1_operand" "")))
12290 (clobber (reg:CC 17))]
12291 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12292 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12293 "ror{w}\t%0"
12294 [(set_attr "type" "ishift")
12295 (set (attr "length")
12296 (if_then_else (match_operand 0 "register_operand" "")
12297 (const_string "2")
12298 (const_string "*")))])
12299
12300 (define_insn "*rotrhi3"
12301 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12302 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12303 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12304 (clobber (reg:CC 17))]
12305 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12306 "@
12307 ror{w}\t{%2, %0|%0, %2}
12308 ror{w}\t{%b2, %0|%0, %b2}"
12309 [(set_attr "type" "ishift")
12310 (set_attr "mode" "HI")])
12311
12312 (define_expand "rotrqi3"
12313 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12314 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12315 (match_operand:QI 2 "nonmemory_operand" "")))
12316 (clobber (reg:CC 17))]
12317 "TARGET_QIMODE_MATH"
12318 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12319
12320 (define_insn "*rotrqi3_1_one_bit"
12321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12322 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_int_1_operand" "")))
12324 (clobber (reg:CC 17))]
12325 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12326 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12327 "ror{b}\t%0"
12328 [(set_attr "type" "ishift")
12329 (set (attr "length")
12330 (if_then_else (match_operand 0 "register_operand" "")
12331 (const_string "2")
12332 (const_string "*")))])
12333
12334 (define_insn "*rotrqi3_1"
12335 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12336 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12337 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12338 (clobber (reg:CC 17))]
12339 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12340 "@
12341 ror{b}\t{%2, %0|%0, %2}
12342 ror{b}\t{%b2, %0|%0, %b2}"
12343 [(set_attr "type" "ishift")
12344 (set_attr "mode" "QI")])
12345 \f
12346 ;; Bit set / bit test instructions
12347
12348 (define_expand "extv"
12349 [(set (match_operand:SI 0 "register_operand" "")
12350 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12351 (match_operand:SI 2 "immediate_operand" "")
12352 (match_operand:SI 3 "immediate_operand" "")))]
12353 ""
12354 {
12355 /* Handle extractions from %ah et al. */
12356 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12357 FAIL;
12358
12359 /* From mips.md: extract_bit_field doesn't verify that our source
12360 matches the predicate, so check it again here. */
12361 if (! register_operand (operands[1], VOIDmode))
12362 FAIL;
12363 })
12364
12365 (define_expand "extzv"
12366 [(set (match_operand:SI 0 "register_operand" "")
12367 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12368 (match_operand:SI 2 "immediate_operand" "")
12369 (match_operand:SI 3 "immediate_operand" "")))]
12370 ""
12371 {
12372 /* Handle extractions from %ah et al. */
12373 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12374 FAIL;
12375
12376 /* From mips.md: extract_bit_field doesn't verify that our source
12377 matches the predicate, so check it again here. */
12378 if (! register_operand (operands[1], VOIDmode))
12379 FAIL;
12380 })
12381
12382 (define_expand "insv"
12383 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12384 (match_operand:SI 1 "immediate_operand" "")
12385 (match_operand:SI 2 "immediate_operand" ""))
12386 (match_operand:SI 3 "register_operand" ""))]
12387 ""
12388 {
12389 /* Handle extractions from %ah et al. */
12390 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12391 FAIL;
12392
12393 /* From mips.md: insert_bit_field doesn't verify that our source
12394 matches the predicate, so check it again here. */
12395 if (! register_operand (operands[0], VOIDmode))
12396 FAIL;
12397 })
12398
12399 ;; %%% bts, btr, btc, bt.
12400 \f
12401 ;; Store-flag instructions.
12402
12403 ;; For all sCOND expanders, also expand the compare or test insn that
12404 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12405
12406 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12407 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12408 ;; way, which can later delete the movzx if only QImode is needed.
12409
12410 (define_expand "seq"
12411 [(set (match_operand:SI 0 "register_operand" "")
12412 (eq:SI (reg:CC 17) (const_int 0)))]
12413 ""
12414 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12415
12416 (define_expand "sne"
12417 [(set (match_operand:SI 0 "register_operand" "")
12418 (ne:SI (reg:CC 17) (const_int 0)))]
12419 ""
12420 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12421
12422 (define_expand "sgt"
12423 [(set (match_operand:SI 0 "register_operand" "")
12424 (gt:SI (reg:CC 17) (const_int 0)))]
12425 ""
12426 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12427
12428 (define_expand "sgtu"
12429 [(set (match_operand:SI 0 "register_operand" "")
12430 (gtu:SI (reg:CC 17) (const_int 0)))]
12431 ""
12432 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12433
12434 (define_expand "slt"
12435 [(set (match_operand:SI 0 "register_operand" "")
12436 (lt:SI (reg:CC 17) (const_int 0)))]
12437 ""
12438 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12439
12440 (define_expand "sltu"
12441 [(set (match_operand:SI 0 "register_operand" "")
12442 (ltu:SI (reg:CC 17) (const_int 0)))]
12443 ""
12444 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12445
12446 (define_expand "sge"
12447 [(set (match_operand:SI 0 "register_operand" "")
12448 (ge:SI (reg:CC 17) (const_int 0)))]
12449 ""
12450 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12451
12452 (define_expand "sgeu"
12453 [(set (match_operand:SI 0 "register_operand" "")
12454 (geu:SI (reg:CC 17) (const_int 0)))]
12455 ""
12456 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12457
12458 (define_expand "sle"
12459 [(set (match_operand:SI 0 "register_operand" "")
12460 (le:SI (reg:CC 17) (const_int 0)))]
12461 ""
12462 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12463
12464 (define_expand "sleu"
12465 [(set (match_operand:SI 0 "register_operand" "")
12466 (leu:SI (reg:CC 17) (const_int 0)))]
12467 ""
12468 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12469
12470 (define_expand "sunordered"
12471 [(set (match_operand:SI 0 "register_operand" "")
12472 (unordered:SI (reg:CC 17) (const_int 0)))]
12473 "TARGET_80387 || TARGET_SSE"
12474 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12475
12476 (define_expand "sordered"
12477 [(set (match_operand:SI 0 "register_operand" "")
12478 (ordered:SI (reg:CC 17) (const_int 0)))]
12479 "TARGET_80387"
12480 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12481
12482 (define_expand "suneq"
12483 [(set (match_operand:SI 0 "register_operand" "")
12484 (uneq:SI (reg:CC 17) (const_int 0)))]
12485 "TARGET_80387 || TARGET_SSE"
12486 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12487
12488 (define_expand "sunge"
12489 [(set (match_operand:SI 0 "register_operand" "")
12490 (unge:SI (reg:CC 17) (const_int 0)))]
12491 "TARGET_80387 || TARGET_SSE"
12492 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12493
12494 (define_expand "sungt"
12495 [(set (match_operand:SI 0 "register_operand" "")
12496 (ungt:SI (reg:CC 17) (const_int 0)))]
12497 "TARGET_80387 || TARGET_SSE"
12498 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12499
12500 (define_expand "sunle"
12501 [(set (match_operand:SI 0 "register_operand" "")
12502 (unle:SI (reg:CC 17) (const_int 0)))]
12503 "TARGET_80387 || TARGET_SSE"
12504 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12505
12506 (define_expand "sunlt"
12507 [(set (match_operand:SI 0 "register_operand" "")
12508 (unlt:SI (reg:CC 17) (const_int 0)))]
12509 "TARGET_80387 || TARGET_SSE"
12510 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12511
12512 (define_expand "sltgt"
12513 [(set (match_operand:SI 0 "register_operand" "")
12514 (ltgt:SI (reg:CC 17) (const_int 0)))]
12515 "TARGET_80387 || TARGET_SSE"
12516 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12517
12518 (define_insn "*setcc_1"
12519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12520 (match_operator:QI 1 "ix86_comparison_operator"
12521 [(reg 17) (const_int 0)]))]
12522 ""
12523 "set%C1\t%0"
12524 [(set_attr "type" "setcc")
12525 (set_attr "mode" "QI")])
12526
12527 (define_insn "setcc_2"
12528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12529 (match_operator:QI 1 "ix86_comparison_operator"
12530 [(reg 17) (const_int 0)]))]
12531 ""
12532 "set%C1\t%0"
12533 [(set_attr "type" "setcc")
12534 (set_attr "mode" "QI")])
12535
12536 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12537 ;; subsequent logical operations are used to imitate conditional moves.
12538 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12539 ;; it directly. Futher holding this value in pseudo register might bring
12540 ;; problem in implicit normalization in spill code.
12541 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12542 ;; instructions after reload by splitting the conditional move patterns.
12543
12544 (define_insn "*sse_setccsf"
12545 [(set (match_operand:SF 0 "register_operand" "=x")
12546 (match_operator:SF 1 "sse_comparison_operator"
12547 [(match_operand:SF 2 "register_operand" "0")
12548 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12549 "TARGET_SSE && reload_completed"
12550 "cmp%D1ss\t{%3, %0|%0, %3}"
12551 [(set_attr "type" "sse")
12552 (set_attr "mode" "SF")])
12553
12554 (define_insn "*sse_setccdf"
12555 [(set (match_operand:DF 0 "register_operand" "=Y")
12556 (match_operator:DF 1 "sse_comparison_operator"
12557 [(match_operand:DF 2 "register_operand" "0")
12558 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12559 "TARGET_SSE2 && reload_completed"
12560 "cmp%D1sd\t{%3, %0|%0, %3}"
12561 [(set_attr "type" "sse")
12562 (set_attr "mode" "DF")])
12563 \f
12564 ;; Basic conditional jump instructions.
12565 ;; We ignore the overflow flag for signed branch instructions.
12566
12567 ;; For all bCOND expanders, also expand the compare or test insn that
12568 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12569
12570 (define_expand "beq"
12571 [(set (pc)
12572 (if_then_else (match_dup 1)
12573 (label_ref (match_operand 0 "" ""))
12574 (pc)))]
12575 ""
12576 "ix86_expand_branch (EQ, operands[0]); DONE;")
12577
12578 (define_expand "bne"
12579 [(set (pc)
12580 (if_then_else (match_dup 1)
12581 (label_ref (match_operand 0 "" ""))
12582 (pc)))]
12583 ""
12584 "ix86_expand_branch (NE, operands[0]); DONE;")
12585
12586 (define_expand "bgt"
12587 [(set (pc)
12588 (if_then_else (match_dup 1)
12589 (label_ref (match_operand 0 "" ""))
12590 (pc)))]
12591 ""
12592 "ix86_expand_branch (GT, operands[0]); DONE;")
12593
12594 (define_expand "bgtu"
12595 [(set (pc)
12596 (if_then_else (match_dup 1)
12597 (label_ref (match_operand 0 "" ""))
12598 (pc)))]
12599 ""
12600 "ix86_expand_branch (GTU, operands[0]); DONE;")
12601
12602 (define_expand "blt"
12603 [(set (pc)
12604 (if_then_else (match_dup 1)
12605 (label_ref (match_operand 0 "" ""))
12606 (pc)))]
12607 ""
12608 "ix86_expand_branch (LT, operands[0]); DONE;")
12609
12610 (define_expand "bltu"
12611 [(set (pc)
12612 (if_then_else (match_dup 1)
12613 (label_ref (match_operand 0 "" ""))
12614 (pc)))]
12615 ""
12616 "ix86_expand_branch (LTU, operands[0]); DONE;")
12617
12618 (define_expand "bge"
12619 [(set (pc)
12620 (if_then_else (match_dup 1)
12621 (label_ref (match_operand 0 "" ""))
12622 (pc)))]
12623 ""
12624 "ix86_expand_branch (GE, operands[0]); DONE;")
12625
12626 (define_expand "bgeu"
12627 [(set (pc)
12628 (if_then_else (match_dup 1)
12629 (label_ref (match_operand 0 "" ""))
12630 (pc)))]
12631 ""
12632 "ix86_expand_branch (GEU, operands[0]); DONE;")
12633
12634 (define_expand "ble"
12635 [(set (pc)
12636 (if_then_else (match_dup 1)
12637 (label_ref (match_operand 0 "" ""))
12638 (pc)))]
12639 ""
12640 "ix86_expand_branch (LE, operands[0]); DONE;")
12641
12642 (define_expand "bleu"
12643 [(set (pc)
12644 (if_then_else (match_dup 1)
12645 (label_ref (match_operand 0 "" ""))
12646 (pc)))]
12647 ""
12648 "ix86_expand_branch (LEU, operands[0]); DONE;")
12649
12650 (define_expand "bunordered"
12651 [(set (pc)
12652 (if_then_else (match_dup 1)
12653 (label_ref (match_operand 0 "" ""))
12654 (pc)))]
12655 "TARGET_80387 || TARGET_SSE"
12656 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12657
12658 (define_expand "bordered"
12659 [(set (pc)
12660 (if_then_else (match_dup 1)
12661 (label_ref (match_operand 0 "" ""))
12662 (pc)))]
12663 "TARGET_80387 || TARGET_SSE"
12664 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12665
12666 (define_expand "buneq"
12667 [(set (pc)
12668 (if_then_else (match_dup 1)
12669 (label_ref (match_operand 0 "" ""))
12670 (pc)))]
12671 "TARGET_80387 || TARGET_SSE"
12672 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12673
12674 (define_expand "bunge"
12675 [(set (pc)
12676 (if_then_else (match_dup 1)
12677 (label_ref (match_operand 0 "" ""))
12678 (pc)))]
12679 "TARGET_80387 || TARGET_SSE"
12680 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12681
12682 (define_expand "bungt"
12683 [(set (pc)
12684 (if_then_else (match_dup 1)
12685 (label_ref (match_operand 0 "" ""))
12686 (pc)))]
12687 "TARGET_80387 || TARGET_SSE"
12688 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12689
12690 (define_expand "bunle"
12691 [(set (pc)
12692 (if_then_else (match_dup 1)
12693 (label_ref (match_operand 0 "" ""))
12694 (pc)))]
12695 "TARGET_80387 || TARGET_SSE"
12696 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12697
12698 (define_expand "bunlt"
12699 [(set (pc)
12700 (if_then_else (match_dup 1)
12701 (label_ref (match_operand 0 "" ""))
12702 (pc)))]
12703 "TARGET_80387 || TARGET_SSE"
12704 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12705
12706 (define_expand "bltgt"
12707 [(set (pc)
12708 (if_then_else (match_dup 1)
12709 (label_ref (match_operand 0 "" ""))
12710 (pc)))]
12711 "TARGET_80387 || TARGET_SSE"
12712 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12713
12714 (define_insn "*jcc_1"
12715 [(set (pc)
12716 (if_then_else (match_operator 1 "ix86_comparison_operator"
12717 [(reg 17) (const_int 0)])
12718 (label_ref (match_operand 0 "" ""))
12719 (pc)))]
12720 ""
12721 "%+j%C1\t%l0"
12722 [(set_attr "type" "ibr")
12723 (set (attr "prefix_0f")
12724 (if_then_else (and (ge (minus (match_dup 0) (pc))
12725 (const_int -128))
12726 (lt (minus (match_dup 0) (pc))
12727 (const_int 124)))
12728 (const_int 0)
12729 (const_int 1)))])
12730
12731 (define_insn "*jcc_2"
12732 [(set (pc)
12733 (if_then_else (match_operator 1 "ix86_comparison_operator"
12734 [(reg 17) (const_int 0)])
12735 (pc)
12736 (label_ref (match_operand 0 "" ""))))]
12737 ""
12738 "%+j%c1\t%l0"
12739 [(set_attr "type" "ibr")
12740 (set (attr "prefix_0f")
12741 (if_then_else (and (ge (minus (match_dup 0) (pc))
12742 (const_int -128))
12743 (lt (minus (match_dup 0) (pc))
12744 (const_int 124)))
12745 (const_int 0)
12746 (const_int 1)))])
12747
12748 ;; Define combination compare-and-branch fp compare instructions to use
12749 ;; during early optimization. Splitting the operation apart early makes
12750 ;; for bad code when we want to reverse the operation.
12751
12752 (define_insn "*fp_jcc_1"
12753 [(set (pc)
12754 (if_then_else (match_operator 0 "comparison_operator"
12755 [(match_operand 1 "register_operand" "f")
12756 (match_operand 2 "register_operand" "f")])
12757 (label_ref (match_operand 3 "" ""))
12758 (pc)))
12759 (clobber (reg:CCFP 18))
12760 (clobber (reg:CCFP 17))]
12761 "TARGET_CMOVE && TARGET_80387
12762 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12763 && FLOAT_MODE_P (GET_MODE (operands[1]))
12764 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12765 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12766 "#")
12767
12768 (define_insn "*fp_jcc_1_sse"
12769 [(set (pc)
12770 (if_then_else (match_operator 0 "comparison_operator"
12771 [(match_operand 1 "register_operand" "f#x,x#f")
12772 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12773 (label_ref (match_operand 3 "" ""))
12774 (pc)))
12775 (clobber (reg:CCFP 18))
12776 (clobber (reg:CCFP 17))]
12777 "TARGET_80387
12778 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12779 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12780 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12781 "#")
12782
12783 (define_insn "*fp_jcc_1_sse_only"
12784 [(set (pc)
12785 (if_then_else (match_operator 0 "comparison_operator"
12786 [(match_operand 1 "register_operand" "x")
12787 (match_operand 2 "nonimmediate_operand" "xm")])
12788 (label_ref (match_operand 3 "" ""))
12789 (pc)))
12790 (clobber (reg:CCFP 18))
12791 (clobber (reg:CCFP 17))]
12792 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12793 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12794 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12795 "#")
12796
12797 (define_insn "*fp_jcc_2"
12798 [(set (pc)
12799 (if_then_else (match_operator 0 "comparison_operator"
12800 [(match_operand 1 "register_operand" "f")
12801 (match_operand 2 "register_operand" "f")])
12802 (pc)
12803 (label_ref (match_operand 3 "" ""))))
12804 (clobber (reg:CCFP 18))
12805 (clobber (reg:CCFP 17))]
12806 "TARGET_CMOVE && TARGET_80387
12807 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12808 && FLOAT_MODE_P (GET_MODE (operands[1]))
12809 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12810 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12811 "#")
12812
12813 (define_insn "*fp_jcc_2_sse"
12814 [(set (pc)
12815 (if_then_else (match_operator 0 "comparison_operator"
12816 [(match_operand 1 "register_operand" "f#x,x#f")
12817 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12818 (pc)
12819 (label_ref (match_operand 3 "" ""))))
12820 (clobber (reg:CCFP 18))
12821 (clobber (reg:CCFP 17))]
12822 "TARGET_80387
12823 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12826 "#")
12827
12828 (define_insn "*fp_jcc_2_sse_only"
12829 [(set (pc)
12830 (if_then_else (match_operator 0 "comparison_operator"
12831 [(match_operand 1 "register_operand" "x")
12832 (match_operand 2 "nonimmediate_operand" "xm")])
12833 (pc)
12834 (label_ref (match_operand 3 "" ""))))
12835 (clobber (reg:CCFP 18))
12836 (clobber (reg:CCFP 17))]
12837 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12838 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12839 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12840 "#")
12841
12842 (define_insn "*fp_jcc_3"
12843 [(set (pc)
12844 (if_then_else (match_operator 0 "comparison_operator"
12845 [(match_operand 1 "register_operand" "f")
12846 (match_operand 2 "nonimmediate_operand" "fm")])
12847 (label_ref (match_operand 3 "" ""))
12848 (pc)))
12849 (clobber (reg:CCFP 18))
12850 (clobber (reg:CCFP 17))
12851 (clobber (match_scratch:HI 4 "=a"))]
12852 "TARGET_80387
12853 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12854 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12855 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12856 && SELECT_CC_MODE (GET_CODE (operands[0]),
12857 operands[1], operands[2]) == CCFPmode
12858 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12859 "#")
12860
12861 (define_insn "*fp_jcc_4"
12862 [(set (pc)
12863 (if_then_else (match_operator 0 "comparison_operator"
12864 [(match_operand 1 "register_operand" "f")
12865 (match_operand 2 "nonimmediate_operand" "fm")])
12866 (pc)
12867 (label_ref (match_operand 3 "" ""))))
12868 (clobber (reg:CCFP 18))
12869 (clobber (reg:CCFP 17))
12870 (clobber (match_scratch:HI 4 "=a"))]
12871 "TARGET_80387
12872 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12873 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12874 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12875 && SELECT_CC_MODE (GET_CODE (operands[0]),
12876 operands[1], operands[2]) == CCFPmode
12877 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12878 "#")
12879
12880 (define_insn "*fp_jcc_5"
12881 [(set (pc)
12882 (if_then_else (match_operator 0 "comparison_operator"
12883 [(match_operand 1 "register_operand" "f")
12884 (match_operand 2 "register_operand" "f")])
12885 (label_ref (match_operand 3 "" ""))
12886 (pc)))
12887 (clobber (reg:CCFP 18))
12888 (clobber (reg:CCFP 17))
12889 (clobber (match_scratch:HI 4 "=a"))]
12890 "TARGET_80387
12891 && FLOAT_MODE_P (GET_MODE (operands[1]))
12892 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12893 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12894 "#")
12895
12896 (define_insn "*fp_jcc_6"
12897 [(set (pc)
12898 (if_then_else (match_operator 0 "comparison_operator"
12899 [(match_operand 1 "register_operand" "f")
12900 (match_operand 2 "register_operand" "f")])
12901 (pc)
12902 (label_ref (match_operand 3 "" ""))))
12903 (clobber (reg:CCFP 18))
12904 (clobber (reg:CCFP 17))
12905 (clobber (match_scratch:HI 4 "=a"))]
12906 "TARGET_80387
12907 && FLOAT_MODE_P (GET_MODE (operands[1]))
12908 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12909 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12910 "#")
12911
12912 (define_split
12913 [(set (pc)
12914 (if_then_else (match_operator 0 "comparison_operator"
12915 [(match_operand 1 "register_operand" "")
12916 (match_operand 2 "nonimmediate_operand" "")])
12917 (match_operand 3 "" "")
12918 (match_operand 4 "" "")))
12919 (clobber (reg:CCFP 18))
12920 (clobber (reg:CCFP 17))]
12921 "reload_completed"
12922 [(const_int 0)]
12923 {
12924 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12925 operands[3], operands[4], NULL_RTX);
12926 DONE;
12927 })
12928
12929 (define_split
12930 [(set (pc)
12931 (if_then_else (match_operator 0 "comparison_operator"
12932 [(match_operand 1 "register_operand" "")
12933 (match_operand 2 "nonimmediate_operand" "")])
12934 (match_operand 3 "" "")
12935 (match_operand 4 "" "")))
12936 (clobber (reg:CCFP 18))
12937 (clobber (reg:CCFP 17))
12938 (clobber (match_scratch:HI 5 "=a"))]
12939 "reload_completed"
12940 [(set (pc)
12941 (if_then_else (match_dup 6)
12942 (match_dup 3)
12943 (match_dup 4)))]
12944 {
12945 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12946 operands[3], operands[4], operands[5]);
12947 DONE;
12948 })
12949 \f
12950 ;; Unconditional and other jump instructions
12951
12952 (define_insn "jump"
12953 [(set (pc)
12954 (label_ref (match_operand 0 "" "")))]
12955 ""
12956 "jmp\t%l0"
12957 [(set_attr "type" "ibr")])
12958
12959 (define_expand "indirect_jump"
12960 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
12961 ""
12962 "")
12963
12964 (define_insn "*indirect_jump"
12965 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12966 "!TARGET_64BIT"
12967 "jmp\t%A0"
12968 [(set_attr "type" "ibr")
12969 (set_attr "length_immediate" "0")])
12970
12971 (define_insn "*indirect_jump_rtx64"
12972 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
12973 "TARGET_64BIT"
12974 "jmp\t%A0"
12975 [(set_attr "type" "ibr")
12976 (set_attr "length_immediate" "0")])
12977
12978 (define_expand "tablejump"
12979 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
12980 (use (label_ref (match_operand 1 "" "")))])]
12981 ""
12982 {
12983 /* In PIC mode, the table entries are stored GOT-relative. Convert
12984 the relative address to an absolute address. */
12985 if (flag_pic)
12986 {
12987 if (TARGET_64BIT)
12988 operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
12989 operands[1], NULL_RTX, 0,
12990 OPTAB_DIRECT);
12991 else
12992 {
12993 operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
12994 operands[0], NULL_RTX, 1,
12995 OPTAB_DIRECT);
12996 current_function_uses_pic_offset_table = 1;
12997 }
12998 }
12999 })
13000
13001 (define_insn "*tablejump_1"
13002 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13003 (use (label_ref (match_operand 1 "" "")))]
13004 "!TARGET_64BIT"
13005 "jmp\t%A0"
13006 [(set_attr "type" "ibr")
13007 (set_attr "length_immediate" "0")])
13008
13009 (define_insn "*tablejump_1_rtx64"
13010 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13011 (use (label_ref (match_operand 1 "" "")))]
13012 "TARGET_64BIT"
13013 "jmp\t%A0"
13014 [(set_attr "type" "ibr")
13015 (set_attr "length_immediate" "0")])
13016 \f
13017 ;; Loop instruction
13018 ;;
13019 ;; This is all complicated by the fact that since this is a jump insn
13020 ;; we must handle our own reloads.
13021
13022 (define_expand "doloop_end"
13023 [(use (match_operand 0 "" "")) ; loop pseudo
13024 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13025 (use (match_operand 2 "" "")) ; max iterations
13026 (use (match_operand 3 "" "")) ; loop level
13027 (use (match_operand 4 "" ""))] ; label
13028 "!TARGET_64BIT && TARGET_USE_LOOP"
13029 "
13030 {
13031 /* Only use cloop on innermost loops. */
13032 if (INTVAL (operands[3]) > 1)
13033 FAIL;
13034 if (GET_MODE (operands[0]) != SImode)
13035 FAIL;
13036 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13037 operands[0]));
13038 DONE;
13039 }")
13040
13041 (define_insn "doloop_end_internal"
13042 [(set (pc)
13043 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13044 (const_int 1))
13045 (label_ref (match_operand 0 "" ""))
13046 (pc)))
13047 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13048 (plus:SI (match_dup 1)
13049 (const_int -1)))
13050 (clobber (match_scratch:SI 3 "=X,X,r"))
13051 (clobber (reg:CC 17))]
13052 "!TARGET_64BIT && TARGET_USE_LOOP"
13053 {
13054 if (which_alternative != 0)
13055 return "#";
13056 if (get_attr_length (insn) == 2)
13057 return "%+loop\t%l0";
13058 else
13059 return "dec{l}\t%1\;%+jne\t%l0";
13060 }
13061 [(set_attr "ppro_uops" "many")
13062 (set (attr "type")
13063 (if_then_else (and (eq_attr "alternative" "0")
13064 (and (ge (minus (match_dup 0) (pc))
13065 (const_int -128))
13066 (lt (minus (match_dup 0) (pc))
13067 (const_int 124))))
13068 (const_string "ibr")
13069 (const_string "multi")))])
13070
13071 (define_split
13072 [(set (pc)
13073 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13074 (const_int 1))
13075 (match_operand 0 "" "")
13076 (pc)))
13077 (set (match_dup 1)
13078 (plus:SI (match_dup 1)
13079 (const_int -1)))
13080 (clobber (match_scratch:SI 2 ""))
13081 (clobber (reg:CC 17))]
13082 "!TARGET_64BIT && TARGET_USE_LOOP
13083 && reload_completed
13084 && REGNO (operands[1]) != 2"
13085 [(parallel [(set (reg:CCZ 17)
13086 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13087 (const_int 0)))
13088 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13089 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13090 (match_dup 0)
13091 (pc)))]
13092 "")
13093
13094 (define_split
13095 [(set (pc)
13096 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13097 (const_int 1))
13098 (match_operand 0 "" "")
13099 (pc)))
13100 (set (match_operand:SI 2 "nonimmediate_operand" "")
13101 (plus:SI (match_dup 1)
13102 (const_int -1)))
13103 (clobber (match_scratch:SI 3 ""))
13104 (clobber (reg:CC 17))]
13105 "!TARGET_64BIT && TARGET_USE_LOOP
13106 && reload_completed
13107 && (! REG_P (operands[2])
13108 || ! rtx_equal_p (operands[1], operands[2]))"
13109 [(set (match_dup 3) (match_dup 1))
13110 (parallel [(set (reg:CCZ 17)
13111 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13112 (const_int 0)))
13113 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13114 (set (match_dup 2) (match_dup 3))
13115 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13116 (match_dup 0)
13117 (pc)))]
13118 "")
13119
13120 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13121
13122 (define_peephole2
13123 [(set (reg 17) (match_operand 0 "" ""))
13124 (set (match_operand:QI 1 "register_operand" "")
13125 (match_operator:QI 2 "ix86_comparison_operator"
13126 [(reg 17) (const_int 0)]))
13127 (set (match_operand 3 "q_regs_operand" "")
13128 (zero_extend (match_dup 1)))]
13129 "peep2_reg_dead_p (3, operands[1])
13130 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13131 [(set (match_dup 3) (const_int 0))
13132 (set (match_dup 4) (match_dup 0))
13133 (set (strict_low_part (match_dup 5))
13134 (match_dup 2))]
13135 "operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13136 operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));")
13137 \f
13138 ;; Call instructions.
13139
13140 ;; The predicates normally associated with named expanders are not properly
13141 ;; checked for calls. This is a bug in the generic code, but it isn't that
13142 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13143
13144 ;; Call subroutine returning no value.
13145
13146 (define_expand "call_pop"
13147 [(parallel [(call (match_operand:QI 0 "" "")
13148 (match_operand:SI 1 "" ""))
13149 (set (reg:SI 7)
13150 (plus:SI (reg:SI 7)
13151 (match_operand:SI 3 "" "")))])]
13152 "!TARGET_64BIT"
13153 {
13154 if (operands[3] == const0_rtx)
13155 {
13156 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
13157 DONE;
13158 }
13159 /* Static functions and indirect calls don't need
13160 current_function_uses_pic_offset_table. */
13161 if (flag_pic
13162 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13163 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13164 current_function_uses_pic_offset_table = 1;
13165 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13166 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13167 if (TARGET_64BIT)
13168 abort();
13169 })
13170
13171 (define_insn "*call_pop_0"
13172 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13173 (match_operand:SI 1 "" ""))
13174 (set (reg:SI 7) (plus:SI (reg:SI 7)
13175 (match_operand:SI 2 "immediate_operand" "")))]
13176 "!TARGET_64BIT"
13177 {
13178 if (SIBLING_CALL_P (insn))
13179 return "jmp\t%P0";
13180 else
13181 return "call\t%P0";
13182 }
13183 [(set_attr "type" "call")])
13184
13185 (define_insn "*call_pop_1"
13186 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13187 (match_operand:SI 1 "" ""))
13188 (set (reg:SI 7) (plus:SI (reg:SI 7)
13189 (match_operand:SI 2 "immediate_operand" "i")))]
13190 "!TARGET_64BIT"
13191 {
13192 if (constant_call_address_operand (operands[0], Pmode))
13193 {
13194 if (SIBLING_CALL_P (insn))
13195 return "jmp\t%P0";
13196 else
13197 return "call\t%P0";
13198 }
13199 if (SIBLING_CALL_P (insn))
13200 return "jmp\t%A0";
13201 else
13202 return "call\t%A0";
13203 }
13204 [(set_attr "type" "call")])
13205
13206 (define_expand "call"
13207 [(call (match_operand:QI 0 "" "")
13208 (match_operand 1 "" ""))
13209 (use (match_operand 2 "" ""))]
13210 ;; Operand 1 not used on the i386.
13211 ""
13212 {
13213 rtx insn;
13214 /* Static functions and indirect calls don't need
13215 current_function_uses_pic_offset_table. */
13216 if (flag_pic
13217 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
13218 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
13219 current_function_uses_pic_offset_table = 1;
13220
13221 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
13222 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
13223 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
13224 {
13225 rtx reg = gen_rtx_REG (QImode, 0);
13226 emit_move_insn (reg, operands[2]);
13227 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13228 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13229 DONE;
13230 }
13231 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
13232 DONE;
13233 })
13234
13235 (define_expand "call_exp"
13236 [(call (match_operand:QI 0 "" "")
13237 (match_operand 1 "" ""))]
13238 ""
13239 "")
13240
13241 (define_insn "*call_0"
13242 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13243 (match_operand 1 "" ""))]
13244 ""
13245 {
13246 if (SIBLING_CALL_P (insn))
13247 return "jmp\t%P0";
13248 else
13249 return "call\t%P0";
13250 }
13251 [(set_attr "type" "call")])
13252
13253 (define_insn "*call_1"
13254 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13255 (match_operand 1 "" ""))]
13256 "!TARGET_64BIT"
13257 {
13258 if (constant_call_address_operand (operands[0], QImode))
13259 {
13260 if (SIBLING_CALL_P (insn))
13261 return "jmp\t%P0";
13262 else
13263 return "call\t%P0";
13264 }
13265 if (SIBLING_CALL_P (insn))
13266 return "jmp\t%A0";
13267 else
13268 return "call\t%A0";
13269 }
13270 [(set_attr "type" "call")])
13271
13272 (define_insn "*call_1_rex64"
13273 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13274 (match_operand 1 "" ""))]
13275 "TARGET_64BIT"
13276 {
13277 if (constant_call_address_operand (operands[0], QImode))
13278 {
13279 if (SIBLING_CALL_P (insn))
13280 return "jmp\t%P0";
13281 else
13282 return "call\t%P0";
13283 }
13284 if (SIBLING_CALL_P (insn))
13285 return "jmp\t%A0";
13286 else
13287 return "call\t%A0";
13288 }
13289 [(set_attr "type" "call")])
13290
13291 ;; Call subroutine, returning value in operand 0
13292 ;; (which must be a hard register).
13293
13294 (define_expand "call_value_pop"
13295 [(parallel [(set (match_operand 0 "" "")
13296 (call (match_operand:QI 1 "" "")
13297 (match_operand:SI 2 "" "")))
13298 (set (reg:SI 7)
13299 (plus:SI (reg:SI 7)
13300 (match_operand:SI 4 "" "")))])]
13301 "!TARGET_64BIT"
13302 {
13303 if (operands[4] == const0_rtx)
13304 {
13305 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13306 constm1_rtx));
13307 DONE;
13308 }
13309 /* Static functions and indirect calls don't need
13310 current_function_uses_pic_offset_table. */
13311 if (flag_pic
13312 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13313 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13314 current_function_uses_pic_offset_table = 1;
13315 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13316 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13317 })
13318
13319 (define_expand "call_value"
13320 [(set (match_operand 0 "" "")
13321 (call (match_operand:QI 1 "" "")
13322 (match_operand:SI 2 "" "")))
13323 (use (match_operand:SI 3 "" ""))]
13324 ;; Operand 2 not used on the i386.
13325 ""
13326 {
13327 rtx insn;
13328 /* Static functions and indirect calls don't need
13329 current_function_uses_pic_offset_table. */
13330 if (flag_pic
13331 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13332 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13333 current_function_uses_pic_offset_table = 1;
13334 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13335 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13336 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13337 {
13338 rtx reg = gen_rtx_REG (QImode, 0);
13339 emit_move_insn (reg, operands[3]);
13340 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13341 operands[2]));
13342 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13343 DONE;
13344 }
13345 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13346 operands[2]));
13347 DONE;
13348 })
13349
13350 (define_expand "call_value_exp"
13351 [(set (match_operand 0 "" "")
13352 (call (match_operand:QI 1 "" "")
13353 (match_operand:SI 2 "" "")))]
13354 ""
13355 "")
13356
13357 ;; Call subroutine returning any type.
13358
13359 (define_expand "untyped_call"
13360 [(parallel [(call (match_operand 0 "" "")
13361 (const_int 0))
13362 (match_operand 1 "" "")
13363 (match_operand 2 "" "")])]
13364 ""
13365 {
13366 int i;
13367
13368 /* In order to give reg-stack an easier job in validating two
13369 coprocessor registers as containing a possible return value,
13370 simply pretend the untyped call returns a complex long double
13371 value. */
13372
13373 emit_call_insn (TARGET_80387
13374 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13375 operands[0], const0_rtx,
13376 GEN_INT (SSE_REGPARM_MAX - 1))
13377 : gen_call (operands[0], const0_rtx,
13378 GEN_INT (SSE_REGPARM_MAX - 1)));
13379
13380 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13381 {
13382 rtx set = XVECEXP (operands[2], 0, i);
13383 emit_move_insn (SET_DEST (set), SET_SRC (set));
13384 }
13385
13386 /* The optimizer does not know that the call sets the function value
13387 registers we stored in the result block. We avoid problems by
13388 claiming that all hard registers are used and clobbered at this
13389 point. */
13390 emit_insn (gen_blockage ());
13391
13392 DONE;
13393 })
13394 \f
13395 ;; Prologue and epilogue instructions
13396
13397 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13398 ;; all of memory. This blocks insns from being moved across this point.
13399
13400 (define_insn "blockage"
13401 [(unspec_volatile [(const_int 0)] 0)]
13402 ""
13403 ""
13404 [(set_attr "length" "0")])
13405
13406 ;; Insn emitted into the body of a function to return from a function.
13407 ;; This is only done if the function's epilogue is known to be simple.
13408 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13409
13410 (define_expand "return"
13411 [(return)]
13412 "ix86_can_use_return_insn_p ()"
13413 {
13414 if (current_function_pops_args)
13415 {
13416 rtx popc = GEN_INT (current_function_pops_args);
13417 emit_jump_insn (gen_return_pop_internal (popc));
13418 DONE;
13419 }
13420 })
13421
13422 (define_insn "return_internal"
13423 [(return)]
13424 "reload_completed"
13425 "ret"
13426 [(set_attr "length" "1")
13427 (set_attr "length_immediate" "0")
13428 (set_attr "modrm" "0")])
13429
13430 (define_insn "return_pop_internal"
13431 [(return)
13432 (use (match_operand:SI 0 "const_int_operand" ""))]
13433 "reload_completed"
13434 "ret\t%0"
13435 [(set_attr "length" "3")
13436 (set_attr "length_immediate" "2")
13437 (set_attr "modrm" "0")])
13438
13439 (define_insn "return_indirect_internal"
13440 [(return)
13441 (use (match_operand:SI 0 "register_operand" "r"))]
13442 "reload_completed"
13443 "jmp\t%A0"
13444 [(set_attr "type" "ibr")
13445 (set_attr "length_immediate" "0")])
13446
13447 (define_insn "nop"
13448 [(const_int 0)]
13449 ""
13450 "nop"
13451 [(set_attr "length" "1")
13452 (set_attr "length_immediate" "0")
13453 (set_attr "modrm" "0")
13454 (set_attr "ppro_uops" "one")])
13455
13456 (define_expand "prologue"
13457 [(const_int 1)]
13458 ""
13459 "ix86_expand_prologue (); DONE;")
13460
13461 (define_insn "prologue_set_got"
13462 [(set (match_operand:SI 0 "register_operand" "=r")
13463 (unspec_volatile:SI
13464 [(plus:SI (match_dup 0)
13465 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13466 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13467 (clobber (reg:CC 17))]
13468 "!TARGET_64BIT"
13469 {
13470 if (GET_CODE (operands[2]) == LABEL_REF)
13471 operands[2] = XEXP (operands[2], 0);
13472 if (TARGET_DEEP_BRANCH_PREDICTION)
13473 return "add{l}\t{%1, %0|%0, %1}";
13474 else
13475 return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
13476 }
13477 [(set_attr "type" "alu")
13478 ; Since this insn may have two constant operands, we must set the
13479 ; length manually.
13480 (set_attr "length_immediate" "4")
13481 (set_attr "mode" "SI")])
13482
13483 (define_insn "prologue_get_pc"
13484 [(set (match_operand:SI 0 "register_operand" "=r")
13485 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13486 "!TARGET_64BIT"
13487 {
13488 if (GET_CODE (operands[1]) == LABEL_REF)
13489 operands[1] = XEXP (operands[1], 0);
13490 output_asm_insn ("call\t%X1", operands);
13491 if (! TARGET_DEEP_BRANCH_PREDICTION)
13492 {
13493 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
13494 CODE_LABEL_NUMBER (operands[1]));
13495 }
13496 RET;
13497 }
13498 [(set_attr "type" "multi")])
13499
13500 (define_expand "epilogue"
13501 [(const_int 1)]
13502 ""
13503 "ix86_expand_epilogue (1); DONE;")
13504
13505 (define_expand "sibcall_epilogue"
13506 [(const_int 1)]
13507 ""
13508 "ix86_expand_epilogue (0); DONE;")
13509
13510 (define_expand "eh_return"
13511 [(use (match_operand 0 "register_operand" ""))
13512 (use (match_operand 1 "register_operand" ""))]
13513 ""
13514 {
13515 rtx tmp, sa = operands[0], ra = operands[1];
13516
13517 /* Tricky bit: we write the address of the handler to which we will
13518 be returning into someone else's stack frame, one word below the
13519 stack address we wish to restore. */
13520 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13521 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13522 tmp = gen_rtx_MEM (Pmode, tmp);
13523 emit_move_insn (tmp, ra);
13524
13525 if (Pmode == SImode)
13526 emit_insn (gen_eh_return_si (sa));
13527 else
13528 emit_insn (gen_eh_return_di (sa));
13529 emit_barrier ();
13530 DONE;
13531 })
13532
13533 (define_insn_and_split "eh_return_si"
13534 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
13535 "!TARGET_64BIT"
13536 "#"
13537 "reload_completed"
13538 [(const_int 1)]
13539 "ix86_expand_epilogue (2); DONE;")
13540
13541 (define_insn_and_split "eh_return_di"
13542 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
13543 "TARGET_64BIT"
13544 "#"
13545 "reload_completed"
13546 [(const_int 1)]
13547 "ix86_expand_epilogue (2); DONE;")
13548
13549 (define_insn "leave"
13550 [(set (reg:SI 7) (reg:SI 6))
13551 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))
13552 (clobber (mem:BLK (scratch)))]
13553 "!TARGET_64BIT"
13554 "leave"
13555 [(set_attr "length_immediate" "0")
13556 (set_attr "length" "1")
13557 (set_attr "modrm" "0")
13558 (set_attr "modrm" "0")
13559 (set_attr "athlon_decode" "vector")
13560 (set_attr "ppro_uops" "few")])
13561
13562 (define_insn "leave_rex64"
13563 [(set (reg:DI 7) (reg:DI 6))
13564 (set (reg:DI 6) (mem:DI (pre_dec:DI (reg:DI 7))))
13565 (clobber (mem:BLK (scratch)))]
13566 "TARGET_64BIT"
13567 "leave"
13568 [(set_attr "length_immediate" "0")
13569 (set_attr "length" "1")
13570 (set_attr "modrm" "0")
13571 (set_attr "modrm" "0")
13572 (set_attr "athlon_decode" "vector")
13573 (set_attr "ppro_uops" "few")])
13574 \f
13575 (define_expand "ffssi2"
13576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13577 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13578 ""
13579 {
13580 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13581 rtx in = operands[1];
13582
13583 if (TARGET_CMOVE)
13584 {
13585 emit_move_insn (tmp, constm1_rtx);
13586 emit_insn (gen_ffssi_1 (out, in));
13587 emit_insn (gen_rtx_SET (VOIDmode, out,
13588 gen_rtx_IF_THEN_ELSE (SImode,
13589 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13590 const0_rtx),
13591 tmp,
13592 out)));
13593 emit_insn (gen_addsi3 (out, out, const1_rtx));
13594 emit_move_insn (operands[0], out);
13595 }
13596
13597 /* Pentium bsf instruction is extremly slow. The following code is
13598 recommended by the Intel Optimizing Manual as a reasonable replacement:
13599 TEST EAX,EAX
13600 JZ SHORT BS2
13601 XOR ECX,ECX
13602 MOV DWORD PTR [TEMP+4],ECX
13603 SUB ECX,EAX
13604 AND EAX,ECX
13605 MOV DWORD PTR [TEMP],EAX
13606 FILD QWORD PTR [TEMP]
13607 FSTP QWORD PTR [TEMP]
13608 WAIT ; WAIT only needed for compatibility with
13609 ; earlier processors
13610 MOV ECX, DWORD PTR [TEMP+4]
13611 SHR ECX,20
13612 SUB ECX,3FFH
13613 TEST EAX,EAX ; clear zero flag
13614 BS2:
13615 Following piece of code expand ffs to similar beast.
13616 */
13617
13618 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13619 {
13620 rtx label = gen_label_rtx ();
13621 rtx lo, hi;
13622 rtx mem = assign_386_stack_local (DImode, 0);
13623 rtx fptmp = gen_reg_rtx (DFmode);
13624 split_di (&mem, 1, &lo, &hi);
13625
13626 emit_move_insn (out, const0_rtx);
13627
13628 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
13629
13630 emit_move_insn (hi, out);
13631 emit_insn (gen_subsi3 (out, out, in));
13632 emit_insn (gen_andsi3 (out, out, in));
13633 emit_move_insn (lo, out);
13634 emit_insn (gen_floatdidf2 (fptmp,mem));
13635 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13636 emit_move_insn (out, hi);
13637 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13638 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13639
13640 emit_label (label);
13641 LABEL_NUSES (label) = 1;
13642
13643 emit_move_insn (operands[0], out);
13644 }
13645 else
13646 {
13647 emit_move_insn (tmp, const0_rtx);
13648 emit_insn (gen_ffssi_1 (out, in));
13649 emit_insn (gen_rtx_SET (VOIDmode,
13650 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13651 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13652 const0_rtx)));
13653 emit_insn (gen_negsi2 (tmp, tmp));
13654 emit_insn (gen_iorsi3 (out, out, tmp));
13655 emit_insn (gen_addsi3 (out, out, const1_rtx));
13656 emit_move_insn (operands[0], out);
13657 }
13658 DONE;
13659 })
13660
13661 (define_insn "ffssi_1"
13662 [(set (reg:CCZ 17)
13663 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13664 (const_int 0)))
13665 (set (match_operand:SI 0 "register_operand" "=r")
13666 (unspec:SI [(match_dup 1)] 5))]
13667 ""
13668 "bsf{l}\t{%1, %0|%0, %1}"
13669 [(set_attr "prefix_0f" "1")
13670 (set_attr "ppro_uops" "few")])
13671
13672 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13673 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
13674 \f
13675 ;; These patterns match the binary 387 instructions for addM3, subM3,
13676 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13677 ;; SFmode. The first is the normal insn, the second the same insn but
13678 ;; with one operand a conversion, and the third the same insn but with
13679 ;; the other operand a conversion. The conversion may be SFmode or
13680 ;; SImode if the target mode DFmode, but only SImode if the target mode
13681 ;; is SFmode.
13682
13683 ;; Gcc is slightly more smart about handling normal two address instructions
13684 ;; so use special patterns for add and mull.
13685 (define_insn "*fop_sf_comm"
13686 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13687 (match_operator:SF 3 "binary_fp_operator"
13688 [(match_operand:SF 1 "register_operand" "%0,0")
13689 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13690 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
13691 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13692 "* return output_387_binary_op (insn, operands);"
13693 [(set (attr "type")
13694 (if_then_else (eq_attr "alternative" "1")
13695 (const_string "sse")
13696 (if_then_else (match_operand:SF 3 "mult_operator" "")
13697 (const_string "fmul")
13698 (const_string "fop"))))
13699 (set_attr "mode" "SF")])
13700
13701 (define_insn "*fop_sf_comm_sse"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 3 "binary_fp_operator"
13704 [(match_operand:SF 1 "register_operand" "%0")
13705 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13706 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13707 "* return output_387_binary_op (insn, operands);"
13708 [(set_attr "type" "sse")
13709 (set_attr "mode" "SF")])
13710
13711 (define_insn "*fop_df_comm"
13712 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13713 (match_operator:DF 3 "binary_fp_operator"
13714 [(match_operand:DF 1 "register_operand" "%0,0")
13715 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13716 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
13717 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13718 "* return output_387_binary_op (insn, operands);"
13719 [(set (attr "type")
13720 (if_then_else (eq_attr "alternative" "1")
13721 (const_string "sse")
13722 (if_then_else (match_operand:SF 3 "mult_operator" "")
13723 (const_string "fmul")
13724 (const_string "fop"))))
13725 (set_attr "mode" "DF")])
13726
13727 (define_insn "*fop_df_comm_sse"
13728 [(set (match_operand:DF 0 "register_operand" "=Y")
13729 (match_operator:DF 3 "binary_fp_operator"
13730 [(match_operand:DF 1 "register_operand" "%0")
13731 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13732 "TARGET_SSE2
13733 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13734 "* return output_387_binary_op (insn, operands);"
13735 [(set_attr "type" "sse")
13736 (set_attr "mode" "DF")])
13737
13738 (define_insn "*fop_xf_comm"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (match_operator:XF 3 "binary_fp_operator"
13741 [(match_operand:XF 1 "register_operand" "%0")
13742 (match_operand:XF 2 "register_operand" "f")]))]
13743 "!TARGET_64BIT && TARGET_80387
13744 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13745 "* return output_387_binary_op (insn, operands);"
13746 [(set (attr "type")
13747 (if_then_else (match_operand:XF 3 "mult_operator" "")
13748 (const_string "fmul")
13749 (const_string "fop")))
13750 (set_attr "mode" "XF")])
13751
13752 (define_insn "*fop_tf_comm"
13753 [(set (match_operand:TF 0 "register_operand" "=f")
13754 (match_operator:TF 3 "binary_fp_operator"
13755 [(match_operand:TF 1 "register_operand" "%0")
13756 (match_operand:TF 2 "register_operand" "f")]))]
13757 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13758 "* return output_387_binary_op (insn, operands);"
13759 [(set (attr "type")
13760 (if_then_else (match_operand:TF 3 "mult_operator" "")
13761 (const_string "fmul")
13762 (const_string "fop")))
13763 (set_attr "mode" "XF")])
13764
13765 (define_insn "*fop_sf_1"
13766 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13767 (match_operator:SF 3 "binary_fp_operator"
13768 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13769 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13770 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
13771 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13772 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13773 "* return output_387_binary_op (insn, operands);"
13774 [(set (attr "type")
13775 (cond [(eq_attr "alternative" "2")
13776 (const_string "sse")
13777 (match_operand:SF 3 "mult_operator" "")
13778 (const_string "fmul")
13779 (match_operand:SF 3 "div_operator" "")
13780 (const_string "fdiv")
13781 ]
13782 (const_string "fop")))
13783 (set_attr "mode" "SF")])
13784
13785 (define_insn "*fop_sf_1_sse"
13786 [(set (match_operand:SF 0 "register_operand" "=x")
13787 (match_operator:SF 3 "binary_fp_operator"
13788 [(match_operand:SF 1 "register_operand" "0")
13789 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13790 "TARGET_SSE
13791 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13792 "* return output_387_binary_op (insn, operands);"
13793 [(set_attr "type" "sse")
13794 (set_attr "mode" "SF")])
13795
13796 ;; ??? Add SSE splitters for these!
13797 (define_insn "*fop_sf_2"
13798 [(set (match_operand:SF 0 "register_operand" "=f,f")
13799 (match_operator:SF 3 "binary_fp_operator"
13800 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13801 (match_operand:SF 2 "register_operand" "0,0")]))]
13802 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
13803 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13804 [(set (attr "type")
13805 (cond [(match_operand:SF 3 "mult_operator" "")
13806 (const_string "fmul")
13807 (match_operand:SF 3 "div_operator" "")
13808 (const_string "fdiv")
13809 ]
13810 (const_string "fop")))
13811 (set_attr "fp_int_src" "true")
13812 (set_attr "ppro_uops" "many")
13813 (set_attr "mode" "SI")])
13814
13815 (define_insn "*fop_sf_3"
13816 [(set (match_operand:SF 0 "register_operand" "=f,f")
13817 (match_operator:SF 3 "binary_fp_operator"
13818 [(match_operand:SF 1 "register_operand" "0,0")
13819 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13820 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
13821 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13822 [(set (attr "type")
13823 (cond [(match_operand:SF 3 "mult_operator" "")
13824 (const_string "fmul")
13825 (match_operand:SF 3 "div_operator" "")
13826 (const_string "fdiv")
13827 ]
13828 (const_string "fop")))
13829 (set_attr "fp_int_src" "true")
13830 (set_attr "ppro_uops" "many")
13831 (set_attr "mode" "SI")])
13832
13833 (define_insn "*fop_df_1"
13834 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
13835 (match_operator:DF 3 "binary_fp_operator"
13836 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
13837 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
13838 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
13839 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13840 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13841 "* return output_387_binary_op (insn, operands);"
13842 [(set (attr "type")
13843 (cond [(eq_attr "alternative" "2")
13844 (const_string "sse")
13845 (match_operand:DF 3 "mult_operator" "")
13846 (const_string "fmul")
13847 (match_operand:DF 3 "div_operator" "")
13848 (const_string "fdiv")
13849 ]
13850 (const_string "fop")))
13851 (set_attr "mode" "DF")])
13852
13853 (define_insn "*fop_df_1_sse"
13854 [(set (match_operand:DF 0 "register_operand" "=Y")
13855 (match_operator:DF 3 "binary_fp_operator"
13856 [(match_operand:DF 1 "register_operand" "0")
13857 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13858 "TARGET_SSE
13859 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13860 "* return output_387_binary_op (insn, operands);"
13861 [(set_attr "type" "sse")])
13862
13863 ;; ??? Add SSE splitters for these!
13864 (define_insn "*fop_df_2"
13865 [(set (match_operand:DF 0 "register_operand" "=f,f")
13866 (match_operator:DF 3 "binary_fp_operator"
13867 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13868 (match_operand:DF 2 "register_operand" "0,0")]))]
13869 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
13870 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13871 [(set (attr "type")
13872 (cond [(match_operand:DF 3 "mult_operator" "")
13873 (const_string "fmul")
13874 (match_operand:DF 3 "div_operator" "")
13875 (const_string "fdiv")
13876 ]
13877 (const_string "fop")))
13878 (set_attr "fp_int_src" "true")
13879 (set_attr "ppro_uops" "many")
13880 (set_attr "mode" "SI")])
13881
13882 (define_insn "*fop_df_3"
13883 [(set (match_operand:DF 0 "register_operand" "=f,f")
13884 (match_operator:DF 3 "binary_fp_operator"
13885 [(match_operand:DF 1 "register_operand" "0,0")
13886 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13887 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
13888 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13889 [(set (attr "type")
13890 (cond [(match_operand:DF 3 "mult_operator" "")
13891 (const_string "fmul")
13892 (match_operand:DF 3 "div_operator" "")
13893 (const_string "fdiv")
13894 ]
13895 (const_string "fop")))
13896 (set_attr "fp_int_src" "true")
13897 (set_attr "ppro_uops" "many")
13898 (set_attr "mode" "SI")])
13899
13900 (define_insn "*fop_df_4"
13901 [(set (match_operand:DF 0 "register_operand" "=f,f")
13902 (match_operator:DF 3 "binary_fp_operator"
13903 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13904 (match_operand:DF 2 "register_operand" "0,f")]))]
13905 "TARGET_80387
13906 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13907 "* return output_387_binary_op (insn, operands);"
13908 [(set (attr "type")
13909 (cond [(match_operand:DF 3 "mult_operator" "")
13910 (const_string "fmul")
13911 (match_operand:DF 3 "div_operator" "")
13912 (const_string "fdiv")
13913 ]
13914 (const_string "fop")))
13915 (set_attr "mode" "SF")])
13916
13917 (define_insn "*fop_df_5"
13918 [(set (match_operand:DF 0 "register_operand" "=f,f")
13919 (match_operator:DF 3 "binary_fp_operator"
13920 [(match_operand:DF 1 "register_operand" "0,f")
13921 (float_extend:DF
13922 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13923 "TARGET_80387 && !TARGET_SSE2"
13924 "* return output_387_binary_op (insn, operands);"
13925 [(set (attr "type")
13926 (cond [(match_operand:DF 3 "mult_operator" "")
13927 (const_string "fmul")
13928 (match_operand:DF 3 "div_operator" "")
13929 (const_string "fdiv")
13930 ]
13931 (const_string "fop")))
13932 (set_attr "mode" "SF")])
13933
13934 (define_insn "*fop_xf_1"
13935 [(set (match_operand:XF 0 "register_operand" "=f,f")
13936 (match_operator:XF 3 "binary_fp_operator"
13937 [(match_operand:XF 1 "register_operand" "0,f")
13938 (match_operand:XF 2 "register_operand" "f,0")]))]
13939 "!TARGET_64BIT && TARGET_80387
13940 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13941 "* return output_387_binary_op (insn, operands);"
13942 [(set (attr "type")
13943 (cond [(match_operand:XF 3 "mult_operator" "")
13944 (const_string "fmul")
13945 (match_operand:XF 3 "div_operator" "")
13946 (const_string "fdiv")
13947 ]
13948 (const_string "fop")))
13949 (set_attr "mode" "XF")])
13950
13951 (define_insn "*fop_tf_1"
13952 [(set (match_operand:TF 0 "register_operand" "=f,f")
13953 (match_operator:TF 3 "binary_fp_operator"
13954 [(match_operand:TF 1 "register_operand" "0,f")
13955 (match_operand:TF 2 "register_operand" "f,0")]))]
13956 "TARGET_80387
13957 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13958 "* return output_387_binary_op (insn, operands);"
13959 [(set (attr "type")
13960 (cond [(match_operand:TF 3 "mult_operator" "")
13961 (const_string "fmul")
13962 (match_operand:TF 3 "div_operator" "")
13963 (const_string "fdiv")
13964 ]
13965 (const_string "fop")))
13966 (set_attr "mode" "XF")])
13967
13968 (define_insn "*fop_xf_2"
13969 [(set (match_operand:XF 0 "register_operand" "=f,f")
13970 (match_operator:XF 3 "binary_fp_operator"
13971 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13972 (match_operand:XF 2 "register_operand" "0,0")]))]
13973 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
13974 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13975 [(set (attr "type")
13976 (cond [(match_operand:XF 3 "mult_operator" "")
13977 (const_string "fmul")
13978 (match_operand:XF 3 "div_operator" "")
13979 (const_string "fdiv")
13980 ]
13981 (const_string "fop")))
13982 (set_attr "fp_int_src" "true")
13983 (set_attr "mode" "SI")
13984 (set_attr "ppro_uops" "many")])
13985
13986 (define_insn "*fop_tf_2"
13987 [(set (match_operand:TF 0 "register_operand" "=f,f")
13988 (match_operator:TF 3 "binary_fp_operator"
13989 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13990 (match_operand:TF 2 "register_operand" "0,0")]))]
13991 "TARGET_80387 && TARGET_USE_FIOP"
13992 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13993 [(set (attr "type")
13994 (cond [(match_operand:TF 3 "mult_operator" "")
13995 (const_string "fmul")
13996 (match_operand:TF 3 "div_operator" "")
13997 (const_string "fdiv")
13998 ]
13999 (const_string "fop")))
14000 (set_attr "fp_int_src" "true")
14001 (set_attr "mode" "SI")
14002 (set_attr "ppro_uops" "many")])
14003
14004 (define_insn "*fop_xf_3"
14005 [(set (match_operand:XF 0 "register_operand" "=f,f")
14006 (match_operator:XF 3 "binary_fp_operator"
14007 [(match_operand:XF 1 "register_operand" "0,0")
14008 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14009 "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
14010 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14011 [(set (attr "type")
14012 (cond [(match_operand:XF 3 "mult_operator" "")
14013 (const_string "fmul")
14014 (match_operand:XF 3 "div_operator" "")
14015 (const_string "fdiv")
14016 ]
14017 (const_string "fop")))
14018 (set_attr "fp_int_src" "true")
14019 (set_attr "mode" "SI")
14020 (set_attr "ppro_uops" "many")])
14021
14022 (define_insn "*fop_tf_3"
14023 [(set (match_operand:TF 0 "register_operand" "=f,f")
14024 (match_operator:TF 3 "binary_fp_operator"
14025 [(match_operand:TF 1 "register_operand" "0,0")
14026 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14027 "TARGET_80387 && TARGET_USE_FIOP"
14028 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14029 [(set (attr "type")
14030 (cond [(match_operand:TF 3 "mult_operator" "")
14031 (const_string "fmul")
14032 (match_operand:TF 3 "div_operator" "")
14033 (const_string "fdiv")
14034 ]
14035 (const_string "fop")))
14036 (set_attr "fp_int_src" "true")
14037 (set_attr "mode" "SI")
14038 (set_attr "ppro_uops" "many")])
14039
14040 (define_insn "*fop_xf_4"
14041 [(set (match_operand:XF 0 "register_operand" "=f,f")
14042 (match_operator:XF 3 "binary_fp_operator"
14043 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14044 (match_operand:XF 2 "register_operand" "0,f")]))]
14045 "!TARGET_64BIT && TARGET_80387"
14046 "* return output_387_binary_op (insn, operands);"
14047 [(set (attr "type")
14048 (cond [(match_operand:XF 3 "mult_operator" "")
14049 (const_string "fmul")
14050 (match_operand:XF 3 "div_operator" "")
14051 (const_string "fdiv")
14052 ]
14053 (const_string "fop")))
14054 (set_attr "mode" "SF")])
14055
14056 (define_insn "*fop_tf_4"
14057 [(set (match_operand:TF 0 "register_operand" "=f,f")
14058 (match_operator:TF 3 "binary_fp_operator"
14059 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14060 (match_operand:TF 2 "register_operand" "0,f")]))]
14061 "TARGET_80387"
14062 "* return output_387_binary_op (insn, operands);"
14063 [(set (attr "type")
14064 (cond [(match_operand:TF 3 "mult_operator" "")
14065 (const_string "fmul")
14066 (match_operand:TF 3 "div_operator" "")
14067 (const_string "fdiv")
14068 ]
14069 (const_string "fop")))
14070 (set_attr "mode" "SF")])
14071
14072 (define_insn "*fop_xf_5"
14073 [(set (match_operand:XF 0 "register_operand" "=f,f")
14074 (match_operator:XF 3 "binary_fp_operator"
14075 [(match_operand:XF 1 "register_operand" "0,f")
14076 (float_extend:XF
14077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14078 "!TARGET_64BIT && TARGET_80387"
14079 "* return output_387_binary_op (insn, operands);"
14080 [(set (attr "type")
14081 (cond [(match_operand:XF 3 "mult_operator" "")
14082 (const_string "fmul")
14083 (match_operand:XF 3 "div_operator" "")
14084 (const_string "fdiv")
14085 ]
14086 (const_string "fop")))
14087 (set_attr "mode" "SF")])
14088
14089 (define_insn "*fop_tf_5"
14090 [(set (match_operand:TF 0 "register_operand" "=f,f")
14091 (match_operator:TF 3 "binary_fp_operator"
14092 [(match_operand:TF 1 "register_operand" "0,f")
14093 (float_extend:TF
14094 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14095 "TARGET_80387"
14096 "* return output_387_binary_op (insn, operands);"
14097 [(set (attr "type")
14098 (cond [(match_operand:TF 3 "mult_operator" "")
14099 (const_string "fmul")
14100 (match_operand:TF 3 "div_operator" "")
14101 (const_string "fdiv")
14102 ]
14103 (const_string "fop")))
14104 (set_attr "mode" "SF")])
14105
14106 (define_insn "*fop_xf_6"
14107 [(set (match_operand:XF 0 "register_operand" "=f,f")
14108 (match_operator:XF 3 "binary_fp_operator"
14109 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14110 (match_operand:XF 2 "register_operand" "0,f")]))]
14111 "!TARGET_64BIT && TARGET_80387"
14112 "* return output_387_binary_op (insn, operands);"
14113 [(set (attr "type")
14114 (cond [(match_operand:XF 3 "mult_operator" "")
14115 (const_string "fmul")
14116 (match_operand:XF 3 "div_operator" "")
14117 (const_string "fdiv")
14118 ]
14119 (const_string "fop")))
14120 (set_attr "mode" "DF")])
14121
14122 (define_insn "*fop_tf_6"
14123 [(set (match_operand:TF 0 "register_operand" "=f,f")
14124 (match_operator:TF 3 "binary_fp_operator"
14125 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
14126 (match_operand:TF 2 "register_operand" "0,f")]))]
14127 "TARGET_80387"
14128 "* return output_387_binary_op (insn, operands);"
14129 [(set (attr "type")
14130 (cond [(match_operand:TF 3 "mult_operator" "")
14131 (const_string "fmul")
14132 (match_operand:TF 3 "div_operator" "")
14133 (const_string "fdiv")
14134 ]
14135 (const_string "fop")))
14136 (set_attr "mode" "DF")])
14137
14138 (define_insn "*fop_xf_7"
14139 [(set (match_operand:XF 0 "register_operand" "=f,f")
14140 (match_operator:XF 3 "binary_fp_operator"
14141 [(match_operand:XF 1 "register_operand" "0,f")
14142 (float_extend:XF
14143 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14144 "!TARGET_64BIT && TARGET_80387"
14145 "* return output_387_binary_op (insn, operands);"
14146 [(set (attr "type")
14147 (cond [(match_operand:XF 3 "mult_operator" "")
14148 (const_string "fmul")
14149 (match_operand:XF 3 "div_operator" "")
14150 (const_string "fdiv")
14151 ]
14152 (const_string "fop")))
14153 (set_attr "mode" "DF")])
14154
14155 (define_insn "*fop_tf_7"
14156 [(set (match_operand:TF 0 "register_operand" "=f,f")
14157 (match_operator:TF 3 "binary_fp_operator"
14158 [(match_operand:TF 1 "register_operand" "0,f")
14159 (float_extend:TF
14160 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
14161 "TARGET_80387"
14162 "* return output_387_binary_op (insn, operands);"
14163 [(set (attr "type")
14164 (cond [(match_operand:TF 3 "mult_operator" "")
14165 (const_string "fmul")
14166 (match_operand:TF 3 "div_operator" "")
14167 (const_string "fdiv")
14168 ]
14169 (const_string "fop")))
14170 (set_attr "mode" "DF")])
14171
14172 (define_split
14173 [(set (match_operand 0 "register_operand" "")
14174 (match_operator 3 "binary_fp_operator"
14175 [(float (match_operand:SI 1 "register_operand" ""))
14176 (match_operand 2 "register_operand" "")]))]
14177 "TARGET_80387 && reload_completed
14178 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14179 [(const_int 0)]
14180 {
14181 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14182 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14183 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14184 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14185 GET_MODE (operands[3]),
14186 operands[4],
14187 operands[2])));
14188 ix86_free_from_memory (GET_MODE (operands[1]));
14189 DONE;
14190 })
14191
14192 (define_split
14193 [(set (match_operand 0 "register_operand" "")
14194 (match_operator 3 "binary_fp_operator"
14195 [(match_operand 1 "register_operand" "")
14196 (float (match_operand:SI 2 "register_operand" ""))]))]
14197 "TARGET_80387 && reload_completed
14198 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14199 [(const_int 0)]
14200 {
14201 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14202 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14203 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14204 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14205 GET_MODE (operands[3]),
14206 operands[1],
14207 operands[4])));
14208 ix86_free_from_memory (GET_MODE (operands[2]));
14209 DONE;
14210 })
14211 \f
14212 ;; FPU special functions.
14213
14214 (define_expand "sqrtsf2"
14215 [(set (match_operand:SF 0 "register_operand" "")
14216 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14217 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE"
14218 {
14219 if (!TARGET_SSE)
14220 operands[1] = force_reg (SFmode, operands[1]);
14221 })
14222
14223 (define_insn "sqrtsf2_1"
14224 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14225 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14226 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14227 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
14228 "@
14229 fsqrt
14230 sqrtss\t{%1, %0|%0, %1}"
14231 [(set_attr "type" "fpspc,sse")
14232 (set_attr "mode" "SF,SF")
14233 (set_attr "athlon_decode" "direct,*")])
14234
14235 (define_insn "sqrtsf2_1_sse_only"
14236 [(set (match_operand:SF 0 "register_operand" "=x")
14237 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14238 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14239 "sqrtss\t{%1, %0|%0, %1}"
14240 [(set_attr "type" "sse")
14241 (set_attr "mode" "SF")
14242 (set_attr "athlon_decode" "*")])
14243
14244 (define_insn "sqrtsf2_i387"
14245 [(set (match_operand:SF 0 "register_operand" "=f")
14246 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14247 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14248 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
14249 "fsqrt"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "SF")
14252 (set_attr "athlon_decode" "direct")])
14253
14254 (define_expand "sqrtdf2"
14255 [(set (match_operand:DF 0 "register_operand" "")
14256 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14257 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
14258 {
14259 if (!TARGET_SSE2)
14260 operands[1] = force_reg (DFmode, operands[1]);
14261 })
14262
14263 (define_insn "sqrtdf2_1"
14264 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14265 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14266 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14267 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
14268 "@
14269 fsqrt
14270 sqrtsd\t{%1, %0|%0, %1}"
14271 [(set_attr "type" "fpspc,sse")
14272 (set_attr "mode" "DF,DF")
14273 (set_attr "athlon_decode" "direct,*")])
14274
14275 (define_insn "sqrtdf2_1_sse_only"
14276 [(set (match_operand:DF 0 "register_operand" "=Y")
14277 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14278 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14279 "sqrtsd\t{%1, %0|%0, %1}"
14280 [(set_attr "type" "sse")
14281 (set_attr "mode" "DF")
14282 (set_attr "athlon_decode" "*")])
14283
14284 (define_insn "sqrtdf2_i387"
14285 [(set (match_operand:DF 0 "register_operand" "=f")
14286 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14287 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14288 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
14289 "fsqrt"
14290 [(set_attr "type" "fpspc")
14291 (set_attr "mode" "DF")
14292 (set_attr "athlon_decode" "direct")])
14293
14294 (define_insn "*sqrtextendsfdf2"
14295 [(set (match_operand:DF 0 "register_operand" "=f")
14296 (sqrt:DF (float_extend:DF
14297 (match_operand:SF 1 "register_operand" "0"))))]
14298 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2"
14299 "fsqrt"
14300 [(set_attr "type" "fpspc")
14301 (set_attr "mode" "DF")
14302 (set_attr "athlon_decode" "direct")])
14303
14304 (define_insn "sqrtxf2"
14305 [(set (match_operand:XF 0 "register_operand" "=f")
14306 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14307 "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14308 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14309 "fsqrt"
14310 [(set_attr "type" "fpspc")
14311 (set_attr "mode" "XF")
14312 (set_attr "athlon_decode" "direct")])
14313
14314 (define_insn "sqrttf2"
14315 [(set (match_operand:TF 0 "register_operand" "=f")
14316 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14317 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14318 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14319 "fsqrt"
14320 [(set_attr "type" "fpspc")
14321 (set_attr "mode" "XF")
14322 (set_attr "athlon_decode" "direct")])
14323
14324 (define_insn "*sqrtextenddfxf2"
14325 [(set (match_operand:XF 0 "register_operand" "=f")
14326 (sqrt:XF (float_extend:XF
14327 (match_operand:DF 1 "register_operand" "0"))))]
14328 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14329 "fsqrt"
14330 [(set_attr "type" "fpspc")
14331 (set_attr "mode" "XF")
14332 (set_attr "athlon_decode" "direct")])
14333
14334 (define_insn "*sqrtextenddftf2"
14335 [(set (match_operand:TF 0 "register_operand" "=f")
14336 (sqrt:TF (float_extend:TF
14337 (match_operand:DF 1 "register_operand" "0"))))]
14338 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14339 "fsqrt"
14340 [(set_attr "type" "fpspc")
14341 (set_attr "mode" "XF")
14342 (set_attr "athlon_decode" "direct")])
14343
14344 (define_insn "*sqrtextendsfxf2"
14345 [(set (match_operand:XF 0 "register_operand" "=f")
14346 (sqrt:XF (float_extend:XF
14347 (match_operand:SF 1 "register_operand" "0"))))]
14348 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
14349 "fsqrt"
14350 [(set_attr "type" "fpspc")
14351 (set_attr "mode" "XF")
14352 (set_attr "athlon_decode" "direct")])
14353
14354 (define_insn "*sqrtextendsftf2"
14355 [(set (match_operand:TF 0 "register_operand" "=f")
14356 (sqrt:TF (float_extend:TF
14357 (match_operand:SF 1 "register_operand" "0"))))]
14358 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14359 "fsqrt"
14360 [(set_attr "type" "fpspc")
14361 (set_attr "mode" "XF")
14362 (set_attr "athlon_decode" "direct")])
14363
14364 (define_insn "sindf2"
14365 [(set (match_operand:DF 0 "register_operand" "=f")
14366 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14367 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14368 && flag_unsafe_math_optimizations"
14369 "fsin"
14370 [(set_attr "type" "fpspc")
14371 (set_attr "mode" "DF")])
14372
14373 (define_insn "sinsf2"
14374 [(set (match_operand:SF 0 "register_operand" "=f")
14375 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14376 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14377 && flag_unsafe_math_optimizations"
14378 "fsin"
14379 [(set_attr "type" "fpspc")
14380 (set_attr "mode" "SF")])
14381
14382 (define_insn "*sinextendsfdf2"
14383 [(set (match_operand:DF 0 "register_operand" "=f")
14384 (unspec:DF [(float_extend:DF
14385 (match_operand:SF 1 "register_operand" "0"))] 1))]
14386 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14387 && flag_unsafe_math_optimizations"
14388 "fsin"
14389 [(set_attr "type" "fpspc")
14390 (set_attr "mode" "DF")])
14391
14392 (define_insn "sinxf2"
14393 [(set (match_operand:XF 0 "register_operand" "=f")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14395 "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
14396 && flag_unsafe_math_optimizations"
14397 "fsin"
14398 [(set_attr "type" "fpspc")
14399 (set_attr "mode" "XF")])
14400
14401 (define_insn "sintf2"
14402 [(set (match_operand:TF 0 "register_operand" "=f")
14403 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14404 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14405 && flag_unsafe_math_optimizations"
14406 "fsin"
14407 [(set_attr "type" "fpspc")
14408 (set_attr "mode" "XF")])
14409
14410 (define_insn "cosdf2"
14411 [(set (match_operand:DF 0 "register_operand" "=f")
14412 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14414 && flag_unsafe_math_optimizations"
14415 "fcos"
14416 [(set_attr "type" "fpspc")
14417 (set_attr "mode" "DF")])
14418
14419 (define_insn "cossf2"
14420 [(set (match_operand:SF 0 "register_operand" "=f")
14421 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14422 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14423 && flag_unsafe_math_optimizations"
14424 "fcos"
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "SF")])
14427
14428 (define_insn "*cosextendsfdf2"
14429 [(set (match_operand:DF 0 "register_operand" "=f")
14430 (unspec:DF [(float_extend:DF
14431 (match_operand:SF 1 "register_operand" "0"))] 2))]
14432 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14433 && flag_unsafe_math_optimizations"
14434 "fcos"
14435 [(set_attr "type" "fpspc")
14436 (set_attr "mode" "DF")])
14437
14438 (define_insn "cosxf2"
14439 [(set (match_operand:XF 0 "register_operand" "=f")
14440 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14441 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14442 && flag_unsafe_math_optimizations"
14443 "fcos"
14444 [(set_attr "type" "fpspc")
14445 (set_attr "mode" "XF")])
14446
14447 (define_insn "costf2"
14448 [(set (match_operand:TF 0 "register_operand" "=f")
14449 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14450 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14451 && flag_unsafe_math_optimizations"
14452 "fcos"
14453 [(set_attr "type" "fpspc")
14454 (set_attr "mode" "XF")])
14455 \f
14456 ;; Block operation instructions
14457
14458 (define_insn "cld"
14459 [(set (reg:SI 19) (const_int 0))]
14460 ""
14461 "cld"
14462 [(set_attr "type" "cld")])
14463
14464 (define_expand "movstrsi"
14465 [(use (match_operand:BLK 0 "memory_operand" ""))
14466 (use (match_operand:BLK 1 "memory_operand" ""))
14467 (use (match_operand:SI 2 "nonmemory_operand" ""))
14468 (use (match_operand:SI 3 "const_int_operand" ""))]
14469 ""
14470 {
14471 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14472 DONE;
14473 else
14474 FAIL;
14475 })
14476
14477 (define_expand "movstrdi"
14478 [(use (match_operand:BLK 0 "memory_operand" ""))
14479 (use (match_operand:BLK 1 "memory_operand" ""))
14480 (use (match_operand:DI 2 "nonmemory_operand" ""))
14481 (use (match_operand:DI 3 "const_int_operand" ""))]
14482 "TARGET_64BIT"
14483 {
14484 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14485 DONE;
14486 else
14487 FAIL;
14488 })
14489
14490 ;; Most CPUs don't like single string operations
14491 ;; Handle this case here to simplify previous expander.
14492
14493 (define_expand "strmovdi_rex64"
14494 [(set (match_dup 2)
14495 (mem:DI (match_operand:DI 1 "register_operand" "")))
14496 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14497 (match_dup 2))
14498 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14499 (clobber (reg:CC 17))])
14500 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14501 (clobber (reg:CC 17))])]
14502 "TARGET_64BIT"
14503 {
14504 if (TARGET_SINGLE_STRINGOP || optimize_size)
14505 {
14506 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14507 operands[1]));
14508 DONE;
14509 }
14510 else
14511 operands[2] = gen_reg_rtx (DImode);
14512 })
14513
14514
14515 (define_expand "strmovsi"
14516 [(set (match_dup 2)
14517 (mem:SI (match_operand:SI 1 "register_operand" "")))
14518 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14519 (match_dup 2))
14520 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14521 (clobber (reg:CC 17))])
14522 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14523 (clobber (reg:CC 17))])]
14524 ""
14525 {
14526 if (TARGET_64BIT)
14527 {
14528 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14529 DONE;
14530 }
14531 if (TARGET_SINGLE_STRINGOP || optimize_size)
14532 {
14533 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14534 operands[1]));
14535 DONE;
14536 }
14537 else
14538 operands[2] = gen_reg_rtx (SImode);
14539 })
14540
14541 (define_expand "strmovsi_rex64"
14542 [(set (match_dup 2)
14543 (mem:SI (match_operand:DI 1 "register_operand" "")))
14544 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14545 (match_dup 2))
14546 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14547 (clobber (reg:CC 17))])
14548 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14549 (clobber (reg:CC 17))])]
14550 "TARGET_64BIT"
14551 {
14552 if (TARGET_SINGLE_STRINGOP || optimize_size)
14553 {
14554 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14555 operands[1]));
14556 DONE;
14557 }
14558 else
14559 operands[2] = gen_reg_rtx (SImode);
14560 })
14561
14562 (define_expand "strmovhi"
14563 [(set (match_dup 2)
14564 (mem:HI (match_operand:SI 1 "register_operand" "")))
14565 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14566 (match_dup 2))
14567 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14568 (clobber (reg:CC 17))])
14569 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14570 (clobber (reg:CC 17))])]
14571 ""
14572 {
14573 if (TARGET_64BIT)
14574 {
14575 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14576 DONE;
14577 }
14578 if (TARGET_SINGLE_STRINGOP || optimize_size)
14579 {
14580 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14581 operands[1]));
14582 DONE;
14583 }
14584 else
14585 operands[2] = gen_reg_rtx (HImode);
14586 })
14587
14588 (define_expand "strmovhi_rex64"
14589 [(set (match_dup 2)
14590 (mem:HI (match_operand:DI 1 "register_operand" "")))
14591 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14592 (match_dup 2))
14593 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14594 (clobber (reg:CC 17))])
14595 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14596 (clobber (reg:CC 17))])]
14597 "TARGET_64BIT"
14598 {
14599 if (TARGET_SINGLE_STRINGOP || optimize_size)
14600 {
14601 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14602 operands[1]));
14603 DONE;
14604 }
14605 else
14606 operands[2] = gen_reg_rtx (HImode);
14607 })
14608
14609 (define_expand "strmovqi"
14610 [(set (match_dup 2)
14611 (mem:QI (match_operand:SI 1 "register_operand" "")))
14612 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14613 (match_dup 2))
14614 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14615 (clobber (reg:CC 17))])
14616 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14617 (clobber (reg:CC 17))])]
14618 ""
14619 {
14620 if (TARGET_64BIT)
14621 {
14622 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14623 DONE;
14624 }
14625 if (TARGET_SINGLE_STRINGOP || optimize_size)
14626 {
14627 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14628 operands[1]));
14629 DONE;
14630 }
14631 else
14632 operands[2] = gen_reg_rtx (QImode);
14633 })
14634
14635 (define_expand "strmovqi_rex64"
14636 [(set (match_dup 2)
14637 (mem:QI (match_operand:DI 1 "register_operand" "")))
14638 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14639 (match_dup 2))
14640 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14641 (clobber (reg:CC 17))])
14642 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14643 (clobber (reg:CC 17))])]
14644 "TARGET_64BIT"
14645 {
14646 if (TARGET_SINGLE_STRINGOP || optimize_size)
14647 {
14648 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14649 operands[1]));
14650 DONE;
14651 }
14652 else
14653 operands[2] = gen_reg_rtx (QImode);
14654 })
14655
14656 (define_insn "strmovdi_rex_1"
14657 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14658 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14659 (set (match_operand:DI 0 "register_operand" "=D")
14660 (plus:DI (match_dup 2)
14661 (const_int 8)))
14662 (set (match_operand:DI 1 "register_operand" "=S")
14663 (plus:DI (match_dup 3)
14664 (const_int 8)))
14665 (use (reg:SI 19))]
14666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14667 "movsq"
14668 [(set_attr "type" "str")
14669 (set_attr "mode" "DI")
14670 (set_attr "memory" "both")])
14671
14672 (define_insn "strmovsi_1"
14673 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14674 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14675 (set (match_operand:SI 0 "register_operand" "=D")
14676 (plus:SI (match_dup 2)
14677 (const_int 4)))
14678 (set (match_operand:SI 1 "register_operand" "=S")
14679 (plus:SI (match_dup 3)
14680 (const_int 4)))
14681 (use (reg:SI 19))]
14682 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14683 "{movsl|movsd}"
14684 [(set_attr "type" "str")
14685 (set_attr "mode" "SI")
14686 (set_attr "memory" "both")])
14687
14688 (define_insn "strmovsi_rex_1"
14689 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14690 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14691 (set (match_operand:DI 0 "register_operand" "=D")
14692 (plus:DI (match_dup 2)
14693 (const_int 4)))
14694 (set (match_operand:DI 1 "register_operand" "=S")
14695 (plus:DI (match_dup 3)
14696 (const_int 4)))
14697 (use (reg:SI 19))]
14698 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14699 "{movsl|movsd}"
14700 [(set_attr "type" "str")
14701 (set_attr "mode" "SI")
14702 (set_attr "memory" "both")])
14703
14704 (define_insn "strmovhi_1"
14705 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14706 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14707 (set (match_operand:SI 0 "register_operand" "=D")
14708 (plus:SI (match_dup 2)
14709 (const_int 2)))
14710 (set (match_operand:SI 1 "register_operand" "=S")
14711 (plus:SI (match_dup 3)
14712 (const_int 2)))
14713 (use (reg:SI 19))]
14714 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14715 "movsw"
14716 [(set_attr "type" "str")
14717 (set_attr "memory" "both")
14718 (set_attr "mode" "HI")])
14719
14720 (define_insn "strmovhi_rex_1"
14721 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14722 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14723 (set (match_operand:DI 0 "register_operand" "=D")
14724 (plus:DI (match_dup 2)
14725 (const_int 2)))
14726 (set (match_operand:DI 1 "register_operand" "=S")
14727 (plus:DI (match_dup 3)
14728 (const_int 2)))
14729 (use (reg:SI 19))]
14730 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14731 "movsw"
14732 [(set_attr "type" "str")
14733 (set_attr "memory" "both")
14734 (set_attr "mode" "HI")])
14735
14736 (define_insn "strmovqi_1"
14737 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14738 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14739 (set (match_operand:SI 0 "register_operand" "=D")
14740 (plus:SI (match_dup 2)
14741 (const_int 1)))
14742 (set (match_operand:SI 1 "register_operand" "=S")
14743 (plus:SI (match_dup 3)
14744 (const_int 1)))
14745 (use (reg:SI 19))]
14746 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14747 "movsb"
14748 [(set_attr "type" "str")
14749 (set_attr "memory" "both")
14750 (set_attr "mode" "QI")])
14751
14752 (define_insn "strmovqi_rex_1"
14753 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14754 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14755 (set (match_operand:DI 0 "register_operand" "=D")
14756 (plus:DI (match_dup 2)
14757 (const_int 1)))
14758 (set (match_operand:DI 1 "register_operand" "=S")
14759 (plus:DI (match_dup 3)
14760 (const_int 1)))
14761 (use (reg:SI 19))]
14762 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14763 "movsb"
14764 [(set_attr "type" "str")
14765 (set_attr "memory" "both")
14766 (set_attr "mode" "QI")])
14767
14768 (define_insn "rep_movdi_rex64"
14769 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14770 (set (match_operand:DI 0 "register_operand" "=D")
14771 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14772 (const_int 3))
14773 (match_operand:DI 3 "register_operand" "0")))
14774 (set (match_operand:DI 1 "register_operand" "=S")
14775 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
14776 (match_operand:DI 4 "register_operand" "1")))
14777 (set (mem:BLK (match_dup 3))
14778 (mem:BLK (match_dup 4)))
14779 (use (match_dup 5))
14780 (use (reg:SI 19))]
14781 "TARGET_64BIT"
14782 "rep\;movsq|rep movsq"
14783 [(set_attr "type" "str")
14784 (set_attr "prefix_rep" "1")
14785 (set_attr "memory" "both")
14786 (set_attr "mode" "DI")])
14787
14788 (define_insn "rep_movsi"
14789 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14790 (set (match_operand:SI 0 "register_operand" "=D")
14791 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
14792 (const_int 2))
14793 (match_operand:SI 3 "register_operand" "0")))
14794 (set (match_operand:SI 1 "register_operand" "=S")
14795 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
14796 (match_operand:SI 4 "register_operand" "1")))
14797 (set (mem:BLK (match_dup 3))
14798 (mem:BLK (match_dup 4)))
14799 (use (match_dup 5))
14800 (use (reg:SI 19))]
14801 "!TARGET_64BIT"
14802 "rep\;movsl|rep movsd"
14803 [(set_attr "type" "str")
14804 (set_attr "prefix_rep" "1")
14805 (set_attr "memory" "both")
14806 (set_attr "mode" "SI")])
14807
14808 (define_insn "rep_movsi_rex64"
14809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14810 (set (match_operand:DI 0 "register_operand" "=D")
14811 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14812 (const_int 2))
14813 (match_operand:DI 3 "register_operand" "0")))
14814 (set (match_operand:DI 1 "register_operand" "=S")
14815 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
14816 (match_operand:DI 4 "register_operand" "1")))
14817 (set (mem:BLK (match_dup 3))
14818 (mem:BLK (match_dup 4)))
14819 (use (match_dup 5))
14820 (use (reg:SI 19))]
14821 "TARGET_64BIT"
14822 "rep\;movsl|rep movsd"
14823 [(set_attr "type" "str")
14824 (set_attr "prefix_rep" "1")
14825 (set_attr "memory" "both")
14826 (set_attr "mode" "SI")])
14827
14828 (define_insn "rep_movqi"
14829 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14830 (set (match_operand:SI 0 "register_operand" "=D")
14831 (plus:SI (match_operand:SI 3 "register_operand" "0")
14832 (match_operand:SI 5 "register_operand" "2")))
14833 (set (match_operand:SI 1 "register_operand" "=S")
14834 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
14835 (set (mem:BLK (match_dup 3))
14836 (mem:BLK (match_dup 4)))
14837 (use (match_dup 5))
14838 (use (reg:SI 19))]
14839 "!TARGET_64BIT"
14840 "rep\;movsb|rep movsb"
14841 [(set_attr "type" "str")
14842 (set_attr "prefix_rep" "1")
14843 (set_attr "memory" "both")
14844 (set_attr "mode" "SI")])
14845
14846 (define_insn "rep_movqi_rex64"
14847 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14848 (set (match_operand:DI 0 "register_operand" "=D")
14849 (plus:DI (match_operand:DI 3 "register_operand" "0")
14850 (match_operand:DI 5 "register_operand" "2")))
14851 (set (match_operand:DI 1 "register_operand" "=S")
14852 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
14853 (set (mem:BLK (match_dup 3))
14854 (mem:BLK (match_dup 4)))
14855 (use (match_dup 5))
14856 (use (reg:SI 19))]
14857 "TARGET_64BIT"
14858 "rep\;movsb|rep movsb"
14859 [(set_attr "type" "str")
14860 (set_attr "prefix_rep" "1")
14861 (set_attr "memory" "both")
14862 (set_attr "mode" "SI")])
14863
14864 (define_expand "clrstrsi"
14865 [(use (match_operand:BLK 0 "memory_operand" ""))
14866 (use (match_operand:SI 1 "nonmemory_operand" ""))
14867 (use (match_operand 2 "const_int_operand" ""))]
14868 ""
14869 {
14870 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14871 DONE;
14872 else
14873 FAIL;
14874 })
14875
14876 (define_expand "clrstrdi"
14877 [(use (match_operand:BLK 0 "memory_operand" ""))
14878 (use (match_operand:DI 1 "nonmemory_operand" ""))
14879 (use (match_operand 2 "const_int_operand" ""))]
14880 "TARGET_64BIT"
14881 {
14882 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14883 DONE;
14884 else
14885 FAIL;
14886 })
14887
14888 ;; Most CPUs don't like single string operations
14889 ;; Handle this case here to simplify previous expander.
14890
14891 (define_expand "strsetdi_rex64"
14892 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
14893 (match_operand:DI 1 "register_operand" ""))
14894 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14895 (clobber (reg:CC 17))])]
14896 "TARGET_64BIT"
14897 {
14898 if (TARGET_SINGLE_STRINGOP || optimize_size)
14899 {
14900 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
14901 DONE;
14902 }
14903 })
14904
14905 (define_expand "strsetsi"
14906 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
14907 (match_operand:SI 1 "register_operand" ""))
14908 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14909 (clobber (reg:CC 17))])]
14910 ""
14911 {
14912 if (TARGET_64BIT)
14913 {
14914 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
14915 DONE;
14916 }
14917 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14918 {
14919 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
14920 DONE;
14921 }
14922 })
14923
14924 (define_expand "strsetsi_rex64"
14925 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
14926 (match_operand:SI 1 "register_operand" ""))
14927 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14928 (clobber (reg:CC 17))])]
14929 "TARGET_64BIT"
14930 {
14931 if (TARGET_SINGLE_STRINGOP || optimize_size)
14932 {
14933 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
14934 DONE;
14935 }
14936 })
14937
14938 (define_expand "strsethi"
14939 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
14940 (match_operand:HI 1 "register_operand" ""))
14941 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14942 (clobber (reg:CC 17))])]
14943 ""
14944 {
14945 if (TARGET_64BIT)
14946 {
14947 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
14948 DONE;
14949 }
14950 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14951 {
14952 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
14953 DONE;
14954 }
14955 })
14956
14957 (define_expand "strsethi_rex64"
14958 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
14959 (match_operand:HI 1 "register_operand" ""))
14960 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14961 (clobber (reg:CC 17))])]
14962 "TARGET_64BIT"
14963 {
14964 if (TARGET_SINGLE_STRINGOP || optimize_size)
14965 {
14966 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
14967 DONE;
14968 }
14969 })
14970
14971 (define_expand "strsetqi"
14972 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
14973 (match_operand:QI 1 "register_operand" ""))
14974 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14975 (clobber (reg:CC 17))])]
14976 ""
14977 {
14978 if (TARGET_64BIT)
14979 {
14980 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
14981 DONE;
14982 }
14983 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14984 {
14985 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
14986 DONE;
14987 }
14988 })
14989
14990 (define_expand "strsetqi_rex64"
14991 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
14992 (match_operand:QI 1 "register_operand" ""))
14993 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14994 (clobber (reg:CC 17))])]
14995 "TARGET_64BIT"
14996 {
14997 if (TARGET_SINGLE_STRINGOP || optimize_size)
14998 {
14999 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15000 DONE;
15001 }
15002 })
15003
15004 (define_insn "strsetdi_rex_1"
15005 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15006 (match_operand:SI 2 "register_operand" "a"))
15007 (set (match_operand:DI 0 "register_operand" "=D")
15008 (plus:DI (match_dup 1)
15009 (const_int 8)))
15010 (use (reg:SI 19))]
15011 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15012 "stosq"
15013 [(set_attr "type" "str")
15014 (set_attr "memory" "store")
15015 (set_attr "mode" "DI")])
15016
15017 (define_insn "strsetsi_1"
15018 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15019 (match_operand:SI 2 "register_operand" "a"))
15020 (set (match_operand:SI 0 "register_operand" "=D")
15021 (plus:SI (match_dup 1)
15022 (const_int 4)))
15023 (use (reg:SI 19))]
15024 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15025 "stosl|stosd"
15026 [(set_attr "type" "str")
15027 (set_attr "memory" "store")
15028 (set_attr "mode" "SI")])
15029
15030 (define_insn "strsetsi_rex_1"
15031 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15032 (match_operand:SI 2 "register_operand" "a"))
15033 (set (match_operand:DI 0 "register_operand" "=D")
15034 (plus:DI (match_dup 1)
15035 (const_int 4)))
15036 (use (reg:SI 19))]
15037 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15038 "stosl|stosd"
15039 [(set_attr "type" "str")
15040 (set_attr "memory" "store")
15041 (set_attr "mode" "SI")])
15042
15043 (define_insn "strsethi_1"
15044 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15045 (match_operand:HI 2 "register_operand" "a"))
15046 (set (match_operand:SI 0 "register_operand" "=D")
15047 (plus:SI (match_dup 1)
15048 (const_int 2)))
15049 (use (reg:SI 19))]
15050 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15051 "stosw"
15052 [(set_attr "type" "str")
15053 (set_attr "memory" "store")
15054 (set_attr "mode" "HI")])
15055
15056 (define_insn "strsethi_rex_1"
15057 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15058 (match_operand:HI 2 "register_operand" "a"))
15059 (set (match_operand:DI 0 "register_operand" "=D")
15060 (plus:DI (match_dup 1)
15061 (const_int 2)))
15062 (use (reg:SI 19))]
15063 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15064 "stosw"
15065 [(set_attr "type" "str")
15066 (set_attr "memory" "store")
15067 (set_attr "mode" "HI")])
15068
15069 (define_insn "strsetqi_1"
15070 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15071 (match_operand:QI 2 "register_operand" "a"))
15072 (set (match_operand:SI 0 "register_operand" "=D")
15073 (plus:SI (match_dup 1)
15074 (const_int 1)))
15075 (use (reg:SI 19))]
15076 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15077 "stosb"
15078 [(set_attr "type" "str")
15079 (set_attr "memory" "store")
15080 (set_attr "mode" "QI")])
15081
15082 (define_insn "strsetqi_rex_1"
15083 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15084 (match_operand:QI 2 "register_operand" "a"))
15085 (set (match_operand:DI 0 "register_operand" "=D")
15086 (plus:DI (match_dup 1)
15087 (const_int 1)))
15088 (use (reg:SI 19))]
15089 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15090 "stosb"
15091 [(set_attr "type" "str")
15092 (set_attr "memory" "store")
15093 (set_attr "mode" "QI")])
15094
15095 (define_insn "rep_stosdi_rex64"
15096 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15097 (set (match_operand:DI 0 "register_operand" "=D")
15098 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15099 (const_int 3))
15100 (match_operand:DI 3 "register_operand" "0")))
15101 (set (mem:BLK (match_dup 3))
15102 (const_int 0))
15103 (use (match_operand:DI 2 "register_operand" "a"))
15104 (use (match_dup 4))
15105 (use (reg:SI 19))]
15106 "TARGET_64BIT"
15107 "rep\;stosq|rep stosq"
15108 [(set_attr "type" "str")
15109 (set_attr "prefix_rep" "1")
15110 (set_attr "memory" "store")
15111 (set_attr "mode" "DI")])
15112
15113 (define_insn "rep_stossi"
15114 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15115 (set (match_operand:SI 0 "register_operand" "=D")
15116 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15117 (const_int 2))
15118 (match_operand:SI 3 "register_operand" "0")))
15119 (set (mem:BLK (match_dup 3))
15120 (const_int 0))
15121 (use (match_operand:SI 2 "register_operand" "a"))
15122 (use (match_dup 4))
15123 (use (reg:SI 19))]
15124 "!TARGET_64BIT"
15125 "rep\;stosl|rep stosd"
15126 [(set_attr "type" "str")
15127 (set_attr "prefix_rep" "1")
15128 (set_attr "memory" "store")
15129 (set_attr "mode" "SI")])
15130
15131 (define_insn "rep_stossi_rex64"
15132 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15133 (set (match_operand:DI 0 "register_operand" "=D")
15134 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15135 (const_int 2))
15136 (match_operand:DI 3 "register_operand" "0")))
15137 (set (mem:BLK (match_dup 3))
15138 (const_int 0))
15139 (use (match_operand:SI 2 "register_operand" "a"))
15140 (use (match_dup 4))
15141 (use (reg:SI 19))]
15142 "TARGET_64BIT"
15143 "rep\;stosl|rep stosd"
15144 [(set_attr "type" "str")
15145 (set_attr "prefix_rep" "1")
15146 (set_attr "memory" "store")
15147 (set_attr "mode" "SI")])
15148
15149 (define_insn "rep_stosqi"
15150 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15151 (set (match_operand:SI 0 "register_operand" "=D")
15152 (plus:SI (match_operand:SI 3 "register_operand" "0")
15153 (match_operand:SI 4 "register_operand" "1")))
15154 (set (mem:BLK (match_dup 3))
15155 (const_int 0))
15156 (use (match_operand:QI 2 "register_operand" "a"))
15157 (use (match_dup 4))
15158 (use (reg:SI 19))]
15159 "!TARGET_64BIT"
15160 "rep\;stosb|rep stosb"
15161 [(set_attr "type" "str")
15162 (set_attr "prefix_rep" "1")
15163 (set_attr "memory" "store")
15164 (set_attr "mode" "QI")])
15165
15166 (define_insn "rep_stosqi_rex64"
15167 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15168 (set (match_operand:DI 0 "register_operand" "=D")
15169 (plus:DI (match_operand:DI 3 "register_operand" "0")
15170 (match_operand:DI 4 "register_operand" "1")))
15171 (set (mem:BLK (match_dup 3))
15172 (const_int 0))
15173 (use (match_operand:QI 2 "register_operand" "a"))
15174 (use (match_dup 4))
15175 (use (reg:DI 19))]
15176 "TARGET_64BIT"
15177 "rep\;stosb|rep stosb"
15178 [(set_attr "type" "str")
15179 (set_attr "prefix_rep" "1")
15180 (set_attr "memory" "store")
15181 (set_attr "mode" "QI")])
15182
15183 (define_expand "cmpstrsi"
15184 [(set (match_operand:SI 0 "register_operand" "")
15185 (compare:SI (match_operand:BLK 1 "general_operand" "")
15186 (match_operand:BLK 2 "general_operand" "")))
15187 (use (match_operand 3 "general_operand" ""))
15188 (use (match_operand 4 "immediate_operand" ""))]
15189 ""
15190 {
15191 rtx addr1, addr2, out, outlow, count, countreg, align;
15192
15193 out = operands[0];
15194 if (GET_CODE (out) != REG)
15195 out = gen_reg_rtx (SImode);
15196
15197 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15198 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15199
15200 count = operands[3];
15201 countreg = ix86_zero_extend_to_Pmode (count);
15202
15203 /* %%% Iff we are testing strict equality, we can use known alignment
15204 to good advantage. This may be possible with combine, particularly
15205 once cc0 is dead. */
15206 align = operands[4];
15207
15208 emit_insn (gen_cld ());
15209 if (GET_CODE (count) == CONST_INT)
15210 {
15211 if (INTVAL (count) == 0)
15212 {
15213 emit_move_insn (operands[0], const0_rtx);
15214 DONE;
15215 }
15216 if (TARGET_64BIT)
15217 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15218 addr1, addr2, countreg));
15219 else
15220 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15221 addr1, addr2, countreg));
15222 }
15223 else
15224 {
15225 if (TARGET_64BIT)
15226 {
15227 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15228 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15229 addr1, addr2, countreg));
15230 }
15231 else
15232 {
15233 emit_insn (gen_cmpsi_1 (countreg, countreg));
15234 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15235 addr1, addr2, countreg));
15236 }
15237 }
15238
15239 outlow = gen_lowpart (QImode, out);
15240 emit_insn (gen_cmpintqi (outlow));
15241 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15242
15243 if (operands[0] != out)
15244 emit_move_insn (operands[0], out);
15245
15246 DONE;
15247 })
15248
15249 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15250
15251 (define_expand "cmpintqi"
15252 [(set (match_dup 1)
15253 (gtu:QI (reg:CC 17) (const_int 0)))
15254 (set (match_dup 2)
15255 (ltu:QI (reg:CC 17) (const_int 0)))
15256 (parallel [(set (match_operand:QI 0 "register_operand" "")
15257 (minus:QI (match_dup 1)
15258 (match_dup 2)))
15259 (clobber (reg:CC 17))])]
15260 ""
15261 "operands[1] = gen_reg_rtx (QImode);
15262 operands[2] = gen_reg_rtx (QImode);")
15263
15264 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15265 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15266
15267 (define_insn "cmpstrqi_nz_1"
15268 [(set (reg:CC 17)
15269 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15270 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15271 (use (match_operand:SI 6 "register_operand" "2"))
15272 (use (match_operand:SI 3 "immediate_operand" "i"))
15273 (use (reg:SI 19))
15274 (clobber (match_operand:SI 0 "register_operand" "=S"))
15275 (clobber (match_operand:SI 1 "register_operand" "=D"))
15276 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15277 "!TARGET_64BIT"
15278 "repz{\;| }cmpsb"
15279 [(set_attr "type" "str")
15280 (set_attr "mode" "QI")
15281 (set_attr "prefix_rep" "1")])
15282
15283 (define_insn "cmpstrqi_nz_rex_1"
15284 [(set (reg:CC 17)
15285 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15286 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15287 (use (match_operand:DI 6 "register_operand" "2"))
15288 (use (match_operand:SI 3 "immediate_operand" "i"))
15289 (use (reg:SI 19))
15290 (clobber (match_operand:DI 0 "register_operand" "=S"))
15291 (clobber (match_operand:DI 1 "register_operand" "=D"))
15292 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15293 "TARGET_64BIT"
15294 "repz{\;| }cmpsb"
15295 [(set_attr "type" "str")
15296 (set_attr "mode" "QI")
15297 (set_attr "prefix_rep" "1")])
15298
15299 ;; The same, but the count is not known to not be zero.
15300
15301 (define_insn "cmpstrqi_1"
15302 [(set (reg:CC 17)
15303 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15304 (const_int 0))
15305 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15306 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15307 (const_int 0)))
15308 (use (match_operand:SI 3 "immediate_operand" "i"))
15309 (use (reg:CC 17))
15310 (use (reg:SI 19))
15311 (clobber (match_operand:SI 0 "register_operand" "=S"))
15312 (clobber (match_operand:SI 1 "register_operand" "=D"))
15313 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15314 "!TARGET_64BIT"
15315 "repz{\;| }cmpsb"
15316 [(set_attr "type" "str")
15317 (set_attr "mode" "QI")
15318 (set_attr "prefix_rep" "1")])
15319
15320 (define_insn "cmpstrqi_rex_1"
15321 [(set (reg:CC 17)
15322 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15323 (const_int 0))
15324 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15325 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15326 (const_int 0)))
15327 (use (match_operand:SI 3 "immediate_operand" "i"))
15328 (use (reg:CC 17))
15329 (use (reg:SI 19))
15330 (clobber (match_operand:DI 0 "register_operand" "=S"))
15331 (clobber (match_operand:DI 1 "register_operand" "=D"))
15332 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15333 "TARGET_64BIT"
15334 "repz{\;| }cmpsb"
15335 [(set_attr "type" "str")
15336 (set_attr "mode" "QI")
15337 (set_attr "prefix_rep" "1")])
15338
15339 (define_expand "strlensi"
15340 [(set (match_operand:SI 0 "register_operand" "")
15341 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15342 (match_operand:QI 2 "immediate_operand" "")
15343 (match_operand 3 "immediate_operand" "")] 0))]
15344 ""
15345 {
15346 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15347 DONE;
15348 else
15349 FAIL;
15350 })
15351
15352 (define_expand "strlendi"
15353 [(set (match_operand:DI 0 "register_operand" "")
15354 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15355 (match_operand:QI 2 "immediate_operand" "")
15356 (match_operand 3 "immediate_operand" "")] 0))]
15357 ""
15358 {
15359 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15360 DONE;
15361 else
15362 FAIL;
15363 })
15364
15365 (define_insn "strlenqi_1"
15366 [(set (match_operand:SI 0 "register_operand" "=&c")
15367 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15368 (match_operand:QI 2 "register_operand" "a")
15369 (match_operand:SI 3 "immediate_operand" "i")
15370 (match_operand:SI 4 "register_operand" "0")] 0))
15371 (use (reg:SI 19))
15372 (clobber (match_operand:SI 1 "register_operand" "=D"))
15373 (clobber (reg:CC 17))]
15374 "!TARGET_64BIT"
15375 "repnz{\;| }scasb"
15376 [(set_attr "type" "str")
15377 (set_attr "mode" "QI")
15378 (set_attr "prefix_rep" "1")])
15379
15380 (define_insn "strlenqi_rex_1"
15381 [(set (match_operand:DI 0 "register_operand" "=&c")
15382 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15383 (match_operand:QI 2 "register_operand" "a")
15384 (match_operand:DI 3 "immediate_operand" "i")
15385 (match_operand:DI 4 "register_operand" "0")] 0))
15386 (use (reg:SI 19))
15387 (clobber (match_operand:DI 1 "register_operand" "=D"))
15388 (clobber (reg:CC 17))]
15389 "TARGET_64BIT"
15390 "repnz{\;| }scasb"
15391 [(set_attr "type" "str")
15392 (set_attr "mode" "QI")
15393 (set_attr "prefix_rep" "1")])
15394
15395 ;; Peephole optimizations to clean up after cmpstr*. This should be
15396 ;; handled in combine, but it is not currently up to the task.
15397 ;; When used for their truth value, the cmpstr* expanders generate
15398 ;; code like this:
15399 ;;
15400 ;; repz cmpsb
15401 ;; seta %al
15402 ;; setb %dl
15403 ;; cmpb %al, %dl
15404 ;; jcc label
15405 ;;
15406 ;; The intermediate three instructions are unnecessary.
15407
15408 ;; This one handles cmpstr*_nz_1...
15409 (define_peephole2
15410 [(parallel[
15411 (set (reg:CC 17)
15412 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15413 (mem:BLK (match_operand 5 "register_operand" ""))))
15414 (use (match_operand 6 "register_operand" ""))
15415 (use (match_operand:SI 3 "immediate_operand" ""))
15416 (use (reg:SI 19))
15417 (clobber (match_operand 0 "register_operand" ""))
15418 (clobber (match_operand 1 "register_operand" ""))
15419 (clobber (match_operand 2 "register_operand" ""))])
15420 (set (match_operand:QI 7 "register_operand" "")
15421 (gtu:QI (reg:CC 17) (const_int 0)))
15422 (set (match_operand:QI 8 "register_operand" "")
15423 (ltu:QI (reg:CC 17) (const_int 0)))
15424 (set (reg 17)
15425 (compare (match_dup 7) (match_dup 8)))
15426 ]
15427 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15428 [(parallel[
15429 (set (reg:CC 17)
15430 (compare:CC (mem:BLK (match_dup 4))
15431 (mem:BLK (match_dup 5))))
15432 (use (match_dup 6))
15433 (use (match_dup 3))
15434 (use (reg:SI 19))
15435 (clobber (match_dup 0))
15436 (clobber (match_dup 1))
15437 (clobber (match_dup 2))])]
15438 "")
15439
15440 ;; ...and this one handles cmpstr*_1.
15441 (define_peephole2
15442 [(parallel[
15443 (set (reg:CC 17)
15444 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15445 (const_int 0))
15446 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15447 (mem:BLK (match_operand 5 "register_operand" "")))
15448 (const_int 0)))
15449 (use (match_operand:SI 3 "immediate_operand" ""))
15450 (use (reg:CC 17))
15451 (use (reg:SI 19))
15452 (clobber (match_operand 0 "register_operand" ""))
15453 (clobber (match_operand 1 "register_operand" ""))
15454 (clobber (match_operand 2 "register_operand" ""))])
15455 (set (match_operand:QI 7 "register_operand" "")
15456 (gtu:QI (reg:CC 17) (const_int 0)))
15457 (set (match_operand:QI 8 "register_operand" "")
15458 (ltu:QI (reg:CC 17) (const_int 0)))
15459 (set (reg 17)
15460 (compare (match_dup 7) (match_dup 8)))
15461 ]
15462 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15463 [(parallel[
15464 (set (reg:CC 17)
15465 (if_then_else:CC (ne (match_dup 6)
15466 (const_int 0))
15467 (compare:CC (mem:BLK (match_dup 4))
15468 (mem:BLK (match_dup 5)))
15469 (const_int 0)))
15470 (use (match_dup 3))
15471 (use (reg:CC 17))
15472 (use (reg:SI 19))
15473 (clobber (match_dup 0))
15474 (clobber (match_dup 1))
15475 (clobber (match_dup 2))])]
15476 "")
15477
15478
15479 \f
15480 ;; Conditional move instructions.
15481
15482 (define_expand "movdicc_rex64"
15483 [(set (match_operand:DI 0 "register_operand" "")
15484 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15485 (match_operand:DI 2 "x86_64_general_operand" "")
15486 (match_operand:DI 3 "x86_64_general_operand" "")))]
15487 "TARGET_64BIT"
15488 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15489
15490 (define_insn "x86_movdicc_0_m1_rex64"
15491 [(set (match_operand:DI 0 "register_operand" "=r")
15492 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15493 (const_int -1)
15494 (const_int 0)))
15495 (clobber (reg:CC 17))]
15496 "TARGET_64BIT"
15497 "sbb{q}\t%0, %0"
15498 ; Since we don't have the proper number of operands for an alu insn,
15499 ; fill in all the blanks.
15500 [(set_attr "type" "alu")
15501 (set_attr "memory" "none")
15502 (set_attr "imm_disp" "false")
15503 (set_attr "mode" "DI")
15504 (set_attr "length_immediate" "0")])
15505
15506 (define_insn "*movdicc_c_rex64"
15507 [(set (match_operand:DI 0 "register_operand" "=r,r")
15508 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15509 [(reg 17) (const_int 0)])
15510 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15511 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15512 "TARGET_64BIT && TARGET_CMOVE
15513 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15514 "@
15515 cmov%C1\t{%2, %0|%0, %2}
15516 cmov%c1\t{%3, %0|%0, %3}"
15517 [(set_attr "type" "icmov")
15518 (set_attr "mode" "DI")])
15519
15520 (define_expand "movsicc"
15521 [(set (match_operand:SI 0 "register_operand" "")
15522 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15523 (match_operand:SI 2 "general_operand" "")
15524 (match_operand:SI 3 "general_operand" "")))]
15525 ""
15526 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15527
15528 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15529 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15530 ;; So just document what we're doing explicitly.
15531
15532 (define_insn "x86_movsicc_0_m1"
15533 [(set (match_operand:SI 0 "register_operand" "=r")
15534 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15535 (const_int -1)
15536 (const_int 0)))
15537 (clobber (reg:CC 17))]
15538 ""
15539 "sbb{l}\t%0, %0"
15540 ; Since we don't have the proper number of operands for an alu insn,
15541 ; fill in all the blanks.
15542 [(set_attr "type" "alu")
15543 (set_attr "memory" "none")
15544 (set_attr "imm_disp" "false")
15545 (set_attr "mode" "SI")
15546 (set_attr "length_immediate" "0")])
15547
15548 (define_insn "*movsicc_noc"
15549 [(set (match_operand:SI 0 "register_operand" "=r,r")
15550 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15551 [(reg 17) (const_int 0)])
15552 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15553 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15554 "TARGET_CMOVE
15555 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15556 "@
15557 cmov%C1\t{%2, %0|%0, %2}
15558 cmov%c1\t{%3, %0|%0, %3}"
15559 [(set_attr "type" "icmov")
15560 (set_attr "mode" "SI")])
15561
15562 (define_expand "movhicc"
15563 [(set (match_operand:HI 0 "register_operand" "")
15564 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15565 (match_operand:HI 2 "nonimmediate_operand" "")
15566 (match_operand:HI 3 "nonimmediate_operand" "")))]
15567 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15568 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15569
15570 (define_insn "*movhicc_noc"
15571 [(set (match_operand:HI 0 "register_operand" "=r,r")
15572 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15573 [(reg 17) (const_int 0)])
15574 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15575 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15576 "TARGET_CMOVE
15577 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15578 "@
15579 cmov%C1\t{%2, %0|%0, %2}
15580 cmov%c1\t{%3, %0|%0, %3}"
15581 [(set_attr "type" "icmov")
15582 (set_attr "mode" "HI")])
15583
15584 (define_expand "movsfcc"
15585 [(set (match_operand:SF 0 "register_operand" "")
15586 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15587 (match_operand:SF 2 "register_operand" "")
15588 (match_operand:SF 3 "register_operand" "")))]
15589 "TARGET_CMOVE"
15590 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15591
15592 (define_insn "*movsfcc_1"
15593 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15594 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15595 [(reg 17) (const_int 0)])
15596 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15597 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15598 "TARGET_CMOVE
15599 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15600 "@
15601 fcmov%F1\t{%2, %0|%0, %2}
15602 fcmov%f1\t{%3, %0|%0, %3}
15603 cmov%C1\t{%2, %0|%0, %2}
15604 cmov%c1\t{%3, %0|%0, %3}"
15605 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15606 (set_attr "mode" "SF,SF,SI,SI")])
15607
15608 (define_expand "movdfcc"
15609 [(set (match_operand:DF 0 "register_operand" "")
15610 (if_then_else:DF (match_operand 1 "comparison_operator" "")
15611 (match_operand:DF 2 "register_operand" "")
15612 (match_operand:DF 3 "register_operand" "")))]
15613 "TARGET_CMOVE"
15614 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15615
15616 (define_insn "*movdfcc_1"
15617 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15618 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15619 [(reg 17) (const_int 0)])
15620 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15621 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15622 "!TARGET_64BIT && TARGET_CMOVE
15623 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15624 "@
15625 fcmov%F1\t{%2, %0|%0, %2}
15626 fcmov%f1\t{%3, %0|%0, %3}
15627 #
15628 #"
15629 [(set_attr "type" "fcmov,fcmov,multi,multi")
15630 (set_attr "mode" "DF")])
15631
15632 (define_insn "*movdfcc_1_rex64"
15633 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15634 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15635 [(reg 17) (const_int 0)])
15636 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15637 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15638 "TARGET_64BIT && TARGET_CMOVE
15639 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15640 "@
15641 fcmov%F1\t{%2, %0|%0, %2}
15642 fcmov%f1\t{%3, %0|%0, %3}
15643 cmov%C1\t{%2, %0|%0, %2}
15644 cmov%c1\t{%3, %0|%0, %3}"
15645 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15646 (set_attr "mode" "DF")])
15647
15648 (define_split
15649 [(set (match_operand:DF 0 "register_operand" "")
15650 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15651 [(match_operand 4 "" "") (const_int 0)])
15652 (match_operand:DF 2 "nonimmediate_operand" "")
15653 (match_operand:DF 3 "nonimmediate_operand" "")))]
15654 "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
15655 [(set (match_dup 2)
15656 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15657 (match_dup 5)
15658 (match_dup 7)))
15659 (set (match_dup 3)
15660 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15661 (match_dup 6)
15662 (match_dup 8)))]
15663 "split_di (operands+2, 1, operands+5, operands+6);
15664 split_di (operands+3, 1, operands+7, operands+8);
15665 split_di (operands, 1, operands+2, operands+3);")
15666
15667 (define_expand "movxfcc"
15668 [(set (match_operand:XF 0 "register_operand" "")
15669 (if_then_else:XF (match_operand 1 "comparison_operator" "")
15670 (match_operand:XF 2 "register_operand" "")
15671 (match_operand:XF 3 "register_operand" "")))]
15672 "!TARGET_64BIT && TARGET_CMOVE"
15673 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15674
15675 (define_expand "movtfcc"
15676 [(set (match_operand:TF 0 "register_operand" "")
15677 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15678 (match_operand:TF 2 "register_operand" "")
15679 (match_operand:TF 3 "register_operand" "")))]
15680 "TARGET_CMOVE"
15681 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15682
15683 (define_insn "*movxfcc_1"
15684 [(set (match_operand:XF 0 "register_operand" "=f,f")
15685 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15686 [(reg 17) (const_int 0)])
15687 (match_operand:XF 2 "register_operand" "f,0")
15688 (match_operand:XF 3 "register_operand" "0,f")))]
15689 "!TARGET_64BIT && TARGET_CMOVE"
15690 "@
15691 fcmov%F1\t{%2, %0|%0, %2}
15692 fcmov%f1\t{%3, %0|%0, %3}"
15693 [(set_attr "type" "fcmov")
15694 (set_attr "mode" "XF")])
15695
15696 (define_insn "*movtfcc_1"
15697 [(set (match_operand:TF 0 "register_operand" "=f,f")
15698 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15699 [(reg 17) (const_int 0)])
15700 (match_operand:TF 2 "register_operand" "f,0")
15701 (match_operand:TF 3 "register_operand" "0,f")))]
15702 "TARGET_CMOVE"
15703 "@
15704 fcmov%F1\t{%2, %0|%0, %2}
15705 fcmov%f1\t{%3, %0|%0, %3}"
15706 [(set_attr "type" "fcmov")
15707 (set_attr "mode" "XF")])
15708
15709 (define_expand "minsf3"
15710 [(parallel [
15711 (set (match_operand:SF 0 "register_operand" "")
15712 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15713 (match_operand:SF 2 "nonimmediate_operand" ""))
15714 (match_dup 1)
15715 (match_dup 2)))
15716 (clobber (reg:CC 17))])]
15717 "TARGET_SSE"
15718 "")
15719
15720 (define_insn "*minsf"
15721 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15722 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15723 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15724 (match_dup 1)
15725 (match_dup 2)))
15726 (clobber (reg:CC 17))]
15727 "TARGET_SSE && TARGET_IEEE_FP"
15728 "#")
15729
15730 (define_insn "*minsf_nonieee"
15731 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15732 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
15733 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15734 (match_dup 1)
15735 (match_dup 2)))
15736 (clobber (reg:CC 17))]
15737 "TARGET_SSE && !TARGET_IEEE_FP"
15738 "#")
15739
15740 (define_split
15741 [(set (match_operand:SF 0 "register_operand" "")
15742 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15743 (match_operand:SF 2 "nonimmediate_operand" ""))
15744 (match_operand:SF 3 "register_operand" "")
15745 (match_operand:SF 4 "nonimmediate_operand" "")))
15746 (clobber (reg:CC 17))]
15747 "SSE_REG_P (operands[0]) && reload_completed
15748 && ((operands_match_p (operands[1], operands[3])
15749 && operands_match_p (operands[2], operands[4]))
15750 || (operands_match_p (operands[1], operands[4])
15751 && operands_match_p (operands[2], operands[3])))"
15752 [(set (match_dup 0)
15753 (if_then_else:SF (lt (match_dup 1)
15754 (match_dup 2))
15755 (match_dup 1)
15756 (match_dup 2)))])
15757
15758 ;; We can't represent the LT test directly. Do this by swapping the operands.
15759
15760 (define_split
15761 [(set (match_operand:SF 0 "register_operand" "")
15762 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15763 (match_operand:SF 2 "register_operand" ""))
15764 (match_operand:DF 3 "register_operand" "")
15765 (match_operand:DF 4 "register_operand" "")))
15766 (clobber (reg:CC 17))]
15767 "FP_REG_P (operands[0]) && reload_completed
15768 && ((operands_match_p (operands[1], operands[3])
15769 && operands_match_p (operands[2], operands[4]))
15770 || (operands_match_p (operands[1], operands[4])
15771 && operands_match_p (operands[2], operands[3])))"
15772 [(set (reg:CCFP 17)
15773 (compare:CCFP (match_dup 2)
15774 (match_dup 1)))
15775 (set (match_dup 0)
15776 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
15777 (match_dup 1)
15778 (match_dup 2)))])
15779
15780 (define_insn "*minsf_sse"
15781 [(set (match_operand:SF 0 "register_operand" "=x")
15782 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
15783 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15784 (match_dup 1)
15785 (match_dup 2)))]
15786 "TARGET_SSE && reload_completed"
15787 "minss\t{%2, %0|%0, %2}"
15788 [(set_attr "type" "sse")
15789 (set_attr "mode" "SF")])
15790
15791 (define_expand "mindf3"
15792 [(parallel [
15793 (set (match_operand:DF 0 "register_operand" "")
15794 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15795 (match_operand:DF 2 "nonimmediate_operand" ""))
15796 (match_dup 1)
15797 (match_dup 2)))
15798 (clobber (reg:CC 17))])]
15799 "TARGET_SSE2"
15800 "#")
15801
15802 (define_insn "*mindf"
15803 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15804 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15805 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15806 (match_dup 1)
15807 (match_dup 2)))
15808 (clobber (reg:CC 17))]
15809 "TARGET_SSE2 && TARGET_IEEE_FP"
15810 "#")
15811
15812 (define_insn "*mindf_nonieee"
15813 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15814 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
15815 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15816 (match_dup 1)
15817 (match_dup 2)))
15818 (clobber (reg:CC 17))]
15819 "TARGET_SSE2 && !TARGET_IEEE_FP"
15820 "#")
15821
15822 (define_split
15823 [(set (match_operand:DF 0 "register_operand" "")
15824 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15825 (match_operand:DF 2 "nonimmediate_operand" ""))
15826 (match_operand:DF 3 "register_operand" "")
15827 (match_operand:DF 4 "nonimmediate_operand" "")))
15828 (clobber (reg:CC 17))]
15829 "SSE_REG_P (operands[0]) && reload_completed
15830 && ((operands_match_p (operands[1], operands[3])
15831 && operands_match_p (operands[2], operands[4]))
15832 || (operands_match_p (operands[1], operands[4])
15833 && operands_match_p (operands[2], operands[3])))"
15834 [(set (match_dup 0)
15835 (if_then_else:DF (lt (match_dup 1)
15836 (match_dup 2))
15837 (match_dup 1)
15838 (match_dup 2)))])
15839
15840 ;; We can't represent the LT test directly. Do this by swapping the operands.
15841 (define_split
15842 [(set (match_operand:DF 0 "register_operand" "")
15843 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15844 (match_operand:DF 2 "register_operand" ""))
15845 (match_operand:DF 3 "register_operand" "")
15846 (match_operand:DF 4 "register_operand" "")))
15847 (clobber (reg:CC 17))]
15848 "FP_REG_P (operands[0]) && reload_completed
15849 && ((operands_match_p (operands[1], operands[3])
15850 && operands_match_p (operands[2], operands[4]))
15851 || (operands_match_p (operands[1], operands[4])
15852 && operands_match_p (operands[2], operands[3])))"
15853 [(set (reg:CCFP 17)
15854 (compare:CCFP (match_dup 2)
15855 (match_dup 2)))
15856 (set (match_dup 0)
15857 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
15858 (match_dup 1)
15859 (match_dup 2)))])
15860
15861 (define_insn "*mindf_sse"
15862 [(set (match_operand:DF 0 "register_operand" "=Y")
15863 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
15864 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15865 (match_dup 1)
15866 (match_dup 2)))]
15867 "TARGET_SSE2 && reload_completed"
15868 "minsd\t{%2, %0|%0, %2}"
15869 [(set_attr "type" "sse")
15870 (set_attr "mode" "DF")])
15871
15872 (define_expand "maxsf3"
15873 [(parallel [
15874 (set (match_operand:SF 0 "register_operand" "")
15875 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15876 (match_operand:SF 2 "nonimmediate_operand" ""))
15877 (match_dup 1)
15878 (match_dup 2)))
15879 (clobber (reg:CC 17))])]
15880 "TARGET_SSE"
15881 "#")
15882
15883 (define_insn "*maxsf"
15884 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15885 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
15886 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
15887 (match_dup 1)
15888 (match_dup 2)))
15889 (clobber (reg:CC 17))]
15890 "TARGET_SSE && TARGET_IEEE_FP"
15891 "#")
15892
15893 (define_insn "*maxsf_nonieee"
15894 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15895 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
15896 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15897 (match_dup 1)
15898 (match_dup 2)))
15899 (clobber (reg:CC 17))]
15900 "TARGET_SSE && !TARGET_IEEE_FP"
15901 "#")
15902
15903 (define_split
15904 [(set (match_operand:SF 0 "register_operand" "")
15905 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15906 (match_operand:SF 2 "nonimmediate_operand" ""))
15907 (match_operand:SF 3 "register_operand" "")
15908 (match_operand:SF 4 "nonimmediate_operand" "")))
15909 (clobber (reg:CC 17))]
15910 "SSE_REG_P (operands[0]) && reload_completed
15911 && ((operands_match_p (operands[1], operands[3])
15912 && operands_match_p (operands[2], operands[4]))
15913 || (operands_match_p (operands[1], operands[4])
15914 && operands_match_p (operands[2], operands[3])))"
15915 [(set (match_dup 0)
15916 (if_then_else:SF (gt (match_dup 1)
15917 (match_dup 2))
15918 (match_dup 1)
15919 (match_dup 2)))])
15920
15921 (define_split
15922 [(set (match_operand:SF 0 "register_operand" "")
15923 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15924 (match_operand:SF 2 "register_operand" ""))
15925 (match_operand:SF 3 "register_operand" "")
15926 (match_operand:SF 4 "register_operand" "")))
15927 (clobber (reg:CC 17))]
15928 "FP_REG_P (operands[0]) && reload_completed
15929 && ((operands_match_p (operands[1], operands[3])
15930 && operands_match_p (operands[2], operands[4]))
15931 || (operands_match_p (operands[1], operands[4])
15932 && operands_match_p (operands[2], operands[3])))"
15933 [(set (reg:CCFP 17)
15934 (compare:CCFP (match_dup 1)
15935 (match_dup 2)))
15936 (set (match_dup 0)
15937 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
15938 (match_dup 1)
15939 (match_dup 2)))])
15940
15941 (define_insn "*maxsf_sse"
15942 [(set (match_operand:SF 0 "register_operand" "=x")
15943 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
15944 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15945 (match_dup 1)
15946 (match_dup 2)))]
15947 "TARGET_SSE && reload_completed"
15948 "maxss\t{%2, %0|%0, %2}"
15949 [(set_attr "type" "sse")
15950 (set_attr "mode" "SF")])
15951
15952 (define_expand "maxdf3"
15953 [(parallel [
15954 (set (match_operand:DF 0 "register_operand" "")
15955 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15956 (match_operand:DF 2 "nonimmediate_operand" ""))
15957 (match_dup 1)
15958 (match_dup 2)))
15959 (clobber (reg:CC 17))])]
15960 "TARGET_SSE2"
15961 "#")
15962
15963 (define_insn "*maxdf"
15964 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15965 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15966 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
15967 (match_dup 1)
15968 (match_dup 2)))
15969 (clobber (reg:CC 17))]
15970 "TARGET_SSE2 && TARGET_IEEE_FP"
15971 "#")
15972
15973 (define_insn "*maxdf_nonieee"
15974 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15975 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
15976 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15977 (match_dup 1)
15978 (match_dup 2)))
15979 (clobber (reg:CC 17))]
15980 "TARGET_SSE2 && !TARGET_IEEE_FP"
15981 "#")
15982
15983 (define_split
15984 [(set (match_operand:DF 0 "register_operand" "")
15985 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15986 (match_operand:DF 2 "nonimmediate_operand" ""))
15987 (match_operand:DF 3 "register_operand" "")
15988 (match_operand:DF 4 "nonimmediate_operand" "")))
15989 (clobber (reg:CC 17))]
15990 "SSE_REG_P (operands[0]) && reload_completed
15991 && ((operands_match_p (operands[1], operands[3])
15992 && operands_match_p (operands[2], operands[4]))
15993 || (operands_match_p (operands[1], operands[4])
15994 && operands_match_p (operands[2], operands[3])))"
15995 [(set (match_dup 0)
15996 (if_then_else:DF (gt (match_dup 1)
15997 (match_dup 2))
15998 (match_dup 1)
15999 (match_dup 2)))])
16000
16001 (define_split
16002 [(set (match_operand:DF 0 "register_operand" "")
16003 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16004 (match_operand:DF 2 "register_operand" ""))
16005 (match_operand:DF 3 "register_operand" "")
16006 (match_operand:DF 4 "register_operand" "")))
16007 (clobber (reg:CC 17))]
16008 "FP_REG_P (operands[0]) && reload_completed
16009 && ((operands_match_p (operands[1], operands[3])
16010 && operands_match_p (operands[2], operands[4]))
16011 || (operands_match_p (operands[1], operands[4])
16012 && operands_match_p (operands[2], operands[3])))"
16013 [(set (reg:CCFP 17)
16014 (compare:CCFP (match_dup 1)
16015 (match_dup 2)))
16016 (set (match_dup 0)
16017 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16018 (match_dup 1)
16019 (match_dup 2)))])
16020
16021 (define_insn "*maxdf_sse"
16022 [(set (match_operand:DF 0 "register_operand" "=Y")
16023 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16024 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16025 (match_dup 1)
16026 (match_dup 2)))]
16027 "TARGET_SSE2 && reload_completed"
16028 "maxsd\t{%2, %0|%0, %2}"
16029 [(set_attr "type" "sse")
16030 (set_attr "mode" "DF")])
16031 \f
16032 ;; Misc patterns (?)
16033
16034 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
16035 ;; Otherwise there will be nothing to keep
16036 ;;
16037 ;; [(set (reg ebp) (reg esp))]
16038 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16039 ;; (clobber (eflags)]
16040 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16041 ;;
16042 ;; in proper program order.
16043 (define_expand "pro_epilogue_adjust_stack"
16044 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
16045 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16046 (match_operand:SI 2 "immediate_operand" "i,i")))
16047 (clobber (reg:CC 17))
16048 (clobber (mem:BLK (scratch)))])]
16049 ""
16050 {
16051 if (TARGET_64BIT)
16052 {
16053 emit_insn (gen_pro_epilogue_adjust_stack_rex64
16054 (operands[0], operands[1], operands[2]));
16055 DONE;
16056 }
16057 })
16058
16059 (define_insn "*pro_epilogue_adjust_stack_1"
16060 [(set (match_operand:SI 0 "register_operand" "=r,r")
16061 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16062 (match_operand:SI 2 "immediate_operand" "i,i")))
16063 (clobber (reg:CC 17))
16064 (clobber (mem:BLK (scratch)))]
16065 "!TARGET_64BIT"
16066 {
16067 switch (get_attr_type (insn))
16068 {
16069 case TYPE_IMOV:
16070 return "mov{l}\t{%1, %0|%0, %1}";
16071
16072 case TYPE_ALU:
16073 if (GET_CODE (operands[2]) == CONST_INT
16074 && (INTVAL (operands[2]) == 128
16075 || (INTVAL (operands[2]) < 0
16076 && INTVAL (operands[2]) != -128)))
16077 {
16078 operands[2] = GEN_INT (-INTVAL (operands[2]));
16079 return "sub{l}\t{%2, %0|%0, %2}";
16080 }
16081 return "add{l}\t{%2, %0|%0, %2}";
16082
16083 case TYPE_LEA:
16084 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16085 return "lea{l}\t{%a2, %0|%0, %a2}";
16086
16087 default:
16088 abort ();
16089 }
16090 }
16091 [(set (attr "type")
16092 (cond [(eq_attr "alternative" "0")
16093 (const_string "alu")
16094 (match_operand:SI 2 "const0_operand" "")
16095 (const_string "imov")
16096 ]
16097 (const_string "lea")))
16098 (set_attr "mode" "SI")])
16099
16100 (define_insn "pro_epilogue_adjust_stack_rex64"
16101 [(set (match_operand:DI 0 "register_operand" "=r,r")
16102 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16103 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16104 (clobber (reg:CC 17))
16105 (clobber (mem:BLK (scratch)))]
16106 "TARGET_64BIT"
16107 {
16108 switch (get_attr_type (insn))
16109 {
16110 case TYPE_IMOV:
16111 return "mov{q}\t{%1, %0|%0, %1}";
16112
16113 case TYPE_ALU:
16114 if (GET_CODE (operands[2]) == CONST_INT
16115 && (INTVAL (operands[2]) == 128
16116 || (INTVAL (operands[2]) < 0
16117 && INTVAL (operands[2]) != -128)))
16118 {
16119 operands[2] = GEN_INT (-INTVAL (operands[2]));
16120 return "sub{q}\t{%2, %0|%0, %2}";
16121 }
16122 return "add{q}\t{%2, %0|%0, %2}";
16123
16124 case TYPE_LEA:
16125 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16126 return "lea{q}\t{%a2, %0|%0, %a2}";
16127
16128 default:
16129 abort ();
16130 }
16131 }
16132 [(set (attr "type")
16133 (cond [(eq_attr "alternative" "0")
16134 (const_string "alu")
16135 (match_operand:DI 2 "const0_operand" "")
16136 (const_string "imov")
16137 ]
16138 (const_string "lea")))
16139 (set_attr "mode" "DI")])
16140
16141
16142 ;; Placeholder for the conditional moves. This one is split eighter to SSE
16143 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16144 ;; fact is that compares supported by the cmp??ss instructions are exactly
16145 ;; swapped of those supported by cmove sequence.
16146 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16147 ;; supported by i387 comparisons and we do need to emit two conditional moves
16148 ;; in tandem.
16149
16150 (define_insn "sse_movsfcc"
16151 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16152 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16153 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16154 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16155 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16156 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16157 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16158 (clobber (reg:CC 17))]
16159 "TARGET_SSE
16160 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16161 && (!TARGET_IEEE_FP
16162 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16163 "#")
16164
16165 (define_insn "sse_movsfcc_eq"
16166 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16167 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16168 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16169 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16170 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16171 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16172 (clobber (reg:CC 17))]
16173 "TARGET_SSE
16174 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16175 "#")
16176
16177 (define_insn "sse_movdfcc"
16178 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16179 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16180 [(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16181 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16182 (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16183 (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16184 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16185 (clobber (reg:CC 17))]
16186 "TARGET_SSE2
16187 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16188 && (!TARGET_IEEE_FP
16189 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16190 "#")
16191
16192 (define_insn "sse_movdfcc_eq"
16193 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16194 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16195 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16196 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16197 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16198 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16199 (clobber (reg:CC 17))]
16200 "TARGET_SSE
16201 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16202 "#")
16203
16204 ;; For non-sse moves just expand the usual cmove sequence.
16205 (define_split
16206 [(set (match_operand 0 "register_operand" "")
16207 (if_then_else (match_operator 1 "comparison_operator"
16208 [(match_operand 4 "nonimmediate_operand" "")
16209 (match_operand 5 "register_operand" "")])
16210 (match_operand 2 "nonimmediate_operand" "")
16211 (match_operand 3 "nonimmediate_operand" "")))
16212 (clobber (match_operand 6 "" ""))
16213 (clobber (reg:CC 17))]
16214 "!SSE_REG_P (operands[0]) && reload_completed
16215 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16216 [(const_int 0)]
16217 {
16218 ix86_compare_op0 = operands[5];
16219 ix86_compare_op1 = operands[4];
16220 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16221 VOIDmode, operands[5], operands[4]);
16222 ix86_expand_fp_movcc (operands);
16223 DONE;
16224 })
16225
16226 ;; Split SSE based conditional move into seqence:
16227 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16228 ;; and op2, op0 - zero op2 if comparison was false
16229 ;; nand op0, op3 - load op3 to op0 if comparison was false
16230 ;; or op2, op0 - get the non-zero one into the result.
16231 (define_split
16232 [(set (match_operand 0 "register_operand" "")
16233 (if_then_else (match_operator 1 "sse_comparison_operator"
16234 [(match_operand 4 "register_operand" "")
16235 (match_operand 5 "nonimmediate_operand" "")])
16236 (match_operand 2 "register_operand" "")
16237 (match_operand 3 "register_operand" "")))
16238 (clobber (match_operand 6 "" ""))
16239 (clobber (reg:CC 17))]
16240 "SSE_REG_P (operands[0]) && reload_completed"
16241 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
16242 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
16243 (subreg:TI (match_dup 4) 0)))
16244 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
16245 (subreg:TI (match_dup 3) 0)))
16246 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
16247 (subreg:TI (match_dup 7) 0)))]
16248 {
16249 PUT_MODE (operands[1], GET_MODE (operands[0]));
16250 if (operands_match_p (operands[0], operands[4]))
16251 operands[6] = operands[4], operands[7] = operands[2];
16252 else
16253 operands[6] = operands[2], operands[7] = operands[4];
16254 })
16255
16256 ;; Special case of conditional move we can handle effectivly.
16257 ;; Do not brother with the integer/floating point case, since these are
16258 ;; bot considerably slower, unlike in the generic case.
16259 (define_insn "*sse_movsfcc_const0_1"
16260 [(set (match_operand:SF 0 "register_operand" "=x")
16261 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16262 [(match_operand:SF 4 "register_operand" "0")
16263 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16264 (match_operand:SF 2 "register_operand" "x")
16265 (match_operand:SF 3 "const0_operand" "X")))]
16266 "TARGET_SSE"
16267 "#")
16268
16269 (define_insn "*sse_movsfcc_const0_2"
16270 [(set (match_operand:SF 0 "register_operand" "=x")
16271 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16272 [(match_operand:SF 4 "register_operand" "0")
16273 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16274 (match_operand:SF 2 "const0_operand" "x")
16275 (match_operand:SF 3 "register_operand" "X")))]
16276 "TARGET_SSE"
16277 "#")
16278
16279 (define_insn "*sse_movsfcc_const0_3"
16280 [(set (match_operand:SF 0 "register_operand" "=x")
16281 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16282 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16283 (match_operand:SF 5 "register_operand" "0")])
16284 (match_operand:SF 2 "register_operand" "x")
16285 (match_operand:SF 3 "const0_operand" "X")))]
16286 "TARGET_SSE"
16287 "#")
16288
16289 (define_insn "*sse_movsfcc_const0_4"
16290 [(set (match_operand:SF 0 "register_operand" "=x")
16291 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16292 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16293 (match_operand:SF 5 "register_operand" "0")])
16294 (match_operand:SF 2 "const0_operand" "x")
16295 (match_operand:SF 3 "register_operand" "X")))]
16296 "TARGET_SSE"
16297 "#")
16298
16299 (define_insn "*sse_movdfcc_const0_1"
16300 [(set (match_operand:SF 0 "register_operand" "=x")
16301 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16302 [(match_operand:SF 4 "register_operand" "0")
16303 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16304 (match_operand:SF 2 "register_operand" "x")
16305 (match_operand:SF 3 "const0_operand" "X")))]
16306 "TARGET_SSE2"
16307 "#")
16308
16309 (define_insn "*sse_movdfcc_const0_2"
16310 [(set (match_operand:SF 0 "register_operand" "=x")
16311 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16312 [(match_operand:SF 4 "register_operand" "0")
16313 (match_operand:SF 5 "nonimmediate_operand" "xm")])
16314 (match_operand:SF 2 "const0_operand" "x")
16315 (match_operand:SF 3 "register_operand" "X")))]
16316 "TARGET_SSE2"
16317 "#")
16318
16319 (define_insn "*sse_movdfcc_const0_3"
16320 [(set (match_operand:SF 0 "register_operand" "=x")
16321 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16322 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16323 (match_operand:SF 5 "register_operand" "0")])
16324 (match_operand:SF 2 "register_operand" "x")
16325 (match_operand:SF 3 "const0_operand" "X")))]
16326 "TARGET_SSE2"
16327 "#")
16328
16329 (define_insn "*sse_movdfcc_const0_4"
16330 [(set (match_operand:SF 0 "register_operand" "=x")
16331 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16332 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16333 (match_operand:SF 5 "register_operand" "0")])
16334 (match_operand:SF 2 "const0_operand" "x")
16335 (match_operand:SF 3 "register_operand" "X")))]
16336 "TARGET_SSE2"
16337 "#")
16338
16339 (define_split
16340 [(set (match_operand 0 "register_operand" "")
16341 (if_then_else (match_operator 1 "comparison_operator"
16342 [(match_operand 4 "register_operand" "")
16343 (match_operand 5 "nonimmediate_operand" "")])
16344 (match_operand 2 "nonmemory_operand" "")
16345 (match_operand 3 "nonmemory_operand" "")))]
16346 "SSE_REG_P (operands[0]) && reload_completed
16347 && (const0_operand (operands[2], GET_MODE (operands[0]))
16348 || const0_operand (operands[3], GET_MODE (operands[0])))"
16349 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16350 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16351 (subreg:TI (match_dup 7) 0)))]
16352 {
16353 PUT_MODE (operands[1], GET_MODE (operands[0]));
16354 if (!sse_comparison_operator (operands[1], VOIDmode))
16355 {
16356 rtx tmp = operands[5];
16357 operands[5] = operands[4];
16358 operands[4] = tmp;
16359 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16360 }
16361 if (const0_operand (operands[2], GET_MODE (operands[0])))
16362 {
16363 operands[7] = operands[3];
16364 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16365 0));
16366 }
16367 else
16368 {
16369 operands[7] = operands[2];
16370 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16371 }
16372 })
16373
16374 (define_expand "allocate_stack_worker"
16375 [(match_operand:SI 0 "register_operand" "")]
16376 "TARGET_STACK_PROBE"
16377 {
16378 if (TARGET_64BIT)
16379 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16380 else
16381 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16382 DONE;
16383 })
16384
16385 (define_insn "allocate_stack_worker_1"
16386 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16387 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16388 (clobber (match_dup 0))
16389 (clobber (reg:CC 17))]
16390 "!TARGET_64BIT && TARGET_STACK_PROBE"
16391 "call\t__alloca"
16392 [(set_attr "type" "multi")
16393 (set_attr "length" "5")])
16394
16395 (define_insn "allocate_stack_worker_rex64"
16396 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16397 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16398 (clobber (match_dup 0))
16399 (clobber (reg:CC 17))]
16400 "TARGET_64BIT && TARGET_STACK_PROBE"
16401 "call\t__alloca"
16402 [(set_attr "type" "multi")
16403 (set_attr "length" "5")])
16404
16405 (define_expand "allocate_stack"
16406 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16407 (minus:SI (reg:SI 7)
16408 (match_operand:SI 1 "general_operand" "")))
16409 (clobber (reg:CC 17))])
16410 (parallel [(set (reg:SI 7)
16411 (minus:SI (reg:SI 7) (match_dup 1)))
16412 (clobber (reg:CC 17))])]
16413 "TARGET_STACK_PROBE"
16414 {
16415 #ifdef CHECK_STACK_LIMIT
16416 if (GET_CODE (operands[1]) == CONST_INT
16417 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16418 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16419 operands[1]));
16420 else
16421 #endif
16422 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16423 operands[1])));
16424
16425 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16426 DONE;
16427 })
16428
16429 (define_expand "builtin_setjmp_receiver"
16430 [(label_ref (match_operand 0 "" ""))]
16431 "!TARGET_64BIT && flag_pic"
16432 {
16433 load_pic_register ();
16434 DONE;
16435 })
16436 \f
16437 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16438
16439 (define_split
16440 [(set (match_operand 0 "register_operand" "")
16441 (match_operator 3 "promotable_binary_operator"
16442 [(match_operand 1 "register_operand" "")
16443 (match_operand 2 "aligned_operand" "")]))
16444 (clobber (reg:CC 17))]
16445 "! TARGET_PARTIAL_REG_STALL && reload_completed
16446 && ((GET_MODE (operands[0]) == HImode
16447 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16448 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16449 || (GET_MODE (operands[0]) == QImode
16450 && (TARGET_PROMOTE_QImode || optimize_size)))"
16451 [(parallel [(set (match_dup 0)
16452 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16453 (clobber (reg:CC 17))])]
16454 "operands[0] = gen_lowpart (SImode, operands[0]);
16455 operands[1] = gen_lowpart (SImode, operands[1]);
16456 if (GET_CODE (operands[3]) != ASHIFT)
16457 operands[2] = gen_lowpart (SImode, operands[2]);
16458 PUT_MODE (operands[3], SImode);")
16459
16460 (define_split
16461 [(set (reg 17)
16462 (compare (and (match_operand 1 "aligned_operand" "")
16463 (match_operand 2 "const_int_operand" ""))
16464 (const_int 0)))
16465 (set (match_operand 0 "register_operand" "")
16466 (and (match_dup 1) (match_dup 2)))]
16467 "! TARGET_PARTIAL_REG_STALL && reload_completed
16468 && ix86_match_ccmode (insn, CCNOmode)
16469 && (GET_MODE (operands[0]) == HImode
16470 || (GET_MODE (operands[0]) == QImode
16471 && (TARGET_PROMOTE_QImode || optimize_size)))"
16472 [(parallel [(set (reg:CCNO 17)
16473 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16474 (const_int 0)))
16475 (set (match_dup 0)
16476 (and:SI (match_dup 1) (match_dup 2)))])]
16477 "operands[2]
16478 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16479 & GET_MODE_MASK (GET_MODE (operands[0])),
16480 SImode));
16481 operands[0] = gen_lowpart (SImode, operands[0]);
16482 operands[1] = gen_lowpart (SImode, operands[1]);")
16483
16484 (define_split
16485 [(set (reg 17)
16486 (compare (and (match_operand 0 "aligned_operand" "")
16487 (match_operand 1 "const_int_operand" ""))
16488 (const_int 0)))]
16489 "! TARGET_PARTIAL_REG_STALL && reload_completed
16490 && ix86_match_ccmode (insn, CCNOmode)
16491 && (GET_MODE (operands[0]) == HImode
16492 || (GET_MODE (operands[0]) == QImode
16493 && (TARGET_PROMOTE_QImode || optimize_size)))"
16494 [(set (reg:CCNO 17)
16495 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16496 (const_int 0)))]
16497 "operands[1]
16498 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16499 & GET_MODE_MASK (GET_MODE (operands[0])),
16500 SImode));
16501 operands[0] = gen_lowpart (SImode, operands[0]);")
16502
16503 (define_split
16504 [(set (match_operand 0 "register_operand" "")
16505 (neg (match_operand 1 "register_operand" "")))
16506 (clobber (reg:CC 17))]
16507 "! TARGET_PARTIAL_REG_STALL && reload_completed
16508 && (GET_MODE (operands[0]) == HImode
16509 || (GET_MODE (operands[0]) == QImode
16510 && (TARGET_PROMOTE_QImode || optimize_size)))"
16511 [(parallel [(set (match_dup 0)
16512 (neg:SI (match_dup 1)))
16513 (clobber (reg:CC 17))])]
16514 "operands[0] = gen_lowpart (SImode, operands[0]);
16515 operands[1] = gen_lowpart (SImode, operands[1]);")
16516
16517 (define_split
16518 [(set (match_operand 0 "register_operand" "")
16519 (not (match_operand 1 "register_operand" "")))]
16520 "! TARGET_PARTIAL_REG_STALL && reload_completed
16521 && (GET_MODE (operands[0]) == HImode
16522 || (GET_MODE (operands[0]) == QImode
16523 && (TARGET_PROMOTE_QImode || optimize_size)))"
16524 [(set (match_dup 0)
16525 (not:SI (match_dup 1)))]
16526 "operands[0] = gen_lowpart (SImode, operands[0]);
16527 operands[1] = gen_lowpart (SImode, operands[1]);")
16528
16529 (define_split
16530 [(set (match_operand 0 "register_operand" "")
16531 (if_then_else (match_operator 1 "comparison_operator"
16532 [(reg 17) (const_int 0)])
16533 (match_operand 2 "register_operand" "")
16534 (match_operand 3 "register_operand" "")))]
16535 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16536 && (GET_MODE (operands[0]) == HImode
16537 || (GET_MODE (operands[0]) == QImode
16538 && (TARGET_PROMOTE_QImode || optimize_size)))"
16539 [(set (match_dup 0)
16540 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16541 "operands[0] = gen_lowpart (SImode, operands[0]);
16542 operands[2] = gen_lowpart (SImode, operands[2]);
16543 operands[3] = gen_lowpart (SImode, operands[3]);")
16544
16545 \f
16546 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16547 ;; transform a complex memory operation into two memory to register operations.
16548
16549 ;; Don't push memory operands
16550 (define_peephole2
16551 [(set (match_operand:SI 0 "push_operand" "")
16552 (match_operand:SI 1 "memory_operand" ""))
16553 (match_scratch:SI 2 "r")]
16554 "! optimize_size && ! TARGET_PUSH_MEMORY"
16555 [(set (match_dup 2) (match_dup 1))
16556 (set (match_dup 0) (match_dup 2))]
16557 "")
16558
16559 (define_peephole2
16560 [(set (match_operand:DI 0 "push_operand" "")
16561 (match_operand:DI 1 "memory_operand" ""))
16562 (match_scratch:DI 2 "r")]
16563 "! optimize_size && ! TARGET_PUSH_MEMORY"
16564 [(set (match_dup 2) (match_dup 1))
16565 (set (match_dup 0) (match_dup 2))]
16566 "")
16567
16568 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16569 ;; SImode pushes.
16570 (define_peephole2
16571 [(set (match_operand:SF 0 "push_operand" "")
16572 (match_operand:SF 1 "memory_operand" ""))
16573 (match_scratch:SF 2 "r")]
16574 "! optimize_size && ! TARGET_PUSH_MEMORY"
16575 [(set (match_dup 2) (match_dup 1))
16576 (set (match_dup 0) (match_dup 2))]
16577 "")
16578
16579 (define_peephole2
16580 [(set (match_operand:HI 0 "push_operand" "")
16581 (match_operand:HI 1 "memory_operand" ""))
16582 (match_scratch:HI 2 "r")]
16583 "! optimize_size && ! TARGET_PUSH_MEMORY"
16584 [(set (match_dup 2) (match_dup 1))
16585 (set (match_dup 0) (match_dup 2))]
16586 "")
16587
16588 (define_peephole2
16589 [(set (match_operand:QI 0 "push_operand" "")
16590 (match_operand:QI 1 "memory_operand" ""))
16591 (match_scratch:QI 2 "q")]
16592 "! optimize_size && ! TARGET_PUSH_MEMORY"
16593 [(set (match_dup 2) (match_dup 1))
16594 (set (match_dup 0) (match_dup 2))]
16595 "")
16596
16597 ;; Don't move an immediate directly to memory when the instruction
16598 ;; gets too big.
16599 (define_peephole2
16600 [(match_scratch:SI 1 "r")
16601 (set (match_operand:SI 0 "memory_operand" "")
16602 (const_int 0))]
16603 "! optimize_size
16604 && ! TARGET_USE_MOV0
16605 && TARGET_SPLIT_LONG_MOVES
16606 && get_attr_length (insn) >= ix86_cost->large_insn
16607 && peep2_regno_dead_p (0, FLAGS_REG)"
16608 [(parallel [(set (match_dup 1) (const_int 0))
16609 (clobber (reg:CC 17))])
16610 (set (match_dup 0) (match_dup 1))]
16611 "")
16612
16613 (define_peephole2
16614 [(match_scratch:HI 1 "r")
16615 (set (match_operand:HI 0 "memory_operand" "")
16616 (const_int 0))]
16617 "! optimize_size
16618 && ! TARGET_USE_MOV0
16619 && TARGET_SPLIT_LONG_MOVES
16620 && get_attr_length (insn) >= ix86_cost->large_insn
16621 && peep2_regno_dead_p (0, FLAGS_REG)"
16622 [(parallel [(set (match_dup 2) (const_int 0))
16623 (clobber (reg:CC 17))])
16624 (set (match_dup 0) (match_dup 1))]
16625 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16626
16627 (define_peephole2
16628 [(match_scratch:QI 1 "q")
16629 (set (match_operand:QI 0 "memory_operand" "")
16630 (const_int 0))]
16631 "! optimize_size
16632 && ! TARGET_USE_MOV0
16633 && TARGET_SPLIT_LONG_MOVES
16634 && get_attr_length (insn) >= ix86_cost->large_insn
16635 && peep2_regno_dead_p (0, FLAGS_REG)"
16636 [(parallel [(set (match_dup 2) (const_int 0))
16637 (clobber (reg:CC 17))])
16638 (set (match_dup 0) (match_dup 1))]
16639 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16640
16641 (define_peephole2
16642 [(match_scratch:SI 2 "r")
16643 (set (match_operand:SI 0 "memory_operand" "")
16644 (match_operand:SI 1 "immediate_operand" ""))]
16645 "! optimize_size
16646 && get_attr_length (insn) >= ix86_cost->large_insn
16647 && TARGET_SPLIT_LONG_MOVES"
16648 [(set (match_dup 2) (match_dup 1))
16649 (set (match_dup 0) (match_dup 2))]
16650 "")
16651
16652 (define_peephole2
16653 [(match_scratch:HI 2 "r")
16654 (set (match_operand:HI 0 "memory_operand" "")
16655 (match_operand:HI 1 "immediate_operand" ""))]
16656 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16657 && TARGET_SPLIT_LONG_MOVES"
16658 [(set (match_dup 2) (match_dup 1))
16659 (set (match_dup 0) (match_dup 2))]
16660 "")
16661
16662 (define_peephole2
16663 [(match_scratch:QI 2 "q")
16664 (set (match_operand:QI 0 "memory_operand" "")
16665 (match_operand:QI 1 "immediate_operand" ""))]
16666 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16667 && TARGET_SPLIT_LONG_MOVES"
16668 [(set (match_dup 2) (match_dup 1))
16669 (set (match_dup 0) (match_dup 2))]
16670 "")
16671
16672 ;; Don't compare memory with zero, load and use a test instead.
16673 (define_peephole2
16674 [(set (reg 17)
16675 (compare (match_operand:SI 0 "memory_operand" "")
16676 (const_int 0)))
16677 (match_scratch:SI 3 "r")]
16678 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16679 [(set (match_dup 3) (match_dup 0))
16680 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16681 "")
16682
16683 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16684 ;; Don't split NOTs with a displacement operand, because resulting XOR
16685 ;; will not be pariable anyway.
16686 ;;
16687 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
16688 ;; represented using a modRM byte. The XOR replacement is long decoded,
16689 ;; so this split helps here as well.
16690 ;;
16691 ;; Note: Can't do this as a regular split because we can't get proper
16692 ;; lifetime information then.
16693
16694 (define_peephole2
16695 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16696 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16697 "!optimize_size
16698 && peep2_regno_dead_p (0, FLAGS_REG)
16699 && ((TARGET_PENTIUM
16700 && (GET_CODE (operands[0]) != MEM
16701 || !memory_displacement_operand (operands[0], SImode)))
16702 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16703 [(parallel [(set (match_dup 0)
16704 (xor:SI (match_dup 1) (const_int -1)))
16705 (clobber (reg:CC 17))])]
16706 "")
16707
16708 (define_peephole2
16709 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16710 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16711 "!optimize_size
16712 && peep2_regno_dead_p (0, FLAGS_REG)
16713 && ((TARGET_PENTIUM
16714 && (GET_CODE (operands[0]) != MEM
16715 || !memory_displacement_operand (operands[0], HImode)))
16716 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16717 [(parallel [(set (match_dup 0)
16718 (xor:HI (match_dup 1) (const_int -1)))
16719 (clobber (reg:CC 17))])]
16720 "")
16721
16722 (define_peephole2
16723 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16724 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16725 "!optimize_size
16726 && peep2_regno_dead_p (0, FLAGS_REG)
16727 && ((TARGET_PENTIUM
16728 && (GET_CODE (operands[0]) != MEM
16729 || !memory_displacement_operand (operands[0], QImode)))
16730 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16731 [(parallel [(set (match_dup 0)
16732 (xor:QI (match_dup 1) (const_int -1)))
16733 (clobber (reg:CC 17))])]
16734 "")
16735
16736 ;; Non pairable "test imm, reg" instructions can be translated to
16737 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16738 ;; byte opcode instead of two, have a short form for byte operands),
16739 ;; so do it for other CPUs as well. Given that the value was dead,
16740 ;; this should not create any new dependancies. Pass on the sub-word
16741 ;; versions if we're concerned about partial register stalls.
16742
16743 (define_peephole2
16744 [(set (reg 17)
16745 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16746 (match_operand:SI 1 "immediate_operand" ""))
16747 (const_int 0)))]
16748 "ix86_match_ccmode (insn, CCNOmode)
16749 && (true_regnum (operands[0]) != 0
16750 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
16751 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16752 [(parallel
16753 [(set (reg:CCNO 17)
16754 (compare:CCNO (and:SI (match_dup 0)
16755 (match_dup 1))
16756 (const_int 0)))
16757 (set (match_dup 0)
16758 (and:SI (match_dup 0) (match_dup 1)))])]
16759 "")
16760
16761 ;; We don't need to handle HImode case, because it will be promoted to SImode
16762 ;; on ! TARGET_PARTIAL_REG_STALL
16763
16764 (define_peephole2
16765 [(set (reg 17)
16766 (compare (and:QI (match_operand:QI 0 "register_operand" "")
16767 (match_operand:QI 1 "immediate_operand" ""))
16768 (const_int 0)))]
16769 "! TARGET_PARTIAL_REG_STALL
16770 && ix86_match_ccmode (insn, CCNOmode)
16771 && true_regnum (operands[0]) != 0
16772 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16773 [(parallel
16774 [(set (reg:CCNO 17)
16775 (compare:CCNO (and:QI (match_dup 0)
16776 (match_dup 1))
16777 (const_int 0)))
16778 (set (match_dup 0)
16779 (and:QI (match_dup 0) (match_dup 1)))])]
16780 "")
16781
16782 (define_peephole2
16783 [(set (reg 17)
16784 (compare
16785 (and:SI
16786 (zero_extract:SI
16787 (match_operand 0 "ext_register_operand" "")
16788 (const_int 8)
16789 (const_int 8))
16790 (match_operand 1 "const_int_operand" ""))
16791 (const_int 0)))]
16792 "! TARGET_PARTIAL_REG_STALL
16793 && ix86_match_ccmode (insn, CCNOmode)
16794 && true_regnum (operands[0]) != 0
16795 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16796 [(parallel [(set (reg:CCNO 17)
16797 (compare:CCNO
16798 (and:SI
16799 (zero_extract:SI
16800 (match_dup 0)
16801 (const_int 8)
16802 (const_int 8))
16803 (match_dup 1))
16804 (const_int 0)))
16805 (set (zero_extract:SI (match_dup 0)
16806 (const_int 8)
16807 (const_int 8))
16808 (and:SI
16809 (zero_extract:SI
16810 (match_dup 0)
16811 (const_int 8)
16812 (const_int 8))
16813 (match_dup 1)))])]
16814 "")
16815
16816 ;; Don't do logical operations with memory inputs.
16817 (define_peephole2
16818 [(match_scratch:SI 2 "r")
16819 (parallel [(set (match_operand:SI 0 "register_operand" "")
16820 (match_operator:SI 3 "arith_or_logical_operator"
16821 [(match_dup 0)
16822 (match_operand:SI 1 "memory_operand" "")]))
16823 (clobber (reg:CC 17))])]
16824 "! optimize_size && ! TARGET_READ_MODIFY"
16825 [(set (match_dup 2) (match_dup 1))
16826 (parallel [(set (match_dup 0)
16827 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16828 (clobber (reg:CC 17))])]
16829 "")
16830
16831 (define_peephole2
16832 [(match_scratch:SI 2 "r")
16833 (parallel [(set (match_operand:SI 0 "register_operand" "")
16834 (match_operator:SI 3 "arith_or_logical_operator"
16835 [(match_operand:SI 1 "memory_operand" "")
16836 (match_dup 0)]))
16837 (clobber (reg:CC 17))])]
16838 "! optimize_size && ! TARGET_READ_MODIFY"
16839 [(set (match_dup 2) (match_dup 1))
16840 (parallel [(set (match_dup 0)
16841 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16842 (clobber (reg:CC 17))])]
16843 "")
16844
16845 ; Don't do logical operations with memory outputs
16846 ;
16847 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16848 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16849 ; the same decoder scheduling characteristics as the original.
16850
16851 (define_peephole2
16852 [(match_scratch:SI 2 "r")
16853 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16854 (match_operator:SI 3 "arith_or_logical_operator"
16855 [(match_dup 0)
16856 (match_operand:SI 1 "nonmemory_operand" "")]))
16857 (clobber (reg:CC 17))])]
16858 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16859 [(set (match_dup 2) (match_dup 0))
16860 (parallel [(set (match_dup 2)
16861 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16862 (clobber (reg:CC 17))])
16863 (set (match_dup 0) (match_dup 2))]
16864 "")
16865
16866 (define_peephole2
16867 [(match_scratch:SI 2 "r")
16868 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16869 (match_operator:SI 3 "arith_or_logical_operator"
16870 [(match_operand:SI 1 "nonmemory_operand" "")
16871 (match_dup 0)]))
16872 (clobber (reg:CC 17))])]
16873 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16874 [(set (match_dup 2) (match_dup 0))
16875 (parallel [(set (match_dup 2)
16876 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16877 (clobber (reg:CC 17))])
16878 (set (match_dup 0) (match_dup 2))]
16879 "")
16880
16881 ;; Attempt to always use XOR for zeroing registers.
16882 (define_peephole2
16883 [(set (match_operand 0 "register_operand" "")
16884 (const_int 0))]
16885 "(GET_MODE (operands[0]) == QImode
16886 || GET_MODE (operands[0]) == HImode
16887 || GET_MODE (operands[0]) == SImode
16888 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16889 && (! TARGET_USE_MOV0 || optimize_size)
16890 && peep2_regno_dead_p (0, FLAGS_REG)"
16891 [(parallel [(set (match_dup 0) (const_int 0))
16892 (clobber (reg:CC 17))])]
16893 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16894 true_regnum (operands[0]));")
16895
16896 (define_peephole2
16897 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16898 (const_int 0))]
16899 "(GET_MODE (operands[0]) == QImode
16900 || GET_MODE (operands[0]) == HImode)
16901 && (! TARGET_USE_MOV0 || optimize_size)
16902 && peep2_regno_dead_p (0, FLAGS_REG)"
16903 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16904 (clobber (reg:CC 17))])])
16905
16906 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16907 (define_peephole2
16908 [(set (match_operand 0 "register_operand" "")
16909 (const_int -1))]
16910 "(GET_MODE (operands[0]) == HImode
16911 || GET_MODE (operands[0]) == SImode
16912 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16913 && (optimize_size || TARGET_PENTIUM)
16914 && peep2_regno_dead_p (0, FLAGS_REG)"
16915 [(parallel [(set (match_dup 0) (const_int -1))
16916 (clobber (reg:CC 17))])]
16917 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16918 true_regnum (operands[0]));")
16919
16920 ;; Attempt to convert simple leas to adds. These can be created by
16921 ;; move expanders.
16922 (define_peephole2
16923 [(set (match_operand:SI 0 "register_operand" "")
16924 (plus:SI (match_dup 0)
16925 (match_operand:SI 1 "nonmemory_operand" "")))]
16926 "peep2_regno_dead_p (0, FLAGS_REG)"
16927 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16928 (clobber (reg:CC 17))])]
16929 "")
16930
16931 (define_peephole2
16932 [(set (match_operand:SI 0 "register_operand" "")
16933 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16934 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16935 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
16936 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16937 (clobber (reg:CC 17))])]
16938 "operands[2] = gen_lowpart (SImode, operands[2]);")
16939
16940 (define_peephole2
16941 [(set (match_operand:DI 0 "register_operand" "")
16942 (plus:DI (match_dup 0)
16943 (match_operand:DI 1 "x86_64_general_operand" "")))]
16944 "peep2_regno_dead_p (0, FLAGS_REG)"
16945 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
16946 (clobber (reg:CC 17))])]
16947 "")
16948
16949 (define_peephole2
16950 [(set (match_operand:SI 0 "register_operand" "")
16951 (mult:SI (match_dup 0)
16952 (match_operand:SI 1 "const_int_operand" "")))]
16953 "exact_log2 (INTVAL (operands[1])) >= 0
16954 && peep2_regno_dead_p (0, FLAGS_REG)"
16955 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16956 (clobber (reg:CC 17))])]
16957 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16958
16959 (define_peephole2
16960 [(set (match_operand:DI 0 "register_operand" "")
16961 (mult:DI (match_dup 0)
16962 (match_operand:DI 1 "const_int_operand" "")))]
16963 "exact_log2 (INTVAL (operands[1])) >= 0
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
16966 (clobber (reg:CC 17))])]
16967 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16968
16969 (define_peephole2
16970 [(set (match_operand:SI 0 "register_operand" "")
16971 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16972 (match_operand:DI 2 "const_int_operand" "")) 0))]
16973 "exact_log2 (INTVAL (operands[1])) >= 0
16974 && REGNO (operands[0]) == REGNO (operands[1])
16975 && peep2_regno_dead_p (0, FLAGS_REG)"
16976 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16977 (clobber (reg:CC 17))])]
16978 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16979
16980 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16981 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
16982 ;; many CPUs it is also faster, since special hardware to avoid esp
16983 ;; dependancies is present.
16984
16985 ;; While some of these converisons may be done using splitters, we use peepholes
16986 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
16987
16988 ;; Convert prologue esp substractions to push.
16989 ;; We need register to push. In order to keep verify_flow_info happy we have
16990 ;; two choices
16991 ;; - use scratch and clobber it in order to avoid dependencies
16992 ;; - use already live register
16993 ;; We can't use the second way right now, since there is no reliable way how to
16994 ;; verify that given register is live. First choice will also most likely in
16995 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16996 ;; call clobbered registers are dead. We may want to use base pointer as an
16997 ;; alternative when no register is available later.
16998
16999 (define_peephole2
17000 [(match_scratch:SI 0 "r")
17001 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17002 (clobber (reg:CC 17))
17003 (clobber (mem:BLK (scratch)))])]
17004 "optimize_size || !TARGET_SUB_ESP_4"
17005 [(clobber (match_dup 0))
17006 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17007 (clobber (mem:BLK (scratch)))])])
17008
17009 (define_peephole2
17010 [(match_scratch:SI 0 "r")
17011 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17012 (clobber (reg:CC 17))
17013 (clobber (mem:BLK (scratch)))])]
17014 "optimize_size || !TARGET_SUB_ESP_8"
17015 [(clobber (match_dup 0))
17016 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17017 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17018 (clobber (mem:BLK (scratch)))])])
17019
17020 ;; Convert esp substractions to push.
17021 (define_peephole2
17022 [(match_scratch:SI 0 "r")
17023 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17024 (clobber (reg:CC 17))])]
17025 "optimize_size || !TARGET_SUB_ESP_4"
17026 [(clobber (match_dup 0))
17027 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17028
17029 (define_peephole2
17030 [(match_scratch:SI 0 "r")
17031 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17032 (clobber (reg:CC 17))])]
17033 "optimize_size || !TARGET_SUB_ESP_8"
17034 [(clobber (match_dup 0))
17035 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17036 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17037
17038 ;; Convert epilogue deallocator to pop.
17039 (define_peephole2
17040 [(match_scratch:SI 0 "r")
17041 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17042 (clobber (reg:CC 17))
17043 (clobber (mem:BLK (scratch)))])]
17044 "optimize_size || !TARGET_ADD_ESP_4"
17045 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17046 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17047 (clobber (mem:BLK (scratch)))])]
17048 "")
17049
17050 ;; Two pops case is tricky, since pop causes dependency on destination register.
17051 ;; We use two registers if available.
17052 (define_peephole2
17053 [(match_scratch:SI 0 "r")
17054 (match_scratch:SI 1 "r")
17055 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17056 (clobber (reg:CC 17))
17057 (clobber (mem:BLK (scratch)))])]
17058 "optimize_size || !TARGET_ADD_ESP_8"
17059 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17060 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17061 (clobber (mem:BLK (scratch)))])
17062 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17063 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17064 "")
17065
17066 (define_peephole2
17067 [(match_scratch:SI 0 "r")
17068 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17069 (clobber (reg:CC 17))
17070 (clobber (mem:BLK (scratch)))])]
17071 "optimize_size"
17072 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17073 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17074 (clobber (mem:BLK (scratch)))])
17075 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17076 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17077 "")
17078
17079 ;; Convert esp additions to pop.
17080 (define_peephole2
17081 [(match_scratch:SI 0 "r")
17082 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17083 (clobber (reg:CC 17))])]
17084 ""
17085 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17086 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17087 "")
17088
17089 ;; Two pops case is tricky, since pop causes dependency on destination register.
17090 ;; We use two registers if available.
17091 (define_peephole2
17092 [(match_scratch:SI 0 "r")
17093 (match_scratch:SI 1 "r")
17094 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17095 (clobber (reg:CC 17))])]
17096 ""
17097 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17098 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17099 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17100 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17101 "")
17102
17103 (define_peephole2
17104 [(match_scratch:SI 0 "r")
17105 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17106 (clobber (reg:CC 17))])]
17107 "optimize_size"
17108 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17109 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17110 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17111 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17112 "")
17113 \f
17114 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17115 ;; required and register dies.
17116 (define_peephole2
17117 [(set (reg 17)
17118 (compare (match_operand:SI 0 "register_operand" "")
17119 (match_operand:SI 1 "incdec_operand" "")))]
17120 "ix86_match_ccmode (insn, CCGCmode)
17121 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17122 [(parallel [(set (reg:CCGC 17)
17123 (compare:CCGC (match_dup 0)
17124 (match_dup 1)))
17125 (clobber (match_dup 0))])]
17126 "")
17127
17128 (define_peephole2
17129 [(set (reg 17)
17130 (compare (match_operand:HI 0 "register_operand" "")
17131 (match_operand:HI 1 "incdec_operand" "")))]
17132 "ix86_match_ccmode (insn, CCGCmode)
17133 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17134 [(parallel [(set (reg:CCGC 17)
17135 (compare:CCGC (match_dup 0)
17136 (match_dup 1)))
17137 (clobber (match_dup 0))])]
17138 "")
17139
17140 (define_peephole2
17141 [(set (reg 17)
17142 (compare (match_operand:QI 0 "register_operand" "")
17143 (match_operand:QI 1 "incdec_operand" "")))]
17144 "ix86_match_ccmode (insn, CCGCmode)
17145 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17146 [(parallel [(set (reg:CCGC 17)
17147 (compare:CCGC (match_dup 0)
17148 (match_dup 1)))
17149 (clobber (match_dup 0))])]
17150 "")
17151
17152 ;; Convert compares with 128 to shorter add -128
17153 (define_peephole2
17154 [(set (reg 17)
17155 (compare (match_operand:SI 0 "register_operand" "")
17156 (const_int 128)))]
17157 "ix86_match_ccmode (insn, CCGCmode)
17158 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17159 [(parallel [(set (reg:CCGC 17)
17160 (compare:CCGC (match_dup 0)
17161 (const_int 128)))
17162 (clobber (match_dup 0))])]
17163 "")
17164
17165 (define_peephole2
17166 [(set (reg 17)
17167 (compare (match_operand:HI 0 "register_operand" "")
17168 (const_int 128)))]
17169 "ix86_match_ccmode (insn, CCGCmode)
17170 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17171 [(parallel [(set (reg:CCGC 17)
17172 (compare:CCGC (match_dup 0)
17173 (const_int 128)))
17174 (clobber (match_dup 0))])]
17175 "")
17176 \f
17177 (define_peephole2
17178 [(match_scratch:DI 0 "r")
17179 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17180 (clobber (reg:CC 17))
17181 (clobber (mem:BLK (scratch)))])]
17182 "optimize_size || !TARGET_SUB_ESP_4"
17183 [(clobber (match_dup 0))
17184 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17185 (clobber (mem:BLK (scratch)))])])
17186
17187 (define_peephole2
17188 [(match_scratch:DI 0 "r")
17189 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17190 (clobber (reg:CC 17))
17191 (clobber (mem:BLK (scratch)))])]
17192 "optimize_size || !TARGET_SUB_ESP_8"
17193 [(clobber (match_dup 0))
17194 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17195 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17196 (clobber (mem:BLK (scratch)))])])
17197
17198 ;; Convert esp substractions to push.
17199 (define_peephole2
17200 [(match_scratch:DI 0 "r")
17201 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17202 (clobber (reg:CC 17))])]
17203 "optimize_size || !TARGET_SUB_ESP_4"
17204 [(clobber (match_dup 0))
17205 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17206
17207 (define_peephole2
17208 [(match_scratch:DI 0 "r")
17209 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17210 (clobber (reg:CC 17))])]
17211 "optimize_size || !TARGET_SUB_ESP_8"
17212 [(clobber (match_dup 0))
17213 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17214 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
17215
17216 ;; Convert epilogue deallocator to pop.
17217 (define_peephole2
17218 [(match_scratch:DI 0 "r")
17219 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17220 (clobber (reg:CC 17))
17221 (clobber (mem:BLK (scratch)))])]
17222 "optimize_size || !TARGET_ADD_ESP_4"
17223 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17224 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17225 (clobber (mem:BLK (scratch)))])]
17226 "")
17227
17228 ;; Two pops case is tricky, since pop causes dependency on destination register.
17229 ;; We use two registers if available.
17230 (define_peephole2
17231 [(match_scratch:DI 0 "r")
17232 (match_scratch:DI 1 "r")
17233 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17234 (clobber (reg:CC 17))
17235 (clobber (mem:BLK (scratch)))])]
17236 "optimize_size || !TARGET_ADD_ESP_8"
17237 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17238 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17239 (clobber (mem:BLK (scratch)))])
17240 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17241 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17242 "")
17243
17244 (define_peephole2
17245 [(match_scratch:DI 0 "r")
17246 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17247 (clobber (reg:CC 17))
17248 (clobber (mem:BLK (scratch)))])]
17249 "optimize_size"
17250 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17251 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17252 (clobber (mem:BLK (scratch)))])
17253 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17254 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17255 "")
17256
17257 ;; Convert esp additions to pop.
17258 (define_peephole2
17259 [(match_scratch:DI 0 "r")
17260 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
17261 (clobber (reg:CC 17))])]
17262 ""
17263 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17264 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17265 "")
17266
17267 ;; Two pops case is tricky, since pop causes dependency on destination register.
17268 ;; We use two registers if available.
17269 (define_peephole2
17270 [(match_scratch:DI 0 "r")
17271 (match_scratch:DI 1 "r")
17272 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17273 (clobber (reg:CC 17))])]
17274 ""
17275 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17276 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17277 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
17278 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17279 "")
17280
17281 (define_peephole2
17282 [(match_scratch:DI 0 "r")
17283 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
17284 (clobber (reg:CC 17))])]
17285 "optimize_size"
17286 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17287 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
17288 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
17289 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
17290 "")
17291 \f
17292 ;; Call-value patterns last so that the wildcard operand does not
17293 ;; disrupt insn-recog's switch tables.
17294
17295 (define_insn "*call_value_pop_0"
17296 [(set (match_operand 0 "" "")
17297 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17298 (match_operand:SI 2 "" "")))
17299 (set (reg:SI 7) (plus:SI (reg:SI 7)
17300 (match_operand:SI 3 "immediate_operand" "")))]
17301 "!TARGET_64BIT"
17302 {
17303 if (SIBLING_CALL_P (insn))
17304 return "jmp\t%P1";
17305 else
17306 return "call\t%P1";
17307 }
17308 [(set_attr "type" "callv")])
17309
17310 (define_insn "*call_value_pop_1"
17311 [(set (match_operand 0 "" "")
17312 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17313 (match_operand:SI 2 "" "")))
17314 (set (reg:SI 7) (plus:SI (reg:SI 7)
17315 (match_operand:SI 3 "immediate_operand" "i")))]
17316 "!TARGET_64BIT"
17317 {
17318 if (constant_call_address_operand (operands[1], QImode))
17319 {
17320 if (SIBLING_CALL_P (insn))
17321 return "jmp\t%P1";
17322 else
17323 return "call\t%P1";
17324 }
17325 if (SIBLING_CALL_P (insn))
17326 return "jmp\t%A1";
17327 else
17328 return "call\t%A1";
17329 }
17330 [(set_attr "type" "callv")])
17331
17332 (define_insn "*call_value_0"
17333 [(set (match_operand 0 "" "")
17334 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17335 (match_operand:SI 2 "" "")))]
17336 "!TARGET_64BIT"
17337 {
17338 if (SIBLING_CALL_P (insn))
17339 return "jmp\t%P1";
17340 else
17341 return "call\t%P1";
17342 }
17343 [(set_attr "type" "callv")])
17344
17345 (define_insn "*call_value_0_rex64"
17346 [(set (match_operand 0 "" "")
17347 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17348 (match_operand:DI 2 "const_int_operand" "")))]
17349 "TARGET_64BIT"
17350 {
17351 if (SIBLING_CALL_P (insn))
17352 return "jmp\t%P1";
17353 else
17354 return "call\t%P1";
17355 }
17356 [(set_attr "type" "callv")])
17357
17358 (define_insn "*call_value_1"
17359 [(set (match_operand 0 "" "")
17360 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17361 (match_operand:SI 2 "" "")))]
17362 "!TARGET_64BIT"
17363 {
17364 if (constant_call_address_operand (operands[1], QImode))
17365 {
17366 if (SIBLING_CALL_P (insn))
17367 return "jmp\t%P1";
17368 else
17369 return "call\t%P1";
17370 }
17371 if (SIBLING_CALL_P (insn))
17372 return "jmp\t%*%1";
17373 else
17374 return "call\t%*%1";
17375 }
17376 [(set_attr "type" "callv")])
17377
17378 (define_insn "*call_value_1_rex64"
17379 [(set (match_operand 0 "" "")
17380 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17381 (match_operand:DI 2 "" "")))]
17382 "TARGET_64BIT"
17383 {
17384 if (constant_call_address_operand (operands[1], QImode))
17385 {
17386 if (SIBLING_CALL_P (insn))
17387 return "jmp\t%P1";
17388 else
17389 return "call\t%P1";
17390 }
17391 if (SIBLING_CALL_P (insn))
17392 return "jmp\t%A1";
17393 else
17394 return "call\t%A1";
17395 }
17396 [(set_attr "type" "callv")])
17397 \f
17398 (define_insn "trap"
17399 [(trap_if (const_int 1) (const_int 5))]
17400 ""
17401 "int\t$5")
17402
17403 ;;; ix86 doesn't have conditional trap instructions, but we fake them
17404 ;;; for the sake of bounds checking. By emitting bounds checks as
17405 ;;; conditional traps rather than as conditional jumps around
17406 ;;; unconditional traps we avoid introducing spurious basic-block
17407 ;;; boundaries and facilitate elimination of redundant checks. In
17408 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17409 ;;; interrupt 5.
17410 ;;;
17411 ;;; FIXME: Static branch prediction rules for ix86 are such that
17412 ;;; forward conditional branches predict as untaken. As implemented
17413 ;;; below, pseudo conditional traps violate that rule. We should use
17414 ;;; .pushsection/.popsection to place all of the `int 5's in a special
17415 ;;; section loaded at the end of the text segment and branch forward
17416 ;;; there on bounds-failure, and then jump back immediately (in case
17417 ;;; the system chooses to ignore bounds violations, or to report
17418 ;;; violations and continue execution).
17419
17420 (define_expand "conditional_trap"
17421 [(trap_if (match_operator 0 "comparison_operator"
17422 [(match_dup 2) (const_int 0)])
17423 (match_operand 1 "const_int_operand" ""))]
17424 ""
17425 {
17426 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17427 ix86_expand_compare (GET_CODE (operands[0]),
17428 NULL, NULL),
17429 operands[1]));
17430 DONE;
17431 })
17432
17433 (define_insn "*conditional_trap_1"
17434 [(trap_if (match_operator 0 "comparison_operator"
17435 [(reg 17) (const_int 0)])
17436 (match_operand 1 "const_int_operand" ""))]
17437 ""
17438 {
17439 operands[2] = gen_label_rtx ();
17440 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
17441 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
17442 CODE_LABEL_NUMBER (operands[2]));
17443 RET;
17444 })
17445
17446 ;; Pentium III SIMD instructions.
17447
17448 ;; Moves for SSE/MMX regs.
17449
17450 (define_insn "movv4sf_internal"
17451 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17452 (match_operand:V4SF 1 "general_operand" "xm,x"))]
17453 "TARGET_SSE"
17454 ;; @@@ let's try to use movaps here.
17455 "movaps\t{%1, %0|%0, %1}"
17456 [(set_attr "type" "sse")])
17457
17458 (define_insn "movv4si_internal"
17459 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17460 (match_operand:V4SI 1 "general_operand" "xm,x"))]
17461 "TARGET_SSE"
17462 ;; @@@ let's try to use movaps here.
17463 "movaps\t{%1, %0|%0, %1}"
17464 [(set_attr "type" "sse")])
17465
17466 (define_insn "movv8qi_internal"
17467 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17468 (match_operand:V8QI 1 "general_operand" "ym,y"))]
17469 "TARGET_MMX"
17470 "movq\t{%1, %0|%0, %1}"
17471 [(set_attr "type" "mmx")])
17472
17473 (define_insn "movv4hi_internal"
17474 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17475 (match_operand:V4HI 1 "general_operand" "ym,y"))]
17476 "TARGET_MMX"
17477 "movq\t{%1, %0|%0, %1}"
17478 [(set_attr "type" "mmx")])
17479
17480 (define_insn "movv2si_internal"
17481 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17482 (match_operand:V2SI 1 "general_operand" "ym,y"))]
17483 "TARGET_MMX"
17484 "movq\t{%1, %0|%0, %1}"
17485 [(set_attr "type" "mmx")])
17486
17487 (define_insn "movv2sf_internal"
17488 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
17489 (match_operand:V2SF 1 "general_operand" "ym,y"))]
17490 "TARGET_3DNOW"
17491 "movq\\t{%1, %0|%0, %1}"
17492 [(set_attr "type" "mmx")])
17493
17494 (define_expand "movti"
17495 [(set (match_operand:TI 0 "general_operand" "")
17496 (match_operand:TI 1 "general_operand" ""))]
17497 "TARGET_SSE"
17498 {
17499 /* For constants other than zero into memory. We do not know how the
17500 instructions used to build constants modify the upper 64 bits
17501 of the register, once we have that information we may be able
17502 to handle some of them more efficiently. */
17503 if ((reload_in_progress | reload_completed) == 0
17504 && register_operand (operands[0], TImode)
17505 && CONSTANT_P (operands[1]))
17506 {
17507 rtx addr = gen_reg_rtx (Pmode);
17508
17509 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
17510 operands[1] = gen_rtx_MEM (TImode, addr);
17511 }
17512
17513 /* Make operand1 a register if it isn't already. */
17514 if ((reload_in_progress | reload_completed) == 0
17515 && !register_operand (operands[0], TImode)
17516 && !register_operand (operands[1], TImode)
17517 && operands[1] != CONST0_RTX (TImode))
17518 {
17519 rtx temp = force_reg (TImode, operands[1]);
17520 emit_move_insn (operands[0], temp);
17521 DONE;
17522 }
17523 })
17524
17525 (define_expand "movv4sf"
17526 [(set (match_operand:V4SF 0 "general_operand" "")
17527 (match_operand:V4SF 1 "general_operand" ""))]
17528 "TARGET_SSE"
17529 {
17530 /* For constants other than zero into memory. We do not know how the
17531 instructions used to build constants modify the upper 64 bits
17532 of the register, once we have that information we may be able
17533 to handle some of them more efficiently. */
17534 if ((reload_in_progress | reload_completed) == 0
17535 && register_operand (operands[0], V4SFmode)
17536 && CONSTANT_P (operands[1]))
17537 {
17538 rtx addr = gen_reg_rtx (Pmode);
17539
17540 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
17541 operands[1] = gen_rtx_MEM (V4SFmode, addr);
17542 }
17543
17544 /* Make operand1 a register if it isn't already. */
17545 if ((reload_in_progress | reload_completed) == 0
17546 && !register_operand (operands[0], V4SFmode)
17547 && !register_operand (operands[1], V4SFmode)
17548 && operands[1] != CONST0_RTX (V4SFmode))
17549 {
17550 rtx temp = force_reg (V4SFmode, operands[1]);
17551 emit_move_insn (operands[0], temp);
17552 DONE;
17553 }
17554 })
17555
17556 (define_expand "movv4si"
17557 [(set (match_operand:V4SI 0 "general_operand" "")
17558 (match_operand:V4SI 1 "general_operand" ""))]
17559 "TARGET_MMX"
17560 {
17561 /* For constants other than zero into memory. We do not know how the
17562 instructions used to build constants modify the upper 64 bits
17563 of the register, once we have that information we may be able
17564 to handle some of them more efficiently. */
17565 if ((reload_in_progress | reload_completed) == 0
17566 && register_operand (operands[0], V4SImode)
17567 && CONSTANT_P (operands[1]))
17568 {
17569 rtx addr = gen_reg_rtx (Pmode);
17570
17571 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
17572 operands[1] = gen_rtx_MEM (V4SImode, addr);
17573 }
17574
17575 /* Make operand1 a register if it isn't already. */
17576 if ((reload_in_progress | reload_completed) == 0
17577 && !register_operand (operands[0], V4SImode)
17578 && !register_operand (operands[1], V4SImode)
17579 && operands[1] != CONST0_RTX (V4SImode))
17580 {
17581 rtx temp = force_reg (V4SImode, operands[1]);
17582 emit_move_insn (operands[0], temp);
17583 DONE;
17584 }
17585 })
17586
17587 (define_expand "movv2si"
17588 [(set (match_operand:V2SI 0 "general_operand" "")
17589 (match_operand:V2SI 1 "general_operand" ""))]
17590 "TARGET_MMX"
17591 {
17592 /* For constants other than zero into memory. We do not know how the
17593 instructions used to build constants modify the upper 64 bits
17594 of the register, once we have that information we may be able
17595 to handle some of them more efficiently. */
17596 if ((reload_in_progress | reload_completed) == 0
17597 && register_operand (operands[0], V2SImode)
17598 && CONSTANT_P (operands[1]))
17599 {
17600 rtx addr = gen_reg_rtx (Pmode);
17601
17602 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
17603 operands[1] = gen_rtx_MEM (V2SImode, addr);
17604 }
17605
17606 /* Make operand1 a register if it isn't already. */
17607 if ((reload_in_progress | reload_completed) == 0
17608 && !register_operand (operands[0], V2SImode)
17609 && !register_operand (operands[1], V2SImode)
17610 && operands[1] != CONST0_RTX (V2SImode))
17611 {
17612 rtx temp = force_reg (V2SImode, operands[1]);
17613 emit_move_insn (operands[0], temp);
17614 DONE;
17615 }
17616 })
17617
17618 (define_expand "movv4hi"
17619 [(set (match_operand:V4HI 0 "general_operand" "")
17620 (match_operand:V4HI 1 "general_operand" ""))]
17621 "TARGET_MMX"
17622 {
17623 /* For constants other than zero into memory. We do not know how the
17624 instructions used to build constants modify the upper 64 bits
17625 of the register, once we have that information we may be able
17626 to handle some of them more efficiently. */
17627 if ((reload_in_progress | reload_completed) == 0
17628 && register_operand (operands[0], V4HImode)
17629 && CONSTANT_P (operands[1]))
17630 {
17631 rtx addr = gen_reg_rtx (Pmode);
17632
17633 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
17634 operands[1] = gen_rtx_MEM (V4HImode, addr);
17635 }
17636
17637 /* Make operand1 a register if it isn't already. */
17638 if ((reload_in_progress | reload_completed) == 0
17639 && !register_operand (operands[0], V4HImode)
17640 && !register_operand (operands[1], V4HImode)
17641 && operands[1] != CONST0_RTX (V4HImode))
17642 {
17643 rtx temp = force_reg (V4HImode, operands[1]);
17644 emit_move_insn (operands[0], temp);
17645 DONE;
17646 }
17647 })
17648
17649 (define_expand "movv8qi"
17650 [(set (match_operand:V8QI 0 "general_operand" "")
17651 (match_operand:V8QI 1 "general_operand" ""))]
17652 "TARGET_MMX"
17653 {
17654 /* For constants other than zero into memory. We do not know how the
17655 instructions used to build constants modify the upper 64 bits
17656 of the register, once we have that information we may be able
17657 to handle some of them more efficiently. */
17658 if ((reload_in_progress | reload_completed) == 0
17659 && register_operand (operands[0], V8QImode)
17660 && CONSTANT_P (operands[1]))
17661 {
17662 rtx addr = gen_reg_rtx (Pmode);
17663
17664 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
17665 operands[1] = gen_rtx_MEM (V8QImode, addr);
17666 }
17667
17668 /* Make operand1 a register if it isn't already. */
17669 if ((reload_in_progress | reload_completed) == 0
17670 && !register_operand (operands[0], V8QImode)
17671 && !register_operand (operands[1], V8QImode)
17672 && operands[1] != CONST0_RTX (V8QImode))
17673 {
17674 rtx temp = force_reg (V8QImode, operands[1]);
17675 emit_move_insn (operands[0], temp);
17676 DONE;
17677 }
17678 })
17679
17680 (define_expand "movv2sf"
17681 [(set (match_operand:V2SF 0 "general_operand" "")
17682 (match_operand:V2SF 1 "general_operand" ""))]
17683 "TARGET_3DNOW"
17684 "
17685 {
17686 /* For constants other than zero into memory. We do not know how the
17687 instructions used to build constants modify the upper 64 bits
17688 of the register, once we have that information we may be able
17689 to handle some of them more efficiently. */
17690 if ((reload_in_progress | reload_completed) == 0
17691 && register_operand (operands[0], V2SFmode)
17692 && CONSTANT_P (operands[1]))
17693 {
17694 rtx addr = gen_reg_rtx (Pmode);
17695
17696 emit_move_insn (addr,
17697 XEXP (force_const_mem (V2SFmode, operands[1]), 0));
17698 operands[1] = gen_rtx_MEM (V2SFmode, addr);
17699 }
17700
17701 /* Make operand1 a register is it isn't already. */
17702 if ((reload_in_progress | reload_completed) == 0
17703 && !register_operand (operands[0], V2SFmode)
17704 && !register_operand (operands[1], V2SFmode)
17705 && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
17706 && operands[1] != CONST0_RTX (V2SFmode))
17707 {
17708 rtx temp = force_reg (V2SFmode, operands[1]);
17709 emit_move_insn (operands[0], temp);
17710 DONE;
17711 }
17712 }")
17713
17714 (define_insn_and_split "*pushti"
17715 [(set (match_operand:TI 0 "push_operand" "=<")
17716 (match_operand:TI 1 "nonmemory_operand" "x"))]
17717 "TARGET_SSE"
17718 "#"
17719 ""
17720 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17721 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17722 ""
17723 [(set_attr "type" "sse")])
17724
17725 (define_insn_and_split "*pushv4sf"
17726 [(set (match_operand:V4SF 0 "push_operand" "=<")
17727 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17728 "TARGET_SSE"
17729 "#"
17730 ""
17731 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17732 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17733 ""
17734 [(set_attr "type" "sse")])
17735
17736 (define_insn_and_split "*pushv4si"
17737 [(set (match_operand:V4SI 0 "push_operand" "=<")
17738 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17739 "TARGET_SSE"
17740 "#"
17741 ""
17742 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17743 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17744 ""
17745 [(set_attr "type" "sse")])
17746
17747 (define_insn_and_split "*pushv2si"
17748 [(set (match_operand:V2SI 0 "push_operand" "=<")
17749 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17750 "TARGET_MMX"
17751 "#"
17752 ""
17753 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17754 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17755 ""
17756 [(set_attr "type" "mmx")])
17757
17758 (define_insn_and_split "*pushv4hi"
17759 [(set (match_operand:V4HI 0 "push_operand" "=<")
17760 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17761 "TARGET_MMX"
17762 "#"
17763 ""
17764 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17765 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17766 ""
17767 [(set_attr "type" "mmx")])
17768
17769 (define_insn_and_split "*pushv8qi"
17770 [(set (match_operand:V8QI 0 "push_operand" "=<")
17771 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17772 "TARGET_MMX"
17773 "#"
17774 ""
17775 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17776 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17777 ""
17778 [(set_attr "type" "mmx")])
17779
17780 (define_insn_and_split "*pushv2sf"
17781 [(set (match_operand:V2SF 0 "push_operand" "=<")
17782 (match_operand:V2SF 1 "nonmemory_operand" "y"))]
17783 "TARGET_3DNOW"
17784 "#"
17785 ""
17786 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17787 (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
17788 ""
17789 [(set_attr "type" "mmx")])
17790
17791 (define_insn "movti_internal"
17792 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
17793 (match_operand:TI 1 "general_operand" "xm,x"))]
17794 "TARGET_SSE"
17795 "@
17796 movaps\t{%1, %0|%0, %1}
17797 movaps\t{%1, %0|%0, %1}"
17798 [(set_attr "type" "sse")])
17799
17800 ;; These two patterns are useful for specifying exactly whether to use
17801 ;; movaps or movups
17802 (define_insn "sse_movaps"
17803 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17804 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
17805 "TARGET_SSE"
17806 "@
17807 movaps\t{%1, %0|%0, %1}
17808 movaps\t{%1, %0|%0, %1}"
17809 [(set_attr "type" "sse")])
17810
17811 (define_insn "sse_movups"
17812 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17813 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
17814 "TARGET_SSE"
17815 "@
17816 movups\t{%1, %0|%0, %1}
17817 movups\t{%1, %0|%0, %1}"
17818 [(set_attr "type" "sse")])
17819
17820
17821 ;; SSE Strange Moves.
17822
17823 (define_insn "sse_movmskps"
17824 [(set (match_operand:SI 0 "register_operand" "=r")
17825 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
17826 "TARGET_SSE"
17827 "movmskps\t{%1, %0|%0, %1}"
17828 [(set_attr "type" "sse")])
17829
17830 (define_insn "mmx_pmovmskb"
17831 [(set (match_operand:SI 0 "register_operand" "=r")
17832 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
17833 "TARGET_SSE || TARGET_3DNOW_A"
17834 "pmovmskb\t{%1, %0|%0, %1}"
17835 [(set_attr "type" "sse")])
17836
17837 (define_insn "mmx_maskmovq"
17838 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17839 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17840 (match_operand:V8QI 2 "register_operand" "y")] 32))]
17841 "TARGET_SSE || TARGET_3DNOW_A"
17842 ;; @@@ check ordering of operands in intel/nonintel syntax
17843 "maskmovq\t{%2, %1|%1, %2}"
17844 [(set_attr "type" "sse")])
17845
17846 (define_insn "sse_movntv4sf"
17847 [(set (match_operand:V4SF 0 "memory_operand" "=m")
17848 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
17849 "TARGET_SSE"
17850 "movntps\t{%1, %0|%0, %1}"
17851 [(set_attr "type" "sse")])
17852
17853 (define_insn "sse_movntdi"
17854 [(set (match_operand:DI 0 "memory_operand" "=m")
17855 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
17856 "TARGET_SSE || TARGET_3DNOW_A"
17857 "movntq\t{%1, %0|%0, %1}"
17858 [(set_attr "type" "sse")])
17859
17860 (define_insn "sse_movhlps"
17861 [(set (match_operand:V4SF 0 "register_operand" "=x")
17862 (vec_merge:V4SF
17863 (match_operand:V4SF 1 "register_operand" "0")
17864 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17865 (parallel [(const_int 2)
17866 (const_int 3)
17867 (const_int 0)
17868 (const_int 1)]))
17869 (const_int 3)))]
17870 "TARGET_SSE"
17871 "movhlps\t{%2, %0|%0, %2}"
17872 [(set_attr "type" "sse")])
17873
17874 (define_insn "sse_movlhps"
17875 [(set (match_operand:V4SF 0 "register_operand" "=x")
17876 (vec_merge:V4SF
17877 (match_operand:V4SF 1 "register_operand" "0")
17878 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17879 (parallel [(const_int 2)
17880 (const_int 3)
17881 (const_int 0)
17882 (const_int 1)]))
17883 (const_int 12)))]
17884 "TARGET_SSE"
17885 "movlhps\t{%2, %0|%0, %2}"
17886 [(set_attr "type" "sse")])
17887
17888 (define_insn "sse_movhps"
17889 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17890 (vec_merge:V4SF
17891 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17892 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17893 (const_int 12)))]
17894 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17895 "movhps\t{%2, %0|%0, %2}"
17896 [(set_attr "type" "sse")])
17897
17898 (define_insn "sse_movlps"
17899 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17900 (vec_merge:V4SF
17901 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17902 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17903 (const_int 3)))]
17904 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17905 "movlps\t{%2, %0|%0, %2}"
17906 [(set_attr "type" "sse")])
17907
17908 (define_insn "sse_loadss"
17909 [(set (match_operand:V4SF 0 "register_operand" "=x")
17910 (vec_merge:V4SF
17911 (match_operand:V4SF 1 "memory_operand" "m")
17912 (vec_duplicate:V4SF (float:SF (const_int 0)))
17913 (const_int 1)))]
17914 "TARGET_SSE"
17915 "movss\t{%1, %0|%0, %1}"
17916 [(set_attr "type" "sse")])
17917
17918 (define_insn "sse_movss"
17919 [(set (match_operand:V4SF 0 "register_operand" "=x")
17920 (vec_merge:V4SF
17921 (match_operand:V4SF 1 "register_operand" "0")
17922 (match_operand:V4SF 2 "register_operand" "x")
17923 (const_int 1)))]
17924 "TARGET_SSE"
17925 "movss\t{%2, %0|%0, %2}"
17926 [(set_attr "type" "sse")])
17927
17928 (define_insn "sse_storess"
17929 [(set (match_operand:SF 0 "memory_operand" "=m")
17930 (vec_select:SF
17931 (match_operand:V4SF 1 "register_operand" "x")
17932 (parallel [(const_int 0)])))]
17933 "TARGET_SSE"
17934 "movss\t{%1, %0|%0, %1}"
17935 [(set_attr "type" "sse")])
17936
17937 (define_insn "sse_shufps"
17938 [(set (match_operand:V4SF 0 "register_operand" "=x")
17939 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
17940 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
17941 (match_operand:SI 3 "immediate_operand" "i")] 41))]
17942 "TARGET_SSE"
17943 ;; @@@ check operand order for intel/nonintel syntax
17944 "shufps\t{%3, %2, %0|%0, %2, %3}"
17945 [(set_attr "type" "sse")])
17946
17947
17948 ;; SSE arithmetic
17949
17950 (define_insn "addv4sf3"
17951 [(set (match_operand:V4SF 0 "register_operand" "=x")
17952 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17953 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17954 "TARGET_SSE"
17955 "addps\t{%2, %0|%0, %2}"
17956 [(set_attr "type" "sse")])
17957
17958 (define_insn "vmaddv4sf3"
17959 [(set (match_operand:V4SF 0 "register_operand" "=x")
17960 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17961 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17962 (match_dup 1)
17963 (const_int 1)))]
17964 "TARGET_SSE"
17965 "addss\t{%2, %0|%0, %2}"
17966 [(set_attr "type" "sse")])
17967
17968 (define_insn "subv4sf3"
17969 [(set (match_operand:V4SF 0 "register_operand" "=x")
17970 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17971 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17972 "TARGET_SSE"
17973 "subps\t{%2, %0|%0, %2}"
17974 [(set_attr "type" "sse")])
17975
17976 (define_insn "vmsubv4sf3"
17977 [(set (match_operand:V4SF 0 "register_operand" "=x")
17978 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17979 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17980 (match_dup 1)
17981 (const_int 1)))]
17982 "TARGET_SSE"
17983 "subss\t{%2, %0|%0, %2}"
17984 [(set_attr "type" "sse")])
17985
17986 (define_insn "mulv4sf3"
17987 [(set (match_operand:V4SF 0 "register_operand" "=x")
17988 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17989 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17990 "TARGET_SSE"
17991 "mulps\t{%2, %0|%0, %2}"
17992 [(set_attr "type" "sse")])
17993
17994 (define_insn "vmmulv4sf3"
17995 [(set (match_operand:V4SF 0 "register_operand" "=x")
17996 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17997 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17998 (match_dup 1)
17999 (const_int 1)))]
18000 "TARGET_SSE"
18001 "mulss\t{%2, %0|%0, %2}"
18002 [(set_attr "type" "sse")])
18003
18004 (define_insn "divv4sf3"
18005 [(set (match_operand:V4SF 0 "register_operand" "=x")
18006 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18007 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18008 "TARGET_SSE"
18009 "divps\t{%2, %0|%0, %2}"
18010 [(set_attr "type" "sse")])
18011
18012 (define_insn "vmdivv4sf3"
18013 [(set (match_operand:V4SF 0 "register_operand" "=x")
18014 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
18015 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18016 (match_dup 1)
18017 (const_int 1)))]
18018 "TARGET_SSE"
18019 "divss\t{%2, %0|%0, %2}"
18020 [(set_attr "type" "sse")])
18021
18022
18023 ;; SSE square root/reciprocal
18024
18025 (define_insn "rcpv4sf2"
18026 [(set (match_operand:V4SF 0 "register_operand" "=x")
18027 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
18028 "TARGET_SSE"
18029 "rcpps\t{%1, %0|%0, %1}"
18030 [(set_attr "type" "sse")])
18031
18032 (define_insn "vmrcpv4sf2"
18033 [(set (match_operand:V4SF 0 "register_operand" "=x")
18034 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
18035 (match_operand:V4SF 2 "register_operand" "0")
18036 (const_int 1)))]
18037 "TARGET_SSE"
18038 "rcpss\t{%1, %0|%0, %1}"
18039 [(set_attr "type" "sse")])
18040
18041 (define_insn "rsqrtv4sf2"
18042 [(set (match_operand:V4SF 0 "register_operand" "=x")
18043 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
18044 "TARGET_SSE"
18045 "rsqrtps\t{%1, %0|%0, %1}"
18046 [(set_attr "type" "sse")])
18047
18048 (define_insn "vmrsqrtv4sf2"
18049 [(set (match_operand:V4SF 0 "register_operand" "=x")
18050 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
18051 (match_operand:V4SF 2 "register_operand" "0")
18052 (const_int 1)))]
18053 "TARGET_SSE"
18054 "rsqrtss\t{%1, %0|%0, %1}"
18055 [(set_attr "type" "sse")])
18056
18057 (define_insn "sqrtv4sf2"
18058 [(set (match_operand:V4SF 0 "register_operand" "=x")
18059 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
18060 "TARGET_SSE"
18061 "sqrtps\t{%1, %0|%0, %1}"
18062 [(set_attr "type" "sse")])
18063
18064 (define_insn "vmsqrtv4sf2"
18065 [(set (match_operand:V4SF 0 "register_operand" "=x")
18066 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
18067 (match_operand:V4SF 2 "register_operand" "0")
18068 (const_int 1)))]
18069 "TARGET_SSE"
18070 "sqrtss\t{%1, %0|%0, %1}"
18071 [(set_attr "type" "sse")])
18072
18073
18074 ;; SSE logical operations.
18075
18076 ;; These are not called andti3 etc. because we really really don't want
18077 ;; the compiler to widen DImode ands to TImode ands and then try to move
18078 ;; into DImode subregs of SSE registers, and them together, and move out
18079 ;; of DImode subregs again!
18080
18081 (define_insn "*sse_andti3_df_1"
18082 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18083 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18084 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18085 "TARGET_SSE2"
18086 "andpd\t{%2, %0|%0, %2}"
18087 [(set_attr "type" "sse")])
18088
18089 (define_insn "*sse_andti3_df_2"
18090 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18091 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18092 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18093 "TARGET_SSE2"
18094 "andpd\t{%2, %0|%0, %2}"
18095 [(set_attr "type" "sse")])
18096
18097 (define_insn "*sse_andti3_sf_1"
18098 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18099 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18100 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18101 "TARGET_SSE"
18102 "andps\t{%2, %0|%0, %2}"
18103 [(set_attr "type" "sse")])
18104
18105 (define_insn "*sse_andti3_sf_2"
18106 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18107 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18108 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18109 "TARGET_SSE"
18110 "andps\t{%2, %0|%0, %2}"
18111 [(set_attr "type" "sse")])
18112
18113 (define_insn "sse_andti3"
18114 [(set (match_operand:TI 0 "register_operand" "=x")
18115 (and:TI (match_operand:TI 1 "register_operand" "%0")
18116 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18117 "TARGET_SSE && !TARGET_SSE2"
18118 "andps\t{%2, %0|%0, %2}"
18119 [(set_attr "type" "sse")])
18120
18121 (define_insn "*sse_andti3_sse2"
18122 [(set (match_operand:TI 0 "register_operand" "=x")
18123 (and:TI (match_operand:TI 1 "register_operand" "%0")
18124 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18125 "TARGET_SSE2"
18126 "pand\t{%2, %0|%0, %2}"
18127 [(set_attr "type" "sse")])
18128
18129 (define_insn "*sse_nandti3_df"
18130 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18131 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
18132 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18133 "TARGET_SSE2"
18134 "andnpd\t{%2, %0|%0, %2}"
18135 [(set_attr "type" "sse")])
18136
18137 (define_insn "*sse_nandti3_sf"
18138 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18139 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
18140 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18141 "TARGET_SSE"
18142 "andnps\t{%2, %0|%0, %2}"
18143 [(set_attr "type" "sse")])
18144
18145 (define_insn "sse_nandti3"
18146 [(set (match_operand:TI 0 "register_operand" "=x")
18147 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18148 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18149 "TARGET_SSE && !TARGET_SSE2"
18150 "andnps\t{%2, %0|%0, %2}"
18151 [(set_attr "type" "sse")])
18152
18153 (define_insn "*sse_nandti3_sse2"
18154 [(set (match_operand:TI 0 "register_operand" "=x")
18155 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
18156 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18157 "TARGET_SSE2"
18158 "pnand\t{%2, %0|%0, %2}"
18159 [(set_attr "type" "sse")])
18160
18161 (define_insn "*sse_iorti3_df_1"
18162 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18163 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18164 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18165 "TARGET_SSE2"
18166 "orpd\t{%2, %0|%0, %2}"
18167 [(set_attr "type" "sse")])
18168
18169 (define_insn "*sse_iorti3_df_2"
18170 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18171 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18172 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18173 "TARGET_SSE2"
18174 "orpd\t{%2, %0|%0, %2}"
18175 [(set_attr "type" "sse")])
18176
18177 (define_insn "*sse_iorti3_sf_1"
18178 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18179 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18180 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18181 "TARGET_SSE"
18182 "orps\t{%2, %0|%0, %2}"
18183 [(set_attr "type" "sse")])
18184
18185 (define_insn "*sse_iorti3_sf_2"
18186 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18187 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18188 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18189 "TARGET_SSE"
18190 "orps\t{%2, %0|%0, %2}"
18191 [(set_attr "type" "sse")])
18192
18193 (define_insn "sse_iorti3"
18194 [(set (match_operand:TI 0 "register_operand" "=x")
18195 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18196 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18197 "TARGET_SSE && !TARGET_SSE2"
18198 "orps\t{%2, %0|%0, %2}"
18199 [(set_attr "type" "sse")])
18200
18201 (define_insn "*sse_iorti3_sse2"
18202 [(set (match_operand:TI 0 "register_operand" "=x")
18203 (ior:TI (match_operand:TI 1 "register_operand" "%0")
18204 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18205 "TARGET_SSE2"
18206 "por\t{%2, %0|%0, %2}"
18207 [(set_attr "type" "sse")])
18208
18209 (define_insn "*sse_xorti3_df_1"
18210 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18211 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
18212 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
18213 "TARGET_SSE2"
18214 "xorpd\t{%2, %0|%0, %2}"
18215 [(set_attr "type" "sse")])
18216
18217 (define_insn "*sse_xorti3_df_2"
18218 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
18219 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
18220 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
18221 "TARGET_SSE2"
18222 "xorpd\t{%2, %0|%0, %2}"
18223 [(set_attr "type" "sse")])
18224
18225 (define_insn "*sse_xorti3_sf_1"
18226 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18227 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
18228 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
18229 "TARGET_SSE"
18230 "xorps\t{%2, %0|%0, %2}"
18231 [(set_attr "type" "sse")])
18232
18233 (define_insn "*sse_xorti3_sf_2"
18234 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
18235 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
18236 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18237 "TARGET_SSE"
18238 "xorps\t{%2, %0|%0, %2}"
18239 [(set_attr "type" "sse")])
18240
18241 (define_insn "sse_xorti3"
18242 [(set (match_operand:TI 0 "register_operand" "=x")
18243 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18244 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18245 "TARGET_SSE && !TARGET_SSE2"
18246 "xorps\t{%2, %0|%0, %2}"
18247 [(set_attr "type" "sse")])
18248
18249 (define_insn "*sse_xorti3_sse2"
18250 [(set (match_operand:TI 0 "register_operand" "=x")
18251 (xor:TI (match_operand:TI 1 "register_operand" "%0")
18252 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
18253 "TARGET_SSE2"
18254 "pxor\t{%2, %0|%0, %2}"
18255 [(set_attr "type" "sse")])
18256
18257 ;; Use xor, but don't show input operands so they aren't live before
18258 ;; this insn.
18259 (define_insn "sse_clrti"
18260 [(set (match_operand:TI 0 "register_operand" "=x")
18261 (unspec:TI [(const_int 0)] 45))]
18262 "TARGET_SSE"
18263 "xorps\t{%0, %0|%0, %0}"
18264 [(set_attr "type" "sse")])
18265
18266
18267 ;; SSE mask-generating compares
18268
18269 (define_insn "maskcmpv4sf3"
18270 [(set (match_operand:V4SI 0 "register_operand" "=x")
18271 (match_operator:V4SI 3 "sse_comparison_operator"
18272 [(match_operand:V4SF 1 "register_operand" "0")
18273 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
18274 "TARGET_SSE"
18275 "cmp%D3ps\t{%2, %0|%0, %2}"
18276 [(set_attr "type" "sse")])
18277
18278 (define_insn "maskncmpv4sf3"
18279 [(set (match_operand:V4SI 0 "register_operand" "=x")
18280 (not:V4SI
18281 (match_operator:V4SI 3 "sse_comparison_operator"
18282 [(match_operand:V4SF 1 "register_operand" "0")
18283 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
18284 "TARGET_SSE"
18285 "cmpn%D3ps\t{%2, %0|%0, %2}"
18286 [(set_attr "type" "sse")])
18287
18288 (define_insn "vmmaskcmpv4sf3"
18289 [(set (match_operand:V4SI 0 "register_operand" "=x")
18290 (vec_merge:V4SI
18291 (match_operator:V4SI 3 "sse_comparison_operator"
18292 [(match_operand:V4SF 1 "register_operand" "0")
18293 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
18294 (match_dup 1)
18295 (const_int 1)))]
18296 "TARGET_SSE"
18297 "cmp%D3ss\t{%2, %0|%0, %2}"
18298 [(set_attr "type" "sse")])
18299
18300 (define_insn "vmmaskncmpv4sf3"
18301 [(set (match_operand:V4SI 0 "register_operand" "=x")
18302 (vec_merge:V4SI
18303 (not:V4SI
18304 (match_operator:V4SI 3 "sse_comparison_operator"
18305 [(match_operand:V4SF 1 "register_operand" "0")
18306 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
18307 (subreg:V4SI (match_dup 1) 0)
18308 (const_int 1)))]
18309 "TARGET_SSE"
18310 "cmp%D3ss\t{%2, %0|%0, %2}"
18311 [(set_attr "type" "sse")])
18312
18313 (define_insn "sse_comi"
18314 [(set (reg:CCFP 17)
18315 (match_operator:CCFP 2 "sse_comparison_operator"
18316 [(vec_select:SF
18317 (match_operand:V4SF 0 "register_operand" "x")
18318 (parallel [(const_int 0)]))
18319 (vec_select:SF
18320 (match_operand:V4SF 1 "register_operand" "x")
18321 (parallel [(const_int 0)]))]))]
18322 "TARGET_SSE"
18323 "comiss\t{%1, %0|%0, %1}"
18324 [(set_attr "type" "sse")])
18325
18326 (define_insn "sse_ucomi"
18327 [(set (reg:CCFPU 17)
18328 (match_operator:CCFPU 2 "sse_comparison_operator"
18329 [(vec_select:SF
18330 (match_operand:V4SF 0 "register_operand" "x")
18331 (parallel [(const_int 0)]))
18332 (vec_select:SF
18333 (match_operand:V4SF 1 "register_operand" "x")
18334 (parallel [(const_int 0)]))]))]
18335 "TARGET_SSE"
18336 "ucomiss\t{%1, %0|%0, %1}"
18337 [(set_attr "type" "sse")])
18338
18339
18340 ;; SSE unpack
18341
18342 (define_insn "sse_unpckhps"
18343 [(set (match_operand:V4SF 0 "register_operand" "=x")
18344 (vec_merge:V4SF
18345 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18346 (parallel [(const_int 2)
18347 (const_int 0)
18348 (const_int 3)
18349 (const_int 1)]))
18350 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18351 (parallel [(const_int 0)
18352 (const_int 2)
18353 (const_int 1)
18354 (const_int 3)]))
18355 (const_int 5)))]
18356 "TARGET_SSE"
18357 "unpckhps\t{%2, %0|%0, %2}"
18358 [(set_attr "type" "sse")])
18359
18360 (define_insn "sse_unpcklps"
18361 [(set (match_operand:V4SF 0 "register_operand" "=x")
18362 (vec_merge:V4SF
18363 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
18364 (parallel [(const_int 0)
18365 (const_int 2)
18366 (const_int 1)
18367 (const_int 3)]))
18368 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
18369 (parallel [(const_int 2)
18370 (const_int 0)
18371 (const_int 3)
18372 (const_int 1)]))
18373 (const_int 5)))]
18374 "TARGET_SSE"
18375 "unpcklps\t{%2, %0|%0, %2}"
18376 [(set_attr "type" "sse")])
18377
18378
18379 ;; SSE min/max
18380
18381 (define_insn "smaxv4sf3"
18382 [(set (match_operand:V4SF 0 "register_operand" "=x")
18383 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18384 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18385 "TARGET_SSE"
18386 "maxps\t{%2, %0|%0, %2}"
18387 [(set_attr "type" "sse")])
18388
18389 (define_insn "vmsmaxv4sf3"
18390 [(set (match_operand:V4SF 0 "register_operand" "=x")
18391 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18392 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18393 (match_dup 1)
18394 (const_int 1)))]
18395 "TARGET_SSE"
18396 "maxss\t{%2, %0|%0, %2}"
18397 [(set_attr "type" "sse")])
18398
18399 (define_insn "sminv4sf3"
18400 [(set (match_operand:V4SF 0 "register_operand" "=x")
18401 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18402 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18403 "TARGET_SSE"
18404 "minps\t{%2, %0|%0, %2}"
18405 [(set_attr "type" "sse")])
18406
18407 (define_insn "vmsminv4sf3"
18408 [(set (match_operand:V4SF 0 "register_operand" "=x")
18409 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18410 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18411 (match_dup 1)
18412 (const_int 1)))]
18413 "TARGET_SSE"
18414 "minss\t{%2, %0|%0, %2}"
18415 [(set_attr "type" "sse")])
18416
18417
18418 ;; SSE <-> integer/MMX conversions
18419
18420 (define_insn "cvtpi2ps"
18421 [(set (match_operand:V4SF 0 "register_operand" "=x")
18422 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18423 (vec_duplicate:V4SF
18424 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
18425 (const_int 12)))]
18426 "TARGET_SSE"
18427 "cvtpi2ps\t{%2, %0|%0, %2}"
18428 [(set_attr "type" "sse")])
18429
18430 (define_insn "cvtps2pi"
18431 [(set (match_operand:V2SI 0 "register_operand" "=y")
18432 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18433 (parallel
18434 [(const_int 0)
18435 (const_int 1)])))]
18436 "TARGET_SSE"
18437 "cvtps2pi\t{%1, %0|%0, %1}"
18438 [(set_attr "type" "sse")])
18439
18440 (define_insn "cvttps2pi"
18441 [(set (match_operand:V2SI 0 "register_operand" "=y")
18442 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18443 (parallel
18444 [(const_int 0)
18445 (const_int 1)])))]
18446 "TARGET_SSE"
18447 "cvttps2pi\t{%1, %0|%0, %1}"
18448 [(set_attr "type" "sse")])
18449
18450 (define_insn "cvtsi2ss"
18451 [(set (match_operand:V4SF 0 "register_operand" "=x")
18452 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18453 (vec_duplicate:V4SF
18454 (float:SF (match_operand:SI 2 "register_operand" "rm")))
18455 (const_int 15)))]
18456 "TARGET_SSE"
18457 "cvtsi2ss\t{%2, %0|%0, %2}"
18458 [(set_attr "type" "sse")])
18459
18460 (define_insn "cvtss2si"
18461 [(set (match_operand:SI 0 "register_operand" "=r")
18462 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18463 (parallel [(const_int 0)])))]
18464 "TARGET_SSE"
18465 "cvtss2si\t{%1, %0|%0, %1}"
18466 [(set_attr "type" "sse")])
18467
18468 (define_insn "cvttss2si"
18469 [(set (match_operand:SI 0 "register_operand" "=r")
18470 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18471 (parallel [(const_int 0)])))]
18472 "TARGET_SSE"
18473 "cvttss2si\t{%1, %0|%0, %1}"
18474 [(set_attr "type" "sse")])
18475
18476
18477 ;; MMX insns
18478
18479 ;; MMX arithmetic
18480
18481 (define_insn "addv8qi3"
18482 [(set (match_operand:V8QI 0 "register_operand" "=y")
18483 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18484 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18485 "TARGET_MMX"
18486 "paddb\t{%2, %0|%0, %2}"
18487 [(set_attr "type" "mmx")])
18488
18489 (define_insn "addv4hi3"
18490 [(set (match_operand:V4HI 0 "register_operand" "=y")
18491 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18492 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18493 "TARGET_MMX"
18494 "paddw\t{%2, %0|%0, %2}"
18495 [(set_attr "type" "mmx")])
18496
18497 (define_insn "addv2si3"
18498 [(set (match_operand:V2SI 0 "register_operand" "=y")
18499 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18500 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18501 "TARGET_MMX"
18502 "paddd\t{%2, %0|%0, %2}"
18503 [(set_attr "type" "mmx")])
18504
18505 (define_insn "ssaddv8qi3"
18506 [(set (match_operand:V8QI 0 "register_operand" "=y")
18507 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18508 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18509 "TARGET_MMX"
18510 "paddsb\t{%2, %0|%0, %2}"
18511 [(set_attr "type" "mmx")])
18512
18513 (define_insn "ssaddv4hi3"
18514 [(set (match_operand:V4HI 0 "register_operand" "=y")
18515 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18516 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18517 "TARGET_MMX"
18518 "paddsw\t{%2, %0|%0, %2}"
18519 [(set_attr "type" "mmx")])
18520
18521 (define_insn "usaddv8qi3"
18522 [(set (match_operand:V8QI 0 "register_operand" "=y")
18523 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18524 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18525 "TARGET_MMX"
18526 "paddusb\t{%2, %0|%0, %2}"
18527 [(set_attr "type" "mmx")])
18528
18529 (define_insn "usaddv4hi3"
18530 [(set (match_operand:V4HI 0 "register_operand" "=y")
18531 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18532 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18533 "TARGET_MMX"
18534 "paddusw\t{%2, %0|%0, %2}"
18535 [(set_attr "type" "mmx")])
18536
18537 (define_insn "subv8qi3"
18538 [(set (match_operand:V8QI 0 "register_operand" "=y")
18539 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18540 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18541 "TARGET_MMX"
18542 "psubb\t{%2, %0|%0, %2}"
18543 [(set_attr "type" "mmx")])
18544
18545 (define_insn "subv4hi3"
18546 [(set (match_operand:V4HI 0 "register_operand" "=y")
18547 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18548 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18549 "TARGET_MMX"
18550 "psubw\t{%2, %0|%0, %2}"
18551 [(set_attr "type" "mmx")])
18552
18553 (define_insn "subv2si3"
18554 [(set (match_operand:V2SI 0 "register_operand" "=y")
18555 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18556 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18557 "TARGET_MMX"
18558 "psubd\t{%2, %0|%0, %2}"
18559 [(set_attr "type" "mmx")])
18560
18561 (define_insn "sssubv8qi3"
18562 [(set (match_operand:V8QI 0 "register_operand" "=y")
18563 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18564 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18565 "TARGET_MMX"
18566 "psubsb\t{%2, %0|%0, %2}"
18567 [(set_attr "type" "mmx")])
18568
18569 (define_insn "sssubv4hi3"
18570 [(set (match_operand:V4HI 0 "register_operand" "=y")
18571 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18572 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18573 "TARGET_MMX"
18574 "psubsw\t{%2, %0|%0, %2}"
18575 [(set_attr "type" "mmx")])
18576
18577 (define_insn "ussubv8qi3"
18578 [(set (match_operand:V8QI 0 "register_operand" "=y")
18579 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18580 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18581 "TARGET_MMX"
18582 "psubusb\t{%2, %0|%0, %2}"
18583 [(set_attr "type" "mmx")])
18584
18585 (define_insn "ussubv4hi3"
18586 [(set (match_operand:V4HI 0 "register_operand" "=y")
18587 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18588 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18589 "TARGET_MMX"
18590 "psubusw\t{%2, %0|%0, %2}"
18591 [(set_attr "type" "mmx")])
18592
18593 (define_insn "mulv4hi3"
18594 [(set (match_operand:V4HI 0 "register_operand" "=y")
18595 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18596 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18597 "TARGET_MMX"
18598 "pmullw\t{%2, %0|%0, %2}"
18599 [(set_attr "type" "mmx")])
18600
18601 (define_insn "smulv4hi3_highpart"
18602 [(set (match_operand:V4HI 0 "register_operand" "=y")
18603 (truncate:V4HI
18604 (lshiftrt:V4SI
18605 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18606 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18607 (const_int 16))))]
18608 "TARGET_MMX"
18609 "pmulhw\t{%2, %0|%0, %2}"
18610 [(set_attr "type" "mmx")])
18611
18612 (define_insn "umulv4hi3_highpart"
18613 [(set (match_operand:V4HI 0 "register_operand" "=y")
18614 (truncate:V4HI
18615 (lshiftrt:V4SI
18616 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18617 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18618 (const_int 16))))]
18619 "TARGET_SSE || TARGET_3DNOW_A"
18620 "pmulhuw\t{%2, %0|%0, %2}"
18621 [(set_attr "type" "mmx")])
18622
18623 (define_insn "mmx_pmaddwd"
18624 [(set (match_operand:V2SI 0 "register_operand" "=y")
18625 (plus:V2SI
18626 (mult:V2SI
18627 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18628 (parallel [(const_int 0)
18629 (const_int 2)])))
18630 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18631 (parallel [(const_int 0)
18632 (const_int 2)]))))
18633 (mult:V2SI
18634 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18635 (parallel [(const_int 1)
18636 (const_int 3)])))
18637 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18638 (parallel [(const_int 1)
18639 (const_int 3)]))))))]
18640 "TARGET_MMX"
18641 "pmaddwd\t{%2, %0|%0, %2}"
18642 [(set_attr "type" "mmx")])
18643
18644
18645 ;; MMX logical operations
18646 ;; Note we don't want to declare these as regular iordi3 insns to prevent
18647 ;; normal code that also wants to use the FPU from getting broken.
18648 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
18649 (define_insn "mmx_iordi3"
18650 [(set (match_operand:DI 0 "register_operand" "=y")
18651 (unspec:DI
18652 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18653 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18654 "TARGET_MMX"
18655 "por\t{%2, %0|%0, %2}"
18656 [(set_attr "type" "mmx")])
18657
18658 (define_insn "mmx_xordi3"
18659 [(set (match_operand:DI 0 "register_operand" "=y")
18660 (unspec:DI
18661 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18662 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18663 "TARGET_MMX"
18664 "pxor\t{%2, %0|%0, %2}"
18665 [(set_attr "type" "mmx")])
18666
18667 ;; Same as pxor, but don't show input operands so that we don't think
18668 ;; they are live.
18669 (define_insn "mmx_clrdi"
18670 [(set (match_operand:DI 0 "register_operand" "=y")
18671 (unspec:DI [(const_int 0)] 45))]
18672 "TARGET_MMX"
18673 "pxor\t{%0, %0|%0, %0}"
18674 [(set_attr "type" "mmx")])
18675
18676 (define_insn "mmx_anddi3"
18677 [(set (match_operand:DI 0 "register_operand" "=y")
18678 (unspec:DI
18679 [(and:DI (match_operand:DI 1 "register_operand" "0")
18680 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18681 "TARGET_MMX"
18682 "pand\t{%2, %0|%0, %2}"
18683 [(set_attr "type" "mmx")])
18684
18685 (define_insn "mmx_nanddi3"
18686 [(set (match_operand:DI 0 "register_operand" "=y")
18687 (unspec:DI
18688 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18689 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18690 "TARGET_MMX"
18691 "pandn\t{%2, %0|%0, %2}"
18692 [(set_attr "type" "mmx")])
18693
18694
18695 ;; MMX unsigned averages/sum of absolute differences
18696
18697 (define_insn "mmx_uavgv8qi3"
18698 [(set (match_operand:V8QI 0 "register_operand" "=y")
18699 (ashiftrt:V8QI
18700 (plus:V8QI (plus:V8QI
18701 (match_operand:V8QI 1 "register_operand" "0")
18702 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18703 (vec_const:V8QI (parallel [(const_int 1)
18704 (const_int 1)
18705 (const_int 1)
18706 (const_int 1)
18707 (const_int 1)
18708 (const_int 1)
18709 (const_int 1)
18710 (const_int 1)])))
18711 (const_int 1)))]
18712 "TARGET_SSE || TARGET_3DNOW_A"
18713 "pavgb\t{%2, %0|%0, %2}"
18714 [(set_attr "type" "sse")])
18715
18716 (define_insn "mmx_uavgv4hi3"
18717 [(set (match_operand:V4HI 0 "register_operand" "=y")
18718 (ashiftrt:V4HI
18719 (plus:V4HI (plus:V4HI
18720 (match_operand:V4HI 1 "register_operand" "0")
18721 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18722 (vec_const:V4HI (parallel [(const_int 1)
18723 (const_int 1)
18724 (const_int 1)
18725 (const_int 1)])))
18726 (const_int 1)))]
18727 "TARGET_SSE || TARGET_3DNOW_A"
18728 "pavgw\t{%2, %0|%0, %2}"
18729 [(set_attr "type" "sse")])
18730
18731 (define_insn "mmx_psadbw"
18732 [(set (match_operand:V8QI 0 "register_operand" "=y")
18733 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18734 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
18735 "TARGET_SSE || TARGET_3DNOW_A"
18736 "psadbw\t{%2, %0|%0, %2}"
18737 [(set_attr "type" "sse")])
18738
18739
18740 ;; MMX insert/extract/shuffle
18741
18742 (define_insn "mmx_pinsrw"
18743 [(set (match_operand:V4HI 0 "register_operand" "=y")
18744 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18745 (vec_duplicate:V4HI
18746 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18747 (match_operand:SI 3 "immediate_operand" "i")))]
18748 "TARGET_SSE || TARGET_3DNOW_A"
18749 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
18750 [(set_attr "type" "sse")])
18751
18752 (define_insn "mmx_pextrw"
18753 [(set (match_operand:SI 0 "register_operand" "=r")
18754 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18755 (parallel
18756 [(match_operand:SI 2 "immediate_operand" "i")]))))]
18757 "TARGET_SSE || TARGET_3DNOW_A"
18758 "pextrw\t{%2, %1, %0|%0, %1, %2}"
18759 [(set_attr "type" "sse")])
18760
18761 (define_insn "mmx_pshufw"
18762 [(set (match_operand:V4HI 0 "register_operand" "=y")
18763 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18764 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18765 (match_operand:SI 3 "immediate_operand" "i")] 41))]
18766 "TARGET_SSE || TARGET_3DNOW_A"
18767 "pshufw\t{%3, %2, %0|%0, %2, %3}"
18768 [(set_attr "type" "sse")])
18769
18770
18771 ;; MMX mask-generating comparisons
18772
18773 (define_insn "eqv8qi3"
18774 [(set (match_operand:V8QI 0 "register_operand" "=y")
18775 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18776 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18777 "TARGET_MMX"
18778 "pcmpeqb\t{%2, %0|%0, %2}"
18779 [(set_attr "type" "mmx")])
18780
18781 (define_insn "eqv4hi3"
18782 [(set (match_operand:V4HI 0 "register_operand" "=y")
18783 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18784 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18785 "TARGET_MMX"
18786 "pcmpeqw\t{%2, %0|%0, %2}"
18787 [(set_attr "type" "mmx")])
18788
18789 (define_insn "eqv2si3"
18790 [(set (match_operand:V2SI 0 "register_operand" "=y")
18791 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18792 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18793 "TARGET_MMX"
18794 "pcmpeqd\t{%2, %0|%0, %2}"
18795 [(set_attr "type" "mmx")])
18796
18797 (define_insn "gtv8qi3"
18798 [(set (match_operand:V8QI 0 "register_operand" "=y")
18799 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18800 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18801 "TARGET_MMX"
18802 "pcmpgtb\t{%2, %0|%0, %2}"
18803 [(set_attr "type" "mmx")])
18804
18805 (define_insn "gtv4hi3"
18806 [(set (match_operand:V4HI 0 "register_operand" "=y")
18807 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18808 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18809 "TARGET_MMX"
18810 "pcmpgtw\t{%2, %0|%0, %2}"
18811 [(set_attr "type" "mmx")])
18812
18813 (define_insn "gtv2si3"
18814 [(set (match_operand:V2SI 0 "register_operand" "=y")
18815 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18816 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18817 "TARGET_MMX"
18818 "pcmpgtd\t{%2, %0|%0, %2}"
18819 [(set_attr "type" "mmx")])
18820
18821
18822 ;; MMX max/min insns
18823
18824 (define_insn "umaxv8qi3"
18825 [(set (match_operand:V8QI 0 "register_operand" "=y")
18826 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18827 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18828 "TARGET_SSE || TARGET_3DNOW_A"
18829 "pmaxub\t{%2, %0|%0, %2}"
18830 [(set_attr "type" "sse")])
18831
18832 (define_insn "smaxv4hi3"
18833 [(set (match_operand:V4HI 0 "register_operand" "=y")
18834 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18835 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18836 "TARGET_SSE || TARGET_3DNOW_A"
18837 "pmaxsw\t{%2, %0|%0, %2}"
18838 [(set_attr "type" "sse")])
18839
18840 (define_insn "uminv8qi3"
18841 [(set (match_operand:V8QI 0 "register_operand" "=y")
18842 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18843 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18844 "TARGET_SSE || TARGET_3DNOW_A"
18845 "pminub\t{%2, %0|%0, %2}"
18846 [(set_attr "type" "sse")])
18847
18848 (define_insn "sminv4hi3"
18849 [(set (match_operand:V4HI 0 "register_operand" "=y")
18850 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18851 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18852 "TARGET_SSE || TARGET_3DNOW_A"
18853 "pminsw\t{%2, %0|%0, %2}"
18854 [(set_attr "type" "sse")])
18855
18856
18857 ;; MMX shifts
18858
18859 (define_insn "ashrv4hi3"
18860 [(set (match_operand:V4HI 0 "register_operand" "=y")
18861 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18862 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18863 "TARGET_MMX"
18864 "psraw\t{%2, %0|%0, %2}"
18865 [(set_attr "type" "mmx")])
18866
18867 (define_insn "ashrv2si3"
18868 [(set (match_operand:V2SI 0 "register_operand" "=y")
18869 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18870 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18871 "TARGET_MMX"
18872 "psrad\t{%2, %0|%0, %2}"
18873 [(set_attr "type" "mmx")])
18874
18875 (define_insn "lshrv4hi3"
18876 [(set (match_operand:V4HI 0 "register_operand" "=y")
18877 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18878 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18879 "TARGET_MMX"
18880 "psrlw\t{%2, %0|%0, %2}"
18881 [(set_attr "type" "mmx")])
18882
18883 (define_insn "lshrv2si3"
18884 [(set (match_operand:V2SI 0 "register_operand" "=y")
18885 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18886 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18887 "TARGET_MMX"
18888 "psrld\t{%2, %0|%0, %2}"
18889 [(set_attr "type" "mmx")])
18890
18891 ;; See logical MMX insns.
18892 (define_insn "mmx_lshrdi3"
18893 [(set (match_operand:DI 0 "register_operand" "=y")
18894 (unspec:DI
18895 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
18896 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
18897 "TARGET_MMX"
18898 "psrlq\t{%2, %0|%0, %2}"
18899 [(set_attr "type" "mmx")])
18900
18901 (define_insn "ashlv4hi3"
18902 [(set (match_operand:V4HI 0 "register_operand" "=y")
18903 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
18904 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18905 "TARGET_MMX"
18906 "psllw\t{%2, %0|%0, %2}"
18907 [(set_attr "type" "mmx")])
18908
18909 (define_insn "ashlv2si3"
18910 [(set (match_operand:V2SI 0 "register_operand" "=y")
18911 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
18912 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18913 "TARGET_MMX"
18914 "pslld\t{%2, %0|%0, %2}"
18915 [(set_attr "type" "mmx")])
18916
18917 ;; See logical MMX insns.
18918 (define_insn "mmx_ashldi3"
18919 [(set (match_operand:DI 0 "register_operand" "=y")
18920 (unspec:DI
18921 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
18922 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
18923 "TARGET_MMX"
18924 "psllq\t{%2, %0|%0, %2}"
18925 [(set_attr "type" "mmx")])
18926
18927
18928 ;; MMX pack/unpack insns.
18929
18930 (define_insn "mmx_packsswb"
18931 [(set (match_operand:V8QI 0 "register_operand" "=y")
18932 (vec_concat:V8QI
18933 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18934 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18935 "TARGET_MMX"
18936 "packsswb\t{%2, %0|%0, %2}"
18937 [(set_attr "type" "mmx")])
18938
18939 (define_insn "mmx_packssdw"
18940 [(set (match_operand:V4HI 0 "register_operand" "=y")
18941 (vec_concat:V4HI
18942 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
18943 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
18944 "TARGET_MMX"
18945 "packssdw\t{%2, %0|%0, %2}"
18946 [(set_attr "type" "mmx")])
18947
18948 (define_insn "mmx_packuswb"
18949 [(set (match_operand:V8QI 0 "register_operand" "=y")
18950 (vec_concat:V8QI
18951 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18952 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18953 "TARGET_MMX"
18954 "packuswb\t{%2, %0|%0, %2}"
18955 [(set_attr "type" "mmx")])
18956
18957 (define_insn "mmx_punpckhbw"
18958 [(set (match_operand:V8QI 0 "register_operand" "=y")
18959 (vec_merge:V8QI
18960 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
18961 (parallel [(const_int 4)
18962 (const_int 0)
18963 (const_int 5)
18964 (const_int 1)
18965 (const_int 6)
18966 (const_int 2)
18967 (const_int 7)
18968 (const_int 3)]))
18969 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
18970 (parallel [(const_int 0)
18971 (const_int 4)
18972 (const_int 1)
18973 (const_int 5)
18974 (const_int 2)
18975 (const_int 6)
18976 (const_int 3)
18977 (const_int 7)]))
18978 (const_int 85)))]
18979 "TARGET_MMX"
18980 "punpckhbw\t{%2, %0|%0, %2}"
18981 [(set_attr "type" "mmx")])
18982
18983 (define_insn "mmx_punpckhwd"
18984 [(set (match_operand:V4HI 0 "register_operand" "=y")
18985 (vec_merge:V4HI
18986 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
18987 (parallel [(const_int 0)
18988 (const_int 2)
18989 (const_int 1)
18990 (const_int 3)]))
18991 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
18992 (parallel [(const_int 2)
18993 (const_int 0)
18994 (const_int 3)
18995 (const_int 1)]))
18996 (const_int 5)))]
18997 "TARGET_MMX"
18998 "punpckhwd\t{%2, %0|%0, %2}"
18999 [(set_attr "type" "mmx")])
19000
19001 (define_insn "mmx_punpckhdq"
19002 [(set (match_operand:V2SI 0 "register_operand" "=y")
19003 (vec_merge:V2SI
19004 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19005 (parallel [(const_int 0)
19006 (const_int 1)]))
19007 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19008 (parallel [(const_int 1)
19009 (const_int 0)]))
19010 (const_int 1)))]
19011 "TARGET_MMX"
19012 "punpckhdq\t{%2, %0|%0, %2}"
19013 [(set_attr "type" "mmx")])
19014
19015 (define_insn "mmx_punpcklbw"
19016 [(set (match_operand:V8QI 0 "register_operand" "=y")
19017 (vec_merge:V8QI
19018 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
19019 (parallel [(const_int 0)
19020 (const_int 4)
19021 (const_int 1)
19022 (const_int 5)
19023 (const_int 2)
19024 (const_int 6)
19025 (const_int 3)
19026 (const_int 7)]))
19027 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
19028 (parallel [(const_int 4)
19029 (const_int 0)
19030 (const_int 5)
19031 (const_int 1)
19032 (const_int 6)
19033 (const_int 2)
19034 (const_int 7)
19035 (const_int 3)]))
19036 (const_int 85)))]
19037 "TARGET_MMX"
19038 "punpcklbw\t{%2, %0|%0, %2}"
19039 [(set_attr "type" "mmx")])
19040
19041 (define_insn "mmx_punpcklwd"
19042 [(set (match_operand:V4HI 0 "register_operand" "=y")
19043 (vec_merge:V4HI
19044 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
19045 (parallel [(const_int 2)
19046 (const_int 0)
19047 (const_int 3)
19048 (const_int 1)]))
19049 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
19050 (parallel [(const_int 0)
19051 (const_int 2)
19052 (const_int 1)
19053 (const_int 3)]))
19054 (const_int 5)))]
19055 "TARGET_MMX"
19056 "punpcklwd\t{%2, %0|%0, %2}"
19057 [(set_attr "type" "mmx")])
19058
19059 (define_insn "mmx_punpckldq"
19060 [(set (match_operand:V2SI 0 "register_operand" "=y")
19061 (vec_merge:V2SI
19062 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
19063 (parallel [(const_int 1)
19064 (const_int 0)]))
19065 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
19066 (parallel [(const_int 0)
19067 (const_int 1)]))
19068 (const_int 1)))]
19069 "TARGET_MMX"
19070 "punpckldq\t{%2, %0|%0, %2}"
19071 [(set_attr "type" "mmx")])
19072
19073
19074 ;; Miscellaneous stuff
19075
19076 (define_insn "emms"
19077 [(unspec_volatile [(const_int 0)] 31)
19078 (clobber (reg:XF 8))
19079 (clobber (reg:XF 9))
19080 (clobber (reg:XF 10))
19081 (clobber (reg:XF 11))
19082 (clobber (reg:XF 12))
19083 (clobber (reg:XF 13))
19084 (clobber (reg:XF 14))
19085 (clobber (reg:XF 15))
19086 (clobber (reg:DI 29))
19087 (clobber (reg:DI 30))
19088 (clobber (reg:DI 31))
19089 (clobber (reg:DI 32))
19090 (clobber (reg:DI 33))
19091 (clobber (reg:DI 34))
19092 (clobber (reg:DI 35))
19093 (clobber (reg:DI 36))]
19094 "TARGET_MMX"
19095 "emms"
19096 [(set_attr "type" "mmx")
19097 (set_attr "memory" "unknown")])
19098
19099 (define_insn "ldmxcsr"
19100 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
19101 "TARGET_MMX"
19102 "ldmxcsr\t%0"
19103 [(set_attr "type" "mmx")])
19104
19105 (define_insn "stmxcsr"
19106 [(set (match_operand:SI 0 "memory_operand" "=m")
19107 (unspec_volatile:SI [(const_int 0)] 40))]
19108 "TARGET_MMX"
19109 "stmxcsr\t%0"
19110 [(set_attr "type" "mmx")])
19111
19112 (define_expand "sfence"
19113 [(set (match_dup 0)
19114 (unspec:BLK [(match_dup 0)] 44))]
19115 "TARGET_SSE || TARGET_3DNOW_A"
19116 {
19117 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19118 MEM_VOLATILE_P (operands[0]) = 1;
19119 })
19120
19121 (define_insn "*sfence_insn"
19122 [(set (match_operand:BLK 0 "" "")
19123 (unspec:BLK [(match_dup 0)] 44))]
19124 "TARGET_SSE || TARGET_3DNOW_A"
19125 "sfence"
19126 [(set_attr "type" "sse")
19127 (set_attr "memory" "unknown")])
19128
19129 (define_insn "prefetch"
19130 [(unspec [(match_operand:SI 0 "address_operand" "p")
19131 (match_operand:SI 1 "immediate_operand" "n")] 35)]
19132 "TARGET_SSE || TARGET_3DNOW_A"
19133 {
19134 switch (INTVAL (operands[1]))
19135 {
19136 case 0:
19137 return "prefetchnta\t%a0";
19138 case 1:
19139 return "prefetcht0\t%a0";
19140 case 2:
19141 return "prefetcht1\t%a0";
19142 case 3:
19143 return "prefetcht2\t%a0";
19144 default:
19145 abort ();
19146 }
19147 }
19148 [(set_attr "type" "sse")])
19149
19150 (define_expand "sse_prologue_save"
19151 [(parallel [(set (match_operand:BLK 0 "" "")
19152 (unspec:BLK [(reg:DI 21)
19153 (reg:DI 22)
19154 (reg:DI 23)
19155 (reg:DI 24)
19156 (reg:DI 25)
19157 (reg:DI 26)
19158 (reg:DI 27)
19159 (reg:DI 28)] 13))
19160 (use (match_operand:DI 1 "register_operand" ""))
19161 (use (match_operand:DI 2 "immediate_operand" ""))
19162 (use (label_ref:DI (match_operand 3 "" "")))])]
19163 "TARGET_64BIT"
19164 "")
19165
19166 (define_insn "*sse_prologue_save_insn"
19167 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19168 (match_operand:DI 4 "const_int_operand" "n")))
19169 (unspec:BLK [(reg:DI 21)
19170 (reg:DI 22)
19171 (reg:DI 23)
19172 (reg:DI 24)
19173 (reg:DI 25)
19174 (reg:DI 26)
19175 (reg:DI 27)
19176 (reg:DI 28)] 13))
19177 (use (match_operand:DI 1 "register_operand" "r"))
19178 (use (match_operand:DI 2 "const_int_operand" "i"))
19179 (use (label_ref:DI (match_operand 3 "" "X")))]
19180 "TARGET_64BIT
19181 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19182 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19183 "*
19184 {
19185 int i;
19186 operands[0] = gen_rtx_MEM (Pmode,
19187 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19188 output_asm_insn (\"jmp\\t%A1\", operands);
19189 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19190 {
19191 operands[4] = adjust_address (operands[0], DImode, i*16);
19192 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19193 PUT_MODE (operands[4], TImode);
19194 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19195 output_asm_insn (\"rex\", operands);
19196 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19197 }
19198 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
19199 CODE_LABEL_NUMBER (operands[3]));
19200 RET;
19201 }
19202 "
19203 [(set_attr "type" "other")
19204 (set_attr "length_immediate" "0")
19205 (set_attr "length_address" "0")
19206 (set_attr "length" "135")
19207 (set_attr "memory" "store")
19208 (set_attr "modrm" "0")
19209 (set_attr "mode" "DI")])
19210
19211 ;; 3Dnow! instructions
19212
19213 (define_insn "addv2sf3"
19214 [(set (match_operand:V2SF 0 "register_operand" "=y")
19215 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19216 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19217 "TARGET_3DNOW"
19218 "pfadd\\t{%2, %0|%0, %2}"
19219 [(set_attr "type" "mmx")])
19220
19221 (define_insn "subv2sf3"
19222 [(set (match_operand:V2SF 0 "register_operand" "=y")
19223 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
19224 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19225 "TARGET_3DNOW"
19226 "pfsub\\t{%2, %0|%0, %2}"
19227 [(set_attr "type" "mmx")])
19228
19229 (define_insn "subrv2sf3"
19230 [(set (match_operand:V2SF 0 "register_operand" "=y")
19231 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
19232 (match_operand:V2SF 1 "register_operand" "0")))]
19233 "TARGET_3DNOW"
19234 "pfsubr\\t{%2, %0|%0, %2}"
19235 [(set_attr "type" "mmx")])
19236
19237 (define_insn "gtv2sf3"
19238 [(set (match_operand:V2SI 0 "register_operand" "=y")
19239 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
19240 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19241 "TARGET_3DNOW"
19242 "pfcmpgt\\t{%2, %0|%0, %2}"
19243 [(set_attr "type" "mmx")])
19244
19245 (define_insn "gev2sf3"
19246 [(set (match_operand:V2SI 0 "register_operand" "=y")
19247 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
19248 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19249 "TARGET_3DNOW"
19250 "pfcmpge\\t{%2, %0|%0, %2}"
19251 [(set_attr "type" "mmx")])
19252
19253 (define_insn "eqv2sf3"
19254 [(set (match_operand:V2SI 0 "register_operand" "=y")
19255 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
19256 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19257 "TARGET_3DNOW"
19258 "pfcmpeq\\t{%2, %0|%0, %2}"
19259 [(set_attr "type" "mmx")])
19260
19261 (define_insn "pfmaxv2sf3"
19262 [(set (match_operand:V2SF 0 "register_operand" "=y")
19263 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
19264 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19265 "TARGET_3DNOW"
19266 "pfmax\\t{%2, %0|%0, %2}"
19267 [(set_attr "type" "mmx")])
19268
19269 (define_insn "pfminv2sf3"
19270 [(set (match_operand:V2SF 0 "register_operand" "=y")
19271 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
19272 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19273 "TARGET_3DNOW"
19274 "pfmin\\t{%2, %0|%0, %2}"
19275 [(set_attr "type" "mmx")])
19276
19277 (define_insn "mulv2sf3"
19278 [(set (match_operand:V2SF 0 "register_operand" "=y")
19279 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
19280 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
19281 "TARGET_3DNOW"
19282 "pfmul\\t{%2, %0|%0, %2}"
19283 [(set_attr "type" "mmx")])
19284
19285 (define_insn "femms"
19286 [(unspec_volatile [(const_int 0)] 46)
19287 (clobber (reg:XF 8))
19288 (clobber (reg:XF 9))
19289 (clobber (reg:XF 10))
19290 (clobber (reg:XF 11))
19291 (clobber (reg:XF 12))
19292 (clobber (reg:XF 13))
19293 (clobber (reg:XF 14))
19294 (clobber (reg:XF 15))
19295 (clobber (reg:DI 29))
19296 (clobber (reg:DI 30))
19297 (clobber (reg:DI 31))
19298 (clobber (reg:DI 32))
19299 (clobber (reg:DI 33))
19300 (clobber (reg:DI 34))
19301 (clobber (reg:DI 35))
19302 (clobber (reg:DI 36))]
19303 "TARGET_3DNOW"
19304 "femms"
19305 [(set_attr "type" "mmx")])
19306
19307 (define_insn "prefetch_3dnow"
19308 [(unspec [(match_operand:SI 0 "address_operand" "p")] 47)]
19309 "TARGET_3DNOW"
19310 "prefetch\\t%a0"
19311 [(set_attr "type" "mmx")])
19312
19313 (define_insn "prefetchw"
19314 [(unspec [(match_operand:SI 0 "address_operand" "p")] 48)]
19315 "TARGET_3DNOW"
19316 "prefetchw\\t%a0"
19317 [(set_attr "type" "mmx")])
19318
19319 (define_insn "pf2id"
19320 [(set (match_operand:V2SI 0 "register_operand" "=y")
19321 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
19322 "TARGET_3DNOW"
19323 "pf2id\\t{%1, %0|%0, %1}"
19324 [(set_attr "type" "mmx")])
19325
19326 (define_insn "pf2iw"
19327 [(set (match_operand:V2SI 0 "register_operand" "=y")
19328 (sign_extend:V2SI
19329 (ss_truncate:V2HI
19330 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
19331 "TARGET_3DNOW_A"
19332 "pf2iw\\t{%1, %0|%0, %1}"
19333 [(set_attr "type" "mmx")])
19334
19335 (define_insn "pfacc"
19336 [(set (match_operand:V2SF 0 "register_operand" "=y")
19337 (vec_concat:V2SF
19338 (plus:SF
19339 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19340 (parallel [(const_int 0)]))
19341 (vec_select:SF (match_dup 1)
19342 (parallel [(const_int 1)])))
19343 (plus:SF
19344 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19345 (parallel [(const_int 0)]))
19346 (vec_select:SF (match_dup 2)
19347 (parallel [(const_int 1)])))))]
19348 "TARGET_3DNOW"
19349 "pfacc\\t{%2, %0|%0, %2}"
19350 [(set_attr "type" "mmx")])
19351
19352 (define_insn "pfnacc"
19353 [(set (match_operand:V2SF 0 "register_operand" "=y")
19354 (vec_concat:V2SF
19355 (minus:SF
19356 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19357 (parallel [(const_int 0)]))
19358 (vec_select:SF (match_dup 1)
19359 (parallel [(const_int 1)])))
19360 (minus:SF
19361 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19362 (parallel [(const_int 0)]))
19363 (vec_select:SF (match_dup 2)
19364 (parallel [(const_int 1)])))))]
19365 "TARGET_3DNOW_A"
19366 "pfnacc\\t{%2, %0|%0, %2}"
19367 [(set_attr "type" "mmx")])
19368
19369 (define_insn "pfpnacc"
19370 [(set (match_operand:V2SF 0 "register_operand" "=y")
19371 (vec_concat:V2SF
19372 (minus:SF
19373 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
19374 (parallel [(const_int 0)]))
19375 (vec_select:SF (match_dup 1)
19376 (parallel [(const_int 1)])))
19377 (plus:SF
19378 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
19379 (parallel [(const_int 0)]))
19380 (vec_select:SF (match_dup 2)
19381 (parallel [(const_int 1)])))))]
19382 "TARGET_3DNOW_A"
19383 "pfpnacc\\t{%2, %0|%0, %2}"
19384 [(set_attr "type" "mmx")])
19385
19386 (define_insn "pi2fw"
19387 [(set (match_operand:V2SF 0 "register_operand" "=y")
19388 (float:V2SF
19389 (vec_concat:V2SI
19390 (sign_extend:SI
19391 (truncate:HI
19392 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19393 (parallel [(const_int 0)]))))
19394 (sign_extend:SI
19395 (truncate:HI
19396 (vec_select:SI (match_dup 1)
19397 (parallel [(const_int 1)])))))))]
19398 "TARGET_3DNOW_A"
19399 "pi2fw\\t{%1, %0|%0, %1}"
19400 [(set_attr "type" "mmx")])
19401
19402 (define_insn "floatv2si2"
19403 [(set (match_operand:V2SF 0 "register_operand" "=y")
19404 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
19405 "TARGET_3DNOW"
19406 "pi2fd\\t{%1, %0|%0, %1}"
19407 [(set_attr "type" "mmx")])
19408
19409 ;; This insn is identical to pavgb in operation, but the opcode is
19410 ;; different. To avoid accidentally matching pavgb, use an unspec.
19411
19412 (define_insn "pavgusb"
19413 [(set (match_operand:V8QI 0 "register_operand" "=y")
19414 (unspec:V8QI
19415 [(match_operand:V8QI 1 "register_operand" "0")
19416 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
19417 "TARGET_3DNOW"
19418 "pavgusb\\t{%2, %0|%0, %2}"
19419 [(set_attr "type" "mmx")])
19420
19421 ;; 3DNow reciprical and sqrt
19422
19423 (define_insn "pfrcpv2sf2"
19424 [(set (match_operand:V2SF 0 "register_operand" "=y")
19425 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
19426 "TARGET_3DNOW"
19427 "pfrcp\\t{%1, %0|%0, %1}"
19428 [(set_attr "type" "mmx")])
19429
19430 (define_insn "pfrcpit1v2sf3"
19431 [(set (match_operand:V2SF 0 "register_operand" "=y")
19432 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19433 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
19434 "TARGET_3DNOW"
19435 "pfrcpit1\\t{%2, %0|%0, %2}"
19436 [(set_attr "type" "mmx")])
19437
19438 (define_insn "pfrcpit2v2sf3"
19439 [(set (match_operand:V2SF 0 "register_operand" "=y")
19440 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19441 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
19442 "TARGET_3DNOW"
19443 "pfrcpit2\\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "mmx")])
19445
19446 (define_insn "pfrsqrtv2sf2"
19447 [(set (match_operand:V2SF 0 "register_operand" "=y")
19448 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
19449 "TARGET_3DNOW"
19450 "pfrsqrt\\t{%1, %0|%0, %1}"
19451 [(set_attr "type" "mmx")])
19452
19453 (define_insn "pfrsqit1v2sf3"
19454 [(set (match_operand:V2SF 0 "register_operand" "=y")
19455 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
19456 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
19457 "TARGET_3DNOW"
19458 "pfrsqit1\\t{%2, %0|%0, %2}"
19459 [(set_attr "type" "mmx")])
19460
19461 (define_insn "pmulhrwv4hi3"
19462 [(set (match_operand:V4HI 0 "register_operand" "=y")
19463 (truncate:V4HI
19464 (lshiftrt:V4SI
19465 (plus:V4SI
19466 (mult:V4SI
19467 (sign_extend:V4SI
19468 (match_operand:V4HI 1 "register_operand" "0"))
19469 (sign_extend:V4SI
19470 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
19471 (vec_const:V4SI
19472 (parallel [(const_int 0x8000)
19473 (const_int 0x8000)
19474 (const_int 0x8000)
19475 (const_int 0x8000)])))
19476 (const_int 16))))]
19477 "TARGET_3DNOW"
19478 "pmulhrw\\t{%2, %0|%0, %2}"
19479 [(set_attr "type" "mmx")])
19480
19481 (define_insn "pswapdv2si2"
19482 [(set (match_operand:V2SI 0 "register_operand" "=y")
19483 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
19484 (parallel [(const_int 1) (const_int 0)])))]
19485 "TARGET_3DNOW_A"
19486 "pswapd\\t{%1, %0|%0, %1}"
19487 [(set_attr "type" "mmx")])
19488
19489 (define_insn "pswapdv2sf2"
19490 [(set (match_operand:V2SF 0 "register_operand" "=y")
19491 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
19492 (parallel [(const_int 1) (const_int 0)])))]
19493 "TARGET_3DNOW_A"
19494 "pswapd\\t{%1, %0|%0, %1}"
19495 [(set_attr "type" "mmx")])